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

drm/amd/display: wake up ogam mem pwr before programming ocsc

[Description]
OGAM_MEM_PWR could stay in light up when driver woke up to update gamma.
either disable MEM_LOW power feature or set to OGAM_bypass could make artificial color distortion goes away.
Easy reproduce after LOW_MEM Power feature enables and resume from S3.

Signed-off-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Julian Parkin <jparkin@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Charlene Liu and committed by
Alex Deucher
54461859 1bb32e5a

+49 -7
+16
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.c
··· 72 72 } 73 73 } 74 74 75 + void dpp2_power_on_obuf( 76 + struct dpp *dpp_base, 77 + bool power_on) 78 + { 79 + struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base); 80 + 81 + REG_UPDATE(CM_MEM_PWR_CTRL, SHARED_MEM_PWR_DIS, power_on == true ? 1:0); 82 + 83 + REG_UPDATE(OBUF_MEM_PWR_CTRL, 84 + OBUF_MEM_PWR_FORCE, power_on == true ? 0:1); 85 + 86 + REG_UPDATE(DSCL_MEM_PWR_CTRL, 87 + LUT_MEM_PWR_FORCE, power_on == true ? 0:1); 88 + } 89 + 75 90 void dpp2_dummy_program_input_lut( 76 91 struct dpp *dpp_base, 77 92 const struct dc_gamma *gamma) ··· 242 227 CUR0_ENABLE, 0); 243 228 244 229 } 230 + dpp2_power_on_obuf(dpp_base, true); 245 231 246 232 } 247 233
+15 -4
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dpp.h
··· 162 162 SRI(COLOR_KEYER_GREEN, CNVC_CFG, id), \ 163 163 SRI(COLOR_KEYER_BLUE, CNVC_CFG, id), \ 164 164 SRI(CM_SHAPER_LUT_DATA, CM, id), \ 165 - SRI(CURSOR_CONTROL, CURSOR0_, id) 165 + SRI(CURSOR_CONTROL, CURSOR0_, id),\ 166 + SRI(OBUF_MEM_PWR_CTRL, DSCL, id),\ 167 + SRI(DSCL_MEM_PWR_CTRL, DSCL, id) 166 168 167 169 #define TF_REG_LIST_SH_MASK_DCN20(mask_sh)\ 168 170 TF_REG_LIST_SH_MASK_DCN(mask_sh), \ ··· 556 554 TF_SF(CNVC_CFG0_COLOR_KEYER_BLUE, COLOR_KEYER_BLUE_HIGH, mask_sh), \ 557 555 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_PIX_INV_MODE, mask_sh), \ 558 556 TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_PIXEL_ALPHA_MOD_EN, mask_sh), \ 559 - TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ROM_EN, mask_sh) 557 + TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ROM_EN, mask_sh),\ 558 + TF_SF(DSCL0_OBUF_MEM_PWR_CTRL, OBUF_MEM_PWR_FORCE, mask_sh),\ 559 + TF_SF(DSCL0_DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, mask_sh) 560 560 561 561 #define TF_REG_FIELD_LIST_DCN2_0(type) \ 562 562 TF_REG_FIELD_LIST(type) \ ··· 589 585 type COLOR_KEYER_BLUE_HIGH; \ 590 586 type CUR0_PIX_INV_MODE; \ 591 587 type CUR0_PIXEL_ALPHA_MOD_EN; \ 592 - type CUR0_ROM_EN 588 + type CUR0_ROM_EN;\ 589 + type OBUF_MEM_PWR_FORCE;\ 590 + type LUT_MEM_PWR_FORCE 593 591 594 592 struct dcn2_dpp_shift { 595 593 TF_REG_FIELD_LIST_DCN2_0(uint8_t); ··· 615 609 uint32_t COLOR_KEYER_ALPHA; \ 616 610 uint32_t COLOR_KEYER_RED; \ 617 611 uint32_t COLOR_KEYER_GREEN; \ 618 - uint32_t COLOR_KEYER_BLUE 612 + uint32_t COLOR_KEYER_BLUE; \ 613 + uint32_t OBUF_MEM_PWR_CTRL;\ 614 + uint32_t DSCL_MEM_PWR_CTRL 619 615 620 616 struct dcn2_dpp_registers { 621 617 DPP_DCN2_REG_VARIABLE_LIST; ··· 703 695 const struct dcn2_dpp_shift *tf_shift, 704 696 const struct dcn2_dpp_mask *tf_mask); 705 697 698 + void dpp2_power_on_obuf( 699 + struct dpp *dpp_base, 700 + bool power_on); 706 701 #endif /* __DC_HWSS_DCN20_H__ */
+6
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
··· 631 631 { 632 632 struct mpc *mpc = dc->res_pool->mpc; 633 633 enum mpc_output_csc_mode ocsc_mode = MPC_OUTPUT_CSC_COEF_A; 634 + int mpcc_id = pipe_ctx->plane_res.hubp->inst; 635 + 636 + if (mpc->funcs->power_on_mpc_mem_pwr) 637 + mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true); 634 638 635 639 if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 636 640 if (mpc->funcs->set_output_csc != NULL) ··· 664 660 * if programming for all pipes is required then remove condition 665 661 * pipe_ctx->top_pipe == NULL ,but then fix the diagnostic. 666 662 */ 663 + if (mpc->funcs->power_on_mpc_mem_pwr) 664 + mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, true); 667 665 if ((pipe_ctx->top_pipe == NULL || dc_res_is_odm_head_pipe(pipe_ctx)) 668 666 && mpc->funcs->set_output_gamma && stream->out_transfer_func) { 669 667 if (stream->out_transfer_func->type == TF_TYPE_HWPWL)
+3 -2
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.c
··· 233 233 reg->masks.exp_resion_start_segment = mpc20->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B; 234 234 } 235 235 236 - static void mpc20_power_on_ogam_lut( 236 + void mpc20_power_on_ogam_lut( 237 237 struct mpc *mpc, int mpcc_id, 238 238 bool power_on) 239 239 { 240 240 struct dcn20_mpc *mpc20 = TO_DCN20_MPC(mpc); 241 241 242 242 REG_SET(MPCC_MEM_PWR_CTRL[mpcc_id], 0, 243 - MPCC_OGAM_MEM_PWR_FORCE, power_on == true ? 0:1); 243 + MPCC_OGAM_MEM_PWR_DIS, power_on == true ? 1:0); 244 244 245 245 } 246 246 ··· 509 509 .set_output_csc = mpc2_set_output_csc, 510 510 .set_ocsc_default = mpc2_set_ocsc_default, 511 511 .set_output_gamma = mpc2_set_output_gamma, 512 + .power_on_mpc_mem_pwr = mpc20_power_on_ogam_lut, 512 513 }; 513 514 514 515 void dcn20_mpc_construct(struct dcn20_mpc *mpc20,
+5 -1
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_mpc.h
··· 159 159 SF(MPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_B, MPCC_OGAM_RAMB_EXP_REGION_START_B, mask_sh),\ 160 160 SF(MPCC_OGAM0_MPCC_OGAM_RAMB_START_CNTL_B, MPCC_OGAM_RAMB_EXP_REGION_START_SEGMENT_B, mask_sh),\ 161 161 SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_FORCE, mask_sh),\ 162 + SF(MPCC0_MPCC_MEM_PWR_CTRL, MPCC_OGAM_MEM_PWR_DIS, mask_sh),\ 162 163 SF(MPCC_OGAM0_MPCC_OGAM_LUT_INDEX, MPCC_OGAM_LUT_INDEX, mask_sh),\ 163 164 SF(MPCC_OGAM0_MPCC_OGAM_LUT_RAM_CONTROL, MPCC_OGAM_LUT_WRITE_EN_MASK, mask_sh),\ 164 165 SF(MPCC_OGAM0_MPCC_OGAM_LUT_RAM_CONTROL, MPCC_OGAM_LUT_RAM_SEL, mask_sh),\ ··· 173 172 SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ 174 173 SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ 175 174 SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) 175 + 176 176 177 177 #define MPC_REG_FIELD_LIST_DCN2_0(type) \ 178 178 MPC_REG_FIELD_LIST(type)\ ··· 219 217 type MPC_OUT_DENORM_CLAMP_MIN_G_Y;\ 220 218 type MPC_OUT_DENORM_CLAMP_MAX_B_CB;\ 221 219 type MPC_OUT_DENORM_CLAMP_MIN_B_CB;\ 222 - type MPCC_DISABLED; 220 + type MPCC_DISABLED;\ 221 + type MPCC_OGAM_MEM_PWR_DIS; 223 222 224 223 struct dcn20_mpc_registers { 225 224 MPC_REG_VARIABLE_LIST_DCN2_0 ··· 285 282 286 283 void mpc2_assert_idle_mpcc(struct mpc *mpc, int id); 287 284 void mpc2_assert_mpcc_idle_before_connect(struct mpc *mpc, int mpcc_id); 285 + void mpc20_power_on_ogam_lut(struct mpc *mpc, int mpcc_id, bool power_on); 288 286 #endif
+4
drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
··· 254 254 struct mpc *mpc, 255 255 int mpcc_id, 256 256 const struct pwl_params *params); 257 + void (*power_on_mpc_mem_pwr)( 258 + struct mpc *mpc, 259 + int mpcc_id, 260 + bool power_on); 257 261 #endif 258 262 259 263 };