drm/radeon/dpm: handle bapm on trinity
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 9 Sep 2013 22:56:50 +0000 (18:56 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 11 Sep 2013 15:44:37 +0000 (11:44 -0400)
bapm is a power management feature for handling the
power budget between the CPU and GPU on APUs.  This
patch adds support for enabling or disabling it.
For now disable it by default.  Enabling it properly
requires quite a bit more work and will be addressed
in a separate patch.

This patch fixes hangs on boot on certain trinity
laptops when the system is on battery power.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
drivers/gpu/drm/radeon/ppsmc.h
drivers/gpu/drm/radeon/trinity_dpm.c
drivers/gpu/drm/radeon/trinity_dpm.h
drivers/gpu/drm/radeon/trinity_smc.c

index 682842804bce3e47ffe5d961a0125747f132d6e1..5670b8291285d6827e87abd7a66b447ee774d315 100644 (file)
@@ -163,6 +163,8 @@ typedef uint8_t PPSMC_Result;
 #define PPSMC_MSG_VCEPowerON                ((uint32_t) 0x10f)
 #define PPSMC_MSG_DCE_RemoveVoltageAdjustment   ((uint32_t) 0x11d)
 #define PPSMC_MSG_DCE_AllowVoltageAdjustment    ((uint32_t) 0x11e)
+#define PPSMC_MSG_EnableBAPM                ((uint32_t) 0x120)
+#define PPSMC_MSG_DisableBAPM               ((uint32_t) 0x121)
 #define PPSMC_MSG_UVD_DPM_Config            ((uint32_t) 0x124)
 
 
index b07b7b8f1aff4523bfe955a0beddbc041efb9164..b1b5b3f5e07be079d9a0e7ecd090d9ceca33fd87 100644 (file)
@@ -1091,6 +1091,7 @@ int trinity_dpm_enable(struct radeon_device *rdev)
        trinity_program_sclk_dpm(rdev);
        trinity_start_dpm(rdev);
        trinity_wait_for_dpm_enabled(rdev);
+       trinity_dpm_bapm_enable(rdev, false);
        trinity_release_mutex(rdev);
 
        if (rdev->irq.installed &&
@@ -1116,6 +1117,7 @@ void trinity_dpm_disable(struct radeon_device *rdev)
                trinity_release_mutex(rdev);
                return;
        }
+       trinity_dpm_bapm_enable(rdev, false);
        trinity_disable_clock_power_gating(rdev);
        sumo_clear_vc(rdev);
        trinity_wait_for_level_0(rdev);
index e82df071f8b3e5e6f64265f150aa3c1fffb90b5a..259d9e817c962c72a90acd0a11052b014832a212 100644 (file)
@@ -118,6 +118,7 @@ struct trinity_power_info {
 #define TRINITY_AT_DFLT            30
 
 /* trinity_smc.c */
+int trinity_dpm_bapm_enable(struct radeon_device *rdev, bool enable);
 int trinity_dpm_config(struct radeon_device *rdev, bool enable);
 int trinity_uvd_dpm_config(struct radeon_device *rdev);
 int trinity_dpm_force_state(struct radeon_device *rdev, u32 n);
index a42d89f1830cce2ae6611163601755c9de5243d6..9672bcbc7312218a357f07ae54393ed511284279 100644 (file)
@@ -56,6 +56,14 @@ static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
        return 0;
 }
 
+int trinity_dpm_bapm_enable(struct radeon_device *rdev, bool enable)
+{
+       if (enable)
+               return trinity_notify_message_to_smu(rdev, PPSMC_MSG_EnableBAPM);
+       else
+               return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DisableBAPM);
+}
+
 int trinity_dpm_config(struct radeon_device *rdev, bool enable)
 {
        if (enable)