From 7d61d835824f73dc4097b51f800382467c8049c5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Jul 2013 13:26:05 -0400 Subject: drm/radeon: fix audio dto programming on DCE4+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to set the dto source before setting the dividers otherwise we may get stability problems with the dto leading to audio playback problems. Signed-off-by: Alex Deucher Reviewed-by: Christian König Cc: stable@vger.kernel.org diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index b0d3fb3..bb9ea36 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -157,9 +157,9 @@ static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) * 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_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); } -- cgit v0.10.2 From 489bc476b4c2b3097fe9e980379bbbab260a6156 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Jul 2013 18:05:07 -0400 Subject: drm/radeon/dpm: fix display gap programming on SI Need to set the DISP*_GAP fields as well as the DISP*_GAP_MCHG fields. Same as on previous asics. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 73aaa2e..6ecbb87 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -3620,8 +3620,12 @@ static void si_enable_display_gap(struct radeon_device *rdev) { u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL); + tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK); + tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) | + DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE)); + tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK); - tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) | + tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) | DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE)); WREG32(CG_DISPLAY_GAP_CNTL, tmp); } -- cgit v0.10.2 From f44a0120ef07cc9a1f36ab86751ec2b0598d7a2b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Jul 2013 18:18:32 -0400 Subject: drm/radeon/dpm: fix si_calculate_memory_refresh_rate() Update alogorithm as per internal advice. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 6ecbb87..80c1f50 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -37,8 +37,6 @@ #define SMC_RAM_END 0x20000 -#define DDR3_DRAM_ROWS 0x2000 - #define SCLK_MIN_DEEPSLEEP_FREQ 1350 static const struct si_cac_config_reg cac_weights_tahiti[] = @@ -4040,16 +4038,15 @@ static int si_force_switch_to_arb_f0(struct radeon_device *rdev) static u32 si_calculate_memory_refresh_rate(struct radeon_device *rdev, u32 engine_clock) { - struct rv7xx_power_info *pi = rv770_get_pi(rdev); u32 dram_rows; u32 dram_refresh_rate; u32 mc_arb_rfsh_rate; u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT; - if (pi->mem_gddr5) - dram_rows = 1 << (tmp + 10); + if (tmp >= 4) + dram_rows = 16384; else - dram_rows = DDR3_DRAM_ROWS; + dram_rows = 1 << (tmp + 10); dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3); mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64; -- cgit v0.10.2 From 46348dc29bc936360057e9b41003274284ec0a47 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 26 Jul 2013 18:21:02 -0400 Subject: drm/radeon/dpm: fix powertune handling for pci id 0x6835 0x6835 should be treated as a cape verde pro. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 80c1f50..994f9e5 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1939,6 +1939,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev) case 0x683B: case 0x683F: case 0x6829: + case 0x6835: si_pi->cac_weights = cac_weights_cape_verde_pro; si_pi->dte_data = dte_data_cape_verde; break; -- cgit v0.10.2 From b2d70917e4b9fc5bddfbd025bfb1f15185e74971 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 27 Jul 2013 17:53:25 -0400 Subject: drm/radeon: properly handle cg on asics without UVD Don't try and enable clockgating if the asic doesn't have UVD. Use rdev->has_uvd rather than using local checks. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index d325280..1d656f7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5215,14 +5215,12 @@ static void si_enable_mc_ls(struct radeon_device *rdev, static void si_init_cg(struct radeon_device *rdev) { - bool has_uvd = true; - si_enable_mgcg(rdev, true); si_enable_cgcg(rdev, true); /* disable MC LS on Tahiti */ if (rdev->family == CHIP_TAHITI) si_enable_mc_ls(rdev, false); - if (has_uvd) { + if (rdev->has_uvd) { si_enable_uvd_mgcg(rdev, true); si_init_uvd_internal_cg(rdev); } @@ -5230,9 +5228,7 @@ static void si_init_cg(struct radeon_device *rdev) static void si_fini_cg(struct radeon_device *rdev) { - bool has_uvd = true; - - if (has_uvd) + if (rdev->has_uvd) si_enable_uvd_mgcg(rdev, false); si_enable_cgcg(rdev, false); si_enable_mgcg(rdev, false); -- cgit v0.10.2 From 20fab6415cfe33172dfaea1595a2739bdea5f57e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 28 Jul 2013 12:33:56 -0400 Subject: drm/radeon/atom: fix fb when fetching engine params For correctness. The fb divider isn't actually used in any of the relevant dpm code. It's calculated from the other parameters. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index e3f3e88..4ccd61f 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2782,7 +2782,7 @@ int radeon_atom_get_clock_dividers(struct radeon_device *rdev, ATOM_PLL_CNTL_FLAG_PLL_POST_DIV_EN) ? true : false; dividers->enable_dithen = (args.v3.ucCntlFlag & ATOM_PLL_CNTL_FLAG_FRACTION_DISABLE) ? false : true; - dividers->fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); + dividers->whole_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDiv); dividers->frac_fb_div = le16_to_cpu(args.v3.ulFbDiv.usFbDivFrac); dividers->ref_div = args.v3.ucRefDiv; dividers->vco_mode = (args.v3.ucCntlFlag & -- cgit v0.10.2 From f86d0269b471d88c9c06da4972f9145f978a0e5a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 29 Jul 2013 10:45:27 -0400 Subject: drm/radeon/dpm: fix forcing performance state to low on cayman Need to program EnabledLevels to 1 to force the low state. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 559cf24..4f9b9bc 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -1054,10 +1054,6 @@ static int ni_restrict_performance_levels_before_switch(struct radeon_device *rd int ni_dpm_force_performance_level(struct radeon_device *rdev, enum radeon_dpm_forced_level level) { - struct radeon_ps *rps = rdev->pm.dpm.current_ps; - struct ni_ps *ps = ni_get_ps(rps); - u32 levels; - if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) return -EINVAL; @@ -1068,8 +1064,7 @@ int ni_dpm_force_performance_level(struct radeon_device *rdev, if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) return -EINVAL; - levels = ps->performance_level_count - 1; - if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) + if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK) return -EINVAL; } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) -- cgit v0.10.2 From 3652f00591982b15f0702dd90e4e5f0ddcfe7f8b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 29 Jul 2013 11:51:25 -0400 Subject: drm/radeon/si: disable cgcg and pg for now Coarse grain clockgating causes problems with reclocking on some cards and powergating (verde only) causes problems with ring initialization. The proper fix (restructuring the init sequences) is too invasive for 3.11 so just disable them for now. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 1d656f7..6ca9046 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5216,7 +5216,7 @@ static void si_enable_mc_ls(struct radeon_device *rdev, static void si_init_cg(struct radeon_device *rdev) { si_enable_mgcg(rdev, true); - si_enable_cgcg(rdev, true); + si_enable_cgcg(rdev, false); /* disable MC LS on Tahiti */ if (rdev->family == CHIP_TAHITI) si_enable_mc_ls(rdev, false); @@ -5237,11 +5237,11 @@ static void si_fini_cg(struct radeon_device *rdev) static void si_init_pg(struct radeon_device *rdev) { bool has_pg = false; - +#if 0 /* only cape verde supports PG */ if (rdev->family == CHIP_VERDE) has_pg = true; - +#endif if (has_pg) { si_init_ao_cu_mask(rdev); si_init_dma_pg(rdev); -- cgit v0.10.2 From d05f7e700a3a47eeb7dbe236d2680381f5b5edcb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 28 Jul 2013 18:26:38 -0400 Subject: drm/radeon/dpm: disable cac setup on SI Disable cac setup on SI for now since it causes strange performance level restrictions on certain cards. I suspect there may be issues with some of the 64 bit fixed point double emulation that is used to set up those parameters. I need to double check the math before this can be re-enabled. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 994f9e5..e8ee685 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1929,6 +1929,7 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev) si_pi->cac_override = cac_override_pitcairn; si_pi->powertune_data = &powertune_data_pitcairn; si_pi->dte_data = dte_data_pitcairn; + break; } } else if (rdev->family == CHIP_VERDE) { si_pi->lcac_config = lcac_cape_verde; @@ -2041,7 +2042,8 @@ static void si_initialize_powertune_defaults(struct radeon_device *rdev) ni_pi->enable_sq_ramping = false; si_pi->enable_dte = false; - if (si_pi->powertune_data->enable_powertune_by_default) { + /* XXX: fix me */ + if (0/*si_pi->powertune_data->enable_powertune_by_default*/) { ni_pi->enable_power_containment= true; ni_pi->enable_cac = true; if (si_pi->dte_data.enable_dte_by_default) { -- cgit v0.10.2 From 63f22d0e98cf74adf4ecfb25099607239b00c751 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 27 Jul 2013 17:50:26 -0400 Subject: drm/radeon/dpm: fix and enable reclocking on SI The SMC interface changed compared to Cayman and previous asics. Set the enabled levels properly and enable reclocking by default when dpm is enabled. Signed-off-by: Alex Deucher diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index e8ee685..1604a87 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -3238,10 +3238,10 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, { struct radeon_ps *rps = rdev->pm.dpm.current_ps; struct ni_ps *ps = ni_get_ps(rps); - u32 levels; + u32 levels = ps->performance_level_count; if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { - if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) + if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) return -EINVAL; if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK) @@ -3250,14 +3250,13 @@ int si_dpm_force_performance_level(struct radeon_device *rdev, if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) return -EINVAL; - levels = ps->performance_level_count - 1; - if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) + if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK) return -EINVAL; } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) { if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK) return -EINVAL; - if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK) + if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK) return -EINVAL; } @@ -6017,16 +6016,11 @@ int si_dpm_set_power_state(struct radeon_device *rdev) return ret; } -#if 0 - /* XXX */ ret = si_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO); if (ret) { DRM_ERROR("si_dpm_force_performance_level failed\n"); return ret; } -#else - rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO; -#endif return 0; } -- cgit v0.10.2