drm/rockchip: vop: introduce VOP_REG_MASK
authorMark Yao <mark.yao@rock-chips.com>
Wed, 20 Apr 2016 06:18:15 +0000 (14:18 +0800)
committerSean Paul <seanpaul@chromium.org>
Tue, 23 Aug 2016 15:44:29 +0000 (11:44 -0400)
Some new vop register support mask, bit[16-31] is mask,
bit[0-15] is value, the mask is correspond to the value.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
[seanpaul masked 'v' per tfiga's review comments]
Reviewed-by: Mark Yao <mark.yao@rock-chips.com>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
drivers/gpu/drm/rockchip/rockchip_drm_vop.c
drivers/gpu/drm/rockchip/rockchip_drm_vop.h
drivers/gpu/drm/rockchip/rockchip_vop_reg.c

index 31744fe99b3880b1cf9d27266e7c76b81b8ad56d..76ad5d5d6dd64c7889c86ef728437ac7554fc166 100644 (file)
 #include "rockchip_drm_fb.h"
 #include "rockchip_drm_vop.h"
 
-#define __REG_SET_RELAXED(x, off, mask, shift, v) \
-               vop_mask_write_relaxed(x, off, (mask) << shift, (v) << shift)
-#define __REG_SET_NORMAL(x, off, mask, shift, v) \
-               vop_mask_write(x, off, (mask) << shift, (v) << shift)
+#define __REG_SET_RELAXED(x, off, mask, shift, v, write_mask) \
+               vop_mask_write(x, off, mask, shift, v, write_mask, true)
+
+#define __REG_SET_NORMAL(x, off, mask, shift, v, write_mask) \
+               vop_mask_write(x, off, mask, shift, v, write_mask, false)
 
 #define REG_SET(x, base, reg, v, mode) \
-               __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v)
+               __REG_SET_##mode(x, base + reg.offset, \
+                                reg.mask, reg.shift, v, reg.write_mask)
 #define REG_SET_MASK(x, base, reg, mask, v, mode) \
-               __REG_SET_##mode(x, base + reg.offset, mask, reg.shift, v)
+               __REG_SET_##mode(x, base + reg.offset, \
+                                mask, reg.shift, v, reg.write_mask)
 
 #define VOP_WIN_SET(x, win, name, v) \
                REG_SET(x, win->base, win->phy->name, v, RELAXED)
@@ -162,27 +165,25 @@ static inline uint32_t vop_read_reg(struct vop *vop, uint32_t base,
 }
 
 static inline void vop_mask_write(struct vop *vop, uint32_t offset,
-                                 uint32_t mask, uint32_t v)
+                                 uint32_t mask, uint32_t shift, uint32_t v,
+                                 bool write_mask, bool relaxed)
 {
-       if (mask) {
-               uint32_t cached_val = vop->regsbak[offset >> 2];
-
-               cached_val = (cached_val & ~mask) | v;
-               writel(cached_val, vop->regs + offset);
-               vop->regsbak[offset >> 2] = cached_val;
-       }
-}
+       if (!mask)
+               return;
 
-static inline void vop_mask_write_relaxed(struct vop *vop, uint32_t offset,
-                                         uint32_t mask, uint32_t v)
-{
-       if (mask) {
+       if (write_mask) {
+               v = ((v << shift) & 0xffff) | (mask << (shift + 16));
+       } else {
                uint32_t cached_val = vop->regsbak[offset >> 2];
 
-               cached_val = (cached_val & ~mask) | v;
-               writel_relaxed(cached_val, vop->regs + offset);
-               vop->regsbak[offset >> 2] = cached_val;
+               v = (cached_val & ~(mask << shift)) | ((v & mask) << shift);
+               vop->regsbak[offset >> 2] = v;
        }
+
+       if (relaxed)
+               writel_relaxed(v, vop->regs + offset);
+       else
+               writel(v, vop->regs + offset);
 }
 
 static inline uint32_t vop_get_intr_type(struct vop *vop,
index 071ff0be7a958d6cf9a16e65004737913fa87646..28dafb6b7e5125227d70a2433c09d2465ac8130c 100644 (file)
@@ -33,6 +33,7 @@ struct vop_reg {
        uint32_t offset;
        uint32_t shift;
        uint32_t mask;
+       bool write_mask;
 };
 
 struct vop_ctrl {
index 44caf14b3559d571223ee166a6c477f4d37e5603..e3f72ba5cb8a0e4cc84f1e8a3278d69e99faeca6 100644 (file)
 #define VOP_REG(off, _mask, s) \
                {.offset = off, \
                 .mask = _mask, \
-                .shift = s,}
+                .shift = s, \
+                .write_mask = false,}
+
+#define VOP_REG_MASK(off, _mask, s) \
+               {.offset = off, \
+                .mask = _mask, \
+                .shift = s, \
+                .write_mask = true,}
 
 static const uint32_t formats_win_full[] = {
        DRM_FORMAT_XRGB8888,