Commit a39a5816 authored by Eric Yang's avatar Eric Yang Committed by Alex Deucher

drm/amd/display: fix inputting clk lvl into dml for RN

[Why]
Previous logic is only good for 15W parts. Other configuration
need a smarter logic to match clk levels with pp table in the fuse.

[How]
Cache all 8 DPM level's clock data, find lvl that match each pstate
in the pp table and build input into DML base on that
Signed-off-by: default avatarEric Yang <Eric.Yang2@amd.com>
Signed-off-by: default avatarSung Lee <sung.lee@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarBhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 71b81f12
...@@ -162,10 +162,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { ...@@ -162,10 +162,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
.clock_limits = { .clock_limits = {
{ {
.state = 0, .state = 0,
.dcfclk_mhz = 304.0, .dcfclk_mhz = 400.0,
.fabricclk_mhz = 600.0, .fabricclk_mhz = 400.0,
.dispclk_mhz = 618.0, .dispclk_mhz = 600.0,
.dppclk_mhz = 440.0, .dppclk_mhz = 400.00,
.phyclk_mhz = 600.0, .phyclk_mhz = 600.0,
.socclk_mhz = 278.0, .socclk_mhz = 278.0,
.dscclk_mhz = 205.67, .dscclk_mhz = 205.67,
...@@ -173,10 +173,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { ...@@ -173,10 +173,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
}, },
{ {
.state = 1, .state = 1,
.dcfclk_mhz = 304.0, .dcfclk_mhz = 464.52,
.fabricclk_mhz = 600.0, .fabricclk_mhz = 800.0,
.dispclk_mhz = 618.0, .dispclk_mhz = 654.55,
.dppclk_mhz = 618.0, .dppclk_mhz = 626.09,
.phyclk_mhz = 600.0, .phyclk_mhz = 600.0,
.socclk_mhz = 278.0, .socclk_mhz = 278.0,
.dscclk_mhz = 205.67, .dscclk_mhz = 205.67,
...@@ -184,32 +184,65 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { ...@@ -184,32 +184,65 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
}, },
{ {
.state = 2, .state = 2,
.dcfclk_mhz = 608.0, .dcfclk_mhz = 514.29,
.fabricclk_mhz = 1066.0, .fabricclk_mhz = 933.0,
.dispclk_mhz = 888.0, .dispclk_mhz = 757.89,
.dppclk_mhz = 888.0, .dppclk_mhz = 685.71,
.phyclk_mhz = 810.0, .phyclk_mhz = 600.0,
.socclk_mhz = 278.0, .socclk_mhz = 278.0,
.dscclk_mhz = 287.67, .dscclk_mhz = 287.67,
.dram_speed_mts = 2133.0, .dram_speed_mts = 1866.0,
}, },
{ {
.state = 3, .state = 3,
.dcfclk_mhz = 676.0, .dcfclk_mhz = 576.00,
.fabricclk_mhz = 1600.0, .fabricclk_mhz = 1067.0,
.dispclk_mhz = 1015.0, .dispclk_mhz = 847.06,
.dppclk_mhz = 1015.0, .dppclk_mhz = 757.89,
.phyclk_mhz = 810.0, .phyclk_mhz = 600.0,
.socclk_mhz = 715.0, .socclk_mhz = 715.0,
.dscclk_mhz = 318.334, .dscclk_mhz = 318.334,
.dram_speed_mts = 4266.0, .dram_speed_mts = 2134.0,
}, },
{ {
.state = 4, .state = 4,
.dcfclk_mhz = 810.0, .dcfclk_mhz = 626.09,
.fabricclk_mhz = 1200.0,
.dispclk_mhz = 900.00,
.dppclk_mhz = 847.06,
.phyclk_mhz = 810.0,
.socclk_mhz = 953.0,
.dscclk_mhz = 489.0,
.dram_speed_mts = 2400.0,
},
{
.state = 5,
.dcfclk_mhz = 685.71,
.fabricclk_mhz = 1333.0,
.dispclk_mhz = 1028.57,
.dppclk_mhz = 960.00,
.phyclk_mhz = 810.0,
.socclk_mhz = 278.0,
.dscclk_mhz = 287.67,
.dram_speed_mts = 2666.0,
},
{
.state = 6,
.dcfclk_mhz = 757.89,
.fabricclk_mhz = 1467.0,
.dispclk_mhz = 1107.69,
.dppclk_mhz = 1028.57,
.phyclk_mhz = 810.0,
.socclk_mhz = 715.0,
.dscclk_mhz = 318.334,
.dram_speed_mts = 3200.0,
},
{
.state = 7,
.dcfclk_mhz = 847.06,
.fabricclk_mhz = 1600.0, .fabricclk_mhz = 1600.0,
.dispclk_mhz = 1395.0, .dispclk_mhz = 1395.0,
.dppclk_mhz = 1285.0, .dppclk_mhz = 1285.00,
.phyclk_mhz = 1325.0, .phyclk_mhz = 1325.0,
.socclk_mhz = 953.0, .socclk_mhz = 953.0,
.dscclk_mhz = 489.0, .dscclk_mhz = 489.0,
...@@ -217,8 +250,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { ...@@ -217,8 +250,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
}, },
/*Extra state, no dispclk ramping*/ /*Extra state, no dispclk ramping*/
{ {
.state = 5, .state = 8,
.dcfclk_mhz = 810.0, .dcfclk_mhz = 847.06,
.fabricclk_mhz = 1600.0, .fabricclk_mhz = 1600.0,
.dispclk_mhz = 1395.0, .dispclk_mhz = 1395.0,
.dppclk_mhz = 1285.0, .dppclk_mhz = 1285.0,
...@@ -265,7 +298,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { ...@@ -265,7 +298,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
.xfc_bus_transport_time_us = 4, .xfc_bus_transport_time_us = 4,
.xfc_xbuf_latency_tolerance_us = 4, .xfc_xbuf_latency_tolerance_us = 4,
.use_urgent_burst_bw = 1, .use_urgent_burst_bw = 1,
.num_states = 5 .num_states = 9
}; };
#ifndef MAX #ifndef MAX
...@@ -1333,25 +1366,77 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param ...@@ -1333,25 +1366,77 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
{ {
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
struct clk_limit_table *clk_table = &bw_params->clk_table; struct clk_limit_table *clk_table = &bw_params->clk_table;
int i; unsigned int i, j, k;
int closest_clk_lvl;
// diags does not retrieve proper values from SMU
// cap states to 5 and make state 5 the max state
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) || IS_DIAG_DC(dc->ctx->dce_environment)) {
dcn2_1_soc.num_states = 5;
dcn2_1_soc.clock_limits[5].state = 5;
dcn2_1_soc.clock_limits[5].dcfclk_mhz = 810.0;
dcn2_1_soc.clock_limits[5].fabricclk_mhz = 1600.0;
dcn2_1_soc.clock_limits[5].dispclk_mhz = 1395.0;
dcn2_1_soc.clock_limits[5].dppclk_mhz = 1285.0;
dcn2_1_soc.clock_limits[5].phyclk_mhz = 1325.0;
dcn2_1_soc.clock_limits[5].socclk_mhz = 953.0;
dcn2_1_soc.clock_limits[5].dscclk_mhz = 489.0;
dcn2_1_soc.clock_limits[5].dram_speed_mts = 4266.0;
} else {
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
dcn2_1_ip.max_num_dpp = pool->base.pipe_count; dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
dcn2_1_soc.num_chans = bw_params->num_channels; dcn2_1_soc.num_chans = bw_params->num_channels;
for (i = 0; i < clk_table->num_entries; i++) { /* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */
dcn2_1_soc.clock_limits[0].state = 0;
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz;
dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz;
dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
/*
* Other levels: find cloest DCN clocks that fit the given clock limit using dcfclk
* as indicater
*/
closest_clk_lvl = -1;
/* index currently being filled */
k = 1;
for (i = 1; i < clk_table->num_entries; i++) {
/* loop backwards, skip duplicate state, +1 because SMU has precision issue */
for (j = dcn2_1_soc.num_states - 2; j >= k; j--) {
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
closest_clk_lvl = j;
break;
}
}
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/
if (closest_clk_lvl != -1) {
dcn2_1_soc.clock_limits[k].state = i;
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
k++;
}
}
dcn2_1_soc.clock_limits[i].state = i; /* duplicate last level */
dcn2_1_soc.clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; dcn2_1_soc.clock_limits[k] = dcn2_1_soc.clock_limits[k - 1];
dcn2_1_soc.clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; dcn2_1_soc.clock_limits[k].state = k;
dcn2_1_soc.clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; dcn2_1_soc.num_states = k + 1;
dcn2_1_soc.clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
} }
dcn2_1_soc.clock_limits[i] = dcn2_1_soc.clock_limits[i - 1];
dcn2_1_soc.num_states = i;
// diags does not retrieve proper values from SMU, do not update DML instance for diags
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment))
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#ifndef __DISPLAY_MODE_STRUCTS_H__ #ifndef __DISPLAY_MODE_STRUCTS_H__
#define __DISPLAY_MODE_STRUCTS_H__ #define __DISPLAY_MODE_STRUCTS_H__
#define MAX_CLOCK_LIMIT_STATES 8 #define MAX_CLOCK_LIMIT_STATES 9
typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st; typedef struct _vcs_dpi_voltage_scaling_st voltage_scaling_st;
typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st; typedef struct _vcs_dpi_soc_bounding_box_st soc_bounding_box_st;
...@@ -61,6 +61,7 @@ struct _vcs_dpi_voltage_scaling_st { ...@@ -61,6 +61,7 @@ struct _vcs_dpi_voltage_scaling_st {
double dram_speed_mts; double dram_speed_mts;
double fabricclk_mhz; double fabricclk_mhz;
double dispclk_mhz; double dispclk_mhz;
double dram_bw_per_chan_gbps;
double phyclk_mhz; double phyclk_mhz;
double dppclk_mhz; double dppclk_mhz;
double dtbclk_mhz; double dtbclk_mhz;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment