Commit fef1c8d0 authored by Tomasz Stanislawski's avatar Tomasz Stanislawski Committed by Mauro Carvalho Chehab

[media] v4l: s5p-tv: add TV Mixer driver for Samsung S5P platform

Add driver for TV Mixer on Samsung platforms from S5P family.
Mixer is responsible for merging images from three layers and
passing result to the output.

Drivers are using:
- v4l2 framework
- videobuf2
- runtime PM
Signed-off-by: default avatarTomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Reviewed-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 9a498400
......@@ -57,4 +57,20 @@ config VIDEO_SAMSUNG_S5P_SDO
subdev for use by other drivers. This driver requires
hdmiphy driver to work correctly.
config VIDEO_SAMSUNG_S5P_MIXER
tristate "Samsung Mixer and Video Processor Driver"
depends on VIDEO_DEV && VIDEO_V4L2
depends on VIDEO_SAMSUNG_S5P_TV
select VIDEOBUF2_DMA_CONTIG
help
Say Y here if you want support for the Mixer in Samsung S5P SoCs.
This device produce image data to one of output interfaces.
config VIDEO_SAMSUNG_S5P_MIXER_DEBUG
bool "Enable debug for Mixer Driver"
depends on VIDEO_SAMSUNG_S5P_MIXER
default n
help
Enables debugging for Mixer driver.
endif # VIDEO_SAMSUNG_S5P_TV
......@@ -12,4 +12,6 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o
s5p-hdmi-y += hdmi_drv.o
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
s5p-sdo-y += sdo_drv.o
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MIXER) += s5p-mixer.o
s5p-mixer-y += mixer_drv.o mixer_video.o mixer_reg.o mixer_grp_layer.o mixer_vp_layer.o
This diff is collapsed.
This diff is collapsed.
/*
* Samsung TV Mixer driver
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
*
* Tomasz Stanislawski, <t.stanislaws@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundiation. either version 2 of the License,
* or (at your option) any later version
*/
#include "mixer.h"
#include <media/videobuf2-dma-contig.h>
/* FORMAT DEFINITIONS */
static const struct mxr_format mxr_fb_fmt_rgb565 = {
.name = "RGB565",
.fourcc = V4L2_PIX_FMT_RGB565,
.colorspace = V4L2_COLORSPACE_SRGB,
.num_planes = 1,
.plane = {
{ .width = 1, .height = 1, .size = 2 },
},
.num_subframes = 1,
.cookie = 4,
};
static const struct mxr_format mxr_fb_fmt_argb1555 = {
.name = "ARGB1555",
.num_planes = 1,
.fourcc = V4L2_PIX_FMT_RGB555,
.colorspace = V4L2_COLORSPACE_SRGB,
.plane = {
{ .width = 1, .height = 1, .size = 2 },
},
.num_subframes = 1,
.cookie = 5,
};
static const struct mxr_format mxr_fb_fmt_argb4444 = {
.name = "ARGB4444",
.num_planes = 1,
.fourcc = V4L2_PIX_FMT_RGB444,
.colorspace = V4L2_COLORSPACE_SRGB,
.plane = {
{ .width = 1, .height = 1, .size = 2 },
},
.num_subframes = 1,
.cookie = 6,
};
static const struct mxr_format mxr_fb_fmt_argb8888 = {
.name = "ARGB8888",
.fourcc = V4L2_PIX_FMT_BGR32,
.colorspace = V4L2_COLORSPACE_SRGB,
.num_planes = 1,
.plane = {
{ .width = 1, .height = 1, .size = 4 },
},
.num_subframes = 1,
.cookie = 7,
};
static const struct mxr_format *mxr_graph_format[] = {
&mxr_fb_fmt_rgb565,
&mxr_fb_fmt_argb1555,
&mxr_fb_fmt_argb4444,
&mxr_fb_fmt_argb8888,
};
/* AUXILIARY CALLBACKS */
static void mxr_graph_layer_release(struct mxr_layer *layer)
{
mxr_base_layer_unregister(layer);
mxr_base_layer_release(layer);
}
static void mxr_graph_buffer_set(struct mxr_layer *layer,
struct mxr_buffer *buf)
{
dma_addr_t addr = 0;
if (buf)
addr = vb2_dma_contig_plane_paddr(&buf->vb, 0);
mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
}
static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
{
mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
}
static void mxr_graph_format_set(struct mxr_layer *layer)
{
mxr_reg_graph_format(layer->mdev, layer->idx,
layer->fmt, &layer->geo);
}
static void mxr_graph_fix_geometry(struct mxr_layer *layer)
{
struct mxr_geometry *geo = &layer->geo;
/* limit to boundary size */
geo->src.full_width = clamp_val(geo->src.full_width, 1, 32767);
geo->src.full_height = clamp_val(geo->src.full_height, 1, 2047);
geo->src.width = clamp_val(geo->src.width, 1, geo->src.full_width);
geo->src.width = min(geo->src.width, 2047U);
/* not possible to crop of Y axis */
geo->src.y_offset = min(geo->src.y_offset, geo->src.full_height - 1);
geo->src.height = geo->src.full_height - geo->src.y_offset;
/* limitting offset */
geo->src.x_offset = min(geo->src.x_offset,
geo->src.full_width - geo->src.width);
/* setting position in output */
geo->dst.width = min(geo->dst.width, geo->dst.full_width);
geo->dst.height = min(geo->dst.height, geo->dst.full_height);
/* Mixer supports only 1x and 2x scaling */
if (geo->dst.width >= 2 * geo->src.width) {
geo->x_ratio = 1;
geo->dst.width = 2 * geo->src.width;
} else {
geo->x_ratio = 0;
geo->dst.width = geo->src.width;
}
if (geo->dst.height >= 2 * geo->src.height) {
geo->y_ratio = 1;
geo->dst.height = 2 * geo->src.height;
} else {
geo->y_ratio = 0;
geo->dst.height = geo->src.height;
}
geo->dst.x_offset = min(geo->dst.x_offset,
geo->dst.full_width - geo->dst.width);
geo->dst.y_offset = min(geo->dst.y_offset,
geo->dst.full_height - geo->dst.height);
}
/* PUBLIC API */
struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
{
struct mxr_layer *layer;
int ret;
struct mxr_layer_ops ops = {
.release = mxr_graph_layer_release,
.buffer_set = mxr_graph_buffer_set,
.stream_set = mxr_graph_stream_set,
.format_set = mxr_graph_format_set,
.fix_geometry = mxr_graph_fix_geometry,
};
char name[32];
sprintf(name, "graph%d", idx);
layer = mxr_base_layer_create(mdev, idx, name, &ops);
if (layer == NULL) {
mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
goto fail;
}
layer->fmt_array = mxr_graph_format;
layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
ret = mxr_base_layer_register(layer);
if (ret)
goto fail_layer;
return layer;
fail_layer:
mxr_base_layer_release(layer);
fail:
return NULL;
}
This diff is collapsed.
This diff is collapsed.
/*
* Samsung TV Mixer driver
*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
*
* Tomasz Stanislawski, <t.stanislaws@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundiation. either version 2 of the License,
* or (at your option) any later version
*/
#include "mixer.h"
#include "regs-vp.h"
#include <media/videobuf2-dma-contig.h>
/* FORMAT DEFINITIONS */
static const struct mxr_format mxr_fmt_nv12 = {
.name = "NV12",
.fourcc = V4L2_PIX_FMT_NV12,
.colorspace = V4L2_COLORSPACE_JPEG,
.num_planes = 2,
.plane = {
{ .width = 1, .height = 1, .size = 1 },
{ .width = 2, .height = 2, .size = 2 },
},
.num_subframes = 1,
.cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
};
static const struct mxr_format mxr_fmt_nv21 = {
.name = "NV21",
.fourcc = V4L2_PIX_FMT_NV21,
.colorspace = V4L2_COLORSPACE_JPEG,
.num_planes = 2,
.plane = {
{ .width = 1, .height = 1, .size = 1 },
{ .width = 2, .height = 2, .size = 2 },
},
.num_subframes = 1,
.cookie = VP_MODE_NV21 | VP_MODE_MEM_LINEAR,
};
static const struct mxr_format mxr_fmt_nv12m = {
.name = "NV12 (mplane)",
.fourcc = V4L2_PIX_FMT_NV12M,
.colorspace = V4L2_COLORSPACE_JPEG,
.num_planes = 2,
.plane = {
{ .width = 1, .height = 1, .size = 1 },
{ .width = 2, .height = 2, .size = 2 },
},
.num_subframes = 2,
.plane2subframe = {0, 1},
.cookie = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
};
static const struct mxr_format mxr_fmt_nv12mt = {
.name = "NV12 tiled (mplane)",
.fourcc = V4L2_PIX_FMT_NV12MT,
.colorspace = V4L2_COLORSPACE_JPEG,
.num_planes = 2,
.plane = {
{ .width = 128, .height = 32, .size = 4096 },
{ .width = 128, .height = 32, .size = 2048 },
},
.num_subframes = 2,
.plane2subframe = {0, 1},
.cookie = VP_MODE_NV12 | VP_MODE_MEM_TILED,
};
static const struct mxr_format *mxr_video_format[] = {
&mxr_fmt_nv12,
&mxr_fmt_nv21,
&mxr_fmt_nv12m,
&mxr_fmt_nv12mt,
};
/* AUXILIARY CALLBACKS */
static void mxr_vp_layer_release(struct mxr_layer *layer)
{
mxr_base_layer_unregister(layer);
mxr_base_layer_release(layer);
}
static void mxr_vp_buffer_set(struct mxr_layer *layer,
struct mxr_buffer *buf)
{
dma_addr_t luma_addr[2] = {0, 0};
dma_addr_t chroma_addr[2] = {0, 0};
if (buf == NULL) {
mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
return;
}
luma_addr[0] = vb2_dma_contig_plane_paddr(&buf->vb, 0);
if (layer->fmt->num_subframes == 2) {
chroma_addr[0] = vb2_dma_contig_plane_paddr(&buf->vb, 1);
} else {
/* FIXME: mxr_get_plane_size compute integer division,
* which is slow and should not be performed in interrupt */
chroma_addr[0] = luma_addr[0] + mxr_get_plane_size(
&layer->fmt->plane[0], layer->geo.src.full_width,
layer->geo.src.full_height);
}
if (layer->fmt->cookie & VP_MODE_MEM_TILED) {
luma_addr[1] = luma_addr[0] + 0x40;
chroma_addr[1] = chroma_addr[0] + 0x40;
} else {
luma_addr[1] = luma_addr[0] + layer->geo.src.full_width;
chroma_addr[1] = chroma_addr[0];
}
mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
}
static void mxr_vp_stream_set(struct mxr_layer *layer, int en)
{
mxr_reg_vp_layer_stream(layer->mdev, en);
}
static void mxr_vp_format_set(struct mxr_layer *layer)
{
mxr_reg_vp_format(layer->mdev, layer->fmt, &layer->geo);
}
static void mxr_vp_fix_geometry(struct mxr_layer *layer)
{
struct mxr_geometry *geo = &layer->geo;
/* align horizontal size to 8 pixels */
geo->src.full_width = ALIGN(geo->src.full_width, 8);
/* limit to boundary size */
geo->src.full_width = clamp_val(geo->src.full_width, 8, 8192);
geo->src.full_height = clamp_val(geo->src.full_height, 1, 8192);
geo->src.width = clamp_val(geo->src.width, 32, geo->src.full_width);
geo->src.width = min(geo->src.width, 2047U);
geo->src.height = clamp_val(geo->src.height, 4, geo->src.full_height);
geo->src.height = min(geo->src.height, 2047U);
/* setting size of output window */
geo->dst.width = clamp_val(geo->dst.width, 8, geo->dst.full_width);
geo->dst.height = clamp_val(geo->dst.height, 1, geo->dst.full_height);
/* ensure that scaling is in range 1/4x to 16x */
if (geo->src.width >= 4 * geo->dst.width)
geo->src.width = 4 * geo->dst.width;
if (geo->dst.width >= 16 * geo->src.width)
geo->dst.width = 16 * geo->src.width;
if (geo->src.height >= 4 * geo->dst.height)
geo->src.height = 4 * geo->dst.height;
if (geo->dst.height >= 16 * geo->src.height)
geo->dst.height = 16 * geo->src.height;
/* setting scaling ratio */
geo->x_ratio = (geo->src.width << 16) / geo->dst.width;
geo->y_ratio = (geo->src.height << 16) / geo->dst.height;
/* adjust offsets */
geo->src.x_offset = min(geo->src.x_offset,
geo->src.full_width - geo->src.width);
geo->src.y_offset = min(geo->src.y_offset,
geo->src.full_height - geo->src.height);
geo->dst.x_offset = min(geo->dst.x_offset,
geo->dst.full_width - geo->dst.width);
geo->dst.y_offset = min(geo->dst.y_offset,
geo->dst.full_height - geo->dst.height);
}
/* PUBLIC API */
struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx)
{
struct mxr_layer *layer;
int ret;
struct mxr_layer_ops ops = {
.release = mxr_vp_layer_release,
.buffer_set = mxr_vp_buffer_set,
.stream_set = mxr_vp_stream_set,
.format_set = mxr_vp_format_set,
.fix_geometry = mxr_vp_fix_geometry,
};
char name[32];
sprintf(name, "video%d", idx);
layer = mxr_base_layer_create(mdev, idx, name, &ops);
if (layer == NULL) {
mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
goto fail;
}
layer->fmt_array = mxr_video_format;
layer->fmt_array_size = ARRAY_SIZE(mxr_video_format);
ret = mxr_base_layer_register(layer);
if (ret)
goto fail_layer;
return layer;
fail_layer:
mxr_base_layer_release(layer);
fail:
return NULL;
}
/*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Mixer register header file for Samsung Mixer driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef SAMSUNG_REGS_MIXER_H
#define SAMSUNG_REGS_MIXER_H
/*
* Register part
*/
#define MXR_STATUS 0x0000
#define MXR_CFG 0x0004
#define MXR_INT_EN 0x0008
#define MXR_INT_STATUS 0x000C
#define MXR_LAYER_CFG 0x0010
#define MXR_VIDEO_CFG 0x0014
#define MXR_GRAPHIC0_CFG 0x0020
#define MXR_GRAPHIC0_BASE 0x0024
#define MXR_GRAPHIC0_SPAN 0x0028
#define MXR_GRAPHIC0_SXY 0x002C
#define MXR_GRAPHIC0_WH 0x0030
#define MXR_GRAPHIC0_DXY 0x0034
#define MXR_GRAPHIC0_BLANK 0x0038
#define MXR_GRAPHIC1_CFG 0x0040
#define MXR_GRAPHIC1_BASE 0x0044
#define MXR_GRAPHIC1_SPAN 0x0048
#define MXR_GRAPHIC1_SXY 0x004C
#define MXR_GRAPHIC1_WH 0x0050
#define MXR_GRAPHIC1_DXY 0x0054
#define MXR_GRAPHIC1_BLANK 0x0058
#define MXR_BG_CFG 0x0060
#define MXR_BG_COLOR0 0x0064
#define MXR_BG_COLOR1 0x0068
#define MXR_BG_COLOR2 0x006C
/* for parametrized access to layer registers */
#define MXR_GRAPHIC_CFG(i) (0x0020 + (i) * 0x20)
#define MXR_GRAPHIC_BASE(i) (0x0024 + (i) * 0x20)
#define MXR_GRAPHIC_SPAN(i) (0x0028 + (i) * 0x20)
#define MXR_GRAPHIC_SXY(i) (0x002C + (i) * 0x20)
#define MXR_GRAPHIC_WH(i) (0x0030 + (i) * 0x20)
#define MXR_GRAPHIC_DXY(i) (0x0034 + (i) * 0x20)
/*
* Bit definition part
*/
/* generates mask for range of bits */
#define MXR_MASK(high_bit, low_bit) \
(((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
#define MXR_MASK_VAL(val, high_bit, low_bit) \
(((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
/* bits for MXR_STATUS */
#define MXR_STATUS_16_BURST (1 << 7)
#define MXR_STATUS_BURST_MASK (1 << 7)
#define MXR_STATUS_SYNC_ENABLE (1 << 2)
#define MXR_STATUS_REG_RUN (1 << 0)
/* bits for MXR_CFG */
#define MXR_CFG_OUT_YUV444 (0 << 8)
#define MXR_CFG_OUT_RGB888 (1 << 8)
#define MXR_CFG_DST_SDO (0 << 7)
#define MXR_CFG_DST_HDMI (1 << 7)
#define MXR_CFG_DST_MASK (1 << 7)
#define MXR_CFG_SCAN_HD_720 (0 << 6)
#define MXR_CFG_SCAN_HD_1080 (1 << 6)
#define MXR_CFG_GRP1_ENABLE (1 << 5)
#define MXR_CFG_GRP0_ENABLE (1 << 4)
#define MXR_CFG_VP_ENABLE (1 << 3)
#define MXR_CFG_SCAN_INTERLACE (0 << 2)
#define MXR_CFG_SCAN_PROGRASSIVE (1 << 2)
#define MXR_CFG_SCAN_NTSC (0 << 1)
#define MXR_CFG_SCAN_PAL (1 << 1)
#define MXR_CFG_SCAN_SD (0 << 0)
#define MXR_CFG_SCAN_HD (1 << 0)
#define MXR_CFG_SCAN_MASK 0x47
/* bits for MXR_GRAPHICn_CFG */
#define MXR_GRP_CFG_COLOR_KEY_DISABLE (1 << 21)
#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20)
#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8)
#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0)
#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
/* bits for MXR_GRAPHICn_WH */
#define MXR_GRP_WH_H_SCALE(x) MXR_MASK_VAL(x, 28, 28)
#define MXR_GRP_WH_V_SCALE(x) MXR_MASK_VAL(x, 12, 12)
#define MXR_GRP_WH_WIDTH(x) MXR_MASK_VAL(x, 26, 16)
#define MXR_GRP_WH_HEIGHT(x) MXR_MASK_VAL(x, 10, 0)
/* bits for MXR_GRAPHICn_SXY */
#define MXR_GRP_SXY_SX(x) MXR_MASK_VAL(x, 26, 16)
#define MXR_GRP_SXY_SY(x) MXR_MASK_VAL(x, 10, 0)
/* bits for MXR_GRAPHICn_DXY */
#define MXR_GRP_DXY_DX(x) MXR_MASK_VAL(x, 26, 16)
#define MXR_GRP_DXY_DY(x) MXR_MASK_VAL(x, 10, 0)
/* bits for MXR_INT_EN */
#define MXR_INT_EN_VSYNC (1 << 11)
#define MXR_INT_EN_ALL (0x0f << 8)
/* bit for MXR_INT_STATUS */
#define MXR_INT_CLEAR_VSYNC (1 << 11)
#define MXR_INT_STATUS_VSYNC (1 << 0)
/* bit for MXR_LAYER_CFG */
#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8)
#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4)
#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0)
#endif /* SAMSUNG_REGS_MIXER_H */
/*
* Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Video processor register header file for Samsung Mixer driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef SAMSUNG_REGS_VP_H
#define SAMSUNG_REGS_VP_H
/*
* Register part
*/
#define VP_ENABLE 0x0000
#define VP_SRESET 0x0004
#define VP_SHADOW_UPDATE 0x0008
#define VP_FIELD_ID 0x000C
#define VP_MODE 0x0010
#define VP_IMG_SIZE_Y 0x0014
#define VP_IMG_SIZE_C 0x0018
#define VP_PER_RATE_CTRL 0x001C
#define VP_TOP_Y_PTR 0x0028
#define VP_BOT_Y_PTR 0x002C
#define VP_TOP_C_PTR 0x0030
#define VP_BOT_C_PTR 0x0034
#define VP_ENDIAN_MODE 0x03CC
#define VP_SRC_H_POSITION 0x0044
#define VP_SRC_V_POSITION 0x0048
#define VP_SRC_WIDTH 0x004C
#define VP_SRC_HEIGHT 0x0050
#define VP_DST_H_POSITION 0x0054
#define VP_DST_V_POSITION 0x0058
#define VP_DST_WIDTH 0x005C
#define VP_DST_HEIGHT 0x0060
#define VP_H_RATIO 0x0064
#define VP_V_RATIO 0x0068
#define VP_POLY8_Y0_LL 0x006C
#define VP_POLY4_Y0_LL 0x00EC
#define VP_POLY4_C0_LL 0x012C
/*
* Bit definition part
*/
/* generates mask for range of bits */
#define VP_MASK(high_bit, low_bit) \
(((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
#define VP_MASK_VAL(val, high_bit, low_bit) \
(((val) << (low_bit)) & VP_MASK(high_bit, low_bit))
/* VP_ENABLE */
#define VP_ENABLE_ON (1 << 0)
/* VP_SRESET */
#define VP_SRESET_PROCESSING (1 << 0)
/* VP_SHADOW_UPDATE */
#define VP_SHADOW_UPDATE_ENABLE (1 << 0)
/* VP_MODE */
#define VP_MODE_NV12 (0 << 6)
#define VP_MODE_NV21 (1 << 6)
#define VP_MODE_LINE_SKIP (1 << 5)
#define VP_MODE_MEM_LINEAR (0 << 4)
#define VP_MODE_MEM_TILED (1 << 4)
#define VP_MODE_FMT_MASK (5 << 4)
#define VP_MODE_FIELD_ID_AUTO_TOGGLING (1 << 2)
#define VP_MODE_2D_IPC (1 << 1)
/* VP_IMG_SIZE_Y */
/* VP_IMG_SIZE_C */
#define VP_IMG_HSIZE(x) VP_MASK_VAL(x, 29, 16)
#define VP_IMG_VSIZE(x) VP_MASK_VAL(x, 13, 0)
/* VP_SRC_H_POSITION */
#define VP_SRC_H_POSITION_VAL(x) VP_MASK_VAL(x, 14, 4)
/* VP_ENDIAN_MODE */
#define VP_ENDIAN_MODE_LITTLE (1 << 0)
#endif /* SAMSUNG_REGS_VP_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment