Skip to content

Commit 7200205

Browse files
Meenakshikumar Somasundaramalexdeucher
authored andcommitted
drm/amd/display: Display distortion after hotplug 5K tiled display
[Why] During hot plug of specific 5K tiled display, sometimes both the tiles are not synchronized resulting in distortion. The reason is that otgs of both the tiles goes out of sync when otg workaround (dcnxxx_disable_otg_wa) is applied for bandwidth optimization. The otg workaround reenables otg but otg synchronization context is not reset and hence dc_trigger_sync() does not resynchronize otg again. [How] Implement reset_sync_context_for_pipe() to reset the otg synchronization context for the disabled pipe and its slave pipes when otg workaround is applied. Reviewed-by: Nicholas Kazlauskas <[email protected]> Acked-by: Wayne Lin <[email protected]> Signed-off-by: Meenakshikumar Somasundaram <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 056fb8c commit 7200205

File tree

6 files changed

+45
-20
lines changed

6 files changed

+45
-20
lines changed

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ static int dcn31_get_active_display_cnt_wa(
9999
return display_count;
100100
}
101101

102-
static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
102+
static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
103103
{
104104
struct dc *dc = clk_mgr_base->ctx->dc;
105105
int i;
@@ -110,9 +110,10 @@ static void dcn31_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
110110
if (pipe->top_pipe || pipe->prev_odm_pipe)
111111
continue;
112112
if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
113-
if (disable)
113+
if (disable) {
114114
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
115-
else
115+
reset_sync_context_for_pipe(dc, context, i);
116+
} else
116117
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
117118
}
118119
}
@@ -211,11 +212,11 @@ void dcn31_update_clocks(struct clk_mgr *clk_mgr_base,
211212
}
212213

213214
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
214-
dcn31_disable_otg_wa(clk_mgr_base, true);
215+
dcn31_disable_otg_wa(clk_mgr_base, context, true);
215216

216217
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
217218
dcn31_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
218-
dcn31_disable_otg_wa(clk_mgr_base, false);
219+
dcn31_disable_otg_wa(clk_mgr_base, context, false);
219220

220221
update_dispclk = true;
221222
}

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static int dcn314_get_active_display_cnt_wa(
119119
return display_count;
120120
}
121121

122-
static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
122+
static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
123123
{
124124
struct dc *dc = clk_mgr_base->ctx->dc;
125125
int i;
@@ -131,9 +131,10 @@ static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
131131
continue;
132132
if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL ||
133133
dc_is_virtual_signal(pipe->stream->signal))) {
134-
if (disable)
134+
if (disable) {
135135
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
136-
else
136+
reset_sync_context_for_pipe(dc, context, i);
137+
} else
137138
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
138139
}
139140
}
@@ -233,11 +234,11 @@ void dcn314_update_clocks(struct clk_mgr *clk_mgr_base,
233234
}
234235

235236
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
236-
dcn314_disable_otg_wa(clk_mgr_base, true);
237+
dcn314_disable_otg_wa(clk_mgr_base, context, true);
237238

238239
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
239240
dcn314_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
240-
dcn314_disable_otg_wa(clk_mgr_base, false);
241+
dcn314_disable_otg_wa(clk_mgr_base, context, false);
241242

242243
update_dispclk = true;
243244
}

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static int dcn315_get_active_display_cnt_wa(
7979
return display_count;
8080
}
8181

82-
static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
82+
static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
8383
{
8484
struct dc *dc = clk_mgr_base->ctx->dc;
8585
int i;
@@ -91,9 +91,10 @@ static void dcn315_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
9191
continue;
9292
if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL ||
9393
dc_is_virtual_signal(pipe->stream->signal))) {
94-
if (disable)
94+
if (disable) {
9595
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
96-
else
96+
reset_sync_context_for_pipe(dc, context, i);
97+
} else
9798
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
9899
}
99100
}
@@ -175,12 +176,12 @@ static void dcn315_update_clocks(struct clk_mgr *clk_mgr_base,
175176
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
176177
/* No need to apply the w/a if we haven't taken over from bios yet */
177178
if (clk_mgr_base->clks.dispclk_khz)
178-
dcn315_disable_otg_wa(clk_mgr_base, true);
179+
dcn315_disable_otg_wa(clk_mgr_base, context, true);
179180

180181
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
181182
dcn315_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
182183
if (clk_mgr_base->clks.dispclk_khz)
183-
dcn315_disable_otg_wa(clk_mgr_base, false);
184+
dcn315_disable_otg_wa(clk_mgr_base, context, false);
184185

185186
update_dispclk = true;
186187
}

drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static int dcn316_get_active_display_cnt_wa(
112112
return display_count;
113113
}
114114

115-
static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
115+
static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
116116
{
117117
struct dc *dc = clk_mgr_base->ctx->dc;
118118
int i;
@@ -124,9 +124,10 @@ static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, bool disable)
124124
continue;
125125
if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL ||
126126
dc_is_virtual_signal(pipe->stream->signal))) {
127-
if (disable)
127+
if (disable) {
128128
pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
129-
else
129+
reset_sync_context_for_pipe(dc, context, i);
130+
} else
130131
pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
131132
}
132133
}
@@ -221,11 +222,11 @@ static void dcn316_update_clocks(struct clk_mgr *clk_mgr_base,
221222
}
222223

223224
if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
224-
dcn316_disable_otg_wa(clk_mgr_base, true);
225+
dcn316_disable_otg_wa(clk_mgr_base, context, true);
225226

226227
clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
227228
dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
228-
dcn316_disable_otg_wa(clk_mgr_base, false);
229+
dcn316_disable_otg_wa(clk_mgr_base, context, false);
229230

230231
update_dispclk = true;
231232
}

drivers/gpu/drm/amd/display/dc/core/dc_resource.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3584,6 +3584,23 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
35843584
}
35853585
}
35863586

3587+
void reset_sync_context_for_pipe(const struct dc *dc,
3588+
struct dc_state *context,
3589+
uint8_t pipe_idx)
3590+
{
3591+
int i;
3592+
struct pipe_ctx *pipe_ctx_reset;
3593+
3594+
/* reset the otg sync context for the pipe and its slave pipes if any */
3595+
for (i = 0; i < dc->res_pool->pipe_count; i++) {
3596+
pipe_ctx_reset = &context->res_ctx.pipe_ctx[i];
3597+
3598+
if (((GET_PIPE_SYNCD_FROM_PIPE(pipe_ctx_reset) == pipe_idx) &&
3599+
IS_PIPE_SYNCD_VALID(pipe_ctx_reset)) || (i == pipe_idx))
3600+
SET_PIPE_SYNCD_TO_PIPE(pipe_ctx_reset, i);
3601+
}
3602+
}
3603+
35873604
uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter)
35883605
{
35893606
/* TODO - get transmitter to phy idx mapping from DMUB */

drivers/gpu/drm/amd/display/dc/inc/resource.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ void check_syncd_pipes_for_disabled_master_pipe(struct dc *dc,
219219
struct dc_state *context,
220220
uint8_t disabled_master_pipe_idx);
221221

222+
void reset_sync_context_for_pipe(const struct dc *dc,
223+
struct dc_state *context,
224+
uint8_t pipe_idx);
225+
222226
uint8_t resource_transmitter_to_phy_idx(const struct dc *dc, enum transmitter transmitter);
223227

224228
const struct link_hwss *get_link_hwss(const struct dc_link *link,

0 commit comments

Comments
 (0)