Skip to content

Commit edfa93d

Browse files
George Shenalexdeucher
authored andcommitted
drm/amd/display: Remove MPC rate control logic from DCN30 and above
[Why] MPC flow rate control is not needed for DCN30 and above. Current logic that uses it can result in underflow for certain edge cases (such as DSC N422 + ODM combine + 422 left edge pixel). [How] Remove MPC flow rate control logic and programming for DCN30 and above. Cc: Mario Limonciello <[email protected]> Cc: Alex Deucher <[email protected]> Cc: [email protected] Reviewed-by: Wenjing Liu <[email protected]> Acked-by: Tom Chung <[email protected]> Signed-off-by: George Shen <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent fe869c2 commit edfa93d

File tree

6 files changed

+41
-155
lines changed

6 files changed

+41
-155
lines changed

drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,36 @@
4444
#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
4545

4646

47+
void mpc3_mpc_init(struct mpc *mpc)
48+
{
49+
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
50+
int opp_id;
51+
52+
mpc1_mpc_init(mpc);
53+
54+
for (opp_id = 0; opp_id < MAX_OPP; opp_id++) {
55+
if (REG(MUX[opp_id]))
56+
/* disable mpc out rate and flow control */
57+
REG_UPDATE_2(MUX[opp_id], MPC_OUT_RATE_CONTROL_DISABLE,
58+
1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
59+
}
60+
}
61+
62+
void mpc3_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
63+
{
64+
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
65+
66+
mpc1_mpc_init_single_inst(mpc, mpcc_id);
67+
68+
/* assuming mpc out mux is connected to opp with the same index at this
69+
* point in time (e.g. transitioning from vbios to driver)
70+
*/
71+
if (mpcc_id < MAX_OPP && REG(MUX[mpcc_id]))
72+
/* disable mpc out rate and flow control */
73+
REG_UPDATE_2(MUX[mpcc_id], MPC_OUT_RATE_CONTROL_DISABLE,
74+
1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
75+
}
76+
4777
bool mpc3_is_dwb_idle(
4878
struct mpc *mpc,
4979
int dwb_id)
@@ -80,25 +110,6 @@ void mpc3_disable_dwb_mux(
80110
MPC_DWB0_MUX, 0xf);
81111
}
82112

83-
void mpc3_set_out_rate_control(
84-
struct mpc *mpc,
85-
int opp_id,
86-
bool enable,
87-
bool rate_2x_mode,
88-
struct mpc_dwb_flow_control *flow_control)
89-
{
90-
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
91-
92-
REG_UPDATE_2(MUX[opp_id],
93-
MPC_OUT_RATE_CONTROL_DISABLE, !enable,
94-
MPC_OUT_RATE_CONTROL, rate_2x_mode);
95-
96-
if (flow_control)
97-
REG_UPDATE_2(MUX[opp_id],
98-
MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode,
99-
MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1);
100-
}
101-
102113
enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
103114
{
104115
/*Contrary to DCN2 and DCN1 wherein a single status register field holds this info;
@@ -1490,8 +1501,8 @@ static const struct mpc_funcs dcn30_mpc_funcs = {
14901501
.read_mpcc_state = mpc3_read_mpcc_state,
14911502
.insert_plane = mpc1_insert_plane,
14921503
.remove_mpcc = mpc1_remove_mpcc,
1493-
.mpc_init = mpc1_mpc_init,
1494-
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
1504+
.mpc_init = mpc3_mpc_init,
1505+
.mpc_init_single_inst = mpc3_mpc_init_single_inst,
14951506
.update_blending = mpc2_update_blending,
14961507
.cursor_lock = mpc1_cursor_lock,
14971508
.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
@@ -1508,7 +1519,6 @@ static const struct mpc_funcs dcn30_mpc_funcs = {
15081519
.set_dwb_mux = mpc3_set_dwb_mux,
15091520
.disable_dwb_mux = mpc3_disable_dwb_mux,
15101521
.is_dwb_idle = mpc3_is_dwb_idle,
1511-
.set_out_rate_control = mpc3_set_out_rate_control,
15121522
.set_gamut_remap = mpc3_set_gamut_remap,
15131523
.program_shaper = mpc3_program_shaper,
15141524
.acquire_rmu = mpcc3_acquire_rmu,

drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,13 @@ void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
10071007
int num_mpcc,
10081008
int num_rmu);
10091009

1010+
void mpc3_mpc_init(
1011+
struct mpc *mpc);
1012+
1013+
void mpc3_mpc_init_single_inst(
1014+
struct mpc *mpc,
1015+
unsigned int mpcc_id);
1016+
10101017
bool mpc3_program_shaper(
10111018
struct mpc *mpc,
10121019
const struct pwl_params *params,
@@ -1078,13 +1085,6 @@ bool mpc3_is_dwb_idle(
10781085
struct mpc *mpc,
10791086
int dwb_id);
10801087

1081-
void mpc3_set_out_rate_control(
1082-
struct mpc *mpc,
1083-
int opp_id,
1084-
bool enable,
1085-
bool rate_2x_mode,
1086-
struct mpc_dwb_flow_control *flow_control);
1087-
10881088
void mpc3_power_on_ogam_lut(
10891089
struct mpc *mpc, int mpcc_id,
10901090
bool power_on);

drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void mpc32_mpc_init(struct mpc *mpc)
4747
struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
4848
int mpcc_id;
4949

50-
mpc1_mpc_init(mpc);
50+
mpc3_mpc_init(mpc);
5151

5252
if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
5353
if (mpc30->mpc_mask->MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE) {
@@ -991,7 +991,7 @@ static const struct mpc_funcs dcn32_mpc_funcs = {
991991
.insert_plane = mpc1_insert_plane,
992992
.remove_mpcc = mpc1_remove_mpcc,
993993
.mpc_init = mpc32_mpc_init,
994-
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
994+
.mpc_init_single_inst = mpc3_mpc_init_single_inst,
995995
.update_blending = mpc2_update_blending,
996996
.cursor_lock = mpc1_cursor_lock,
997997
.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
@@ -1008,7 +1008,6 @@ static const struct mpc_funcs dcn32_mpc_funcs = {
10081008
.set_dwb_mux = mpc3_set_dwb_mux,
10091009
.disable_dwb_mux = mpc3_disable_dwb_mux,
10101010
.is_dwb_idle = mpc3_is_dwb_idle,
1011-
.set_out_rate_control = mpc3_set_out_rate_control,
10121011
.set_gamut_remap = mpc3_set_gamut_remap,
10131012
.program_shaper = mpc32_program_shaper,
10141013
.program_3dlut = mpc32_program_3dlut,

drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,6 @@
6969
#define FN(reg_name, field_name) \
7070
hws->shifts->field_name, hws->masks->field_name
7171

72-
static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
73-
int opp_cnt)
74-
{
75-
bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
76-
int flow_ctrl_cnt;
77-
78-
if (opp_cnt >= 2)
79-
hblank_halved = true;
80-
81-
flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
82-
stream->timing.h_border_left -
83-
stream->timing.h_border_right;
84-
85-
if (hblank_halved)
86-
flow_ctrl_cnt /= 2;
87-
88-
/* ODM combine 4:1 case */
89-
if (opp_cnt == 4)
90-
flow_ctrl_cnt /= 2;
91-
92-
return flow_ctrl_cnt;
93-
}
94-
9572
static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
9673
{
9774
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -183,10 +160,6 @@ void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx
183160
struct pipe_ctx *odm_pipe;
184161
int opp_cnt = 0;
185162
int opp_inst[MAX_PIPES] = {0};
186-
bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
187-
struct mpc_dwb_flow_control flow_control;
188-
struct mpc *mpc = dc->res_pool->mpc;
189-
int i;
190163

191164
opp_cnt = get_odm_config(pipe_ctx, opp_inst);
192165

@@ -199,20 +172,6 @@ void dcn314_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx
199172
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
200173
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
201174

202-
rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
203-
flow_control.flow_ctrl_mode = 0;
204-
flow_control.flow_ctrl_cnt0 = 0x80;
205-
flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
206-
if (mpc->funcs->set_out_rate_control) {
207-
for (i = 0; i < opp_cnt; ++i) {
208-
mpc->funcs->set_out_rate_control(
209-
mpc, opp_inst[i],
210-
true,
211-
rate_control_2x_pclk,
212-
&flow_control);
213-
}
214-
}
215-
216175
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
217176
odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
218177
odm_pipe->stream_res.opp,

drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -966,29 +966,6 @@ void dcn32_init_hw(struct dc *dc)
966966
}
967967
}
968968

969-
static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
970-
int opp_cnt)
971-
{
972-
bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
973-
int flow_ctrl_cnt;
974-
975-
if (opp_cnt >= 2)
976-
hblank_halved = true;
977-
978-
flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
979-
stream->timing.h_border_left -
980-
stream->timing.h_border_right;
981-
982-
if (hblank_halved)
983-
flow_ctrl_cnt /= 2;
984-
985-
/* ODM combine 4:1 case */
986-
if (opp_cnt == 4)
987-
flow_ctrl_cnt /= 2;
988-
989-
return flow_ctrl_cnt;
990-
}
991-
992969
static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
993970
{
994971
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -1103,10 +1080,6 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
11031080
struct pipe_ctx *odm_pipe;
11041081
int opp_cnt = 0;
11051082
int opp_inst[MAX_PIPES] = {0};
1106-
bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
1107-
struct mpc_dwb_flow_control flow_control;
1108-
struct mpc *mpc = dc->res_pool->mpc;
1109-
int i;
11101083

11111084
opp_cnt = get_odm_config(pipe_ctx, opp_inst);
11121085

@@ -1119,20 +1092,6 @@ void dcn32_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
11191092
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
11201093
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
11211094

1122-
rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
1123-
flow_control.flow_ctrl_mode = 0;
1124-
flow_control.flow_ctrl_cnt0 = 0x80;
1125-
flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
1126-
if (mpc->funcs->set_out_rate_control) {
1127-
for (i = 0; i < opp_cnt; ++i) {
1128-
mpc->funcs->set_out_rate_control(
1129-
mpc, opp_inst[i],
1130-
true,
1131-
rate_control_2x_pclk,
1132-
&flow_control);
1133-
}
1134-
}
1135-
11361095
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
11371096
odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
11381097
odm_pipe->stream_res.opp,

drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -358,29 +358,6 @@ void dcn35_init_hw(struct dc *dc)
358358
}
359359
}
360360

361-
static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
362-
int opp_cnt)
363-
{
364-
bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
365-
int flow_ctrl_cnt;
366-
367-
if (opp_cnt >= 2)
368-
hblank_halved = true;
369-
370-
flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
371-
stream->timing.h_border_left -
372-
stream->timing.h_border_right;
373-
374-
if (hblank_halved)
375-
flow_ctrl_cnt /= 2;
376-
377-
/* ODM combine 4:1 case */
378-
if (opp_cnt == 4)
379-
flow_ctrl_cnt /= 2;
380-
381-
return flow_ctrl_cnt;
382-
}
383-
384361
static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
385362
{
386363
struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -474,10 +451,6 @@ void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
474451
struct pipe_ctx *odm_pipe;
475452
int opp_cnt = 0;
476453
int opp_inst[MAX_PIPES] = {0};
477-
bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
478-
struct mpc_dwb_flow_control flow_control;
479-
struct mpc *mpc = dc->res_pool->mpc;
480-
int i;
481454

482455
opp_cnt = get_odm_config(pipe_ctx, opp_inst);
483456

@@ -490,20 +463,6 @@ void dcn35_update_odm(struct dc *dc, struct dc_state *context, struct pipe_ctx *
490463
pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
491464
pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
492465

493-
rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
494-
flow_control.flow_ctrl_mode = 0;
495-
flow_control.flow_ctrl_cnt0 = 0x80;
496-
flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
497-
if (mpc->funcs->set_out_rate_control) {
498-
for (i = 0; i < opp_cnt; ++i) {
499-
mpc->funcs->set_out_rate_control(
500-
mpc, opp_inst[i],
501-
true,
502-
rate_control_2x_pclk,
503-
&flow_control);
504-
}
505-
}
506-
507466
for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
508467
odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
509468
odm_pipe->stream_res.opp,

0 commit comments

Comments
 (0)