diff options
author | Eric Huang <JinHuiEric.Huang@amd.com> | 2016-05-19 15:50:09 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-07-07 14:50:48 -0400 |
commit | 19fbc43a863f743d30c49cd18e91b40b96f43964 (patch) | |
tree | 77fa07e639cb89b29f4324e8490aaa04a4b82c92 /drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |
parent | 8b2e574dc4bf18e86bc09bd15215a2d62a3008ee (diff) |
drm/amdgpu: add the CI code to enable clock level selection
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Eric Huang <JinHuiEric.Huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/ci_dpm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 102d400ef44e..1e9b8ce62925 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c | |||
@@ -6414,6 +6414,118 @@ static int ci_dpm_set_powergating_state(void *handle, | |||
6414 | return 0; | 6414 | return 0; |
6415 | } | 6415 | } |
6416 | 6416 | ||
6417 | static int ci_dpm_print_clock_levels(struct amdgpu_device *adev, | ||
6418 | enum pp_clock_type type, char *buf) | ||
6419 | { | ||
6420 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6421 | struct ci_single_dpm_table *sclk_table = &pi->dpm_table.sclk_table; | ||
6422 | struct ci_single_dpm_table *mclk_table = &pi->dpm_table.mclk_table; | ||
6423 | struct ci_single_dpm_table *pcie_table = &pi->dpm_table.pcie_speed_table; | ||
6424 | |||
6425 | int i, now, size = 0; | ||
6426 | uint32_t clock, pcie_speed; | ||
6427 | |||
6428 | switch (type) { | ||
6429 | case PP_SCLK: | ||
6430 | amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetSclkFrequency); | ||
6431 | clock = RREG32(mmSMC_MSG_ARG_0); | ||
6432 | |||
6433 | for (i = 0; i < sclk_table->count; i++) { | ||
6434 | if (clock > sclk_table->dpm_levels[i].value) | ||
6435 | continue; | ||
6436 | break; | ||
6437 | } | ||
6438 | now = i; | ||
6439 | |||
6440 | for (i = 0; i < sclk_table->count; i++) | ||
6441 | size += sprintf(buf + size, "%d: %uMhz %s\n", | ||
6442 | i, sclk_table->dpm_levels[i].value / 100, | ||
6443 | (i == now) ? "*" : ""); | ||
6444 | break; | ||
6445 | case PP_MCLK: | ||
6446 | amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetMclkFrequency); | ||
6447 | clock = RREG32(mmSMC_MSG_ARG_0); | ||
6448 | |||
6449 | for (i = 0; i < mclk_table->count; i++) { | ||
6450 | if (clock > mclk_table->dpm_levels[i].value) | ||
6451 | continue; | ||
6452 | break; | ||
6453 | } | ||
6454 | now = i; | ||
6455 | |||
6456 | for (i = 0; i < mclk_table->count; i++) | ||
6457 | size += sprintf(buf + size, "%d: %uMhz %s\n", | ||
6458 | i, mclk_table->dpm_levels[i].value / 100, | ||
6459 | (i == now) ? "*" : ""); | ||
6460 | break; | ||
6461 | case PP_PCIE: | ||
6462 | pcie_speed = ci_get_current_pcie_speed(adev); | ||
6463 | for (i = 0; i < pcie_table->count; i++) { | ||
6464 | if (pcie_speed != pcie_table->dpm_levels[i].value) | ||
6465 | continue; | ||
6466 | break; | ||
6467 | } | ||
6468 | now = i; | ||
6469 | |||
6470 | for (i = 0; i < pcie_table->count; i++) | ||
6471 | size += sprintf(buf + size, "%d: %s %s\n", i, | ||
6472 | (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" : | ||
6473 | (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : | ||
6474 | (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", | ||
6475 | (i == now) ? "*" : ""); | ||
6476 | break; | ||
6477 | default: | ||
6478 | break; | ||
6479 | } | ||
6480 | |||
6481 | return size; | ||
6482 | } | ||
6483 | |||
6484 | static int ci_dpm_force_clock_level(struct amdgpu_device *adev, | ||
6485 | enum pp_clock_type type, uint32_t mask) | ||
6486 | { | ||
6487 | struct ci_power_info *pi = ci_get_pi(adev); | ||
6488 | |||
6489 | if (adev->pm.dpm.forced_level | ||
6490 | != AMDGPU_DPM_FORCED_LEVEL_MANUAL) | ||
6491 | return -EINVAL; | ||
6492 | |||
6493 | switch (type) { | ||
6494 | case PP_SCLK: | ||
6495 | if (!pi->sclk_dpm_key_disabled) | ||
6496 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6497 | PPSMC_MSG_SCLKDPM_SetEnabledMask, | ||
6498 | pi->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); | ||
6499 | break; | ||
6500 | |||
6501 | case PP_MCLK: | ||
6502 | if (!pi->mclk_dpm_key_disabled) | ||
6503 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6504 | PPSMC_MSG_MCLKDPM_SetEnabledMask, | ||
6505 | pi->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); | ||
6506 | break; | ||
6507 | |||
6508 | case PP_PCIE: | ||
6509 | { | ||
6510 | uint32_t tmp = mask & pi->dpm_level_enable_mask.pcie_dpm_enable_mask; | ||
6511 | uint32_t level = 0; | ||
6512 | |||
6513 | while (tmp >>= 1) | ||
6514 | level++; | ||
6515 | |||
6516 | if (!pi->pcie_dpm_key_disabled) | ||
6517 | amdgpu_ci_send_msg_to_smc_with_parameter(adev, | ||
6518 | PPSMC_MSG_PCIeDPM_ForceLevel, | ||
6519 | level); | ||
6520 | break; | ||
6521 | } | ||
6522 | default: | ||
6523 | break; | ||
6524 | } | ||
6525 | |||
6526 | return 0; | ||
6527 | } | ||
6528 | |||
6417 | const struct amd_ip_funcs ci_dpm_ip_funcs = { | 6529 | const struct amd_ip_funcs ci_dpm_ip_funcs = { |
6418 | .name = "ci_dpm", | 6530 | .name = "ci_dpm", |
6419 | .early_init = ci_dpm_early_init, | 6531 | .early_init = ci_dpm_early_init, |
@@ -6448,6 +6560,8 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = { | |||
6448 | .get_fan_control_mode = &ci_dpm_get_fan_control_mode, | 6560 | .get_fan_control_mode = &ci_dpm_get_fan_control_mode, |
6449 | .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, | 6561 | .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, |
6450 | .get_fan_speed_percent = &ci_dpm_get_fan_speed_percent, | 6562 | .get_fan_speed_percent = &ci_dpm_get_fan_speed_percent, |
6563 | .print_clock_levels = ci_dpm_print_clock_levels, | ||
6564 | .force_clock_level = ci_dpm_force_clock_level, | ||
6451 | }; | 6565 | }; |
6452 | 6566 | ||
6453 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 6567 | static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) |