Skip to content

Commit 6c6eaa2

Browse files
Ivan Lipskigregkh
authored andcommitted
drm/amd/display: Clear the CUR_ENABLE register on DCN314 w/out DPP PG
commit 3ebf766 upstream. [Why&How] ON DCN314, clearing DPP SW structure without power gating it can cause a double cursor in full screen with non-native scaling. A W/A that clears CURSOR0_CONTROL cursor_enable flag if dcn10_plane_atomic_power_down is called and DPP power gating is disabled. Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4168 Reviewed-by: Sun peng (Leo) Li <sunpeng.li@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com> (cherry picked from commit 645f74f) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 7d689cd commit 6c6eaa2

File tree

7 files changed

+90
-0
lines changed

7 files changed

+90
-0
lines changed

drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,15 @@ void dpp1_dppclk_control(
520520
REG_UPDATE(DPP_CONTROL, DPP_CLOCK_ENABLE, 0);
521521
}
522522

523+
void dpp_force_disable_cursor(struct dpp *dpp_base)
524+
{
525+
struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
526+
527+
/* Force disable cursor */
528+
REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, 0);
529+
dpp_base->pos.cur0_ctl.bits.cur0_enable = 0;
530+
}
531+
523532
static const struct dpp_funcs dcn10_dpp_funcs = {
524533
.dpp_read_state = dpp_read_state,
525534
.dpp_reset = dpp_reset,

drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,4 +1525,6 @@ void dpp1_construct(struct dcn10_dpp *dpp1,
15251525

15261526
void dpp1_cm_get_gamut_remap(struct dpp *dpp_base,
15271527
struct dpp_grph_csc_adjustment *adjust);
1528+
void dpp_force_disable_cursor(struct dpp *dpp_base);
1529+
15281530
#endif

drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,7 @@ static struct dpp_funcs dcn30_dpp_funcs = {
14941494
.dpp_dppclk_control = dpp1_dppclk_control,
14951495
.dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier,
14961496
.dpp_get_gamut_remap = dpp3_cm_get_gamut_remap,
1497+
.dpp_force_disable_cursor = dpp_force_disable_cursor,
14971498
};
14981499

14991500

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,75 @@ void dcn314_disable_link_output(struct dc_link *link,
528528

529529
apply_symclk_on_tx_off_wa(link);
530530
}
531+
532+
/**
533+
* dcn314_dpp_pg_control - DPP power gate control.
534+
*
535+
* @hws: dce_hwseq reference.
536+
* @dpp_inst: DPP instance reference.
537+
* @power_on: true if we want to enable power gate, false otherwise.
538+
*
539+
* Enable or disable power gate in the specific DPP instance.
540+
* If power gating is disabled, will force disable cursor in the DPP instance.
541+
*/
542+
void dcn314_dpp_pg_control(
543+
struct dce_hwseq *hws,
544+
unsigned int dpp_inst,
545+
bool power_on)
546+
{
547+
uint32_t power_gate = power_on ? 0 : 1;
548+
uint32_t pwr_status = power_on ? 0 : 2;
549+
550+
551+
if (hws->ctx->dc->debug.disable_dpp_power_gate) {
552+
/* Workaround for DCN314 with disabled power gating */
553+
if (!power_on) {
554+
555+
/* Force disable cursor if power gating is disabled */
556+
struct dpp *dpp = hws->ctx->dc->res_pool->dpps[dpp_inst];
557+
if (dpp && dpp->funcs->dpp_force_disable_cursor)
558+
dpp->funcs->dpp_force_disable_cursor(dpp);
559+
}
560+
return;
561+
}
562+
if (REG(DOMAIN1_PG_CONFIG) == 0)
563+
return;
564+
565+
switch (dpp_inst) {
566+
case 0: /* DPP0 */
567+
REG_UPDATE(DOMAIN1_PG_CONFIG,
568+
DOMAIN1_POWER_GATE, power_gate);
569+
570+
REG_WAIT(DOMAIN1_PG_STATUS,
571+
DOMAIN1_PGFSM_PWR_STATUS, pwr_status,
572+
1, 1000);
573+
break;
574+
case 1: /* DPP1 */
575+
REG_UPDATE(DOMAIN3_PG_CONFIG,
576+
DOMAIN3_POWER_GATE, power_gate);
577+
578+
REG_WAIT(DOMAIN3_PG_STATUS,
579+
DOMAIN3_PGFSM_PWR_STATUS, pwr_status,
580+
1, 1000);
581+
break;
582+
case 2: /* DPP2 */
583+
REG_UPDATE(DOMAIN5_PG_CONFIG,
584+
DOMAIN5_POWER_GATE, power_gate);
585+
586+
REG_WAIT(DOMAIN5_PG_STATUS,
587+
DOMAIN5_PGFSM_PWR_STATUS, pwr_status,
588+
1, 1000);
589+
break;
590+
case 3: /* DPP3 */
591+
REG_UPDATE(DOMAIN7_PG_CONFIG,
592+
DOMAIN7_POWER_GATE, power_gate);
593+
594+
REG_WAIT(DOMAIN7_PG_STATUS,
595+
DOMAIN7_PGFSM_PWR_STATUS, pwr_status,
596+
1, 1000);
597+
break;
598+
default:
599+
BREAK_TO_DEBUGGER();
600+
break;
601+
}
602+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ void dcn314_dpp_root_clock_control(struct dce_hwseq *hws, unsigned int dpp_inst,
4747

4848
void dcn314_disable_link_output(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal);
4949

50+
void dcn314_dpp_pg_control(struct dce_hwseq *hws, unsigned int dpp_inst, bool power_on);
51+
5052
#endif /* __DC_HWSS_DCN314_H__ */

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ static const struct hwseq_private_funcs dcn314_private_funcs = {
141141
.enable_power_gating_plane = dcn314_enable_power_gating_plane,
142142
.dpp_root_clock_control = dcn314_dpp_root_clock_control,
143143
.hubp_pg_control = dcn31_hubp_pg_control,
144+
.dpp_pg_control = dcn314_dpp_pg_control,
144145
.program_all_writeback_pipes_in_tree = dcn30_program_all_writeback_pipes_in_tree,
145146
.update_odm = dcn314_update_odm,
146147
.dsc_pg_control = dcn314_dsc_pg_control,

drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@ struct dpp_funcs {
349349
struct dpp *dpp_base,
350350
enum dc_color_space color_space,
351351
struct dc_csc_transform cursor_csc_color_matrix);
352+
353+
void (*dpp_force_disable_cursor)(struct dpp *dpp_base);
354+
352355
};
353356

354357

0 commit comments

Comments
 (0)