aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c')
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c404
1 files changed, 333 insertions, 71 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
index 92912ab20944..120a9e2c3152 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c
@@ -581,25 +581,24 @@ static int fiji_patch_boot_state(struct pp_hwmgr *hwmgr,
581 581
582static int fiji_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) 582static int fiji_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
583{ 583{
584 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
585
586 if (data->soft_pp_table) {
587 kfree(data->soft_pp_table);
588 data->soft_pp_table = NULL;
589 }
590
591 return phm_hwmgr_backend_fini(hwmgr); 584 return phm_hwmgr_backend_fini(hwmgr);
592} 585}
593 586
594static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) 587static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
595{ 588{
596 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 589 struct fiji_hwmgr *data;
597 uint32_t i; 590 uint32_t i;
598 struct phm_ppt_v1_information *table_info = 591 struct phm_ppt_v1_information *table_info =
599 (struct phm_ppt_v1_information *)(hwmgr->pptable); 592 (struct phm_ppt_v1_information *)(hwmgr->pptable);
600 bool stay_in_boot; 593 bool stay_in_boot;
601 int result; 594 int result;
602 595
596 data = kzalloc(sizeof(struct fiji_hwmgr), GFP_KERNEL);
597 if (data == NULL)
598 return -ENOMEM;
599
600 hwmgr->backend = data;
601
603 data->dll_default_on = false; 602 data->dll_default_on = false;
604 data->sram_end = SMC_RAM_END; 603 data->sram_end = SMC_RAM_END;
605 604
@@ -699,7 +698,7 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
699 if (0 == result) { 698 if (0 == result) {
700 struct cgs_system_info sys_info = {0}; 699 struct cgs_system_info sys_info = {0};
701 700
702 data->is_tlu_enabled = 0; 701 data->is_tlu_enabled = false;
703 hwmgr->platform_descriptor.hardwareActivityPerformanceLevels = 702 hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
704 FIJI_MAX_HARDWARE_POWERLEVELS; 703 FIJI_MAX_HARDWARE_POWERLEVELS;
705 hwmgr->platform_descriptor.hardwarePerformanceLevels = 2; 704 hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
@@ -734,7 +733,7 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
734 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO; 733 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_GEN_INFO;
735 result = cgs_query_system_info(hwmgr->device, &sys_info); 734 result = cgs_query_system_info(hwmgr->device, &sys_info);
736 if (result) 735 if (result)
737 data->pcie_gen_cap = 0x30007; 736 data->pcie_gen_cap = AMDGPU_DEFAULT_PCIE_GEN_MASK;
738 else 737 else
739 data->pcie_gen_cap = (uint32_t)sys_info.value; 738 data->pcie_gen_cap = (uint32_t)sys_info.value;
740 if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) 739 if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
@@ -743,7 +742,7 @@ static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
743 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW; 742 sys_info.info_id = CGS_SYSTEM_INFO_PCIE_MLW;
744 result = cgs_query_system_info(hwmgr->device, &sys_info); 743 result = cgs_query_system_info(hwmgr->device, &sys_info);
745 if (result) 744 if (result)
746 data->pcie_lane_cap = 0x2f0000; 745 data->pcie_lane_cap = AMDGPU_DEFAULT_PCIE_MLW_MASK;
747 else 746 else
748 data->pcie_lane_cap = (uint32_t)sys_info.value; 747 data->pcie_lane_cap = (uint32_t)sys_info.value;
749 } else { 748 } else {
@@ -1236,6 +1235,34 @@ static int fiji_program_voting_clients(struct pp_hwmgr *hwmgr)
1236 return 0; 1235 return 0;
1237} 1236}
1238 1237
1238static int fiji_clear_voting_clients(struct pp_hwmgr *hwmgr)
1239{
1240 /* Reset voting clients before disabling DPM */
1241 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
1242 SCLK_PWRMGT_CNTL, RESET_SCLK_CNT, 1);
1243 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
1244 SCLK_PWRMGT_CNTL, RESET_BUSY_CNT, 1);
1245
1246 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1247 ixCG_FREQ_TRAN_VOTING_0, 0);
1248 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1249 ixCG_FREQ_TRAN_VOTING_1, 0);
1250 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1251 ixCG_FREQ_TRAN_VOTING_2, 0);
1252 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1253 ixCG_FREQ_TRAN_VOTING_3, 0);
1254 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1255 ixCG_FREQ_TRAN_VOTING_4, 0);
1256 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1257 ixCG_FREQ_TRAN_VOTING_5, 0);
1258 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1259 ixCG_FREQ_TRAN_VOTING_6, 0);
1260 cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC,
1261 ixCG_FREQ_TRAN_VOTING_7, 0);
1262
1263 return 0;
1264}
1265
1239/** 1266/**
1240* Get the location of various tables inside the FW image. 1267* Get the location of various tables inside the FW image.
1241* 1268*
@@ -1363,6 +1390,17 @@ static int fiji_copy_and_switch_arb_sets(struct pp_hwmgr *hwmgr,
1363} 1390}
1364 1391
1365/** 1392/**
1393* Call SMC to reset S0/S1 to S1 and Reset SMIO to initial value
1394*
1395* @param hwmgr the address of the powerplay hardware manager.
1396* @return if success then 0;
1397*/
1398static int fiji_reset_to_default(struct pp_hwmgr *hwmgr)
1399{
1400 return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_ResetToDefaults);
1401}
1402
1403/**
1366* Initial switch from ARB F0->F1 1404* Initial switch from ARB F0->F1
1367* 1405*
1368* @param hwmgr the address of the powerplay hardware manager. 1406* @param hwmgr the address of the powerplay hardware manager.
@@ -1375,6 +1413,21 @@ static int fiji_initial_switch_from_arbf0_to_f1(struct pp_hwmgr *hwmgr)
1375 MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1); 1413 MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
1376} 1414}
1377 1415
1416static int fiji_force_switch_to_arbf0(struct pp_hwmgr *hwmgr)
1417{
1418 uint32_t tmp;
1419
1420 tmp = (cgs_read_ind_register(hwmgr->device,
1421 CGS_IND_REG__SMC, ixSMC_SCRATCH9) &
1422 0x0000ff00) >> 8;
1423
1424 if (tmp == MC_CG_ARB_FREQ_F0)
1425 return 0;
1426
1427 return fiji_copy_and_switch_arb_sets(hwmgr,
1428 tmp, MC_CG_ARB_FREQ_F0);
1429}
1430
1378static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr, 1431static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr,
1379 struct fiji_single_dpm_table *dpm_table, uint32_t count) 1432 struct fiji_single_dpm_table *dpm_table, uint32_t count)
1380{ 1433{
@@ -1397,7 +1450,7 @@ static void fiji_setup_pcie_table_entry(
1397{ 1450{
1398 dpm_table->dpm_levels[index].value = pcie_gen; 1451 dpm_table->dpm_levels[index].value = pcie_gen;
1399 dpm_table->dpm_levels[index].param1 = pcie_lanes; 1452 dpm_table->dpm_levels[index].param1 = pcie_lanes;
1400 dpm_table->dpm_levels[index].enabled = 1; 1453 dpm_table->dpm_levels[index].enabled = true;
1401} 1454}
1402 1455
1403static int fiji_setup_default_pcie_table(struct pp_hwmgr *hwmgr) 1456static int fiji_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
@@ -1609,7 +1662,6 @@ static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr,
1609{ 1662{
1610 uint32_t count; 1663 uint32_t count;
1611 uint8_t index; 1664 uint8_t index;
1612 int result = 0;
1613 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 1665 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
1614 struct phm_ppt_v1_information *table_info = 1666 struct phm_ppt_v1_information *table_info =
1615 (struct phm_ppt_v1_information *)(hwmgr->pptable); 1667 (struct phm_ppt_v1_information *)(hwmgr->pptable);
@@ -1631,7 +1683,7 @@ static int fiji_populate_cac_table(struct pp_hwmgr *hwmgr,
1631 VOLTAGE_SCALE)) / 25); 1683 VOLTAGE_SCALE)) / 25);
1632 } 1684 }
1633 1685
1634 return result; 1686 return 0;
1635} 1687}
1636 1688
1637/** 1689/**
@@ -3177,6 +3229,17 @@ static int fiji_enable_ulv(struct pp_hwmgr *hwmgr)
3177 return 0; 3229 return 0;
3178} 3230}
3179 3231
3232static int fiji_disable_ulv(struct pp_hwmgr *hwmgr)
3233{
3234 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
3235 struct fiji_ulv_parm *ulv = &(data->ulv);
3236
3237 if (ulv->ulv_supported)
3238 return smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DisableULV);
3239
3240 return 0;
3241}
3242
3180static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) 3243static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
3181{ 3244{
3182 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, 3245 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
@@ -3197,6 +3260,21 @@ static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
3197 return 0; 3260 return 0;
3198} 3261}
3199 3262
3263static int fiji_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
3264{
3265 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3266 PHM_PlatformCaps_SclkDeepSleep)) {
3267 if (smum_send_msg_to_smc(hwmgr->smumgr,
3268 PPSMC_MSG_MASTER_DeepSleep_OFF)) {
3269 PP_ASSERT_WITH_CODE(false,
3270 "Attempt to disable Master Deep Sleep switch failed!",
3271 return -1);
3272 }
3273 }
3274
3275 return 0;
3276}
3277
3200static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) 3278static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
3201{ 3279{
3202 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 3280 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
@@ -3357,6 +3435,70 @@ static int fiji_start_dpm(struct pp_hwmgr *hwmgr)
3357 return 0; 3435 return 0;
3358} 3436}
3359 3437
3438static int fiji_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
3439{
3440 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
3441
3442 /* disable SCLK dpm */
3443 if (!data->sclk_dpm_key_disabled)
3444 PP_ASSERT_WITH_CODE(
3445 (smum_send_msg_to_smc(hwmgr->smumgr,
3446 PPSMC_MSG_DPM_Disable) == 0),
3447 "Failed to disable SCLK DPM!",
3448 return -1);
3449
3450 /* disable MCLK dpm */
3451 if (!data->mclk_dpm_key_disabled) {
3452 PP_ASSERT_WITH_CODE(
3453 (smum_send_msg_to_smc_with_parameter(hwmgr->smumgr,
3454 PPSMC_MSG_MCLKDPM_SetEnabledMask, 1) == 0),
3455 "Failed to force MCLK DPM0!",
3456 return -1);
3457
3458 PP_ASSERT_WITH_CODE(
3459 (smum_send_msg_to_smc(hwmgr->smumgr,
3460 PPSMC_MSG_MCLKDPM_Disable) == 0),
3461 "Failed to disable MCLK DPM!",
3462 return -1);
3463 }
3464
3465 return 0;
3466}
3467
3468static int fiji_stop_dpm(struct pp_hwmgr *hwmgr)
3469{
3470 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
3471
3472 /* disable general power management */
3473 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, GENERAL_PWRMGT,
3474 GLOBAL_PWRMGT_EN, 0);
3475 /* disable sclk deep sleep */
3476 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, SCLK_PWRMGT_CNTL,
3477 DYNAMIC_PM_EN, 0);
3478
3479 /* disable PCIE dpm */
3480 if (!data->pcie_dpm_key_disabled) {
3481 PP_ASSERT_WITH_CODE(
3482 (smum_send_msg_to_smc(hwmgr->smumgr,
3483 PPSMC_MSG_PCIeDPM_Disable) == 0),
3484 "Failed to disable pcie DPM during DPM Stop Function!",
3485 return -1);
3486 }
3487
3488 if (fiji_disable_sclk_mclk_dpm(hwmgr)) {
3489 printk(KERN_ERR "Failed to disable Sclk DPM and Mclk DPM!");
3490 return -1;
3491 }
3492
3493 PP_ASSERT_WITH_CODE(
3494 (smum_send_msg_to_smc(hwmgr->smumgr,
3495 PPSMC_MSG_Voltage_Cntl_Disable) == 0),
3496 "Failed to disable voltage DPM during DPM Stop Function!",
3497 return -1);
3498
3499 return 0;
3500}
3501
3360static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr, 3502static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr,
3361 uint32_t sources) 3503 uint32_t sources)
3362{ 3504{
@@ -3415,6 +3557,23 @@ static int fiji_enable_thermal_auto_throttle(struct pp_hwmgr *hwmgr)
3415 return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); 3557 return fiji_enable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
3416} 3558}
3417 3559
3560static int fiji_disable_auto_throttle_source(struct pp_hwmgr *hwmgr,
3561 PHM_AutoThrottleSource source)
3562{
3563 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
3564
3565 if (data->active_auto_throttle_sources & (1 << source)) {
3566 data->active_auto_throttle_sources &= ~(1 << source);
3567 fiji_set_dpm_event_sources(hwmgr, data->active_auto_throttle_sources);
3568 }
3569 return 0;
3570}
3571
3572static int fiji_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr)
3573{
3574 return fiji_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal);
3575}
3576
3418static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr) 3577static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
3419{ 3578{
3420 int tmp_result, result = 0; 3579 int tmp_result, result = 0;
@@ -3529,6 +3688,64 @@ static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
3529 return result; 3688 return result;
3530} 3689}
3531 3690
3691static int fiji_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
3692{
3693 int tmp_result, result = 0;
3694
3695 tmp_result = (fiji_is_dpm_running(hwmgr)) ? 0 : -1;
3696 PP_ASSERT_WITH_CODE(tmp_result == 0,
3697 "DPM is not running right now, no need to disable DPM!",
3698 return 0);
3699
3700 if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps,
3701 PHM_PlatformCaps_ThermalController))
3702 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
3703 GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, 1);
3704
3705 tmp_result = fiji_disable_power_containment(hwmgr);
3706 PP_ASSERT_WITH_CODE((tmp_result == 0),
3707 "Failed to disable power containment!", result = tmp_result);
3708
3709 tmp_result = fiji_disable_smc_cac(hwmgr);
3710 PP_ASSERT_WITH_CODE((tmp_result == 0),
3711 "Failed to disable SMC CAC!", result = tmp_result);
3712
3713 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
3714 CG_SPLL_SPREAD_SPECTRUM, SSEN, 0);
3715 PHM_WRITE_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC,
3716 GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, 0);
3717
3718 tmp_result = fiji_disable_thermal_auto_throttle(hwmgr);
3719 PP_ASSERT_WITH_CODE((tmp_result == 0),
3720 "Failed to disable thermal auto throttle!", result = tmp_result);
3721
3722 tmp_result = fiji_stop_dpm(hwmgr);
3723 PP_ASSERT_WITH_CODE((tmp_result == 0),
3724 "Failed to stop DPM!", result = tmp_result);
3725
3726 tmp_result = fiji_disable_deep_sleep_master_switch(hwmgr);
3727 PP_ASSERT_WITH_CODE((tmp_result == 0),
3728 "Failed to disable deep sleep master switch!", result = tmp_result);
3729
3730 tmp_result = fiji_disable_ulv(hwmgr);
3731 PP_ASSERT_WITH_CODE((tmp_result == 0),
3732 "Failed to disable ULV!", result = tmp_result);
3733
3734 tmp_result = fiji_clear_voting_clients(hwmgr);
3735 PP_ASSERT_WITH_CODE((tmp_result == 0),
3736 "Failed to clear voting clients!", result = tmp_result);
3737
3738 tmp_result = fiji_reset_to_default(hwmgr);
3739 PP_ASSERT_WITH_CODE((tmp_result == 0),
3740 "Failed to reset to default!", result = tmp_result);
3741
3742 tmp_result = fiji_force_switch_to_arbf0(hwmgr);
3743 PP_ASSERT_WITH_CODE((tmp_result == 0),
3744 "Failed to force to switch arbf0!", result = tmp_result);
3745
3746 return result;
3747}
3748
3532static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr) 3749static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr)
3533{ 3750{
3534 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 3751 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
@@ -4171,8 +4388,9 @@ static int fiji_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4171 if ((0 == data->sclk_dpm_key_disabled) && 4388 if ((0 == data->sclk_dpm_key_disabled) &&
4172 (data->need_update_smu7_dpm_table & 4389 (data->need_update_smu7_dpm_table &
4173 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) { 4390 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
4174 PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr), 4391 PP_ASSERT_WITH_CODE(fiji_is_dpm_running(hwmgr),
4175 "Trying to freeze SCLK DPM when DPM is disabled",); 4392 "Trying to freeze SCLK DPM when DPM is disabled",
4393 );
4176 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr, 4394 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
4177 PPSMC_MSG_SCLKDPM_FreezeLevel), 4395 PPSMC_MSG_SCLKDPM_FreezeLevel),
4178 "Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!", 4396 "Failed to freeze SCLK DPM during FreezeSclkMclkDPM Function!",
@@ -4182,8 +4400,9 @@ static int fiji_freeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4182 if ((0 == data->mclk_dpm_key_disabled) && 4400 if ((0 == data->mclk_dpm_key_disabled) &&
4183 (data->need_update_smu7_dpm_table & 4401 (data->need_update_smu7_dpm_table &
4184 DPMTABLE_OD_UPDATE_MCLK)) { 4402 DPMTABLE_OD_UPDATE_MCLK)) {
4185 PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr), 4403 PP_ASSERT_WITH_CODE(fiji_is_dpm_running(hwmgr),
4186 "Trying to freeze MCLK DPM when DPM is disabled",); 4404 "Trying to freeze MCLK DPM when DPM is disabled",
4405 );
4187 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr, 4406 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
4188 PPSMC_MSG_MCLKDPM_FreezeLevel), 4407 PPSMC_MSG_MCLKDPM_FreezeLevel),
4189 "Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!", 4408 "Failed to freeze MCLK DPM during FreezeSclkMclkDPM Function!",
@@ -4353,7 +4572,6 @@ static int fiji_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
4353static int fiji_trim_dpm_states(struct pp_hwmgr *hwmgr, 4572static int fiji_trim_dpm_states(struct pp_hwmgr *hwmgr,
4354 const struct fiji_power_state *fiji_ps) 4573 const struct fiji_power_state *fiji_ps)
4355{ 4574{
4356 int result = 0;
4357 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend); 4575 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
4358 uint32_t high_limit_count; 4576 uint32_t high_limit_count;
4359 4577
@@ -4373,7 +4591,7 @@ static int fiji_trim_dpm_states(struct pp_hwmgr *hwmgr,
4373 fiji_ps->performance_levels[0].memory_clock, 4591 fiji_ps->performance_levels[0].memory_clock,
4374 fiji_ps->performance_levels[high_limit_count].memory_clock); 4592 fiji_ps->performance_levels[high_limit_count].memory_clock);
4375 4593
4376 return result; 4594 return 0;
4377} 4595}
4378 4596
4379static int fiji_generate_dpm_level_enable_mask( 4597static int fiji_generate_dpm_level_enable_mask(
@@ -4632,8 +4850,9 @@ static int fiji_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4632 (data->need_update_smu7_dpm_table & 4850 (data->need_update_smu7_dpm_table &
4633 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) { 4851 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK))) {
4634 4852
4635 PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr), 4853 PP_ASSERT_WITH_CODE(fiji_is_dpm_running(hwmgr),
4636 "Trying to Unfreeze SCLK DPM when DPM is disabled",); 4854 "Trying to Unfreeze SCLK DPM when DPM is disabled",
4855 );
4637 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr, 4856 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
4638 PPSMC_MSG_SCLKDPM_UnfreezeLevel), 4857 PPSMC_MSG_SCLKDPM_UnfreezeLevel),
4639 "Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!", 4858 "Failed to unfreeze SCLK DPM during UnFreezeSclkMclkDPM Function!",
@@ -4643,8 +4862,9 @@ static int fiji_unfreeze_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
4643 if ((0 == data->mclk_dpm_key_disabled) && 4862 if ((0 == data->mclk_dpm_key_disabled) &&
4644 (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) { 4863 (data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_MCLK)) {
4645 4864
4646 PP_ASSERT_WITH_CODE(true == fiji_is_dpm_running(hwmgr), 4865 PP_ASSERT_WITH_CODE(fiji_is_dpm_running(hwmgr),
4647 "Trying to Unfreeze MCLK DPM when DPM is disabled",); 4866 "Trying to Unfreeze MCLK DPM when DPM is disabled",
4867 );
4648 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr, 4868 PP_ASSERT_WITH_CODE(0 == smum_send_msg_to_smc(hwmgr->smumgr,
4649 PPSMC_MSG_SCLKDPM_UnfreezeLevel), 4869 PPSMC_MSG_SCLKDPM_UnfreezeLevel),
4650 "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!", 4870 "Failed to unfreeze MCLK DPM during UnFreezeSclkMclkDPM Function!",
@@ -5071,42 +5291,6 @@ static int fiji_get_fan_control_mode(struct pp_hwmgr *hwmgr)
5071 CG_FDO_CTRL2, FDO_PWM_MODE); 5291 CG_FDO_CTRL2, FDO_PWM_MODE);
5072} 5292}
5073 5293
5074static int fiji_get_pp_table(struct pp_hwmgr *hwmgr, char **table)
5075{
5076 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5077
5078 if (!data->soft_pp_table) {
5079 data->soft_pp_table = kmemdup(hwmgr->soft_pp_table,
5080 hwmgr->soft_pp_table_size,
5081 GFP_KERNEL);
5082 if (!data->soft_pp_table)
5083 return -ENOMEM;
5084 }
5085
5086 *table = (char *)&data->soft_pp_table;
5087
5088 return hwmgr->soft_pp_table_size;
5089}
5090
5091static int fiji_set_pp_table(struct pp_hwmgr *hwmgr, const char *buf, size_t size)
5092{
5093 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5094
5095 if (!data->soft_pp_table) {
5096 data->soft_pp_table = kzalloc(hwmgr->soft_pp_table_size, GFP_KERNEL);
5097 if (!data->soft_pp_table)
5098 return -ENOMEM;
5099 }
5100
5101 memcpy(data->soft_pp_table, buf, size);
5102
5103 hwmgr->soft_pp_table = data->soft_pp_table;
5104
5105 /* TODO: re-init powerplay to implement modified pptable */
5106
5107 return 0;
5108}
5109
5110static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, 5294static int fiji_force_clock_level(struct pp_hwmgr *hwmgr,
5111 enum pp_clock_type type, uint32_t mask) 5295 enum pp_clock_type type, uint32_t mask)
5112{ 5296{
@@ -5276,12 +5460,96 @@ bool fiji_check_smc_update_required_for_display_configuration(struct pp_hwmgr *h
5276 return is_update_required; 5460 return is_update_required;
5277} 5461}
5278 5462
5463static int fiji_get_sclk_od(struct pp_hwmgr *hwmgr)
5464{
5465 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5466 struct fiji_single_dpm_table *sclk_table = &(data->dpm_table.sclk_table);
5467 struct fiji_single_dpm_table *golden_sclk_table =
5468 &(data->golden_dpm_table.sclk_table);
5469 int value;
5470
5471 value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
5472 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
5473 100 /
5474 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
5475
5476 return value;
5477}
5478
5479static int fiji_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
5480{
5481 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5482 struct fiji_single_dpm_table *golden_sclk_table =
5483 &(data->golden_dpm_table.sclk_table);
5484 struct pp_power_state *ps;
5485 struct fiji_power_state *fiji_ps;
5486
5487 if (value > 20)
5488 value = 20;
5489
5490 ps = hwmgr->request_ps;
5491
5492 if (ps == NULL)
5493 return -EINVAL;
5494
5495 fiji_ps = cast_phw_fiji_power_state(&ps->hardware);
5496
5497 fiji_ps->performance_levels[fiji_ps->performance_level_count - 1].engine_clock =
5498 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value *
5499 value / 100 +
5500 golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
5501
5502 return 0;
5503}
5504
5505static int fiji_get_mclk_od(struct pp_hwmgr *hwmgr)
5506{
5507 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5508 struct fiji_single_dpm_table *mclk_table = &(data->dpm_table.mclk_table);
5509 struct fiji_single_dpm_table *golden_mclk_table =
5510 &(data->golden_dpm_table.mclk_table);
5511 int value;
5512
5513 value = (mclk_table->dpm_levels[mclk_table->count - 1].value -
5514 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) *
5515 100 /
5516 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
5517
5518 return value;
5519}
5520
5521static int fiji_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
5522{
5523 struct fiji_hwmgr *data = (struct fiji_hwmgr *)(hwmgr->backend);
5524 struct fiji_single_dpm_table *golden_mclk_table =
5525 &(data->golden_dpm_table.mclk_table);
5526 struct pp_power_state *ps;
5527 struct fiji_power_state *fiji_ps;
5528
5529 if (value > 20)
5530 value = 20;
5531
5532 ps = hwmgr->request_ps;
5533
5534 if (ps == NULL)
5535 return -EINVAL;
5536
5537 fiji_ps = cast_phw_fiji_power_state(&ps->hardware);
5538
5539 fiji_ps->performance_levels[fiji_ps->performance_level_count - 1].memory_clock =
5540 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value *
5541 value / 100 +
5542 golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value;
5543
5544 return 0;
5545}
5279 5546
5280static const struct pp_hwmgr_func fiji_hwmgr_funcs = { 5547static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
5281 .backend_init = &fiji_hwmgr_backend_init, 5548 .backend_init = &fiji_hwmgr_backend_init,
5282 .backend_fini = &fiji_hwmgr_backend_fini, 5549 .backend_fini = &fiji_hwmgr_backend_fini,
5283 .asic_setup = &fiji_setup_asic_task, 5550 .asic_setup = &fiji_setup_asic_task,
5284 .dynamic_state_management_enable = &fiji_enable_dpm_tasks, 5551 .dynamic_state_management_enable = &fiji_enable_dpm_tasks,
5552 .dynamic_state_management_disable = &fiji_disable_dpm_tasks,
5285 .force_dpm_level = &fiji_dpm_force_dpm_level, 5553 .force_dpm_level = &fiji_dpm_force_dpm_level,
5286 .get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries, 5554 .get_num_of_pp_table_entries = &tonga_get_number_of_powerplay_table_entries,
5287 .get_power_state_size = &fiji_get_power_state_size, 5555 .get_power_state_size = &fiji_get_power_state_size,
@@ -5314,24 +5582,18 @@ static const struct pp_hwmgr_func fiji_hwmgr_funcs = {
5314 .get_fan_control_mode = fiji_get_fan_control_mode, 5582 .get_fan_control_mode = fiji_get_fan_control_mode,
5315 .check_states_equal = fiji_check_states_equal, 5583 .check_states_equal = fiji_check_states_equal,
5316 .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration, 5584 .check_smc_update_required_for_display_configuration = fiji_check_smc_update_required_for_display_configuration,
5317 .get_pp_table = fiji_get_pp_table,
5318 .set_pp_table = fiji_set_pp_table,
5319 .force_clock_level = fiji_force_clock_level, 5585 .force_clock_level = fiji_force_clock_level,
5320 .print_clock_levels = fiji_print_clock_levels, 5586 .print_clock_levels = fiji_print_clock_levels,
5587 .get_sclk_od = fiji_get_sclk_od,
5588 .set_sclk_od = fiji_set_sclk_od,
5589 .get_mclk_od = fiji_get_mclk_od,
5590 .set_mclk_od = fiji_set_mclk_od,
5321}; 5591};
5322 5592
5323int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) 5593int fiji_hwmgr_init(struct pp_hwmgr *hwmgr)
5324{ 5594{
5325 struct fiji_hwmgr *data;
5326 int ret = 0;
5327
5328 data = kzalloc(sizeof(struct fiji_hwmgr), GFP_KERNEL);
5329 if (data == NULL)
5330 return -ENOMEM;
5331
5332 hwmgr->backend = data;
5333 hwmgr->hwmgr_func = &fiji_hwmgr_funcs; 5595 hwmgr->hwmgr_func = &fiji_hwmgr_funcs;
5334 hwmgr->pptable_func = &tonga_pptable_funcs; 5596 hwmgr->pptable_func = &tonga_pptable_funcs;
5335 pp_fiji_thermal_initialize(hwmgr); 5597 pp_fiji_thermal_initialize(hwmgr);
5336 return ret; 5598 return 0;
5337} 5599}