From nobody Thu Oct 2 11:50:25 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD1CF1E1E1B for ; Thu, 18 Sep 2025 00:45:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758156316; cv=none; b=qCp7jNN57N4j6uvm6RAlnQWI9EtRdnIHc+7CPx2ujD+4YcCiwbVJ3GsXiLSw8BPPMprDNjsBF3EUca2nspK155MXlEzWRm2zYihY1K0XnEAdFgqWfudcwUVOJ8bLrUgoDD2ZnMP4hnFyDf4fW9PvJcVXeGdb5t5yztxVv7ldMhE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758156316; c=relaxed/simple; bh=AeLBQl03qAG/0Pv36jLJWBzJBntn596lkNvH2nd0VLc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rTLi+VtuMYeXoO9BfuZzIZIlmv6pImUqRbZzYdP35cOE1Nw5SfGdnD7de6dSHQP6X72YMMJRq9712YPSB8XZKmipM7VJCRDCoFwgo1tlp9ObErzPoy/kV9A2A/gCs5tVYxr/JcfFxmC4eHFVYmKWbpgx65XuZQVX5JndFHc+ZwY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=bYIDfJT0; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="bYIDfJT0" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1758156312; bh=AeLBQl03qAG/0Pv36jLJWBzJBntn596lkNvH2nd0VLc=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bYIDfJT00GucC0EwmTtTdzTFuVVPsx1f+fzkoTrJ45tOjz7pBaoS1to6gcapNZ1N6 LOCpMYPZBy7n/VwxDztfDbH+mTq9iyZ5tyJ30yO8EKKE7P8YBU8IjkMxT9bRPWoRpy MXNo2n9h+7Ijh9rYK8UI4XF+nORZu2hUhyGXgAUL4DhPWnKhsXbWHAJN40rFyeqbLZ MGnGbPX5+RNj4Br+Xp8VOYx6O6oh7/Bg+wblfDXsoGXCVi3p5vW7yr/GNHPkkhQdmK 7E8Y+vlmso5ggQnTX5I2bpXRmqOHNk8t5QKSobARKJWl0fu5aFK+Ui3Ih145jVb5q1 SI2E/YkgjNe0g== Received: from [127.0.1.1] (unknown [IPv6:2600:4041:5b1a:9400:62f0:406e:ac79:4a96]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nfraprado) by bali.collaboradmins.com (Postfix) with ESMTPSA id 9E9B417E130F; Thu, 18 Sep 2025 02:45:04 +0200 (CEST) From: =?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?= Date: Wed, 17 Sep 2025 20:43:24 -0400 Subject: [PATCH RFC v2 15/20] drm/mediatek: gamma: Support post-blend color pipeline API Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250917-mtk-post-blend-color-pipeline-v2-15-ac4471b44758@collabora.com> References: <20250917-mtk-post-blend-color-pipeline-v2-0-ac4471b44758@collabora.com> In-Reply-To: <20250917-mtk-post-blend-color-pipeline-v2-0-ac4471b44758@collabora.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Chun-Kuang Hu , Philipp Zabel , Matthias Brugger , AngeloGioacchino Del Regno , Haneen Mohammed , Melissa Wen Cc: Alex Hung , wayland-devel@lists.freedesktop.org, harry.wentland@amd.com, leo.liu@amd.com, ville.syrjala@linux.intel.com, pekka.paalanen@collabora.com, contact@emersion.fr, mwen@igalia.com, jadahl@redhat.com, sebastian.wick@redhat.com, shashank.sharma@amd.com, agoins@nvidia.com, joshua@froggi.es, mdaenzer@redhat.com, aleixpol@kde.org, xaver.hugl@gmail.com, victoria@system76.com, uma.shankar@intel.com, quic_naseer@quicinc.com, quic_cbraga@quicinc.com, quic_abhinavk@quicinc.com, marcan@marcan.st, Liviu.Dudau@arm.com, sashamcintosh@google.com, chaitanya.kumar.borah@intel.com, louis.chauvet@bootlin.com, mcanal@igalia.com, kernel@collabora.com, daniels@collabora.com, leandro.ribeiro@collabora.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-mediatek@lists.infradead.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?N=C3=ADcolas_F=2E_R=2E_A=2E_Prado?= , Simona Vetter X-Mailer: b4 0.14.2 Implement the gamma_set_color_pipeline DDP component function to allow configuring the gamma LUT through the post-blend color pipeline API. The color pipeline API uses a 32-bit long, rather than 16-bit long, LUT, so also update the functions to handle both cases. Also make sure to enable or disable the LUT function depending on whether the block should be bypassed or not. Signed-off-by: N=C3=ADcolas F. R. A. Prado --- drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 3 +- drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +- drivers/gpu/drm/mediatek/mtk_disp_gamma.c | 107 +++++++++++++++++++++++++-= ---- 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/medi= atek/mtk_ddp_comp.c index c873b527423f51733058cbc3d0ad2a719e26bfe1..d253906546506ecf1f1e2a23123= b80e774e981ae 100644 --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c @@ -327,7 +327,8 @@ static const struct mtk_ddp_comp_funcs ddp_gamma =3D { .clk_enable =3D mtk_gamma_clk_enable, .clk_disable =3D mtk_gamma_clk_disable, .gamma_get_lut_size =3D mtk_gamma_get_lut_size, - .gamma_set =3D mtk_gamma_set, + .gamma_set =3D mtk_gamma_set_legacy, + .gamma_set_color_pipeline =3D mtk_gamma_set_color_pipeline, .config =3D mtk_gamma_config, .start =3D mtk_gamma_start, .stop =3D mtk_gamma_stop, diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/medi= atek/mtk_disp_drv.h index ac84cf579150fd0535c79f43ad5942f8d412d450..7795aa5bc057fc09597cbd582f0= 4e4dc76d3ecba 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h @@ -58,7 +58,8 @@ void mtk_gamma_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt); unsigned int mtk_gamma_get_lut_size(struct device *dev); -void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state); +void mtk_gamma_set_legacy(struct device *dev, struct drm_crtc_state *state= ); +void mtk_gamma_set_color_pipeline(struct device *dev, struct drm_color_lut= 32 *lut); void mtk_gamma_start(struct device *dev); void mtk_gamma_stop(struct device *dev); =20 diff --git a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c b/drivers/gpu/drm/me= diatek/mtk_disp_gamma.c index 8afd15006df2a21f3f52fe00eca3c5501f4fb76a..dec9eeb53cb8539e49ecc1087e0= 37645c792ee3d 100644 --- a/drivers/gpu/drm/mediatek/mtk_disp_gamma.c +++ b/drivers/gpu/drm/mediatek/mtk_disp_gamma.c @@ -87,13 +87,34 @@ unsigned int mtk_gamma_get_lut_size(struct device *dev) return 0; } =20 -static bool mtk_gamma_lut_is_descending(struct drm_color_lut *lut, u32 lut= _size) +static bool mtk_gamma_lut_is_descending(void *lut, bool bits32, u32 lut_si= ze) { u64 first, last; int last_entry =3D lut_size - 1; + u32 lutr_first, lutg_first, lutb_first, lutr_last, lutg_last, lutb_last; + struct drm_color_lut32 *lut32; + struct drm_color_lut *lut16; + + if (bits32) { + lut32 =3D (struct drm_color_lut32 *)lut; + lutr_first =3D lut32[0].red; + lutg_first =3D lut32[0].green; + lutb_first =3D lut32[0].blue; + lutr_last =3D lut32[last_entry].red; + lutg_last =3D lut32[last_entry].green; + lutb_last =3D lut32[last_entry].blue; + } else { + lut16 =3D (struct drm_color_lut *)lut; + lutr_first =3D lut16[0].red; + lutg_first =3D lut16[0].green; + lutb_first =3D lut16[0].blue; + lutr_last =3D lut16[last_entry].red; + lutg_last =3D lut16[last_entry].green; + lutb_last =3D lut16[last_entry].blue; + } =20 - first =3D lut[0].red + lut[0].green + lut[0].blue; - last =3D lut[last_entry].red + lut[last_entry].green + lut[last_entry].bl= ue; + first =3D lutr_first + lutg_first + lutb_first; + last =3D lutr_last + lutg_last + lutb_last; =20 return !!(first > last); } @@ -113,7 +134,7 @@ static bool mtk_gamma_lut_is_descending(struct drm_colo= r_lut *lut, u32 lut_size) * - 12-bits LUT supported * - 10-its LUT not supported */ -void mtk_gamma_set(struct device *dev, struct drm_crtc_state *state) +static void mtk_gamma_set(struct device *dev, void *lut, bool bits32) { struct mtk_disp_gamma *gamma =3D dev_get_drvdata(dev); void __iomem *lut0_base =3D gamma->regs + DISP_GAMMA_LUT; @@ -121,19 +142,20 @@ void mtk_gamma_set(struct device *dev, struct drm_crt= c_state *state) u32 cfg_val, data_mode, lbank_val, word[2]; u8 lut_bits =3D gamma->data->lut_bits; int cur_bank, num_lut_banks; - struct drm_color_lut *lut; unsigned int i; - - /* If there's no gamma lut there's nothing to do here. */ - if (!state->gamma_lut) - return; + struct drm_color_lut32 *lut32; + struct drm_color_lut *lut16; =20 num_lut_banks =3D gamma->data->lut_size / gamma->data->lut_bank_size; - lut =3D (struct drm_color_lut *)state->gamma_lut->data; =20 /* Switch to 12 bits data mode if supported */ data_mode =3D FIELD_PREP(DISP_GAMMA_BANK_DATA_MODE, !!(lut_bits =3D=3D 12= )); =20 + if (bits32) + lut32 =3D (struct drm_color_lut32 *)lut; + else + lut16 =3D (struct drm_color_lut *)lut; + for (cur_bank =3D 0; cur_bank < num_lut_banks; cur_bank++) { =20 /* Switch gamma bank and set data mode before writing LUT */ @@ -146,10 +168,21 @@ void mtk_gamma_set(struct device *dev, struct drm_crt= c_state *state) for (i =3D 0; i < gamma->data->lut_bank_size; i++) { int n =3D cur_bank * gamma->data->lut_bank_size + i; struct drm_color_lut diff, hwlut; + u32 lutr, lutg, lutb; + + if (bits32) { + lutr =3D lut32[n].red; + lutg =3D lut32[n].green; + lutb =3D lut32[n].blue; + } else { + lutr =3D lut16[n].red; + lutg =3D lut16[n].green; + lutb =3D lut16[n].blue; + } =20 - hwlut.red =3D drm_color_lut_extract(lut[n].red, lut_bits); - hwlut.green =3D drm_color_lut_extract(lut[n].green, lut_bits); - hwlut.blue =3D drm_color_lut_extract(lut[n].blue, lut_bits); + hwlut.red =3D drm_color_lut_extract(lutr, lut_bits); + hwlut.green =3D drm_color_lut_extract(lutg, lut_bits); + hwlut.blue =3D drm_color_lut_extract(lutb, lut_bits); =20 if (!gamma->data->lut_diff || (i % 2 =3D=3D 0)) { if (lut_bits =3D=3D 12) { @@ -162,13 +195,25 @@ void mtk_gamma_set(struct device *dev, struct drm_crt= c_state *state) word[0] |=3D FIELD_PREP(DISP_GAMMA_LUT_10BIT_B, hwlut.blue); } } else { - diff.red =3D lut[n].red - lut[n - 1].red; + u32 lutr_prev, lutg_prev, lutb_prev; + + if (bits32) { + lutr_prev =3D lut32[n-1].red; + lutg_prev =3D lut32[n-1].green; + lutb_prev =3D lut32[n-1].blue; + } else { + lutr_prev =3D lut16[n-1].red; + lutg_prev =3D lut16[n-1].green; + lutb_prev =3D lut16[n-1].blue; + } + + diff.red =3D lutr - lutr_prev; diff.red =3D drm_color_lut_extract(diff.red, lut_bits); =20 - diff.green =3D lut[n].green - lut[n - 1].green; + diff.green =3D lutg - lutg_prev; diff.green =3D drm_color_lut_extract(diff.green, lut_bits); =20 - diff.blue =3D lut[n].blue - lut[n - 1].blue; + diff.blue =3D lutb - lutb_prev; diff.blue =3D drm_color_lut_extract(diff.blue, lut_bits); =20 if (lut_bits =3D=3D 12) { @@ -191,7 +236,7 @@ void mtk_gamma_set(struct device *dev, struct drm_crtc_= state *state) =20 if (!gamma->data->has_dither) { /* Descending or Rising LUT */ - if (mtk_gamma_lut_is_descending(lut, gamma->data->lut_size - 1)) + if (mtk_gamma_lut_is_descending(lut, bits32, gamma->data->lut_size - 1)) cfg_val |=3D FIELD_PREP(GAMMA_LUT_TYPE, 1); else cfg_val &=3D ~GAMMA_LUT_TYPE; @@ -206,6 +251,34 @@ void mtk_gamma_set(struct device *dev, struct drm_crtc= _state *state) writel(cfg_val, gamma->regs + DISP_GAMMA_CFG); } =20 +void mtk_gamma_set_legacy(struct device *dev, struct drm_crtc_state *state) +{ + struct drm_color_lut *lut =3D (struct drm_color_lut *)state->gamma_lut->d= ata; + + /* If there's no gamma lut there's nothing to do here. */ + if (!state->gamma_lut) + return; + + mtk_gamma_set(dev, lut, false); +} + +void mtk_gamma_set_color_pipeline(struct device *dev, struct drm_color_lut= 32 *lut) +{ + struct mtk_disp_gamma *gamma =3D dev_get_drvdata(dev); + u32 cfg_val; + + /* Configure block to be bypassed */ + if (!lut) { + cfg_val =3D readl(gamma->regs + DISP_GAMMA_CFG); + cfg_val &=3D ~GAMMA_LUT_EN; + cfg_val |=3D GAMMA_RELAY_MODE; + writel(cfg_val, gamma->regs + DISP_GAMMA_CFG); + return; + } + + mtk_gamma_set(dev, lut, true); +} + void mtk_gamma_config(struct device *dev, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) --=20 2.50.1