Re: [PATCHv7 6/6] drm/rockchip: Add support for afbc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Emil,

在 2020/3/16 下午10:10, Emil Velikov 写道:
On Wed, 11 Mar 2020 at 14:56, Andrzej Pietrasiewicz
<andrzej.p@xxxxxxxxxxxxx> wrote:
This patch adds support for afbc handling. afbc is a compressed format
which reduces the necessary memory bandwidth.

Co-developed-by: Mark Yao <mark.yao@xxxxxxxxxxxxxx>
Signed-off-by: Mark Yao <mark.yao@xxxxxxxxxxxxxx>
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxxxx>
---
  drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   1 +
  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  43 +++++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 137 +++++++++++++++++++-
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  17 +++
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c |  83 +++++++++++-
  5 files changed, 276 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
index c5b06048124e..e33c2dcd0d4b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h
@@ -30,6 +30,7 @@ struct rockchip_crtc_state {
         int output_mode;
         int output_bpc;
         int output_flags;
+       bool enable_afbc;
  };
  #define to_rockchip_crtc_state(s) \
                 container_of(s, struct rockchip_crtc_state, base)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 221e72e71432..9b13c784b347 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -57,8 +57,49 @@ static const struct drm_mode_config_helper_funcs rockchip_mode_config_helpers =
         .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
  };

+static struct drm_framebuffer *
+rockchip_fb_create(struct drm_device *dev, struct drm_file *file,
+                  const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+       struct drm_afbc_framebuffer *afbc_fb;
+       const struct drm_format_info *info;
+       int ret;
+
+       info = drm_get_format_info(dev, mode_cmd);
+       if (!info)
+               return ERR_PTR(-ENOMEM);
+
+       afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL);
+       if (!afbc_fb)
+               return ERR_PTR(-ENOMEM);
+
+       ret = drm_gem_fb_init_with_funcs(dev, &afbc_fb->base, file, mode_cmd,
+                                        &rockchip_drm_fb_funcs);
+       if (ret) {
+               kfree(afbc_fb);
+               return ERR_PTR(ret);
+       }
+
+       if (drm_is_afbc(mode_cmd->modifier[0])) {
+               int ret, i;
+
+               ret = drm_gem_fb_afbc_init(dev, mode_cmd, afbc_fb);
+               if (ret) {
+                       struct drm_gem_object **obj = afbc_fb->base.obj;
+
+                       for (i = 0; i < info->num_planes; ++i)
+                               drm_gem_object_put_unlocked(obj[i]);
+
+                       kfree(afbc_fb);
+                       return ERR_PTR(ret);
+               }
+       }
+
+       return &afbc_fb->base;
+}
+
  static const struct drm_mode_config_funcs rockchip_drm_mode_config_funcs = {
-       .fb_create = drm_gem_fb_create_with_dirty,
+       .fb_create = rockchip_fb_create,
         .output_poll_changed = drm_fb_helper_output_poll_changed,
         .atomic_check = drm_atomic_helper_check,
         .atomic_commit = drm_atomic_helper_commit,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index cecb2cc781f5..b87d22eb6ae1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -91,9 +91,22 @@
  #define VOP_WIN_TO_INDEX(vop_win) \
         ((vop_win) - (vop_win)->vop->win)

+#define VOP_AFBC_SET(vop, name, v) \
+       do { \
+               if ((vop)->data->afbc) \
+                       vop_reg_set((vop), &(vop)->data->afbc->name, \
+                                   0, ~0, v, #name); \
+       } while (0)
+
  #define to_vop(x) container_of(x, struct vop, crtc)
  #define to_vop_win(x) container_of(x, struct vop_win, base)

+#define AFBC_FMT_RGB565                0x0
+#define AFBC_FMT_U8U8U8U8      0x5
+#define AFBC_FMT_U8U8U8                0x4
+
+#define AFBC_TILE_16x16                BIT(4)
+
  /*
   * The coefficients of the following matrix are all fixed points.
   * The format is S2.10 for the 3x3 part of the matrix, and S9.12 for the offsets.
@@ -274,6 +287,29 @@ static enum vop_data_format vop_convert_format(uint32_t format)
         }
  }

+static int vop_convert_afbc_format(uint32_t format)
+{
+       switch (format) {
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ABGR8888:
+               return AFBC_FMT_U8U8U8U8;
+       case DRM_FORMAT_RGB888:
+       case DRM_FORMAT_BGR888:
+               return AFBC_FMT_U8U8U8;
+       case DRM_FORMAT_RGB565:
+       case DRM_FORMAT_BGR565:
+               return AFBC_FMT_RGB565;
+       /* either of the below should not be reachable */
+       default:
+               DRM_WARN_ONCE("unsupported AFBC format[%08x]\n", format);
+               return -EINVAL;
+       }
+
+       return -EINVAL;
+}
+
  static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src,
                                   uint32_t dst, bool is_horizontal,
                                   int vsu_mode, int *vskiplines)
@@ -598,6 +634,17 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
                         vop_win_disable(vop, vop_win);
                 }
         }
+
+       if (vop->data->afbc) {
+               struct rockchip_crtc_state *s;
+               /*
+                * Disable AFBC and forget there was a vop window with AFBC
+                */
+               VOP_AFBC_SET(vop, enable, 0);
+               s = to_rockchip_crtc_state(crtc->state);
+               s->enable_afbc = false;
+       }
+
         spin_unlock(&vop->reg_lock);

         vop_cfg_done(vop);
@@ -710,6 +757,26 @@ static void vop_plane_destroy(struct drm_plane *plane)
         drm_plane_cleanup(plane);
  }

+static inline bool rockchip_afbc(u64 modifier)
+{
+       return modifier == ROCKCHIP_AFBC_MOD;
+}
+
+static bool rockchip_mod_supported(struct drm_plane *plane,
+                                  u32 format, u64 modifier)
+{
+       if (modifier == DRM_FORMAT_MOD_LINEAR)
+               return true;
+
+       if (!rockchip_afbc(modifier)) {
+               DRM_DEBUG_KMS("Unsupported format modifer 0x%llx\n", modifier);
+
+               return false;
+       }
+
+       return vop_convert_afbc_format(format) >= 0;
+}
+
  static int vop_plane_atomic_check(struct drm_plane *plane,
                            struct drm_plane_state *state)
  {
@@ -758,6 +825,30 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
                 return -EINVAL;
         }

+       if (rockchip_afbc(fb->modifier)) {
+               struct vop *vop = to_vop(crtc);
+
+               if (!vop->data->afbc) {
+                       DRM_ERROR("vop does not support AFBC\n");
+                       return -EINVAL;
+               }
+
+               ret = vop_convert_afbc_format(fb->format->format);
+               if (ret < 0)
+                       return ret;
+
+               if (state->src.x1 || state->src.y1) {
+                       DRM_ERROR("AFBC does not support offset display, xpos=%d, ypos=%d, offset=%d\n", state->src.x1, state->src.y1, fb->offsets[0]);
+                       return -EINVAL;
+               }
+
+               if (state->rotation && state->rotation != DRM_MODE_ROTATE_0) {
+                       DRM_ERROR("No rotation support in AFBC, rotation=%d\n",
+                                 state->rotation);
+                       return -EINVAL;
+               }
+       }
+
         return 0;
  }

@@ -846,6 +937,16 @@ static void vop_plane_atomic_update(struct drm_plane *plane,

         spin_lock(&vop->reg_lock);

+       if (rockchip_afbc(fb->modifier)) {
+               int afbc_format = vop_convert_afbc_format(fb->format->format);
+
+               VOP_AFBC_SET(vop, format, afbc_format | AFBC_TILE_16x16);
+               VOP_AFBC_SET(vop, hreg_block_split, 0);
+               VOP_AFBC_SET(vop, win_sel, VOP_WIN_TO_INDEX(vop_win));
+               VOP_AFBC_SET(vop, hdr_ptr, dma_addr);
+               VOP_AFBC_SET(vop, pic_size, act_info);
+       }
+
         VOP_WIN_SET(vop, win, format, format);
         VOP_WIN_SET(vop, win, yrgb_vir, DIV_ROUND_UP(fb->pitches[0], 4));
         VOP_WIN_SET(vop, win, yrgb_mst, dma_addr);
@@ -1001,6 +1102,7 @@ static const struct drm_plane_funcs vop_plane_funcs = {
         .reset = drm_atomic_helper_plane_reset,
         .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
         .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+       .format_mod_supported = rockchip_mod_supported,
  };

  static int vop_crtc_enable_vblank(struct drm_crtc *crtc)
@@ -1310,6 +1412,10 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc,
                                  struct drm_crtc_state *crtc_state)
  {
         struct vop *vop = to_vop(crtc);
+       struct drm_plane *plane;
+       struct drm_plane_state *plane_state;
+       struct rockchip_crtc_state *s;
+       int afbc_planes = 0;

         if (vop->lut_regs && crtc_state->color_mgmt_changed &&
             crtc_state->gamma_lut) {
@@ -1323,6 +1429,27 @@ static int vop_crtc_atomic_check(struct drm_crtc *crtc,
                 }
         }

+       drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+               plane_state =
+                       drm_atomic_get_plane_state(crtc_state->state, plane);
+               if (IS_ERR(plane_state)) {
+                       DRM_DEBUG_KMS("Cannot get plane state for plane %s\n",
+                                     plane->name);
+                       return PTR_ERR(plane_state);
+               }
+
+               if (drm_is_afbc(plane_state->fb->modifier))
+                       ++afbc_planes;
+       }
+
+       if (afbc_planes > 1) {
+               DRM_DEBUG_KMS("Invalid number of AFBC planes; got %d, expected at most 1\n", afbc_planes);
+               return -EINVAL;
+       }
+
+       s = to_rockchip_crtc_state(crtc_state);
+       s->enable_afbc = afbc_planes > 0;
+
         return 0;
  }

@@ -1333,6 +1460,7 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,
         struct drm_plane_state *old_plane_state, *new_plane_state;
         struct vop *vop = to_vop(crtc);
         struct drm_plane *plane;
+       struct rockchip_crtc_state *s;
         int i;

         if (WARN_ON(!vop->is_enabled))
@@ -1340,6 +1468,9 @@ static void vop_crtc_atomic_flush(struct drm_crtc *crtc,

         spin_lock(&vop->reg_lock);

+       /* Enable AFBC if there is some AFBC window, disable otherwise. */
+       s = to_rockchip_crtc_state(crtc->state);
+       VOP_AFBC_SET(vop, enable, s->enable_afbc);
         vop_cfg_done(vop);

         spin_unlock(&vop->reg_lock);
@@ -1634,7 +1765,8 @@ static int vop_create_crtc(struct vop *vop)
                                                0, &vop_plane_funcs,
                                                win_data->phy->data_formats,
                                                win_data->phy->nformats,
-                                              NULL, win_data->type, NULL);
+                                              win_data->phy->format_modifiers,
+                                              win_data->type, NULL);
                 if (ret) {
                         DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
                                       ret);
@@ -1678,7 +1810,8 @@ static int vop_create_crtc(struct vop *vop)
                                                &vop_plane_funcs,
                                                win_data->phy->data_formats,
                                                win_data->phy->nformats,
-                                              NULL, win_data->type, NULL);
+                                              win_data->phy->format_modifiers,
+                                              win_data->type, NULL);
                 if (ret) {
                         DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
                                       ret);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index cc672620d6e0..d03bdb531ef2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -17,6 +17,11 @@

  #define NUM_YUV2YUV_COEFFICIENTS 12

+#define ROCKCHIP_AFBC_MOD \
+       DRM_FORMAT_MOD_ARM_AFBC( \
+               AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE \
+       )
+
  enum vop_data_format {
         VOP_FMT_ARGB8888 = 0,
         VOP_FMT_RGB888,
@@ -34,6 +39,16 @@ struct vop_reg {
         bool relaxed;
  };

+struct vop_afbc {
+       struct vop_reg enable;
+       struct vop_reg win_sel;
+       struct vop_reg format;
+       struct vop_reg hreg_block_split;
+       struct vop_reg pic_size;
+       struct vop_reg hdr_ptr;
+       struct vop_reg rstn;
+};
+
  struct vop_modeset {
         struct vop_reg htotal_pw;
         struct vop_reg hact_st_end;
@@ -134,6 +149,7 @@ struct vop_win_phy {
         const struct vop_scl_regs *scl;
         const uint32_t *data_formats;
         uint32_t nformats;
+       const uint64_t *format_modifiers;

         struct vop_reg enable;
         struct vop_reg gate;
@@ -173,6 +189,7 @@ struct vop_data {
         const struct vop_misc *misc;
         const struct vop_modeset *modeset;
         const struct vop_output *output;
+       const struct vop_afbc *afbc;
         const struct vop_win_yuv2yuv_data *win_yuv2yuv;
         const struct vop_win_data *win;
         unsigned int win_size;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 7a9d979c8d5d..2413deded22c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -50,6 +50,17 @@ static const uint32_t formats_win_full[] = {
         DRM_FORMAT_NV24,
  };

+static const uint64_t format_modifiers_win_full[] = {
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID,
+};
+
+static const uint64_t format_modifiers_win_full_afbc[] = {
+       ROCKCHIP_AFBC_MOD,
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID,
+};
+
  static const uint32_t formats_win_lite[] = {
         DRM_FORMAT_XRGB8888,
         DRM_FORMAT_ARGB8888,
@@ -61,6 +72,11 @@ static const uint32_t formats_win_lite[] = {
         DRM_FORMAT_BGR565,
  };

+static const uint64_t format_modifiers_win_lite[] = {
+       DRM_FORMAT_MOD_LINEAR,
+       DRM_FORMAT_MOD_INVALID,
+};
+
  static const struct vop_scl_regs rk3036_win_scl = {
         .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
         .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
@@ -72,6 +88,7 @@ static const struct vop_win_phy rk3036_win0_data = {
         .scl = &rk3036_win_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
@@ -87,6 +104,7 @@ static const struct vop_win_phy rk3036_win0_data = {
  static const struct vop_win_phy rk3036_win1_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
@@ -153,6 +171,7 @@ static const struct vop_data rk3036_vop = {
  static const struct vop_win_phy rk3126_win1_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
         .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
         .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
@@ -234,6 +253,7 @@ static const struct vop_win_phy px30_win0_data = {
         .scl = &px30_win_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
         .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
         .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
@@ -249,6 +269,7 @@ static const struct vop_win_phy px30_win0_data = {
  static const struct vop_win_phy px30_win1_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
         .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
         .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
@@ -261,6 +282,7 @@ static const struct vop_win_phy px30_win1_data = {
  static const struct vop_win_phy px30_win2_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
         .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
         .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
@@ -316,6 +338,7 @@ static const struct vop_win_phy rk3066_win0_data = {
         .scl = &rk3066_win_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4),
         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19),
@@ -332,6 +355,7 @@ static const struct vop_win_phy rk3066_win1_data = {
         .scl = &rk3066_win_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7),
         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23),
@@ -347,6 +371,7 @@ static const struct vop_win_phy rk3066_win1_data = {
  static const struct vop_win_phy rk3066_win2_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2),
         .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10),
         .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27),
@@ -426,6 +451,7 @@ static const struct vop_win_phy rk3188_win0_data = {
         .scl = &rk3188_win_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
@@ -440,6 +466,7 @@ static const struct vop_win_phy rk3188_win0_data = {
  static const struct vop_win_phy rk3188_win1_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
         .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
         .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
@@ -545,6 +572,7 @@ static const struct vop_win_phy rk3288_win01_data = {
         .scl = &rk3288_win_full_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
         .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
         .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
@@ -563,6 +591,7 @@ static const struct vop_win_phy rk3288_win01_data = {
  static const struct vop_win_phy rk3288_win23_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
         .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
         .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
@@ -677,6 +706,7 @@ static const struct vop_win_phy rk3368_win01_data = {
         .scl = &rk3288_win_full_scl,
         .data_formats = formats_win_full,
         .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full,
         .enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
         .format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
         .rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
@@ -697,6 +727,7 @@ static const struct vop_win_phy rk3368_win01_data = {
  static const struct vop_win_phy rk3368_win23_data = {
         .data_formats = formats_win_lite,
         .nformats = ARRAY_SIZE(formats_win_lite),
+       .format_modifiers = format_modifiers_win_lite,
         .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
         .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
         .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
@@ -817,6 +848,53 @@ static const struct vop_win_yuv2yuv_data rk3399_vop_big_win_yuv2yuv_data[] = {
           .y2r_en = VOP_REG(RK3399_YUV2YUV_WIN, 0x1, 9) },
         { .base = 0xC0, .phy = &rk3399_yuv2yuv_win23_data },
         { .base = 0x120, .phy = &rk3399_yuv2yuv_win23_data },
+
+};
+
+static const struct vop_win_phy rk3399_win01_data = {
+       .scl = &rk3288_win_full_scl,
+       .data_formats = formats_win_full,
+       .nformats = ARRAY_SIZE(formats_win_full),
+       .format_modifiers = format_modifiers_win_full_afbc,
+       .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
+       .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
+       .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+       .y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
+       .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
+       .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
+       .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
+       .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
+       .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
+       .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
+       .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
+       .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
+       .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
+};
+
+/*
+ * rk3399 vop big windows register layout is same as rk3288, but we
+ * have a separate rk3399 win data array here so that we can advertise
+ * AFBC on the primary plane.
+ */
+static const struct vop_win_data rk3399_vop_win_data[] = {
+       { .base = 0x00, .phy = &rk3399_win01_data,
+         .type = DRM_PLANE_TYPE_PRIMARY },
+       { .base = 0x40, .phy = &rk3288_win01_data,
+         .type = DRM_PLANE_TYPE_OVERLAY },
+       { .base = 0x00, .phy = &rk3288_win23_data,
+         .type = DRM_PLANE_TYPE_OVERLAY },
+       { .base = 0x50, .phy = &rk3288_win23_data,
+         .type = DRM_PLANE_TYPE_CURSOR },
+};
+
+static const struct vop_afbc rk3399_vop_afbc = {
+       .rstn = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 3),
+       .enable = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 0),
+       .win_sel = VOP_REG(RK3399_AFBCD0_CTRL, 0x3, 1),
+       .format = VOP_REG(RK3399_AFBCD0_CTRL, 0x1f, 16),
+       .hreg_block_split = VOP_REG(RK3399_AFBCD0_CTRL, 0x1, 21),
+       .hdr_ptr = VOP_REG(RK3399_AFBCD0_HDR_PTR, 0xffffffff, 0),
+       .pic_size = VOP_REG(RK3399_AFBCD0_PIC_SIZE, 0xffffffff, 0),
  };

  static const struct vop_data rk3399_vop_big = {
@@ -826,9 +904,10 @@ static const struct vop_data rk3399_vop_big = {
         .common = &rk3288_common,
         .modeset = &rk3288_modeset,
         .output = &rk3399_output,
+       .afbc = &rk3399_vop_afbc,
         .misc = &rk3368_misc,
-       .win = rk3368_vop_win_data,
-       .win_size = ARRAY_SIZE(rk3368_vop_win_data),
+       .win = rk3399_vop_win_data,
+       .win_size = ARRAY_SIZE(rk3399_vop_win_data),
         .win_yuv2yuv = rk3399_vop_big_win_yuv2yuv_data,
  };

--
2.17.1
Heiko, Sandy, being the maintainers of the Rockchip driver, can you
review/ack this patch?

I believe the intention is to merge the series via drm-misc. Andrzej
already has commit access.

-Emil


Thanks for you patch, maybe we need to consider the compatibility with px30 platform afbc features,the main difference is:

1.  px30 support x offset and y offset display, and the state->src.x1 / state->src.y1  should be alibegned as 16pixel/line;

2.px30 only win1 can support afbdc format;


_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/dri-devel




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux