[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251223-mtk-ovl-pre-blend-colorops-v1-10-0cb99bd0ab33@collabora.com>
Date: Tue, 23 Dec 2025 16:44:51 -0300
From: Nícolas F. R. A. Prado <nfraprado@...labora.com>
To: Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
Maxime Ripard <mripard@...nel.org>, Thomas Zimmermann <tzimmermann@...e.de>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Chun-Kuang Hu <chunkuang.hu@...nel.org>,
Philipp Zabel <p.zabel@...gutronix.de>,
Matthias Brugger <matthias.bgg@...il.com>,
AngeloGioacchino Del Regno <angelogioacchino.delregno@...labora.com>
Cc: dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
linux-mediatek@...ts.infradead.org, linux-arm-kernel@...ts.infradead.org,
daniels@...labora.com, ariel.dalessandro@...labora.com,
kernel@...labora.com,
Nícolas F. R. A. Prado <nfraprado@...labora.com>
Subject: [PATCH 10/11] drm/mediatek: ovl: Enable support for R2R Color
Space Conversion
The OVL hardware allows applying a 3x3 matrix transformation for each
layer through the 'RGB to RGB Color Space Conversion' (R2R CSC) setting.
Implement support for it and expose it as a colorop through the DRM
plane color pipeline uAPI.
Signed-off-by: Nícolas F. R. A. Prado <nfraprado@...labora.com>
---
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 55 ++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a70092c792a9..c8a2b1b13035 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -4,6 +4,7 @@
*/
#include <drm/drm_blend.h>
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_colorop.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
@@ -52,6 +53,7 @@
#define OVL_CON_CLRFMT_10_BIT (1)
#define DISP_REG_OVL_WCG_CFG1 0x2d8
#define IGAMMA_EN(layer) BIT(0 + 4 * (layer))
+#define CSC_EN(layer) BIT(1 + 4 * (layer))
#define GAMMA_EN(layer) BIT(2 + 4 * (layer))
#define DISP_REG_OVL_WCG_CFG2 0x2dc
#define IGAMMA_MASK(layer) GENMASK((layer) * 4 + 1, (layer) * 4)
@@ -62,6 +64,7 @@
#define GAMMA_BT709 1
#define GAMMA_BT2020 2
#define GAMMA_HLG 3
+#define DISP_REG_OVL_R2R_PARA(layer) (0x500 + (layer) * 0x40)
#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)
@@ -579,11 +582,44 @@ static void mtk_ovl_apply_igamma(struct mtk_disp_ovl *ovl, unsigned int idx,
IGAMMA_EN(idx));
}
+static void mtk_ovl_write_r2r_para(struct mtk_disp_ovl *ovl, unsigned int idx,
+ struct drm_color_ctm *ctm,
+ struct cmdq_pkt *cmdq_pkt)
+{
+ unsigned int i;
+ u64 val;
+
+ for (i = 0; i < ARRAY_SIZE(ctm->matrix); i++) {
+ val = drm_color_ctm_s31_32_to_qm_n(ctm->matrix[i], 5, 18);
+ mtk_ddp_write(cmdq_pkt, val, &ovl->cmdq_reg, ovl->regs,
+ DISP_REG_OVL_R2R_PARA(idx) + i * 4);
+ }
+}
+
+static void mtk_ovl_apply_r2r_csc(struct mtk_disp_ovl *ovl, unsigned int idx,
+ struct drm_colorop *colorop,
+ struct cmdq_pkt *cmdq_pkt)
+{
+ struct drm_color_ctm *ctm;
+
+ if (colorop->state->data && colorop->state->data->data) {
+ ctm = (struct drm_color_ctm *)colorop->state->data->data;
+ mtk_ovl_write_r2r_para(ovl, idx, ctm, cmdq_pkt);
+ }
+
+ mtk_ddp_write_mask(cmdq_pkt, colorop->state->bypass ? 0 : CSC_EN(idx),
+ &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_WCG_CFG1,
+ CSC_EN(idx));
+}
+
static void mtk_ovl_apply_colorop(struct mtk_disp_ovl *ovl, unsigned int idx,
struct drm_colorop *colorop,
struct cmdq_pkt *cmdq_pkt)
{
switch (colorop->type) {
+ case DRM_COLOROP_CTM_3X3:
+ mtk_ovl_apply_r2r_csc(ovl, idx, colorop, cmdq_pkt);
+ break;
case DRM_COLOROP_1D_CURVE:
/* gamma is the last colorop in pipeline */
if (!colorop->next)
@@ -602,7 +638,7 @@ static void mtk_ovl_disable_colorops(struct mtk_disp_ovl *ovl, unsigned int idx,
{
mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
DISP_REG_OVL_WCG_CFG1,
- IGAMMA_EN(idx) | GAMMA_EN(idx));
+ IGAMMA_EN(idx) | CSC_EN(idx) | GAMMA_EN(idx));
/* igamma curve needs to be set to default when igamma is disabled */
mtk_ddp_write_mask(cmdq_pkt, IGAMMA_SCRGB, &ovl->cmdq_reg, ovl->regs,
@@ -771,6 +807,23 @@ mtk_ovl_initialize_plane_color_pipeline(struct drm_plane *plane,
i++;
+ /* 2nd op: OVL's R2R Color Space Conversion */
+ ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL);
+ if (!ops[i]) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ ret = drm_plane_colorop_ctm_3x3_init(dev, ops[i], plane,
+ &mtk_ovl_colorop_funcs,
+ DRM_COLOROP_FLAG_ALLOW_BYPASS);
+ if (ret)
+ goto err_colorop_init;
+
+ drm_colorop_set_next_property(ops[i - 1], ops[i]);
+
+ i++;
+
/* 3rd op: OVL's Gamma */
ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL);
if (!ops[i]) {
--
2.51.0
Powered by blists - more mailing lists