drm/rockchip: vop2: Read vp config done bits before change it

The config done bits of VP0, VP1, VP2 on RK3568 stands on
the first three bits on REG_CFG_DONE register without mask bit.

If two or three config done events happens one after
another in a very shot time, the flowing config done
write may override the previous config done bit before
it take effect:
 1: config done 0x8001 for VP0
 2: config done 0x8002 for VP1

 0x8002 may override 0x8001 before it take effect.

So we do a read | write here.

Change-Id: I35ad380b1c2751542697c9c7cdacea12dd08d924
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
This commit is contained in:
Andy Yan
2020-11-22 20:08:41 +08:00
committed by Tao Huang
parent ceaaf760e6
commit 2fc439df49
2 changed files with 22 additions and 1 deletions

View File

@@ -716,8 +716,28 @@ static inline void vop2_cfg_done(struct drm_crtc *crtc)
{
struct vop2_video_port *vp = to_vop2_video_port(crtc);
struct vop2 *vop2 = vp->vop2;
uint32_t done;
uint32_t val;
VOP_MODULE_SET(vop2, vp, cfg_done, 1);
/*
* This is a workaround, the config done bits of VP0,
* VP1, VP2 on RK3568 stands on the first three bits
* on REG_CFG_DONE register without mask bit.
* If two or three config done events happens one after
* another in a very shot time, the flowing config done
* write may override the previous config done bit before
* it take effect:
* 1: config done 0x8001 for VP0
* 2: config done 0x8002 for VP1
*
* 0x8002 may override 0x8001 before it take effect.
*
* So we do a read | write here.
*
*/
done = vop2_readl(vop2, 0) & 0x7;
val = RK3568_VOP2_GLB_CFG_DONE_EN | BIT(vp->id) | done;
vop2_writel(vop2, 0, val);
}
static inline void vop2_wb_cfg_done(struct vop2 *vop2)

View File

@@ -1051,6 +1051,7 @@
/* System registers definition */
#define RK3568_REG_CFG_DONE 0x000
#define RK3568_VOP2_WB_CFG_DONE BIT(14)
#define RK3568_VOP2_GLB_CFG_DONE_EN BIT(15)
#define RK3568_VERSION_INFO 0x004
#define RK3568_SYS_AUTO_GATING_CTRL 0x008
#define RK3568_DSP_IF_EN 0x028