Lines Matching +full:16 +full:- +full:channel
1 // SPDX-License-Identifier: GPL-2.0-or-later
21 static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, in sun8i_vi_layer_update_alpha() argument
26 ch_base = sun8i_channel_base(mixer, channel); in sun8i_vi_layer_update_alpha()
28 if (mixer->cfg->is_de3) { in sun8i_vi_layer_update_alpha()
32 (plane->state->alpha >> 8); in sun8i_vi_layer_update_alpha()
34 val |= (plane->state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? in sun8i_vi_layer_update_alpha()
38 regmap_update_bits(mixer->engine.regs, in sun8i_vi_layer_update_alpha()
42 } else if (mixer->cfg->vi_num == 1) { in sun8i_vi_layer_update_alpha()
43 regmap_update_bits(mixer->engine.regs, in sun8i_vi_layer_update_alpha()
47 (plane->state->alpha >> 8)); in sun8i_vi_layer_update_alpha()
51 static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, in sun8i_vi_layer_update_coord() argument
55 struct drm_plane_state *state = plane->state; in sun8i_vi_layer_update_coord()
56 const struct drm_format_info *format = state->fb->format; in sun8i_vi_layer_update_coord()
65 DRM_DEBUG_DRIVER("Updating VI channel %d overlay %d\n", in sun8i_vi_layer_update_coord()
66 channel, overlay); in sun8i_vi_layer_update_coord()
69 ch_base = sun8i_channel_base(mixer, channel); in sun8i_vi_layer_update_coord()
71 src_w = drm_rect_width(&state->src) >> 16; in sun8i_vi_layer_update_coord()
72 src_h = drm_rect_height(&state->src) >> 16; in sun8i_vi_layer_update_coord()
73 dst_w = drm_rect_width(&state->dst); in sun8i_vi_layer_update_coord()
74 dst_h = drm_rect_height(&state->dst); in sun8i_vi_layer_update_coord()
76 hphase = state->src.x1 & 0xffff; in sun8i_vi_layer_update_coord()
77 vphase = state->src.y1 & 0xffff; in sun8i_vi_layer_update_coord()
80 if (format->hsub > 1) { in sun8i_vi_layer_update_coord()
83 mask = format->hsub - 1; in sun8i_vi_layer_update_coord()
84 remainder = (state->src.x1 >> 16) & mask; in sun8i_vi_layer_update_coord()
86 hphase += remainder << 16; in sun8i_vi_layer_update_coord()
89 if (format->vsub > 1) { in sun8i_vi_layer_update_coord()
92 mask = format->vsub - 1; in sun8i_vi_layer_update_coord()
93 remainder = (state->src.y1 >> 16) & mask; in sun8i_vi_layer_update_coord()
95 vphase += remainder << 16; in sun8i_vi_layer_update_coord()
103 (state->src.x1 >> 16) & ~(format->hsub - 1), in sun8i_vi_layer_update_coord()
104 (state->src.y1 >> 16) & ~(format->vsub - 1)); in sun8i_vi_layer_update_coord()
106 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
109 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
117 subsampled = format->hsub > 1 || format->vsub > 1; in sun8i_vi_layer_update_coord()
127 mode = &plane->state->crtc->state->mode; in sun8i_vi_layer_update_coord()
128 fps = (mode->clock * 1000) / (mode->vtotal * mode->htotal); in sun8i_vi_layer_update_coord()
129 ability = clk_get_rate(mixer->mod_clk); in sun8i_vi_layer_update_coord()
132 do_div(ability, mode->vdisplay * fps * max(src_w, dst_w)); in sun8i_vi_layer_update_coord()
144 scanline = subsampled ? mixer->cfg->scanline_yuv : 2048; in sun8i_vi_layer_update_coord()
153 hscale = (src_w << 16) / dst_w; in sun8i_vi_layer_update_coord()
154 vscale = (src_h << 16) / dst_h; in sun8i_vi_layer_update_coord()
156 sun8i_vi_scaler_setup(mixer, channel, src_w, src_h, dst_w, in sun8i_vi_layer_update_coord()
159 sun8i_vi_scaler_enable(mixer, channel, true); in sun8i_vi_layer_update_coord()
162 sun8i_vi_scaler_enable(mixer, channel, false); in sun8i_vi_layer_update_coord()
165 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
169 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
173 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
177 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
184 state->dst.x1, state->dst.y1); in sun8i_vi_layer_update_coord()
186 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
188 SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); in sun8i_vi_layer_update_coord()
189 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_coord()
198 if (!format->is_yuv) in sun8i_vi_layer_get_csc_mode()
201 switch (format->format) { in sun8i_vi_layer_get_csc_mode()
212 static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, in sun8i_vi_layer_update_formats() argument
215 struct drm_plane_state *state = plane->state; in sun8i_vi_layer_update_formats()
220 ch_base = sun8i_channel_base(mixer, channel); in sun8i_vi_layer_update_formats()
222 fmt = state->fb->format; in sun8i_vi_layer_update_formats()
223 ret = sun8i_mixer_drm_format_to_hw(fmt->format, &hw_fmt); in sun8i_vi_layer_update_formats()
230 regmap_update_bits(mixer->engine.regs, in sun8i_vi_layer_update_formats()
236 sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode, in sun8i_vi_layer_update_formats()
237 state->color_encoding, in sun8i_vi_layer_update_formats()
238 state->color_range); in sun8i_vi_layer_update_formats()
239 sun8i_csc_enable_ccsc(mixer, channel, true); in sun8i_vi_layer_update_formats()
241 sun8i_csc_enable_ccsc(mixer, channel, false); in sun8i_vi_layer_update_formats()
244 if (!fmt->is_yuv) in sun8i_vi_layer_update_formats()
249 regmap_update_bits(mixer->engine.regs, in sun8i_vi_layer_update_formats()
256 static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel, in sun8i_vi_layer_update_buffer() argument
259 struct drm_plane_state *state = plane->state; in sun8i_vi_layer_update_buffer()
260 struct drm_framebuffer *fb = state->fb; in sun8i_vi_layer_update_buffer()
261 const struct drm_format_info *format = fb->format; in sun8i_vi_layer_update_buffer()
268 ch_base = sun8i_channel_base(mixer, channel); in sun8i_vi_layer_update_buffer()
271 src_x = (state->src.x1 >> 16) & ~(format->hsub - 1); in sun8i_vi_layer_update_buffer()
272 src_y = (state->src.y1 >> 16) & ~(format->vsub - 1); in sun8i_vi_layer_update_buffer()
274 for (i = 0; i < format->num_planes; i++) { in sun8i_vi_layer_update_buffer()
278 DRM_DEBUG_DRIVER("Using GEM @ %pad\n", &gem->dma_addr); in sun8i_vi_layer_update_buffer()
281 dma_addr = gem->dma_addr + fb->offsets[i]; in sun8i_vi_layer_update_buffer()
287 dx /= format->hsub; in sun8i_vi_layer_update_buffer()
288 dy /= format->vsub; in sun8i_vi_layer_update_buffer()
292 dma_addr += dx * format->cpp[i]; in sun8i_vi_layer_update_buffer()
293 dma_addr += dy * fb->pitches[i]; in sun8i_vi_layer_update_buffer()
297 i + 1, fb->pitches[i]); in sun8i_vi_layer_update_buffer()
298 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_buffer()
301 fb->pitches[i]); in sun8i_vi_layer_update_buffer()
306 regmap_write(mixer->engine.regs, in sun8i_vi_layer_update_buffer()
321 struct drm_crtc *crtc = new_plane_state->crtc; in sun8i_vi_layer_atomic_check()
331 return -EINVAL; in sun8i_vi_layer_atomic_check()
336 if (layer->mixer->cfg->scaler_mask & BIT(layer->channel)) { in sun8i_vi_layer_atomic_check()
353 unsigned int zpos = new_state->normalized_zpos; in sun8i_vi_layer_atomic_update()
354 struct sun8i_mixer *mixer = layer->mixer; in sun8i_vi_layer_atomic_update()
356 if (!new_state->crtc || !new_state->visible) in sun8i_vi_layer_atomic_update()
359 sun8i_vi_layer_update_coord(mixer, layer->channel, in sun8i_vi_layer_atomic_update()
360 layer->overlay, plane, zpos); in sun8i_vi_layer_atomic_update()
361 sun8i_vi_layer_update_alpha(mixer, layer->channel, in sun8i_vi_layer_atomic_update()
362 layer->overlay, plane); in sun8i_vi_layer_atomic_update()
363 sun8i_vi_layer_update_formats(mixer, layer->channel, in sun8i_vi_layer_atomic_update()
364 layer->overlay, plane); in sun8i_vi_layer_atomic_update()
365 sun8i_vi_layer_update_buffer(mixer, layer->channel, in sun8i_vi_layer_atomic_update()
366 layer->overlay, plane); in sun8i_vi_layer_atomic_update()
385 * channel is ignored. This structure lists all unique variants
386 * where alpha channel is replaced with "don't care" (X) channel.
482 layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); in sun8i_vi_layer_init_one()
484 return ERR_PTR(-ENOMEM); in sun8i_vi_layer_init_one()
486 if (mixer->cfg->is_de3) { in sun8i_vi_layer_init_one()
494 if (!mixer->cfg->ui_num && index == 0) in sun8i_vi_layer_init_one()
498 ret = drm_universal_plane_init(drm, &layer->plane, 0, in sun8i_vi_layer_init_one()
504 dev_err(drm->dev, "Couldn't initialize layer\n"); in sun8i_vi_layer_init_one()
508 plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; in sun8i_vi_layer_init_one()
510 if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) { in sun8i_vi_layer_init_one()
511 ret = drm_plane_create_alpha_property(&layer->plane); in sun8i_vi_layer_init_one()
513 dev_err(drm->dev, "Couldn't add alpha property\n"); in sun8i_vi_layer_init_one()
518 ret = drm_plane_create_zpos_property(&layer->plane, index, in sun8i_vi_layer_init_one()
519 0, plane_cnt - 1); in sun8i_vi_layer_init_one()
521 dev_err(drm->dev, "Couldn't add zpos property\n"); in sun8i_vi_layer_init_one()
527 if (mixer->cfg->is_de3) in sun8i_vi_layer_init_one()
533 ret = drm_plane_create_color_properties(&layer->plane, in sun8i_vi_layer_init_one()
539 dev_err(drm->dev, "Couldn't add encoding and range properties!\n"); in sun8i_vi_layer_init_one()
543 drm_plane_helper_add(&layer->plane, &sun8i_vi_layer_helper_funcs); in sun8i_vi_layer_init_one()
544 layer->mixer = mixer; in sun8i_vi_layer_init_one()
545 layer->type = SUN8I_LAYER_TYPE_VI; in sun8i_vi_layer_init_one()
546 layer->channel = index; in sun8i_vi_layer_init_one()
547 layer->overlay = 0; in sun8i_vi_layer_init_one()