[PATCH v7] rockchip/drm: vop2: add support for gamma LUT

Andy Yan andyshrk at 163.com
Tue Nov 5 04:30:55 PST 2024


Hi Piotr,

At 2024-11-02 03:01:17, "Piotr Zalewski" <pZ010001011111 at proton.me> wrote:
>Add support for gamma LUT in VOP2 driver. The implementation was inspired
>by one found in VOP1 driver. Blue and red channels in gamma LUT register
>write were swapped with respect to how gamma LUT values are written in
>VOP1. Gamma LUT port selection was added before the write of new gamma LUT
>table.
>
>If the current SoC is rk356x, check if no other CRTC has gamma LUT enabled
>in atomic_check (only one video port can use gamma LUT at a time) and
>disable gamma LUT before the LUT table write.
>
>If the current SoC isn't rk356x, "seamless" gamma lut update is performed
>similarly to how it was done in the case of RK3399 in VOP1[1]. In seamless
>update gamma LUT disable before the write isn't necessary, check if no
>other CRTC has gamma LUT enabled is also not necessary, different register
>is being used to select gamma LUT port[2] and after setting DSP_LUT_EN bit,
>GAMMA_UPDATE_EN bit is set[3].
>
>Gamma size is set and drm color management is enabled for each video port's
>CRTC except ones which have no associated device.
>
>Patch was tested on RK3566 (Pinetab2). When using userspace tools
>which set eg. constant color temperature no issues were noticed. When
>using userspace tools which adjust eg. color temperature the slight screen
>flicker is visible probably because of gamma LUT disable needed in the
>case of RK356x before gamma LUT write.
>
>Compare behaviour of eg.:
>```
>gammastep -O 3000
>```
>
>To eg.:
>```
>gammastep -l 53:23 -t 6000:3000
>```
>
>In latter case color temperature is slowly adjusted at the beginning which
>causes screen to slighly flicker. Then it adjusts every few seconds which
>also causes slight screen flicker.
>
>[1] https://lists.infradead.org/pipermail/linux-rockchip/2021-October/028132.html
>[2] https://lore.kernel.org/linux-rockchip/48249708-8c05-40d2-a5d8-23de960c5a77@rock-chips.com/
>[3] https://github.com/radxa/kernel/blob/linux-6.1-stan-rkr1/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c#L3437
>
>Helped-by: Daniel Stone <daniel at fooishbar.org>
>Helped-by: Dragan Simic <dsimic at manjaro.org>
>Helped-by: Diederik de Haas <didi.debian at cknow.org>
>Helped-by: Andy Yan <andy.yan at rock-chips.com>
>Signed-off-by: Piotr Zalewski <pZ010001011111 at proton.me>

    Reviewed-by: Andy Yan <andyshrk at 163.com>

>---
>
>Notes:
>    Changes in v7:
>        - Code styling changes only [6].
>
>    Changes in v6:
>        - Move gamma lut write to atomic_flush[4].
>        - In atomic_check if any other than the currently updated CRTC has
>          gamma lut enabled, return -EINVAL [5] (perform a check only if
>          device is rk356x).
>        - Instead of checking for rk3588 to determine seamless gamma
>          update availability check for rk3566/rk3568.
>        - remove null check in vop2_create_crtcs
>        - Move some code to separate functions to increase readability.
>
>    Changes in v5:
>        - Do not trigger full modeset in case seamless gamma lut update
>          isn't possible (eg. rk356x case). It was discovered that with
>          full modeset, userspace tools which adjust color temperature with
>          high frequency cause screen to go black and reduce overall
>          performance. Instead, revert to previous behaviour of lut update
>          happening in atomic_begin or (in case there is a modeset) in
>          atomic_enable. Also, add unrelated to modeset trigger
>          changes/improvements from v4 on top. Improve code readability
>          too.
>
>    Changes in v4:
>        - rework the implementation to better utilize DRM atomic updates[2]
>        - handle the RK3588 case[2][3]
>
>    Changes in v3:
>        - v3 is patch v2 "resend", by mistake the incremental patch was
>        sent in v2
>
>    Changes in v2:
>        - Apply code styling corrections[1]
>        - Move gamma LUT write inside the vop2 lock
>
>    Link to v6: https://lore.kernel.org/linux-rockchip/20241016223558.673145-2-pZ010001011111@proton.me/
>    Link to v5: https://lore.kernel.org/linux-rockchip/20241014222022.571819-4-pZ010001011111@proton.me/
>    Link to v4: https://lore.kernel.org/linux-rockchip/20240815124306.189282-2-pZ010001011111@proton.me/
>    Link to v3: https://lore.kernel.org/linux-rockchip/TkgKVivuaLFLILPY-n3iZo_8KF-daKdqdu-0_e0HP-5Ar_8DAL
>DeNWog2suwWKjX7eomcbGET0KZe7DlzdhK2YM6CbLbeKeFZr-MJzJMtw0=@proton.me/
>    Link to v2: https://lore.kernel.org/linux-rockchip/Hk03HDb6wSSHWtEFZHUye06HR0-9YzP5nCHx9A8_kHzWSZawDr
>U1o1pjEGkCOJFoRg0nTB4BWEv6V0XBOjF4-0Mj44lp2TrjaQfnytzp-Pk=@proton.me/
>    Link to v1: https://lore.kernel.org/linux-rockchip/ZVMxgcrtgHui9fJpnhbN6TSPhofHbbXElh241lImrzzTUl-8We
>jGpaR8CPzYhBgoqe_xj7N6En8Ny7Z-gsCr0kaFs7apwjYV1MBJJLmLHxs=@proton.me/
>
>    [1] https://lore.kernel.org/linux-rockchip/d019761504b540600d9fc7a585d6f95f@manjaro.org
>    [2] https://lore.kernel.org/linux-rockchip/CAPj87rOM=j0zmuWL9frGKV1xzPbJrk=Q9ip7F_HAPYnbCqPouw@mail.g
>mail.com
>    [3] https://lore.kernel.org/linux-rockchip/7d998e4c-e1d3-4e8b-af76-c5bc83b43647@rock-chips.com
>    [4] https://lore.kernel.org/linux-rockchip/7b45f190.452f.1928e41b746.Coremail.andyshrk@163.com/
>    [5] https://lore.kernel.org/linux-rockchip/CAPj87rOdQPsuH9qB_ZLfC9S=cO2noNi1mOGW0ZmQ6SHCugb9=w@mail.g
>mail.com/
>    [6] https://lore.kernel.org/linux-rockchip/6a92e23a.56c.192d5ae32d5.Coremail.andyshrk@163.com/
>
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 190 +++++++++++++++++++
> drivers/gpu/drm/rockchip/rockchip_drm_vop2.h |   5 +
> 2 files changed, 195 insertions(+)
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index 9873172e3fd3..58439ee8a52c 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -278,6 +278,15 @@ static u32 vop2_readl(struct vop2 *vop2, u32 offset)
> 	return val;
> }
> 
>+static u32 vop2_vp_read(struct vop2_video_port *vp, u32 offset)
>+{
>+	u32 val;
>+
>+	regmap_read(vp->vop2->map, vp->data->offset + offset, &val);
>+
>+	return val;
>+}
>+
> static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
> {
> 	regmap_field_write(win->reg[reg], v);
>@@ -998,6 +1007,67 @@ static void vop2_disable(struct vop2 *vop2)
> 	clk_disable_unprepare(vop2->hclk);
> }
> 
>+static bool vop2_vp_dsp_lut_is_enabled(struct vop2_video_port *vp)
>+{
>+	u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL);
>+
>+	return dsp_ctrl & RK3568_VP_DSP_CTRL__DSP_LUT_EN;
>+}
>+
>+static void vop2_vp_dsp_lut_disable(struct vop2_video_port *vp)
>+{
>+	u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL);
>+
>+	dsp_ctrl &= ~RK3568_VP_DSP_CTRL__DSP_LUT_EN;
>+	vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
>+}
>+
>+static bool vop2_vp_dsp_lut_poll_disabled(struct vop2_video_port *vp)
>+{
>+	u32 dsp_ctrl;
>+	int ret = readx_poll_timeout(vop2_vp_dsp_lut_is_enabled, vp, dsp_ctrl,
>+				!dsp_ctrl, 5, 30 * 1000);
>+	if (ret) {
>+		drm_err(vp->vop2->drm, "display LUT RAM enable timeout!\n");
>+		return false;
>+	}
>+
>+	return true;
>+}
>+
>+static void vop2_vp_dsp_lut_enable(struct vop2_video_port *vp)
>+{
>+	u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL);
>+
>+	dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_LUT_EN;
>+	vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
>+}
>+
>+static void vop2_vp_dsp_lut_update_enable(struct vop2_video_port *vp)
>+{
>+	u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL);
>+
>+	dsp_ctrl |= RK3588_VP_DSP_CTRL__GAMMA_UPDATE_EN;
>+	vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
>+}
>+



More information about the Linux-rockchip mailing list