Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 16d5b272 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux

Some more radeon fixes.  Mostly dpm and uvd fixes.  Fixes hangs
with dpm on more rv6xx asics, and fixes suspend and resume with UVD.

* 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: make missing smc ucode non-fatal
  drm/radeon/dpm: require rlc for dpm
  drm/radeon/cik: use a mutex to properly lock srbm instanced registers
  drm/radeon: remove unnecessary unpin
  drm/radeon: add more UVD CS checking
  drm/radeon: stop sending invalid UVD destroy msg
  drm/radeon: only save UVD bo when we have open handles
  drm/radeon: always program the MC on startup
  drm/radeon: fix audio dto calculation on DCE3+ (v3)
  drm/radeon/dpm: disable sclk ss on rv6xx
  drm/radeon: fix halting UVD
  drm/radeon/dpm: adjust power state properly for UVD on SI
  drm/radeon/dpm: fix spread spectrum setup (v2)
  drm/radeon/dpm: adjust thermal protection requirements
  drm/radeon: select audio dto based on encoder id for DCE3
  drm/radeon: properly handle pm on gpu reset
parents 3ac65259 8a53fa23
Loading
Loading
Loading
Loading
+2 −15
Original line number Diff line number Diff line
@@ -2548,9 +2548,6 @@ int btc_dpm_init(struct radeon_device *rdev)
{
	struct rv7xx_power_info *pi;
	struct evergreen_power_info *eg_pi;
	int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
	u16 data_offset, size;
	u8 frev, crev;
	struct atom_clock_dividers dividers;
	int ret;

@@ -2633,16 +2630,7 @@ int btc_dpm_init(struct radeon_device *rdev)
	eg_pi->vddci_control =
		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);

	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                   &frev, &crev, &data_offset)) {
		pi->sclk_ss = true;
		pi->mclk_ss = true;
		pi->dynamic_ss = true;
	} else {
		pi->sclk_ss = false;
		pi->mclk_ss = false;
		pi->dynamic_ss = true;
	}
	rv770_get_engine_memory_ss(rdev);

	pi->asi = RV770_ASI_DFLT;
	pi->pasi = CYPRESS_HASI_DFLT;
@@ -2659,8 +2647,7 @@ int btc_dpm_init(struct radeon_device *rdev)

	pi->dynamic_pcie_gen2 = true;

	if (pi->gfx_clock_gating &&
	    (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
		pi->thermal_protection = true;
	else
		pi->thermal_protection = false;
+15 −3
Original line number Diff line number Diff line
@@ -2587,9 +2587,11 @@ u32 cik_compute_ring_get_rptr(struct radeon_device *rdev,
	if (rdev->wb.enabled) {
		rptr = le32_to_cpu(rdev->wb.wb[ring->rptr_offs/4]);
	} else {
		mutex_lock(&rdev->srbm_mutex);
		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
		rptr = RREG32(CP_HQD_PQ_RPTR);
		cik_srbm_select(rdev, 0, 0, 0, 0);
		mutex_unlock(&rdev->srbm_mutex);
	}
	rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;

@@ -2604,9 +2606,11 @@ u32 cik_compute_ring_get_wptr(struct radeon_device *rdev,
	if (rdev->wb.enabled) {
		wptr = le32_to_cpu(rdev->wb.wb[ring->wptr_offs/4]);
	} else {
		mutex_lock(&rdev->srbm_mutex);
		cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0);
		wptr = RREG32(CP_HQD_PQ_WPTR);
		cik_srbm_select(rdev, 0, 0, 0, 0);
		mutex_unlock(&rdev->srbm_mutex);
	}
	wptr = (wptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift;

@@ -2897,6 +2901,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
	WREG32(CP_CPF_DEBUG, tmp);

	/* init the pipes */
	mutex_lock(&rdev->srbm_mutex);
	for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); i++) {
		int me = (i < 4) ? 1 : 2;
		int pipe = (i < 4) ? i : (i - 4);
@@ -2919,6 +2924,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
		WREG32(CP_HPD_EOP_CONTROL, tmp);
	}
	cik_srbm_select(rdev, 0, 0, 0, 0);
	mutex_unlock(&rdev->srbm_mutex);

	/* init the queues.  Just two for now. */
	for (i = 0; i < 2; i++) {
@@ -2972,6 +2978,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
		mqd->static_thread_mgmt23[0] = 0xffffffff;
		mqd->static_thread_mgmt23[1] = 0xffffffff;

		mutex_lock(&rdev->srbm_mutex);
		cik_srbm_select(rdev, rdev->ring[idx].me,
				rdev->ring[idx].pipe,
				rdev->ring[idx].queue, 0);
@@ -3099,6 +3106,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev)
		WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);

		cik_srbm_select(rdev, 0, 0, 0, 0);
		mutex_unlock(&rdev->srbm_mutex);

		radeon_bo_kunmap(rdev->ring[idx].mqd_obj);
		radeon_bo_unreserve(rdev->ring[idx].mqd_obj);
@@ -4320,6 +4328,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)

	/* XXX SH_MEM regs */
	/* where to put LDS, scratch, GPUVM in FSA64 space */
	mutex_lock(&rdev->srbm_mutex);
	for (i = 0; i < 16; i++) {
		cik_srbm_select(rdev, 0, 0, 0, i);
		/* CP and shaders */
@@ -4335,6 +4344,7 @@ static int cik_pcie_gart_enable(struct radeon_device *rdev)
		/* XXX SDMA RLC - todo */
	}
	cik_srbm_select(rdev, 0, 0, 0, 0);
	mutex_unlock(&rdev->srbm_mutex);

	cik_pcie_gart_tlb_flush(rdev);
	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
@@ -5954,6 +5964,8 @@ static int cik_startup(struct radeon_device *rdev)
	struct radeon_ring *ring;
	int r;

	cik_mc_program(rdev);

	if (rdev->flags & RADEON_IS_IGP) {
		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
		    !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) {
@@ -5985,7 +5997,6 @@ static int cik_startup(struct radeon_device *rdev)
	if (r)
		return r;

	cik_mc_program(rdev);
	r = cik_pcie_gart_enable(rdev);
	if (r)
		return r;
@@ -6194,7 +6205,7 @@ int cik_suspend(struct radeon_device *rdev)
	radeon_vm_manager_fini(rdev);
	cik_cp_enable(rdev, false);
	cik_sdma_enable(rdev, false);
	r600_uvd_rbc_stop(rdev);
	r600_uvd_stop(rdev);
	radeon_uvd_suspend(rdev);
	cik_irq_suspend(rdev);
	radeon_wb_disable(rdev);
@@ -6358,6 +6369,7 @@ void cik_fini(struct radeon_device *rdev)
	radeon_vm_manager_fini(rdev);
	radeon_ib_pool_fini(rdev);
	radeon_irq_kms_fini(rdev);
	r600_uvd_stop(rdev);
	radeon_uvd_fini(rdev);
	cik_pcie_gart_fini(rdev);
	r600_vram_scratch_fini(rdev);
@@ -6978,7 +6990,7 @@ int cik_uvd_resume(struct radeon_device *rdev)

	/* programm the VCPU memory controller bits 0-27 */
	addr = rdev->uvd.gpu_addr >> 3;
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd.fw_size + 4) >> 3;
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size + 4) >> 3;
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
	WREG32(UVD_VCPU_CACHE_SIZE0, size);

+2 −15
Original line number Diff line number Diff line
@@ -2038,9 +2038,6 @@ int cypress_dpm_init(struct radeon_device *rdev)
{
	struct rv7xx_power_info *pi;
	struct evergreen_power_info *eg_pi;
	int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
	uint16_t data_offset, size;
	uint8_t frev, crev;
	struct atom_clock_dividers dividers;
	int ret;

@@ -2092,16 +2089,7 @@ int cypress_dpm_init(struct radeon_device *rdev)
	eg_pi->vddci_control =
		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);

	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
                                   &frev, &crev, &data_offset)) {
		pi->sclk_ss = true;
		pi->mclk_ss = true;
		pi->dynamic_ss = true;
	} else {
		pi->sclk_ss = false;
		pi->mclk_ss = false;
		pi->dynamic_ss = true;
	}
	rv770_get_engine_memory_ss(rdev);

	pi->asi = RV770_ASI_DFLT;
	pi->pasi = CYPRESS_HASI_DFLT;
@@ -2122,8 +2110,7 @@ int cypress_dpm_init(struct radeon_device *rdev)

	pi->dynamic_pcie_gen2 = true;

	if (pi->gfx_clock_gating &&
	    (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
		pi->thermal_protection = true;
	else
		pi->thermal_protection = false;
+4 −2
Original line number Diff line number Diff line
@@ -5106,6 +5106,8 @@ static int evergreen_startup(struct radeon_device *rdev)
	/* enable aspm */
	evergreen_program_aspm(rdev);

	evergreen_mc_program(rdev);

	if (ASIC_IS_DCE5(rdev)) {
		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
			r = ni_init_microcode(rdev);
@@ -5133,7 +5135,6 @@ static int evergreen_startup(struct radeon_device *rdev)
	if (r)
		return r;

	evergreen_mc_program(rdev);
	if (rdev->flags & RADEON_IS_AGP) {
		evergreen_agp_enable(rdev);
	} else {
@@ -5291,10 +5292,10 @@ int evergreen_resume(struct radeon_device *rdev)
int evergreen_suspend(struct radeon_device *rdev)
{
	r600_audio_fini(rdev);
	r600_uvd_stop(rdev);
	radeon_uvd_suspend(rdev);
	r700_cp_stop(rdev);
	r600_dma_stop(rdev);
	r600_uvd_rbc_stop(rdev);
	evergreen_irq_suspend(rdev);
	radeon_wb_disable(rdev);
	evergreen_pcie_gart_disable(rdev);
@@ -5429,6 +5430,7 @@ void evergreen_fini(struct radeon_device *rdev)
	radeon_ib_pool_fini(rdev);
	radeon_irq_kms_fini(rdev);
	evergreen_pcie_gart_fini(rdev);
	r600_uvd_stop(rdev);
	radeon_uvd_fini(rdev);
	r600_vram_scratch_fini(rdev);
	radeon_gem_fini(rdev);
+24 −2
Original line number Diff line number Diff line
@@ -148,18 +148,40 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
	u32 base_rate = 24000;
	u32 max_ratio = clock / base_rate;
	u32 dto_phase;
	u32 dto_modulo = clock;
	u32 wallclock_ratio;
	u32 dto_cntl;

	if (!dig || !dig->afmt)
		return;

	if (max_ratio >= 8) {
		dto_phase = 192 * 1000;
		wallclock_ratio = 3;
	} else if (max_ratio >= 4) {
		dto_phase = 96 * 1000;
		wallclock_ratio = 2;
	} else if (max_ratio >= 2) {
		dto_phase = 48 * 1000;
		wallclock_ratio = 1;
	} else {
		dto_phase = 24 * 1000;
		wallclock_ratio = 0;
	}
	dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
	dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
	WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);

	/* XXX two dtos; generally use dto0 for hdmi */
	/* Express [24MHz / target pixel clock] as an exact rational
	 * number (coefficient of two integer numbers.  DCCG_AUDIO_DTOx_PHASE
	 * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
	 */
	WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
	WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
	WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
	WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
	WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
}


Loading