Lines Matching +full:sun4i +full:- +full:a10 +full:- +full:ahb +full:- +full:clk

1 // SPDX-License-Identifier: GPL-2.0+
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
7 #include <linux/clk.h>
59 * The first three values of each row are coded as 13-bit signed fixed-point
61 * constant coded as a 14-bit signed fixed-point number with 4 bits for the
65 * G = 1.164 * Y - 0.391 * U - 0.813 * V + 135
66 * R = 1.164 * Y + 1.596 * V - 222
83 if (frontend->data->has_coef_access_ctrl) in sun4i_frontend_scaler_init()
84 regmap_write_bits(frontend->regs, SUN4I_FRONTEND_FRM_CTRL_REG, in sun4i_frontend_scaler_init()
89 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZCOEF0_REG(i), in sun4i_frontend_scaler_init()
91 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZCOEF0_REG(i), in sun4i_frontend_scaler_init()
93 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZCOEF1_REG(i), in sun4i_frontend_scaler_init()
95 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZCOEF1_REG(i), in sun4i_frontend_scaler_init()
97 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTCOEF_REG(i), in sun4i_frontend_scaler_init()
99 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTCOEF_REG(i), in sun4i_frontend_scaler_init()
103 if (frontend->data->has_coef_rdy) in sun4i_frontend_scaler_init()
104 regmap_write_bits(frontend->regs, in sun4i_frontend_scaler_init()
112 return pm_runtime_get_sync(frontend->dev); in sun4i_frontend_init()
118 pm_runtime_put(frontend->dev); in sun4i_frontend_exit()
159 struct drm_plane_state *state = plane->state; in sun4i_frontend_update_buffer()
160 struct drm_framebuffer *fb = state->fb; in sun4i_frontend_update_buffer()
166 if (fb->modifier == DRM_FORMAT_MOD_ALLWINNER_TILED) { in sun4i_frontend_update_buffer()
167 unsigned int width = state->src_w >> 16; in sun4i_frontend_update_buffer()
170 strides[0] = SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[0]); in sun4i_frontend_update_buffer()
173 * The X1 offset is the offset to the bottom-right point in the in sun4i_frontend_update_buffer()
174 * end tile, which is the final pixel (at offset width - 1) in sun4i_frontend_update_buffer()
175 * within the end tile (with a 32-byte mask). in sun4i_frontend_update_buffer()
177 offset = (width - 1) & (32 - 1); in sun4i_frontend_update_buffer()
179 regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF0_REG, in sun4i_frontend_update_buffer()
182 if (fb->format->num_planes > 1) { in sun4i_frontend_update_buffer()
184 SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[1]); in sun4i_frontend_update_buffer()
186 regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF1_REG, in sun4i_frontend_update_buffer()
190 if (fb->format->num_planes > 2) { in sun4i_frontend_update_buffer()
192 SUN4I_FRONTEND_LINESTRD_TILED(fb->pitches[2]); in sun4i_frontend_update_buffer()
194 regmap_write(frontend->regs, SUN4I_FRONTEND_TB_OFF2_REG, in sun4i_frontend_update_buffer()
198 strides[0] = fb->pitches[0]; in sun4i_frontend_update_buffer()
200 if (fb->format->num_planes > 1) in sun4i_frontend_update_buffer()
201 strides[1] = fb->pitches[1]; in sun4i_frontend_update_buffer()
203 if (fb->format->num_planes > 2) in sun4i_frontend_update_buffer()
204 strides[2] = fb->pitches[2]; in sun4i_frontend_update_buffer()
208 DRM_DEBUG_DRIVER("Frontend stride: %d bytes\n", fb->pitches[0]); in sun4i_frontend_update_buffer()
209 regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD0_REG, in sun4i_frontend_update_buffer()
212 if (fb->format->num_planes > 1) in sun4i_frontend_update_buffer()
213 regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD1_REG, in sun4i_frontend_update_buffer()
216 if (fb->format->num_planes > 2) in sun4i_frontend_update_buffer()
217 regmap_write(frontend->regs, SUN4I_FRONTEND_LINESTRD2_REG, in sun4i_frontend_update_buffer()
221 swap = sun4i_frontend_format_chroma_requires_swap(fb->format->format); in sun4i_frontend_update_buffer()
226 regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR0_REG, dma_addr); in sun4i_frontend_update_buffer()
228 if (fb->format->num_planes > 1) { in sun4i_frontend_update_buffer()
232 regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR1_REG, in sun4i_frontend_update_buffer()
236 if (fb->format->num_planes > 2) { in sun4i_frontend_update_buffer()
240 regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR2_REG, in sun4i_frontend_update_buffer()
250 if (!format->is_yuv) in sun4i_frontend_drm_format_to_input_fmt()
261 return -EINVAL; in sun4i_frontend_drm_format_to_input_fmt()
272 switch (format->num_planes) { in sun4i_frontend_drm_format_to_input_mode()
288 return -EINVAL; in sun4i_frontend_drm_format_to_input_mode()
302 switch (format->format) { in sun4i_frontend_drm_format_to_input_sequence()
344 return -EINVAL; in sun4i_frontend_drm_format_to_input_sequence()
360 return -EINVAL; in sun4i_frontend_drm_format_to_output_fmt()
405 struct drm_plane_state *state = plane->state; in sun4i_frontend_update_formats()
406 struct drm_framebuffer *fb = state->fb; in sun4i_frontend_update_formats()
407 const struct drm_format_info *format = fb->format; in sun4i_frontend_update_formats()
408 uint64_t modifier = fb->modifier; in sun4i_frontend_update_formats()
445 ch1_phase_idx = (format->num_planes > 1) ? 1 : 0; in sun4i_frontend_update_formats()
446 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZPHASE_REG, in sun4i_frontend_update_formats()
447 frontend->data->ch_phase[0]); in sun4i_frontend_update_formats()
448 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZPHASE_REG, in sun4i_frontend_update_formats()
449 frontend->data->ch_phase[ch1_phase_idx]); in sun4i_frontend_update_formats()
450 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE0_REG, in sun4i_frontend_update_formats()
451 frontend->data->ch_phase[0]); in sun4i_frontend_update_formats()
452 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE0_REG, in sun4i_frontend_update_formats()
453 frontend->data->ch_phase[ch1_phase_idx]); in sun4i_frontend_update_formats()
454 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG, in sun4i_frontend_update_formats()
455 frontend->data->ch_phase[0]); in sun4i_frontend_update_formats()
456 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG, in sun4i_frontend_update_formats()
457 frontend->data->ch_phase[ch1_phase_idx]); in sun4i_frontend_update_formats()
465 if (format->is_yuv) { in sun4i_frontend_update_formats()
470 regmap_write(frontend->regs, in sun4i_frontend_update_formats()
477 regmap_update_bits(frontend->regs, SUN4I_FRONTEND_BYPASS_REG, in sun4i_frontend_update_formats()
480 regmap_write(frontend->regs, SUN4I_FRONTEND_INPUT_FMT_REG, in sun4i_frontend_update_formats()
488 regmap_write(frontend->regs, SUN4I_FRONTEND_OUTPUT_FMT_REG, in sun4i_frontend_update_formats()
498 struct drm_plane_state *state = plane->state; in sun4i_frontend_update_coord()
499 struct drm_framebuffer *fb = state->fb; in sun4i_frontend_update_coord()
505 state->crtc_w, state->crtc_h); in sun4i_frontend_update_coord()
507 luma_width = state->src_w >> 16; in sun4i_frontend_update_coord()
508 luma_height = state->src_h >> 16; in sun4i_frontend_update_coord()
510 chroma_width = DIV_ROUND_UP(luma_width, fb->format->hsub); in sun4i_frontend_update_coord()
511 chroma_height = DIV_ROUND_UP(luma_height, fb->format->vsub); in sun4i_frontend_update_coord()
513 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_INSIZE_REG, in sun4i_frontend_update_coord()
515 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_INSIZE_REG, in sun4i_frontend_update_coord()
518 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_OUTSIZE_REG, in sun4i_frontend_update_coord()
519 SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); in sun4i_frontend_update_coord()
520 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_OUTSIZE_REG, in sun4i_frontend_update_coord()
521 SUN4I_FRONTEND_OUTSIZE(state->crtc_h, state->crtc_w)); in sun4i_frontend_update_coord()
523 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZFACT_REG, in sun4i_frontend_update_coord()
524 (luma_width << 16) / state->crtc_w); in sun4i_frontend_update_coord()
525 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZFACT_REG, in sun4i_frontend_update_coord()
526 (chroma_width << 16) / state->crtc_w); in sun4i_frontend_update_coord()
528 regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTFACT_REG, in sun4i_frontend_update_coord()
529 (luma_height << 16) / state->crtc_h); in sun4i_frontend_update_coord()
530 regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTFACT_REG, in sun4i_frontend_update_coord()
531 (chroma_height << 16) / state->crtc_h); in sun4i_frontend_update_coord()
533 regmap_write_bits(frontend->regs, SUN4I_FRONTEND_FRM_CTRL_REG, in sun4i_frontend_update_coord()
541 regmap_write_bits(frontend->regs, SUN4I_FRONTEND_FRM_CTRL_REG, in sun4i_frontend_enable()
562 struct sun4i_drv *drv = drm->dev_private; in sun4i_frontend_bind()
567 return -ENOMEM; in sun4i_frontend_bind()
570 frontend->dev = dev; in sun4i_frontend_bind()
571 frontend->node = dev->of_node; in sun4i_frontend_bind()
573 frontend->data = of_device_get_match_data(dev); in sun4i_frontend_bind()
574 if (!frontend->data) in sun4i_frontend_bind()
575 return -ENODEV; in sun4i_frontend_bind()
581 frontend->regs = devm_regmap_init_mmio(dev, regs, in sun4i_frontend_bind()
583 if (IS_ERR(frontend->regs)) { in sun4i_frontend_bind()
585 return PTR_ERR(frontend->regs); in sun4i_frontend_bind()
588 frontend->reset = devm_reset_control_get(dev, NULL); in sun4i_frontend_bind()
589 if (IS_ERR(frontend->reset)) { in sun4i_frontend_bind()
591 return PTR_ERR(frontend->reset); in sun4i_frontend_bind()
594 frontend->bus_clk = devm_clk_get(dev, "ahb"); in sun4i_frontend_bind()
595 if (IS_ERR(frontend->bus_clk)) { in sun4i_frontend_bind()
597 return PTR_ERR(frontend->bus_clk); in sun4i_frontend_bind()
600 frontend->mod_clk = devm_clk_get(dev, "mod"); in sun4i_frontend_bind()
601 if (IS_ERR(frontend->mod_clk)) { in sun4i_frontend_bind()
603 return PTR_ERR(frontend->mod_clk); in sun4i_frontend_bind()
606 frontend->ram_clk = devm_clk_get(dev, "ram"); in sun4i_frontend_bind()
607 if (IS_ERR(frontend->ram_clk)) { in sun4i_frontend_bind()
609 return PTR_ERR(frontend->ram_clk); in sun4i_frontend_bind()
612 list_add_tail(&frontend->list, &drv->frontend_list); in sun4i_frontend_bind()
623 list_del(&frontend->list); in sun4i_frontend_unbind()
634 return component_add(&pdev->dev, &sun4i_frontend_ops); in sun4i_frontend_probe()
639 component_del(&pdev->dev, &sun4i_frontend_ops); in sun4i_frontend_remove()
647 clk_set_rate(frontend->mod_clk, 300000000); in sun4i_frontend_runtime_resume()
649 clk_prepare_enable(frontend->bus_clk); in sun4i_frontend_runtime_resume()
650 clk_prepare_enable(frontend->mod_clk); in sun4i_frontend_runtime_resume()
651 clk_prepare_enable(frontend->ram_clk); in sun4i_frontend_runtime_resume()
653 ret = reset_control_reset(frontend->reset); in sun4i_frontend_runtime_resume()
659 regmap_update_bits(frontend->regs, SUN4I_FRONTEND_EN_REG, in sun4i_frontend_runtime_resume()
672 clk_disable_unprepare(frontend->ram_clk); in sun4i_frontend_runtime_suspend()
673 clk_disable_unprepare(frontend->mod_clk); in sun4i_frontend_runtime_suspend()
674 clk_disable_unprepare(frontend->bus_clk); in sun4i_frontend_runtime_suspend()
676 reset_control_assert(frontend->reset); in sun4i_frontend_runtime_suspend()
698 .compatible = "allwinner,sun4i-a10-display-frontend",
702 .compatible = "allwinner,sun7i-a20-display-frontend",
706 .compatible = "allwinner,sun8i-a23-display-frontend",
710 .compatible = "allwinner,sun8i-a33-display-frontend",
722 .name = "sun4i-frontend",
729 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
730 MODULE_DESCRIPTION("Allwinner A10 Display Engine Frontend Driver");