diff options
| author | Evan Quan <evan.quan@amd.com> | 2018-09-17 02:59:54 -0400 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2018-09-19 13:38:02 -0400 |
| commit | 32f2a0d117769bdca7f7ee6224659f2c688ebc85 (patch) | |
| tree | e8eaeffdd76b415db03428350474a361270cf052 /drivers/gpu | |
| parent | b1f82cb21231ccfec3c15b628f8deed778cce22b (diff) | |
drm/amd/powerplay: retrieve the updated clock table after OD
With OD settings applied, the clock table will be updated accordingly.
We need to retrieve the new clock tables then.
Signed-off-by: Evan Quan <evan.quan@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 114 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 2 |
2 files changed, 90 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 4f9bf6049d1c..d45cbfe8e184 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | |||
| @@ -514,6 +514,47 @@ static int vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr, | |||
| 514 | return ret; | 514 | return ret; |
| 515 | } | 515 | } |
| 516 | 516 | ||
| 517 | static int vega20_setup_gfxclk_dpm_table(struct pp_hwmgr *hwmgr) | ||
| 518 | { | ||
| 519 | struct vega20_hwmgr *data = | ||
| 520 | (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 521 | struct vega20_single_dpm_table *dpm_table; | ||
| 522 | int ret = 0; | ||
| 523 | |||
| 524 | dpm_table = &(data->dpm_table.gfx_table); | ||
| 525 | if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { | ||
| 526 | ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); | ||
| 527 | PP_ASSERT_WITH_CODE(!ret, | ||
| 528 | "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", | ||
| 529 | return ret); | ||
| 530 | } else { | ||
| 531 | dpm_table->count = 1; | ||
| 532 | dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100; | ||
| 533 | } | ||
| 534 | |||
| 535 | return ret; | ||
| 536 | } | ||
| 537 | |||
| 538 | static int vega20_setup_memclk_dpm_table(struct pp_hwmgr *hwmgr) | ||
| 539 | { | ||
| 540 | struct vega20_hwmgr *data = | ||
| 541 | (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 542 | struct vega20_single_dpm_table *dpm_table; | ||
| 543 | int ret = 0; | ||
| 544 | |||
| 545 | dpm_table = &(data->dpm_table.mem_table); | ||
| 546 | if (data->smu_features[GNLD_DPM_UCLK].enabled) { | ||
| 547 | ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); | ||
| 548 | PP_ASSERT_WITH_CODE(!ret, | ||
| 549 | "[SetupDefaultDpmTable] failed to get memclk dpm levels!", | ||
| 550 | return ret); | ||
| 551 | } else { | ||
| 552 | dpm_table->count = 1; | ||
| 553 | dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100; | ||
| 554 | } | ||
| 555 | |||
| 556 | return ret; | ||
| 557 | } | ||
| 517 | 558 | ||
| 518 | /* | 559 | /* |
| 519 | * This function is to initialize all DPM state tables | 560 | * This function is to initialize all DPM state tables |
| @@ -547,28 +588,16 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | |||
| 547 | 588 | ||
| 548 | /* gfxclk */ | 589 | /* gfxclk */ |
| 549 | dpm_table = &(data->dpm_table.gfx_table); | 590 | dpm_table = &(data->dpm_table.gfx_table); |
| 550 | if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { | 591 | ret = vega20_setup_gfxclk_dpm_table(hwmgr); |
| 551 | ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); | 592 | if (ret) |
| 552 | PP_ASSERT_WITH_CODE(!ret, | 593 | return ret; |
| 553 | "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", | ||
| 554 | return ret); | ||
| 555 | } else { | ||
| 556 | dpm_table->count = 1; | ||
| 557 | dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100; | ||
| 558 | } | ||
| 559 | vega20_init_dpm_state(&(dpm_table->dpm_state)); | 594 | vega20_init_dpm_state(&(dpm_table->dpm_state)); |
| 560 | 595 | ||
| 561 | /* memclk */ | 596 | /* memclk */ |
| 562 | dpm_table = &(data->dpm_table.mem_table); | 597 | dpm_table = &(data->dpm_table.mem_table); |
| 563 | if (data->smu_features[GNLD_DPM_UCLK].enabled) { | 598 | ret = vega20_setup_memclk_dpm_table(hwmgr); |
| 564 | ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); | 599 | if (ret) |
| 565 | PP_ASSERT_WITH_CODE(!ret, | 600 | return ret; |
| 566 | "[SetupDefaultDpmTable] failed to get memclk dpm levels!", | ||
| 567 | return ret); | ||
| 568 | } else { | ||
| 569 | dpm_table->count = 1; | ||
| 570 | dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100; | ||
| 571 | } | ||
| 572 | vega20_init_dpm_state(&(dpm_table->dpm_state)); | 601 | vega20_init_dpm_state(&(dpm_table->dpm_state)); |
| 573 | 602 | ||
| 574 | /* eclk */ | 603 | /* eclk */ |
| @@ -1181,6 +1210,9 @@ static int vega20_od8_set_settings( | |||
| 1181 | { | 1210 | { |
| 1182 | OverDriveTable_t od_table; | 1211 | OverDriveTable_t od_table; |
| 1183 | int ret = 0; | 1212 | int ret = 0; |
| 1213 | struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); | ||
| 1214 | struct vega20_od8_single_setting *od8_settings = | ||
| 1215 | data->od8_settings.od8_settings_array; | ||
| 1184 | 1216 | ||
| 1185 | ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE); | 1217 | ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE); |
| 1186 | PP_ASSERT_WITH_CODE(!ret, | 1218 | PP_ASSERT_WITH_CODE(!ret, |
| @@ -1192,6 +1224,10 @@ static int vega20_od8_set_settings( | |||
| 1192 | od_table.GfxclkFmin = (uint16_t)value; | 1224 | od_table.GfxclkFmin = (uint16_t)value; |
| 1193 | break; | 1225 | break; |
| 1194 | case OD8_SETTING_GFXCLK_FMAX: | 1226 | case OD8_SETTING_GFXCLK_FMAX: |
| 1227 | if (value < od8_settings[OD8_SETTING_GFXCLK_FMAX].min_value || | ||
| 1228 | value > od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value) | ||
| 1229 | return -EINVAL; | ||
| 1230 | |||
| 1195 | od_table.GfxclkFmax = (uint16_t)value; | 1231 | od_table.GfxclkFmax = (uint16_t)value; |
| 1196 | break; | 1232 | break; |
| 1197 | case OD8_SETTING_GFXCLK_FREQ1: | 1233 | case OD8_SETTING_GFXCLK_FREQ1: |
| @@ -1213,6 +1249,9 @@ static int vega20_od8_set_settings( | |||
| 1213 | od_table.GfxclkVolt3 = (uint16_t)value; | 1249 | od_table.GfxclkVolt3 = (uint16_t)value; |
| 1214 | break; | 1250 | break; |
| 1215 | case OD8_SETTING_UCLK_FMAX: | 1251 | case OD8_SETTING_UCLK_FMAX: |
| 1252 | if (value < od8_settings[OD8_SETTING_UCLK_FMAX].min_value || | ||
| 1253 | value > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) | ||
| 1254 | return -EINVAL; | ||
| 1216 | od_table.UclkFmax = (uint16_t)value; | 1255 | od_table.UclkFmax = (uint16_t)value; |
| 1217 | break; | 1256 | break; |
| 1218 | case OD8_SETTING_POWER_PERCENTAGE: | 1257 | case OD8_SETTING_POWER_PERCENTAGE: |
| @@ -1262,8 +1301,6 @@ static int vega20_set_sclk_od( | |||
| 1262 | struct pp_hwmgr *hwmgr, uint32_t value) | 1301 | struct pp_hwmgr *hwmgr, uint32_t value) |
| 1263 | { | 1302 | { |
| 1264 | struct vega20_hwmgr *data = hwmgr->backend; | 1303 | struct vega20_hwmgr *data = hwmgr->backend; |
| 1265 | struct vega20_single_dpm_table *sclk_table = | ||
| 1266 | &(data->dpm_table.gfx_table); | ||
| 1267 | struct vega20_single_dpm_table *golden_sclk_table = | 1304 | struct vega20_single_dpm_table *golden_sclk_table = |
| 1268 | &(data->golden_dpm_table.gfx_table); | 1305 | &(data->golden_dpm_table.gfx_table); |
| 1269 | uint32_t od_sclk; | 1306 | uint32_t od_sclk; |
| @@ -1278,8 +1315,8 @@ static int vega20_set_sclk_od( | |||
| 1278 | "[SetSclkOD] failed to set od gfxclk!", | 1315 | "[SetSclkOD] failed to set od gfxclk!", |
| 1279 | return ret); | 1316 | return ret); |
| 1280 | 1317 | ||
| 1281 | /* refresh gfxclk table */ | 1318 | /* retrieve updated gfxclk table */ |
| 1282 | ret = vega20_setup_single_dpm_table(hwmgr, sclk_table, PPCLK_GFXCLK); | 1319 | ret = vega20_setup_gfxclk_dpm_table(hwmgr); |
| 1283 | PP_ASSERT_WITH_CODE(!ret, | 1320 | PP_ASSERT_WITH_CODE(!ret, |
| 1284 | "[SetSclkOD] failed to refresh gfxclk table!", | 1321 | "[SetSclkOD] failed to refresh gfxclk table!", |
| 1285 | return ret); | 1322 | return ret); |
| @@ -1309,8 +1346,6 @@ static int vega20_set_mclk_od( | |||
| 1309 | struct pp_hwmgr *hwmgr, uint32_t value) | 1346 | struct pp_hwmgr *hwmgr, uint32_t value) |
| 1310 | { | 1347 | { |
| 1311 | struct vega20_hwmgr *data = hwmgr->backend; | 1348 | struct vega20_hwmgr *data = hwmgr->backend; |
| 1312 | struct vega20_single_dpm_table *mclk_table = | ||
| 1313 | &(data->dpm_table.mem_table); | ||
| 1314 | struct vega20_single_dpm_table *golden_mclk_table = | 1349 | struct vega20_single_dpm_table *golden_mclk_table = |
| 1315 | &(data->golden_dpm_table.mem_table); | 1350 | &(data->golden_dpm_table.mem_table); |
| 1316 | uint32_t od_mclk; | 1351 | uint32_t od_mclk; |
| @@ -1325,8 +1360,8 @@ static int vega20_set_mclk_od( | |||
| 1325 | "[SetMclkOD] failed to set od memclk!", | 1360 | "[SetMclkOD] failed to set od memclk!", |
| 1326 | return ret); | 1361 | return ret); |
| 1327 | 1362 | ||
| 1328 | /* refresh memclk table */ | 1363 | /* retrieve updated memclk table */ |
| 1329 | ret = vega20_setup_single_dpm_table(hwmgr, mclk_table, PPCLK_UCLK); | 1364 | ret = vega20_setup_memclk_dpm_table(hwmgr); |
| 1330 | PP_ASSERT_WITH_CODE(!ret, | 1365 | PP_ASSERT_WITH_CODE(!ret, |
| 1331 | "[SetMclkOD] failed to refresh memclk table!", | 1366 | "[SetMclkOD] failed to refresh memclk table!", |
| 1332 | return ret); | 1367 | return ret); |
| @@ -2451,6 +2486,10 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, | |||
| 2451 | return -EINVAL; | 2486 | return -EINVAL; |
| 2452 | } | 2487 | } |
| 2453 | 2488 | ||
| 2489 | if ((input_index == 0 && od_table->GfxclkFmin != input_clk) || | ||
| 2490 | (input_index == 1 && od_table->GfxclkFmax != input_clk)) | ||
| 2491 | data->gfxclk_overdrive = true; | ||
| 2492 | |||
| 2454 | if (input_index == 0) | 2493 | if (input_index == 0) |
| 2455 | od_table->GfxclkFmin = input_clk; | 2494 | od_table->GfxclkFmin = input_clk; |
| 2456 | else | 2495 | else |
| @@ -2495,6 +2534,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, | |||
| 2495 | return -EINVAL; | 2534 | return -EINVAL; |
| 2496 | } | 2535 | } |
| 2497 | 2536 | ||
| 2537 | if (input_index == 1 && od_table->UclkFmax != input_clk) | ||
| 2538 | data->memclk_overdrive = true; | ||
| 2539 | |||
| 2498 | od_table->UclkFmax = input_clk; | 2540 | od_table->UclkFmax = input_clk; |
| 2499 | } | 2541 | } |
| 2500 | 2542 | ||
| @@ -2567,6 +2609,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, | |||
| 2567 | break; | 2609 | break; |
| 2568 | 2610 | ||
| 2569 | case PP_OD_RESTORE_DEFAULT_TABLE: | 2611 | case PP_OD_RESTORE_DEFAULT_TABLE: |
| 2612 | data->gfxclk_overdrive = false; | ||
| 2613 | data->memclk_overdrive = false; | ||
| 2614 | |||
| 2570 | ret = vega20_copy_table_from_smc(hwmgr, | 2615 | ret = vega20_copy_table_from_smc(hwmgr, |
| 2571 | (uint8_t *)od_table, | 2616 | (uint8_t *)od_table, |
| 2572 | TABLE_OVERDRIVE); | 2617 | TABLE_OVERDRIVE); |
| @@ -2583,6 +2628,23 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, | |||
| 2583 | "Failed to import overdrive table!", | 2628 | "Failed to import overdrive table!", |
| 2584 | return ret); | 2629 | return ret); |
| 2585 | 2630 | ||
| 2631 | /* retrieve updated gfxclk table */ | ||
| 2632 | if (data->gfxclk_overdrive) { | ||
| 2633 | data->gfxclk_overdrive = false; | ||
| 2634 | |||
| 2635 | ret = vega20_setup_gfxclk_dpm_table(hwmgr); | ||
| 2636 | if (ret) | ||
| 2637 | return ret; | ||
| 2638 | } | ||
| 2639 | |||
| 2640 | /* retrieve updated memclk table */ | ||
| 2641 | if (data->memclk_overdrive) { | ||
| 2642 | data->memclk_overdrive = false; | ||
| 2643 | |||
| 2644 | ret = vega20_setup_memclk_dpm_table(hwmgr); | ||
| 2645 | if (ret) | ||
| 2646 | return ret; | ||
| 2647 | } | ||
| 2586 | break; | 2648 | break; |
| 2587 | 2649 | ||
| 2588 | default: | 2650 | default: |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h index b71a5f25c734..56fe6a0d42e8 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h | |||
| @@ -502,6 +502,8 @@ struct vega20_hwmgr { | |||
| 502 | 502 | ||
| 503 | /* ---- Overdrive next setting ---- */ | 503 | /* ---- Overdrive next setting ---- */ |
| 504 | struct vega20_odn_data odn_data; | 504 | struct vega20_odn_data odn_data; |
| 505 | bool gfxclk_overdrive; | ||
| 506 | bool memclk_overdrive; | ||
| 505 | 507 | ||
| 506 | /* ---- Overdrive8 Setting ---- */ | 508 | /* ---- Overdrive8 Setting ---- */ |
| 507 | struct vega20_od8_settings od8_settings; | 509 | struct vega20_od8_settings od8_settings; |
