[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250822-mtk-post-blend-color-pipeline-v1-4-a9446d4aca82@collabora.com>
Date: Fri, 22 Aug 2025 14:36:14 -0400
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: Alex Hung <alex.hung@....com>, wayland-devel@...ts.freedesktop.org,
harry.wentland@....com, leo.liu@....com, ville.syrjala@...ux.intel.com,
pekka.paalanen@...labora.com, contact@...rsion.fr, mwen@...lia.com,
jadahl@...hat.com, sebastian.wick@...hat.com, shashank.sharma@....com,
agoins@...dia.com, joshua@...ggi.es, mdaenzer@...hat.com, aleixpol@....org,
xaver.hugl@...il.com, victoria@...tem76.com, uma.shankar@...el.com,
quic_naseer@...cinc.com, quic_cbraga@...cinc.com, quic_abhinavk@...cinc.com,
marcan@...can.st, Liviu.Dudau@....com, sashamcintosh@...gle.com,
chaitanya.kumar.borah@...el.com, louis.chauvet@...tlin.com,
mcanal@...lia.com, kernel@...labora.com, daniels@...labora.com,
dri-devel@...ts.freedesktop.org, linux-kernel@...r.kernel.org,
linux-mediatek@...ts.infradead.org, linux-arm-kernel@...ts.infradead.org,
Nícolas F. R. A. Prado <nfraprado@...labora.com>,
Simona Vetter <simona.vetter@...ll.ch>
Subject: [PATCH RFC 4/5] drm/mediatek: ccorr: Support post-blend color
pipeline API
Implement the ctm_set_color_pipeline DDP component function to allow
configuring the CTM through the color pipeline API.
The color pipeline API only defines a 3x4 matrix, while the driver
currently only supports setting the coefficients for a 3x3 matrix.
However the underlying hardware does support setting the offset
coefficients that make up a 3x4 matrix, so implement support for setting
them so the 3x4 matrix structure for the API can be used as is.
Also make sure to enable or disable the CTM function depending on
whether the block should be bypassed or not.
Signed-off-by: Nícolas F. R. A. Prado <nfraprado@...labora.com>
---
drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 3 +-
drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 100 ++++++++++++++++++++++++++----
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +-
3 files changed, 93 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
index ac6620e10262e3b9a4a82093f13c3101f79520de..c873b527423f51733058cbc3d0ad2a719e26bfe1 100644
--- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
@@ -284,7 +284,8 @@ static const struct mtk_ddp_comp_funcs ddp_ccorr = {
.config = mtk_ccorr_config,
.start = mtk_ccorr_start,
.stop = mtk_ccorr_stop,
- .ctm_set = mtk_ccorr_ctm_set,
+ .ctm_set = mtk_ccorr_ctm_set_legacy,
+ .ctm_set_color_pipeline = mtk_ccorr_ctm_set_color_pipeline,
};
static const struct mtk_ddp_comp_funcs ddp_color = {
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
index 10d60d2c2a568ebbe09f90e8f42a73e4c2366662..f69a7d8b97f741f0c5461e8cd6f38f70b0690e7e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c
@@ -28,6 +28,11 @@
#define DISP_CCORR_COEF_2 0x0088
#define DISP_CCORR_COEF_3 0x008C
#define DISP_CCORR_COEF_4 0x0090
+#define DISP_CCORR_OFFSET_0 0x0100
+#define CCORR_OFFSET_EN BIT(31)
+#define DISP_CCORR_OFFSET_1 0x0104
+#define DISP_CCORR_OFFSET_2 0x0108
+#define DISP_CCORR_OFFSET_MASK GENMASK(26, 14)
struct mtk_disp_ccorr_data {
u32 matrix_bits;
@@ -101,25 +106,48 @@ static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n)
return r;
}
-void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
+static void mtk_ccorr_ctm_set(struct device *dev, struct cmdq_pkt *cmdq_pkt,
+ void *ctm, bool ctm_3x4)
{
struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
- struct drm_property_blob *blob = state->ctm;
- struct drm_color_ctm *ctm;
- const u64 *input;
+ u64 coeffs_in[9];
+ u64 coeffs_offset_in[3];
uint16_t coeffs[9] = { 0 };
+ uint16_t coeffs_offset[3];
int i;
- struct cmdq_pkt *cmdq_pkt = NULL;
u32 matrix_bits = ccorr->data->matrix_bits;
+ u32 val;
+
+ if (ctm_3x4) {
+ struct drm_color_ctm_3x4 *ctm_3x4 = (struct drm_color_ctm_3x4 *)ctm;
+
+ coeffs_in[0] = ctm_3x4->matrix[0];
+ coeffs_in[1] = ctm_3x4->matrix[1];
+ coeffs_in[2] = ctm_3x4->matrix[2];
+ coeffs_in[3] = ctm_3x4->matrix[4];
+ coeffs_in[4] = ctm_3x4->matrix[5];
+ coeffs_in[5] = ctm_3x4->matrix[6];
+ coeffs_in[6] = ctm_3x4->matrix[8];
+ coeffs_in[7] = ctm_3x4->matrix[9];
+ coeffs_in[8] = ctm_3x4->matrix[10];
+
+ coeffs_offset_in[0] = ctm_3x4->matrix[3];
+ coeffs_offset_in[1] = ctm_3x4->matrix[7];
+ coeffs_offset_in[2] = ctm_3x4->matrix[11];
+ } else {
+ struct drm_color_ctm *ctm_3x3 = (struct drm_color_ctm *)ctm;
- if (!blob)
- return;
-
- ctm = (struct drm_color_ctm *)blob->data;
- input = ctm->matrix;
+ for (i = 0; i < ARRAY_SIZE(coeffs_in); i++)
+ coeffs_in[i] = ctm_3x3->matrix[i];
+ }
for (i = 0; i < ARRAY_SIZE(coeffs); i++)
- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits);
+ coeffs[i] = mtk_ctm_s31_32_to_s1_n(coeffs_in[i], matrix_bits);
+
+ if (ctm_3x4) {
+ for (i = 0; i < ARRAY_SIZE(coeffs_offset); i++)
+ coeffs_offset[i] = mtk_ctm_s31_32_to_s1_n(coeffs_offset_in[i], matrix_bits);
+ }
mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
&ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0);
@@ -131,6 +159,56 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
&ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_3);
mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,
&ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_4);
+
+ if (ctm_3x4) {
+ val = CCORR_OFFSET_EN;
+ val |= FIELD_PREP(DISP_CCORR_OFFSET_MASK, coeffs_offset[0]);
+ mtk_ddp_write(cmdq_pkt, val, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_OFFSET_0);
+ val = FIELD_PREP(DISP_CCORR_OFFSET_MASK, coeffs_offset[1]);
+ mtk_ddp_write(cmdq_pkt, val, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_OFFSET_1);
+ val = FIELD_PREP(DISP_CCORR_OFFSET_MASK, coeffs_offset[2]);
+ mtk_ddp_write(cmdq_pkt, val, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_OFFSET_2);
+ } else {
+ mtk_ddp_write_mask(cmdq_pkt, 0, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_OFFSET_0,
+ CCORR_OFFSET_EN);
+ }
+
+ mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_CFG);
+}
+
+void mtk_ccorr_ctm_set_legacy(struct device *dev, struct drm_crtc_state *state)
+{
+ struct drm_property_blob *blob = state->ctm;
+ struct cmdq_pkt *cmdq_pkt = NULL;
+ struct drm_color_ctm *ctm;
+
+ if (!blob)
+ return;
+
+ ctm = (struct drm_color_ctm *)blob->data;
+
+ mtk_ccorr_ctm_set(dev, cmdq_pkt, ctm, false);
+}
+
+void mtk_ccorr_ctm_set_color_pipeline(struct device *dev, struct drm_color_ctm_3x4 *ctm)
+{
+ struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
+ struct cmdq_pkt *cmdq_pkt = NULL;
+
+ /* Configure block to be bypassed */
+ if (!ctm) {
+ mtk_ddp_write_mask(cmdq_pkt, CCORR_RELAY_MODE, &ccorr->cmdq_reg,
+ ccorr->regs, DISP_CCORR_CFG,
+ CCORR_RELAY_MODE | CCORR_ENGINE_EN);
+ return;
+ }
+
+ mtk_ccorr_ctm_set(dev, cmdq_pkt, ctm, true);
}
static int mtk_disp_ccorr_bind(struct device *dev, struct device *master,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 679d413bf10be1e2fc4804a60a3fbe5d734614f6..ac84cf579150fd0535c79f43ad5942f8d412d450 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -22,7 +22,8 @@ void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state);
void mtk_aal_start(struct device *dev);
void mtk_aal_stop(struct device *dev);
-void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state);
+void mtk_ccorr_ctm_set_legacy(struct device *dev, struct drm_crtc_state *state);
+void mtk_ccorr_ctm_set_color_pipeline(struct device *dev, struct drm_color_ctm_3x4 *ctm);
int mtk_ccorr_clk_enable(struct device *dev);
void mtk_ccorr_clk_disable(struct device *dev);
void mtk_ccorr_config(struct device *dev, unsigned int w,
--
2.47.2
Powered by blists - more mailing lists