g2d: add support for YCbCr 10-bit of Exynos9820
authorCho KyongHo <pullip.cho@samsung.com>
Wed, 11 Apr 2018 07:39:03 +0000 (16:39 +0900)
committerSeungchul Kim <sc377.kim@samsung.com>
Mon, 28 May 2018 05:28:11 +0000 (14:28 +0900)
YCbCr 10-bit configuration to REG_LAYERX_COLORMODE of exynos9820 is
different from exynos9810. Since G2D driver uses the values to the
register as color format values, changes in the bitfields of
REG_LAYERX_COLORMODE also impacts to color format values.

Change-Id: I7e6bb03601db3aa3e34316a51070abd92d878832
Signed-off-by: Cho KyongHo <pullip.cho@samsung.com>
drivers/gpu/exynos/g2d/g2d.h
drivers/gpu/exynos/g2d/g2d_command.c
drivers/gpu/exynos/g2d/g2d_command.h
drivers/gpu/exynos/g2d/g2d_drv.c
drivers/gpu/exynos/g2d/g2d_format.h
drivers/gpu/exynos/g2d/g2d_uapi_process.c

index 4e5ad05c05b4b552f746f8aa59abbd3840c12c0a..b7f6f19c0322f559c02ddab9a0e74265016fed7f 100644 (file)
@@ -72,10 +72,10 @@ struct g2d_dvfs_table {
        u32 freq;
 };
 
-/*
- * Proved that G2D does not leak protected conents that it is processing.
- */
+/* Proved that G2D does not leak protected conents that it is processing. */
 #define G2D_DEVICE_CAPS_SELF_PROTECTION                1
+/* Separate bitfield to select YCbCr Bitdepth at REG_COLORMODE[29:28] */
+#define G2D_DEVICE_CAPS_YUV_BITDEPTH           2
 
 struct g2d_device {
        unsigned long           state;
index b4928c45fbea44bc0aed28333d1142f83ea6930c..9999d3c033b09af51d7561944658281212544e02 100644 (file)
@@ -160,7 +160,7 @@ void g2d_complete_commands(struct g2d_task *task)
        g2d_set_start_commands(task);
 }
 
-static const struct g2d_fmt g2d_formats[] = {
+static const struct g2d_fmt g2d_formats_common[] = {
        {
                .name           = "ARGB8888",
                .fmtvalue       = G2D_FMT_ARGB8888,     /* [31:0] ARGB */
@@ -216,26 +216,6 @@ static const struct g2d_fmt g2d_formats[] = {
                .fmtvalue       = G2D_FMT_NV21,
                .bpp            = { 8, 4 },
                .num_planes     = 2,
-       }, {
-               .name           = "NV12_8+2",
-               .fmtvalue       = G2D_FMT_NV12_82,
-               .bpp            = { 8, 2, 4, 1 },
-               .num_planes     = 4,
-       }, {
-               .name           = "NV21_8+2",
-               .fmtvalue       = G2D_FMT_NV21_82,
-               .bpp            = { 8, 2, 4, 1 },
-               .num_planes     = 4,
-       }, {
-               .name           = "NV12_P010",
-               .fmtvalue       = G2D_FMT_NV12_P010,
-               .bpp            = { 16, 8},
-               .num_planes     = 2,
-       }, {
-               .name           = "NV21N_P010",
-               .fmtvalue       = G2D_FMT_NV21_P010,
-               .bpp            = { 16, 8},
-               .num_planes     = 2,
        }, {
                .name           = "YUYV",
                .fmtvalue       = G2D_FMT_YUYV,
@@ -274,14 +254,81 @@ static const struct g2d_fmt g2d_formats[] = {
        },
 };
 
-const struct g2d_fmt *g2d_find_format(u32 fmtval)
+static const struct g2d_fmt g2d_formats_9810[] = {
+       {
+               .name           = "NV12_8+2",
+               .fmtvalue       = G2D_FMT_NV12_82_9810,
+               .bpp            = { 8, 2, 4, 1 },
+               .num_planes     = 4,
+       }, {
+               .name           = "NV21_8+2",
+               .fmtvalue       = G2D_FMT_NV21_82_9810,
+               .bpp            = { 8, 2, 4, 1 },
+               .num_planes     = 4,
+       }, {
+               .name           = "NV12_P010",
+               .fmtvalue       = G2D_FMT_NV12_P010_9810,
+               .bpp            = { 16, 8},
+               .num_planes     = 2,
+       }, {
+               .name           = "NV21_P010",
+               .fmtvalue       = G2D_FMT_NV21_P010_9810,
+               .bpp            = { 16, 8},
+               .num_planes     = 2,
+       },
+};
+
+static const struct g2d_fmt g2d_formats_9820[] = {
+       {
+               .name           = "NV12_8+2",
+               .fmtvalue       = G2D_FMT_NV12_82_9820,
+               .bpp            = { 8, 2, 4, 1 },
+               .num_planes     = 4,
+       }, {
+               .name           = "NV21_8+2",
+               .fmtvalue       = G2D_FMT_NV21_82_9820,
+               .bpp            = { 8, 2, 4, 1 },
+               .num_planes     = 4,
+       }, {
+               .name           = "NV12_P010",
+               .fmtvalue       = G2D_FMT_NV12_P010_9820,
+               .bpp            = { 16, 8},
+               .num_planes     = 2,
+       }, {
+               .name           = "NV21_P010",
+               .fmtvalue       = G2D_FMT_NV21_P010_9820,
+               .bpp            = { 16, 8},
+               .num_planes     = 2,
+       }, {
+               .name           = "NV16_P210",
+               .fmtvalue       = G2D_FMT_NV16_P210_9820,
+               .bpp            = { 16, 16},
+               .num_planes     = 2,
+       }, {
+               .name           = "NV61_P210",
+               .fmtvalue       = G2D_FMT_NV61_P210_9820,
+               .bpp            = { 16, 16},
+               .num_planes     = 2,
+       },
+};
+
+const struct g2d_fmt *g2d_find_format(u32 fmtval, unsigned long devcaps)
 {
        size_t i;
 
-       for (i = 0; i < ARRAY_SIZE(g2d_formats); i++)
-               if (g2d_formats[i].fmtvalue == G2D_IMGFMT(fmtval))
-                       return &g2d_formats[i];
+       for (i = 0; i < ARRAY_SIZE(g2d_formats_common); i++)
+               if (g2d_formats_common[i].fmtvalue == G2D_IMGFMT(fmtval))
+                       return &g2d_formats_common[i];
 
+       if (!(devcaps & G2D_DEVICE_CAPS_YUV_BITDEPTH)) {
+               for (i = 0; i < ARRAY_SIZE(g2d_formats_9810); i++)
+                       if (g2d_formats_9810[i].fmtvalue == G2D_IMGFMT(fmtval))
+                               return &g2d_formats_9810[i];
+       } else {
+               for (i = 0; i < ARRAY_SIZE(g2d_formats_9820); i++)
+                       if (g2d_formats_9820[i].fmtvalue == G2D_IMGFMT(fmtval))
+                               return &g2d_formats_9820[i];
+       }
        return NULL;
 }
 
@@ -334,11 +381,14 @@ static unsigned char dst_base_reg_offset[4] = {0x00, 0x50, 0x30, 0x34};
                 (ALIGN((cmd)[G2DSFR_IMG_HEIGHT].value, 16) / 16) * 16)
 
 size_t g2d_get_payload_index(struct g2d_reg cmd[], const struct g2d_fmt *fmt,
-                            unsigned int idx, unsigned int buffer_count)
+                            unsigned int idx, unsigned int buffer_count,
+                            unsigned long caps)
 {
+       bool yuv82 = IS_YUV_82(fmt->fmtvalue,
+                              caps & G2D_DEVICE_CAPS_YUV_BITDEPTH);
        BUG_ON(!IS_YUV(cmd[G2DSFR_IMG_COLORMODE].value));
 
-       if (IS_YUV420_82(fmt->fmtvalue) && (buffer_count == 2)) {
+       if (yuv82 && (buffer_count == 2)) {
                /* YCbCr420 8+2 semi-planar in two buffers */
                /* regard G2D_LAYERFLAG_MFC_STRIDE is set */
                u32 width = cmd[G2DSFR_IMG_WIDTH].value;
@@ -353,15 +403,16 @@ size_t g2d_get_payload_index(struct g2d_reg cmd[], const struct g2d_fmt *fmt,
 }
 
 size_t g2d_get_payload(struct g2d_reg cmd[], const struct g2d_fmt *fmt,
-                      u32 flags)
+                      u32 flags, unsigned long cap)
 {
        size_t payload = 0;
        u32 mode = cmd[G2DSFR_IMG_COLORMODE].value;
        u32 width = cmd[G2DSFR_IMG_WIDTH].value;
        u32 height = cmd[G2DSFR_IMG_BOTTOM].value;
        size_t pixcount = width * height;
+       bool yuv82 = IS_YUV_82(mode, cap & G2D_DEVICE_CAPS_YUV_BITDEPTH);
 
-       if (IS_YUV420_82(mode)) {
+       if (yuv82) {
                if (!(flags & G2D_LAYERFLAG_MFC_STRIDE)) {
                        /*
                         * constraints of base addresses of NV12/21 8+2
@@ -466,7 +517,7 @@ struct command_checker {
 
 static struct command_checker source_command_checker[G2DSFR_SRC_FIELD_COUNT] = {
        {"STRIDE",      0x0020, 0x0001FFFF, NULL,},
-       {"COLORMODE",   0x0028, 0x031FFFFF, check_srccolor_mode,},
+       {"COLORMODE",   0x0028, 0x331FFFFF, check_srccolor_mode,},
        {"LEFT",        0x002C, 0x00001FFF, NULL,},
        {"TOP",         0x0030, 0x00001FFF, NULL,},
        {"RIGHT",       0x0034, 0x00003FFF, check_width_height,},
@@ -495,7 +546,7 @@ static struct command_checker source_command_checker[G2DSFR_SRC_FIELD_COUNT] = {
 static struct command_checker target_command_checker[G2DSFR_DST_FIELD_COUNT] = {
        /* BASE OFFSET: 0x0120 */
        {"STRIDE",      0x0004, 0x0001FFFF, NULL,},
-       {"COLORMODE",   0x000C, 0x033FFFFF, check_dstcolor_mode,},
+       {"COLORMODE",   0x000C, 0x333FFFFF, check_dstcolor_mode,},
        {"LEFT",        0x0010, 0x00001FFF, NULL,},
        {"TOP",         0x0014, 0x00001FFF, NULL,},
        {"RIGHT",       0x0018, 0x00003FFF, check_width_height,},
@@ -536,6 +587,8 @@ static int g2d_copy_commands(struct g2d_device *g2d_dev, int index,
                                "%s: Invalid %s[%d] SFR '%s' value %#x\n",
                                __func__, (index < 0) ? "target" : "source",
                                index, checker[i].cmdname, cmd[i]);
+                       dev_err(g2d_dev->dev,
+                               "mask %#x\n", checker[i].mask);
                        return -EINVAL;
                }
 
@@ -568,6 +621,7 @@ static bool g2d_validate_image_format(struct g2d_device *g2d_dev,
                struct g2d_task *task, struct g2d_reg commands[], bool dst)
 {
        struct device *dev = g2d_dev->dev;
+       bool yuvbitdepth = !!(g2d_dev->caps & G2D_DEVICE_CAPS_YUV_BITDEPTH);
        u32 stride = commands[G2DSFR_IMG_STRIDE].value;
        u32 mode   = commands[G2DSFR_IMG_COLORMODE].value;
        u32 width  = commands[G2DSFR_IMG_WIDTH].value;
@@ -588,7 +642,7 @@ static bool g2d_validate_image_format(struct g2d_device *g2d_dev,
                                        left, top, right, bottom))
                return false;
 
-       fmt = g2d_find_format(mode);
+       fmt = g2d_find_format(mode, g2d_dev->caps);
        if (fmt == NULL) {
                dev_err(dev, "%s: Color mode %#x is not supported\n",
                        __func__, mode);
@@ -641,7 +695,7 @@ static bool g2d_validate_image_format(struct g2d_device *g2d_dev,
                                        !IS_AFBC_HEIGHT_ALIGNED(height)))
                        goto err_align;
 
-               if (IS_YUV420_82(mode) && !IS_ALIGNED(width, 64))
+               if (IS_YUV_82(mode, yuvbitdepth) && !IS_ALIGNED(width, 64))
                        goto err_align;
 
                return true;
@@ -677,7 +731,7 @@ err_align:
                commands[G2DSFR_IMG_BOTTOM].value,
                IS_AFBC(mode) ? "AFBC" :
                        IS_YUV422(mode) ? "YUV422" : "YUV20",
-               IS_YUV420_82(mode) ? "8+2" : "",
+               IS_YUV_82(mode, yuvbitdepth) ? "8+2" : "",
                IS_HWFC(task->flags) ? "HWFC" : "");
 
        return false;
@@ -855,7 +909,8 @@ static unsigned int g2d_set_image_buffer(struct g2d_task *task,
                                         struct g2d_layer *layer, u32 colormode,
                                         unsigned char offsets[], u32 base)
 {
-       const struct g2d_fmt *fmt = g2d_find_format(colormode);
+       const struct g2d_fmt *fmt = g2d_find_format(colormode,
+                                                   task->g2d_dev->caps);
        struct g2d_reg *reg = (struct g2d_reg *)page_address(task->cmd_page);
        unsigned int cmd_count = task->cmd_count;
        u32 width = layer_width(layer);
@@ -984,8 +1039,12 @@ bool g2d_prepare_source(struct g2d_task *task,
 {
        struct g2d_reg *reg = (struct g2d_reg *)page_address(task->cmd_page);
        u32 colormode = layer->commands[G2DSFR_IMG_COLORMODE].value;
-       unsigned char *offsets = IS_YUV420_82(colormode) ?
-                               src_base_reg_offset_yuv82 : src_base_reg_offset;
+       bool yuv82;
+       unsigned char *offsets;
+
+       yuv82 = IS_YUV_82(colormode,
+                         task->g2d_dev->caps & G2D_DEVICE_CAPS_YUV_BITDEPTH);
+       offsets = yuv82 ? src_base_reg_offset_yuv82 : src_base_reg_offset;
 
        reg[TASK_REG_LAYER_UPDATE].value |= 1 << index;
 
index e2f4aa85784d253d8e39a947e1f01b67bdff94fd..9c4b60c7392d39aa5ef0b62f1039e9e4d4e396b0 100644 (file)
@@ -32,7 +32,7 @@ struct g2d_fmt {
 
 void g2d_init_commands(struct g2d_task *task);
 void g2d_complete_commands(struct g2d_task *task);
-const struct g2d_fmt *g2d_find_format(u32 fmtval);
+const struct g2d_fmt *g2d_find_format(u32 fmtval, unsigned long devcaps);
 int g2d_import_commands(struct g2d_device *g2d_dev, struct g2d_task *task,
                        struct g2d_task_data *data, unsigned int num_sources);
 bool g2d_validate_source_commands(struct g2d_device *g2d_dev,
@@ -42,9 +42,10 @@ bool g2d_validate_source_commands(struct g2d_device *g2d_dev,
 bool g2d_validate_target_commands(struct g2d_device *g2d_dev,
                                  struct g2d_task *task);
 size_t g2d_get_payload(struct g2d_reg cmd[], const struct g2d_fmt *fmt,
-                      u32 flags);
+                      u32 flags, unsigned long caps);
 size_t g2d_get_payload_index(struct g2d_reg cmd[], const struct g2d_fmt *fmt,
-                            unsigned int idx, unsigned int buffer_count);
+                            unsigned int idx, unsigned int buffer_count,
+                            unsigned long caps);
 bool g2d_prepare_source(struct g2d_task *task,
                        struct g2d_layer *layer, int index);
 bool g2d_prepare_target(struct g2d_task *task);
index a4ec50458168abf0f66f0bbb7fee2522127a0cf8..0bd47ab9b4634777c3cc50a1303206fdfd446771 100644 (file)
@@ -777,7 +777,7 @@ struct g2d_device_data {
 };
 
 const struct g2d_device_data g2d_9820_data __initconst = {
-       .caps = G2D_DEVICE_CAPS_SELF_PROTECTION,
+       .caps = G2D_DEVICE_CAPS_SELF_PROTECTION | G2D_DEVICE_CAPS_YUV_BITDEPTH,
 };
 
 static const struct of_device_id of_g2d_match[] __refconst = {
index 2c1e0496ca98f64907b96df622c3c428d2c7be70..31c76470728b6d082a67d938e7ea4fe3a3ec8fca 100644 (file)
 #define G2D_DATAFMT_5551       (5 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_8          (6 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_RESERVED   (7 << G2D_DATAFMT_SHIFT)
+#define G2D_DATAFMT_YUV_MIN    (8 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_YUV420SP   (8 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_YUV420P    (9 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_YUV422I    (10 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_YUV422SP   (11 << G2D_DATAFMT_SHIFT)
-#define G2D_DATAFMT_P010       (12 << G2D_DATAFMT_SHIFT)
-#define G2D_DATAFMT_YUV420SP82 (13 << G2D_DATAFMT_SHIFT)
+#define G2D_DATAFMT_P010_9810  (12 << G2D_DATAFMT_SHIFT)
+#define G2D_DATAFMT_YUV420SP82_9810 (13 << G2D_DATAFMT_SHIFT)
+#define G2D_DATAFMT_YUV_MAX    (13 << G2D_DATAFMT_SHIFT)
 #define G2D_DATAFMT_2101010    (14 << G2D_DATAFMT_SHIFT)
 
+// YCBCR Bitdepth selection is available from Exynos9820
+#define G2D_YCBCR_BITDEPTH_SHIFT 28
+#define G2D_YCBCR_BITDEPTH_MASK  (0x3 << G2D_YCBCR_BITDEPTH_SHIFT)
+#define G2D_FMT_8      (0 << G2D_YCBCR_BITDEPTH_SHIFT)
+#define G2D_FMT_10     (1 << G2D_YCBCR_BITDEPTH_SHIFT)
+#define G2D_FMT_82     (2 << G2D_YCBCR_BITDEPTH_SHIFT)
+
 #define G2D_FMT_ARGB8888       (G2D_DATAFMT_8888 | G2D_SWZ_ARGB)
 #define G2D_FMT_ABGR8888       (G2D_DATAFMT_8888 | G2D_SWZ_ABGR)
 #define G2D_FMT_XBGR8888       (G2D_DATAFMT_8888 | G2D_SWZ_xBGR)
 #define G2D_FMT_VYUY           (G2D_DATAFMT_YUV422I | G2D_YUV_CY | G2D_YUV_VU)
 #define G2D_FMT_NV16           (G2D_DATAFMT_YUV422SP | G2D_YUV_UV)
 #define G2D_FMT_NV61           (G2D_DATAFMT_YUV422SP | G2D_YUV_VU)
-#define G2D_FMT_NV12_82                (G2D_DATAFMT_YUV420SP82 | G2D_YUV_UV)
-#define G2D_FMT_NV21_82                (G2D_DATAFMT_YUV420SP82 | G2D_YUV_VU)
-#define G2D_FMT_NV12_P010      (G2D_DATAFMT_P010 | G2D_YUV_UV)
-#define G2D_FMT_NV21_P010      (G2D_DATAFMT_P010 | G2D_YUV_VU)
+#define G2D_FMT_NV12_82_9810   (G2D_DATAFMT_YUV420SP82_9810 | G2D_YUV_UV)
+#define G2D_FMT_NV21_82_9810   (G2D_DATAFMT_YUV420SP82_9810 | G2D_YUV_VU)
+#define G2D_FMT_NV12_82_9820   (G2D_DATAFMT_YUV420SP | G2D_FMT_82 | G2D_YUV_UV)
+#define G2D_FMT_NV21_82_9820   (G2D_DATAFMT_YUV420SP | G2D_FMT_82 | G2D_YUV_VU)
+#define G2D_FMT_NV12_P010_9810 (G2D_DATAFMT_P010_9810 | G2D_YUV_UV)
+#define G2D_FMT_NV21_P010_9810 (G2D_DATAFMT_P010_9810 | G2D_YUV_VU)
+#define G2D_FMT_NV12_P010_9820 (G2D_DATAFMT_YUV420SP | G2D_FMT_10 | G2D_YUV_UV)
+#define G2D_FMT_NV21_P010_9820 (G2D_DATAFMT_YUV420SP | G2D_FMT_10 | G2D_YUV_VU)
+#define G2D_FMT_NV16_P210_9820 (G2D_DATAFMT_YUV422SP | G2D_FMT_10 | G2D_YUV_UV)
+#define G2D_FMT_NV61_P210_9820 (G2D_DATAFMT_YUV422SP | G2D_FMT_10 | G2D_YUV_VU)
 #define G2D_FMT_ABGR2101010    (G2D_DATAFMT_2101010 | G2D_SWZ_ABGR)
 
 #define G2D_DATAFORMAT_AFBC    (1 << 20)
 
 #define IS_AFBC(fmt)   ((fmt & G2D_DATAFORMAT_AFBC) != 0)
 #define IS_UORDER(fmt) ((fmt & G2D_DATAFORMAT_UORDER) != 0)
-#define IS_YUV(fmt)    ((((fmt) & G2D_DATAFMT_MASK) > G2D_DATAFMT_RESERVED) &&\
-                       (((fmt) & G2D_DATAFMT_MASK) != G2D_DATAFMT_2101010))
+#define IS_YUV(fmt)    ((((fmt) & G2D_DATAFMT_MASK) >= G2D_DATAFMT_YUV_MIN) &&\
+                       (((fmt) & G2D_DATAFMT_MASK) <= G2D_DATAFMT_YUV_MAX))
 #define IS_YUV420(fmt) ((((fmt) >> G2D_DATAFMT_SHIFT) & 0xF) == 0x8)
 #define IS_YUV422(fmt) ((((fmt) >> G2D_DATAFMT_SHIFT) & 0xE) == 0xA)
 #define IS_YUV422_2P(fmt)      ((((fmt) >> G2D_DATAFMT_SHIFT) & 0xF) == 0xB)
 #define IS_RGB(fmt)    ((((fmt) & G2D_DATAFMT_MASK) < G2D_DATAFMT_8) ||\
-                       (((fmt) & G2D_DATAFMT_MASK) == G2D_DATAFMT_2101010))
-#define IS_YUV420_82(fmt) (((fmt) & G2D_DATAFMT_MASK) == G2D_DATAFMT_YUV420SP82)
+                       (((fmt) & G2D_DATAFMT_MASK) > G2D_DATAFMT_YUV_MAX))
+
+#define IS_YUV_82_9810(fmt) \
+               (((fmt) & G2D_DATAFMT_MASK) == G2D_DATAFMT_YUV420SP82_9810)
+#define IS_YUV_P10_9810(fmt) \
+               (((fmt) & G2D_DATAFMT_MASK) == G2D_DATAFMT_P010_9810)
+
+#define IS_YUV_82_9820(fmt) (((fmt) & G2D_YCBCR_BITDEPTH_MASK) == G2D_FMT_82)
+#define IS_YUV_P10_9820(fmt) (((fmt) & G2D_YCBCR_BITDEPTH_MASK) == G2D_FMT_10)
+
+#define IS_YUV_82(fmt, bitdepthfield) \
+               (!(bitdepthfield) ? IS_YUV_82_9810(fmt) : IS_YUV_82_9820(fmt))
 
 #define IS_AFBC_WIDTH_ALIGNED(width)   IS_ALIGNED((width), 16)
 #define IS_AFBC_HEIGHT_ALIGNED(height) IS_ALIGNED((height), 4)
 
-#define G2D_IMGFMT(value) ((value) & \
-                       (G2D_DATAFMT_MASK | G2D_YUVORDER_MASK | G2D_SWZ_MASK))
+#define G2D_IMGFMT(value) ((value) & (G2D_YCBCR_BITDEPTH_MASK | \
+                          G2D_DATAFMT_MASK | G2D_YUVORDER_MASK | G2D_SWZ_MASK))
 
 #define G2D_MAX_PLANES 4
 
index 4c9d46e5a2572a162864539730681ea0a0ff6935..6c9957ce09f461445266c3187bf372e50652acfd 100644 (file)
@@ -134,7 +134,7 @@ static int g2d_prepare_buffer(struct g2d_device *g2d_dev,
        unsigned int payload;
        int i;
 
-       fmt = g2d_find_format(cmd[G2DSFR_IMG_COLORMODE].value);
+       fmt = g2d_find_format(cmd[G2DSFR_IMG_COLORMODE].value, g2d_dev->caps);
 
        BUG_ON(!fmt);
 
@@ -150,7 +150,8 @@ static int g2d_prepare_buffer(struct g2d_device *g2d_dev,
        if (data->num_buffers > 1) {
                for (i = 0; i < data->num_buffers; i++) {
                        payload = (unsigned int)g2d_get_payload_index(
-                                               cmd, fmt, i, data->num_buffers);
+                                               cmd, fmt, i, data->num_buffers,
+                                               g2d_dev->caps);
                        if (data->buffer[i].length < payload) {
                                dev_err(dev,
                                        "%s: Too small buffer[%d]: expected %uB"
@@ -166,7 +167,8 @@ static int g2d_prepare_buffer(struct g2d_device *g2d_dev,
                        layer->buffer[i].payload = payload;
                }
        } else {
-               payload = (unsigned int)g2d_get_payload(cmd, fmt, layer->flags);
+               payload = (unsigned int)g2d_get_payload(cmd, fmt, layer->flags,
+                                                       g2d_dev->caps);
                if (data->buffer[0].length < payload) {
                        dev_err(dev, "%s: Too small buffer: expected %uB"
                                " for %ux%u(bt %u)/%s but %uB is given\n",