HI Piotr,

在 2025-06-19 19:54:12,"Piotr Zalewski" <pz010001011...@proton.me> 写道:
>Hi Andy
>
>> 
>> The root case for the problem is now clear。
>> 
>> Most of the registers in VOP need to write the cfd_done register(call 
>> vop2_cfg_done)
>> after you have configured the registers. Then, they will take effect only 
>> when the VSYNC event occurs(It doesn't take effect immediately after you 
>> finish writing.).
>> This also includes all the VP_DSP_CTRL registers.
>> 
>> see the code:
>> 
>> vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
>> 
>> vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state);
>> -->
>> 
>> static void vop2_vp_dsp_lut_disable(struct vop2_video_port vp)
>> {
>> u32 dsp_ctrl = vop2_vp_read(vp, RK3568_VP_DSP_CTRL);
>> 
>> 
>> When we read this register, we are reading the actual effective value,
>> not the one(dsp_ctrl) that was just written in before (it has not yet taken 
>> effect)
>> 
>> So when we continue to write about this register here, we overwrite the 
>> actual
>> value we originally intended to put in.
>> 
>> 
>> dsp_ctrl &= ~RK3568_VP_DSP_CTRL__DSP_LUT_EN;
>> vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
>> }
>> 
>> I think the correct solution should be similar to the Windows-related 
>> registry settings.
>> All the registers related to Video Ports should be set as non-volatile, see:
>> 
>> /
>> * The window registers are only updated when config done is written.
>> * Until that they read back the old value. As we read-modify-write
>> * these registers mark them as non-volatile. This makes sure we read
>> * the new values from the regmap register cache.
>> */
>> static const struct regmap_range vop2_nonvolatile_range[] = {
>> regmap_reg_range(0x1000, 0x23ff),
>> };
>> 
>> static const struct regmap_access_table vop2_volatile_table = {
>> .no_ranges = vop2_nonvolatile_range,
>> .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range),
>> };
>
>Following your suggestion I added vop2 video port registers as not
>volatile and it fixed the issue. I took the values from RK3588 TRM
>Part2 V1.1. See the patch below and confirm if it is correct.
>
>diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
>b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>index d0f5fea15e21..c5c1910fa5ca 100644
>--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>@@ -2596,6 +2596,7 @@ static int vop2_win_init(struct vop2 *vop2)
>  */
> static const struct regmap_range vop2_nonvolatile_range[] = {
>       regmap_reg_range(0x1000, 0x23ff),
>+      regmap_reg_range(0x0C00, 0x0fff),
> };
> 

For a complete solution, the registers of all four Video Ports should all be
marked as non-volatile.
And they should be arranged in ascending order of address size, so they
should be placed before 0x1000.

Additionally, the comments here should also be updated accordingly.


#define RK3568_VP0_CTRL_BASE                    0x0C00
#define RK3568_VP1_CTRL_BASE                    0x0D00
#define RK3568_VP2_CTRL_BASE                    0x0E00
#define RK3588_VP3_CTRL_BASE                    0x0F00

> static const struct regmap_access_table vop2_volatile_table = {
>
>
>> Actually, there is another question. I still haven't figured out why
>> this problem doesn't occur when compiling rockchipdrm=y .
>
>Couldn't reason out why this only happens with drm=m yet
>unfortunately.

This should eventually lead to an answer. However, I've been quite busy recently
and haven't had time to conduct further analysis yet. I will incorporate it 
into my TODO list.


>
>Best regards, Piotr Zalewski

Reply via email to