aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
authorTom St Denis <tom.stdenis@amd.com>2016-09-15 10:07:34 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-09-19 14:38:26 -0400
commita6e3695221446cf825d12db9c6ad3502c45fb9de (patch)
tree8bb5b1275bd20498c5642c4445cee93e20e56cc6 /drivers/gpu/drm/amd
parent167ac5733c70683c4886a8b3ef347cc6c93a76a6 (diff)
drm/amd/powerplay: Add read_sensor() callback to hwmgr (v3)
Provides standardized interface to read various sensors. The API is extensible (by adding to the end of the amd_pp_sensors enumeration list. Support has been added to Carrizo/smu7 (v2) Squashed the two sensor patches into one. (v3) Updated to apply to smu7_hwmgr instead Signed-off-by: Tom St Denis <tom.stdenis@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/powerplay/amd_powerplay.c20
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c96
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c36
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h12
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/hwmgr.h1
5 files changed, 165 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
index b1d19409bf86..ee0368381e82 100644
--- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
+++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c
@@ -894,6 +894,25 @@ static int pp_dpm_set_mclk_od(void *handle, uint32_t value)
894 return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value); 894 return hwmgr->hwmgr_func->set_mclk_od(hwmgr, value);
895} 895}
896 896
897static int pp_dpm_read_sensor(void *handle, int idx, int32_t *value)
898{
899 struct pp_hwmgr *hwmgr;
900
901 if (!handle)
902 return -EINVAL;
903
904 hwmgr = ((struct pp_instance *)handle)->hwmgr;
905
906 PP_CHECK_HW(hwmgr);
907
908 if (hwmgr->hwmgr_func->read_sensor == NULL) {
909 printk(KERN_INFO "%s was not implemented.\n", __func__);
910 return 0;
911 }
912
913 return hwmgr->hwmgr_func->read_sensor(hwmgr, idx, value);
914}
915
897const struct amd_powerplay_funcs pp_dpm_funcs = { 916const struct amd_powerplay_funcs pp_dpm_funcs = {
898 .get_temperature = pp_dpm_get_temperature, 917 .get_temperature = pp_dpm_get_temperature,
899 .load_firmware = pp_dpm_load_fw, 918 .load_firmware = pp_dpm_load_fw,
@@ -920,6 +939,7 @@ const struct amd_powerplay_funcs pp_dpm_funcs = {
920 .set_sclk_od = pp_dpm_set_sclk_od, 939 .set_sclk_od = pp_dpm_set_sclk_od,
921 .get_mclk_od = pp_dpm_get_mclk_od, 940 .get_mclk_od = pp_dpm_get_mclk_od,
922 .set_mclk_od = pp_dpm_set_mclk_od, 941 .set_mclk_od = pp_dpm_set_mclk_od,
942 .read_sensor = pp_dpm_read_sensor,
923}; 943};
924 944
925static int amd_pp_instance_init(struct amd_pp_init *pp_init, 945static int amd_pp_instance_init(struct amd_pp_init *pp_init,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
index 5ecef1732e20..9f3c5a8a903c 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
@@ -1857,6 +1857,101 @@ static int cz_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_c
1857 return 0; 1857 return 0;
1858} 1858}
1859 1859
1860static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, int32_t *value)
1861{
1862 struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
1863
1864 struct phm_clock_voltage_dependency_table *table =
1865 hwmgr->dyn_state.vddc_dependency_on_sclk;
1866
1867 struct phm_vce_clock_voltage_dependency_table *vce_table =
1868 hwmgr->dyn_state.vce_clock_voltage_dependency_table;
1869
1870 struct phm_uvd_clock_voltage_dependency_table *uvd_table =
1871 hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
1872
1873 uint32_t sclk_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX),
1874 TARGET_AND_CURRENT_PROFILE_INDEX, CURR_SCLK_INDEX);
1875 uint32_t uvd_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX_2),
1876 TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_UVD_INDEX);
1877 uint32_t vce_index = PHM_GET_FIELD(cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixTARGET_AND_CURRENT_PROFILE_INDEX_2),
1878 TARGET_AND_CURRENT_PROFILE_INDEX_2, CURR_VCE_INDEX);
1879
1880 uint32_t sclk, vclk, dclk, ecclk, tmp, activity_percent;
1881 uint16_t vddnb, vddgfx;
1882 int result;
1883
1884 switch (idx) {
1885 case AMDGPU_PP_SENSOR_GFX_SCLK:
1886 if (sclk_index < NUM_SCLK_LEVELS) {
1887 sclk = table->entries[sclk_index].clk;
1888 *value = sclk;
1889 return 0;
1890 }
1891 return -EINVAL;
1892 case AMDGPU_PP_SENSOR_VDDNB:
1893 tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_NB_CURRENTVID) &
1894 CURRENT_NB_VID_MASK) >> CURRENT_NB_VID__SHIFT;
1895 vddnb = cz_convert_8Bit_index_to_voltage(hwmgr, tmp);
1896 *value = vddnb;
1897 return 0;
1898 case AMDGPU_PP_SENSOR_VDDGFX:
1899 tmp = (cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, ixSMUSVI_GFX_CURRENTVID) &
1900 CURRENT_GFX_VID_MASK) >> CURRENT_GFX_VID__SHIFT;
1901 vddgfx = cz_convert_8Bit_index_to_voltage(hwmgr, (u16)tmp);
1902 *value = vddgfx;
1903 return 0;
1904 case AMDGPU_PP_SENSOR_UVD_VCLK:
1905 if (!cz_hwmgr->uvd_power_gated) {
1906 if (uvd_index >= CZ_MAX_HARDWARE_POWERLEVELS) {
1907 return -EINVAL;
1908 } else {
1909 vclk = uvd_table->entries[uvd_index].vclk;
1910 *value = vclk;
1911 return 0;
1912 }
1913 }
1914 *value = 0;
1915 return 0;
1916 case AMDGPU_PP_SENSOR_UVD_DCLK:
1917 if (!cz_hwmgr->uvd_power_gated) {
1918 if (uvd_index >= CZ_MAX_HARDWARE_POWERLEVELS) {
1919 return -EINVAL;
1920 } else {
1921 dclk = uvd_table->entries[uvd_index].dclk;
1922 *value = dclk;
1923 return 0;
1924 }
1925 }
1926 *value = 0;
1927 return 0;
1928 case AMDGPU_PP_SENSOR_VCE_ECCLK:
1929 if (!cz_hwmgr->vce_power_gated) {
1930 if (vce_index >= CZ_MAX_HARDWARE_POWERLEVELS) {
1931 return -EINVAL;
1932 } else {
1933 ecclk = vce_table->entries[vce_index].ecclk;
1934 *value = ecclk;
1935 return 0;
1936 }
1937 }
1938 *value = 0;
1939 return 0;
1940 case AMDGPU_PP_SENSOR_GPU_LOAD:
1941 result = smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_GetAverageGraphicsActivity);
1942 if (0 == result) {
1943 activity_percent = cgs_read_register(hwmgr->device, mmSMU_MP1_SRBM2P_ARG_0);
1944 activity_percent = activity_percent > 100 ? 100 : activity_percent;
1945 } else {
1946 activity_percent = 50;
1947 }
1948 *value = activity_percent;
1949 return 0;
1950 default:
1951 return -EINVAL;
1952 }
1953}
1954
1860static const struct pp_hwmgr_func cz_hwmgr_funcs = { 1955static const struct pp_hwmgr_func cz_hwmgr_funcs = {
1861 .backend_init = cz_hwmgr_backend_init, 1956 .backend_init = cz_hwmgr_backend_init,
1862 .backend_fini = cz_hwmgr_backend_fini, 1957 .backend_fini = cz_hwmgr_backend_fini,
@@ -1882,6 +1977,7 @@ static const struct pp_hwmgr_func cz_hwmgr_funcs = {
1882 .get_current_shallow_sleep_clocks = cz_get_current_shallow_sleep_clocks, 1977 .get_current_shallow_sleep_clocks = cz_get_current_shallow_sleep_clocks,
1883 .get_clock_by_type = cz_get_clock_by_type, 1978 .get_clock_by_type = cz_get_clock_by_type,
1884 .get_max_high_clocks = cz_get_max_high_clocks, 1979 .get_max_high_clocks = cz_get_max_high_clocks,
1980 .read_sensor = cz_read_sensor,
1885}; 1981};
1886 1982
1887int cz_hwmgr_init(struct pp_hwmgr *hwmgr) 1983int cz_hwmgr_init(struct pp_hwmgr *hwmgr)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index f67e1e260b30..07a7d046d6f6 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -3144,6 +3144,41 @@ smu7_print_current_perforce_level(struct pp_hwmgr *hwmgr, struct seq_file *m)
3144 seq_printf(m, "vce %sabled\n", data->vce_power_gated ? "dis" : "en"); 3144 seq_printf(m, "vce %sabled\n", data->vce_power_gated ? "dis" : "en");
3145} 3145}
3146 3146
3147static int smu7_read_sensor(struct pp_hwmgr *hwmgr, int idx, int32_t *value)
3148{
3149 uint32_t sclk, mclk, activity_percent;
3150 uint32_t offset;
3151 struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
3152
3153 switch (idx) {
3154 case AMDGPU_PP_SENSOR_GFX_SCLK:
3155 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetSclkFrequency);
3156 sclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
3157 *value = sclk;
3158 return 0;
3159 case AMDGPU_PP_SENSOR_GFX_MCLK:
3160 smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_API_GetMclkFrequency);
3161 mclk = cgs_read_register(hwmgr->device, mmSMC_MSG_ARG_0);
3162 *value = mclk;
3163 return 0;
3164 case AMDGPU_PP_SENSOR_GPU_LOAD:
3165 offset = data->soft_regs_start + smum_get_offsetof(hwmgr->smumgr,
3166 SMU_SoftRegisters,
3167 AverageGraphicsActivity);
3168
3169 activity_percent = cgs_read_ind_register(hwmgr->device, CGS_IND_REG__SMC, offset);
3170 activity_percent += 0x80;
3171 activity_percent >>= 8;
3172 *value = activity_percent > 100 ? 100 : activity_percent;
3173 return 0;
3174 case AMDGPU_PP_SENSOR_GPU_TEMP:
3175 *value = smu7_thermal_get_temperature(hwmgr);
3176 return 0;
3177 default:
3178 return -EINVAL;
3179 }
3180}
3181
3147static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) 3182static int smu7_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
3148{ 3183{
3149 const struct phm_set_power_state_input *states = 3184 const struct phm_set_power_state_input *states =
@@ -4315,6 +4350,7 @@ static struct pp_hwmgr_func smu7_hwmgr_funcs = {
4315 .get_mclk_od = smu7_get_mclk_od, 4350 .get_mclk_od = smu7_get_mclk_od,
4316 .set_mclk_od = smu7_set_mclk_od, 4351 .set_mclk_od = smu7_set_mclk_od,
4317 .get_clock_by_type = smu7_get_clock_by_type, 4352 .get_clock_by_type = smu7_get_clock_by_type,
4353 .read_sensor = smu7_read_sensor,
4318}; 4354};
4319 4355
4320uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock, 4356uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
index f941acf563a9..dfa0f38a5e76 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amd_powerplay.h
@@ -29,6 +29,17 @@
29#include "amd_shared.h" 29#include "amd_shared.h"
30#include "cgs_common.h" 30#include "cgs_common.h"
31 31
32enum amd_pp_sensors {
33 AMDGPU_PP_SENSOR_GFX_SCLK = 0,
34 AMDGPU_PP_SENSOR_VDDNB,
35 AMDGPU_PP_SENSOR_VDDGFX,
36 AMDGPU_PP_SENSOR_UVD_VCLK,
37 AMDGPU_PP_SENSOR_UVD_DCLK,
38 AMDGPU_PP_SENSOR_VCE_ECCLK,
39 AMDGPU_PP_SENSOR_GPU_LOAD,
40 AMDGPU_PP_SENSOR_GFX_MCLK,
41 AMDGPU_PP_SENSOR_GPU_TEMP,
42};
32 43
33enum amd_pp_event { 44enum amd_pp_event {
34 AMD_PP_EVENT_INITIALIZE = 0, 45 AMD_PP_EVENT_INITIALIZE = 0,
@@ -347,6 +358,7 @@ struct amd_powerplay_funcs {
347 int (*set_sclk_od)(void *handle, uint32_t value); 358 int (*set_sclk_od)(void *handle, uint32_t value);
348 int (*get_mclk_od)(void *handle); 359 int (*get_mclk_od)(void *handle);
349 int (*set_mclk_od)(void *handle, uint32_t value); 360 int (*set_mclk_od)(void *handle, uint32_t value);
361 int (*read_sensor)(void *handle, int idx, int32_t *value);
350}; 362};
351 363
352struct amd_powerplay { 364struct amd_powerplay {
diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
index c9628b4db2c3..fcd45452380d 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
@@ -359,6 +359,7 @@ struct pp_hwmgr_func {
359 int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); 359 int (*set_sclk_od)(struct pp_hwmgr *hwmgr, uint32_t value);
360 int (*get_mclk_od)(struct pp_hwmgr *hwmgr); 360 int (*get_mclk_od)(struct pp_hwmgr *hwmgr);
361 int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value); 361 int (*set_mclk_od)(struct pp_hwmgr *hwmgr, uint32_t value);
362 int (*read_sensor)(struct pp_hwmgr *hwmgr, int idx, int32_t *value);
362}; 363};
363 364
364struct pp_table_func { 365struct pp_table_func {