linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/15] Support IGT in display driver
@ 2023-08-23 15:13 Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 01/15] soc: mediatek: Add register definitions for GCE Hsiao Chien Sung
                   ` (14 more replies)
  0 siblings, 15 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

This series adds support for running IGT (Intel GPU Tool) tests
with MediaTek display driver. The following changes will be
applied:

1. Add a new API for creating GCE thread loop to retrieve CRCs
   from the hardware component
2. Support hardware CRC calculation in both VDOSYS0 and VDOSYS1
3. Support alpha blending in both VDOSYS0 and VDOSYS1
4. Fix minor bugs that are found during IGT test

Hsiao Chien Sung (15):
  soc: mediatek: Add register definitions for GCE
  soc: mediatek: Disable 9-bit alpha in ETHDR
  soc: mediatek: Support GCE thread loop
  mailbox: mtk-cmdq: Support GCE thread loop
  drm/mediatek: Support alpha blending in display driver
  drm/mediatek: Support alpha blending in VDOSYS0
  drm/mediatek: Support alpha blending in VDOSYS1
  drm/mediatek: Move struct mtk_drm_crtc to the header file
  drm/mediatek: Add OVL compatible name for MT8195
  drm/mediatek: Support CRC in display driver
  drm/mediatek: Support CRC in VDOSYS0
  drm/mediatek: Support CRC in VDOSYS1
  drm/mediatek: Add missing plane settings when async update
  drm/mediatek: Adjust DRM mode configs for IGT
  drm/mediatek: Fix errors when reporting rotation capability

 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   3 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c       | 304 ++++++++++++++++--
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  15 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       |  97 +++---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |  64 ++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   3 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   5 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  12 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c      |  15 +-
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 170 +++++++++-
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |   4 +
 drivers/mailbox/mtk-cmdq-mailbox.c            |   5 +
 drivers/soc/mediatek/mtk-cmdq-helper.c        |  30 ++
 drivers/soc/mediatek/mtk-mmsys.c              |   1 +
 include/linux/mailbox/mtk-cmdq-mailbox.h      |   1 +
 include/linux/soc/mediatek/mtk-cmdq.h         |   9 +
 16 files changed, 646 insertions(+), 92 deletions(-)

--
2.18.0


^ permalink raw reply	[flat|nested] 33+ messages in thread

* [PATCH 01/15] soc: mediatek: Add register definitions for GCE
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:11   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 02/15] soc: mediatek: Disable 9-bit alpha in ETHDR Hsiao Chien Sung
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Add register definitions for GCE so users can use them
as a buffer to store data.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 include/linux/soc/mediatek/mtk-cmdq.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 649955d2cf5c..3eb95ef34c6c 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -14,6 +14,13 @@
 #define CMDQ_ADDR_HIGH(addr)	((u32)(((addr) >> 16) & GENMASK(31, 0)))
 #define CMDQ_ADDR_LOW(addr)	((u16)(addr) | BIT(1))
 
+#define CMDQ_TPR_ID		(56)
+
+#define CMDQ_THR_SPR_IDX0	(0)
+#define CMDQ_THR_SPR_IDX1	(1)
+#define CMDQ_THR_SPR_IDX2	(2)
+#define CMDQ_THR_SPR_IDX3	(3)
+
 struct cmdq_pkt;
 
 struct cmdq_client_reg {
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 02/15] soc: mediatek: Disable 9-bit alpha in ETHDR
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 01/15] soc: mediatek: Add register definitions for GCE Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 03/15] soc: mediatek: Support GCE thread loop Hsiao Chien Sung
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

ETHDR 9-bit alpha should be disabled by default,
otherwise alpha blending will not work.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 9619faa796e8..acfa6fafbe52 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -209,6 +209,7 @@ void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16
 
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0,
 			      alpha << 16 | alpha, cmdq_pkt);
+	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(15 + idx), 0, cmdq_pkt);
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx),
 			      alpha_sel << (19 + idx), cmdq_pkt);
 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 03/15] soc: mediatek: Support GCE thread loop
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 01/15] soc: mediatek: Add register definitions for GCE Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 02/15] soc: mediatek: Disable 9-bit alpha in ETHDR Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-29  7:07   ` CK Hu (胡俊光)
  2023-08-30  2:15   ` CK Hu (胡俊光)
  2023-08-23 15:13 ` [PATCH 04/15] mailbox: mtk-cmdq: " Hsiao Chien Sung
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Add a new API to create GCE thread loop by
appending a command at the end of CMDQ packet
to jump to the head of it.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c | 30 ++++++++++++++++++++++++++
 include/linux/soc/mediatek/mtk-cmdq.h  |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index c1837a468267..7d503d491c0d 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -430,6 +430,9 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
 	int err;
 	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
 
+	dma_sync_single_for_device(client->chan->mbox->dev, pkt->pa_base,
+				   pkt->cmd_buf_size, DMA_TO_DEVICE);
+
 	err = mbox_send_message(client->chan, pkt);
 	if (err < 0)
 		return err;
@@ -440,4 +443,31 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
 }
 EXPORT_SYMBOL(cmdq_pkt_flush_async);
 
+int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt)
+{
+	struct cmdq_instruction inst = { {0} };
+	int err;
+	u8 shift_pa = 0;
+
+	shift_pa = cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)->chan);
+
+	/* insert EOC and generate IRQ for command iteration */
+	inst.op = CMDQ_CODE_EOC;
+	inst.value = CMDQ_EOC_IRQ_EN;
+	err = cmdq_pkt_append_command(pkt, inst);
+	if (err < 0)
+		return err;
+
+	/* jump to head of the packet */
+	inst.op = CMDQ_CODE_JUMP;
+	inst.offset = CMDQ_JUMP_RELATIVE;
+	inst.value = pkt->pa_base >> shift_pa;
+	err = cmdq_pkt_append_command(pkt, inst);
+
+	pkt->loop = true;
+
+	return err;
+}
+EXPORT_SYMBOL(cmdq_pkt_finalize_loop);
+
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 3eb95ef34c6c..4c30f891d924 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -273,6 +273,8 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt, dma_addr_t addr);
  */
 int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
 
+int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt);
+
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
  *                          packet and call back at the end of done packet
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 04/15] mailbox: mtk-cmdq: Support GCE thread loop
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (2 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 03/15] soc: mediatek: Support GCE thread loop Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-29  7:13   ` CK Hu (胡俊光)
  2023-08-23 15:13 ` [PATCH 05/15] drm/mediatek: Support alpha blending in display driver Hsiao Chien Sung
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Do not disable CMDQ thread if it is a loop.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/mailbox/mtk-cmdq-mailbox.c       | 5 +++++
 include/linux/mailbox/mtk-cmdq-mailbox.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index b18d47ea13a0..88ff39a28415 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -264,6 +264,11 @@ static void cmdq_thread_irq_handler(struct cmdq *cmdq,
 
 	curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq->pdata->shift;
 
+	task = list_first_entry_or_null(&thread->task_busy_list,
+					struct cmdq_task, list_entry);
+	if (task && task->pkt->loop)
+		return;
+
 	list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
 				 list_entry) {
 		task_end_pa = task->pa_base + task->pkt->cmd_buf_size;
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index a8f0070c7aa9..f78a08e7c6ed 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -76,6 +76,7 @@ struct cmdq_pkt {
 	size_t			cmd_buf_size; /* command occupied size */
 	size_t			buf_size; /* real buffer size */
 	void			*cl;
+	bool			loop;
 };
 
 u8 cmdq_get_shift_pa(struct mbox_chan *chan);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 05/15] drm/mediatek: Support alpha blending in display driver
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (3 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 04/15] mailbox: mtk-cmdq: " Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:17   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0 Hsiao Chien Sung
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Support alpha blending by adding correct blend mode and
alpha property in plane initialization.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 31f9420aff6f..ca22d02375d5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -305,6 +305,9 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		   size_t num_formats)
 {
 	int err;
+	u32 blend_mode = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+			 BIT(DRM_MODE_BLEND_PREMULTI)   |
+			 BIT(DRM_MODE_BLEND_COVERAGE);
 
 	if (!formats || !num_formats) {
 		DRM_ERROR("no formats for plane\n");
@@ -327,6 +330,14 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 			DRM_INFO("Create rotation property failed\n");
 	}
 
+	err = drm_plane_create_alpha_property(plane);
+	if (err)
+		DRM_ERROR("failed to create property: alpha\n");
+
+	err = drm_plane_create_blend_mode_property(plane, blend_mode);
+	if (err)
+		DRM_ERROR("failed to create property: blend_mode\n");
+
 	drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
 
 	return 0;
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (4 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 05/15] drm/mediatek: Support alpha blending in display driver Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:10   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1 Hsiao Chien Sung
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Support premultiply and coverage alpha blending modes.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 175 +++++++++++++++++++++---
 1 file changed, 155 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8f52cc1f3fba..824f81291293 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -31,6 +31,7 @@
 #define OVL_LAYER_SMI_ID_EN				BIT(0)
 #define OVL_BGCLR_SEL_IN				BIT(2)
 #define OVL_LAYER_AFBC_EN(n)				BIT(4+n)
+#define OVL_OUTPUT_CLAMP				BIT(26)
 #define DISP_REG_OVL_ROI_BGCLR			0x0028
 #define DISP_REG_OVL_SRC_CON			0x002c
 #define DISP_REG_OVL_CON(n)			(0x0030 + 0x20 * (n))
@@ -39,10 +40,28 @@
 #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
 #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
 #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
+#define OVL_CONST_BLEND					BIT(28)
 #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701		0x0040
 #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
+#define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
+#define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << ((n) * 4 + 1))
+#define DISP_REG_OVL_Y2R_PARA_R0(n)		(0x0134 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_RMY				(GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_G0(n)		(0x013c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_GMU				(GENMASK(30, 16))
+#define DISP_REG_OVL_Y2R_PARA_B1(n)		(0x0148 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_BMV				(GENMASK(14, 0))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_0(n)	(0x014c + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_YA				(GENMASK(10, 0))
+#define OVL_Y2R_PARA_C_CF_UA				(GENMASK(26, 16))
+#define DISP_REG_OVL_Y2R_PARA_YUV_A_1(n)	(0x0150 + 0x28 * (n))
+#define OVL_Y2R_PARA_C_CF_VA				(GENMASK(10, 0))
+#define DISP_REG_OVL_Y2R_PRE_ADD2(n)		(0x0154 + 0x28 * (n))
+#define DISP_REG_OVL_R2R_R0(n)			(0x0500 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_G1(n)			(0x0510 + 0x40 * (n))
+#define DISP_REG_OVL_R2R_B2(n)			(0x0520 + 0x40 * (n))
 #define DISP_REG_OVL_ADDR_MT8173		0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x04)
@@ -52,13 +71,19 @@
 #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
 #define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)
 
-#define OVL_CON_BYTE_SWAP	BIT(24)
-#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
-#define OVL_CON_CLRFMT_RGB	(1 << 12)
-#define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
-#define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
-#define OVL_CON_CLRFMT_UYVY	(4 << 12)
-#define OVL_CON_CLRFMT_YUYV	(5 << 12)
+#define OVL_CON_CLRFMT_MAN		BIT(23)
+#define OVL_CON_BYTE_SWAP		BIT(24)
+#define OVL_CON_RGB_SWAP		BIT(25)
+#define OVL_CON_MTX_AUTO_DIS		BIT(26)
+#define OVL_CON_MTX_EN			BIT(27)
+#define OVL_CON_CLRFMT_RGB		(1 << 12)
+#define OVL_CON_CLRFMT_RGBA8888		(2 << 12)
+#define OVL_CON_CLRFMT_ARGB8888		(3 << 12)
+#define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
+#define OVL_CON_CLRFMT_UYVY		(4 << 12)
+#define OVL_CON_CLRFMT_YUYV		(5 << 12)
+#define OVL_CON_MTX_YUV_TO_RGB		(6 << 16)
+#define OVL_CON_MTX_PROGRAMMABLE	(8 << 16)
 #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
 					0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
@@ -72,6 +97,22 @@
 #define	OVL_CON_VIRT_FLIP	BIT(9)
 #define	OVL_CON_HORZ_FLIP	BIT(10)
 
+static inline bool is_10bit_rgb(u32 fmt)
+{
+	switch (fmt) {
+	case DRM_FORMAT_XRGB2101010:
+	case DRM_FORMAT_ARGB2101010:
+	case DRM_FORMAT_RGBX1010102:
+	case DRM_FORMAT_RGBA1010102:
+	case DRM_FORMAT_XBGR2101010:
+	case DRM_FORMAT_ABGR2101010:
+	case DRM_FORMAT_BGRX1010102:
+	case DRM_FORMAT_BGRA1010102:
+		return true;
+	}
+	return false;
+}
+
 static const u32 mt8173_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -89,12 +130,20 @@ static const u32 mt8173_formats[] = {
 static const u32 mt8195_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XRGB2101010,
 	DRM_FORMAT_ARGB2101010,
 	DRM_FORMAT_BGRX8888,
 	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_BGRX1010102,
 	DRM_FORMAT_BGRA1010102,
 	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XBGR2101010,
+	DRM_FORMAT_ABGR2101010,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_RGBX1010102,
+	DRM_FORMAT_RGBA1010102,
 	DRM_FORMAT_RGB888,
 	DRM_FORMAT_BGR888,
 	DRM_FORMAT_RGB565,
@@ -208,14 +257,14 @@ void mtk_ovl_clk_disable(struct device *dev)
 void mtk_ovl_start(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+	unsigned int reg = 0;
 
 	if (ovl->data->smi_id_en) {
-		unsigned int reg;
-
 		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
 		reg = reg | OVL_LAYER_SMI_ID_EN;
-		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
 	}
+	reg |= OVL_OUTPUT_CLAMP;
+	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
 	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
 }
 
@@ -254,9 +303,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
 	reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
 	reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
 
-	if (format == DRM_FORMAT_RGBA1010102 ||
-	    format == DRM_FORMAT_BGRA1010102 ||
-	    format == DRM_FORMAT_ARGB2101010)
+	if (is_10bit_rgb(format))
 		bit_depth = OVL_CON_CLRFMT_10_BIT;
 
 	reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
@@ -357,7 +404,8 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
 		      DISP_REG_OVL_RDMA_CTRL(idx));
 }
 
-static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
+static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt,
+				    unsigned int blend_mode)
 {
 	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
 	 * is defined in mediatek HW data sheet.
@@ -376,17 +424,37 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 		return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_RGBX8888:
 	case DRM_FORMAT_RGBA8888:
+		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_ARGB8888 :
+		       OVL_CON_CLRFMT_PARGB8888;
+	case DRM_FORMAT_RGBX1010102:
+	case DRM_FORMAT_RGBA1010102:
 		return OVL_CON_CLRFMT_ARGB8888;
 	case DRM_FORMAT_BGRX8888:
 	case DRM_FORMAT_BGRA8888:
+		return OVL_CON_BYTE_SWAP |
+		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_ARGB8888 :
+		       OVL_CON_CLRFMT_PARGB8888);
+	case DRM_FORMAT_BGRX1010102:
 	case DRM_FORMAT_BGRA1010102:
 		return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_XRGB8888:
 	case DRM_FORMAT_ARGB8888:
+		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_RGBA8888 :
+		       OVL_CON_CLRFMT_PARGB8888;
+	case DRM_FORMAT_XRGB2101010:
 	case DRM_FORMAT_ARGB2101010:
 		return OVL_CON_CLRFMT_RGBA8888;
 	case DRM_FORMAT_XBGR8888:
 	case DRM_FORMAT_ABGR8888:
+		return OVL_CON_RGB_SWAP |
+		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
+		       OVL_CON_CLRFMT_RGBA8888 :
+		       OVL_CON_CLRFMT_PARGB8888);
+	case DRM_FORMAT_XBGR2101010:
+	case DRM_FORMAT_ABGR2101010:
 		return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
 	case DRM_FORMAT_UYVY:
 		return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
@@ -408,6 +476,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 	unsigned int fmt = pending->format;
 	unsigned int offset = (pending->y << 16) | pending->x;
 	unsigned int src_size = (pending->height << 16) | pending->width;
+	unsigned int blend_mode = state->base.pixel_blend_mode;
+	unsigned int ignore_pixel_alpha = 0;
 	unsigned int con;
 	bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
 	union overlay_pitch {
@@ -420,14 +490,79 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 
 	overlay_pitch.pitch = pitch;
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
 		mtk_ovl_layer_off(dev, idx, cmdq_pkt);
 		return;
 	}
 
-	con = ovl_fmt_convert(ovl, fmt);
-	if (state->base.fb && state->base.fb->format->has_alpha)
-		con |= OVL_CON_AEN | OVL_CON_ALPHA;
+	con = ovl_fmt_convert(ovl, fmt, blend_mode);
+	if (state->base.fb) {
+		con |= OVL_CON_AEN;
+		con |= state->base.alpha & 0xff;
+	}
+
+	if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+	    (state->base.fb && !state->base.fb->format->has_alpha))
+		ignore_pixel_alpha = OVL_CONST_BLEND;
+
+	/* need to do Y2R and R2R to reduce 10bit data to 8bit for CRC calculation */
+	if (ovl->data->supports_clrfmt_ext) {
+		u32 y2r_coef = 0, y2r_offset = 0, r2r_coef = 0, csc_en = 0;
+
+		if (is_10bit_rgb(fmt)) {
+			con |= OVL_CON_MTX_AUTO_DIS | OVL_CON_MTX_EN | OVL_CON_MTX_PROGRAMMABLE;
+
+			/* Y2R coef setting: bit 13 is 2^1, bit 12 is 2^0, bit 11 is 2^-1, ... */
+			y2r_coef = BIT(10);	/* bit 10 is 2^-2 = 0.25 */
+			y2r_offset = 0x7fe;	/* -1 in 10bit */
+			/* R2R coef setting: bit 19 is 2^1, bit 18 is 2^0, bit 17 is 2^-1, ... */
+			r2r_coef = BIT(20);	/* bit 20 is 2^2 = 4 */
+			csc_en = OVL_CLRFMT_EXT1_CSC_EN(idx);	/* CSC_EN is for R2R */
+
+			/*
+			 * 1. YUV input data - 1 and shift right for 2 bits to remove it
+			 * [R']   [0.25    0    0]   [Y in - 1]
+			 * [G'] = [   0 0.25    0] * [U in - 1]
+			 * [B']   [   0    0 0.25]   [V in - 1]
+			 *
+			 * 2. shift left for 2 bit letting the last 2 bits become 0
+			 * [R out]   [ 4  0  0]   [R']
+			 * [G out] = [ 0  4  0] * [G']
+			 * [B out]   [ 0  0  4]   [B']
+			 */
+		}
+
+		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_R0(idx),
+				   OVL_Y2R_PARA_C_CF_RMY);
+		mtk_ddp_write_mask(cmdq_pkt, (y2r_coef << 16),
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_G0(idx),
+				   OVL_Y2R_PARA_C_CF_GMU);
+		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_B1(idx),
+				   OVL_Y2R_PARA_C_CF_BMV);
+
+		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+				   OVL_Y2R_PARA_C_CF_YA);
+		mtk_ddp_write_mask(cmdq_pkt, (y2r_offset << 16),
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
+				   OVL_Y2R_PARA_C_CF_UA);
+		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_1(idx),
+				   OVL_Y2R_PARA_C_CF_VA);
+
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_R0(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_G1(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_B2(idx));
+
+		mtk_ddp_write_mask(cmdq_pkt, csc_en,
+				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT1,
+				   OVL_CLRFMT_EXT1_CSC_EN(idx));
+	}
 
 	if (pending->rotation & DRM_MODE_REFLECT_Y) {
 		con |= OVL_CON_VIRT_FLIP;
@@ -444,8 +579,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 
 	mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_CON(idx));
-	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
-			      DISP_REG_OVL_PITCH(idx));
+	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
+			      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_SRC_SIZE(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (5 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0 Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:15   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 08/15] drm/mediatek: Move struct mtk_drm_crtc to the header file Hsiao Chien Sung
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Support premultiply and coverage alpha blending modes.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_ethdr.c | 50 +++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 73dc4da3ba3b..3058c122a4c3 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -5,6 +5,7 @@
 
 #include <drm/drm_fourcc.h>
 #include <drm/drm_framebuffer.h>
+#include <drm/drm_blend.h>
 #include <linux/clk.h>
 #include <linux/component.h>
 #include <linux/of_device.h>
@@ -35,6 +36,7 @@
 #define MIX_SRC_L0_EN				BIT(0)
 #define MIX_L_SRC_CON(n)		(0x28 + 0x18 * (n))
 #define NON_PREMULTI_SOURCE			(2 << 12)
+#define PREMULTI_SOURCE				(3 << 12)
 #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
 #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
 #define MIX_FUNC_DCM0			0x120
@@ -50,9 +52,7 @@
 
 #define MIXER_INX_MODE_BYPASS			0
 #define MIXER_INX_MODE_EVEN_EXTEND		1
-#define DEFAULT_9BIT_ALPHA			0x100
 #define	MIXER_ALPHA_AEN				BIT(8)
-#define	MIXER_ALPHA				0xff
 #define ETHDR_CLK_NUM				13
 
 enum mtk_ethdr_comp_id {
@@ -153,33 +153,59 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
 	struct mtk_plane_pending_state *pending = &state->pending;
 	unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
 	unsigned int align_width = ALIGN_DOWN(pending->width, 2);
-	unsigned int alpha_con = 0;
+	unsigned int mix_con = NON_PREMULTI_SOURCE;
+	bool replace_src_a = false;
+
+	union format {
+		unsigned int raw;
+		char str[5];
+	} format;
 
 	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
 
 	if (idx >= 4)
 		return;
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
+		/*
+		 * instead of disabling layer with MIX_SRC_CON directly
+		 * set the size to 0 to avoid screen shift due to mode switch
+		 */
 		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
 		return;
 	}
 
-	if (state->base.fb && state->base.fb->format->has_alpha)
-		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+	mix_con |= MIXER_ALPHA_AEN | (state->base.alpha & 0xff);
+
+	if (state->base.pixel_blend_mode != DRM_MODE_BLEND_COVERAGE)
+		mix_con |= PREMULTI_SOURCE;
+
+	if (state->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+	    (state->base.fb && !state->base.fb->format->has_alpha)) {
+		/*
+		 * Mixer doesn't support CONST_BLD mode,
+		 * use a trick to make the output equivalent
+		 */
+		replace_src_a = true;
+	}
+
+	format.raw = pending->format;
+
+	dev_dbg(dev, "L%d: %ux%u(%u,%u)%s: SCA=0x%x(%u), MIX=0x%x\n", idx,
+		pending->width, pending->height, pending->x, pending->y,
+		format.str, (state->base.alpha & 0xff), state->base.pixel_blend_mode,
+		mix_con);
 
-	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true,
-				  DEFAULT_9BIT_ALPHA,
+	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a, 0xff,
 				  pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
 				  MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt);
 
 	mtk_ddp_write(cmdq_pkt, pending->height << 16 | align_width, &mixer->cmdq_base,
 		      mixer->regs, MIX_L_SRC_SIZE(idx));
 	mtk_ddp_write(cmdq_pkt, offset, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_OFFSET(idx));
-	mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
-			   0x1ff);
-	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
-			   BIT(idx));
+	mtk_ddp_write(cmdq_pkt, mix_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx));
+	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs,
+			   MIX_SRC_CON, BIT(idx));
 }
 
 void mtk_ethdr_config(struct device *dev, unsigned int w,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 08/15] drm/mediatek: Move struct mtk_drm_crtc to the header file
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (6 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1 Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 09/15] drm/mediatek: Add OVL compatible name for MT8195 Hsiao Chien Sung
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Move the struct from mtk_drm_crtc.c to mtk_drm_crtc.h
so it can be referenced in other files.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 44 -------------------------
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 44 +++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index d40142842f85..e8313739b54d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -24,50 +24,6 @@
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
 
-/*
- * struct mtk_drm_crtc - MediaTek specific crtc structure.
- * @base: crtc object.
- * @enabled: records whether crtc_enable succeeded
- * @planes: array of 4 drm_plane structures, one for each overlay plane
- * @pending_planes: whether any plane has pending changes to be applied
- * @mmsys_dev: pointer to the mmsys device for configuration registers
- * @mutex: handle to one of the ten disp_mutex streams
- * @ddp_comp_nr: number of components in ddp_comp
- * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
- *
- * TODO: Needs update: this header is missing a bunch of member descriptions.
- */
-struct mtk_drm_crtc {
-	struct drm_crtc			base;
-	bool				enabled;
-
-	bool				pending_needs_vblank;
-	struct drm_pending_vblank_event	*event;
-
-	struct drm_plane		*planes;
-	unsigned int			layer_nr;
-	bool				pending_planes;
-	bool				pending_async_planes;
-
-#if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	struct cmdq_client		cmdq_client;
-	struct cmdq_pkt			cmdq_handle;
-	u32				cmdq_event;
-	u32				cmdq_vblank_cnt;
-	wait_queue_head_t		cb_blocking_queue;
-#endif
-
-	struct device			*mmsys_dev;
-	struct device			*dma_dev;
-	struct mtk_mutex		*mutex;
-	unsigned int			ddp_comp_nr;
-	struct mtk_ddp_comp		**ddp_comp;
-
-	/* lock for display hardware access */
-	struct mutex			hw_lock;
-	bool				config_updating;
-};
-
 struct mtk_crtc_state {
 	struct drm_crtc_state		base;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 3e9046993d09..34cd1bfed8b3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -14,6 +14,50 @@
 #define MTK_MAX_BPC	10
 #define MTK_MIN_BPC	3
 
+/*
+ * struct mtk_drm_crtc - MediaTek specific crtc structure.
+ * @base: crtc object.
+ * @enabled: records whether crtc_enable succeeded
+ * @planes: array of 4 drm_plane structures, one for each overlay plane
+ * @pending_planes: whether any plane has pending changes to be applied
+ * @mmsys_dev: pointer to the mmsys device for configuration registers
+ * @mutex: handle to one of the ten disp_mutex streams
+ * @ddp_comp_nr: number of components in ddp_comp
+ * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
+ *
+ * TODO: Needs update: this header is missing a bunch of member descriptions.
+ */
+struct mtk_drm_crtc {
+	struct drm_crtc			base;
+	bool				enabled;
+
+	bool				pending_needs_vblank;
+	struct drm_pending_vblank_event	*event;
+
+	struct drm_plane		*planes;
+	unsigned int			layer_nr;
+	bool				pending_planes;
+	bool				pending_async_planes;
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	struct cmdq_client		cmdq_client;
+	struct cmdq_pkt			cmdq_handle;
+	u32				cmdq_event;
+	u32				cmdq_vblank_cnt;
+	wait_queue_head_t		cb_blocking_queue;
+#endif
+
+	struct device			*mmsys_dev;
+	struct device			*dma_dev;
+	struct mtk_mutex		*mutex;
+	unsigned int			ddp_comp_nr;
+	struct mtk_ddp_comp		**ddp_comp;
+
+	/* lock for display hardware access */
+	struct mutex			hw_lock;
+	bool				config_updating;
+};
+
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			const unsigned int *path,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 09/15] drm/mediatek: Add OVL compatible name for MT8195
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (7 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 08/15] drm/mediatek: Move struct mtk_drm_crtc to the header file Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 10/15] drm/mediatek: Support CRC in display driver Hsiao Chien Sung
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Add OVL compatible name for MT8195.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6dcb4ba2466c..fd653d892b9d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -714,6 +714,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8192-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8195-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 10/15] drm/mediatek: Support CRC in display driver
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (8 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 09/15] drm/mediatek: Add OVL compatible name for MT8195 Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:20   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0 Hsiao Chien Sung
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Register CRC related function pointers to support CRC
retrieval.

Skip the first CRC because when the first vblank triggered,
the frame buffer is not ready for CRC calculation yet.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 53 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h     | 20 ++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  5 ++
 3 files changed, 78 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index e8313739b54d..0fa713c550b1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -573,6 +573,17 @@ static void mtk_crtc_ddp_irq(void *data)
 	struct drm_crtc *crtc = data;
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
+	static int skip;
+
+	if (mtk_crtc->crc.cnt && crtc->crc.opened) {
+		if (++skip > 1) {
+			drm_crtc_add_crc_entry(crtc, true,
+					       drm_crtc_vblank_count(crtc),
+					       (u32 *)mtk_crtc->crc.va);
+		}
+	} else {
+		skip = 0;
+	}
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
@@ -605,6 +616,34 @@ static void mtk_drm_crtc_disable_vblank(struct drm_crtc *crtc)
 	mtk_ddp_comp_disable_vblank(comp);
 }
 
+static int mtk_drm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src)
+{
+	if (src && strcmp(src, "auto") != 0) {
+		DRM_DEBUG_DRIVER("%s(crtc-%d): unknown source '%s'\n",
+				 __func__, drm_crtc_index(crtc), src);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int mtk_drm_crtc_verify_crc_source(struct drm_crtc *crtc,
+					  const char *src,
+					  size_t *cnt)
+{
+	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+
+	if (src && strcmp(src, "auto") != 0) {
+		DRM_DEBUG_DRIVER("%s(crtc-%d): unknown source '%s'\n",
+				 __func__, drm_crtc_index(crtc), src);
+		return -EINVAL;
+	}
+
+	*cnt = (size_t)mtk_crtc->crc.cnt;
+
+	return 0;
+}
+
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 			     struct mtk_plane_state *state)
 {
@@ -737,6 +776,8 @@ static const struct drm_crtc_funcs mtk_crtc_funcs = {
 	.atomic_destroy_state	= mtk_drm_crtc_destroy_state,
 	.enable_vblank		= mtk_drm_crtc_enable_vblank,
 	.disable_vblank		= mtk_drm_crtc_disable_vblank,
+	.set_crc_source		= mtk_drm_crtc_set_crc_source,
+	.verify_crc_source	= mtk_drm_crtc_verify_crc_source,
 };
 
 static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = {
@@ -919,6 +960,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 			if (comp->funcs->ctm_set)
 				has_ctm = true;
+
+			if (comp->funcs->crc_cnt) {
+				mtk_crtc->crc.cnt = comp->funcs->crc_cnt(comp->dev);
+				mtk_crtc->crc.va = dma_alloc_coherent(dev,
+								      mtk_crtc->crc.cnt * 4,
+								      &mtk_crtc->crc.pa,
+								      GFP_KERNEL);
+				if (!mtk_crtc->crc.va || !mtk_crtc->crc.pa) {
+					dev_err(dev, "failed to allocate CRC\n");
+					return -ENOMEM;
+				}
+			}
 		}
 
 		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 34cd1bfed8b3..8303464f494c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -14,6 +14,23 @@
 #define MTK_MAX_BPC	10
 #define MTK_MIN_BPC	3
 
+/*
+ * struct mtk_drm_crc - CRC info of the CRTC
+ * @cnt: how many CRCs the CRTC supports
+ * @va: virtual address for CPU to read the CRCs
+ * @pa: physical address for GCE to stored the CRCs
+ *
+ * Hardware components could generate more than one CRC,
+ * for example, one for odd lines, another for even lines of the frame buffer,
+ * and each CRC takes 4 bytes in memory, here we record how many CRC the
+ * generator supports, and access them as an array from the specified address.
+ */
+struct mtk_drm_crc {
+	u32 cnt;
+	void *va;
+	dma_addr_t pa;
+};
+
 /*
  * struct mtk_drm_crtc - MediaTek specific crtc structure.
  * @base: crtc object.
@@ -24,6 +41,7 @@
  * @mutex: handle to one of the ten disp_mutex streams
  * @ddp_comp_nr: number of components in ddp_comp
  * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
+ * @crc: CRC info of the CRTC
  *
  * TODO: Needs update: this header is missing a bunch of member descriptions.
  */
@@ -56,6 +74,8 @@ struct mtk_drm_crtc {
 	/* lock for display hardware access */
 	struct mutex			hw_lock;
 	bool				config_updating;
+
+	struct mtk_drm_crc		crc;
 };
 
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index febcaeef16a1..3b67c3dc0525 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -45,6 +45,10 @@ enum mtk_ddp_comp_type {
 
 struct mtk_ddp_comp;
 struct cmdq_pkt;
+
+/* struct mtk_ddp_comp_funcs - function pointers of the ddp components
+ * @crc_cnt: how many CRCs the component supports
+ */
 struct mtk_ddp_comp_funcs {
 	int (*clk_enable)(struct device *dev);
 	void (*clk_disable)(struct device *dev);
@@ -80,6 +84,7 @@ struct mtk_ddp_comp_funcs {
 	void (*disconnect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
 	void (*add)(struct device *dev, struct mtk_mutex *mutex);
 	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
+	u32 (*crc_cnt)(struct device *dev);
 };
 
 struct mtk_ddp_comp {
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (9 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 10/15] drm/mediatek: Support CRC in display driver Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-24  2:29   ` CK Hu (胡俊光)
  2023-08-31  1:45   ` CK Hu (胡俊光)
  2023-08-23 15:13 ` [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1 Hsiao Chien Sung
                   ` (3 subsequent siblings)
  14 siblings, 2 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

We choose OVL as CRC generator from other hardware
components that are also capable of calculating CRCs,
since its frame done event triggers vblanks, it can be
used as a signal to know when is safe to retrieve CRC of
the frame.

Please note that position of the hardware component
that is chosen as CRC generator in the display path is
significant. For example, while OVL is the first module
in VDOSYS0, its CRC won't be affected by the modules
after it, which means effects applied by PQ, Gamma,
Dither or any other components after OVL won't be
calculated in CRC generation.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 121 +++++++++++++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   1 +
 3 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 2254038519e1..d2753360ae1e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -100,6 +100,7 @@ void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
 const u32 *mtk_ovl_get_formats(struct device *dev);
 size_t mtk_ovl_get_num_formats(struct device *dev);
+u32 mtk_ovl_crc_cnt(struct device *dev);
 
 void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
 void mtk_ovl_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 824f81291293..453db2de3e83 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -25,6 +25,13 @@
 #define OVL_FME_CPL_INT					BIT(1)
 #define DISP_REG_OVL_INTSTA			0x0008
 #define DISP_REG_OVL_EN				0x000c
+#define OVL_EN						BIT(0)
+#define OVL_OP_8BIT_MODE				BIT(4)
+#define OVL_HG_FOVL_CK_ON				BIT(8)
+#define OVL_HF_FOVL_CK_ON				BIT(10)
+#define DISP_REG_OVL_TRIG			0x0010
+#define OVL_CRC_EN					BIT(8)
+#define OVL_CRC_CLR					BIT(9)
 #define DISP_REG_OVL_RST			0x0014
 #define DISP_REG_OVL_ROI_SIZE			0x0020
 #define DISP_REG_OVL_DATAPATH_CON		0x0024
@@ -44,6 +51,8 @@
 #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701		0x0040
+#define DISP_REG_OVL_CRC			0x0270
+#define OVL_CRC_OUT_MASK				GENMASK(30, 0)
 #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
 #define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
 #define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << ((n) * 4 + 1))
@@ -151,6 +160,10 @@ static const u32 mt8195_formats[] = {
 	DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_ovl_crcs[] = {
+	DISP_REG_OVL_CRC,
+};
+
 struct mtk_disp_ovl_data {
 	unsigned int addr;
 	unsigned int gmc_bits;
@@ -161,6 +174,8 @@ struct mtk_disp_ovl_data {
 	const u32 *formats;
 	size_t num_formats;
 	bool supports_clrfmt_ext;
+	const u32 *crcs;
+	size_t crc_cnt;
 };
 
 /*
@@ -176,8 +191,82 @@ struct mtk_disp_ovl {
 	const struct mtk_disp_ovl_data	*data;
 	void				(*vblank_cb)(void *data);
 	void				*vblank_cb_data;
+	struct cmdq_client		*cmdq_client;
+	struct cmdq_pkt			*cmdq_pkt;
+	u32				cmdq_event;
 };
 
+u32 mtk_ovl_crc_cnt(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	return (u32)ovl->data->crc_cnt;
+}
+
+static void mtk_ovl_crc_loop_start(struct device *dev)
+{
+	int i;
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+	struct mtk_drm_crtc *mtk_crtc = container_of(ovl->crtc,
+						struct mtk_drm_crtc, base);
+
+	if (!ovl->cmdq_event || ovl->cmdq_client)
+		return;
+
+	ovl->cmdq_client = cmdq_mbox_create(dev, 0);
+	if (IS_ERR(ovl->cmdq_client)) {
+		pr_err("failed to create mailbox client\n");
+		return;
+	}
+
+	ovl->cmdq_pkt = cmdq_pkt_create(ovl->cmdq_client, PAGE_SIZE);
+	if (!ovl->cmdq_pkt) {
+		pr_err("failed to create cmdq packet\n");
+		return;
+	}
+
+	cmdq_pkt_wfe(ovl->cmdq_pkt, ovl->cmdq_event, true);
+
+	for (i = 0; i < ovl->data->crc_cnt; i++) {
+		/* put crc to spr1 register */
+		cmdq_pkt_read_s(ovl->cmdq_pkt, ovl->cmdq_reg.subsys,
+				ovl->data->crcs[i], CMDQ_THR_SPR_IDX1);
+		cmdq_pkt_assign(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
+				CMDQ_ADDR_HIGH(mtk_crtc->crc.pa + i * sizeof(u32)));
+
+		/* copy spr1 register to crc.pa */
+		cmdq_pkt_write_s(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
+				 CMDQ_ADDR_LOW(mtk_crtc->crc.pa + i * sizeof(u32)),
+				 CMDQ_THR_SPR_IDX1);
+	}
+
+	/* reset crc */
+	mtk_ddp_write_mask(ovl->cmdq_pkt, ~0, &ovl->cmdq_reg, ovl->regs,
+			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
+	/* clear reset bit */
+	mtk_ddp_write_mask(ovl->cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
+			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
+
+	cmdq_pkt_finalize_loop(ovl->cmdq_pkt);
+	cmdq_pkt_flush_async(ovl->cmdq_pkt);
+}
+
+static void mtk_ovl_crc_loop_stop(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	if (ovl->cmdq_pkt) {
+		cmdq_pkt_destroy(ovl->cmdq_pkt);
+		ovl->cmdq_pkt = NULL;
+	}
+
+	if (ovl->cmdq_client) {
+		mbox_flush(ovl->cmdq_client->chan, 2000);
+		cmdq_mbox_destroy(ovl->cmdq_client);
+		ovl->cmdq_client = NULL;
+	}
+}
+
 static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
 {
 	struct mtk_disp_ovl *priv = dev_id;
@@ -201,6 +290,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 
 	ovl->vblank_cb = vblank_cb;
 	ovl->vblank_cb_data = vblank_cb_data;
+	ovl->crtc = (struct drm_crtc *)vblank_cb_data;
 }
 
 void mtk_ovl_unregister_vblank_cb(struct device *dev)
@@ -216,14 +306,14 @@ void mtk_ovl_enable_vblank(struct device *dev)
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
 	writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
-	writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);
+	writel(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
 void mtk_ovl_disable_vblank(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
-	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
+	writel(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
 const u32 *mtk_ovl_get_formats(struct device *dev)
@@ -258,6 +348,7 @@ void mtk_ovl_start(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 	unsigned int reg = 0;
+	unsigned int val = OVL_EN;
 
 	if (ovl->data->smi_id_en) {
 		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
@@ -265,13 +356,22 @@ void mtk_ovl_start(struct device *dev)
 	}
 	reg |= OVL_OUTPUT_CLAMP;
 	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
-	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
+
+	if (ovl->data->crcs)
+		val |= OVL_OP_8BIT_MODE | OVL_HG_FOVL_CK_ON | OVL_HF_FOVL_CK_ON;
+
+	writel_relaxed(val, ovl->regs + DISP_REG_OVL_EN);
+	writel_relaxed(OVL_CRC_EN, ovl->regs + DISP_REG_OVL_TRIG);
+
+	mtk_ovl_crc_loop_start(dev);
 }
 
 void mtk_ovl_stop(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
+	mtk_ovl_crc_loop_stop(dev);
+
 	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
 	if (ovl->data->smi_id_en) {
 		unsigned int reg;
@@ -321,7 +421,8 @@ void mtk_ovl_config(struct device *dev, unsigned int w,
 	if (w != 0 && h != 0)
 		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
 				      DISP_REG_OVL_ROI_SIZE);
-	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
+	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg, ovl->regs,
+			      DISP_REG_OVL_ROI_BGCLR);
 
 	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
 	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
@@ -677,6 +778,16 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 #endif
 
 	priv->data = of_device_get_match_data(dev);
+
+	if (priv->data->crcs) {
+		if (of_property_read_u32_index(dev->of_node,
+					       "mediatek,gce-events", 0,
+					       &priv->cmdq_event)) {
+			dev_err(dev, "failed to get gce-events\n");
+			return -ENOPARAM;
+		}
+	}
+
 	platform_set_drvdata(pdev, priv);
 
 	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
@@ -771,6 +882,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
 	.formats = mt8195_formats,
 	.num_formats = ARRAY_SIZE(mt8195_formats),
 	.supports_clrfmt_ext = true,
+	.crcs = mt8195_ovl_crcs,
+	.crc_cnt = ARRAY_SIZE(mt8195_ovl_crcs),
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index f114da4d36a9..1b747a34a06b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -347,6 +347,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
 	.clk_enable = mtk_ovl_clk_enable,
 	.clk_disable = mtk_ovl_clk_disable,
 	.config = mtk_ovl_config,
+	.crc_cnt = mtk_ovl_crc_cnt,
 	.start = mtk_ovl_start,
 	.stop = mtk_ovl_stop,
 	.register_vblank_cb = mtk_ovl_register_vblank_cb,
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (10 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0 Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:31   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 13/15] drm/mediatek: Add missing plane settings when async update Hsiao Chien Sung
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

We choose Mixer as CRC generator in VDOSYS1 since
its frame done event will trigger vblanks, we can know
when is safe to retrieve CRC of the frame.

In VDOSYS1, there's no image procession after Mixer,
unlike OVL in VDOSYS0, Mixer's CRC will include all the
effects that are applied to the frame.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   1 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  10 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 120 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |   4 +
 5 files changed, 136 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index d2753360ae1e..014086d4d7ca 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -127,6 +127,7 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
 struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
 const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
 size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
+u32 mtk_ovl_adaptor_crc_cnt(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index c0a38f5217ee..64f98b26f4ce 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -159,6 +159,13 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 	mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
 }
 
+u32 mtk_ovl_adaptor_crc_cnt(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	return mtk_ethdr_crc_cnt(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
 void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
 			    unsigned int h, unsigned int vrefresh,
 			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -274,6 +281,9 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
 
 	mtk_ethdr_register_vblank_cb(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
 				     vblank_cb, vblank_cb_data);
+
+	mtk_ethdr_register_crtc(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
+				(struct drm_crtc *)vblank_cb_data);
 }
 
 void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 1b747a34a06b..143136491607 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -398,6 +398,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
 	.clk_enable = mtk_ovl_adaptor_clk_enable,
 	.clk_disable = mtk_ovl_adaptor_clk_disable,
 	.config = mtk_ovl_adaptor_config,
+	.crc_cnt = mtk_ovl_adaptor_crc_cnt,
 	.start = mtk_ovl_adaptor_start,
 	.stop = mtk_ovl_adaptor_stop,
 	.layer_nr = mtk_ovl_adaptor_layer_nr,
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
index 3058c122a4c3..9e341d86d9f9 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -24,6 +24,9 @@
 #define MIX_FME_CPL_INTEN			BIT(1)
 #define MIX_INTSTA			0x8
 #define MIX_EN				0xc
+#define MIX_TRIG			0x10
+#define MIX_TRIG_CRC_EN				BIT(8)
+#define MIX_TRIG_CRC_RST			BIT(9)
 #define MIX_RST				0x14
 #define MIX_ROI_SIZE			0x18
 #define MIX_DATAPATH_CON		0x1c
@@ -39,6 +42,11 @@
 #define PREMULTI_SOURCE				(3 << 12)
 #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
 #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
+
+/* CRC register offsets for odd and even lines */
+#define MIX_CRC_O			0x110
+#define MIX_CRC_E			0x114
+
 #define MIX_FUNC_DCM0			0x120
 #define MIX_FUNC_DCM1			0x124
 #define MIX_FUNC_DCM_ENABLE			0xffffffff
@@ -70,6 +78,9 @@ struct mtk_ethdr_comp {
 	struct device		*dev;
 	void __iomem		*regs;
 	struct cmdq_client_reg	cmdq_base;
+	struct cmdq_client *cmdq_client;
+	struct cmdq_pkt *cmdq_pkt;
+	u32 cmdq_event;
 };
 
 struct mtk_ethdr {
@@ -80,6 +91,9 @@ struct mtk_ethdr {
 	void			*vblank_cb_data;
 	int			irq;
 	struct reset_control	*reset_ctl;
+	struct drm_crtc		*crtc;
+	const u32		*crcs;
+	size_t			crc_cnt;
 };
 
 static const char * const ethdr_clk_str[] = {
@@ -98,6 +112,95 @@ static const char * const ethdr_clk_str[] = {
 	"vdo_be_async",
 };
 
+static const u32 ethdr_crcs[] = {
+	MIX_CRC_O,
+	MIX_CRC_E,
+};
+
+u32 mtk_ethdr_crc_cnt(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	return (u32)priv->crc_cnt;
+}
+
+void mtk_ethdr_register_crtc(struct device *dev, struct drm_crtc *crtc)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	priv->crtc = crtc;
+}
+
+static void mtk_ethdr_crc_loop_start(struct device *dev)
+{
+	int i;
+	struct mtk_ethdr *priv;
+	struct mtk_ethdr_comp *mixer;
+	struct mtk_drm_crtc *mtk_crtc;
+
+	priv = dev_get_drvdata(dev);
+	mixer = &priv->ethdr_comp[ETHDR_MIXER];
+	mtk_crtc = container_of(priv->crtc, struct mtk_drm_crtc, base);
+
+	if (!mixer->cmdq_event || mixer->cmdq_client)
+		return;
+
+	mixer->cmdq_client = cmdq_mbox_create(dev, 0);
+	if (IS_ERR(mixer->cmdq_client)) {
+		pr_err("failed to create mailbox client\n");
+		return;
+	}
+	mixer->cmdq_pkt = cmdq_pkt_create(mixer->cmdq_client, PAGE_SIZE);
+	if (!mixer->cmdq_pkt) {
+		pr_err("failed to create cmdq packet\n");
+		return;
+	}
+
+	cmdq_pkt_wfe(mixer->cmdq_pkt, mixer->cmdq_event, true);
+
+	for (i = 0; i < priv->crc_cnt; i++) {
+		/* put crc to spr1 register */
+		cmdq_pkt_read_s(mixer->cmdq_pkt, mixer->cmdq_base.subsys,
+				mixer->cmdq_base.offset + priv->crcs[i],
+				CMDQ_THR_SPR_IDX1);
+		cmdq_pkt_assign(mixer->cmdq_pkt, CMDQ_THR_SPR_IDX0,
+				CMDQ_ADDR_HIGH(mtk_crtc->crc.pa + i * sizeof(u32)));
+
+		/* copy spr1 register to crc.pa */
+		cmdq_pkt_write_s(mixer->cmdq_pkt, CMDQ_THR_SPR_IDX0,
+				 CMDQ_ADDR_LOW(mtk_crtc->crc.pa + i * sizeof(u32)),
+				 CMDQ_THR_SPR_IDX1);
+	}
+
+	/* reset crc */
+	mtk_ddp_write_mask(mixer->cmdq_pkt, ~0, &mixer->cmdq_base,
+			   mixer->regs, MIX_TRIG, MIX_TRIG_CRC_RST);
+
+	/* clear reset bit */
+	mtk_ddp_write_mask(mixer->cmdq_pkt, 0, &mixer->cmdq_base,
+			   mixer->regs, MIX_TRIG, MIX_TRIG_CRC_RST);
+
+	cmdq_pkt_finalize_loop(mixer->cmdq_pkt);
+	cmdq_pkt_flush_async(mixer->cmdq_pkt);
+}
+
+static void mtk_ethdr_crc_loop_stop(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	if (mixer->cmdq_pkt) {
+		cmdq_pkt_destroy(mixer->cmdq_pkt);
+		mixer->cmdq_pkt = NULL;
+	}
+
+	if (mixer->cmdq_client) {
+		mbox_flush(mixer->cmdq_client->chan, 2000);
+		cmdq_mbox_destroy(mixer->cmdq_client);
+		mixer->cmdq_client = NULL;
+	}
+}
+
 void mtk_ethdr_register_vblank_cb(struct device *dev,
 				  void (*vblank_cb)(void *),
 				  void *vblank_cb_data)
@@ -265,6 +368,9 @@ void mtk_ethdr_start(struct device *dev)
 	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
 
 	writel(1, mixer->regs + MIX_EN);
+	writel(MIX_TRIG_CRC_EN | MIX_TRIG_CRC_RST, mixer->regs + MIX_TRIG);
+
+	mtk_ethdr_crc_loop_start(dev);
 }
 
 void mtk_ethdr_stop(struct device *dev)
@@ -272,6 +378,8 @@ void mtk_ethdr_stop(struct device *dev)
 	struct mtk_ethdr *priv = dev_get_drvdata(dev);
 	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
 
+	mtk_ethdr_crc_loop_stop(dev);
+
 	writel(0, mixer->regs + MIX_EN);
 	writel(1, mixer->regs + MIX_RST);
 	reset_control_reset(priv->reset_ctl);
@@ -334,6 +442,15 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
 					      &priv->ethdr_comp[i].cmdq_base, i);
 		if (ret)
 			dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+
+		if (i == ETHDR_MIXER) {
+			if (of_property_read_u32_index(dev->of_node,
+						       "mediatek,gce-events", 0,
+						       &priv->ethdr_comp[i].cmdq_event)) {
+				dev_err(dev, "gce-events not defined\n");
+				return -ENOPARAM;
+			}
+		}
 #endif
 		dev_dbg(dev, "[DRM]regs:0x%p, node:%d\n", priv->ethdr_comp[i].regs, i);
 	}
@@ -363,6 +480,9 @@ static int mtk_ethdr_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->reset_ctl);
 	}
 
+	priv->crcs = ethdr_crcs;
+	priv->crc_cnt = ARRAY_SIZE(ethdr_crcs);
+
 	platform_set_drvdata(pdev, priv);
 
 	ret = component_add(dev, &mtk_ethdr_component_ops);
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h
index 81af9edea3f7..86d3fa4cf917 100644
--- a/drivers/gpu/drm/mediatek/mtk_ethdr.h
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h
@@ -22,4 +22,8 @@ void mtk_ethdr_register_vblank_cb(struct device *dev,
 void mtk_ethdr_unregister_vblank_cb(struct device *dev);
 void mtk_ethdr_enable_vblank(struct device *dev);
 void mtk_ethdr_disable_vblank(struct device *dev);
+
+u32 mtk_ethdr_crc_cnt(struct device *dev);
+void mtk_ethdr_register_crtc(struct device *dev, struct drm_crtc *crtc);
+
 #endif
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 13/15] drm/mediatek: Add missing plane settings when async update
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (11 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1 Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-09-07 12:33   ` AngeloGioacchino Del Regno
  2023-08-23 15:13 ` [PATCH 14/15] drm/mediatek: Adjust DRM mode configs for IGT Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 15/15] drm/mediatek: Fix errors when reporting rotation capability Hsiao Chien Sung
  14 siblings, 1 reply; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

Fix an issue that plane coordinate was not saved when
calling async update.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index ca22d02375d5..dc19827f6927 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -210,6 +210,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
 	plane->state->src_y = new_state->src_y;
 	plane->state->src_h = new_state->src_h;
 	plane->state->src_w = new_state->src_w;
+	plane->state->dst.x1 = new_state->dst.x1;
+	plane->state->dst.y1 = new_state->dst.y1;
 	swap(plane->state->fb, new_state->fb);
 
 	mtk_plane_update_new_state(new_state, new_plane_state);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 14/15] drm/mediatek: Adjust DRM mode configs for IGT
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (12 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 13/15] drm/mediatek: Add missing plane settings when async update Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  2023-08-23 15:13 ` [PATCH 15/15] drm/mediatek: Fix errors when reporting rotation capability Hsiao Chien Sung
  14 siblings, 0 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

IGT (Intel GPU Tool) could commit the following planes
during the test:

kms_plane:

The sub-tests pixel-format-* will create planes with
size of 1 or 4512 pixels, these size will be rejected
by the original mode configs.
Adjust minimum and maximum value of both plane width
and height.

kms_cursor_crc:

If cursor_width and cursor_height is not defined,
IGT uses min_width and min_height as the limitation
when creating cursor plane so sub-tests like
cursor-rapid-movement will be skipped.
Set cursor_width and cursor_height to 512 pixel can
solve the problem.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index fd653d892b9d..50bcfbd04af1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -425,16 +425,18 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	if (ret)
 		goto put_mutex_dev;
 
-	drm->mode_config.min_width = 64;
-	drm->mode_config.min_height = 64;
+	drm->mode_config.min_width = 1;
+	drm->mode_config.min_height = 1;
 
 	/*
 	 * set max width and height as default value(4096x4096).
 	 * this value would be used to check framebuffer size limitation
 	 * at drm_mode_addfb().
 	 */
-	drm->mode_config.max_width = 4096;
-	drm->mode_config.max_height = 4096;
+	drm->mode_config.max_width = 8191;
+	drm->mode_config.max_height = 8191;
+	drm->mode_config.cursor_width = 512;
+	drm->mode_config.cursor_height = 512;
 	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
 	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
 
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* [PATCH 15/15] drm/mediatek: Fix errors when reporting rotation capability
  2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
                   ` (13 preceding siblings ...)
  2023-08-23 15:13 ` [PATCH 14/15] drm/mediatek: Adjust DRM mode configs for IGT Hsiao Chien Sung
@ 2023-08-23 15:13 ` Hsiao Chien Sung
  14 siblings, 0 replies; 33+ messages in thread
From: Hsiao Chien Sung @ 2023-08-23 15:13 UTC (permalink / raw)
  To: Chun-Kuang Hu, Philipp Zabel, David Airlie, Daniel Vetter,
	Matthias Brugger, AngeloGioacchino Del Regno, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin, Hsiao Chien Sung

For CRTCs that doesn't support rotation should still return
DRM_MODE_ROTATE_0. Since both OVL and OVL adaptor on MTK chip
doesn't support rotation, return the capability of the
hardware accordingly.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h         | 1 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c         | 8 +-------
 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 5 +++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c     | 1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c        | 2 +-
 5 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 014086d4d7ca..2772423ce0c0 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -121,6 +121,7 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
 void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_adaptor_enable_vblank(struct device *dev);
 void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+unsigned int mtk_ovl_adaptor_supported_rotations(struct device *dev);
 void mtk_ovl_adaptor_start(struct device *dev);
 void mtk_ovl_adaptor_stop(struct device *dev);
 unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 453db2de3e83..7a7225604fee 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -437,8 +437,7 @@ unsigned int mtk_ovl_layer_nr(struct device *dev)
 
 unsigned int mtk_ovl_supported_rotations(struct device *dev)
 {
-	return DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
-	       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
+	return DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
 }
 
 int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
@@ -451,11 +450,6 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
 					 DRM_MODE_ROTATE_0 |
 					 DRM_MODE_REFLECT_X |
 					 DRM_MODE_REFLECT_Y);
-	rotation &= ~DRM_MODE_ROTATE_0;
-
-	/* We can only do reflection, not rotation */
-	if ((rotation & DRM_MODE_ROTATE_MASK) != 0)
-		return -EINVAL;
 
 	/*
 	 * TODO: Rotating/reflecting YUV buffers is not supported at this time.
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 64f98b26f4ce..ab5e606a390b 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -286,6 +286,11 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
 				(struct drm_crtc *)vblank_cb_data);
 }
 
+unsigned int mtk_ovl_adaptor_supported_rotations(struct device *dev)
+{
+	return DRM_MODE_ROTATE_0;
+}
+
 void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev)
 {
 	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 143136491607..5108b75be11a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -414,6 +414,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
 	.remove = mtk_ovl_adaptor_remove_comp,
 	.get_formats = mtk_ovl_adaptor_get_formats,
 	.get_num_formats = mtk_ovl_adaptor_get_num_formats,
+	.supported_rotations = mtk_ovl_adaptor_supported_rotations,
 };
 
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index dc19827f6927..f848317e34c8 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -324,7 +324,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		return err;
 	}
 
-	if (supported_rotations & ~DRM_MODE_ROTATE_0) {
+	if (supported_rotations) {
 		err = drm_plane_create_rotation_property(plane,
 							 DRM_MODE_ROTATE_0,
 							 supported_rotations);
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 33+ messages in thread

* Re: [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0
  2023-08-23 15:13 ` [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0 Hsiao Chien Sung
@ 2023-08-24  2:29   ` CK Hu (胡俊光)
  2023-08-30  5:13     ` Shawn Sung (宋孝謙)
  2023-08-31  1:45   ` CK Hu (胡俊光)
  1 sibling, 1 reply; 33+ messages in thread
From: CK Hu (胡俊光) @ 2023-08-24  2:29 UTC (permalink / raw)
  To: chunkuang.hu, Shawn Sung (宋孝謙),
	daniel, p.zabel, airlied, matthias.bgg, jassisinghbrar,
	angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi, Hsiao Chien:

On Wed, 2023-08-23 at 23:13 +0800, Hsiao Chien Sung wrote:
> We choose OVL as CRC generator from other hardware
> components that are also capable of calculating CRCs,
> since its frame done event triggers vblanks, it can be
> used as a signal to know when is safe to retrieve CRC of
> the frame.
> 
> Please note that position of the hardware component
> that is chosen as CRC generator in the display path is
> significant. For example, while OVL is the first module
> in VDOSYS0, its CRC won't be affected by the modules
> after it, which means effects applied by PQ, Gamma,
> Dither or any other components after OVL won't be
> calculated in CRC generation.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   1 +
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 121
> +++++++++++++++++++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   1 +
>  3 files changed, 119 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 2254038519e1..d2753360ae1e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -100,6 +100,7 @@ void mtk_ovl_enable_vblank(struct device *dev);
>  void mtk_ovl_disable_vblank(struct device *dev);
>  const u32 *mtk_ovl_get_formats(struct device *dev);
>  size_t mtk_ovl_get_num_formats(struct device *dev);
> +u32 mtk_ovl_crc_cnt(struct device *dev);
>  
>  void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex
> *mutex);
>  void mtk_ovl_adaptor_remove_comp(struct device *dev, struct
> mtk_mutex *mutex);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 824f81291293..453db2de3e83 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -25,6 +25,13 @@
>  #define OVL_FME_CPL_INT					BIT(1)
>  #define DISP_REG_OVL_INTSTA			0x0008
>  #define DISP_REG_OVL_EN				0x000c
> +#define OVL_EN						BIT(0)
> +#define OVL_OP_8BIT_MODE				BIT(4)
> +#define OVL_HG_FOVL_CK_ON				BIT(8)
> +#define OVL_HF_FOVL_CK_ON				BIT(10)
> +#define DISP_REG_OVL_TRIG			0x0010
> +#define OVL_CRC_EN					BIT(8)
> +#define OVL_CRC_CLR					BIT(9)
>  #define DISP_REG_OVL_RST			0x0014
>  #define DISP_REG_OVL_ROI_SIZE			0x0020
>  #define DISP_REG_OVL_DATAPATH_CON		0x0024
> @@ -44,6 +51,8 @@
>  #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
>  #define DISP_REG_OVL_ADDR_MT2701		0x0040
> +#define DISP_REG_OVL_CRC			0x0270
> +#define OVL_CRC_OUT_MASK				GENMASK(30, 0)
>  #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
>  #define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
>  #define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << ((n) * 4
> + 1))
> @@ -151,6 +160,10 @@ static const u32 mt8195_formats[] = {
>  	DRM_FORMAT_YUYV,
>  };
>  
> +static const u32 mt8195_ovl_crcs[] = {
> +	DISP_REG_OVL_CRC,
> +};
> +
>  struct mtk_disp_ovl_data {
>  	unsigned int addr;
>  	unsigned int gmc_bits;
> @@ -161,6 +174,8 @@ struct mtk_disp_ovl_data {
>  	const u32 *formats;
>  	size_t num_formats;
>  	bool supports_clrfmt_ext;
> +	const u32 *crcs;
> +	size_t crc_cnt;
>  };
>  
>  /*
> @@ -176,8 +191,82 @@ struct mtk_disp_ovl {
>  	const struct mtk_disp_ovl_data	*data;
>  	void				(*vblank_cb)(void *data);
>  	void				*vblank_cb_data;
> +	struct cmdq_client		*cmdq_client;
> +	struct cmdq_pkt			*cmdq_pkt;
> +	u32				cmdq_event;
>  };
>  
> +u32 mtk_ovl_crc_cnt(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	return (u32)ovl->data->crc_cnt;
> +}
> +
> +static void mtk_ovl_crc_loop_start(struct device *dev)
> +{
> +	int i;
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +	struct mtk_drm_crtc *mtk_crtc = container_of(ovl->crtc,
> +						struct mtk_drm_crtc,
> base);
> +
> +	if (!ovl->cmdq_event || ovl->cmdq_client)
> +		return;
> +
> +	ovl->cmdq_client = cmdq_mbox_create(dev, 0);
> +	if (IS_ERR(ovl->cmdq_client)) {
> +		pr_err("failed to create mailbox client\n");
> +		return;
> +	}
> +
> +	ovl->cmdq_pkt = cmdq_pkt_create(ovl->cmdq_client, PAGE_SIZE);
> +	if (!ovl->cmdq_pkt) {
> +		pr_err("failed to create cmdq packet\n");
> +		return;
> +	}
> +
> +	cmdq_pkt_wfe(ovl->cmdq_pkt, ovl->cmdq_event, true);
> +
> +	for (i = 0; i < ovl->data->crc_cnt; i++) {
> +		/* put crc to spr1 register */
> +		cmdq_pkt_read_s(ovl->cmdq_pkt, ovl->cmdq_reg.subsys,
> +				ovl->data->crcs[i], CMDQ_THR_SPR_IDX1);

Read CRC by CPU in ovl irq handler instead of using cmdq, so things
would be simpler.

Regards,
CK

> +		cmdq_pkt_assign(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
> +				CMDQ_ADDR_HIGH(mtk_crtc->crc.pa + i *
> sizeof(u32)));
> +
> +		/* copy spr1 register to crc.pa */
> +		cmdq_pkt_write_s(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
> +				 CMDQ_ADDR_LOW(mtk_crtc->crc.pa + i *
> sizeof(u32)),
> +				 CMDQ_THR_SPR_IDX1);
> +	}
> +
> +	/* reset crc */
> +	mtk_ddp_write_mask(ovl->cmdq_pkt, ~0, &ovl->cmdq_reg, ovl-
> >regs,
> +			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
> +	/* clear reset bit */
> +	mtk_ddp_write_mask(ovl->cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
> +			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
> +
> +	cmdq_pkt_finalize_loop(ovl->cmdq_pkt);
> +	cmdq_pkt_flush_async(ovl->cmdq_pkt);
> +}
> +
> +static void mtk_ovl_crc_loop_stop(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	if (ovl->cmdq_pkt) {
> +		cmdq_pkt_destroy(ovl->cmdq_pkt);
> +		ovl->cmdq_pkt = NULL;
> +	}
> +
> +	if (ovl->cmdq_client) {
> +		mbox_flush(ovl->cmdq_client->chan, 2000);
> +		cmdq_mbox_destroy(ovl->cmdq_client);
> +		ovl->cmdq_client = NULL;
> +	}
> +}
> +
>  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
>  {
>  	struct mtk_disp_ovl *priv = dev_id;
> @@ -201,6 +290,7 @@ void mtk_ovl_register_vblank_cb(struct device
> *dev,
>  
>  	ovl->vblank_cb = vblank_cb;
>  	ovl->vblank_cb_data = vblank_cb_data;
> +	ovl->crtc = (struct drm_crtc *)vblank_cb_data;
>  }
>  
>  void mtk_ovl_unregister_vblank_cb(struct device *dev)
> @@ -216,14 +306,14 @@ void mtk_ovl_enable_vblank(struct device *dev)
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
>  	writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
> -	writel_relaxed(OVL_FME_CPL_INT, ovl->regs +
> DISP_REG_OVL_INTEN);
> +	writel(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);
>  }
>  
>  void mtk_ovl_disable_vblank(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
> -	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
> +	writel(0x0, ovl->regs + DISP_REG_OVL_INTEN);
>  }
>  
>  const u32 *mtk_ovl_get_formats(struct device *dev)
> @@ -258,6 +348,7 @@ void mtk_ovl_start(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  	unsigned int reg = 0;
> +	unsigned int val = OVL_EN;
>  
>  	if (ovl->data->smi_id_en) {
>  		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
> @@ -265,13 +356,22 @@ void mtk_ovl_start(struct device *dev)
>  	}
>  	reg |= OVL_OUTPUT_CLAMP;
>  	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
> -	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
> +
> +	if (ovl->data->crcs)
> +		val |= OVL_OP_8BIT_MODE | OVL_HG_FOVL_CK_ON |
> OVL_HF_FOVL_CK_ON;
> +
> +	writel_relaxed(val, ovl->regs + DISP_REG_OVL_EN);
> +	writel_relaxed(OVL_CRC_EN, ovl->regs + DISP_REG_OVL_TRIG);
> +
> +	mtk_ovl_crc_loop_start(dev);
>  }
>  
>  void mtk_ovl_stop(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
> +	mtk_ovl_crc_loop_stop(dev);
> +
>  	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
>  	if (ovl->data->smi_id_en) {
>  		unsigned int reg;
> @@ -321,7 +421,8 @@ void mtk_ovl_config(struct device *dev, unsigned
> int w,
>  	if (w != 0 && h != 0)
>  		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl-
> >cmdq_reg, ovl->regs,
>  				      DISP_REG_OVL_ROI_SIZE);
> -	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, 
> DISP_REG_OVL_ROI_BGCLR);
> +	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
> ovl->regs,
> +			      DISP_REG_OVL_ROI_BGCLR);
>  
>  	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs,
> DISP_REG_OVL_RST);
>  	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs,
> DISP_REG_OVL_RST);
> @@ -677,6 +778,16 @@ static int mtk_disp_ovl_probe(struct
> platform_device *pdev)
>  #endif
>  
>  	priv->data = of_device_get_match_data(dev);
> +
> +	if (priv->data->crcs) {
> +		if (of_property_read_u32_index(dev->of_node,
> +					       "mediatek,gce-events",
> 0,
> +					       &priv->cmdq_event)) {
> +			dev_err(dev, "failed to get gce-events\n");
> +			return -ENOPARAM;
> +		}
> +	}
> +
>  	platform_set_drvdata(pdev, priv);
>  
>  	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> @@ -771,6 +882,8 @@ static const struct mtk_disp_ovl_data
> mt8195_ovl_driver_data = {
>  	.formats = mt8195_formats,
>  	.num_formats = ARRAY_SIZE(mt8195_formats),
>  	.supports_clrfmt_ext = true,
> +	.crcs = mt8195_ovl_crcs,
> +	.crc_cnt = ARRAY_SIZE(mt8195_ovl_crcs),
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index f114da4d36a9..1b747a34a06b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -347,6 +347,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl =
> {
>  	.clk_enable = mtk_ovl_clk_enable,
>  	.clk_disable = mtk_ovl_clk_disable,
>  	.config = mtk_ovl_config,
> +	.crc_cnt = mtk_ovl_crc_cnt,
>  	.start = mtk_ovl_start,
>  	.stop = mtk_ovl_stop,
>  	.register_vblank_cb = mtk_ovl_register_vblank_cb,

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 03/15] soc: mediatek: Support GCE thread loop
  2023-08-23 15:13 ` [PATCH 03/15] soc: mediatek: Support GCE thread loop Hsiao Chien Sung
@ 2023-08-29  7:07   ` CK Hu (胡俊光)
  2023-08-30  2:15   ` CK Hu (胡俊光)
  1 sibling, 0 replies; 33+ messages in thread
From: CK Hu (胡俊光) @ 2023-08-29  7:07 UTC (permalink / raw)
  To: chunkuang.hu, Shawn Sung (宋孝謙),
	daniel, p.zabel, airlied, matthias.bgg, jassisinghbrar,
	angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi, Hsiao-chien:

On Wed, 2023-08-23 at 23:13 +0800, Hsiao Chien Sung wrote:
> Add a new API to create GCE thread loop by
> appending a command at the end of CMDQ packet
> to jump to the head of it.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c | 30
> ++++++++++++++++++++++++++
>  include/linux/soc/mediatek/mtk-cmdq.h  |  2 ++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index c1837a468267..7d503d491c0d 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -430,6 +430,9 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
>  	int err;
>  	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
>  
> +	dma_sync_single_for_device(client->chan->mbox->dev, pkt-
> >pa_base,
> +				   pkt->cmd_buf_size, DMA_TO_DEVICE);
> +
>  	err = mbox_send_message(client->chan, pkt);
>  	if (err < 0)
>  		return err;
> @@ -440,4 +443,31 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
>  }
>  EXPORT_SYMBOL(cmdq_pkt_flush_async);
>  
> +int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt)
> +{
> +	struct cmdq_instruction inst = { {0} };
> +	int err;
> +	u8 shift_pa = 0;
> +
> +	shift_pa = cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)-
> >chan);
> +
> +	/* insert EOC and generate IRQ for command iteration */
> +	inst.op = CMDQ_CODE_EOC;
> +	inst.value = CMDQ_EOC_IRQ_EN;

It's not necessary to trigger IRQ, so drop this.

> +	err = cmdq_pkt_append_command(pkt, inst);
> +	if (err < 0)
> +		return err;
> +
> +	/* jump to head of the packet */
> +	inst.op = CMDQ_CODE_JUMP;
> +	inst.offset = CMDQ_JUMP_RELATIVE;
> +	inst.value = pkt->pa_base >> shift_pa;
> +	err = cmdq_pkt_append_command(pkt, inst);

This function has only dump function, so rename this function to
relative dump and pass pkt->pa_base by client driver.

Regards,
CK

> +
> +	pkt->loop = true;
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(cmdq_pkt_finalize_loop);
> +
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> b/include/linux/soc/mediatek/mtk-cmdq.h
> index 3eb95ef34c6c..4c30f891d924 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -273,6 +273,8 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt,
> dma_addr_t addr);
>   */
>  int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
>  
> +int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt);
> +
>  /**
>   * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute
> the CMDQ
>   *                          packet and call back at the end of done
> packet

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 04/15] mailbox: mtk-cmdq: Support GCE thread loop
  2023-08-23 15:13 ` [PATCH 04/15] mailbox: mtk-cmdq: " Hsiao Chien Sung
@ 2023-08-29  7:13   ` CK Hu (胡俊光)
  0 siblings, 0 replies; 33+ messages in thread
From: CK Hu (胡俊光) @ 2023-08-29  7:13 UTC (permalink / raw)
  To: chunkuang.hu, Shawn Sung (宋孝謙),
	daniel, p.zabel, airlied, matthias.bgg, jassisinghbrar,
	angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi, Hsiao-chien:


On Wed, 2023-08-23 at 23:13 +0800, Hsiao Chien Sung wrote:
> Do not disable CMDQ thread if it is a loop.

Once loop thread does not insert CMDQ_CODE_EOC command, this patch
could be dropped.

Regards,
CK

> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/mailbox/mtk-cmdq-mailbox.c       | 5 +++++
>  include/linux/mailbox/mtk-cmdq-mailbox.h | 1 +
>  2 files changed, 6 insertions(+)
> 
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c
> b/drivers/mailbox/mtk-cmdq-mailbox.c
> index b18d47ea13a0..88ff39a28415 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -264,6 +264,11 @@ static void cmdq_thread_irq_handler(struct cmdq
> *cmdq,
>  
>  	curr_pa = readl(thread->base + CMDQ_THR_CURR_ADDR) << cmdq-
> >pdata->shift;
>  
> +	task = list_first_entry_or_null(&thread->task_busy_list,
> +					struct cmdq_task, list_entry);
> +	if (task && task->pkt->loop)
> +		return;
> +
>  	list_for_each_entry_safe(task, tmp, &thread->task_busy_list,
>  				 list_entry) {
>  		task_end_pa = task->pa_base + task->pkt->cmd_buf_size;
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h
> b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index a8f0070c7aa9..f78a08e7c6ed 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -76,6 +76,7 @@ struct cmdq_pkt {
>  	size_t			cmd_buf_size; /* command occupied
> size */
>  	size_t			buf_size; /* real buffer size */
>  	void			*cl;
> +	bool			loop;
>  };
>  
>  u8 cmdq_get_shift_pa(struct mbox_chan *chan);

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 03/15] soc: mediatek: Support GCE thread loop
  2023-08-23 15:13 ` [PATCH 03/15] soc: mediatek: Support GCE thread loop Hsiao Chien Sung
  2023-08-29  7:07   ` CK Hu (胡俊光)
@ 2023-08-30  2:15   ` CK Hu (胡俊光)
  1 sibling, 0 replies; 33+ messages in thread
From: CK Hu (胡俊光) @ 2023-08-30  2:15 UTC (permalink / raw)
  To: chunkuang.hu, Shawn Sung (宋孝謙),
	daniel, p.zabel, airlied, matthias.bgg, jassisinghbrar,
	angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi, Hsiao-chien:

On Wed, 2023-08-23 at 23:13 +0800, Hsiao Chien Sung wrote:
> Add a new API to create GCE thread loop by
> appending a command at the end of CMDQ packet
> to jump to the head of it.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c | 30
> ++++++++++++++++++++++++++
>  include/linux/soc/mediatek/mtk-cmdq.h  |  2 ++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index c1837a468267..7d503d491c0d 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -430,6 +430,9 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
>  	int err;
>  	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
>  
> +	dma_sync_single_for_device(client->chan->mbox->dev, pkt-
> >pa_base,
> +				   pkt->cmd_buf_size, DMA_TO_DEVICE);

This function has been called by client driver, so drop this.

Regards,
CK

> +
>  	err = mbox_send_message(client->chan, pkt);
>  	if (err < 0)
>  		return err;
> @@ -440,4 +443,31 @@ int cmdq_pkt_flush_async(struct cmdq_pkt *pkt)
>  }
>  EXPORT_SYMBOL(cmdq_pkt_flush_async);
>  
> +int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt)
> +{
> +	struct cmdq_instruction inst = { {0} };
> +	int err;
> +	u8 shift_pa = 0;
> +
> +	shift_pa = cmdq_get_shift_pa(((struct cmdq_client *)pkt->cl)-
> >chan);
> +
> +	/* insert EOC and generate IRQ for command iteration */
> +	inst.op = CMDQ_CODE_EOC;
> +	inst.value = CMDQ_EOC_IRQ_EN;
> +	err = cmdq_pkt_append_command(pkt, inst);
> +	if (err < 0)
> +		return err;
> +
> +	/* jump to head of the packet */
> +	inst.op = CMDQ_CODE_JUMP;
> +	inst.offset = CMDQ_JUMP_RELATIVE;
> +	inst.value = pkt->pa_base >> shift_pa;
> +	err = cmdq_pkt_append_command(pkt, inst);
> +
> +	pkt->loop = true;
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(cmdq_pkt_finalize_loop);
> +
>  MODULE_LICENSE("GPL v2");
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> b/include/linux/soc/mediatek/mtk-cmdq.h
> index 3eb95ef34c6c..4c30f891d924 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -273,6 +273,8 @@ int cmdq_pkt_jump(struct cmdq_pkt *pkt,
> dma_addr_t addr);
>   */
>  int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
>  
> +int cmdq_pkt_finalize_loop(struct cmdq_pkt *pkt);
> +
>  /**
>   * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute
> the CMDQ
>   *                          packet and call back at the end of done
> packet

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0
  2023-08-24  2:29   ` CK Hu (胡俊光)
@ 2023-08-30  5:13     ` Shawn Sung (宋孝謙)
  0 siblings, 0 replies; 33+ messages in thread
From: Shawn Sung (宋孝謙) @ 2023-08-30  5:13 UTC (permalink / raw)
  To: chunkuang.hu, daniel, p.zabel, CK Hu (胡俊光),
	airlied, matthias.bgg, jassisinghbrar, angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi CK,

On Thu, 2023-08-24 at 02:29 +0000, CK Hu (胡俊光) wrote:
> 
> Read CRC by CPU in ovl irq handler instead of using cmdq, so things
> would be simpler.
> 

CPU is less reliable than GCE in terms of CRC retrieval because:
1. Slower read/write register speed (1/15 of GCE)
2. The time ISR being executed is not controllable
3. CPU and bus could be busy, or the clock rate is low at the time

Although we do have a CPU version, there is about a 5% chance to
fail if the CPU clock rate is not set to the maximum,
therefore, we choose GCE (CMDQ) to do the job for better stability.

Will mention this in the cover letter in the next version.

Thanks,

Hsiao Chien Sung

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0
  2023-08-23 15:13 ` [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0 Hsiao Chien Sung
  2023-08-24  2:29   ` CK Hu (胡俊光)
@ 2023-08-31  1:45   ` CK Hu (胡俊光)
  1 sibling, 0 replies; 33+ messages in thread
From: CK Hu (胡俊光) @ 2023-08-31  1:45 UTC (permalink / raw)
  To: chunkuang.hu, Shawn Sung (宋孝謙),
	daniel, p.zabel, airlied, matthias.bgg, jassisinghbrar,
	angelogioacchino.delregno
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi, Hsio-chien:

On Wed, 2023-08-23 at 23:13 +0800, Hsiao Chien Sung wrote:
> We choose OVL as CRC generator from other hardware
> components that are also capable of calculating CRCs,
> since its frame done event triggers vblanks, it can be
> used as a signal to know when is safe to retrieve CRC of
> the frame.
> 
> Please note that position of the hardware component
> that is chosen as CRC generator in the display path is
> significant. For example, while OVL is the first module
> in VDOSYS0, its CRC won't be affected by the modules
> after it, which means effects applied by PQ, Gamma,
> Dither or any other components after OVL won't be
> calculated in CRC generation.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   1 +
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 121
> +++++++++++++++++++-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   1 +
>  3 files changed, 119 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 2254038519e1..d2753360ae1e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -100,6 +100,7 @@ void mtk_ovl_enable_vblank(struct device *dev);
>  void mtk_ovl_disable_vblank(struct device *dev);
>  const u32 *mtk_ovl_get_formats(struct device *dev);
>  size_t mtk_ovl_get_num_formats(struct device *dev);
> +u32 mtk_ovl_crc_cnt(struct device *dev);
>  
>  void mtk_ovl_adaptor_add_comp(struct device *dev, struct mtk_mutex
> *mutex);
>  void mtk_ovl_adaptor_remove_comp(struct device *dev, struct
> mtk_mutex *mutex);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 824f81291293..453db2de3e83 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -25,6 +25,13 @@
>  #define OVL_FME_CPL_INT					BIT(1)
>  #define DISP_REG_OVL_INTSTA			0x0008
>  #define DISP_REG_OVL_EN				0x000c
> +#define OVL_EN						BIT(0)
> +#define OVL_OP_8BIT_MODE				BIT(4)
> +#define OVL_HG_FOVL_CK_ON				BIT(8)
> +#define OVL_HF_FOVL_CK_ON				BIT(10)
> +#define DISP_REG_OVL_TRIG			0x0010
> +#define OVL_CRC_EN					BIT(8)
> +#define OVL_CRC_CLR					BIT(9)
>  #define DISP_REG_OVL_RST			0x0014
>  #define DISP_REG_OVL_ROI_SIZE			0x0020
>  #define DISP_REG_OVL_DATAPATH_CON		0x0024
> @@ -44,6 +51,8 @@
>  #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
>  #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
>  #define DISP_REG_OVL_ADDR_MT2701		0x0040
> +#define DISP_REG_OVL_CRC			0x0270
> +#define OVL_CRC_OUT_MASK				GENMASK(30, 0)
>  #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
>  #define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
>  #define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << ((n) * 4
> + 1))
> @@ -151,6 +160,10 @@ static const u32 mt8195_formats[] = {
>  	DRM_FORMAT_YUYV,
>  };
>  
> +static const u32 mt8195_ovl_crcs[] = {
> +	DISP_REG_OVL_CRC,
> +};
> +
>  struct mtk_disp_ovl_data {
>  	unsigned int addr;
>  	unsigned int gmc_bits;
> @@ -161,6 +174,8 @@ struct mtk_disp_ovl_data {
>  	const u32 *formats;
>  	size_t num_formats;
>  	bool supports_clrfmt_ext;
> +	const u32 *crcs;
> +	size_t crc_cnt;
> 
>  };
>  
>  /*
> @@ -176,8 +191,82 @@ struct mtk_disp_ovl {
>  	const struct mtk_disp_ovl_data	*data;
>  	void				(*vblank_cb)(void *data);
>  	void				*vblank_cb_data;
> +	struct cmdq_client		*cmdq_client;

struct cmdq_client cmdq_client;

Refer to mtk_drm_crtc.c

> +	struct cmdq_pkt			*cmdq_pkt;

struct cmdq_pkt cmdq_pkt;

Refer to mtk_drm_crtc.c

> +	u32				cmdq_event;
>  };
>  
> +u32 mtk_ovl_crc_cnt(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	return (u32)ovl->data->crc_cnt;

If CONFIG_MTK_CMDQ is not reachable, return 0.

> +}
> +
> +static void mtk_ovl_crc_loop_start(struct device *dev)
> +{
> +	int i;
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +	struct mtk_drm_crtc *mtk_crtc = container_of(ovl->crtc,
> +						struct mtk_drm_crtc,
> base);
> +
> +	if (!ovl->cmdq_event || ovl->cmdq_client)
> +		return;
> +
> +	ovl->cmdq_client = cmdq_mbox_create(dev, 0);
> +	if (IS_ERR(ovl->cmdq_client)) {
> +		pr_err("failed to create mailbox client\n");
> +		return;
> +	}
> +
> +	ovl->cmdq_pkt = cmdq_pkt_create(ovl->cmdq_client, PAGE_SIZE);
> +	if (!ovl->cmdq_pkt) {
> +		pr_err("failed to create cmdq packet\n");
> +		return;
> +	}
> +
> +	cmdq_pkt_wfe(ovl->cmdq_pkt, ovl->cmdq_event, true);
> +
> +	for (i = 0; i < ovl->data->crc_cnt; i++) {
> +		/* put crc to spr1 register */
> +		cmdq_pkt_read_s(ovl->cmdq_pkt, ovl->cmdq_reg.subsys,
> +				ovl->data->crcs[i], CMDQ_THR_SPR_IDX1);
> +		cmdq_pkt_assign(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
> +				CMDQ_ADDR_HIGH(mtk_crtc->crc.pa + i *
> sizeof(u32)));
> +
> +		/* copy spr1 register to crc.pa */
> +		cmdq_pkt_write_s(ovl->cmdq_pkt, CMDQ_THR_SPR_IDX0,
> +				 CMDQ_ADDR_LOW(mtk_crtc->crc.pa + i *
> sizeof(u32)),
> +				 CMDQ_THR_SPR_IDX1);

I would like copy crc to ovl variable instread of crtc variable, and
crtc could query crc value by a new interface.

> +	}
> +
> +	/* reset crc */
> +	mtk_ddp_write_mask(ovl->cmdq_pkt, ~0, &ovl->cmdq_reg, ovl-
> >regs,
> +			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
> +	/* clear reset bit */
> +	mtk_ddp_write_mask(ovl->cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
> +			   DISP_REG_OVL_TRIG, OVL_CRC_CLR);
> +
> +	cmdq_pkt_finalize_loop(ovl->cmdq_pkt);

Create packet in probe function and only flush packet when OVL start.

> +	cmdq_pkt_flush_async(ovl->cmdq_pkt);
> +}
> +
> +static void mtk_ovl_crc_loop_stop(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	if (ovl->cmdq_pkt) {
> +		cmdq_pkt_destroy(ovl->cmdq_pkt);
> +		ovl->cmdq_pkt = NULL;
> +	}
> +
> +	if (ovl->cmdq_client) {
> +		mbox_flush(ovl->cmdq_client->chan, 2000);
> +		cmdq_mbox_destroy(ovl->cmdq_client);
> +		ovl->cmdq_client = NULL;
> +	}
> +}
> +
>  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
>  {
>  	struct mtk_disp_ovl *priv = dev_id;
> @@ -201,6 +290,7 @@ void mtk_ovl_register_vblank_cb(struct device
> *dev,
>  
>  	ovl->vblank_cb = vblank_cb;
>  	ovl->vblank_cb_data = vblank_cb_data;
> +	ovl->crtc = (struct drm_crtc *)vblank_cb_data;
>  }
>  
>  void mtk_ovl_unregister_vblank_cb(struct device *dev)
> @@ -216,14 +306,14 @@ void mtk_ovl_enable_vblank(struct device *dev)
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
>  	writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
> -	writel_relaxed(OVL_FME_CPL_INT, ovl->regs +
> DISP_REG_OVL_INTEN);
> +	writel(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);

This is not related to CRC, so move to another patch.

>  }
>  
>  void mtk_ovl_disable_vblank(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
> -	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
> +	writel(0x0, ovl->regs + DISP_REG_OVL_INTEN);

Ditto.

>  }
>  
>  const u32 *mtk_ovl_get_formats(struct device *dev)
> @@ -258,6 +348,7 @@ void mtk_ovl_start(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  	unsigned int reg = 0;
> +	unsigned int val = OVL_EN;
>  
>  	if (ovl->data->smi_id_en) {
>  		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
> @@ -265,13 +356,22 @@ void mtk_ovl_start(struct device *dev)
>  	}
>  	reg |= OVL_OUTPUT_CLAMP;
>  	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
> -	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
> +
> +	if (ovl->data->crcs)
> +		val |= OVL_OP_8BIT_MODE | OVL_HG_FOVL_CK_ON |
> OVL_HF_FOVL_CK_ON;
> +
> +	writel_relaxed(val, ovl->regs + DISP_REG_OVL_EN);
> +	writel_relaxed(OVL_CRC_EN, ovl->regs + DISP_REG_OVL_TRIG);

Set this only when this SoC support crc.

> +
> +	mtk_ovl_crc_loop_start(dev);
>  }
>  
>  void mtk_ovl_stop(struct device *dev)
>  {
>  	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>  
> +	mtk_ovl_crc_loop_stop(dev);
> +
>  	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_EN);
>  	if (ovl->data->smi_id_en) {
>  		unsigned int reg;
> @@ -321,7 +421,8 @@ void mtk_ovl_config(struct device *dev, unsigned
> int w,
>  	if (w != 0 && h != 0)
>  		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl-
> >cmdq_reg, ovl->regs,
>  				      DISP_REG_OVL_ROI_SIZE);
> -	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, 
> DISP_REG_OVL_ROI_BGCLR);
> +	mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
> ovl->regs,
> +			      DISP_REG_OVL_ROI_BGCLR);

If change background color is not related to CRC, move to another
patch. If it's related, add comment for why do this.

>  
>  	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs,
> DISP_REG_OVL_RST);
>  	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs,
> DISP_REG_OVL_RST);
> @@ -677,6 +778,16 @@ static int mtk_disp_ovl_probe(struct
> platform_device *pdev)
>  #endif
>  
>  	priv->data = of_device_get_match_data(dev);
> +
> +	if (priv->data->crcs) {
> +		if (of_property_read_u32_index(dev->of_node,
> +					       "mediatek,gce-events",
> 0,
> +					       &priv->cmdq_event)) {
> +			dev_err(dev, "failed to get gce-events\n");
> +			return -ENOPARAM;

If this SoC support crc but does not support gce, I think we could just
ignore crc function and keep drm driver work.

Regards,
CK

> +		}
> +	}
> +
>  	platform_set_drvdata(pdev, priv);
>  
>  	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
> @@ -771,6 +882,8 @@ static const struct mtk_disp_ovl_data
> mt8195_ovl_driver_data = {
>  	.formats = mt8195_formats,
>  	.num_formats = ARRAY_SIZE(mt8195_formats),
>  	.supports_clrfmt_ext = true,
> +	.crcs = mt8195_ovl_crcs,
> +	.crc_cnt = ARRAY_SIZE(mt8195_ovl_crcs),
>  };
>  
>  static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index f114da4d36a9..1b747a34a06b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -347,6 +347,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl =
> {
>  	.clk_enable = mtk_ovl_clk_enable,
>  	.clk_disable = mtk_ovl_clk_disable,
>  	.config = mtk_ovl_config,
> +	.crc_cnt = mtk_ovl_crc_cnt,
>  	.start = mtk_ovl_start,
>  	.stop = mtk_ovl_stop,
>  	.register_vblank_cb = mtk_ovl_register_vblank_cb,

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0
  2023-08-23 15:13 ` [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0 Hsiao Chien Sung
@ 2023-09-07 12:10   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:10 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Support premultiply and coverage alpha blending modes.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 175 +++++++++++++++++++++---
>   1 file changed, 155 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 8f52cc1f3fba..824f81291293 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -31,6 +31,7 @@
>   #define OVL_LAYER_SMI_ID_EN				BIT(0)
>   #define OVL_BGCLR_SEL_IN				BIT(2)
>   #define OVL_LAYER_AFBC_EN(n)				BIT(4+n)
> +#define OVL_OUTPUT_CLAMP				BIT(26)
>   #define DISP_REG_OVL_ROI_BGCLR			0x0028
>   #define DISP_REG_OVL_SRC_CON			0x002c
>   #define DISP_REG_OVL_CON(n)			(0x0030 + 0x20 * (n))
> @@ -39,10 +40,28 @@
>   #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
>   #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
>   #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
> +#define OVL_CONST_BLEND					BIT(28)
>   #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
>   #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
>   #define DISP_REG_OVL_ADDR_MT2701		0x0040
>   #define DISP_REG_OVL_CLRFMT_EXT			0x02D0
> +#define DISP_REG_OVL_CLRFMT_EXT1		0x02D8
> +#define OVL_CLRFMT_EXT1_CSC_EN(n)			(1 << ((n) * 4 + 1))

I'd prefer reading (1 << (((n) * 4) + 1) ... but no strong opinions.

> +#define DISP_REG_OVL_Y2R_PARA_R0(n)		(0x0134 + 0x28 * (n))
> +#define OVL_Y2R_PARA_C_CF_RMY				(GENMASK(14, 0))
> +#define DISP_REG_OVL_Y2R_PARA_G0(n)		(0x013c + 0x28 * (n))
> +#define OVL_Y2R_PARA_C_CF_GMU				(GENMASK(30, 16))
> +#define DISP_REG_OVL_Y2R_PARA_B1(n)		(0x0148 + 0x28 * (n))
> +#define OVL_Y2R_PARA_C_CF_BMV				(GENMASK(14, 0))
> +#define DISP_REG_OVL_Y2R_PARA_YUV_A_0(n)	(0x014c + 0x28 * (n))
> +#define OVL_Y2R_PARA_C_CF_YA				(GENMASK(10, 0))
> +#define OVL_Y2R_PARA_C_CF_UA				(GENMASK(26, 16))
> +#define DISP_REG_OVL_Y2R_PARA_YUV_A_1(n)	(0x0150 + 0x28 * (n))
> +#define OVL_Y2R_PARA_C_CF_VA				(GENMASK(10, 0))
> +#define DISP_REG_OVL_Y2R_PRE_ADD2(n)		(0x0154 + 0x28 * (n))
> +#define DISP_REG_OVL_R2R_R0(n)			(0x0500 + 0x40 * (n))
> +#define DISP_REG_OVL_R2R_G1(n)			(0x0510 + 0x40 * (n))
> +#define DISP_REG_OVL_R2R_B2(n)			(0x0520 + 0x40 * (n))
>   #define DISP_REG_OVL_ADDR_MT8173		0x0f40
>   #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))
>   #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x04)
> @@ -52,13 +71,19 @@
>   #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
>   #define GMC_THRESHOLD_LOW	((1 << GMC_THRESHOLD_BITS) / 8)
>   
> -#define OVL_CON_BYTE_SWAP	BIT(24)
> -#define OVL_CON_MTX_YUV_TO_RGB	(6 << 16)
> -#define OVL_CON_CLRFMT_RGB	(1 << 12)
> -#define OVL_CON_CLRFMT_RGBA8888	(2 << 12)
> -#define OVL_CON_CLRFMT_ARGB8888	(3 << 12)
> -#define OVL_CON_CLRFMT_UYVY	(4 << 12)
> -#define OVL_CON_CLRFMT_YUYV	(5 << 12)
> +#define OVL_CON_CLRFMT_MAN		BIT(23)
> +#define OVL_CON_BYTE_SWAP		BIT(24)
> +#define OVL_CON_RGB_SWAP		BIT(25)
> +#define OVL_CON_MTX_AUTO_DIS		BIT(26)
> +#define OVL_CON_MTX_EN			BIT(27)
> +#define OVL_CON_CLRFMT_RGB		(1 << 12)
> +#define OVL_CON_CLRFMT_RGBA8888		(2 << 12)
> +#define OVL_CON_CLRFMT_ARGB8888		(3 << 12)
> +#define OVL_CON_CLRFMT_PARGB8888	(OVL_CON_CLRFMT_ARGB8888 | OVL_CON_CLRFMT_MAN)
> +#define OVL_CON_CLRFMT_UYVY		(4 << 12)
> +#define OVL_CON_CLRFMT_YUYV		(5 << 12)
> +#define OVL_CON_MTX_YUV_TO_RGB		(6 << 16)
> +#define OVL_CON_MTX_PROGRAMMABLE	(8 << 16)
>   #define OVL_CON_CLRFMT_RGB565(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
>   					0 : OVL_CON_CLRFMT_RGB)
>   #define OVL_CON_CLRFMT_RGB888(ovl)	((ovl)->data->fmt_rgb565_is_0 ? \
> @@ -72,6 +97,22 @@
>   #define	OVL_CON_VIRT_FLIP	BIT(9)
>   #define	OVL_CON_HORZ_FLIP	BIT(10)
>   
> +static inline bool is_10bit_rgb(u32 fmt)
> +{
> +	switch (fmt) {
> +	case DRM_FORMAT_XRGB2101010:
> +	case DRM_FORMAT_ARGB2101010:
> +	case DRM_FORMAT_RGBX1010102:
> +	case DRM_FORMAT_RGBA1010102:
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ABGR2101010:
> +	case DRM_FORMAT_BGRX1010102:
> +	case DRM_FORMAT_BGRA1010102:
> +		return true;
> +	}
> +	return false;
> +}
> +
>   static const u32 mt8173_formats[] = {
>   	DRM_FORMAT_XRGB8888,
>   	DRM_FORMAT_ARGB8888,
> @@ -89,12 +130,20 @@ static const u32 mt8173_formats[] = {
>   static const u32 mt8195_formats[] = {
>   	DRM_FORMAT_XRGB8888,
>   	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_XRGB2101010,
>   	DRM_FORMAT_ARGB2101010,
>   	DRM_FORMAT_BGRX8888,
>   	DRM_FORMAT_BGRA8888,
> +	DRM_FORMAT_BGRX1010102,
>   	DRM_FORMAT_BGRA1010102,
>   	DRM_FORMAT_ABGR8888,
>   	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_XBGR2101010,
> +	DRM_FORMAT_ABGR2101010,
> +	DRM_FORMAT_RGBX8888,
> +	DRM_FORMAT_RGBA8888,
> +	DRM_FORMAT_RGBX1010102,
> +	DRM_FORMAT_RGBA1010102,
>   	DRM_FORMAT_RGB888,
>   	DRM_FORMAT_BGR888,
>   	DRM_FORMAT_RGB565,
> @@ -208,14 +257,14 @@ void mtk_ovl_clk_disable(struct device *dev)
>   void mtk_ovl_start(struct device *dev)
>   {
>   	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +	unsigned int reg = 0;
>   
>   	if (ovl->data->smi_id_en) {
> -		unsigned int reg;
> -
>   		reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
>   		reg = reg | OVL_LAYER_SMI_ID_EN;
> -		writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
>   	}
> +	reg |= OVL_OUTPUT_CLAMP;

Uhm, I wonder if clearing out the register and setting only the OVL_OUTPUT_CLAMP
bit is is intentional, or if you wanted to do, instead...

	u32 reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
	if (ovl->data->smi_id_en)
		reg |= OVL_LAYER_SMI_ID_EN;

	reg |= OVL_OUTPUT_CLAMP
	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);

> +	writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
>   	writel_relaxed(0x1, ovl->regs + DISP_REG_OVL_EN);
>   }
>   
> @@ -254,9 +303,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
>   	reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
>   	reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
>   
> -	if (format == DRM_FORMAT_RGBA1010102 ||
> -	    format == DRM_FORMAT_BGRA1010102 ||
> -	    format == DRM_FORMAT_ARGB2101010)
> +	if (is_10bit_rgb(format))
>   		bit_depth = OVL_CON_CLRFMT_10_BIT;
>   
>   	reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
> @@ -357,7 +404,8 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
>   		      DISP_REG_OVL_RDMA_CTRL(idx));
>   }
>   
> -static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
> +static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt,
> +				    unsigned int blend_mode)
>   {
>   	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
>   	 * is defined in mediatek HW data sheet.
> @@ -376,17 +424,37 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
>   		return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
>   	case DRM_FORMAT_RGBX8888:
>   	case DRM_FORMAT_RGBA8888:
> +		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> +		       OVL_CON_CLRFMT_ARGB8888 :
> +		       OVL_CON_CLRFMT_PARGB8888;
> +	case DRM_FORMAT_RGBX1010102:
> +	case DRM_FORMAT_RGBA1010102:
>   		return OVL_CON_CLRFMT_ARGB8888;
>   	case DRM_FORMAT_BGRX8888:
>   	case DRM_FORMAT_BGRA8888:
> +		return OVL_CON_BYTE_SWAP |
> +		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
> +		       OVL_CON_CLRFMT_ARGB8888 :
> +		       OVL_CON_CLRFMT_PARGB8888);
> +	case DRM_FORMAT_BGRX1010102:
>   	case DRM_FORMAT_BGRA1010102:
>   		return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
>   	case DRM_FORMAT_XRGB8888:
>   	case DRM_FORMAT_ARGB8888:
> +		return blend_mode == DRM_MODE_BLEND_COVERAGE ?
> +		       OVL_CON_CLRFMT_RGBA8888 :
> +		       OVL_CON_CLRFMT_PARGB8888;
> +	case DRM_FORMAT_XRGB2101010:
>   	case DRM_FORMAT_ARGB2101010:
>   		return OVL_CON_CLRFMT_RGBA8888;
>   	case DRM_FORMAT_XBGR8888:
>   	case DRM_FORMAT_ABGR8888:
> +		return OVL_CON_RGB_SWAP |
> +		       (blend_mode == DRM_MODE_BLEND_COVERAGE ?
> +		       OVL_CON_CLRFMT_RGBA8888 :
> +		       OVL_CON_CLRFMT_PARGB8888);
> +	case DRM_FORMAT_XBGR2101010:
> +	case DRM_FORMAT_ABGR2101010:
>   		return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
>   	case DRM_FORMAT_UYVY:
>   		return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
> @@ -408,6 +476,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
>   	unsigned int fmt = pending->format;
>   	unsigned int offset = (pending->y << 16) | pending->x;
>   	unsigned int src_size = (pending->height << 16) | pending->width;
> +	unsigned int blend_mode = state->base.pixel_blend_mode;
> +	unsigned int ignore_pixel_alpha = 0;
>   	unsigned int con;
>   	bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
>   	union overlay_pitch {
> @@ -420,14 +490,79 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
>   
>   	overlay_pitch.pitch = pitch;
>   
> -	if (!pending->enable) {
> +	if (!pending->enable || !pending->width || !pending->height) {
>   		mtk_ovl_layer_off(dev, idx, cmdq_pkt);
>   		return;
>   	}
>   
> -	con = ovl_fmt_convert(ovl, fmt);
> -	if (state->base.fb && state->base.fb->format->has_alpha)
> -		con |= OVL_CON_AEN | OVL_CON_ALPHA;
> +	con = ovl_fmt_convert(ovl, fmt, blend_mode);
> +	if (state->base.fb) {
> +		con |= OVL_CON_AEN;
> +		con |= state->base.alpha & 0xff;
> +	}
> +
> +	if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
> +	    (state->base.fb && !state->base.fb->format->has_alpha))
> +		ignore_pixel_alpha = OVL_CONST_BLEND;
> +
> +	/* need to do Y2R and R2R to reduce 10bit data to 8bit for CRC calculation */
> +	if (ovl->data->supports_clrfmt_ext) {
> +		u32 y2r_coef = 0, y2r_offset = 0, r2r_coef = 0, csc_en = 0;
> +
> +		if (is_10bit_rgb(fmt)) {
> +			con |= OVL_CON_MTX_AUTO_DIS | OVL_CON_MTX_EN | OVL_CON_MTX_PROGRAMMABLE;
> +
> +			/* Y2R coef setting: bit 13 is 2^1, bit 12 is 2^0, bit 11 is 2^-1, ... */
> +			y2r_coef = BIT(10);	/* bit 10 is 2^-2 = 0.25 */
> +			y2r_offset = 0x7fe;	/* -1 in 10bit */

Is it possible to calculate this with a macro, instead of hardcoding the 0x7fe value?

Regards,
Angelo

> +			/* R2R coef setting: bit 19 is 2^1, bit 18 is 2^0, bit 17 is 2^-1, ... */
> +			r2r_coef = BIT(20);	/* bit 20 is 2^2 = 4 */
> +			csc_en = OVL_CLRFMT_EXT1_CSC_EN(idx);	/* CSC_EN is for R2R */
> +
> +			/*
> +			 * 1. YUV input data - 1 and shift right for 2 bits to remove it
> +			 * [R']   [0.25    0    0]   [Y in - 1]
> +			 * [G'] = [   0 0.25    0] * [U in - 1]
> +			 * [B']   [   0    0 0.25]   [V in - 1]
> +			 *
> +			 * 2. shift left for 2 bit letting the last 2 bits become 0
> +			 * [R out]   [ 4  0  0]   [R']
> +			 * [G out] = [ 0  4  0] * [G']
> +			 * [B out]   [ 0  0  4]   [B']
> +			 */
> +		}
> +
> +		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_R0(idx),
> +				   OVL_Y2R_PARA_C_CF_RMY);
> +		mtk_ddp_write_mask(cmdq_pkt, (y2r_coef << 16),
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_G0(idx),
> +				   OVL_Y2R_PARA_C_CF_GMU);
> +		mtk_ddp_write_mask(cmdq_pkt, y2r_coef,
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_B1(idx),
> +				   OVL_Y2R_PARA_C_CF_BMV);
> +
> +		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
> +				   OVL_Y2R_PARA_C_CF_YA);
> +		mtk_ddp_write_mask(cmdq_pkt, (y2r_offset << 16),
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_0(idx),
> +				   OVL_Y2R_PARA_C_CF_UA);
> +		mtk_ddp_write_mask(cmdq_pkt, y2r_offset,
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_Y2R_PARA_YUV_A_1(idx),
> +				   OVL_Y2R_PARA_C_CF_VA);
> +
> +		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
> +				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_R0(idx));
> +		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
> +				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_G1(idx));
> +		mtk_ddp_write_relaxed(cmdq_pkt, r2r_coef,
> +				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_R2R_B2(idx));
> +
> +		mtk_ddp_write_mask(cmdq_pkt, csc_en,
> +				   &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_CLRFMT_EXT1,
> +				   OVL_CLRFMT_EXT1_CSC_EN(idx));
> +	}
>   
>   	if (pending->rotation & DRM_MODE_REFLECT_Y) {
>   		con |= OVL_CON_VIRT_FLIP;
> @@ -444,8 +579,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
>   
>   	mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
>   			      DISP_REG_OVL_CON(idx));
> -	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
> -			      DISP_REG_OVL_PITCH(idx));
> +	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb | ignore_pixel_alpha,
> +			      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
>   	mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
>   			      DISP_REG_OVL_SRC_SIZE(idx));
>   	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 01/15] soc: mediatek: Add register definitions for GCE
  2023-08-23 15:13 ` [PATCH 01/15] soc: mediatek: Add register definitions for GCE Hsiao Chien Sung
@ 2023-09-07 12:11   ` AngeloGioacchino Del Regno
  2023-09-11 13:38     ` Shawn Sung (宋孝謙)
  0 siblings, 1 reply; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:11 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Add register definitions for GCE so users can use them
> as a buffer to store data.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>   include/linux/soc/mediatek/mtk-cmdq.h | 7 +++++++
>   1 file changed, 7 insertions(+)
> 
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index 649955d2cf5c..3eb95ef34c6c 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -14,6 +14,13 @@
>   #define CMDQ_ADDR_HIGH(addr)	((u32)(((addr) >> 16) & GENMASK(31, 0)))
>   #define CMDQ_ADDR_LOW(addr)	((u16)(addr) | BIT(1))
>   

Please add a comment explaining "TPR"

> +#define CMDQ_TPR_ID		(56)
> +

Please add a comment explaining what those definitions are, what is "SPR"?

Regards,
Angelo

> +#define CMDQ_THR_SPR_IDX0	(0)
> +#define CMDQ_THR_SPR_IDX1	(1)
> +#define CMDQ_THR_SPR_IDX2	(2)
> +#define CMDQ_THR_SPR_IDX3	(3)
> +
>   struct cmdq_pkt;
>   
>   struct cmdq_client_reg {


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1
  2023-08-23 15:13 ` [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1 Hsiao Chien Sung
@ 2023-09-07 12:15   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:15 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Support premultiply and coverage alpha blending modes.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_ethdr.c | 50 +++++++++++++++++++++-------
>   1 file changed, 38 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> index 73dc4da3ba3b..3058c122a4c3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
> +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> @@ -5,6 +5,7 @@
>   
>   #include <drm/drm_fourcc.h>
>   #include <drm/drm_framebuffer.h>
> +#include <drm/drm_blend.h>
>   #include <linux/clk.h>
>   #include <linux/component.h>
>   #include <linux/of_device.h>
> @@ -35,6 +36,7 @@
>   #define MIX_SRC_L0_EN				BIT(0)
>   #define MIX_L_SRC_CON(n)		(0x28 + 0x18 * (n))
>   #define NON_PREMULTI_SOURCE			(2 << 12)
> +#define PREMULTI_SOURCE				(3 << 12)
>   #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
>   #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
>   #define MIX_FUNC_DCM0			0x120
> @@ -50,9 +52,7 @@
>   
>   #define MIXER_INX_MODE_BYPASS			0
>   #define MIXER_INX_MODE_EVEN_EXTEND		1
> -#define DEFAULT_9BIT_ALPHA			0x100
>   #define	MIXER_ALPHA_AEN				BIT(8)
> -#define	MIXER_ALPHA				0xff
>   #define ETHDR_CLK_NUM				13
>   
>   enum mtk_ethdr_comp_id {
> @@ -153,33 +153,59 @@ void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
>   	struct mtk_plane_pending_state *pending = &state->pending;
>   	unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
>   	unsigned int align_width = ALIGN_DOWN(pending->width, 2);
> -	unsigned int alpha_con = 0;
> +	unsigned int mix_con = NON_PREMULTI_SOURCE;
> +	bool replace_src_a = false;
> +
> +	union format {
> +		unsigned int raw;
> +		char str[5];

Can we please use fixed size variables?

		u32 raw;
		u8 str[5];

> +	} format;
>   

Regards,
Angelo


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 05/15] drm/mediatek: Support alpha blending in display driver
  2023-08-23 15:13 ` [PATCH 05/15] drm/mediatek: Support alpha blending in display driver Hsiao Chien Sung
@ 2023-09-07 12:17   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:17 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Support alpha blending by adding correct blend mode and
> alpha property in plane initialization.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 10/15] drm/mediatek: Support CRC in display driver
  2023-08-23 15:13 ` [PATCH 10/15] drm/mediatek: Support CRC in display driver Hsiao Chien Sung
@ 2023-09-07 12:20   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:20 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Register CRC related function pointers to support CRC
> retrieval.
> 
> Skip the first CRC because when the first vblank triggered,
> the frame buffer is not ready for CRC calculation yet.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 53 +++++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.h     | 20 ++++++++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  5 ++
>   3 files changed, 78 insertions(+)
> 

..snip..

> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index febcaeef16a1..3b67c3dc0525 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -45,6 +45,10 @@ enum mtk_ddp_comp_type {
>   
>   struct mtk_ddp_comp;
>   struct cmdq_pkt;
> +
> +/* struct mtk_ddp_comp_funcs - function pointers of the ddp components

While at it, can you at this point just add kerneldoc for the entire structure?
That should be pretty straightforward, and just a 10 minutes job.

Thanks!
Angelo

> + * @crc_cnt: how many CRCs the component supports
> + */
>   struct mtk_ddp_comp_funcs {
>   	int (*clk_enable)(struct device *dev);
>   	void (*clk_disable)(struct device *dev);
> @@ -80,6 +84,7 @@ struct mtk_ddp_comp_funcs {
>   	void (*disconnect)(struct device *dev, struct device *mmsys_dev, unsigned int next);
>   	void (*add)(struct device *dev, struct mtk_mutex *mutex);
>   	void (*remove)(struct device *dev, struct mtk_mutex *mutex);
> +	u32 (*crc_cnt)(struct device *dev);
>   };
>   


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1
  2023-08-23 15:13 ` [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1 Hsiao Chien Sung
@ 2023-09-07 12:31   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:31 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> We choose Mixer as CRC generator in VDOSYS1 since
> its frame done event will trigger vblanks, we can know
> when is safe to retrieve CRC of the frame.
> 
> In VDOSYS1, there's no image procession after Mixer,
> unlike OVL in VDOSYS0, Mixer's CRC will include all the
> effects that are applied to the frame.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   1 +
>   .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  10 ++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |   1 +
>   drivers/gpu/drm/mediatek/mtk_ethdr.c          | 120 ++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_ethdr.h          |   4 +
>   5 files changed, 136 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index d2753360ae1e..014086d4d7ca 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -127,6 +127,7 @@ unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
>   struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev);
>   const u32 *mtk_ovl_adaptor_get_formats(struct device *dev);
>   size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
> +u32 mtk_ovl_adaptor_crc_cnt(struct device *dev);
>   
>   void mtk_rdma_bypass_shadow(struct device *dev);
>   int mtk_rdma_clk_enable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index c0a38f5217ee..64f98b26f4ce 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -159,6 +159,13 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
>   	mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
>   }
>   
> +u32 mtk_ovl_adaptor_crc_cnt(struct device *dev)
> +{
> +	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
> +
> +	return mtk_ethdr_crc_cnt(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
> +}
> +
>   void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
>   			    unsigned int h, unsigned int vrefresh,
>   			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> @@ -274,6 +281,9 @@ void mtk_ovl_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(vo
>   
>   	mtk_ethdr_register_vblank_cb(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
>   				     vblank_cb, vblank_cb_data);
> +
> +	mtk_ethdr_register_crtc(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
> +				(struct drm_crtc *)vblank_cb_data);
>   }
>   
>   void mtk_ovl_adaptor_unregister_vblank_cb(struct device *dev)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 1b747a34a06b..143136491607 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -398,6 +398,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
>   	.clk_enable = mtk_ovl_adaptor_clk_enable,
>   	.clk_disable = mtk_ovl_adaptor_clk_disable,
>   	.config = mtk_ovl_adaptor_config,
> +	.crc_cnt = mtk_ovl_adaptor_crc_cnt,
>   	.start = mtk_ovl_adaptor_start,
>   	.stop = mtk_ovl_adaptor_stop,
>   	.layer_nr = mtk_ovl_adaptor_layer_nr,
> diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> index 3058c122a4c3..9e341d86d9f9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ethdr.c
> +++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
> @@ -24,6 +24,9 @@
>   #define MIX_FME_CPL_INTEN			BIT(1)
>   #define MIX_INTSTA			0x8
>   #define MIX_EN				0xc
> +#define MIX_TRIG			0x10
> +#define MIX_TRIG_CRC_EN				BIT(8)
> +#define MIX_TRIG_CRC_RST			BIT(9)
>   #define MIX_RST				0x14
>   #define MIX_ROI_SIZE			0x18
>   #define MIX_DATAPATH_CON		0x1c
> @@ -39,6 +42,11 @@
>   #define PREMULTI_SOURCE				(3 << 12)
>   #define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
>   #define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
> +
> +/* CRC register offsets for odd and even lines */
> +#define MIX_CRC_O			0x110
> +#define MIX_CRC_E			0x114
> +
>   #define MIX_FUNC_DCM0			0x120
>   #define MIX_FUNC_DCM1			0x124
>   #define MIX_FUNC_DCM_ENABLE			0xffffffff
> @@ -70,6 +78,9 @@ struct mtk_ethdr_comp {
>   	struct device		*dev;
>   	void __iomem		*regs;
>   	struct cmdq_client_reg	cmdq_base;
> +	struct cmdq_client *cmdq_client;
> +	struct cmdq_pkt *cmdq_pkt;
> +	u32 cmdq_event;
>   };
>   
>   struct mtk_ethdr {
> @@ -80,6 +91,9 @@ struct mtk_ethdr {
>   	void			*vblank_cb_data;
>   	int			irq;
>   	struct reset_control	*reset_ctl;
> +	struct drm_crtc		*crtc;
> +	const u32		*crcs;
> +	size_t			crc_cnt;
>   };
>   
>   static const char * const ethdr_clk_str[] = {
> @@ -98,6 +112,95 @@ static const char * const ethdr_clk_str[] = {
>   	"vdo_be_async",
>   };
>   
> +static const u32 ethdr_crcs[] = {
> +	MIX_CRC_O,
> +	MIX_CRC_E,
> +};
> +
> +u32 mtk_ethdr_crc_cnt(struct device *dev)
> +{
> +	struct mtk_ethdr *priv = dev_get_drvdata(dev);
> +
> +	return (u32)priv->crc_cnt;
> +}
> +
> +void mtk_ethdr_register_crtc(struct device *dev, struct drm_crtc *crtc)
> +{
> +	struct mtk_ethdr *priv = dev_get_drvdata(dev);
> +
> +	priv->crtc = crtc;
> +}
> +
> +static void mtk_ethdr_crc_loop_start(struct device *dev)
> +{
> +	int i;
> +	struct mtk_ethdr *priv;
> +	struct mtk_ethdr_comp *mixer;
> +	struct mtk_drm_crtc *mtk_crtc;

You can initialize those variables at declaration time, since there's no
check in between initializations.

> +
> +	priv = dev_get_drvdata(dev);
> +	mixer = &priv->ethdr_comp[ETHDR_MIXER];
> +	mtk_crtc = container_of(priv->crtc, struct mtk_drm_crtc, base);
> +
> +	if (!mixer->cmdq_event || mixer->cmdq_client)
> +		return;
> +
> +	mixer->cmdq_client = cmdq_mbox_create(dev, 0);
> +	if (IS_ERR(mixer->cmdq_client)) {
> +		pr_err("failed to create mailbox client\n");

Is there any way to *guarantee* that this won't fail?

> +		return;
> +	}
> +	mixer->cmdq_pkt = cmdq_pkt_create(mixer->cmdq_client, PAGE_SIZE);
> +	if (!mixer->cmdq_pkt) {
> +		pr_err("failed to create cmdq packet\n");
> +		return;
> +	}
> +

Regards,
Angelo


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 13/15] drm/mediatek: Add missing plane settings when async update
  2023-08-23 15:13 ` [PATCH 13/15] drm/mediatek: Add missing plane settings when async update Hsiao Chien Sung
@ 2023-09-07 12:33   ` AngeloGioacchino Del Regno
  2023-09-11 13:45     ` Shawn Sung (宋孝謙)
  0 siblings, 1 reply; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-07 12:33 UTC (permalink / raw)
  To: Hsiao Chien Sung, Chun-Kuang Hu, Philipp Zabel, David Airlie,
	Daniel Vetter, Matthias Brugger, Jassi Brar
  Cc: linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Singo Chang, Nancy Lin,
	Jason-JH Lin

Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> Fix an issue that plane coordinate was not saved when
> calling async update.
> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>

 From what I understand, this is a fix for an issue that was present before
your newly introduced code.

This means that you want to add a Fixes tag, and that you should also send
this commit separately from the IGT series. Please do that.

Thanks,
Angelo

> ---
>   drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index ca22d02375d5..dc19827f6927 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -210,6 +210,8 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane,
>   	plane->state->src_y = new_state->src_y;
>   	plane->state->src_h = new_state->src_h;
>   	plane->state->src_w = new_state->src_w;
> +	plane->state->dst.x1 = new_state->dst.x1;
> +	plane->state->dst.y1 = new_state->dst.y1;
>   	swap(plane->state->fb, new_state->fb);
>   
>   	mtk_plane_update_new_state(new_state, new_plane_state);


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 01/15] soc: mediatek: Add register definitions for GCE
  2023-09-07 12:11   ` AngeloGioacchino Del Regno
@ 2023-09-11 13:38     ` Shawn Sung (宋孝謙)
  0 siblings, 0 replies; 33+ messages in thread
From: Shawn Sung (宋孝謙) @ 2023-09-11 13:38 UTC (permalink / raw)
  To: p.zabel, airlied, matthias.bgg, daniel,
	angelogioacchino.delregno, chunkuang.hu, jassisinghbrar
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi Angelo,

On Thu, 2023-09-07 at 14:11 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> > Add register definitions for GCE so users can use them
> > as a buffer to store data.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> > ---
> >   include/linux/soc/mediatek/mtk-cmdq.h | 7 +++++++
> >   1 file changed, 7 insertions(+)
> > 
> > diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> > b/include/linux/soc/mediatek/mtk-cmdq.h
> > index 649955d2cf5c..3eb95ef34c6c 100644
> > --- a/include/linux/soc/mediatek/mtk-cmdq.h
> > +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> > @@ -14,6 +14,13 @@
> >   #define CMDQ_ADDR_HIGH(addr)	((u32)(((addr) >> 16) &
> > GENMASK(31, 0)))
> >   #define CMDQ_ADDR_LOW(addr)	((u16)(addr) | BIT(1))
> >   
> 
> Please add a comment explaining "TPR"

It means Time Purpose Register. Will remove it in the new version since
it is not being used.

> 
> > +#define CMDQ_TPR_ID		(56)
> > +
> 
> Please add a comment explaining what those definitions are, what is
> "SPR"?

SPR is Specific Purpose Registers. Will add a comment in the next
version.

Thanks,
Hsiao Chien Sung

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 13/15] drm/mediatek: Add missing plane settings when async update
  2023-09-07 12:33   ` AngeloGioacchino Del Regno
@ 2023-09-11 13:45     ` Shawn Sung (宋孝謙)
  2023-09-14 13:18       ` AngeloGioacchino Del Regno
  0 siblings, 1 reply; 33+ messages in thread
From: Shawn Sung (宋孝謙) @ 2023-09-11 13:45 UTC (permalink / raw)
  To: p.zabel, airlied, matthias.bgg, daniel,
	angelogioacchino.delregno, chunkuang.hu, jassisinghbrar
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi Angelo,

On Thu, 2023-09-07 at 14:33 +0200, AngeloGioacchino Del Regno wrote:
> Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> > Fix an issue that plane coordinate was not saved when
> > calling async update.
> > 
> > Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> 
>  From what I understand, this is a fix for an issue that was present
> before
> your newly introduced code.
> 
> This means that you want to add a Fixes tag, and that you should also
> send
> this commit separately from the IGT series. Please do that.

Got it, will add a fix tag in the next version. But since without this
patch, IGT will fail at some test cases, could we still send them in
the same series so IGT can pass out-of-the-box?

Thanks,

Hsiao Chien Sung

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 13/15] drm/mediatek: Add missing plane settings when async update
  2023-09-11 13:45     ` Shawn Sung (宋孝謙)
@ 2023-09-14 13:18       ` AngeloGioacchino Del Regno
  2023-09-18  8:58         ` Shawn Sung (宋孝謙)
  0 siblings, 1 reply; 33+ messages in thread
From: AngeloGioacchino Del Regno @ 2023-09-14 13:18 UTC (permalink / raw)
  To: Shawn Sung (宋孝謙),
	p.zabel, airlied, matthias.bgg, daniel, chunkuang.hu,
	jassisinghbrar
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Il 11/09/23 15:45, Shawn Sung (宋孝謙) ha scritto:
> Hi Angelo,
> 
> On Thu, 2023-09-07 at 14:33 +0200, AngeloGioacchino Del Regno wrote:
>> Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
>>> Fix an issue that plane coordinate was not saved when
>>> calling async update.
>>>
>>> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
>>
>>   From what I understand, this is a fix for an issue that was present
>> before
>> your newly introduced code.
>>
>> This means that you want to add a Fixes tag, and that you should also
>> send
>> this commit separately from the IGT series. Please do that.
> 
> Got it, will add a fix tag in the next version. But since without this
> patch, IGT will fail at some test cases, could we still send them in
> the same series so IGT can pass out-of-the-box?
> 

Fixes are applied before new features, so if you send this patch outside
of the IGT series, this will most likely be applied *before* that series.

When the IGT series will be applied, this patch will already be present,
so, please send this one separately.

Regards,
Angelo


^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [PATCH 13/15] drm/mediatek: Add missing plane settings when async update
  2023-09-14 13:18       ` AngeloGioacchino Del Regno
@ 2023-09-18  8:58         ` Shawn Sung (宋孝謙)
  0 siblings, 0 replies; 33+ messages in thread
From: Shawn Sung (宋孝謙) @ 2023-09-18  8:58 UTC (permalink / raw)
  To: p.zabel, airlied, matthias.bgg, daniel,
	angelogioacchino.delregno, chunkuang.hu, jassisinghbrar
  Cc: linux-arm-kernel, linux-kernel, linux-mediatek,
	Jason-JH Lin (林睿祥),
	Nancy Lin (林欣螢),
	Singo Chang (張興國),
	Project_Global_Chrome_Upstream_Group

Hi Angelo,

On Thu, 2023-09-14 at 15:18 +0200, AngeloGioacchino Del Regno wrote:
> Il 11/09/23 15:45, Shawn Sung (宋孝謙) ha scritto:
> > Hi Angelo,
> > 
> > On Thu, 2023-09-07 at 14:33 +0200, AngeloGioacchino Del Regno
> > wrote:
> > > Il 23/08/23 17:13, Hsiao Chien Sung ha scritto:
> > > > Fix an issue that plane coordinate was not saved when
> > > > calling async update.
> > > > 
> > > > Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> > > 
> > >   From what I understand, this is a fix for an issue that was
> > > present
> > > before
> > > your newly introduced code.
> > > 
> > > This means that you want to add a Fixes tag, and that you should
> > > also
> > > send
> > > this commit separately from the IGT series. Please do that.
> > 
> > Got it, will add a fix tag in the next version. But since without
> > this
> > patch, IGT will fail at some test cases, could we still send them
> > in
> > the same series so IGT can pass out-of-the-box?
> > 
> 
> Fixes are applied before new features, so if you send this patch
> outside
> of the IGT series, this will most likely be applied *before* that
> series.
> 
> When the IGT series will be applied, this patch will already be
> present,
> so, please send this one separately.

Got it. Had sent two fixes that are found during IGT test separately.

Thanks,

Hsiao Chien Sung

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2023-09-18  8:59 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-23 15:13 [PATCH 00/15] Support IGT in display driver Hsiao Chien Sung
2023-08-23 15:13 ` [PATCH 01/15] soc: mediatek: Add register definitions for GCE Hsiao Chien Sung
2023-09-07 12:11   ` AngeloGioacchino Del Regno
2023-09-11 13:38     ` Shawn Sung (宋孝謙)
2023-08-23 15:13 ` [PATCH 02/15] soc: mediatek: Disable 9-bit alpha in ETHDR Hsiao Chien Sung
2023-08-23 15:13 ` [PATCH 03/15] soc: mediatek: Support GCE thread loop Hsiao Chien Sung
2023-08-29  7:07   ` CK Hu (胡俊光)
2023-08-30  2:15   ` CK Hu (胡俊光)
2023-08-23 15:13 ` [PATCH 04/15] mailbox: mtk-cmdq: " Hsiao Chien Sung
2023-08-29  7:13   ` CK Hu (胡俊光)
2023-08-23 15:13 ` [PATCH 05/15] drm/mediatek: Support alpha blending in display driver Hsiao Chien Sung
2023-09-07 12:17   ` AngeloGioacchino Del Regno
2023-08-23 15:13 ` [PATCH 06/15] drm/mediatek: Support alpha blending in VDOSYS0 Hsiao Chien Sung
2023-09-07 12:10   ` AngeloGioacchino Del Regno
2023-08-23 15:13 ` [PATCH 07/15] drm/mediatek: Support alpha blending in VDOSYS1 Hsiao Chien Sung
2023-09-07 12:15   ` AngeloGioacchino Del Regno
2023-08-23 15:13 ` [PATCH 08/15] drm/mediatek: Move struct mtk_drm_crtc to the header file Hsiao Chien Sung
2023-08-23 15:13 ` [PATCH 09/15] drm/mediatek: Add OVL compatible name for MT8195 Hsiao Chien Sung
2023-08-23 15:13 ` [PATCH 10/15] drm/mediatek: Support CRC in display driver Hsiao Chien Sung
2023-09-07 12:20   ` AngeloGioacchino Del Regno
2023-08-23 15:13 ` [PATCH 11/15] drm/mediatek: Support CRC in VDOSYS0 Hsiao Chien Sung
2023-08-24  2:29   ` CK Hu (胡俊光)
2023-08-30  5:13     ` Shawn Sung (宋孝謙)
2023-08-31  1:45   ` CK Hu (胡俊光)
2023-08-23 15:13 ` [PATCH 12/15] drm/mediatek: Support CRC in VDOSYS1 Hsiao Chien Sung
2023-09-07 12:31   ` AngeloGioacchino Del Regno
2023-08-23 15:13 ` [PATCH 13/15] drm/mediatek: Add missing plane settings when async update Hsiao Chien Sung
2023-09-07 12:33   ` AngeloGioacchino Del Regno
2023-09-11 13:45     ` Shawn Sung (宋孝謙)
2023-09-14 13:18       ` AngeloGioacchino Del Regno
2023-09-18  8:58         ` Shawn Sung (宋孝謙)
2023-08-23 15:13 ` [PATCH 14/15] drm/mediatek: Adjust DRM mode configs for IGT Hsiao Chien Sung
2023-08-23 15:13 ` [PATCH 15/15] drm/mediatek: Fix errors when reporting rotation capability Hsiao Chien Sung

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).