diff options
author | Dave Airlie <airlied@redhat.com> | 2013-09-02 03:31:40 +0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-09-02 03:31:40 +0400 |
commit | 9c725e5bcdae59d5383d4aec33a34c822582dda5 (patch) | |
tree | 3d55827f5f44f16cb0aada2713029f7490f557d4 /drivers/gpu/drm/radeon/radeon_pm.c | |
parent | efa27f9cec09518c9b574e3ab4a0a41717237429 (diff) | |
parent | 679fe80fbe964ea7f9f71781c2ca65b630949da3 (diff) | |
download | linux-9c725e5bcdae59d5383d4aec33a34c822582dda5.tar.xz |
Merge branch 'drm-next-3.12' of git://people.freedesktop.org/~agd5f/linux into drm-next
Alex writes:
This is the radeon drm-next request. Big changes include:
- support for dpm on CIK parts
- support for ASPM on CIK parts
- support for berlin GPUs
- major ring handling cleanup
- remove the old 3D blit code for bo moves in favor of CP DMA or sDMA
- lots of bug fixes
[airlied: fix up a bunch of conflicts from drm_order removal]
* 'drm-next-3.12' of git://people.freedesktop.org/~agd5f/linux: (898 commits)
drm/radeon/dpm: make sure dc performance level limits are valid (CI)
drm/radeon/dpm: make sure dc performance level limits are valid (BTC-SI) (v2)
drm/radeon: gcc fixes for extended dpm tables
drm/radeon: gcc fixes for kb/kv dpm
drm/radeon: gcc fixes for ci dpm
drm/radeon: gcc fixes for si dpm
drm/radeon: gcc fixes for ni dpm
drm/radeon: gcc fixes for trinity dpm
drm/radeon: gcc fixes for sumo dpm
drm/radeonn: gcc fixes for rv7xx/eg/btc dpm
drm/radeon: gcc fixes for rv6xx dpm
drm/radeon: gcc fixes for radeon_atombios.c
drm/radeon: enable UVD interrupts on CIK
drm/radeon: fix init ordering for r600+
drm/radeon/dpm: only need to reprogram uvd if uvd pg is enabled
drm/radeon: check the return value of uvd_v1_0_start in uvd_v1_0_init
drm/radeon: split out radeon_uvd_resume from uvd_v4_2_resume
radeon kms: fix uninitialised hotplug work usage in r100_irq_process()
drm/radeon/audio: set up the sads on DCE3.2 asics
drm/radeon: fix handling of variable sized arrays for router objects
...
Conflicts:
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_gem_dmabuf.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/radeon/cik.c
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/r600.c
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_pm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_pm.c | 97 |
1 files changed, 70 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index f374c467aaca..d7555369a3e5 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -569,6 +569,8 @@ static int radeon_hwmon_init(struct radeon_device *rdev) case THERMAL_TYPE_NI: case THERMAL_TYPE_SUMO: case THERMAL_TYPE_SI: + case THERMAL_TYPE_CI: + case THERMAL_TYPE_KV: if (rdev->asic->pm.get_temperature == NULL) return err; rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); @@ -624,7 +626,15 @@ static void radeon_dpm_thermal_work_handler(struct work_struct *work) /* switch back the user state */ dpm_state = rdev->pm.dpm.user_state; } - radeon_dpm_enable_power_state(rdev, dpm_state); + mutex_lock(&rdev->pm.mutex); + if (dpm_state == POWER_STATE_TYPE_INTERNAL_THERMAL) + rdev->pm.dpm.thermal_active = true; + else + rdev->pm.dpm.thermal_active = false; + rdev->pm.dpm.state = dpm_state; + mutex_unlock(&rdev->pm.mutex); + + radeon_pm_compute_clocks(rdev); } static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev, @@ -687,7 +697,10 @@ restart_search: break; /* internal states */ case POWER_STATE_TYPE_INTERNAL_UVD: - return rdev->pm.dpm.uvd_ps; + if (rdev->pm.dpm.uvd_ps) + return rdev->pm.dpm.uvd_ps; + else + break; case POWER_STATE_TYPE_INTERNAL_UVD_SD: if (ps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) return ps; @@ -729,10 +742,17 @@ restart_search: /* use a fallback state if we didn't match */ switch (dpm_state) { case POWER_STATE_TYPE_INTERNAL_UVD_SD: + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD; + goto restart_search; case POWER_STATE_TYPE_INTERNAL_UVD_HD: case POWER_STATE_TYPE_INTERNAL_UVD_HD2: case POWER_STATE_TYPE_INTERNAL_UVD_MVC: - return rdev->pm.dpm.uvd_ps; + if (rdev->pm.dpm.uvd_ps) { + return rdev->pm.dpm.uvd_ps; + } else { + dpm_state = POWER_STATE_TYPE_PERFORMANCE; + goto restart_search; + } case POWER_STATE_TYPE_INTERNAL_THERMAL: dpm_state = POWER_STATE_TYPE_INTERNAL_ACPI; goto restart_search; @@ -850,38 +870,51 @@ static void radeon_dpm_change_power_state_locked(struct radeon_device *rdev) radeon_dpm_post_set_power_state(rdev); + /* force low perf level for thermal */ + if (rdev->pm.dpm.thermal_active && + rdev->asic->dpm.force_performance_level) { + radeon_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_LOW); + } + done: mutex_unlock(&rdev->ring_lock); up_write(&rdev->pm.mclk_lock); mutex_unlock(&rdev->ddev->struct_mutex); } -void radeon_dpm_enable_power_state(struct radeon_device *rdev, - enum radeon_pm_state_type dpm_state) +void radeon_dpm_enable_uvd(struct radeon_device *rdev, bool enable) { - if (!rdev->pm.dpm_enabled) - return; + enum radeon_pm_state_type dpm_state; - mutex_lock(&rdev->pm.mutex); - switch (dpm_state) { - case POWER_STATE_TYPE_INTERNAL_THERMAL: - rdev->pm.dpm.thermal_active = true; - break; - case POWER_STATE_TYPE_INTERNAL_UVD: - case POWER_STATE_TYPE_INTERNAL_UVD_SD: - case POWER_STATE_TYPE_INTERNAL_UVD_HD: - case POWER_STATE_TYPE_INTERNAL_UVD_HD2: - case POWER_STATE_TYPE_INTERNAL_UVD_MVC: - rdev->pm.dpm.uvd_active = true; - break; - default: - rdev->pm.dpm.thermal_active = false; - rdev->pm.dpm.uvd_active = false; - break; + if (rdev->asic->dpm.powergate_uvd) { + mutex_lock(&rdev->pm.mutex); + /* enable/disable UVD */ + radeon_dpm_powergate_uvd(rdev, !enable); + mutex_unlock(&rdev->pm.mutex); + } else { + if (enable) { + mutex_lock(&rdev->pm.mutex); + rdev->pm.dpm.uvd_active = true; + if ((rdev->pm.dpm.sd == 1) && (rdev->pm.dpm.hd == 0)) + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_SD; + else if ((rdev->pm.dpm.sd == 2) && (rdev->pm.dpm.hd == 0)) + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD; + else if ((rdev->pm.dpm.sd == 0) && (rdev->pm.dpm.hd == 1)) + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD; + else if ((rdev->pm.dpm.sd == 0) && (rdev->pm.dpm.hd == 2)) + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD2; + else + dpm_state = POWER_STATE_TYPE_INTERNAL_UVD; + rdev->pm.dpm.state = dpm_state; + mutex_unlock(&rdev->pm.mutex); + } else { + mutex_lock(&rdev->pm.mutex); + rdev->pm.dpm.uvd_active = false; + mutex_unlock(&rdev->pm.mutex); + } + + radeon_pm_compute_clocks(rdev); } - rdev->pm.dpm.state = dpm_state; - mutex_unlock(&rdev->pm.mutex); - radeon_pm_compute_clocks(rdev); } static void radeon_pm_suspend_old(struct radeon_device *rdev) @@ -1176,7 +1209,17 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_VERDE: case CHIP_OLAND: case CHIP_HAINAN: - if (radeon_dpm == 1) + case CHIP_BONAIRE: + 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; + else if ((rdev->family >= CHIP_RV770) && + (!(rdev->flags & RADEON_IS_IGP)) && + (!rdev->smc_fw)) + rdev->pm.pm_method = PM_METHOD_PROFILE; + else if (radeon_dpm == 1) rdev->pm.pm_method = PM_METHOD_DPM; else rdev->pm.pm_method = PM_METHOD_PROFILE; |