]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/gpu/drm/amd/powerplay/amd_powerplay.c
Merge remote-tracking branches 'asoc/topic/samsung', 'asoc/topic/sgtl5000', 'asoc...
[linux.git] / drivers / gpu / drm / amd / powerplay / amd_powerplay.c
index 9d2290044708d7f2119c702ddc45d15c77b6b808..e629f8a9fe936be12cb587b921675363ae425cd7 100644 (file)
                        return -EINVAL;                                 \
        } while (0)
 
+#define PP_CHECK_HW(hwmgr)                                             \
+       do {                                                            \
+               if ((hwmgr) == NULL || (hwmgr)->hwmgr_func == NULL)     \
+                       return -EINVAL;                                 \
+       } while (0)
+
 static int pp_early_init(void *handle)
 {
        return 0;
@@ -54,22 +60,29 @@ static int pp_sw_init(void *handle)
        pp_handle = (struct pp_instance *)handle;
        hwmgr = pp_handle->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->pptable_func == NULL ||
-           hwmgr->hwmgr_func == NULL ||
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->pptable_func == NULL ||
            hwmgr->pptable_func->pptable_init == NULL ||
            hwmgr->hwmgr_func->backend_init == NULL)
                return -EINVAL;
 
        ret = hwmgr->pptable_func->pptable_init(hwmgr);
+       if (ret)
+               goto err;
 
-       if (ret == 0)
-               ret = hwmgr->hwmgr_func->backend_init(hwmgr);
-
+       ret = hwmgr->hwmgr_func->backend_init(hwmgr);
        if (ret)
-               printk("amdgpu: powerplay initialization failed\n");
-       else
-               printk("amdgpu: powerplay initialized\n");
+               goto err1;
+
+       pr_info("amdgpu: powerplay initialized\n");
 
+       return 0;
+err1:
+       if (hwmgr->pptable_func->pptable_fini)
+               hwmgr->pptable_func->pptable_fini(hwmgr);
+err:
+       pr_err("amdgpu: powerplay initialization failed\n");
        return ret;
 }
 
@@ -85,10 +98,14 @@ static int pp_sw_fini(void *handle)
        pp_handle = (struct pp_instance *)handle;
        hwmgr = pp_handle->hwmgr;
 
-       if (hwmgr != NULL || hwmgr->hwmgr_func != NULL ||
-           hwmgr->hwmgr_func->backend_fini != NULL)
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->backend_fini != NULL)
                ret = hwmgr->hwmgr_func->backend_fini(hwmgr);
 
+       if (hwmgr->pptable_func->pptable_fini)
+               hwmgr->pptable_func->pptable_fini(hwmgr);
+
        return ret;
 }
 
@@ -172,21 +189,117 @@ static int pp_sw_reset(void *handle)
        return 0;
 }
 
-static void pp_print_status(void *handle)
-{
-
-}
 
 static int pp_set_clockgating_state(void *handle,
                                    enum amd_clockgating_state state)
 {
+       struct pp_hwmgr  *hwmgr;
+       uint32_t msg_id, pp_state;
+
+       if (handle == NULL)
+               return -EINVAL;
+
+       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->update_clock_gatings == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
+
+       if (state == AMD_CG_STATE_UNGATE)
+               pp_state = 0;
+       else
+               pp_state = PP_STATE_CG | PP_STATE_LS;
+
+       /* Enable/disable GFX blocks clock gating through SMU */
+       msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+                       PP_BLOCK_GFX_CG,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+                       PP_BLOCK_GFX_3D,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+                       PP_BLOCK_GFX_RLC,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+                       PP_BLOCK_GFX_CP,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_GFX,
+                       PP_BLOCK_GFX_MG,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+
+       /* Enable/disable System blocks clock gating through SMU */
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_BIF,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_BIF,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_MC,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_ROM,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_DRM,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_HDP,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+       msg_id = PP_CG_MSG_ID(PP_GROUP_SYS,
+                       PP_BLOCK_SYS_SDMA,
+                       PP_STATE_SUPPORT_CG | PP_STATE_SUPPORT_LS,
+                       pp_state);
+       hwmgr->hwmgr_func->update_clock_gatings(hwmgr, &msg_id);
+
        return 0;
 }
 
 static int pp_set_powergating_state(void *handle,
                                    enum amd_powergating_state state)
 {
-       return 0;
+       struct pp_hwmgr  *hwmgr;
+
+       if (handle == NULL)
+               return -EINVAL;
+
+       hwmgr = ((struct pp_instance *)handle)->hwmgr;
+
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->enable_per_cu_power_gating == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
+
+       /* Enable/disable GFX per cu powergating through SMU */
+       return hwmgr->hwmgr_func->enable_per_cu_power_gating(hwmgr,
+                       state == AMD_PG_STATE_GATE ? true : false);
 }
 
 static int pp_suspend(void *handle)
@@ -236,6 +349,7 @@ static int pp_resume(void *handle)
 }
 
 const struct amd_ip_funcs pp_ip_funcs = {
+       .name = "powerplay",
        .early_init = pp_early_init,
        .late_init = NULL,
        .sw_init = pp_sw_init,
@@ -247,7 +361,6 @@ const struct amd_ip_funcs pp_ip_funcs = {
        .is_idle = pp_is_idle,
        .wait_for_idle = pp_wait_for_idle,
        .soft_reset = pp_sw_reset,
-       .print_status = pp_print_status,
        .set_clockgating_state = pp_set_clockgating_state,
        .set_powergating_state = pp_set_powergating_state,
 };
@@ -275,9 +388,12 @@ static int pp_dpm_force_performance_level(void *handle,
 
        hwmgr = pp_handle->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-           hwmgr->hwmgr_func->force_dpm_level == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->force_dpm_level == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        hwmgr->hwmgr_func->force_dpm_level(hwmgr, level);
 
@@ -309,9 +425,12 @@ static int pp_dpm_get_sclk(void *handle, bool low)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-           hwmgr->hwmgr_func->get_sclk == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_sclk == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_sclk(hwmgr, low);
 }
@@ -325,9 +444,12 @@ static int pp_dpm_get_mclk(void *handle, bool low)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-           hwmgr->hwmgr_func->get_mclk == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_mclk == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_mclk(hwmgr, low);
 }
@@ -341,9 +463,12 @@ static int pp_dpm_powergate_vce(void *handle, bool gate)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-           hwmgr->hwmgr_func->powergate_vce == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->powergate_vce == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->powergate_vce(hwmgr, gate);
 }
@@ -357,9 +482,12 @@ static int pp_dpm_powergate_uvd(void *handle, bool gate)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-           hwmgr->hwmgr_func->powergate_uvd == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->powergate_uvd == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->powergate_uvd(hwmgr, gate);
 }
@@ -455,10 +583,14 @@ pp_debugfs_print_current_performance_level(void *handle,
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->print_current_perforce_level == NULL)
+       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL)
                return;
 
+       if (hwmgr->hwmgr_func->print_current_perforce_level == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return;
+       }
+
        hwmgr->hwmgr_func->print_current_perforce_level(hwmgr, m);
 }
 
@@ -471,9 +603,12 @@ static int pp_dpm_set_fan_control_mode(void *handle, uint32_t mode)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->set_fan_control_mode == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->set_fan_control_mode == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->set_fan_control_mode(hwmgr, mode);
 }
@@ -487,9 +622,12 @@ static int pp_dpm_get_fan_control_mode(void *handle)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->get_fan_control_mode == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_fan_control_mode == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_fan_control_mode(hwmgr);
 }
@@ -503,9 +641,12 @@ static int pp_dpm_set_fan_speed_percent(void *handle, uint32_t percent)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->set_fan_speed_percent == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->set_fan_speed_percent == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->set_fan_speed_percent(hwmgr, percent);
 }
@@ -519,9 +660,12 @@ static int pp_dpm_get_fan_speed_percent(void *handle, uint32_t *speed)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->get_fan_speed_percent == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_fan_speed_percent == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_fan_speed_percent(hwmgr, speed);
 }
@@ -535,9 +679,12 @@ static int pp_dpm_get_temperature(void *handle)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-         hwmgr->hwmgr_func->get_temperature == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_temperature == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_temperature(hwmgr);
 }
@@ -591,9 +738,12 @@ static int pp_dpm_get_pp_table(void *handle, char **table)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-               hwmgr->hwmgr_func->get_pp_table == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->get_pp_table == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->get_pp_table(hwmgr, table);
 }
@@ -607,15 +757,18 @@ static int pp_dpm_set_pp_table(void *handle, const char *buf, size_t size)
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-               hwmgr->hwmgr_func->set_pp_table == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->set_pp_table == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
        return hwmgr->hwmgr_func->set_pp_table(hwmgr, buf, size);
 }
 
 static int pp_dpm_force_clock_level(void *handle,
-               enum pp_clock_type type, int level)
+               enum pp_clock_type type, uint32_t mask)
 {
        struct pp_hwmgr *hwmgr;
 
@@ -624,11 +777,14 @@ static int pp_dpm_force_clock_level(void *handle,
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-                       hwmgr->hwmgr_func->force_clock_level == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
+
+       if (hwmgr->hwmgr_func->force_clock_level == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
 
-       return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, level);
+       return hwmgr->hwmgr_func->force_clock_level(hwmgr, type, mask);
 }
 
 static int pp_dpm_print_clock_levels(void *handle,
@@ -641,10 +797,12 @@ static int pp_dpm_print_clock_levels(void *handle,
 
        hwmgr = ((struct pp_instance *)handle)->hwmgr;
 
-       if (hwmgr == NULL || hwmgr->hwmgr_func == NULL ||
-                       hwmgr->hwmgr_func->print_clock_levels == NULL)
-               return -EINVAL;
+       PP_CHECK_HW(hwmgr);
 
+       if (hwmgr->hwmgr_func->print_clock_levels == NULL) {
+               printk(KERN_INFO "%s was not implemented.\n", __func__);
+               return 0;
+       }
        return hwmgr->hwmgr_func->print_clock_levels(hwmgr, type, buf);
 }