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

Configure Feed

Select the types of activity you want to include in your feed.

drm/msm/dpu: Implement 10-bit color alpha for v12.0 DPU

v12.0 DPU on SM8750 comes with 10-bit color alpha. Add register
differences and new implementations of setup_alpha_out(),
setup_border_color() and setup_blend_config().

Notable changes in v6:
Correct fg_alpha shift on new DPU, pointed out by Abel Vesas.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Patchwork: https://patchwork.freedesktop.org/patch/659629/
Link: https://lore.kernel.org/r/20250618-b4-sm8750-display-v7-10-a591c609743d@linaro.org
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

authored by

Krzysztof Kozlowski and committed by
Dmitry Baryshkov
8984f97c afff6425

+97 -10
+16 -7
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
··· 320 320 } 321 321 322 322 static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer, 323 - struct dpu_plane_state *pstate, const struct msm_format *format) 323 + struct dpu_plane_state *pstate, 324 + const struct msm_format *format, 325 + const struct dpu_mdss_version *mdss_ver) 324 326 { 325 327 struct dpu_hw_mixer *lm = mixer->hw_lm; 326 328 u32 blend_op; 327 - u32 fg_alpha, bg_alpha; 329 + u32 fg_alpha, bg_alpha, max_alpha; 328 330 329 - fg_alpha = pstate->base.alpha >> 8; 330 - bg_alpha = 0xff - fg_alpha; 331 + if (mdss_ver->core_major_ver < 12) { 332 + max_alpha = 0xff; 333 + fg_alpha = pstate->base.alpha >> 8; 334 + } else { 335 + max_alpha = 0x3ff; 336 + fg_alpha = pstate->base.alpha >> 6; 337 + } 338 + bg_alpha = max_alpha - fg_alpha; 331 339 332 340 /* default to opaque blending */ 333 341 if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE || ··· 345 337 } else if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) { 346 338 blend_op = DPU_BLEND_FG_ALPHA_FG_CONST | 347 339 DPU_BLEND_BG_ALPHA_FG_PIXEL; 348 - if (fg_alpha != 0xff) { 340 + if (fg_alpha != max_alpha) { 349 341 bg_alpha = fg_alpha; 350 342 blend_op |= DPU_BLEND_BG_MOD_ALPHA | 351 343 DPU_BLEND_BG_INV_MOD_ALPHA; ··· 356 348 /* coverage blending */ 357 349 blend_op = DPU_BLEND_FG_ALPHA_FG_PIXEL | 358 350 DPU_BLEND_BG_ALPHA_FG_PIXEL; 359 - if (fg_alpha != 0xff) { 351 + if (fg_alpha != max_alpha) { 360 352 bg_alpha = fg_alpha; 361 353 blend_op |= DPU_BLEND_FG_MOD_ALPHA | 362 354 DPU_BLEND_FG_INV_MOD_ALPHA | ··· 489 481 490 482 /* blend config update */ 491 483 for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) { 492 - _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format); 484 + _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format, 485 + ctl->mdss_ver); 493 486 494 487 if (bg_alpha_enable && !format->alpha_enable) 495 488 mixer[lm_idx].mixer_op_mode = 0;
+81 -3
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c
··· 19 19 20 20 /* These register are offset to mixer base + stage base */ 21 21 #define LM_BLEND0_OP 0x00 22 + 23 + /* <v12 DPU with offset to mixer base + stage base */ 22 24 #define LM_BLEND0_CONST_ALPHA 0x04 23 25 #define LM_FG_COLOR_FILL_COLOR_0 0x08 24 26 #define LM_FG_COLOR_FILL_COLOR_1 0x0C 25 27 #define LM_FG_COLOR_FILL_SIZE 0x10 26 28 #define LM_FG_COLOR_FILL_XY 0x14 27 29 30 + /* >= v12 DPU */ 31 + #define LM_BORDER_COLOR_0_V12 0x1c 32 + #define LM_BORDER_COLOR_1_V12 0x20 33 + 34 + /* >= v12 DPU with offset to mixer base + stage base */ 35 + #define LM_BLEND0_CONST_ALPHA_V12 0x08 28 36 #define LM_BLEND0_FG_ALPHA 0x04 29 37 #define LM_BLEND0_BG_ALPHA 0x08 30 38 ··· 91 83 } 92 84 } 93 85 86 + static void dpu_hw_lm_setup_border_color_v12(struct dpu_hw_mixer *ctx, 87 + struct dpu_mdss_color *color, 88 + u8 border_en) 89 + { 90 + struct dpu_hw_blk_reg_map *c = &ctx->hw; 91 + 92 + if (border_en) { 93 + DPU_REG_WRITE(c, LM_BORDER_COLOR_0_V12, 94 + (color->color_0 & 0x3ff) | 95 + ((color->color_1 & 0x3ff) << 16)); 96 + DPU_REG_WRITE(c, LM_BORDER_COLOR_1_V12, 97 + (color->color_2 & 0x3ff) | 98 + ((color->color_3 & 0x3ff) << 16)); 99 + } 100 + } 101 + 94 102 static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) 95 103 { 96 104 dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); ··· 133 109 134 110 const_alpha = (bg_alpha & 0xFF) | ((fg_alpha & 0xFF) << 16); 135 111 DPU_REG_WRITE(c, LM_BLEND0_CONST_ALPHA + stage_off, const_alpha); 112 + DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op); 113 + } 114 + 115 + static void 116 + dpu_hw_lm_setup_blend_config_combined_alpha_v12(struct dpu_hw_mixer *ctx, 117 + u32 stage, u32 fg_alpha, 118 + u32 bg_alpha, u32 blend_op) 119 + { 120 + struct dpu_hw_blk_reg_map *c = &ctx->hw; 121 + int stage_off; 122 + u32 const_alpha; 123 + 124 + if (stage == DPU_STAGE_BASE) 125 + return; 126 + 127 + stage_off = _stage_offset(ctx, stage); 128 + if (WARN_ON(stage_off < 0)) 129 + return; 130 + 131 + const_alpha = (bg_alpha & 0x3ff) | ((fg_alpha & 0x3ff) << 16); 132 + DPU_REG_WRITE(c, LM_BLEND0_CONST_ALPHA_V12 + stage_off, const_alpha); 136 133 DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op); 137 134 } 138 135 ··· 189 144 DPU_REG_WRITE(c, LM_OP_MODE, op_mode); 190 145 } 191 146 147 + static void dpu_hw_lm_setup_color3_v12(struct dpu_hw_mixer *ctx, 148 + uint32_t mixer_op_mode) 149 + { 150 + struct dpu_hw_blk_reg_map *c = &ctx->hw; 151 + int op_mode, stages, stage_off, i; 152 + 153 + stages = ctx->cap->sblk->maxblendstages; 154 + if (stages <= 0) 155 + return; 156 + 157 + for (i = DPU_STAGE_0; i <= stages; i++) { 158 + stage_off = _stage_offset(ctx, i); 159 + if (WARN_ON(stage_off < 0)) 160 + return; 161 + 162 + /* set color_out3 bit in blend0_op when enabled in mixer_op_mode */ 163 + op_mode = DPU_REG_READ(c, LM_BLEND0_OP + stage_off); 164 + if (mixer_op_mode & BIT(i)) 165 + op_mode |= BIT(30); 166 + else 167 + op_mode &= ~BIT(30); 168 + 169 + DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, op_mode); 170 + } 171 + } 172 + 192 173 /** 193 174 * dpu_hw_lm_init() - Initializes the mixer hw driver object. 194 175 * should be called once before accessing every mixer. ··· 246 175 c->idx = cfg->id; 247 176 c->cap = cfg; 248 177 c->ops.setup_mixer_out = dpu_hw_lm_setup_out; 249 - if (mdss_ver->core_major_ver >= 4) 178 + if (mdss_ver->core_major_ver >= 12) 179 + c->ops.setup_blend_config = dpu_hw_lm_setup_blend_config_combined_alpha_v12; 180 + else if (mdss_ver->core_major_ver >= 4) 250 181 c->ops.setup_blend_config = dpu_hw_lm_setup_blend_config_combined_alpha; 251 182 else 252 183 c->ops.setup_blend_config = dpu_hw_lm_setup_blend_config; 253 - c->ops.setup_alpha_out = dpu_hw_lm_setup_color3; 254 - c->ops.setup_border_color = dpu_hw_lm_setup_border_color; 184 + if (mdss_ver->core_major_ver < 12) { 185 + c->ops.setup_alpha_out = dpu_hw_lm_setup_color3; 186 + c->ops.setup_border_color = dpu_hw_lm_setup_border_color; 187 + } else { 188 + c->ops.setup_alpha_out = dpu_hw_lm_setup_color3_v12; 189 + c->ops.setup_border_color = dpu_hw_lm_setup_border_color_v12; 190 + } 255 191 c->ops.setup_misr = dpu_hw_lm_setup_misr; 256 192 c->ops.collect_misr = dpu_hw_lm_collect_misr; 257 193