Skip to content

Commit 1409bc6

Browse files
Roman Lialexdeucher
authored andcommitted
drm/amd/display: Fix FBC text console corruption
Signed-off-by: Roman Li <[email protected]> Reviewed-by: Charlene Liu <[email protected]> Acked-by: Harry Wentland <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 89fc8d4 commit 1409bc6

File tree

1 file changed

+54
-13
lines changed

1 file changed

+54
-13
lines changed

drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,43 @@ static uint32_t align_to_chunks_number_per_line(uint32_t pixels)
102102
return 256 * ((pixels + 255) / 256);
103103
}
104104

105+
static void reset_lb_on_vblank(struct dc_context *ctx)
106+
{
107+
uint32_t value, frame_count;
108+
uint32_t retry = 0;
109+
uint32_t status_pos =
110+
dm_read_reg(ctx, mmCRTC_STATUS_POSITION);
111+
112+
113+
/* Only if CRTC is enabled and counter is moving we wait for one frame. */
114+
if (status_pos != dm_read_reg(ctx, mmCRTC_STATUS_POSITION)) {
115+
/* Resetting LB on VBlank */
116+
value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL);
117+
set_reg_field_value(value, 3, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL);
118+
set_reg_field_value(value, 1, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2);
119+
dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value);
120+
121+
frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT);
122+
123+
124+
for (retry = 100; retry > 0; retry--) {
125+
if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT))
126+
break;
127+
msleep(1);
128+
}
129+
if (!retry)
130+
dm_error("Frame count did not increase for 100ms.\n");
131+
132+
/* Resetting LB on VBlank */
133+
value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL);
134+
set_reg_field_value(value, 2, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL);
135+
set_reg_field_value(value, 0, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2);
136+
dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value);
137+
138+
}
139+
140+
}
141+
105142
static void wait_for_fbc_state_changed(
106143
struct dce110_compressor *cp110,
107144
bool enabled)
@@ -232,19 +269,23 @@ void dce110_compressor_disable_fbc(struct compressor *compressor)
232269
{
233270
struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor);
234271

235-
if (compressor->options.bits.FBC_SUPPORT &&
236-
dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
237-
uint32_t reg_data;
238-
/* Turn off compression */
239-
reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
240-
set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
241-
dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
242-
243-
/* Reset enum controller_id to undefined */
244-
compressor->attached_inst = 0;
245-
compressor->is_enabled = false;
246-
247-
wait_for_fbc_state_changed(cp110, false);
272+
if (compressor->options.bits.FBC_SUPPORT) {
273+
if (dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) {
274+
uint32_t reg_data;
275+
/* Turn off compression */
276+
reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL);
277+
set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN);
278+
dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data);
279+
280+
/* Reset enum controller_id to undefined */
281+
compressor->attached_inst = 0;
282+
compressor->is_enabled = false;
283+
284+
wait_for_fbc_state_changed(cp110, false);
285+
}
286+
287+
/* Sync line buffer - dce100/110 only*/
288+
reset_lb_on_vblank(compressor->ctx);
248289
}
249290
}
250291

0 commit comments

Comments
 (0)