Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix FBC text console corruption

Signed-off-by: Roman Li <roman.li@amd.com>
Reviewed-by: Charlene Liu <Charlene.Liu@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Roman Li and committed by
Alex Deucher
1409bc6b 89fc8d4e

+52 -11
+52 -11
drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c
··· 102 102 return 256 * ((pixels + 255) / 256); 103 103 } 104 104 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 + 105 142 static void wait_for_fbc_state_changed( 106 143 struct dce110_compressor *cp110, 107 144 bool enabled) ··· 269 232 { 270 233 struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor); 271 234 272 - if (compressor->options.bits.FBC_SUPPORT && 273 - 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); 235 + if (compressor->options.bits.FBC_SUPPORT) { 236 + if (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); 279 242 280 - /* Reset enum controller_id to undefined */ 281 - compressor->attached_inst = 0; 282 - compressor->is_enabled = false; 243 + /* Reset enum controller_id to undefined */ 244 + compressor->attached_inst = 0; 245 + compressor->is_enabled = false; 283 246 284 - wait_for_fbc_state_changed(cp110, false); 247 + wait_for_fbc_state_changed(cp110, false); 248 + } 249 + 250 + /* Sync line buffer - dce100/110 only*/ 251 + reset_lb_on_vblank(compressor->ctx); 285 252 } 286 253 } 287 254