All of lore.kernel.org
 help / color / mirror / Atom feed
From: Neil Armstrong <narmstrong@baylibre.com>
To: dri-devel@lists.freedesktop.org
Cc: Neil Armstrong <narmstrong@baylibre.com>,
	linux-amlogic@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH 2/3] drm/meson: move OSD scaler management into plane atomic update
Date: Tue,  6 Nov 2018 10:40:01 +0100	[thread overview]
Message-ID: <1541497202-20570-3-git-send-email-narmstrong@baylibre.com> (raw)
In-Reply-To: <1541497202-20570-1-git-send-email-narmstrong@baylibre.com>

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.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 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 38686c9..d78168f 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -189,21 +189,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,
-- 
2.7.4


WARNING: multiple messages have this Message-ID (diff)
From: narmstrong@baylibre.com (Neil Armstrong)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/3] drm/meson: move OSD scaler management into plane atomic update
Date: Tue,  6 Nov 2018 10:40:01 +0100	[thread overview]
Message-ID: <1541497202-20570-3-git-send-email-narmstrong@baylibre.com> (raw)
In-Reply-To: <1541497202-20570-1-git-send-email-narmstrong@baylibre.com>

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.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 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 38686c9..d78168f 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -189,21 +189,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,
-- 
2.7.4

WARNING: multiple messages have this Message-ID (diff)
From: Neil Armstrong <narmstrong@baylibre.com>
To: dri-devel@lists.freedesktop.org
Cc: linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	Neil Armstrong <narmstrong@baylibre.com>
Subject: [PATCH 2/3] drm/meson: move OSD scaler management into plane atomic update
Date: Tue,  6 Nov 2018 10:40:01 +0100	[thread overview]
Message-ID: <1541497202-20570-3-git-send-email-narmstrong@baylibre.com> (raw)
In-Reply-To: <1541497202-20570-1-git-send-email-narmstrong@baylibre.com>

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.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 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 38686c9..d78168f 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -189,21 +189,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,
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: narmstrong@baylibre.com (Neil Armstrong)
To: linus-amlogic@lists.infradead.org
Subject: [PATCH 2/3] drm/meson: move OSD scaler management into plane atomic update
Date: Tue,  6 Nov 2018 10:40:01 +0100	[thread overview]
Message-ID: <1541497202-20570-3-git-send-email-narmstrong@baylibre.com> (raw)
In-Reply-To: <1541497202-20570-1-git-send-email-narmstrong@baylibre.com>

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.

Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 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 38686c9..d78168f 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -189,21 +189,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,
-- 
2.7.4

  parent reply	other threads:[~2018-11-06  9:40 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-06  9:39 [PATCH 0/3] drm/meson: Add support for Overlay and OSD Plane scaling Neil Armstrong
2018-11-06  9:39 ` Neil Armstrong
2018-11-06  9:39 ` Neil Armstrong
2018-11-06  9:39 ` Neil Armstrong
2018-11-06  9:40 ` [PATCH 1/3] drm/meson: Support Overlay plane for video rendering Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-07  9:41   ` Maxime Jourdan
2018-11-07  9:41     ` Maxime Jourdan
2018-11-07  9:41     ` Maxime Jourdan
2018-11-06  9:40 ` Neil Armstrong [this message]
2018-11-06  9:40   ` [PATCH 2/3] drm/meson: move OSD scaler management into plane atomic update Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-06  9:40 ` [PATCH 3/3] drm/meson: Add primary plane scaling Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-06  9:40   ` Neil Armstrong
2018-11-06 11:13 ` [PATCH 0/3] drm/meson: Add support for Overlay and OSD Plane scaling Daniel Vetter
2018-11-06 11:13   ` Daniel Vetter
2018-11-06 11:13   ` Daniel Vetter
2018-11-06 11:13   ` Daniel Vetter
2018-11-06 13:36   ` Neil Armstrong
2018-11-06 13:36     ` Neil Armstrong
2018-11-06 13:36     ` Neil Armstrong
2018-11-06 13:36     ` Neil Armstrong
2018-11-06 13:59     ` Daniel Vetter
2018-11-06 13:59       ` Daniel Vetter
2018-11-06 13:59       ` Daniel Vetter
2018-11-06 13:59       ` Daniel Vetter
2018-11-13 13:33 ` Neil Armstrong
2018-11-13 13:33   ` Neil Armstrong
2018-11-13 13:33   ` Neil Armstrong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1541497202-20570-3-git-send-email-narmstrong@baylibre.com \
    --to=narmstrong@baylibre.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.