Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
  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
 42static 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
106static 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
113static 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
127static 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
141static 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 */
163static 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
180static 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
249static 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
258void 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}