diff options
Diffstat (limited to 'drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c')
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/fiji_hwmgr.c | 404 |
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 | ||
582 | static int fiji_hwmgr_backend_fini(struct pp_hwmgr *hwmgr) | 582 | static 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 | ||
594 | static int fiji_hwmgr_backend_init(struct pp_hwmgr *hwmgr) | 587 | static 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 | ||
1238 | static 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 | */ | ||
1398 | static 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 | ||
1416 | static 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 | |||
1378 | static int fiji_reset_single_dpm_table(struct pp_hwmgr *hwmgr, | 1431 | static 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 | ||
1403 | static int fiji_setup_default_pcie_table(struct pp_hwmgr *hwmgr) | 1456 | static 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 | ||
3232 | static 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 | |||
3180 | static int fiji_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr) | 3243 | static 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 | ||
3263 | static 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 | |||
3200 | static int fiji_enable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr) | 3278 | static 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 | ||
3438 | static 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 | |||
3468 | static 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 | |||
3360 | static void fiji_set_dpm_event_sources(struct pp_hwmgr *hwmgr, | 3502 | static 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 | ||
3560 | static 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 | |||
3572 | static int fiji_disable_thermal_auto_throttle(struct pp_hwmgr *hwmgr) | ||
3573 | { | ||
3574 | return fiji_disable_auto_throttle_source(hwmgr, PHM_AutoThrottleSource_Thermal); | ||
3575 | } | ||
3576 | |||
3418 | static int fiji_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | 3577 | static 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 | ||
3691 | static 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 | |||
3532 | static int fiji_force_dpm_highest(struct pp_hwmgr *hwmgr) | 3749 | static 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, | |||
4353 | static int fiji_trim_dpm_states(struct pp_hwmgr *hwmgr, | 4572 | static 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 | ||
4379 | static int fiji_generate_dpm_level_enable_mask( | 4597 | static 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 | ||
5074 | static 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 | |||
5091 | static 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 | |||
5110 | static int fiji_force_clock_level(struct pp_hwmgr *hwmgr, | 5294 | static 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 | ||
5463 | static 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 | |||
5479 | static 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 | |||
5505 | static 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 | |||
5521 | static 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 | ||
5280 | static const struct pp_hwmgr_func fiji_hwmgr_funcs = { | 5547 | static 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 | ||
5323 | int fiji_hwmgr_init(struct pp_hwmgr *hwmgr) | 5593 | int 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 | } |