Merge branch 'for-5.5/logitech' into for-linus
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / powerplay / renoir_ppt.c
1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #include "amdgpu.h"
25 #include "amdgpu_smu.h"
26 #include "soc15_common.h"
27 #include "smu_v12_0_ppsmc.h"
28 #include "smu12_driver_if.h"
29 #include "smu_v12_0.h"
30 #include "renoir_ppt.h"
31
32
33 #define MSG_MAP(msg, index) \
34         [SMU_MSG_##msg] = {1, (index)}
35
36 #define TAB_MAP_VALID(tab) \
37         [SMU_TABLE_##tab] = {1, TABLE_##tab}
38
39 #define TAB_MAP_INVALID(tab) \
40         [SMU_TABLE_##tab] = {0, TABLE_##tab}
41
42 static struct smu_12_0_cmn2aisc_mapping renoir_message_map[SMU_MSG_MAX_COUNT] = {
43         MSG_MAP(TestMessage,                    PPSMC_MSG_TestMessage),
44         MSG_MAP(GetSmuVersion,                  PPSMC_MSG_GetSmuVersion),
45         MSG_MAP(GetDriverIfVersion,             PPSMC_MSG_GetDriverIfVersion),
46         MSG_MAP(PowerUpGfx,                     PPSMC_MSG_PowerUpGfx),
47         MSG_MAP(AllowGfxOff,                    PPSMC_MSG_EnableGfxOff),
48         MSG_MAP(DisallowGfxOff,                 PPSMC_MSG_DisableGfxOff),
49         MSG_MAP(PowerDownIspByTile,             PPSMC_MSG_PowerDownIspByTile),
50         MSG_MAP(PowerUpIspByTile,               PPSMC_MSG_PowerUpIspByTile),
51         MSG_MAP(PowerDownVcn,                   PPSMC_MSG_PowerDownVcn),
52         MSG_MAP(PowerUpVcn,                     PPSMC_MSG_PowerUpVcn),
53         MSG_MAP(PowerDownSdma,                  PPSMC_MSG_PowerDownSdma),
54         MSG_MAP(PowerUpSdma,                    PPSMC_MSG_PowerUpSdma),
55         MSG_MAP(SetHardMinIspclkByFreq,         PPSMC_MSG_SetHardMinIspclkByFreq),
56         MSG_MAP(SetHardMinVcn,                  PPSMC_MSG_SetHardMinVcn),
57         MSG_MAP(Spare1,                         PPSMC_MSG_spare1),
58         MSG_MAP(Spare2,                         PPSMC_MSG_spare2),
59         MSG_MAP(SetAllowFclkSwitch,             PPSMC_MSG_SetAllowFclkSwitch),
60         MSG_MAP(SetMinVideoGfxclkFreq,          PPSMC_MSG_SetMinVideoGfxclkFreq),
61         MSG_MAP(ActiveProcessNotify,            PPSMC_MSG_ActiveProcessNotify),
62         MSG_MAP(SetCustomPolicy,                PPSMC_MSG_SetCustomPolicy),
63         MSG_MAP(SetVideoFps,                    PPSMC_MSG_SetVideoFps),
64         MSG_MAP(NumOfDisplays,                  PPSMC_MSG_SetDisplayCount),
65         MSG_MAP(QueryPowerLimit,                PPSMC_MSG_QueryPowerLimit),
66         MSG_MAP(SetDriverDramAddrHigh,          PPSMC_MSG_SetDriverDramAddrHigh),
67         MSG_MAP(SetDriverDramAddrLow,           PPSMC_MSG_SetDriverDramAddrLow),
68         MSG_MAP(TransferTableSmu2Dram,          PPSMC_MSG_TransferTableSmu2Dram),
69         MSG_MAP(TransferTableDram2Smu,          PPSMC_MSG_TransferTableDram2Smu),
70         MSG_MAP(GfxDeviceDriverReset,           PPSMC_MSG_GfxDeviceDriverReset),
71         MSG_MAP(SetGfxclkOverdriveByFreqVid,    PPSMC_MSG_SetGfxclkOverdriveByFreqVid),
72         MSG_MAP(SetHardMinDcfclkByFreq,         PPSMC_MSG_SetHardMinDcfclkByFreq),
73         MSG_MAP(SetHardMinSocclkByFreq,         PPSMC_MSG_SetHardMinSocclkByFreq),
74         MSG_MAP(ControlIgpuATS,                 PPSMC_MSG_ControlIgpuATS),
75         MSG_MAP(SetMinVideoFclkFreq,            PPSMC_MSG_SetMinVideoFclkFreq),
76         MSG_MAP(SetMinDeepSleepDcfclk,          PPSMC_MSG_SetMinDeepSleepDcfclk),
77         MSG_MAP(ForcePowerDownGfx,              PPSMC_MSG_ForcePowerDownGfx),
78         MSG_MAP(SetPhyclkVoltageByFreq,         PPSMC_MSG_SetPhyclkVoltageByFreq),
79         MSG_MAP(SetDppclkVoltageByFreq,         PPSMC_MSG_SetDppclkVoltageByFreq),
80         MSG_MAP(SetSoftMinVcn,                  PPSMC_MSG_SetSoftMinVcn),
81         MSG_MAP(EnablePostCode,                 PPSMC_MSG_EnablePostCode),
82         MSG_MAP(GetGfxclkFrequency,             PPSMC_MSG_GetGfxclkFrequency),
83         MSG_MAP(GetFclkFrequency,               PPSMC_MSG_GetFclkFrequency),
84         MSG_MAP(GetMinGfxclkFrequency,          PPSMC_MSG_GetMinGfxclkFrequency),
85         MSG_MAP(GetMaxGfxclkFrequency,          PPSMC_MSG_GetMaxGfxclkFrequency),
86         MSG_MAP(SoftReset,                      PPSMC_MSG_SoftReset),
87         MSG_MAP(SetGfxCGPG,                     PPSMC_MSG_SetGfxCGPG),
88         MSG_MAP(SetSoftMaxGfxClk,               PPSMC_MSG_SetSoftMaxGfxClk),
89         MSG_MAP(SetHardMinGfxClk,               PPSMC_MSG_SetHardMinGfxClk),
90         MSG_MAP(SetSoftMaxSocclkByFreq,         PPSMC_MSG_SetSoftMaxSocclkByFreq),
91         MSG_MAP(SetSoftMaxFclkByFreq,           PPSMC_MSG_SetSoftMaxFclkByFreq),
92         MSG_MAP(SetSoftMaxVcn,                  PPSMC_MSG_SetSoftMaxVcn),
93         MSG_MAP(PowerGateMmHub,                 PPSMC_MSG_PowerGateMmHub),
94         MSG_MAP(UpdatePmeRestore,               PPSMC_MSG_UpdatePmeRestore),
95         MSG_MAP(GpuChangeState,                 PPSMC_MSG_GpuChangeState),
96         MSG_MAP(SetPowerLimitPercentage,        PPSMC_MSG_SetPowerLimitPercentage),
97         MSG_MAP(ForceGfxContentSave,            PPSMC_MSG_ForceGfxContentSave),
98         MSG_MAP(EnableTmdp48MHzRefclkPwrDown,   PPSMC_MSG_EnableTmdp48MHzRefclkPwrDown),
99         MSG_MAP(PowerDownJpeg,                  PPSMC_MSG_PowerDownJpeg),
100         MSG_MAP(PowerUpJpeg,                    PPSMC_MSG_PowerUpJpeg),
101         MSG_MAP(PowerGateAtHub,                 PPSMC_MSG_PowerGateAtHub),
102         MSG_MAP(SetSoftMinJpeg,                 PPSMC_MSG_SetSoftMinJpeg),
103         MSG_MAP(SetHardMinFclkByFreq,           PPSMC_MSG_SetHardMinFclkByFreq),
104 };
105
106 static struct smu_12_0_cmn2aisc_mapping renoir_table_map[SMU_TABLE_COUNT] = {
107         TAB_MAP_VALID(WATERMARKS),
108         TAB_MAP_INVALID(CUSTOM_DPM),
109         TAB_MAP_VALID(DPMCLOCKS),
110         TAB_MAP_VALID(SMU_METRICS),
111 };
112
113 static int renoir_get_smu_msg_index(struct smu_context *smc, uint32_t index)
114 {
115         struct smu_12_0_cmn2aisc_mapping mapping;
116
117         if (index >= SMU_MSG_MAX_COUNT)
118                 return -EINVAL;
119
120         mapping = renoir_message_map[index];
121         if (!(mapping.valid_mapping))
122                 return -EINVAL;
123
124         return mapping.map_to;
125 }
126
127 static int renoir_get_smu_table_index(struct smu_context *smc, uint32_t index)
128 {
129         struct smu_12_0_cmn2aisc_mapping mapping;
130
131         if (index >= SMU_TABLE_COUNT)
132                 return -EINVAL;
133
134         mapping = renoir_table_map[index];
135         if (!(mapping.valid_mapping))
136                 return -EINVAL;
137
138         return mapping.map_to;
139 }
140
141 static int renoir_tables_init(struct smu_context *smu, struct smu_table *tables)
142 {
143         struct smu_table_context *smu_table = &smu->smu_table;
144
145         SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
146                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
147         SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, sizeof(DpmClocks_t),
148                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
149         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
150                 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
151
152         smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL);
153         if (!smu_table->clocks_table)
154                 return -ENOMEM;
155
156         return 0;
157 }
158
159 /**
160  * This interface just for getting uclk ultimate freq and should't introduce
161  * other likewise function result in overmuch callback.
162  */
163 static int renoir_get_dpm_uclk_limited(struct smu_context *smu, uint32_t *clock, bool max)
164 {
165
166         DpmClocks_t *table = smu->smu_table.clocks_table;
167
168         if (!clock || !table)
169                 return -EINVAL;
170
171         if (max)
172                 *clock = table->FClocks[NUM_FCLK_DPM_LEVELS-1].Freq;
173         else
174                 *clock = table->FClocks[0].Freq;
175
176         return 0;
177
178 }
179
180 static int renoir_print_clk_levels(struct smu_context *smu,
181                         enum smu_clk_type clk_type, char *buf)
182 {
183         int i, size = 0, ret = 0;
184         uint32_t cur_value = 0, value = 0, count = 0, min = 0, max = 0;
185         DpmClocks_t *clk_table = smu->smu_table.clocks_table;
186         SmuMetrics_t metrics = {0};
187
188         if (!clk_table || clk_type >= SMU_CLK_COUNT)
189                 return -EINVAL;
190
191         ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
192                                (void *)&metrics, false);
193         if (ret)
194                 return ret;
195
196         switch (clk_type) {
197         case SMU_GFXCLK:
198         case SMU_SCLK:
199                 /* retirve table returned paramters unit is MHz */
200                 cur_value = metrics.ClockFrequency[CLOCK_GFXCLK];
201                 ret = smu_get_dpm_freq_range(smu, SMU_GFXCLK, &min, &max);
202                 if (!ret) {
203                         /* driver only know min/max gfx_clk, Add level 1 for all other gfx clks */
204                         if (cur_value  == max)
205                                 i = 2;
206                         else if (cur_value == min)
207                                 i = 0;
208                         else
209                                 i = 1;
210
211                         size += sprintf(buf + size, "0: %uMhz %s\n", min,
212                                         i == 0 ? "*" : "");
213                         size += sprintf(buf + size, "1: %uMhz %s\n",
214                                         i == 1 ? cur_value : RENOIR_UMD_PSTATE_GFXCLK,
215                                         i == 1 ? "*" : "");
216                         size += sprintf(buf + size, "2: %uMhz %s\n", max,
217                                         i == 2 ? "*" : "");
218                 }
219                 return size;
220         case SMU_SOCCLK:
221                 count = NUM_SOCCLK_DPM_LEVELS;
222                 cur_value = metrics.ClockFrequency[CLOCK_SOCCLK];
223                 break;
224         case SMU_MCLK:
225                 count = NUM_MEMCLK_DPM_LEVELS;
226                 cur_value = metrics.ClockFrequency[CLOCK_UMCCLK];
227                 break;
228         case SMU_DCEFCLK:
229                 count = NUM_DCFCLK_DPM_LEVELS;
230                 cur_value = metrics.ClockFrequency[CLOCK_DCFCLK];
231                 break;
232         case SMU_FCLK:
233                 count = NUM_FCLK_DPM_LEVELS;
234                 cur_value = metrics.ClockFrequency[CLOCK_FCLK];
235                 break;
236         default:
237                 return -EINVAL;
238         }
239
240         for (i = 0; i < count; i++) {
241                 GET_DPM_CUR_FREQ(clk_table, clk_type, i, value);
242                 size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
243                                 cur_value == value ? "*" : "");
244         }
245
246         return size;
247 }
248
249 static const struct pptable_funcs renoir_ppt_funcs = {
250         .get_smu_msg_index = renoir_get_smu_msg_index,
251         .get_smu_table_index = renoir_get_smu_table_index,
252         .tables_init = renoir_tables_init,
253         .set_power_state = NULL,
254         .get_dpm_uclk_limited = renoir_get_dpm_uclk_limited,
255         .print_clk_levels = renoir_print_clk_levels,
256 };
257
258 void renoir_set_ppt_funcs(struct smu_context *smu)
259 {
260         struct smu_table_context *smu_table = &smu->smu_table;
261
262         smu->ppt_funcs = &renoir_ppt_funcs;
263         smu->smc_if_version = SMU12_DRIVER_IF_VERSION;
264         smu_table->table_count = TABLE_COUNT;
265 }