video: rockchip: dvbm: Support vpss wrap
Change-Id: I00d280d9aba30be37c3511a0561af427dc413300 Signed-off-by: Yandong Lin <yandong.lin@rock-chips.com>
This commit is contained in:
@@ -44,18 +44,17 @@ static struct dvbm_ctx *g_ctx;
|
|||||||
|
|
||||||
struct dvbm_ctx {
|
struct dvbm_ctx {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
struct dvbm_port ports[DVBM_PORT_BUTT];
|
||||||
|
|
||||||
u32 isp_connet;
|
u32 isp_connet;
|
||||||
u32 vepu_connet;
|
u32 vepu_connet;
|
||||||
|
|
||||||
/* vepu infos */
|
/* vepu infos */
|
||||||
struct dvbm_port port_vepu;
|
|
||||||
atomic_t vepu_link;
|
atomic_t vepu_link;
|
||||||
struct dvbm_cb vepu_cb;
|
struct dvbm_cb vepu_cb;
|
||||||
struct dvbm_addr_cfg vepu_cfg;
|
struct dvbm_addr_cfg vepu_cfg;
|
||||||
|
|
||||||
/* isp infos */
|
/* isp infos */
|
||||||
struct dvbm_port port_isp;
|
|
||||||
struct dvbm_cb isp_cb;
|
struct dvbm_cb isp_cb;
|
||||||
struct dvbm_isp_cfg_t isp_cfg[DVBM_CHANNEL_NUM];
|
struct dvbm_isp_cfg_t isp_cfg[DVBM_CHANNEL_NUM];
|
||||||
struct dvbm_addr_cfg dvbm_addr[DVBM_CHANNEL_NUM];
|
struct dvbm_addr_cfg dvbm_addr[DVBM_CHANNEL_NUM];
|
||||||
@@ -71,16 +70,21 @@ struct dvbm_ctx {
|
|||||||
|
|
||||||
static struct dvbm_ctx *port_to_ctx(struct dvbm_port *port)
|
static struct dvbm_ctx *port_to_ctx(struct dvbm_port *port)
|
||||||
{
|
{
|
||||||
struct dvbm_ctx *ctx = NULL;
|
return g_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(port))
|
static const char *dvbm_port_name(enum dvbm_port_dir dir)
|
||||||
return g_ctx;
|
{
|
||||||
if (port->dir == DVBM_ISP_PORT)
|
static const char *const name[] = {
|
||||||
ctx = container_of(port, struct dvbm_ctx, port_isp);
|
[DVBM_ISP_PORT] = "isp",
|
||||||
else if (port->dir == DVBM_VEPU_PORT)
|
[DVBM_VEPU_PORT] = "vepu",
|
||||||
ctx = container_of(port, struct dvbm_ctx, port_vepu);
|
[DVBM_VPSS_PORT] = "vpss",
|
||||||
|
};
|
||||||
|
|
||||||
return ctx;
|
if (dir >= DVBM_PORT_BUTT)
|
||||||
|
return "unknown";
|
||||||
|
|
||||||
|
return name[dir];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dvbm2enc_callback(struct dvbm_ctx *ctx, enum dvbm_cb_event event, void *arg)
|
static void dvbm2enc_callback(struct dvbm_ctx *ctx, enum dvbm_cb_event event, void *arg)
|
||||||
@@ -137,10 +141,13 @@ struct dvbm_port *rk_dvbm_get_port(struct platform_device *pdev,
|
|||||||
ctx = (struct dvbm_ctx *)platform_get_drvdata(pdev);
|
ctx = (struct dvbm_ctx *)platform_get_drvdata(pdev);
|
||||||
WARN_ON(!ctx);
|
WARN_ON(!ctx);
|
||||||
dvbm_debug("%s dir %d\n", __func__, dir);
|
dvbm_debug("%s dir %d\n", __func__, dir);
|
||||||
if (dir == DVBM_ISP_PORT)
|
|
||||||
port = &ctx->port_isp;
|
if (dir >= DVBM_PORT_BUTT) {
|
||||||
else if (dir == DVBM_VEPU_PORT)
|
dvbm_err("%s dir %d error\n", __func__, dir);
|
||||||
port = &ctx->port_vepu;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = &ctx->ports[dir];
|
||||||
|
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
@@ -173,17 +180,25 @@ int rk_dvbm_link(struct dvbm_port *port, int id)
|
|||||||
ctx = port_to_ctx(port);
|
ctx = port_to_ctx(port);
|
||||||
dir = port->dir;
|
dir = port->dir;
|
||||||
|
|
||||||
if (dir == DVBM_ISP_PORT) {
|
switch (dir) {
|
||||||
|
case DVBM_ISP_PORT: {
|
||||||
if (id >= DVBM_CHANNEL_NUM)
|
if (id >= DVBM_CHANNEL_NUM)
|
||||||
dvbm_err("id %d is invalid\n", id);
|
dvbm_err("isp id %d is invalid\n", id);
|
||||||
|
|
||||||
dvbm2enc_callback(ctx, DVBM_ISP_REQ_CONNECT, &id);
|
dvbm2enc_callback(ctx, DVBM_ISP_REQ_CONNECT, &id);
|
||||||
} else if (dir == DVBM_VEPU_PORT) {
|
} break;
|
||||||
|
case DVBM_VPSS_PORT: {
|
||||||
|
if (id >= DVBM_CHANNEL_NUM)
|
||||||
|
dvbm_err("vpss id %d is invalid\n", id);
|
||||||
|
|
||||||
|
dvbm2enc_callback(ctx, DVBM_VPSS_REQ_CONNECT, &id);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbm_debug("%s %d connect frm_cnt[%d : %d]\n",
|
dvbm_debug("%s %d connect frm_cnt[%d : %d]\n",
|
||||||
dir == DVBM_ISP_PORT ? "isp" : "vepu", id,
|
dvbm_port_name(dir), id, ctx->isp_frm_start, ctx->isp_frm_end);
|
||||||
ctx->isp_frm_start, ctx->isp_frm_end);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -200,14 +215,24 @@ int rk_dvbm_unlink(struct dvbm_port *port, int id)
|
|||||||
ctx = port_to_ctx(port);
|
ctx = port_to_ctx(port);
|
||||||
dir = port->dir;
|
dir = port->dir;
|
||||||
|
|
||||||
if (dir == DVBM_ISP_PORT) {
|
switch (dir) {
|
||||||
|
case DVBM_ISP_PORT: {
|
||||||
if (id >= DVBM_CHANNEL_NUM)
|
if (id >= DVBM_CHANNEL_NUM)
|
||||||
dvbm_err("id %d is invalid\n", id);
|
dvbm_err("isp id %d is invalid\n", id);
|
||||||
|
|
||||||
dvbm2enc_callback(ctx, DVBM_ISP_REQ_DISCONNECT, &id);
|
dvbm2enc_callback(ctx, DVBM_ISP_REQ_DISCONNECT, &id);
|
||||||
} else if (dir == DVBM_VEPU_PORT) {
|
} break;
|
||||||
|
case DVBM_VPSS_PORT: {
|
||||||
|
if (id >= DVBM_CHANNEL_NUM)
|
||||||
|
dvbm_err("vpss id %d is invalid\n", id);
|
||||||
|
|
||||||
|
dvbm2enc_callback(ctx, DVBM_VPSS_REQ_DISCONNECT, &id);
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
dvbm_debug("%s disconnect\n", dir == DVBM_ISP_PORT ? "isp" : "vepu");
|
|
||||||
|
dvbm_debug("%s %d disconnect\n", dvbm_port_name(dir), id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -239,7 +264,7 @@ int rk_dvbm_ctrl(struct dvbm_port *port, enum dvbm_cmd cmd, void *arg)
|
|||||||
{
|
{
|
||||||
struct dvbm_ctx *ctx;
|
struct dvbm_ctx *ctx;
|
||||||
|
|
||||||
if ((cmd < DVBM_ISP_CMD_BASE) || (cmd > DVBM_VEPU_CMD_BUTT)) {
|
if ((cmd < DVBM_ISP_CMD_BASE) || (cmd > DVBM_VPSS_CMD_BUTT)) {
|
||||||
dvbm_err("%s input cmd invalid\n", __func__);
|
dvbm_err("%s input cmd invalid\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -247,7 +272,8 @@ int rk_dvbm_ctrl(struct dvbm_port *port, enum dvbm_cmd cmd, void *arg)
|
|||||||
ctx = port_to_ctx(port);
|
ctx = port_to_ctx(port);
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case DVBM_ISP_SET_CFG: {
|
case DVBM_ISP_SET_CFG:
|
||||||
|
case DVBM_VPSS_SET_CFG: {
|
||||||
struct dvbm_isp_cfg_t *cfg = (struct dvbm_isp_cfg_t *)arg;
|
struct dvbm_isp_cfg_t *cfg = (struct dvbm_isp_cfg_t *)arg;
|
||||||
struct dvbm_addr_cfg *dvbm_adr;
|
struct dvbm_addr_cfg *dvbm_adr;
|
||||||
u32 chan_id = cfg->chan_id;
|
u32 chan_id = cfg->chan_id;
|
||||||
@@ -270,12 +296,14 @@ int rk_dvbm_ctrl(struct dvbm_port *port, enum dvbm_cmd cmd, void *arg)
|
|||||||
dvbm_adr->cbuf_sadr = cfg->dma_addr + cfg->cbuf_bot;
|
dvbm_adr->cbuf_sadr = cfg->dma_addr + cfg->cbuf_bot;
|
||||||
dvbm2enc_callback(ctx, DVBM_ISP_SET_DVBM_CFG, cfg);
|
dvbm2enc_callback(ctx, DVBM_ISP_SET_DVBM_CFG, cfg);
|
||||||
} break;
|
} break;
|
||||||
case DVBM_ISP_FRM_START: {
|
case DVBM_ISP_FRM_START:
|
||||||
|
case DVBM_VPSS_FRM_START: {
|
||||||
dvbm2enc_callback(ctx, DVBM_VEPU_NOTIFY_FRM_STR, arg);
|
dvbm2enc_callback(ctx, DVBM_VEPU_NOTIFY_FRM_STR, arg);
|
||||||
rk_dvbm_update_isp_frm_info(ctx, 0);
|
rk_dvbm_update_isp_frm_info(ctx, 0);
|
||||||
rk_dvbm_show_time(ctx);
|
rk_dvbm_show_time(ctx);
|
||||||
} break;
|
} break;
|
||||||
case DVBM_ISP_FRM_END: {
|
case DVBM_ISP_FRM_END:
|
||||||
|
case DVBM_VPSS_FRM_END: {
|
||||||
u32 line_cnt = ctx->isp_max_lcnt;
|
u32 line_cnt = ctx->isp_max_lcnt;
|
||||||
|
|
||||||
dvbm2enc_callback(ctx, DVBM_VEPU_NOTIFY_FRM_END, arg);
|
dvbm2enc_callback(ctx, DVBM_VEPU_NOTIFY_FRM_END, arg);
|
||||||
@@ -327,6 +355,7 @@ static int rk_dvbm_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct dvbm_ctx *ctx = NULL;
|
struct dvbm_ctx *ctx = NULL;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
dev_info(dev, "probe start\n");
|
dev_info(dev, "probe start\n");
|
||||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||||
@@ -334,8 +363,8 @@ static int rk_dvbm_probe(struct platform_device *pdev)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ctx->dev = dev;
|
ctx->dev = dev;
|
||||||
ctx->port_isp.dir = DVBM_ISP_PORT;
|
for (i = 0; i < DVBM_PORT_BUTT; i++)
|
||||||
ctx->port_vepu.dir = DVBM_VEPU_PORT;
|
ctx->ports[i].dir = (enum dvbm_port_dir)i;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, ctx);
|
platform_set_drvdata(pdev, ctx);
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
enum dvbm_port_dir {
|
enum dvbm_port_dir {
|
||||||
DVBM_ISP_PORT,
|
DVBM_ISP_PORT,
|
||||||
DVBM_VEPU_PORT,
|
DVBM_VEPU_PORT,
|
||||||
|
DVBM_VPSS_PORT,
|
||||||
|
DVBM_PORT_BUTT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dvbm_cmd {
|
enum dvbm_cmd {
|
||||||
@@ -26,14 +28,12 @@ enum dvbm_cmd {
|
|||||||
DVBM_VEPU_CMD_BASE = 0x10,
|
DVBM_VEPU_CMD_BASE = 0x10,
|
||||||
DVBM_VEPU_GET_ADR,
|
DVBM_VEPU_GET_ADR,
|
||||||
DVBM_VEPU_CMD_BUTT,
|
DVBM_VEPU_CMD_BUTT,
|
||||||
};
|
|
||||||
|
|
||||||
enum isp_frame_status {
|
DVBM_VPSS_CMD_BASE = 0x20,
|
||||||
ISP_FRAME_START,
|
DVBM_VPSS_SET_CFG,
|
||||||
ISP_FRAME_ONE_QUARTER,
|
DVBM_VPSS_FRM_START,
|
||||||
ISP_FRAME_HALF,
|
DVBM_VPSS_FRM_END,
|
||||||
ISP_FRAME_THREE_QUARTERS,
|
DVBM_VPSS_CMD_BUTT,
|
||||||
ISP_FRAME_FINISH,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dvbm_cb_event {
|
enum dvbm_cb_event {
|
||||||
@@ -51,6 +51,12 @@ enum dvbm_cb_event {
|
|||||||
DVBM_VEPU_NOTIFY_FRM_END,
|
DVBM_VEPU_NOTIFY_FRM_END,
|
||||||
DVBM_VEPU_NOTIFY_FRM_INFO,
|
DVBM_VEPU_NOTIFY_FRM_INFO,
|
||||||
DVBM_VEPU_EVENT_BUTT,
|
DVBM_VEPU_EVENT_BUTT,
|
||||||
|
|
||||||
|
DVBM_VPSS_EVENT_BASE = 0x20,
|
||||||
|
DVBM_VPSS_REQ_CONNECT,
|
||||||
|
DVBM_VPSS_REQ_DISCONNECT,
|
||||||
|
DVBM_VPSS_SET_DVBM_CFG,
|
||||||
|
DVBM_VPSS_EVENT_BUTT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dvbm_port {
|
struct dvbm_port {
|
||||||
|
|||||||
Reference in New Issue
Block a user