Newer asics require that the dpm be initialized prior to the other engines in order for clockgating to work properly. The tricky part is that other aspects of dpm are required at later stages (e.g., after displays are enumerated).
This patch set reworks the power management init flow to accomodate the requirements of newer hardware. Most of the pm init/fini/suspend/resume flow has now moved into the asic specific functions. As a result, dpm now initializes reliably on CIK parts and clockgating on these parts now works and is enabled by default. Powergating support for CIK parts is also improved, but is not yet ready to be enabled by default.
I think it's now safe to enable dpm by default on CIK parts.
Alex Deucher (18): drm/radeon/dpm: remove unnecessary checks in dpm_init drm/radeon/si: drop cg_update from dpm code drm/radeon/cik: drop cg_update from dpm code drm/radeon: re-order firmware loading in preparation for dpm rework drm/radeon/dpm: add a late enable callback drm/radeon/dpm: add late_enable for rs780/rs880/rv6xx drm/radeon/dpm: add late_enable for rv7xx-NI drm/radeon/dpm: add late_enable for sumo drm/radeon/dpm: add late_enable for trinity drm/radeon/dpm: add late_enable for SI drm/radeon/dpm: add late_enable for CI drm/radeon/dpm: add late_enable for KB/KV drm/radeon/dpm: switch on new late_enable callback drm/radeon/pm: move pm handling into the asic specific code drm/radeon: enable gfx cgcg on CIK dGPUs drm/radeon: enable gfx cgcg on CIK APUs drm/radeon: enable dpm by default on CI dGPUs drm/radeon: enable dpm by default on CI APUs
drivers/gpu/drm/radeon/btc_dpm.c | 20 ++--- drivers/gpu/drm/radeon/ci_dpm.c | 58 ++++--------- drivers/gpu/drm/radeon/cik.c | 51 +++++++----- drivers/gpu/drm/radeon/cypress_dpm.c | 15 ---- drivers/gpu/drm/radeon/evergreen.c | 42 ++++++---- drivers/gpu/drm/radeon/kv_dpm.c | 48 ++++------- drivers/gpu/drm/radeon/ni.c | 43 ++++++---- drivers/gpu/drm/radeon/ni_dpm.c | 21 ++--- drivers/gpu/drm/radeon/r100.c | 7 ++ drivers/gpu/drm/radeon/r300.c | 7 ++ drivers/gpu/drm/radeon/r420.c | 7 ++ drivers/gpu/drm/radeon/r520.c | 5 ++ drivers/gpu/drm/radeon/r600.c | 23 ++++-- drivers/gpu/drm/radeon/r600_dpm.c | 20 ++++- drivers/gpu/drm/radeon/r600_dpm.h | 2 - drivers/gpu/drm/radeon/radeon.h | 3 + drivers/gpu/drm/radeon/radeon_asic.c | 19 ++++- drivers/gpu/drm/radeon/radeon_asic.h | 7 ++ drivers/gpu/drm/radeon/radeon_device.c | 14 +++- drivers/gpu/drm/radeon/radeon_display.c | 17 +++- drivers/gpu/drm/radeon/radeon_pm.c | 140 ++++++++++++++++++-------------- drivers/gpu/drm/radeon/rs400.c | 7 ++ drivers/gpu/drm/radeon/rs600.c | 7 ++ drivers/gpu/drm/radeon/rs690.c | 7 ++ drivers/gpu/drm/radeon/rs780_dpm.c | 8 -- drivers/gpu/drm/radeon/rv515.c | 7 ++ drivers/gpu/drm/radeon/rv6xx_dpm.c | 10 --- drivers/gpu/drm/radeon/rv770.c | 23 ++++-- drivers/gpu/drm/radeon/rv770_dpm.c | 15 +++- drivers/gpu/drm/radeon/rv770_dpm.h | 4 - drivers/gpu/drm/radeon/si.c | 35 +++++--- drivers/gpu/drm/radeon/si_dpm.c | 60 ++++---------- drivers/gpu/drm/radeon/sumo_dpm.c | 19 +++-- drivers/gpu/drm/radeon/trinity_dpm.c | 17 +++- 34 files changed, 432 insertions(+), 356 deletions(-)
No need to check rdev->pm.num_power_states; this is a vestige of the old pm code.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_pm.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 984097b..384758d 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1192,28 +1192,26 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) rdev->pm.dpm_enabled = true; radeon_pm_compute_clocks(rdev);
- if (rdev->pm.num_power_states > 1) { - ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); - if (ret) - DRM_ERROR("failed to create device file for dpm state\n"); - ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level); - if (ret) - DRM_ERROR("failed to create device file for dpm state\n"); - /* XXX: these are noops for dpm but are here for backwards compat */ - ret = device_create_file(rdev->dev, &dev_attr_power_profile); - if (ret) - DRM_ERROR("failed to create device file for power profile\n"); - ret = device_create_file(rdev->dev, &dev_attr_power_method); - if (ret) - DRM_ERROR("failed to create device file for power method\n"); - - if (radeon_debugfs_pm_init(rdev)) { - DRM_ERROR("Failed to register debugfs file for dpm!\n"); - } + ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); + if (ret) + DRM_ERROR("failed to create device file for dpm state\n"); + ret = device_create_file(rdev->dev, &dev_attr_power_dpm_force_performance_level); + if (ret) + DRM_ERROR("failed to create device file for dpm state\n"); + /* XXX: these are noops for dpm but are here for backwards compat */ + ret = device_create_file(rdev->dev, &dev_attr_power_profile); + if (ret) + DRM_ERROR("failed to create device file for power profile\n"); + ret = device_create_file(rdev->dev, &dev_attr_power_method); + if (ret) + DRM_ERROR("failed to create device file for power method\n");
- DRM_INFO("radeon: dpm initialized\n"); + if (radeon_debugfs_pm_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for dpm!\n"); }
+ DRM_INFO("radeon: dpm initialized\n"); + return 0; }
I'm not entirely sure this is required and it won't work with the dpm restructing anyway.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/si.c | 4 ++-- drivers/gpu/drm/radeon/si_dpm.c | 38 -------------------------------------- 2 files changed, 2 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index a36736d..e3a9fc7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -5210,8 +5210,8 @@ static void si_enable_hdp_ls(struct radeon_device *rdev, WREG32(HDP_MEM_POWER_LS, data); }
-void si_update_cg(struct radeon_device *rdev, - u32 block, bool enable) +static void si_update_cg(struct radeon_device *rdev, + u32 block, bool enable) { if (block & RADEON_CG_BLOCK_GFX) { si_enable_gui_idle_interrupt(rdev, false); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 0b00c79..2d0e94a 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1753,9 +1753,6 @@ static int si_calculate_sclk_params(struct radeon_device *rdev, u32 engine_clock, SISLANDS_SMC_SCLK_VALUE *sclk);
-extern void si_update_cg(struct radeon_device *rdev, - u32 block, bool enable); - static struct si_power_info *si_get_pi(struct radeon_device *rdev) { struct si_power_info *pi = rdev->pm.dpm.priv; @@ -5791,13 +5788,6 @@ int si_dpm_enable(struct radeon_device *rdev) struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; int ret;
- si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - if (si_is_smc_running(rdev)) return -EINVAL; if (pi->voltage_control) @@ -5917,13 +5907,6 @@ int si_dpm_enable(struct radeon_device *rdev)
si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
- si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), true); - ni_update_current_ps(rdev, boot_ps);
return 0; @@ -5934,13 +5917,6 @@ void si_dpm_disable(struct radeon_device *rdev) struct rv7xx_power_info *pi = rv770_get_pi(rdev); struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
- si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - if (!si_is_smc_running(rdev)) return; si_disable_ulv(rdev); @@ -6005,13 +5981,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev) struct radeon_ps *old_ps = &eg_pi->current_rps; int ret;
- si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - ret = si_disable_ulv(rdev); if (ret) { DRM_ERROR("si_disable_ulv failed\n"); @@ -6104,13 +6073,6 @@ int si_dpm_set_power_state(struct radeon_device *rdev) return ret; }
- si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), true); - return 0; }
I'm not entirely sure this is required and it won't work with the dpm restructing anyway.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/ci_dpm.c | 36 ------------------------------------ drivers/gpu/drm/radeon/kv_dpm.c | 25 ------------------------- 2 files changed, 61 deletions(-)
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 1ed4799..f891fc0 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -171,8 +171,6 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, struct atom_voltage_table *voltage_table); extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev); extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev); -extern void cik_update_cg(struct radeon_device *rdev, - u32 block, bool enable);
static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev, struct atom_voltage_table_entry *voltage_table, @@ -4561,13 +4559,6 @@ int ci_dpm_enable(struct radeon_device *rdev) struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; int ret;
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - if (ci_is_smc_running(rdev)) return -EINVAL; if (pi->voltage_control != CISLANDS_VOLTAGE_CONTROL_NONE) { @@ -4689,13 +4680,6 @@ int ci_dpm_enable(struct radeon_device *rdev)
ci_dpm_powergate_uvd(rdev, true);
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), true); - ci_update_current_ps(rdev, boot_ps);
return 0; @@ -4706,12 +4690,6 @@ void ci_dpm_disable(struct radeon_device *rdev) struct ci_power_info *pi = ci_get_pi(rdev); struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - ci_dpm_powergate_uvd(rdev, false);
if (!ci_is_smc_running(rdev)) @@ -4742,13 +4720,6 @@ int ci_dpm_set_power_state(struct radeon_device *rdev) struct radeon_ps *old_ps = &pi->current_rps; int ret;
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), false); - ci_find_dpm_states_clocks_in_dpm_table(rdev, new_ps); if (pi->pcie_performance_request) ci_request_link_speed_change_before_state_change(rdev, new_ps, old_ps); @@ -4804,13 +4775,6 @@ int ci_dpm_set_power_state(struct radeon_device *rdev) if (pi->pcie_performance_request) ci_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_MC | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_UVD | - RADEON_CG_BLOCK_HDP), true); - return 0; }
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index b419055..a0e20eb 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -1126,11 +1126,6 @@ int kv_dpm_enable(struct radeon_device *rdev) struct kv_power_info *pi = kv_get_pi(rdev); int ret;
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_HDP), false); - ret = kv_process_firmware_header(rdev); if (ret) { DRM_ERROR("kv_process_firmware_header failed\n"); @@ -1238,11 +1233,6 @@ int kv_dpm_enable(struct radeon_device *rdev) kv_dpm_powergate_vce(rdev, true); kv_dpm_powergate_uvd(rdev, true);
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_HDP), true); - kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
return ret; @@ -1250,11 +1240,6 @@ int kv_dpm_enable(struct radeon_device *rdev)
void kv_dpm_disable(struct radeon_device *rdev) { - cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_HDP), false); - kv_smc_bapm_enable(rdev, false);
/* powerup blocks */ @@ -1779,11 +1764,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) /*struct radeon_ps *old_ps = &pi->current_rps;*/ int ret;
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_HDP), false); - if (pi->bapm_enable) { ret = kv_smc_bapm_enable(rdev, rdev->pm.dpm.ac_power); if (ret) { @@ -1849,11 +1829,6 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) } }
- cik_update_cg(rdev, (RADEON_CG_BLOCK_GFX | - RADEON_CG_BLOCK_SDMA | - RADEON_CG_BLOCK_BIF | - RADEON_CG_BLOCK_HDP), true); - return 0; }
We need to reorder the driver init sequence to better accomodate dpm which needs to be loaded earlier in the init sequence. Move fw init up so that it's available for dpm init.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/cik.c | 42 ++++++++++++++++++++------------------ drivers/gpu/drm/radeon/evergreen.c | 33 ++++++++++++++++-------------- drivers/gpu/drm/radeon/ni.c | 36 +++++++++++++++++--------------- drivers/gpu/drm/radeon/r600.c | 16 +++++++-------- drivers/gpu/drm/radeon/rv770.c | 16 +++++++-------- drivers/gpu/drm/radeon/si.c | 18 ++++++++-------- 6 files changed, 84 insertions(+), 77 deletions(-)
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index b43a3a3..4ddc3e5 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -7501,26 +7501,7 @@ static int cik_startup(struct radeon_device *rdev)
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) { - r = cik_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - } else { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || - !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw || - !rdev->mc_fw) { - r = cik_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - + if (!(rdev->flags & RADEON_IS_IGP)) { r = ci_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -7833,6 +7814,27 @@ int cik_init(struct radeon_device *rdev) if (r) return r;
+ 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) { + r = cik_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } else { + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || + !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw || + !rdev->mc_fw) { + r = cik_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 9702e55..4abf8b6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -5110,26 +5110,11 @@ static int evergreen_startup(struct radeon_device *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); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } r = ni_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); return r; } - } else { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } }
if (rdev->flags & RADEON_IS_AGP) { @@ -5357,6 +5342,24 @@ int evergreen_init(struct radeon_device *rdev) if (r) return r;
+ if (ASIC_IS_DCE5(rdev)) { + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { + r = ni_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } else { + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = r600_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 11aab2a..757141a 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1866,23 +1866,7 @@ static int cayman_startup(struct radeon_device *rdev)
evergreen_mc_program(rdev);
- if (rdev->flags & RADEON_IS_IGP) { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = ni_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - } else { - if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { - r = ni_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - + if (!(rdev->flags & RADEON_IS_IGP)) { r = ni_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -2133,6 +2117,24 @@ int cayman_init(struct radeon_device *rdev) if (r) return r;
+ if (rdev->flags & RADEON_IS_IGP) { + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = ni_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } else { + if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { + r = ni_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + } + ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024);
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9ad0673..09e83f2 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2775,14 +2775,6 @@ static int r600_startup(struct radeon_device *rdev)
r600_mc_program(rdev);
- if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - if (rdev->flags & RADEON_IS_AGP) { r600_agp_enable(rdev); } else { @@ -2970,6 +2962,14 @@ int r600_init(struct radeon_device *rdev) if (r) return r;
+ if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = r600_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 9f58467..45774ff 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1665,14 +1665,6 @@ static int rv770_startup(struct radeon_device *rdev)
rv770_mc_program(rdev);
- if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { - r = r600_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - if (rdev->flags & RADEON_IS_AGP) { rv770_agp_enable(rdev); } else { @@ -1876,6 +1868,14 @@ int rv770_init(struct radeon_device *rdev) if (r) return r;
+ if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { + r = r600_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index e3a9fc7..1df4631 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -6322,15 +6322,6 @@ static int si_startup(struct radeon_device *rdev)
si_mc_program(rdev);
- if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || - !rdev->rlc_fw || !rdev->mc_fw) { - r = si_init_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load firmware!\n"); - return r; - } - } - r = si_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -6598,6 +6589,15 @@ int si_init(struct radeon_device *rdev) if (r) return r;
+ if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || + !rdev->rlc_fw || !rdev->mc_fw) { + r = si_init_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load firmware!\n"); + return r; + } + } + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024);
Certain features need to be enabled after ring tests (e.g., powergating, etc.). Add a function pointer to split out late enable features.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon.h | 3 +++ drivers/gpu/drm/radeon/radeon_pm.c | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b1f990d..1900917 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -252,6 +252,7 @@ struct radeon_clock { * Power management */ int radeon_pm_init(struct radeon_device *rdev); +int radeon_pm_late_init(struct radeon_device *rdev); void radeon_pm_fini(struct radeon_device *rdev); void radeon_pm_compute_clocks(struct radeon_device *rdev); void radeon_pm_suspend(struct radeon_device *rdev); @@ -1775,6 +1776,7 @@ struct radeon_asic { int (*init)(struct radeon_device *rdev); void (*setup_asic)(struct radeon_device *rdev); int (*enable)(struct radeon_device *rdev); + int (*late_enable)(struct radeon_device *rdev); void (*disable)(struct radeon_device *rdev); int (*pre_set_power_state)(struct radeon_device *rdev); int (*set_power_state)(struct radeon_device *rdev); @@ -2650,6 +2652,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_dpm_init(rdev) rdev->asic->dpm.init((rdev)) #define radeon_dpm_setup_asic(rdev) rdev->asic->dpm.setup_asic((rdev)) #define radeon_dpm_enable(rdev) rdev->asic->dpm.enable((rdev)) +#define radeon_dpm_late_enable(rdev) rdev->asic->dpm.late_enable((rdev)) #define radeon_dpm_disable(rdev) rdev->asic->dpm.disable((rdev)) #define radeon_dpm_pre_set_power_state(rdev) rdev->asic->dpm.pre_set_power_state((rdev)) #define radeon_dpm_set_power_state(rdev) rdev->asic->dpm.set_power_state((rdev)) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 384758d..d4e5bcf 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1288,6 +1288,18 @@ int radeon_pm_init(struct radeon_device *rdev) return radeon_pm_init_old(rdev); }
+int radeon_pm_late_init(struct radeon_device *rdev) +{ + int ret = 0; + + if (rdev->pm.pm_method == PM_METHOD_DPM) { + mutex_lock(&rdev->pm.mutex); + ret = radeon_dpm_late_enable(rdev); + mutex_unlock(&rdev->pm.mutex); + } + return ret; +} + static void radeon_pm_fini_old(struct radeon_device *rdev) { if (rdev->pm.num_power_states > 1) {
Make sure interrupts are enabled before we enable thermal interrupts.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/r600_dpm.c | 16 ++++++++++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 2 ++ drivers/gpu/drm/radeon/radeon_asic.h | 1 + 3 files changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 5513d8f..12e35dd 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -777,6 +777,22 @@ bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor) } }
+int r600_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + } + + return 0; +} + union power_info { struct _ATOM_POWERPLAY_INFO info; struct _ATOM_POWERPLAY_INFO_V2 info_2; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index c0425bb..a38ce4c 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1045,6 +1045,7 @@ static struct radeon_asic rv6xx_asic = { .init = &rv6xx_dpm_init, .setup_asic = &rv6xx_setup_asic, .enable = &rv6xx_dpm_enable, + .late_enable = &r600_dpm_late_enable, .disable = &rv6xx_dpm_disable, .pre_set_power_state = &r600_dpm_pre_set_power_state, .set_power_state = &rv6xx_dpm_set_power_state, @@ -1135,6 +1136,7 @@ static struct radeon_asic rs780_asic = { .init = &rs780_dpm_init, .setup_asic = &rs780_dpm_setup_asic, .enable = &rs780_dpm_enable, + .late_enable = &r600_dpm_late_enable, .disable = &rs780_dpm_disable, .pre_set_power_state = &r600_dpm_pre_set_power_state, .set_power_state = &rs780_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index c9fd97b..438839f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -392,6 +392,7 @@ int rv6xx_get_temp(struct radeon_device *rdev); int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk); int r600_dpm_pre_set_power_state(struct radeon_device *rdev); void r600_dpm_post_set_power_state(struct radeon_device *rdev); +int r600_dpm_late_enable(struct radeon_device *rdev); /* r600 dma */ uint32_t r600_dma_get_rptr(struct radeon_device *rdev, struct radeon_ring *ring);
Make sure interrupts are enabled before we enable thermal interrupts.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 4 ++++ drivers/gpu/drm/radeon/radeon_asic.h | 1 + drivers/gpu/drm/radeon/rv770_dpm.c | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index a38ce4c..9c047b8 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1241,6 +1241,7 @@ static struct radeon_asic rv770_asic = { .init = &rv770_dpm_init, .setup_asic = &rv770_dpm_setup_asic, .enable = &rv770_dpm_enable, + .late_enable = &rv770_dpm_late_enable, .disable = &rv770_dpm_disable, .pre_set_power_state = &r600_dpm_pre_set_power_state, .set_power_state = &rv770_dpm_set_power_state, @@ -1359,6 +1360,7 @@ static struct radeon_asic evergreen_asic = { .init = &cypress_dpm_init, .setup_asic = &cypress_dpm_setup_asic, .enable = &cypress_dpm_enable, + .late_enable = &rv770_dpm_late_enable, .disable = &cypress_dpm_disable, .pre_set_power_state = &r600_dpm_pre_set_power_state, .set_power_state = &cypress_dpm_set_power_state, @@ -1542,6 +1544,7 @@ static struct radeon_asic btc_asic = { .init = &btc_dpm_init, .setup_asic = &btc_dpm_setup_asic, .enable = &btc_dpm_enable, + .late_enable = &rv770_dpm_late_enable, .disable = &btc_dpm_disable, .pre_set_power_state = &btc_dpm_pre_set_power_state, .set_power_state = &btc_dpm_set_power_state, @@ -1685,6 +1688,7 @@ static struct radeon_asic cayman_asic = { .init = &ni_dpm_init, .setup_asic = &ni_dpm_setup_asic, .enable = &ni_dpm_enable, + .late_enable = &rv770_dpm_late_enable, .disable = &ni_dpm_disable, .pre_set_power_state = &ni_dpm_pre_set_power_state, .set_power_state = &ni_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 438839f..85e55c1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -455,6 +455,7 @@ int rv770_get_temp(struct radeon_device *rdev); /* rv7xx pm */ int rv770_dpm_init(struct radeon_device *rdev); int rv770_dpm_enable(struct radeon_device *rdev); +int rv770_dpm_late_enable(struct radeon_device *rdev); void rv770_dpm_disable(struct radeon_device *rdev); int rv770_dpm_set_power_state(struct radeon_device *rdev); void rv770_dpm_setup_asic(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 374499d..5d6188f 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -1986,6 +1986,28 @@ int rv770_dpm_enable(struct radeon_device *rdev) return 0; }
+int rv770_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + PPSMC_Result result; + + ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); + + if (result != PPSMC_Result_OK) + DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); + } + + return 0; +} + void rv770_dpm_disable(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev);
Need to wait to enable cg and pg until after ring tests. Also make sure interrupts are enabled before we enable thermal interrupts.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + drivers/gpu/drm/radeon/sumo_dpm.c | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9c047b8..236afdd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1453,6 +1453,7 @@ static struct radeon_asic sumo_asic = { .init = &sumo_dpm_init, .setup_asic = &sumo_dpm_setup_asic, .enable = &sumo_dpm_enable, + .late_enable = &sumo_dpm_late_enable, .disable = &sumo_dpm_disable, .pre_set_power_state = &sumo_dpm_pre_set_power_state, .set_power_state = &sumo_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 85e55c1..1e7d669 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -547,6 +547,7 @@ u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); bool btc_dpm_vblank_too_short(struct radeon_device *rdev); int sumo_dpm_init(struct radeon_device *rdev); int sumo_dpm_enable(struct radeon_device *rdev); +int sumo_dpm_late_enable(struct radeon_device *rdev); void sumo_dpm_disable(struct radeon_device *rdev); int sumo_dpm_pre_set_power_state(struct radeon_device *rdev); int sumo_dpm_set_power_state(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index 96ea6db8..b63640f 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1247,6 +1247,26 @@ int sumo_dpm_enable(struct radeon_device *rdev) return 0; }
+int sumo_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + ret = sumo_enable_clock_power_gating(rdev); + if (ret) + return ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + } + + return 0; +} + void sumo_dpm_disable(struct radeon_device *rdev) { struct sumo_power_info *pi = sumo_get_pi(rdev);
Need to wait to enable cg and pg until after ring tests. Also make sure interrupts are enabled before we enable thermal interrupts.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + drivers/gpu/drm/radeon/trinity_dpm.c | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 236afdd..2011a7e 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1790,6 +1790,7 @@ static struct radeon_asic trinity_asic = { .init = &trinity_dpm_init, .setup_asic = &trinity_dpm_setup_asic, .enable = &trinity_dpm_enable, + .late_enable = &trinity_dpm_late_enable, .disable = &trinity_dpm_disable, .pre_set_power_state = &trinity_dpm_pre_set_power_state, .set_power_state = &trinity_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 1e7d669..597daec 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -613,6 +613,7 @@ int ni_dpm_force_performance_level(struct radeon_device *rdev, bool ni_dpm_vblank_too_short(struct radeon_device *rdev); int trinity_dpm_init(struct radeon_device *rdev); int trinity_dpm_enable(struct radeon_device *rdev); +int trinity_dpm_late_enable(struct radeon_device *rdev); void trinity_dpm_disable(struct radeon_device *rdev); int trinity_dpm_pre_set_power_state(struct radeon_device *rdev); int trinity_dpm_set_power_state(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index d700698..ee0ce0a 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1121,6 +1121,28 @@ int trinity_dpm_enable(struct radeon_device *rdev) return 0; }
+int trinity_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + trinity_acquire_mutex(rdev); + trinity_enable_clock_power_gating(rdev); + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) { + trinity_release_mutex(rdev); + return ret; + } + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + } + trinity_release_mutex(rdev); + + return 0; +} + void trinity_dpm_disable(struct radeon_device *rdev) { trinity_acquire_mutex(rdev);
Make sure interrupts are enabled before we enable thermal interrupts.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + drivers/gpu/drm/radeon/si_dpm.c | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 2011a7e..23df62f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -1921,6 +1921,7 @@ static struct radeon_asic si_asic = { .init = &si_dpm_init, .setup_asic = &si_dpm_setup_asic, .enable = &si_dpm_enable, + .late_enable = &si_dpm_late_enable, .disable = &si_dpm_disable, .pre_set_power_state = &si_dpm_pre_set_power_state, .set_power_state = &si_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 597daec..9489ee3 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -673,6 +673,7 @@ int si_get_temp(struct radeon_device *rdev); int si_dpm_init(struct radeon_device *rdev); void si_dpm_setup_asic(struct radeon_device *rdev); int si_dpm_enable(struct radeon_device *rdev); +int si_dpm_late_enable(struct radeon_device *rdev); void si_dpm_disable(struct radeon_device *rdev); int si_dpm_pre_set_power_state(struct radeon_device *rdev); int si_dpm_set_power_state(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 2d0e94a..1c547b0 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -5912,6 +5912,28 @@ int si_dpm_enable(struct radeon_device *rdev) return 0; }
+int si_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + PPSMC_Result result; + + ret = si_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) + return ret; + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); + + if (result != PPSMC_Result_OK) + DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); + } + + return 0; +} + void si_dpm_disable(struct radeon_device *rdev) { struct rv7xx_power_info *pi = rv770_get_pi(rdev);
Make sure interrupts are enabled before we enable thermal interrupts. Also, don't powergate uvd until after the ring tests.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/ci_dpm.c | 29 +++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + 3 files changed, 31 insertions(+)
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index f891fc0..13ee5af 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -4685,6 +4685,35 @@ int ci_dpm_enable(struct radeon_device *rdev) return 0; }
+int ci_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { +#if 0 + PPSMC_Result result; +#endif + ret = ci_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) { + DRM_ERROR("ci_set_thermal_temperature_range failed\n"); + return ret; + } + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); +#if 0 + result = ci_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); + + if (result != PPSMC_Result_OK) + DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); +#endif + } + + ci_dpm_powergate_uvd(rdev, true); + + return 0; +} + void ci_dpm_disable(struct radeon_device *rdev) { struct ci_power_info *pi = ci_get_pi(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 23df62f..9c9a407 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2067,6 +2067,7 @@ static struct radeon_asic ci_asic = { .init = &ci_dpm_init, .setup_asic = &ci_dpm_setup_asic, .enable = &ci_dpm_enable, + .late_enable = &ci_dpm_late_enable, .disable = &ci_dpm_disable, .pre_set_power_state = &ci_dpm_pre_set_power_state, .set_power_state = &ci_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 9489ee3..095a4fa 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -755,6 +755,7 @@ int kv_get_temp(struct radeon_device *rdev);
int ci_dpm_init(struct radeon_device *rdev); int ci_dpm_enable(struct radeon_device *rdev); +int ci_dpm_late_enable(struct radeon_device *rdev); void ci_dpm_disable(struct radeon_device *rdev); int ci_dpm_pre_set_power_state(struct radeon_device *rdev); int ci_dpm_set_power_state(struct radeon_device *rdev);
Make sure interrupts are enabled before we enable thermal interrupts. Also, don't powergate uvd, etc. until after the ring tests.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/kv_dpm.c | 24 ++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 1 + 3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index a0e20eb..eced979 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -1238,6 +1238,30 @@ int kv_dpm_enable(struct radeon_device *rdev) return ret; }
+int kv_dpm_late_enable(struct radeon_device *rdev) +{ + int ret; + + if (rdev->irq.installed && + r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { + ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); + if (ret) { + DRM_ERROR("kv_set_thermal_temperature_range failed\n"); + return ret; + } + rdev->irq.dpm_thermal = true; + radeon_irq_set(rdev); + } + + /* powerdown unused blocks for now */ + kv_dpm_powergate_acp(rdev, true); + kv_dpm_powergate_samu(rdev, true); + kv_dpm_powergate_vce(rdev, true); + kv_dpm_powergate_uvd(rdev, true); + + return ret; +} + void kv_dpm_disable(struct radeon_device *rdev) { kv_smc_bapm_enable(rdev, false); diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 9c9a407..b8ef84c 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2169,6 +2169,7 @@ static struct radeon_asic kv_asic = { .init = &kv_dpm_init, .setup_asic = &kv_dpm_setup_asic, .enable = &kv_dpm_enable, + .late_enable = &kv_dpm_late_enable, .disable = &kv_dpm_disable, .pre_set_power_state = &kv_dpm_pre_set_power_state, .set_power_state = &kv_dpm_set_power_state, diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 095a4fa..cb5ca21 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -776,6 +776,7 @@ void ci_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
int kv_dpm_init(struct radeon_device *rdev); int kv_dpm_enable(struct radeon_device *rdev); +int kv_dpm_late_enable(struct radeon_device *rdev); void kv_dpm_disable(struct radeon_device *rdev); int kv_dpm_pre_set_power_state(struct radeon_device *rdev); int kv_dpm_set_power_state(struct radeon_device *rdev);
Right now it's called right after enable, but after reworking the dpm init order, it will get called later to accomodate loading the smc early, but enabling thermal interrupts and block powergating later after the ring tests are complete.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/btc_dpm.c | 15 ------- drivers/gpu/drm/radeon/ci_dpm.c | 21 --------- drivers/gpu/drm/radeon/cypress_dpm.c | 15 ------- drivers/gpu/drm/radeon/kv_dpm.c | 17 ------- drivers/gpu/drm/radeon/ni_dpm.c | 15 ------- drivers/gpu/drm/radeon/r600_dpm.c | 4 +- drivers/gpu/drm/radeon/r600_dpm.h | 2 - drivers/gpu/drm/radeon/radeon_pm.c | 87 ++++++++++++++++++++---------------- drivers/gpu/drm/radeon/rs780_dpm.c | 8 ---- drivers/gpu/drm/radeon/rv6xx_dpm.c | 10 ----- drivers/gpu/drm/radeon/rv770_dpm.c | 19 +------- drivers/gpu/drm/radeon/rv770_dpm.h | 4 -- drivers/gpu/drm/radeon/si_dpm.c | 15 ------- drivers/gpu/drm/radeon/sumo_dpm.c | 13 ------ drivers/gpu/drm/radeon/trinity_dpm.c | 13 ------ 15 files changed, 53 insertions(+), 205 deletions(-)
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 9b6950d..2eb985a 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -2510,21 +2510,6 @@ int btc_dpm_enable(struct radeon_device *rdev) if (eg_pi->ls_clock_gating) btc_ls_clock_gating_enable(rdev, true);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - PPSMC_Result result; - - ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); - } - rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
btc_init_stutter_mode(rdev); diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 13ee5af..6eab12d 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -4656,30 +4656,9 @@ int ci_dpm_enable(struct radeon_device *rdev) DRM_ERROR("ci_enable_power_containment failed\n"); return ret; } - if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { -#if 0 - PPSMC_Result result; -#endif - ret = ci_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) { - DRM_ERROR("ci_set_thermal_temperature_range failed\n"); - return ret; - } - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); -#if 0 - result = ci_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); -#endif - }
ci_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
- ci_dpm_powergate_uvd(rdev, true); - ci_update_current_ps(rdev, boot_ps);
return 0; diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 920e1e4..cf783fc 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -1905,21 +1905,6 @@ int cypress_dpm_enable(struct radeon_device *rdev) if (pi->mg_clock_gating) cypress_mg_clock_gating_enable(rdev, true);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - PPSMC_Result result; - - ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); - } - rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
return 0; diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index eced979..b6e01d5 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -1210,29 +1210,12 @@ int kv_dpm_enable(struct radeon_device *rdev)
kv_reset_acp_boot_level(rdev);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) { - DRM_ERROR("kv_set_thermal_temperature_range failed\n"); - return ret; - } - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - } - ret = kv_smc_bapm_enable(rdev, false); if (ret) { DRM_ERROR("kv_smc_bapm_enable failed\n"); return ret; }
- /* powerdown unused blocks for now */ - kv_dpm_powergate_acp(rdev, true); - kv_dpm_powergate_samu(rdev, true); - kv_dpm_powergate_vce(rdev, true); - kv_dpm_powergate_uvd(rdev, true); - kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
return ret; diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 49c4d48..cb92287 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -3710,21 +3710,6 @@ int ni_dpm_enable(struct radeon_device *rdev) if (eg_pi->ls_clock_gating) ni_ls_clockgating_enable(rdev, true);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - PPSMC_Result result; - - ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, 0xff * 1000); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); - } - rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
ni_update_current_ps(rdev, boot_ps); diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 12e35dd..e4cc9b3 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -729,8 +729,8 @@ bool r600_is_uvd_state(u32 class, u32 class2) return false; }
-int r600_set_thermal_temperature_range(struct radeon_device *rdev, - int min_temp, int max_temp) +static int r600_set_thermal_temperature_range(struct radeon_device *rdev, + int min_temp, int max_temp) { int low_temp = 0 * 1000; int high_temp = 255 * 1000; diff --git a/drivers/gpu/drm/radeon/r600_dpm.h b/drivers/gpu/drm/radeon/r600_dpm.h index 1000bf9..07eab2b 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.h +++ b/drivers/gpu/drm/radeon/r600_dpm.h @@ -213,8 +213,6 @@ void r600_wait_for_power_level(struct radeon_device *rdev, void r600_start_dpm(struct radeon_device *rdev); void r600_stop_dpm(struct radeon_device *rdev);
-int r600_set_thermal_temperature_range(struct radeon_device *rdev, - int min_temp, int max_temp); bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor);
int r600_parse_extended_power_table(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d4e5bcf..7fc76d1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1032,25 +1032,31 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev) radeon_dpm_setup_asic(rdev); ret = radeon_dpm_enable(rdev); mutex_unlock(&rdev->pm.mutex); - if (ret) { - DRM_ERROR("radeon: dpm resume failed\n"); - if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_CAYMAN) && - rdev->mc_fw) { - if (rdev->pm.default_vddc) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, - SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_vddci) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, - SET_VOLTAGE_TYPE_ASIC_VDDCI); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) - radeon_set_memory_clock(rdev, rdev->pm.default_mclk); - } - } else { - rdev->pm.dpm_enabled = true; - radeon_pm_compute_clocks(rdev); + if (ret) + goto dpm_resume_fail; + ret = radeon_pm_late_init(rdev); + if (ret) + goto dpm_resume_fail; + + rdev->pm.dpm_enabled = true; + radeon_pm_compute_clocks(rdev); + return; + +dpm_resume_fail: + DRM_ERROR("radeon: dpm resume failed\n"); + if ((rdev->family >= CHIP_BARTS) && + (rdev->family <= CHIP_CAYMAN) && + rdev->mc_fw) { + if (rdev->pm.default_vddc) + radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, + SET_VOLTAGE_TYPE_ASIC_VDDC); + if (rdev->pm.default_vddci) + radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, + SET_VOLTAGE_TYPE_ASIC_VDDCI); + if (rdev->pm.default_sclk) + radeon_set_engine_clock(rdev, rdev->pm.default_sclk); + if (rdev->pm.default_mclk) + radeon_set_memory_clock(rdev, rdev->pm.default_mclk); } }
@@ -1170,25 +1176,11 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) radeon_dpm_setup_asic(rdev); ret = radeon_dpm_enable(rdev); mutex_unlock(&rdev->pm.mutex); - if (ret) { - rdev->pm.dpm_enabled = false; - if ((rdev->family >= CHIP_BARTS) && - (rdev->family <= CHIP_CAYMAN) && - rdev->mc_fw) { - if (rdev->pm.default_vddc) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, - SET_VOLTAGE_TYPE_ASIC_VDDC); - if (rdev->pm.default_vddci) - radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, - SET_VOLTAGE_TYPE_ASIC_VDDCI); - if (rdev->pm.default_sclk) - radeon_set_engine_clock(rdev, rdev->pm.default_sclk); - if (rdev->pm.default_mclk) - radeon_set_memory_clock(rdev, rdev->pm.default_mclk); - } - DRM_ERROR("radeon: dpm initialization failed\n"); - return ret; - } + if (ret) + goto dpm_failed; + ret = radeon_pm_late_init(rdev); + if (ret) + goto dpm_failed; rdev->pm.dpm_enabled = true; radeon_pm_compute_clocks(rdev);
@@ -1213,6 +1205,25 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) DRM_INFO("radeon: dpm initialized\n");
return 0; + +dpm_failed: + rdev->pm.dpm_enabled = false; + if ((rdev->family >= CHIP_BARTS) && + (rdev->family <= CHIP_CAYMAN) && + rdev->mc_fw) { + if (rdev->pm.default_vddc) + radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, + SET_VOLTAGE_TYPE_ASIC_VDDC); + if (rdev->pm.default_vddci) + radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, + SET_VOLTAGE_TYPE_ASIC_VDDCI); + if (rdev->pm.default_sclk) + radeon_set_engine_clock(rdev, rdev->pm.default_sclk); + if (rdev->pm.default_mclk) + radeon_set_memory_clock(rdev, rdev->pm.default_mclk); + } + DRM_ERROR("radeon: dpm initialization failed\n"); + return ret; }
int radeon_pm_init(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c index 6af8505..8512085 100644 --- a/drivers/gpu/drm/radeon/rs780_dpm.c +++ b/drivers/gpu/drm/radeon/rs780_dpm.c @@ -623,14 +623,6 @@ int rs780_dpm_enable(struct radeon_device *rdev) if (pi->gfx_clock_gating) r600_gfx_clockgating_enable(rdev, true);
- if (rdev->irq.installed && (rdev->pm.int_thermal_type == THERMAL_TYPE_RV6XX)) { - ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - } - return 0; }
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index 26633a0..bebf31c 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c @@ -1546,7 +1546,6 @@ int rv6xx_dpm_enable(struct radeon_device *rdev) { struct rv6xx_power_info *pi = rv6xx_get_pi(rdev); struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; - int ret;
if (r600_dynamicpm_enabled(rdev)) return -EINVAL; @@ -1594,15 +1593,6 @@ int rv6xx_dpm_enable(struct radeon_device *rdev) r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, true); r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, true);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - } - rv6xx_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
r600_start_dpm(rdev); diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 5d6188f..b952678 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -1863,8 +1863,8 @@ void rv770_enable_auto_throttle_source(struct radeon_device *rdev, } }
-int rv770_set_thermal_temperature_range(struct radeon_device *rdev, - int min_temp, int max_temp) +static int rv770_set_thermal_temperature_range(struct radeon_device *rdev, + int min_temp, int max_temp) { int low_temp = 0 * 1000; int high_temp = 255 * 1000; @@ -1966,21 +1966,6 @@ int rv770_dpm_enable(struct radeon_device *rdev) if (pi->mg_clock_gating) rv770_mg_clock_gating_enable(rdev, true);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - PPSMC_Result result; - - ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); - } - rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
return 0; diff --git a/drivers/gpu/drm/radeon/rv770_dpm.h b/drivers/gpu/drm/radeon/rv770_dpm.h index 9244eff..f776634 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.h +++ b/drivers/gpu/drm/radeon/rv770_dpm.h @@ -283,8 +283,4 @@ int rv770_read_smc_soft_register(struct radeon_device *rdev, int rv770_write_smc_soft_register(struct radeon_device *rdev, u16 reg_offset, u32 value);
-/* thermal */ -int rv770_set_thermal_temperature_range(struct radeon_device *rdev, - int min_temp, int max_temp); - #endif diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 1c547b0..05cdd8d 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -5890,21 +5890,6 @@ int si_dpm_enable(struct radeon_device *rdev) si_enable_sclk_control(rdev, true); si_start_dpm(rdev);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - PPSMC_Result result; - - ret = si_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt); - - if (result != PPSMC_Result_OK) - DRM_DEBUG_KMS("Could not enable thermal interrupts.\n"); - } - si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
ni_update_current_ps(rdev, boot_ps); diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index b63640f..78d839f 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1202,14 +1202,10 @@ static void sumo_update_requested_ps(struct radeon_device *rdev, int sumo_dpm_enable(struct radeon_device *rdev) { struct sumo_power_info *pi = sumo_get_pi(rdev); - int ret;
if (sumo_dpm_enabled(rdev)) return -EINVAL;
- ret = sumo_enable_clock_power_gating(rdev); - if (ret) - return ret; sumo_program_bootup_state(rdev); sumo_init_bsp(rdev); sumo_reset_am(rdev); @@ -1233,15 +1229,6 @@ int sumo_dpm_enable(struct radeon_device *rdev) if (pi->enable_boost) sumo_enable_boost_timer(rdev);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) - return ret; - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - } - sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
return 0; diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index ee0ce0a..0f4d703 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1082,7 +1082,6 @@ void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable) int trinity_dpm_enable(struct radeon_device *rdev) { struct trinity_power_info *pi = trinity_get_pi(rdev); - int ret;
trinity_acquire_mutex(rdev);
@@ -1091,7 +1090,6 @@ int trinity_dpm_enable(struct radeon_device *rdev) return -EINVAL; }
- trinity_enable_clock_power_gating(rdev); trinity_program_bootup_state(rdev); sumo_program_vc(rdev, 0x00C00033); trinity_start_am(rdev); @@ -1105,17 +1103,6 @@ int trinity_dpm_enable(struct radeon_device *rdev) trinity_dpm_bapm_enable(rdev, false); trinity_release_mutex(rdev);
- if (rdev->irq.installed && - r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { - ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX); - if (ret) { - trinity_release_mutex(rdev); - return ret; - } - rdev->irq.dpm_thermal = true; - radeon_irq_set(rdev); - } - trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
return 0;
We need more control over the ordering of dpm init with respect to the rest of the asic. Specifically, the SMC has to be initialized before the rlc and cg/pg. The pm code currently initializes late in the driver, but we need it to happen much earlier so move pm handling into the asic specific callbacks.
This makes dpm more reliable and makes clockgating work properly on CIK parts and should help on SI parts as well.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/btc_dpm.c | 5 +++++ drivers/gpu/drm/radeon/ci_dpm.c | 6 ++++++ drivers/gpu/drm/radeon/cik.c | 11 +++++++++-- drivers/gpu/drm/radeon/evergreen.c | 9 ++++++++- drivers/gpu/drm/radeon/ni.c | 9 ++++++++- drivers/gpu/drm/radeon/ni_dpm.c | 6 ++++++ drivers/gpu/drm/radeon/r100.c | 7 +++++++ drivers/gpu/drm/radeon/r300.c | 7 +++++++ drivers/gpu/drm/radeon/r420.c | 7 +++++++ drivers/gpu/drm/radeon/r520.c | 5 +++++ drivers/gpu/drm/radeon/r600.c | 7 +++++++ drivers/gpu/drm/radeon/radeon_device.c | 14 +++++++++++--- drivers/gpu/drm/radeon/radeon_display.c | 17 +++++++++++++---- drivers/gpu/drm/radeon/radeon_pm.c | 11 +++-------- drivers/gpu/drm/radeon/rs400.c | 7 +++++++ drivers/gpu/drm/radeon/rs600.c | 7 +++++++ drivers/gpu/drm/radeon/rs690.c | 7 +++++++ drivers/gpu/drm/radeon/rv515.c | 7 +++++++ drivers/gpu/drm/radeon/rv770.c | 7 +++++++ drivers/gpu/drm/radeon/si.c | 19 ++++++++++++++----- drivers/gpu/drm/radeon/si_dpm.c | 7 +++++++ 21 files changed, 158 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 2eb985a..0fbd36f 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -49,6 +49,7 @@ struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps); struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+extern int ni_mc_load_microcode(struct radeon_device *rdev);
//********* BARTS **************// static const u32 barts_cgcg_cgls_default[] = @@ -2561,7 +2562,11 @@ void btc_dpm_disable(struct radeon_device *rdev) void btc_dpm_setup_asic(struct radeon_device *rdev) { struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + int r;
+ r = ni_mc_load_microcode(rdev); + if (r) + DRM_ERROR("Failed to load MC firmware!\n"); rv770_get_memory_type(rdev); rv740_read_clock_registers(rdev); btc_read_arb_registers(rdev); diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 6eab12d..a3c4711 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -171,6 +171,7 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, struct atom_voltage_table *voltage_table); extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev); extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev); +extern int ci_mc_load_microcode(struct radeon_device *rdev);
static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev, struct atom_voltage_table_entry *voltage_table, @@ -4547,6 +4548,11 @@ void ci_dpm_post_set_power_state(struct radeon_device *rdev)
void ci_dpm_setup_asic(struct radeon_device *rdev) { + int r; + + r = ci_mc_load_microcode(rdev); + if (r) + DRM_ERROR("Failed to load MC firmware!\n"); ci_read_clock_registers(rdev); ci_get_memory_type(rdev); ci_enable_acpi_power_management(rdev); diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 4ddc3e5..25a6ef6 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -1697,7 +1697,7 @@ static void cik_srbm_select(struct radeon_device *rdev, * Load the GDDR MC ucode into the hw (CIK). * Returns 0 on success, error on failure. */ -static int ci_mc_load_microcode(struct radeon_device *rdev) +int ci_mc_load_microcode(struct radeon_device *rdev) { const __be32 *fw_data; u32 running, blackout = 0; @@ -7501,7 +7501,7 @@ static int cik_startup(struct radeon_device *rdev)
cik_mc_program(rdev);
- if (!(rdev->flags & RADEON_IS_IGP)) { + if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) { r = ci_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -7710,6 +7710,8 @@ int cik_resume(struct radeon_device *rdev) /* init golden registers */ cik_init_golden_registers(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = cik_startup(rdev); if (r) { @@ -7733,6 +7735,7 @@ int cik_resume(struct radeon_device *rdev) */ int cik_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); dce6_audio_fini(rdev); radeon_vm_manager_fini(rdev); cik_cp_enable(rdev, false); @@ -7835,6 +7838,9 @@ int cik_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); @@ -7915,6 +7921,7 @@ int cik_init(struct radeon_device *rdev) */ void cik_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); cik_cp_fini(rdev); cik_sdma_fini(rdev); cik_fini_pg(rdev); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4abf8b6..594a3d7 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -5109,7 +5109,7 @@ static int evergreen_startup(struct radeon_device *rdev)
evergreen_mc_program(rdev);
- if (ASIC_IS_DCE5(rdev)) { + if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) { r = ni_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -5252,6 +5252,8 @@ int evergreen_resume(struct radeon_device *rdev) /* init golden registers */ evergreen_init_golden_registers(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = evergreen_startup(rdev); if (r) { @@ -5266,6 +5268,7 @@ int evergreen_resume(struct radeon_device *rdev)
int evergreen_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r600_audio_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); @@ -5360,6 +5363,9 @@ int evergreen_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
@@ -5412,6 +5418,7 @@ int evergreen_init(struct radeon_device *rdev)
void evergreen_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r700_cp_fini(rdev); r600_dma_fini(rdev); diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 757141a..494ba00 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1866,7 +1866,7 @@ static int cayman_startup(struct radeon_device *rdev)
evergreen_mc_program(rdev);
- if (!(rdev->flags & RADEON_IS_IGP)) { + if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) { r = ni_mc_load_microcode(rdev); if (r) { DRM_ERROR("Failed to load MC firmware!\n"); @@ -2035,6 +2035,8 @@ int cayman_resume(struct radeon_device *rdev) /* init golden registers */ ni_init_golden_registers(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = cayman_startup(rdev); if (r) { @@ -2047,6 +2049,7 @@ int cayman_resume(struct radeon_device *rdev)
int cayman_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); if (ASIC_IS_DCE6(rdev)) dce6_audio_fini(rdev); else @@ -2135,6 +2138,9 @@ int cayman_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024);
@@ -2194,6 +2200,7 @@ int cayman_init(struct radeon_device *rdev)
void cayman_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); cayman_cp_fini(rdev); cayman_dma_fini(rdev); r600_irq_fini(rdev); diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index cb92287..c351226 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -720,6 +720,8 @@ static const u32 cayman_sysls_enable[] = struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev); struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+extern int ni_mc_load_microcode(struct radeon_device *rdev); + struct ni_power_info *ni_get_pi(struct radeon_device *rdev) { struct ni_power_info *pi = rdev->pm.dpm.priv; @@ -3565,7 +3567,11 @@ void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev, void ni_dpm_setup_asic(struct radeon_device *rdev) { struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); + int r;
+ r = ni_mc_load_microcode(rdev); + if (r) + DRM_ERROR("Failed to load MC firmware!\n"); ni_read_clock_registers(rdev); btc_read_arb_registers(rdev); rv770_get_memory_type(rdev); diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 10abc4d..526d2aa 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3913,6 +3913,8 @@ int r100_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = r100_startup(rdev); if (r) { @@ -3923,6 +3925,7 @@ int r100_resume(struct radeon_device *rdev)
int r100_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -3933,6 +3936,7 @@ int r100_suspend(struct radeon_device *rdev)
void r100_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); @@ -4039,6 +4043,9 @@ int r100_init(struct radeon_device *rdev) } r100_set_safe_registers(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = r100_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index d8dd269..7c63ef8 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1430,6 +1430,8 @@ int r300_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = r300_startup(rdev); if (r) { @@ -1440,6 +1442,7 @@ int r300_resume(struct radeon_device *rdev)
int r300_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -1452,6 +1455,7 @@ int r300_suspend(struct radeon_device *rdev)
void r300_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); @@ -1538,6 +1542,9 @@ int r300_init(struct radeon_device *rdev) } r300_set_reg_safe(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = r300_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index 6edf2b3..3768aab 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -325,6 +325,8 @@ int r420_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = r420_startup(rdev); if (r) { @@ -335,6 +337,7 @@ int r420_resume(struct radeon_device *rdev)
int r420_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r420_cp_errata_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -348,6 +351,7 @@ int r420_suspend(struct radeon_device *rdev)
void r420_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); @@ -444,6 +448,9 @@ int r420_init(struct radeon_device *rdev) } r420_set_reg_safe(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = r420_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index e1aece7..e209eb7 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -240,6 +240,8 @@ int r520_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = r520_startup(rdev); if (r) { @@ -312,6 +314,9 @@ int r520_init(struct radeon_device *rdev) return r; rv515_set_safe_registers(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = r520_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 09e83f2..d05611a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2881,6 +2881,8 @@ int r600_resume(struct radeon_device *rdev) /* post card */ atom_asic_init(rdev->mode_info.atom_context);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = r600_startup(rdev); if (r) { @@ -2894,6 +2896,7 @@ int r600_resume(struct radeon_device *rdev)
int r600_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r600_audio_fini(rdev); r600_cp_stop(rdev); r600_dma_stop(rdev); @@ -2970,6 +2973,9 @@ int r600_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
@@ -3002,6 +3008,7 @@ int r600_init(struct radeon_device *rdev)
void r600_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r600_cp_fini(rdev); r600_dma_fini(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 39b033b..5f0ff43 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1330,6 +1330,7 @@ int radeon_device_init(struct radeon_device *rdev, if (r) return r; } + if ((radeon_testing & 1)) { if (rdev->accel_working) radeon_test_moves(rdev); @@ -1455,7 +1456,6 @@ int radeon_suspend_kms(struct drm_device *dev, bool suspend, bool fbcon)
radeon_save_bios_scratch_regs(rdev);
- radeon_pm_suspend(rdev); radeon_suspend(rdev); radeon_hpd_fini(rdev); /* evict remaining vram memory */ @@ -1516,14 +1516,22 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) if (r) DRM_ERROR("ib ring test failed (%d).\n", r);
- radeon_pm_resume(rdev); + if (rdev->pm.dpm_enabled) { + /* do dpm late init */ + r = radeon_pm_late_init(rdev); + if (r) { + rdev->pm.dpm_enabled = false; + DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); + } + } + radeon_restore_bios_scratch_regs(rdev);
if (fbcon) { radeon_fbdev_set_suspend(rdev, 0); console_unlock(); } - + /* init dig PHYs, disp eng pll */ if (rdev->is_atom_bios) { radeon_atom_encoder_init(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7b25381..7ea647b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1464,12 +1464,22 @@ int radeon_modeset_init(struct radeon_device *rdev) /* setup afmt */ radeon_afmt_init(rdev);
- /* Initialize power management */ - radeon_pm_init(rdev); - radeon_fbdev_init(rdev); drm_kms_helper_poll_init(rdev->ddev);
+ if (rdev->pm.dpm_enabled) { + /* do dpm late init */ + ret = radeon_pm_late_init(rdev); + if (ret) { + rdev->pm.dpm_enabled = false; + DRM_ERROR("radeon_pm_late_init failed, disabling dpm\n"); + } + /* set the dpm state for PX since there won't be + * a modeset to call this. + */ + radeon_pm_compute_clocks(rdev); + } + return 0; }
@@ -1477,7 +1487,6 @@ void radeon_modeset_fini(struct radeon_device *rdev) { radeon_fbdev_fini(rdev); kfree(rdev->mode_info.bios_hardcoded_edid); - radeon_pm_fini(rdev);
if (rdev->mode_info.mode_config_initialized) { radeon_afmt_fini(rdev); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 7fc76d1..933ada0 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1034,10 +1034,6 @@ static void radeon_pm_resume_dpm(struct radeon_device *rdev) mutex_unlock(&rdev->pm.mutex); if (ret) goto dpm_resume_fail; - ret = radeon_pm_late_init(rdev); - if (ret) - goto dpm_resume_fail; - rdev->pm.dpm_enabled = true; radeon_pm_compute_clocks(rdev); return; @@ -1178,11 +1174,7 @@ static int radeon_pm_init_dpm(struct radeon_device *rdev) mutex_unlock(&rdev->pm.mutex); if (ret) goto dpm_failed; - ret = radeon_pm_late_init(rdev); - if (ret) - goto dpm_failed; rdev->pm.dpm_enabled = true; - radeon_pm_compute_clocks(rdev);
ret = device_create_file(rdev->dev, &dev_attr_power_dpm_state); if (ret) @@ -1441,6 +1433,9 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev) struct drm_crtc *crtc; struct radeon_crtc *radeon_crtc;
+ if (!rdev->pm.dpm_enabled) + return; + mutex_lock(&rdev->pm.mutex);
/* update active crtc counts */ diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 9566b59..b5c2369 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -474,6 +474,8 @@ int rs400_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = rs400_startup(rdev); if (r) { @@ -484,6 +486,7 @@ int rs400_resume(struct radeon_device *rdev)
int rs400_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); r100_irq_disable(rdev); @@ -493,6 +496,7 @@ int rs400_suspend(struct radeon_device *rdev)
void rs400_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); @@ -560,6 +564,9 @@ int rs400_init(struct radeon_device *rdev) return r; r300_set_reg_safe(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = rs400_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 76cc8d3..fdcde76 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -1048,6 +1048,8 @@ int rs600_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = rs600_startup(rdev); if (r) { @@ -1058,6 +1060,7 @@ int rs600_resume(struct radeon_device *rdev)
int rs600_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r600_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -1068,6 +1071,7 @@ int rs600_suspend(struct radeon_device *rdev)
void rs600_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); @@ -1136,6 +1140,9 @@ int rs600_init(struct radeon_device *rdev) return r; rs600_set_safe_registers(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = rs600_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index e7dab06..3595073 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -756,6 +756,8 @@ int rs690_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = rs690_startup(rdev); if (r) { @@ -766,6 +768,7 @@ int rs690_resume(struct radeon_device *rdev)
int rs690_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r600_audio_fini(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); @@ -776,6 +779,7 @@ int rs690_suspend(struct radeon_device *rdev)
void rs690_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r600_audio_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); @@ -845,6 +849,9 @@ int rs690_init(struct radeon_device *rdev) return r; rs600_set_safe_registers(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = rs690_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 5d1c316..98e8138 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -586,6 +586,8 @@ int rv515_resume(struct radeon_device *rdev) /* Initialize surface registers */ radeon_surface_init(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = rv515_startup(rdev); if (r) { @@ -596,6 +598,7 @@ int rv515_resume(struct radeon_device *rdev)
int rv515_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r100_cp_disable(rdev); radeon_wb_disable(rdev); rs600_irq_disable(rdev); @@ -612,6 +615,7 @@ void rv515_set_safe_registers(struct radeon_device *rdev)
void rv515_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r100_cp_fini(rdev); radeon_wb_fini(rdev); radeon_ib_pool_fini(rdev); @@ -685,6 +689,9 @@ int rv515_init(struct radeon_device *rdev) return r; rv515_set_safe_registers(rdev);
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->accel_working = true; r = rv515_startup(rdev); if (r) { diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 45774ff..82a6d44 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1784,6 +1784,8 @@ int rv770_resume(struct radeon_device *rdev) /* init golden registers */ rv770_init_golden_registers(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = rv770_startup(rdev); if (r) { @@ -1798,6 +1800,7 @@ int rv770_resume(struct radeon_device *rdev)
int rv770_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); r600_audio_fini(rdev); uvd_v1_0_fini(rdev); radeon_uvd_suspend(rdev); @@ -1876,6 +1879,9 @@ int rv770_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
@@ -1915,6 +1921,7 @@ int rv770_init(struct radeon_device *rdev)
void rv770_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); r700_cp_fini(rdev); r600_dma_fini(rdev); r600_irq_fini(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 1df4631..7619bc6 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -1460,7 +1460,7 @@ static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = { };
/* ucode loading */ -static int si_mc_load_microcode(struct radeon_device *rdev) +int si_mc_load_microcode(struct radeon_device *rdev) { const __be32 *fw_data; u32 running, blackout = 0; @@ -6322,10 +6322,12 @@ static int si_startup(struct radeon_device *rdev)
si_mc_program(rdev);
- r = si_mc_load_microcode(rdev); - if (r) { - DRM_ERROR("Failed to load MC firmware!\n"); - return r; + if (!rdev->pm.dpm_enabled) { + r = si_mc_load_microcode(rdev); + if (r) { + DRM_ERROR("Failed to load MC firmware!\n"); + return r; + } }
r = si_pcie_gart_enable(rdev); @@ -6502,6 +6504,8 @@ int si_resume(struct radeon_device *rdev) /* init golden registers */ si_init_golden_registers(rdev);
+ radeon_pm_resume(rdev); + rdev->accel_working = true; r = si_startup(rdev); if (r) { @@ -6516,6 +6520,7 @@ int si_resume(struct radeon_device *rdev)
int si_suspend(struct radeon_device *rdev) { + radeon_pm_suspend(rdev); dce6_audio_fini(rdev); radeon_vm_manager_fini(rdev); si_cp_enable(rdev, false); @@ -6598,6 +6603,9 @@ int si_init(struct radeon_device *rdev) } }
+ /* Initialize power management */ + radeon_pm_init(rdev); + ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; ring->ring_obj = NULL; r600_ring_init(rdev, ring, 1024 * 1024); @@ -6664,6 +6672,7 @@ int si_init(struct radeon_device *rdev)
void si_fini(struct radeon_device *rdev) { + radeon_pm_fini(rdev); si_cp_fini(rdev); cayman_dma_fini(rdev); si_fini_pg(rdev); diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 05cdd8d..512919b 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -1738,6 +1738,8 @@ struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev); struct ni_power_info *ni_get_pi(struct radeon_device *rdev); struct ni_ps *ni_get_ps(struct radeon_ps *rps);
+extern int si_mc_load_microcode(struct radeon_device *rdev); + static int si_populate_voltage_value(struct radeon_device *rdev, const struct atom_voltage_table *table, u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage); @@ -5751,6 +5753,11 @@ static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,
void si_dpm_setup_asic(struct radeon_device *rdev) { + int r; + + r = si_mc_load_microcode(rdev); + if (r) + DRM_ERROR("Failed to load MC firmware!\n"); rv770_get_memory_type(rdev); si_read_clock_registers(rdev); si_enable_acpi_power_management(rdev);
Enable coarse grained clockgating on CIK dGPUs. This works properly now that smc is initialized earlier than the rlc and cp.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index b8ef84c..e7ad54f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2460,7 +2460,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->cg_flags = RADEON_CG_SUPPORT_GFX_MGCG | RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGCG | RADEON_CG_SUPPORT_GFX_CGLS | RADEON_CG_SUPPORT_GFX_CGTS | RADEON_CG_SUPPORT_GFX_CGTS_LS | @@ -2479,7 +2479,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->cg_flags = RADEON_CG_SUPPORT_GFX_MGCG | RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGCG | RADEON_CG_SUPPORT_GFX_CGLS | RADEON_CG_SUPPORT_GFX_CGTS | RADEON_CG_SUPPORT_GFX_CP_LS |
Enable coarse grained clockgating. This works properly now that smc is initialized earlier than the rlc and cp.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_asic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index e7ad54f..534aae0 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2504,7 +2504,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->cg_flags = RADEON_CG_SUPPORT_GFX_MGCG | RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGCG | RADEON_CG_SUPPORT_GFX_CGLS | RADEON_CG_SUPPORT_GFX_CGTS | RADEON_CG_SUPPORT_GFX_CGTS_LS | @@ -2532,7 +2532,7 @@ int radeon_asic_init(struct radeon_device *rdev) rdev->cg_flags = RADEON_CG_SUPPORT_GFX_MGCG | RADEON_CG_SUPPORT_GFX_MGLS | - /*RADEON_CG_SUPPORT_GFX_CGCG |*/ + RADEON_CG_SUPPORT_GFX_CGCG | RADEON_CG_SUPPORT_GFX_CGLS | RADEON_CG_SUPPORT_GFX_CGTS | RADEON_CG_SUPPORT_GFX_CGTS_LS |
Dynamic power mangement works reliably now, so enable it by default.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 933ada0..422afc1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1230,10 +1230,8 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_RS780: case CHIP_RS880: case CHIP_CAYMAN: - case CHIP_BONAIRE: case CHIP_KABINI: case CHIP_KAVERI: - case CHIP_HAWAII: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE; @@ -1267,6 +1265,8 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_VERDE: case CHIP_OLAND: case CHIP_HAINAN: + case CHIP_BONAIRE: + case CHIP_HAWAII: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE;
Dynamic power mangement works reliably now, so enable it by default.
Signed-off-by: Alex Deucher alexander.deucher@amd.com --- drivers/gpu/drm/radeon/radeon_pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 422afc1..c0ff200 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1230,8 +1230,6 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_RS780: case CHIP_RS880: case CHIP_CAYMAN: - case CHIP_KABINI: - case CHIP_KAVERI: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw) rdev->pm.pm_method = PM_METHOD_PROFILE; @@ -1266,6 +1264,8 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_OLAND: case CHIP_HAINAN: case CHIP_BONAIRE: + case CHIP_KABINI: + case CHIP_KAVERI: case CHIP_HAWAII: /* DPM requires the RLC, RV770+ dGPU requires SMC */ if (!rdev->rlc_fw)
dri-devel@lists.freedesktop.org