aboutsummaryrefslogtreecommitdiffstats
path: root/testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch
diff options
context:
space:
mode:
Diffstat (limited to 'testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch')
-rw-r--r--testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch198
1 files changed, 198 insertions, 0 deletions
diff --git a/testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch b/testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch
new file mode 100644
index 0000000000..54b356de64
--- /dev/null
+++ b/testing/linux-amlogic/0023-drm-meson-move-OSD-scaler-management-into-plane-atom.patch
@@ -0,0 +1,198 @@
+From b92e7773bdb2d5c86091cbb2d03cc55ec6365115 Mon Sep 17 00:00:00 2001
+From: Neil Armstrong <narmstrong@baylibre.com>
+Date: Mon, 29 Oct 2018 17:04:05 +0100
+Subject: [PATCH] drm/meson: move OSD scaler management into plane atomic
+ update
+
+In preparation to support the Primary Plane scaling, move the basic
+OSD Interlace-Only scaler setup code into the primary plane atomic
+update callback and handle the vsync scaler update like the overlay
+plane scaling registers update.
+
+---
+ drivers/gpu/drm/meson/meson_crtc.c | 35 ++++++++++++++++------------
+ drivers/gpu/drm/meson/meson_drv.h | 10 ++++++++
+ drivers/gpu/drm/meson/meson_plane.c | 39 ++++++++++++++++++++++++++++++-
+ drivers/gpu/drm/meson/meson_vpp.c | 46 -------------------------------------
+ 4 files changed, 68 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
+index 1d9d22c..6099997 100644
+--- a/drivers/gpu/drm/meson/meson_crtc.c
++++ b/drivers/gpu/drm/meson/meson_crtc.c
+@@ -193,21 +193,26 @@ void meson_crtc_irq(struct meson_drm *priv)
+ priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W3));
+ writel_relaxed(priv->viu.osd1_blk0_cfg[4],
+ priv->io_base + _REG(VIU_OSD1_BLK0_CFG_W4));
+-
+- /* If output is interlace, make use of the Scaler */
+- if (priv->viu.osd1_interlace) {
+- struct drm_plane *plane = priv->primary_plane;
+- struct drm_plane_state *state = plane->state;
+- struct drm_rect dest = {
+- .x1 = state->crtc_x,
+- .y1 = state->crtc_y,
+- .x2 = state->crtc_x + state->crtc_w,
+- .y2 = state->crtc_y + state->crtc_h,
+- };
+-
+- meson_vpp_setup_interlace_vscaler_osd1(priv, &dest);
+- } else
+- meson_vpp_disable_interlace_vscaler_osd1(priv);
++ writel_relaxed(priv->viu.osd_sc_ctrl0,
++ priv->io_base + _REG(VPP_OSD_SC_CTRL0));
++ writel_relaxed(priv->viu.osd_sc_i_wh_m1,
++ priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
++ writel_relaxed(priv->viu.osd_sc_o_h_start_end,
++ priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
++ writel_relaxed(priv->viu.osd_sc_o_v_start_end,
++ priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
++ writel_relaxed(priv->viu.osd_sc_v_ini_phase,
++ priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
++ writel_relaxed(priv->viu.osd_sc_v_phase_step,
++ priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
++ writel_relaxed(priv->viu.osd_sc_h_ini_phase,
++ priv->io_base + _REG(VPP_OSD_HSC_INI_PHASE));
++ writel_relaxed(priv->viu.osd_sc_h_phase_step,
++ priv->io_base + _REG(VPP_OSD_HSC_PHASE_STEP));
++ writel_relaxed(priv->viu.osd_sc_h_ctrl0,
++ priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
++ writel_relaxed(priv->viu.osd_sc_v_ctrl0,
++ priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
+
+ if (priv->canvas)
+ meson_canvas_config(priv->canvas, priv->canvas_id_osd1,
+diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h
+index c971557..a955354 100644
+--- a/drivers/gpu/drm/meson/meson_drv.h
++++ b/drivers/gpu/drm/meson/meson_drv.h
+@@ -54,6 +54,16 @@ struct meson_drm {
+ uint32_t osd1_addr;
+ uint32_t osd1_stride;
+ uint32_t osd1_height;
++ uint32_t osd_sc_ctrl0;
++ uint32_t osd_sc_i_wh_m1;
++ uint32_t osd_sc_o_h_start_end;
++ uint32_t osd_sc_o_v_start_end;
++ uint32_t osd_sc_v_ini_phase;
++ uint32_t osd_sc_v_phase_step;
++ uint32_t osd_sc_h_ini_phase;
++ uint32_t osd_sc_h_phase_step;
++ uint32_t osd_sc_h_ctrl0;
++ uint32_t osd_sc_v_ctrl0;
+
+ bool vd1_enabled;
+ bool vd1_commit;
+diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
+index 51bec8e..f915a79 100644
+--- a/drivers/gpu/drm/meson/meson_plane.c
++++ b/drivers/gpu/drm/meson/meson_plane.c
+@@ -143,13 +143,50 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
+ break;
+ };
+
++ /*
++ * When the output is interlaced, the OSD must switch between
++ * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
++ * at each vsync.
++ * But the vertical scaler can provide such funtionnality if
++ * is configured for 2:1 scaling with interlace options enabled.
++ */
+ if (state->crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
+ priv->viu.osd1_interlace = true;
+
+ dest.y1 /= 2;
+ dest.y2 /= 2;
+- } else
++
++ priv->viu.osd_sc_ctrl0 = BIT(3)| /* Enable scaler */
++ BIT(2); /* Select OSD1 */
++
++ /* 2:1 scaling */
++ priv->viu.osd_sc_i_wh_m1 = ((drm_rect_width(&dest) - 1) << 16) |
++ (drm_rect_height(&dest) - 1);
++ priv->viu.osd_sc_o_h_start_end = (dest.x1 << 16) | dest.x2;
++ priv->viu.osd_sc_o_v_start_end = (dest.y1 << 16) | dest.y2;
++
++ /* 2:1 vertical scaling values */
++ priv->viu.osd_sc_v_ini_phase = BIT(16);
++ priv->viu.osd_sc_v_phase_step = BIT(25);
++ priv->viu.osd_sc_v_ctrl0 =
++ (4 << 0) | /* osd_vsc_bank_length */
++ (4 << 3) | /* osd_vsc_top_ini_rcv_num0 */
++ (1 << 8) | /* osd_vsc_top_rpt_p0_num0 */
++ (6 << 11) | /* osd_vsc_bot_ini_rcv_num0 */
++ (2 << 16) | /* osd_vsc_bot_rpt_p0_num0 */
++ BIT(23) | /* osd_prog_interlace */
++ BIT(24); /* Enable vertical scaler */
++
++ /* No horizontal scaling */
++ priv->viu.osd_sc_h_ini_phase = 0;
++ priv->viu.osd_sc_h_phase_step = 0;
++ priv->viu.osd_sc_h_ctrl0 = 0;
++ } else {
+ priv->viu.osd1_interlace = false;
++ priv->viu.osd_sc_ctrl0 = 0;
++ priv->viu.osd_sc_h_ctrl0 = 0;
++ priv->viu.osd_sc_v_ctrl0 = 0;
++ }
+
+ /*
+ * The format of these registers is (x2 << 16 | x1),
+diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c
+index 5dc24a9..f9efb43 100644
+--- a/drivers/gpu/drm/meson/meson_vpp.c
++++ b/drivers/gpu/drm/meson/meson_vpp.c
+@@ -51,52 +51,6 @@ void meson_vpp_setup_mux(struct meson_drm *priv, unsigned int mux)
+ writel(mux, priv->io_base + _REG(VPU_VIU_VENC_MUX_CTRL));
+ }
+
+-/*
+- * When the output is interlaced, the OSD must switch between
+- * each field using the INTERLACE_SEL_ODD (0) of VIU_OSD1_BLK0_CFG_W0
+- * at each vsync.
+- * But the vertical scaler can provide such funtionnality if
+- * is configured for 2:1 scaling with interlace options enabled.
+- */
+-void meson_vpp_setup_interlace_vscaler_osd1(struct meson_drm *priv,
+- struct drm_rect *input)
+-{
+- writel_relaxed(BIT(3) /* Enable scaler */ |
+- BIT(2), /* Select OSD1 */
+- priv->io_base + _REG(VPP_OSD_SC_CTRL0));
+-
+- writel_relaxed(((drm_rect_width(input) - 1) << 16) |
+- (drm_rect_height(input) - 1),
+- priv->io_base + _REG(VPP_OSD_SCI_WH_M1));
+- /* 2:1 scaling */
+- writel_relaxed(((input->x1) << 16) | (input->x2),
+- priv->io_base + _REG(VPP_OSD_SCO_H_START_END));
+- writel_relaxed(((input->y1 >> 1) << 16) | (input->y2 >> 1),
+- priv->io_base + _REG(VPP_OSD_SCO_V_START_END));
+-
+- /* 2:1 scaling values */
+- writel_relaxed(BIT(16), priv->io_base + _REG(VPP_OSD_VSC_INI_PHASE));
+- writel_relaxed(BIT(25), priv->io_base + _REG(VPP_OSD_VSC_PHASE_STEP));
+-
+- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
+-
+- writel_relaxed((4 << 0) /* osd_vsc_bank_length */ |
+- (4 << 3) /* osd_vsc_top_ini_rcv_num0 */ |
+- (1 << 8) /* osd_vsc_top_rpt_p0_num0 */ |
+- (6 << 11) /* osd_vsc_bot_ini_rcv_num0 */ |
+- (2 << 16) /* osd_vsc_bot_rpt_p0_num0 */ |
+- BIT(23) /* osd_prog_interlace */ |
+- BIT(24), /* Enable vertical scaler */
+- priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
+-}
+-
+-void meson_vpp_disable_interlace_vscaler_osd1(struct meson_drm *priv)
+-{
+- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
+- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
+- writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
+-}
+-
+ static unsigned int vpp_filter_coefs_4point_bspline[] = {
+ 0x15561500, 0x14561600, 0x13561700, 0x12561800,
+ 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00,