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 */
.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,
},
};
-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;
}
(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;
}
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
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,},
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,},
"%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;
}
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;
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);
!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;
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;
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);
{
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;
#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