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

drm/sun4i: layer: replace mixer with layer struct

This allows to almost completely decouple layer code from mixer. This is
important for DE33.

Reviewed-by: Chen-Yu Tsai <wens@kernel.org>
Tested-by: Ryan Walklin <ryan@testtoast.com>
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
Link: https://patch.msgid.link/20251104180942.61538-29-jernej.skrabec@gmail.com
Signed-off-by: Chen-Yu Tsai <wens@kernel.org>

authored by

Jernej Skrabec and committed by
Chen-Yu Tsai
bb1d2dde d1fe2639

+66 -67
+2 -2
drivers/gpu/drm/sun4i/sun8i_csc.c
··· 233 233 u32 mode = sun8i_csc_get_mode(state); 234 234 u32 base; 235 235 236 - if (layer->mixer->cfg->de_type == SUN8I_MIXER_DE3) { 236 + if (layer->cfg->de_type == SUN8I_MIXER_DE3) { 237 237 sun8i_de3_ccsc_setup(layer->regs, layer->channel, 238 238 mode, state->color_encoding, 239 239 state->color_range); 240 240 return; 241 241 } 242 242 243 - base = ccsc_base[layer->mixer->cfg->lay_cfg.ccsc][layer->channel]; 243 + base = ccsc_base[layer->cfg->ccsc][layer->channel]; 244 244 245 245 sun8i_csc_setup(layer->regs, base, 246 246 mode, state->color_encoding,
+4 -2
drivers/gpu/drm/sun4i/sun8i_mixer.c
··· 339 339 340 340 layer = sun8i_vi_layer_init_one(drm, mixer, type, 341 341 mixer->engine.regs, i, 342 - phy_index, plane_cnt); 342 + phy_index, plane_cnt, 343 + &mixer->cfg->lay_cfg); 343 344 if (IS_ERR(layer)) { 344 345 dev_err(drm->dev, 345 346 "Couldn't initialize overlay plane\n"); ··· 365 364 366 365 layer = sun8i_ui_layer_init_one(drm, mixer, type, 367 366 mixer->engine.regs, index, 368 - phy_index, plane_cnt); 367 + phy_index, plane_cnt, 368 + &mixer->cfg->lay_cfg); 369 369 if (IS_ERR(layer)) { 370 370 dev_err(drm->dev, "Couldn't initialize %s plane\n", 371 371 i ? "overlay" : "primary");
+14 -13
drivers/gpu/drm/sun4i/sun8i_mixer.h
··· 225 225 }; 226 226 227 227 struct sun8i_layer { 228 - struct drm_plane plane; 229 - struct sun8i_mixer *mixer; 230 - int type; 231 - int index; 232 - int channel; 233 - int overlay; 234 - struct regmap *regs; 228 + struct drm_plane plane; 229 + struct sun8i_mixer *mixer; 230 + int type; 231 + int index; 232 + int channel; 233 + int overlay; 234 + struct regmap *regs; 235 + const struct sun8i_layer_cfg *cfg; 235 236 }; 236 237 237 238 static inline struct sun8i_layer * ··· 261 260 } 262 261 263 262 static inline u32 264 - sun8i_channel_base(struct sun8i_mixer *mixer, int channel) 263 + sun8i_channel_base(struct sun8i_layer *layer) 265 264 { 266 - if (mixer->cfg->de_type == SUN8I_MIXER_DE33) 267 - return DE33_CH_BASE + channel * DE33_CH_SIZE; 268 - else if (mixer->cfg->de_type == SUN8I_MIXER_DE3) 269 - return DE3_CH_BASE + channel * DE3_CH_SIZE; 265 + if (layer->cfg->de_type == SUN8I_MIXER_DE33) 266 + return DE33_CH_BASE + layer->channel * DE33_CH_SIZE; 267 + else if (layer->cfg->de_type == SUN8I_MIXER_DE3) 268 + return DE3_CH_BASE + layer->channel * DE3_CH_SIZE; 270 269 else 271 - return DE2_CH_BASE + channel * DE2_CH_SIZE; 270 + return DE2_CH_BASE + layer->channel * DE2_CH_SIZE; 272 271 } 273 272 274 273 int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format);
+11 -13
drivers/gpu/drm/sun4i/sun8i_ui_layer.c
··· 28 28 29 29 static void sun8i_ui_layer_disable(struct sun8i_layer *layer) 30 30 { 31 - struct sun8i_mixer *mixer = layer->mixer; 32 - u32 ch_base = sun8i_channel_base(mixer, layer->channel); 31 + u32 ch_base = sun8i_channel_base(layer); 33 32 34 - regmap_write(mixer->engine.regs, 33 + regmap_write(layer->regs, 35 34 SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, layer->overlay), 0); 36 35 } 37 36 ··· 38 39 struct drm_plane *plane) 39 40 { 40 41 struct drm_plane_state *state = plane->state; 41 - struct sun8i_mixer *mixer = layer->mixer; 42 42 const struct drm_format_info *fmt; 43 43 u32 val, ch_base, hw_fmt; 44 44 45 - ch_base = sun8i_channel_base(mixer, layer->channel); 45 + ch_base = sun8i_channel_base(layer); 46 46 fmt = state->fb->format; 47 47 sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt); 48 48 ··· 60 62 struct drm_plane *plane) 61 63 { 62 64 struct drm_plane_state *state = plane->state; 63 - struct sun8i_mixer *mixer = layer->mixer; 64 65 u32 src_w, src_h, dst_w, dst_h; 65 66 u32 outsize, insize; 66 67 u32 hphase, vphase; ··· 68 71 DRM_DEBUG_DRIVER("Updating UI channel %d overlay %d\n", 69 72 layer->channel, layer->overlay); 70 73 71 - ch_base = sun8i_channel_base(mixer, layer->channel); 74 + ch_base = sun8i_channel_base(layer); 72 75 73 76 src_w = drm_rect_width(&state->src) >> 16; 74 77 src_h = drm_rect_height(&state->src) >> 16; ··· 100 103 hscale = state->src_w / state->crtc_w; 101 104 vscale = state->src_h / state->crtc_h; 102 105 103 - if (mixer->cfg->de_type == SUN8I_MIXER_DE33) { 106 + if (layer->cfg->de_type == SUN8I_MIXER_DE33) { 104 107 sun8i_vi_scaler_setup(layer, src_w, src_h, dst_w, dst_h, 105 108 hscale, vscale, hphase, vphase, 106 109 state->fb->format); ··· 112 115 } 113 116 } else { 114 117 DRM_DEBUG_DRIVER("HW scaling is not needed\n"); 115 - if (mixer->cfg->de_type == SUN8I_MIXER_DE33) 118 + if (layer->cfg->de_type == SUN8I_MIXER_DE33) 116 119 sun8i_vi_scaler_enable(layer, false); 117 120 else 118 121 sun8i_ui_scaler_enable(layer, false); ··· 123 126 struct drm_plane *plane) 124 127 { 125 128 struct drm_plane_state *state = plane->state; 126 - struct sun8i_mixer *mixer = layer->mixer; 127 129 struct drm_framebuffer *fb = state->fb; 128 130 struct drm_gem_dma_object *gem; 129 131 dma_addr_t dma_addr; 130 132 u32 ch_base; 131 133 int bpp; 132 134 133 - ch_base = sun8i_channel_base(mixer, layer->channel); 135 + ch_base = sun8i_channel_base(layer); 134 136 135 137 /* Get the physical address of the buffer in memory */ 136 138 gem = drm_fb_dma_get_gem_obj(fb, 0); ··· 186 190 min_scale = DRM_PLANE_NO_SCALING; 187 191 max_scale = DRM_PLANE_NO_SCALING; 188 192 189 - if (layer->mixer->cfg->lay_cfg.scaler_mask & BIT(layer->channel)) { 193 + if (layer->cfg->scaler_mask & BIT(layer->channel)) { 190 194 min_scale = SUN8I_UI_SCALER_SCALE_MIN; 191 195 max_scale = SUN8I_UI_SCALER_SCALE_MAX; 192 196 } ··· 262 266 enum drm_plane_type type, 263 267 struct regmap *regs, 264 268 int index, int phy_index, 265 - int plane_cnt) 269 + int plane_cnt, 270 + const struct sun8i_layer_cfg *cfg) 266 271 { 267 272 struct sun8i_layer *layer; 268 273 int ret; ··· 278 281 layer->channel = phy_index; 279 282 layer->overlay = 0; 280 283 layer->regs = regs; 284 + layer->cfg = cfg; 281 285 282 286 /* possible crtcs are set later */ 283 287 ret = drm_universal_plane_init(drm, &layer->plane, 0,
+2 -1
drivers/gpu/drm/sun4i/sun8i_ui_layer.h
··· 54 54 enum drm_plane_type type, 55 55 struct regmap *regs, 56 56 int index, int phy_index, 57 - int plane_cnt); 57 + int plane_cnt, 58 + const struct sun8i_layer_cfg *cfg); 58 59 #endif /* _SUN8I_UI_LAYER_H_ */
+7 -9
drivers/gpu/drm/sun4i/sun8i_ui_scaler.c
··· 89 89 0x0b1c1603, 0x0d1c1502, 0x0e1d1401, 0x0f1d1301, 90 90 }; 91 91 92 - static u32 sun8i_ui_scaler_base(struct sun8i_mixer *mixer, int channel) 92 + static u32 sun8i_ui_scaler_base(struct sun8i_layer *layer) 93 93 { 94 - int offset = mixer->cfg->lay_cfg.vi_scaler_num; 94 + int offset = layer->cfg->vi_scaler_num; 95 95 96 - if (mixer->cfg->de_type == SUN8I_MIXER_DE3) 96 + if (layer->cfg->de_type == SUN8I_MIXER_DE3) 97 97 return DE3_VI_SCALER_UNIT_BASE + 98 98 DE3_VI_SCALER_UNIT_SIZE * offset + 99 - DE3_UI_SCALER_UNIT_SIZE * (channel - offset); 99 + DE3_UI_SCALER_UNIT_SIZE * (layer->channel - offset); 100 100 else 101 101 return DE2_VI_SCALER_UNIT_BASE + 102 102 DE2_VI_SCALER_UNIT_SIZE * offset + 103 - DE2_UI_SCALER_UNIT_SIZE * (channel - offset); 103 + DE2_UI_SCALER_UNIT_SIZE * (layer->channel - offset); 104 104 } 105 105 106 106 static int sun8i_ui_scaler_coef_index(unsigned int step) ··· 129 129 130 130 void sun8i_ui_scaler_enable(struct sun8i_layer *layer, bool enable) 131 131 { 132 - struct sun8i_mixer *mixer = layer->mixer; 133 132 u32 val, base; 134 133 135 - base = sun8i_ui_scaler_base(mixer, layer->channel); 134 + base = sun8i_ui_scaler_base(layer); 136 135 137 136 if (enable) 138 137 val = SUN8I_SCALER_GSU_CTRL_EN | ··· 146 147 u32 src_w, u32 src_h, u32 dst_w, u32 dst_h, 147 148 u32 hscale, u32 vscale, u32 hphase, u32 vphase) 148 149 { 149 - struct sun8i_mixer *mixer = layer->mixer; 150 150 u32 insize, outsize; 151 151 int i, offset; 152 152 u32 base; 153 153 154 - base = sun8i_ui_scaler_base(mixer, layer->channel); 154 + base = sun8i_ui_scaler_base(layer); 155 155 156 156 hphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16; 157 157 vphase <<= SUN8I_UI_SCALER_PHASE_FRAC - 16;
+15 -16
drivers/gpu/drm/sun4i/sun8i_vi_layer.c
··· 21 21 22 22 static void sun8i_vi_layer_disable(struct sun8i_layer *layer) 23 23 { 24 - struct sun8i_mixer *mixer = layer->mixer; 25 - u32 ch_base = sun8i_channel_base(mixer, layer->channel); 24 + u32 ch_base = sun8i_channel_base(layer); 26 25 27 - regmap_write(mixer->engine.regs, 26 + regmap_write(layer->regs, 28 27 SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, layer->overlay), 0); 29 28 } 30 29 ··· 31 32 struct drm_plane *plane) 32 33 { 33 34 struct drm_plane_state *state = plane->state; 34 - struct sun8i_mixer *mixer = layer->mixer; 35 35 const struct drm_format_info *fmt; 36 36 u32 val, ch_base, hw_fmt; 37 37 38 - ch_base = sun8i_channel_base(mixer, layer->channel); 38 + ch_base = sun8i_channel_base(layer); 39 39 fmt = state->fb->format; 40 40 sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt); 41 41 ··· 42 44 if (!fmt->is_yuv) 43 45 val |= SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE; 44 46 val |= SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN; 45 - if (mixer->cfg->de_type >= SUN8I_MIXER_DE3) { 47 + if (layer->cfg->de_type >= SUN8I_MIXER_DE3) { 46 48 val |= SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(state->alpha >> 8); 47 49 val |= (state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? 48 50 SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_PIXEL : ··· 52 54 regmap_write(layer->regs, 53 55 SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, layer->overlay), val); 54 56 55 - if (mixer->cfg->lay_cfg.de2_fcc_alpha) { 57 + if (layer->cfg->de2_fcc_alpha) { 56 58 regmap_write(layer->regs, 57 59 SUN8I_MIXER_FCC_GLOBAL_ALPHA_REG, 58 60 SUN8I_MIXER_FCC_GLOBAL_ALPHA(state->alpha >> 8)); ··· 76 78 DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n", 77 79 layer->channel, layer->overlay); 78 80 79 - ch_base = sun8i_channel_base(mixer, layer->channel); 81 + ch_base = sun8i_channel_base(layer); 80 82 81 83 src_w = drm_rect_width(&state->src) >> 16; 82 84 src_h = drm_rect_height(&state->src) >> 16; ··· 151 153 } 152 154 153 155 /* it seems that every RGB scaler has buffer for 2048 pixels */ 154 - scanline = subsampled ? mixer->cfg->lay_cfg.scanline_yuv : 2048; 156 + scanline = subsampled ? layer->cfg->scanline_yuv : 2048; 155 157 156 158 if (src_w > scanline) { 157 159 DRM_DEBUG_DRIVER("Using horizontal coarse scaling\n"); ··· 193 195 struct drm_plane *plane) 194 196 { 195 197 struct drm_plane_state *state = plane->state; 196 - struct sun8i_mixer *mixer = layer->mixer; 197 198 struct drm_framebuffer *fb = state->fb; 198 199 const struct drm_format_info *format = fb->format; 199 200 struct drm_gem_dma_object *gem; ··· 201 204 u32 ch_base; 202 205 int i; 203 206 204 - ch_base = sun8i_channel_base(mixer, layer->channel); 207 + ch_base = sun8i_channel_base(layer); 205 208 206 209 /* Adjust x and y to be dividable by subsampling factor */ 207 210 src_x = (state->src.x1 >> 16) & ~(format->hsub - 1); ··· 275 278 min_scale = DRM_PLANE_NO_SCALING; 276 279 max_scale = DRM_PLANE_NO_SCALING; 277 280 278 - if (layer->mixer->cfg->lay_cfg.scaler_mask & BIT(layer->channel)) { 281 + if (layer->cfg->scaler_mask & BIT(layer->channel)) { 279 282 min_scale = SUN8I_VI_SCALER_SCALE_MIN; 280 283 max_scale = SUN8I_VI_SCALER_SCALE_MAX; 281 284 } ··· 411 414 enum drm_plane_type type, 412 415 struct regmap *regs, 413 416 int index, int phy_index, 414 - int plane_cnt) 417 + int plane_cnt, 418 + const struct sun8i_layer_cfg *cfg) 415 419 { 416 420 u32 supported_encodings, supported_ranges; 417 421 unsigned int format_count; ··· 430 432 layer->channel = phy_index; 431 433 layer->overlay = 0; 432 434 layer->regs = regs; 435 + layer->cfg = cfg; 433 436 434 - if (mixer->cfg->de_type >= SUN8I_MIXER_DE3) { 437 + if (layer->cfg->de_type >= SUN8I_MIXER_DE3) { 435 438 formats = sun8i_vi_layer_de3_formats; 436 439 format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); 437 440 } else { ··· 451 452 return ERR_PTR(ret); 452 453 } 453 454 454 - if (mixer->cfg->lay_cfg.de2_fcc_alpha || mixer->cfg->de_type >= SUN8I_MIXER_DE3) { 455 + if (layer->cfg->de2_fcc_alpha || layer->cfg->de_type >= SUN8I_MIXER_DE3) { 455 456 ret = drm_plane_create_alpha_property(&layer->plane); 456 457 if (ret) { 457 458 dev_err(drm->dev, "Couldn't add alpha property\n"); ··· 468 469 469 470 supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) | 470 471 BIT(DRM_COLOR_YCBCR_BT709); 471 - if (mixer->cfg->de_type >= SUN8I_MIXER_DE3) 472 + if (layer->cfg->de_type >= SUN8I_MIXER_DE3) 472 473 supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020); 473 474 474 475 supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
+2 -1
drivers/gpu/drm/sun4i/sun8i_vi_layer.h
··· 59 59 enum drm_plane_type type, 60 60 struct regmap *regs, 61 61 int index, int phy_index, 62 - int plane_cnt); 62 + int plane_cnt, 63 + const struct sun8i_layer_cfg *cfg); 63 64 #endif /* _SUN8I_VI_LAYER_H_ */
+9 -10
drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
··· 833 833 0x1012110d, 0x1012110d, 0x1013110c, 0x1013110c, 834 834 }; 835 835 836 - static u32 sun8i_vi_scaler_base(struct sun8i_mixer *mixer, int channel) 836 + static u32 sun8i_vi_scaler_base(struct sun8i_layer *layer) 837 837 { 838 - if (mixer->cfg->de_type == SUN8I_MIXER_DE33) 838 + if (layer->cfg->de_type == SUN8I_MIXER_DE33) 839 839 return DE33_VI_SCALER_UNIT_BASE + 840 - DE33_CH_SIZE * channel; 841 - else if (mixer->cfg->de_type == SUN8I_MIXER_DE3) 840 + DE33_CH_SIZE * layer->channel; 841 + else if (layer->cfg->de_type == SUN8I_MIXER_DE3) 842 842 return DE3_VI_SCALER_UNIT_BASE + 843 - DE3_VI_SCALER_UNIT_SIZE * channel; 843 + DE3_VI_SCALER_UNIT_SIZE * layer->channel; 844 844 else 845 845 return DE2_VI_SCALER_UNIT_BASE + 846 - DE2_VI_SCALER_UNIT_SIZE * channel; 846 + DE2_VI_SCALER_UNIT_SIZE * layer->channel; 847 847 } 848 848 849 849 static int sun8i_vi_scaler_coef_index(unsigned int step) ··· 914 914 { 915 915 u32 val, base; 916 916 917 - base = sun8i_vi_scaler_base(layer->mixer, layer->channel); 917 + base = sun8i_vi_scaler_base(layer); 918 918 919 919 if (enable) 920 920 val = SUN8I_SCALER_VSU_CTRL_EN | ··· 931 931 u32 hscale, u32 vscale, u32 hphase, u32 vphase, 932 932 const struct drm_format_info *format) 933 933 { 934 - struct sun8i_mixer *mixer = layer->mixer; 935 934 u32 chphase, cvphase; 936 935 u32 insize, outsize; 937 936 u32 base; 938 937 939 - base = sun8i_vi_scaler_base(mixer, layer->channel); 938 + base = sun8i_vi_scaler_base(layer); 940 939 941 940 hphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16; 942 941 vphase <<= SUN8I_VI_SCALER_PHASE_FRAC - 16; ··· 959 960 cvphase = vphase; 960 961 } 961 962 962 - if (mixer->cfg->de_type >= SUN8I_MIXER_DE3) { 963 + if (layer->cfg->de_type >= SUN8I_MIXER_DE3) { 963 964 u32 val; 964 965 965 966 if (format->hsub == 1 && format->vsub == 1)