0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #define SWSMU_CODE_LAYER_L2
0025
0026 #include "amdgpu.h"
0027 #include "amdgpu_smu.h"
0028 #include "smu_v11_0.h"
0029 #include "smu11_driver_if_cyan_skillfish.h"
0030 #include "cyan_skillfish_ppt.h"
0031 #include "smu_v11_8_ppsmc.h"
0032 #include "smu_v11_8_pmfw.h"
0033 #include "smu_cmn.h"
0034 #include "soc15_common.h"
0035
0036
0037
0038
0039
0040
0041
0042 #undef pr_err
0043 #undef pr_warn
0044 #undef pr_info
0045 #undef pr_debug
0046
0047
0048 #define CYAN_SKILLFISH_SCLK_MIN 1000
0049 #define CYAN_SKILLFISH_SCLK_MAX 2000
0050
0051
0052 #define CYAN_SKILLFISH_VDDC_MIN 700
0053 #define CYAN_SKILLFISH_VDDC_MAX 1129
0054 #define CYAN_SKILLFISH_VDDC_MAGIC 5118
0055
0056 static struct gfx_user_settings {
0057 uint32_t sclk;
0058 uint32_t vddc;
0059 } cyan_skillfish_user_settings;
0060
0061 static uint32_t cyan_skillfish_sclk_default;
0062
0063 #define FEATURE_MASK(feature) (1ULL << feature)
0064 #define SMC_DPM_FEATURE ( \
0065 FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \
0066 FEATURE_MASK(FEATURE_SOC_DPM_BIT) | \
0067 FEATURE_MASK(FEATURE_GFX_DPM_BIT))
0068
0069 static struct cmn2asic_msg_mapping cyan_skillfish_message_map[SMU_MSG_MAX_COUNT] = {
0070 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
0071 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 0),
0072 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 0),
0073 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverTableDramAddrHigh, 0),
0074 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverTableDramAddrLow, 0),
0075 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0),
0076 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
0077 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 0),
0078 MSG_MAP(RequestGfxclk, PPSMC_MSG_RequestGfxclk, 0),
0079 MSG_MAP(ForceGfxVid, PPSMC_MSG_ForceGfxVid, 0),
0080 MSG_MAP(UnforceGfxVid, PPSMC_MSG_UnforceGfxVid, 0),
0081 };
0082
0083 static struct cmn2asic_mapping cyan_skillfish_table_map[SMU_TABLE_COUNT] = {
0084 TAB_MAP_VALID(SMU_METRICS),
0085 };
0086
0087 static int cyan_skillfish_tables_init(struct smu_context *smu)
0088 {
0089 struct smu_table_context *smu_table = &smu->smu_table;
0090 struct smu_table *tables = smu_table->tables;
0091
0092 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
0093 sizeof(SmuMetrics_t),
0094 PAGE_SIZE,
0095 AMDGPU_GEM_DOMAIN_VRAM);
0096
0097 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
0098 if (!smu_table->metrics_table)
0099 goto err0_out;
0100
0101 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
0102 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
0103 if (!smu_table->gpu_metrics_table)
0104 goto err1_out;
0105
0106 smu_table->metrics_time = 0;
0107
0108 return 0;
0109
0110 err1_out:
0111 smu_table->gpu_metrics_table_size = 0;
0112 kfree(smu_table->metrics_table);
0113 err0_out:
0114 return -ENOMEM;
0115 }
0116
0117 static int cyan_skillfish_init_smc_tables(struct smu_context *smu)
0118 {
0119 int ret = 0;
0120
0121 ret = cyan_skillfish_tables_init(smu);
0122 if (ret)
0123 return ret;
0124
0125 return smu_v11_0_init_smc_tables(smu);
0126 }
0127
0128 static int
0129 cyan_skillfish_get_smu_metrics_data(struct smu_context *smu,
0130 MetricsMember_t member,
0131 uint32_t *value)
0132 {
0133 struct smu_table_context *smu_table = &smu->smu_table;
0134 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
0135 int ret = 0;
0136
0137 ret = smu_cmn_get_metrics_table(smu, NULL, false);
0138 if (ret)
0139 return ret;
0140
0141 switch (member) {
0142 case METRICS_CURR_GFXCLK:
0143 *value = metrics->Current.GfxclkFrequency;
0144 break;
0145 case METRICS_CURR_SOCCLK:
0146 *value = metrics->Current.SocclkFrequency;
0147 break;
0148 case METRICS_CURR_VCLK:
0149 *value = metrics->Current.VclkFrequency;
0150 break;
0151 case METRICS_CURR_DCLK:
0152 *value = metrics->Current.DclkFrequency;
0153 break;
0154 case METRICS_CURR_UCLK:
0155 *value = metrics->Current.MemclkFrequency;
0156 break;
0157 case METRICS_AVERAGE_SOCKETPOWER:
0158 *value = (metrics->Current.CurrentSocketPower << 8) /
0159 1000;
0160 break;
0161 case METRICS_TEMPERATURE_EDGE:
0162 *value = metrics->Current.GfxTemperature / 100 *
0163 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0164 break;
0165 case METRICS_TEMPERATURE_HOTSPOT:
0166 *value = metrics->Current.SocTemperature / 100 *
0167 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
0168 break;
0169 case METRICS_VOLTAGE_VDDSOC:
0170 *value = metrics->Current.Voltage[0];
0171 break;
0172 case METRICS_VOLTAGE_VDDGFX:
0173 *value = metrics->Current.Voltage[1];
0174 break;
0175 case METRICS_THROTTLER_STATUS:
0176 *value = metrics->Current.ThrottlerStatus;
0177 break;
0178 default:
0179 *value = UINT_MAX;
0180 break;
0181 }
0182
0183 return ret;
0184 }
0185
0186 static int cyan_skillfish_read_sensor(struct smu_context *smu,
0187 enum amd_pp_sensors sensor,
0188 void *data,
0189 uint32_t *size)
0190 {
0191 int ret = 0;
0192
0193 if (!data || !size)
0194 return -EINVAL;
0195
0196 switch (sensor) {
0197 case AMDGPU_PP_SENSOR_GFX_SCLK:
0198 ret = cyan_skillfish_get_smu_metrics_data(smu,
0199 METRICS_CURR_GFXCLK,
0200 (uint32_t *)data);
0201 *(uint32_t *)data *= 100;
0202 *size = 4;
0203 break;
0204 case AMDGPU_PP_SENSOR_GFX_MCLK:
0205 ret = cyan_skillfish_get_smu_metrics_data(smu,
0206 METRICS_CURR_UCLK,
0207 (uint32_t *)data);
0208 *(uint32_t *)data *= 100;
0209 *size = 4;
0210 break;
0211 case AMDGPU_PP_SENSOR_GPU_POWER:
0212 ret = cyan_skillfish_get_smu_metrics_data(smu,
0213 METRICS_AVERAGE_SOCKETPOWER,
0214 (uint32_t *)data);
0215 *size = 4;
0216 break;
0217 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
0218 ret = cyan_skillfish_get_smu_metrics_data(smu,
0219 METRICS_TEMPERATURE_HOTSPOT,
0220 (uint32_t *)data);
0221 *size = 4;
0222 break;
0223 case AMDGPU_PP_SENSOR_EDGE_TEMP:
0224 ret = cyan_skillfish_get_smu_metrics_data(smu,
0225 METRICS_TEMPERATURE_EDGE,
0226 (uint32_t *)data);
0227 *size = 4;
0228 break;
0229 case AMDGPU_PP_SENSOR_VDDNB:
0230 ret = cyan_skillfish_get_smu_metrics_data(smu,
0231 METRICS_VOLTAGE_VDDSOC,
0232 (uint32_t *)data);
0233 *size = 4;
0234 break;
0235 case AMDGPU_PP_SENSOR_VDDGFX:
0236 ret = cyan_skillfish_get_smu_metrics_data(smu,
0237 METRICS_VOLTAGE_VDDGFX,
0238 (uint32_t *)data);
0239 *size = 4;
0240 break;
0241 default:
0242 ret = -EOPNOTSUPP;
0243 break;
0244 }
0245
0246 return ret;
0247 }
0248
0249 static int cyan_skillfish_get_current_clk_freq(struct smu_context *smu,
0250 enum smu_clk_type clk_type,
0251 uint32_t *value)
0252 {
0253 MetricsMember_t member_type;
0254
0255 switch (clk_type) {
0256 case SMU_GFXCLK:
0257 case SMU_SCLK:
0258 member_type = METRICS_CURR_GFXCLK;
0259 break;
0260 case SMU_FCLK:
0261 case SMU_MCLK:
0262 member_type = METRICS_CURR_UCLK;
0263 break;
0264 case SMU_SOCCLK:
0265 member_type = METRICS_CURR_SOCCLK;
0266 break;
0267 case SMU_VCLK:
0268 member_type = METRICS_CURR_VCLK;
0269 break;
0270 case SMU_DCLK:
0271 member_type = METRICS_CURR_DCLK;
0272 break;
0273 default:
0274 return -EINVAL;
0275 }
0276
0277 return cyan_skillfish_get_smu_metrics_data(smu, member_type, value);
0278 }
0279
0280 static int cyan_skillfish_print_clk_levels(struct smu_context *smu,
0281 enum smu_clk_type clk_type,
0282 char *buf)
0283 {
0284 int ret = 0, size = 0;
0285 uint32_t cur_value = 0;
0286 int i;
0287
0288 smu_cmn_get_sysfs_buf(&buf, &size);
0289
0290 switch (clk_type) {
0291 case SMU_OD_SCLK:
0292 ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK, &cur_value);
0293 if (ret)
0294 return ret;
0295 size += sysfs_emit_at(buf, size,"%s:\n", "OD_SCLK");
0296 size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
0297 break;
0298 case SMU_OD_VDDC_CURVE:
0299 ret = cyan_skillfish_get_smu_metrics_data(smu, METRICS_VOLTAGE_VDDGFX, &cur_value);
0300 if (ret)
0301 return ret;
0302 size += sysfs_emit_at(buf, size,"%s:\n", "OD_VDDC");
0303 size += sysfs_emit_at(buf, size, "0: %umV *\n", cur_value);
0304 break;
0305 case SMU_OD_RANGE:
0306 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
0307 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
0308 CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
0309 size += sysfs_emit_at(buf, size, "VDDC: %7umV %10umV\n",
0310 CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
0311 break;
0312 case SMU_FCLK:
0313 case SMU_MCLK:
0314 case SMU_SOCCLK:
0315 case SMU_VCLK:
0316 case SMU_DCLK:
0317 ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
0318 if (ret)
0319 return ret;
0320 size += sysfs_emit_at(buf, size, "0: %uMhz *\n", cur_value);
0321 break;
0322 case SMU_SCLK:
0323 case SMU_GFXCLK:
0324 ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &cur_value);
0325 if (ret)
0326 return ret;
0327 if (cur_value == CYAN_SKILLFISH_SCLK_MAX)
0328 i = 2;
0329 else if (cur_value == CYAN_SKILLFISH_SCLK_MIN)
0330 i = 0;
0331 else
0332 i = 1;
0333 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MIN,
0334 i == 0 ? "*" : "");
0335 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
0336 i == 1 ? cur_value : cyan_skillfish_sclk_default,
0337 i == 1 ? "*" : "");
0338 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", CYAN_SKILLFISH_SCLK_MAX,
0339 i == 2 ? "*" : "");
0340 break;
0341 default:
0342 dev_warn(smu->adev->dev, "Unsupported clock type\n");
0343 return ret;
0344 }
0345
0346 return size;
0347 }
0348
0349 static bool cyan_skillfish_is_dpm_running(struct smu_context *smu)
0350 {
0351 struct amdgpu_device *adev = smu->adev;
0352 int ret = 0;
0353 uint64_t feature_enabled;
0354
0355
0356 if (adev->in_suspend)
0357 return false;
0358
0359 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
0360 if (ret)
0361 return false;
0362
0363
0364
0365
0366 if (!cyan_skillfish_sclk_default)
0367 cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK,
0368 &cyan_skillfish_sclk_default);
0369
0370 return !!(feature_enabled & SMC_DPM_FEATURE);
0371 }
0372
0373 static ssize_t cyan_skillfish_get_gpu_metrics(struct smu_context *smu,
0374 void **table)
0375 {
0376 struct smu_table_context *smu_table = &smu->smu_table;
0377 struct gpu_metrics_v2_2 *gpu_metrics =
0378 (struct gpu_metrics_v2_2 *)smu_table->gpu_metrics_table;
0379 SmuMetrics_t metrics;
0380 int i, ret = 0;
0381
0382 ret = smu_cmn_get_metrics_table(smu, &metrics, true);
0383 if (ret)
0384 return ret;
0385
0386 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 2, 2);
0387
0388 gpu_metrics->temperature_gfx = metrics.Current.GfxTemperature;
0389 gpu_metrics->temperature_soc = metrics.Current.SocTemperature;
0390
0391 gpu_metrics->average_socket_power = metrics.Current.CurrentSocketPower;
0392 gpu_metrics->average_soc_power = metrics.Current.Power[0];
0393 gpu_metrics->average_gfx_power = metrics.Current.Power[1];
0394
0395 gpu_metrics->average_gfxclk_frequency = metrics.Average.GfxclkFrequency;
0396 gpu_metrics->average_socclk_frequency = metrics.Average.SocclkFrequency;
0397 gpu_metrics->average_uclk_frequency = metrics.Average.MemclkFrequency;
0398 gpu_metrics->average_fclk_frequency = metrics.Average.MemclkFrequency;
0399 gpu_metrics->average_vclk_frequency = metrics.Average.VclkFrequency;
0400 gpu_metrics->average_dclk_frequency = metrics.Average.DclkFrequency;
0401
0402 gpu_metrics->current_gfxclk = metrics.Current.GfxclkFrequency;
0403 gpu_metrics->current_socclk = metrics.Current.SocclkFrequency;
0404 gpu_metrics->current_uclk = metrics.Current.MemclkFrequency;
0405 gpu_metrics->current_fclk = metrics.Current.MemclkFrequency;
0406 gpu_metrics->current_vclk = metrics.Current.VclkFrequency;
0407 gpu_metrics->current_dclk = metrics.Current.DclkFrequency;
0408
0409 for (i = 0; i < 6; i++) {
0410 gpu_metrics->temperature_core[i] = metrics.Current.CoreTemperature[i];
0411 gpu_metrics->average_core_power[i] = metrics.Average.CorePower[i];
0412 gpu_metrics->current_coreclk[i] = metrics.Current.CoreFrequency[i];
0413 }
0414
0415 for (i = 0; i < 2; i++) {
0416 gpu_metrics->temperature_l3[i] = metrics.Current.L3Temperature[i];
0417 gpu_metrics->current_l3clk[i] = metrics.Current.L3Frequency[i];
0418 }
0419
0420 gpu_metrics->throttle_status = metrics.Current.ThrottlerStatus;
0421 gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
0422
0423 *table = (void *)gpu_metrics;
0424
0425 return sizeof(struct gpu_metrics_v2_2);
0426 }
0427
0428 static int cyan_skillfish_od_edit_dpm_table(struct smu_context *smu,
0429 enum PP_OD_DPM_TABLE_COMMAND type,
0430 long input[], uint32_t size)
0431 {
0432 int ret = 0;
0433 uint32_t vid;
0434
0435 switch (type) {
0436 case PP_OD_EDIT_VDDC_CURVE:
0437 if (size != 3 || input[0] != 0) {
0438 dev_err(smu->adev->dev, "Invalid parameter!\n");
0439 return -EINVAL;
0440 }
0441
0442 if (input[1] < CYAN_SKILLFISH_SCLK_MIN ||
0443 input[1] > CYAN_SKILLFISH_SCLK_MAX) {
0444 dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n",
0445 CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
0446 return -EINVAL;
0447 }
0448
0449 if (input[2] < CYAN_SKILLFISH_VDDC_MIN ||
0450 input[2] > CYAN_SKILLFISH_VDDC_MAX) {
0451 dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n",
0452 CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
0453 return -EINVAL;
0454 }
0455
0456 cyan_skillfish_user_settings.sclk = input[1];
0457 cyan_skillfish_user_settings.vddc = input[2];
0458
0459 break;
0460 case PP_OD_RESTORE_DEFAULT_TABLE:
0461 if (size != 0) {
0462 dev_err(smu->adev->dev, "Invalid parameter!\n");
0463 return -EINVAL;
0464 }
0465
0466 cyan_skillfish_user_settings.sclk = cyan_skillfish_sclk_default;
0467 cyan_skillfish_user_settings.vddc = CYAN_SKILLFISH_VDDC_MAGIC;
0468
0469 break;
0470 case PP_OD_COMMIT_DPM_TABLE:
0471 if (size != 0) {
0472 dev_err(smu->adev->dev, "Invalid parameter!\n");
0473 return -EINVAL;
0474 }
0475
0476 if (cyan_skillfish_user_settings.sclk < CYAN_SKILLFISH_SCLK_MIN ||
0477 cyan_skillfish_user_settings.sclk > CYAN_SKILLFISH_SCLK_MAX) {
0478 dev_err(smu->adev->dev, "Invalid sclk! Valid sclk range: %uMHz - %uMhz\n",
0479 CYAN_SKILLFISH_SCLK_MIN, CYAN_SKILLFISH_SCLK_MAX);
0480 return -EINVAL;
0481 }
0482
0483 if ((cyan_skillfish_user_settings.vddc != CYAN_SKILLFISH_VDDC_MAGIC) &&
0484 (cyan_skillfish_user_settings.vddc < CYAN_SKILLFISH_VDDC_MIN ||
0485 cyan_skillfish_user_settings.vddc > CYAN_SKILLFISH_VDDC_MAX)) {
0486 dev_err(smu->adev->dev, "Invalid vddc! Valid vddc range: %umV - %umV\n",
0487 CYAN_SKILLFISH_VDDC_MIN, CYAN_SKILLFISH_VDDC_MAX);
0488 return -EINVAL;
0489 }
0490
0491 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_RequestGfxclk,
0492 cyan_skillfish_user_settings.sclk, NULL);
0493 if (ret) {
0494 dev_err(smu->adev->dev, "Set sclk failed!\n");
0495 return ret;
0496 }
0497
0498 if (cyan_skillfish_user_settings.vddc == CYAN_SKILLFISH_VDDC_MAGIC) {
0499 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_UnforceGfxVid, NULL);
0500 if (ret) {
0501 dev_err(smu->adev->dev, "Unforce vddc failed!\n");
0502 return ret;
0503 }
0504 } else {
0505
0506
0507
0508
0509 vid = (1550 - cyan_skillfish_user_settings.vddc) * 160 / 1000;
0510 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ForceGfxVid, vid, NULL);
0511 if (ret) {
0512 dev_err(smu->adev->dev, "Force vddc failed!\n");
0513 return ret;
0514 }
0515 }
0516
0517 break;
0518 default:
0519 return -EOPNOTSUPP;
0520 }
0521
0522 return ret;
0523 }
0524
0525 static int cyan_skillfish_get_dpm_ultimate_freq(struct smu_context *smu,
0526 enum smu_clk_type clk_type,
0527 uint32_t *min,
0528 uint32_t *max)
0529 {
0530 int ret = 0;
0531 uint32_t low, high;
0532
0533 switch (clk_type) {
0534 case SMU_GFXCLK:
0535 case SMU_SCLK:
0536 low = CYAN_SKILLFISH_SCLK_MIN;
0537 high = CYAN_SKILLFISH_SCLK_MAX;
0538 break;
0539 default:
0540 ret = cyan_skillfish_get_current_clk_freq(smu, clk_type, &low);
0541 if (ret)
0542 return ret;
0543 high = low;
0544 break;
0545 }
0546
0547 if (min)
0548 *min = low;
0549 if (max)
0550 *max = high;
0551
0552 return 0;
0553 }
0554
0555 static int cyan_skillfish_get_enabled_mask(struct smu_context *smu,
0556 uint64_t *feature_mask)
0557 {
0558 if (!feature_mask)
0559 return -EINVAL;
0560 memset(feature_mask, 0xff, sizeof(*feature_mask));
0561
0562 return 0;
0563 }
0564
0565 static const struct pptable_funcs cyan_skillfish_ppt_funcs = {
0566
0567 .check_fw_status = smu_v11_0_check_fw_status,
0568 .check_fw_version = smu_v11_0_check_fw_version,
0569 .init_power = smu_v11_0_init_power,
0570 .fini_power = smu_v11_0_fini_power,
0571 .init_smc_tables = cyan_skillfish_init_smc_tables,
0572 .fini_smc_tables = smu_v11_0_fini_smc_tables,
0573 .read_sensor = cyan_skillfish_read_sensor,
0574 .print_clk_levels = cyan_skillfish_print_clk_levels,
0575 .get_enabled_mask = cyan_skillfish_get_enabled_mask,
0576 .is_dpm_running = cyan_skillfish_is_dpm_running,
0577 .get_gpu_metrics = cyan_skillfish_get_gpu_metrics,
0578 .od_edit_dpm_table = cyan_skillfish_od_edit_dpm_table,
0579 .get_dpm_ultimate_freq = cyan_skillfish_get_dpm_ultimate_freq,
0580 .register_irq_handler = smu_v11_0_register_irq_handler,
0581 .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
0582 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
0583 .send_smc_msg = smu_cmn_send_smc_msg,
0584 .set_driver_table_location = smu_v11_0_set_driver_table_location,
0585 .interrupt_work = smu_v11_0_interrupt_work,
0586 };
0587
0588 void cyan_skillfish_set_ppt_funcs(struct smu_context *smu)
0589 {
0590 smu->ppt_funcs = &cyan_skillfish_ppt_funcs;
0591 smu->message_map = cyan_skillfish_message_map;
0592 smu->table_map = cyan_skillfish_table_map;
0593 smu->is_apu = true;
0594 smu_v11_0_set_smu_mailbox_registers(smu);
0595 }