summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRex Zhu <Rex.Zhu@amd.com>2017-04-21 14:02:10 +0800
committerAlex Deucher <alexander.deucher@amd.com>2017-05-24 18:31:55 -0400
commitcd70f3d6e3fa816d516a22347292c4eda07cf8ee (patch)
treec0f2b07cd08d81fa3a3650c6ccc68afb17e70fe5
parent8f5508617b1356fafa8ba2960d7748ddbbc89964 (diff)
drm/amd/powerplay: PP/DAL interface changes for dynamic clock switch
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c131
1 files changed, 57 insertions, 74 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
index 654dd43b8639..75cede8bd8d5 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
@@ -837,78 +837,54 @@ static uint32_t rv_get_mem_latency(struct pp_hwmgr *hwmgr,
return MEM_LATENCY_ERR;
}
-static void rv_get_memclocks(struct pp_hwmgr *hwmgr,
+static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
+ enum amd_pp_clock_type type,
struct pp_clock_levels_with_latency *clocks)
{
- struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
- struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
- struct rv_voltage_dependency_table *pmclk_table;
uint32_t i;
-
- pmclk_table = pinfo->vdd_dep_on_mclk;
- clocks->num_levels = 0;
-
- for (i = 0; i < pmclk_table->count; i++) {
- if (pmclk_table->entries[i].clk) {
- clocks->data[clocks->num_levels].clocks_in_khz =
- pmclk_table->entries[i].clk;
- clocks->data[clocks->num_levels].latency_in_us =
- rv_get_mem_latency(hwmgr,
- pmclk_table->entries[i].clk);
- clocks->num_levels++;
- }
- }
-}
-
-static void rv_get_dcefclocks(struct pp_hwmgr *hwmgr,
- struct pp_clock_levels_with_latency *clocks)
-{
struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
- struct rv_voltage_dependency_table *pdcef_table;
- uint32_t i;
-
- pdcef_table = pinfo->vdd_dep_on_dcefclk;
- for (i = 0; i < pdcef_table->count; i++) {
- clocks->data[i].clocks_in_khz = pdcef_table->entries[i].clk;
- clocks->data[i].latency_in_us = 0;
- }
- clocks->num_levels = pdcef_table->count;
-}
-
-static void rv_get_socclocks(struct pp_hwmgr *hwmgr,
- struct pp_clock_levels_with_latency *clocks)
-{
- struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
- struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
- struct rv_voltage_dependency_table *psoc_table;
- uint32_t i;
-
- psoc_table = pinfo->vdd_dep_on_socclk;
+ struct rv_voltage_dependency_table *pclk_vol_table;
+ bool latency_required = false;
- for (i = 0; i < psoc_table->count; i++) {
- clocks->data[i].clocks_in_khz = psoc_table->entries[i].clk;
- clocks->data[i].latency_in_us = 0;
- }
- clocks->num_levels = psoc_table->count;
-}
+ if (pinfo == NULL)
+ return -EINVAL;
-static int rv_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
- enum amd_pp_clock_type type,
- struct pp_clock_levels_with_latency *clocks)
-{
switch (type) {
case amd_pp_mem_clock:
- rv_get_memclocks(hwmgr, clocks);
+ pclk_vol_table = pinfo->vdd_dep_on_mclk;
+ latency_required = true;
break;
- case amd_pp_dcef_clock:
- rv_get_dcefclocks(hwmgr, clocks);
+ case amd_pp_f_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_fclk;
+ latency_required = true;
break;
- case amd_pp_soc_clock:
- rv_get_socclocks(hwmgr, clocks);
+ case amd_pp_dcf_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
break;
+ case amd_pp_disp_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_dispclk;
+ break;
+ case amd_pp_phy_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_phyclk;
+ break;
+ case amd_pp_dpp_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_dppclk;
default:
- return -1;
+ return -EINVAL;
+ }
+
+ if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
+ return -EINVAL;
+
+ clocks->num_levels = 0;
+ for (i = 0; i < pclk_vol_table->count; i++) {
+ clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
+ clocks->data[i].latency_in_us = latency_required ?
+ rv_get_mem_latency(hwmgr,
+ pclk_vol_table->entries[i].clk) :
+ 0;
+ clocks->num_levels++;
}
return 0;
@@ -921,38 +897,38 @@ static int rv_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
uint32_t i;
struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
struct rv_clock_voltage_information *pinfo = &(rv_data->clock_vol_info);
- struct rv_voltage_dependency_table *pclk_vol_table;
+ struct rv_voltage_dependency_table *pclk_vol_table = NULL;
+
+ if (pinfo == NULL)
+ return -EINVAL;
switch (type) {
case amd_pp_mem_clock:
pclk_vol_table = pinfo->vdd_dep_on_mclk;
break;
- case amd_pp_dcef_clock:
- pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
+ case amd_pp_f_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_fclk;
break;
- case amd_pp_disp_clock:
- pclk_vol_table = pinfo->vdd_dep_on_dispclk;
+ case amd_pp_dcf_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
break;
- case amd_pp_phy_clock:
- pclk_vol_table = pinfo->vdd_dep_on_phyclk;
+ case amd_pp_soc_clock:
+ pclk_vol_table = pinfo->vdd_dep_on_socclk;
break;
- case amd_pp_dpp_clock:
- pclk_vol_table = pinfo->vdd_dep_on_dppclk;
default:
return -EINVAL;
}
- if (pclk_vol_table->count == 0)
+ if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
return -EINVAL;
+ clocks->num_levels = 0;
for (i = 0; i < pclk_vol_table->count; i++) {
clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
clocks->num_levels++;
}
- clocks->num_levels = pclk_vol_table->count;
-
return 0;
}
@@ -960,18 +936,25 @@ int rv_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
struct pp_display_clock_request *clock_req)
{
int result = 0;
+ struct rv_hwmgr *rv_data = (struct rv_hwmgr *)(hwmgr->backend);
enum amd_pp_clock_type clk_type = clock_req->clock_type;
- uint32_t clk_freq = clock_req->clock_freq_in_khz / 100;
+ uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
PPSMC_Msg msg;
switch (clk_type) {
- case amd_pp_dcef_clock:
+ case amd_pp_dcf_clock:
+ if (clk_freq == rv_data->dcf_actual_hard_min_freq)
+ return 0;
msg = PPSMC_MSG_SetHardMinDcefclkByFreq;
+ rv_data->dcf_actual_hard_min_freq = clk_freq;
break;
case amd_pp_soc_clock:
msg = PPSMC_MSG_SetHardMinSocclkByFreq;
break;
- case amd_pp_mem_clock:
+ case amd_pp_f_clock:
+ if (clk_freq == rv_data->f_actual_hard_min_freq)
+ return 0;
+ rv_data->f_actual_hard_min_freq = clk_freq;
msg = PPSMC_MSG_SetHardMinFclkByFreq;
break;
default: