media: platform: rockchip: cif: add lite vicap device

Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
Change-Id: I5251d677c6228cd6b09a0052cbb719a97c7fafd6
This commit is contained in:
Allon Huang
2020-07-20 20:31:21 +08:00
committed by Tao Huang
parent 00610f370e
commit b4ac25e9ea
5 changed files with 311 additions and 37 deletions

View File

@@ -1082,11 +1082,13 @@ static void rkcif_assign_new_buffer_pingpong(struct rkcif_stream *stream,
if (stream->curr_buf) {
rkcif_write_register(dev, frm0_addr_y,
stream->curr_buf->buff_addr[RKCIF_PLANE_Y]);
rkcif_write_register(dev, frm0_addr_uv,
stream->curr_buf->buff_addr[RKCIF_PLANE_CBCR]);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm0_addr_uv,
stream->curr_buf->buff_addr[RKCIF_PLANE_CBCR]);
} else {
rkcif_write_register(dev, frm0_addr_y, dummy_buf->dma_addr);
rkcif_write_register(dev, frm0_addr_uv, dummy_buf->dma_addr);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm0_addr_uv, dummy_buf->dma_addr);
}
if (!stream->next_buf) {
@@ -1100,11 +1102,13 @@ static void rkcif_assign_new_buffer_pingpong(struct rkcif_stream *stream,
if (stream->next_buf) {
rkcif_write_register(dev, frm1_addr_y,
stream->next_buf->buff_addr[RKCIF_PLANE_Y]);
rkcif_write_register(dev, frm1_addr_uv,
stream->next_buf->buff_addr[RKCIF_PLANE_CBCR]);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm1_addr_uv,
stream->next_buf->buff_addr[RKCIF_PLANE_CBCR]);
} else {
rkcif_write_register(dev, frm1_addr_y, dummy_buf->dma_addr);
rkcif_write_register(dev, frm1_addr_uv, dummy_buf->dma_addr);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm1_addr_uv, dummy_buf->dma_addr);
}
spin_unlock(&stream->vbq_lock);
} else {
@@ -1150,11 +1154,13 @@ static void rkcif_assign_new_buffer_pingpong(struct rkcif_stream *stream,
if (buffer) {
rkcif_write_register(dev, frm_addr_y,
buffer->buff_addr[RKCIF_PLANE_Y]);
rkcif_write_register(dev, frm_addr_uv,
buffer->buff_addr[RKCIF_PLANE_CBCR]);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm_addr_uv,
buffer->buff_addr[RKCIF_PLANE_CBCR]);
} else {
rkcif_write_register(dev, frm_addr_y, dummy_buf->dma_addr);
rkcif_write_register(dev, frm_addr_uv, dummy_buf->dma_addr);
if (dev->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_write_register(dev, frm_addr_uv, dummy_buf->dma_addr);
v4l2_dbg(1, rkcif_debug, &dev->v4l2_dev,
"frame Drop to dummy buf\n");
}
@@ -1561,9 +1567,9 @@ static void rkcif_buf_queue(struct vb2_buffer *vb)
cifbuf->buff_addr[i] = vb2_dma_contig_plane_dma_addr(vb, i);
if (rkcif_debug && addr && !stream->cifdev->iommu_en) {
memset(addr, 0, pixm->plane_fmt[i].sizeimage);
v4l2_info(&stream->cifdev->v4l2_dev,
"Clear buffer, size: 0x%08x\n",
pixm->plane_fmt[i].sizeimage);
v4l2_dbg(1, rkcif_debug, &stream->cifdev->v4l2_dev,
"Clear buffer, size: 0x%08x\n",
pixm->plane_fmt[i].sizeimage);
}
}
@@ -2093,7 +2099,8 @@ static int rkcif_start_streaming(struct vb2_queue *queue, unsigned int count)
}
if (dev->chip_id == CHIP_RK1808_CIF ||
dev->chip_id == CHIP_RV1126_CIF) {
dev->chip_id == CHIP_RV1126_CIF ||
dev->chip_id == CHIP_RV1126_CIF_LITE) {
if (dev->active_sensor->mbus.type == V4L2_MBUS_CSI2 ||
dev->active_sensor->mbus.type == V4L2_MBUS_CCP2)
ret = rkcif_csi_stream_start(stream);
@@ -2345,7 +2352,8 @@ static int rkcif_fh_open(struct file *filp)
* to reset cif once we hold buffers after buf queued
*/
if (cifdev->chip_id == CHIP_RK1808_CIF ||
cifdev->chip_id == CHIP_RV1126_CIF) {
cifdev->chip_id == CHIP_RV1126_CIF ||
cifdev->chip_id == CHIP_RV1126_CIF_LITE) {
mutex_lock(&cifdev->stream_lock);
if (!atomic_read(&cifdev->fh_cnt))
rkcif_soft_reset(cifdev, true);
@@ -2848,7 +2856,10 @@ int rkcif_register_lvds_subdev(struct rkcif_device *dev)
v4l2_subdev_init(sd, &rkcif_lvds_sd_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
sd->entity.ops = &rkcif_lvds_sd_media_ops;
snprintf(sd->name, sizeof(sd->name), "rkcif-lvds-subdev");
if (dev->chip_id == CHIP_RV1126_CIF)
snprintf(sd->name, sizeof(sd->name), "rkcif-lvds-subdev");
else
snprintf(sd->name, sizeof(sd->name), "rkcif-lite-lvds-subdev");
lvds_subdev->pads[RKCIF_LVDS_PAD_SINK].flags =
MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
@@ -3327,3 +3338,143 @@ void rkcif_irq_pingpong(struct rkcif_device *cif_dev)
}
}
}
void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev)
{
struct rkcif_stream *stream;
struct rkcif_buffer *active_buf = NULL;
struct v4l2_mbus_config *mbus = &cif_dev->active_sensor->mbus;
unsigned int intstat, i = 0xff;
if (mbus->type == V4L2_MBUS_CCP2 &&
cif_dev->chip_id == CHIP_RV1126_CIF_LITE) {
int mipi_id;
struct vb2_v4l2_buffer *vb_done = NULL;
u32 lastline = 0;
intstat = rkcif_read_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT);
lastline = rkcif_read_register(cif_dev, CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1);
/* clear all interrupts that has been triggered */
rkcif_write_register(cif_dev, CIF_REG_MIPI_LVDS_INTSTAT, intstat);
if (intstat & CSI_FIFO_OVERFLOW) {
v4l2_err(&cif_dev->v4l2_dev,
"ERROR: cif lite lvds fifo overflow, intstat:0x%x!!\n",
intstat);
return;
}
if (intstat & CSI_BANDWIDTH_LACK) {
v4l2_err(&cif_dev->v4l2_dev,
"ERROR: cif lite lvds bandwidth lack, intstat:0x%x!!\n",
intstat);
return;
}
if (intstat & CSI_ALL_ERROR_INTEN) {
v4l2_err(&cif_dev->v4l2_dev,
"ERROR: cif lite lvds all err:0x%x!!\n", intstat);
return;
}
if (intstat & CSI_FRAME0_START_ID0)
rkcif_lvds_event_inc_sof(cif_dev);
if (intstat & CSI_FRAME1_START_ID0)
rkcif_lvds_event_inc_sof(cif_dev);
/* if do not reach frame dma end, return irq */
mipi_id = rkcif_csi_g_mipi_id(&cif_dev->v4l2_dev, intstat);
if (mipi_id < 0)
return;
for (i = 0; i < RKCIF_MAX_STREAM_MIPI; i++) {
mipi_id = rkcif_csi_g_mipi_id(&cif_dev->v4l2_dev,
intstat);
if (mipi_id < 0)
continue;
stream = &cif_dev->stream[mipi_id];
if (stream->stopping) {
rkcif_stream_stop(stream);
stream->stopping = false;
wake_up(&stream->wq_stopped);
continue;
}
if (stream->state != RKCIF_STATE_STREAMING)
continue;
switch (mipi_id) {
case RKCIF_STREAM_MIPI_ID0:
stream->frame_phase = SW_FRM_END_ID0(intstat);
intstat &= ~CSI_FRAME_END_ID0;
break;
case RKCIF_STREAM_MIPI_ID1:
stream->frame_phase = SW_FRM_END_ID1(intstat);
intstat &= ~CSI_FRAME_END_ID1;
break;
case RKCIF_STREAM_MIPI_ID2:
stream->frame_phase = SW_FRM_END_ID2(intstat);
intstat &= ~CSI_FRAME_END_ID2;
break;
case RKCIF_STREAM_MIPI_ID3:
stream->frame_phase = SW_FRM_END_ID3(intstat);
intstat &= ~CSI_FRAME_END_ID3;
break;
}
stream->frame_idx++;
active_buf = NULL;
if (stream->frame_phase & CIF_CSI_FRAME1_READY) {
if (stream->next_buf)
active_buf = stream->next_buf;
} else if (stream->frame_phase & CIF_CSI_FRAME0_READY) {
if (stream->curr_buf)
active_buf = stream->curr_buf;
}
rkcif_assign_new_buffer_pingpong(stream, 0, mipi_id);
rkcif_luma_isr(&cif_dev->luma_vdev, mipi_id);
if (active_buf) {
vb_done = &active_buf->vb;
vb_done->vb2_buf.timestamp = ktime_get_ns();
vb_done->sequence = stream->frame_idx;
}
if (cif_dev->hdr.mode == NO_HDR) {
if (active_buf)
rkcif_vb_done_oneframe(stream, vb_done);
} else if (cif_dev->hdr.mode == HDR_X2) {
if (mipi_id == RKCIF_STREAM_MIPI_ID0) {
if (cif_dev->rdbk_buf[RDBK_L]) {
v4l2_err(&cif_dev->v4l2_dev,
"cif lite multiple long data in hdr frame,frm_idx:%d,state:0x%x\n",
stream->frame_idx,
cif_dev->rdbk_buf[RDBK_L]->vb.vb2_buf.state);
cif_dev->rdbk_buf[RDBK_L]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
rkcif_buf_queue(&cif_dev->rdbk_buf[RDBK_L]->vb.vb2_buf);
}
cif_dev->rdbk_buf[RDBK_L] = active_buf;
} else if (mipi_id == RKCIF_STREAM_MIPI_ID1) {
if (cif_dev->rdbk_buf[RDBK_S]) {
v4l2_err(&cif_dev->v4l2_dev,
"cif lite multiple short data in hdr frame, state:0x%x\n",
cif_dev->rdbk_buf[RDBK_S]->vb.vb2_buf.state);
cif_dev->rdbk_buf[RDBK_S]->vb.vb2_buf.state = VB2_BUF_STATE_ACTIVE;
rkcif_buf_queue(&cif_dev->rdbk_buf[RDBK_S]->vb.vb2_buf);
}
cif_dev->rdbk_buf[RDBK_S] = active_buf;
rdbk_frame_end(stream);
}
} else if (cif_dev->hdr.mode == HDR_X3) {
/*TODO: HDR_X3*/
}
}
}
}

View File

@@ -280,10 +280,15 @@ static int rkcif_create_links(struct rkcif_device *dev)
unsigned int s, pad, id, stream_num = 0;
if (dev->chip_id == CHIP_RK1808_CIF ||
dev->chip_id == CHIP_RV1126_CIF)
stream_num = RKCIF_MULTI_STREAMS_NUM;
else
dev->chip_id == CHIP_RV1126_CIF ||
dev->chip_id == CHIP_RV1126_CIF_LITE) {
if (dev->chip_id == CHIP_RV1126_CIF_LITE)
stream_num = RKCIF_MAX_STREAM_LVDS;
else
stream_num = RKCIF_MULTI_STREAMS_NUM;
} else {
stream_num = RKCIF_SINGLE_STREAM;
}
/* sensor links(or mipi-phy) */
for (s = 0; s < dev->num_sensors; ++s) {
@@ -340,7 +345,8 @@ static int rkcif_create_links(struct rkcif_device *dev)
sink_entity = &dev->stream[id].vnode.vdev.entity;
if ((dev->chip_id != CHIP_RK1808_CIF &&
dev->chip_id != CHIP_RV1126_CIF) |
dev->chip_id != CHIP_RV1126_CIF &&
dev->chip_id != CHIP_RV1126_CIF_LITE) |
(id == pad - 1))
flags = MEDIA_LNK_FL_ENABLED;
else
@@ -513,8 +519,13 @@ static int rkcif_register_platform_subdevs(struct rkcif_device *cif_dev)
int stream_num = 0, ret;
if (cif_dev->chip_id == CHIP_RK1808_CIF ||
cif_dev->chip_id == CHIP_RV1126_CIF) {
stream_num = RKCIF_MULTI_STREAMS_NUM;
cif_dev->chip_id == CHIP_RV1126_CIF ||
cif_dev->chip_id == CHIP_RV1126_CIF_LITE) {
if (cif_dev->chip_id == CHIP_RV1126_CIF_LITE)
stream_num = RKCIF_MAX_STREAM_LVDS;
else
stream_num = RKCIF_MULTI_STREAMS_NUM;
ret = rkcif_register_stream_vdevs(cif_dev, stream_num,
true);
} else {
@@ -750,10 +761,7 @@ static const struct cif_reg rk3368_cif_regs[] = {
static const char * const rv1126_cif_clks[] = {
"aclk_cif",
"hclk_cif",
"aclk_cif_lite",
"hclk_cif_lite",
"dclk_cif",
"dclk_cif_lite",
};
static const char * const rv1126_cif_rsts[] = {
@@ -763,10 +771,6 @@ static const char * const rv1126_cif_rsts[] = {
"rst_cif_p",
"rst_cif_i",
"rst_cif_rx_p",
"rst_cif_lite_a",
"rst_cif_lite_h",
"rst_cif_lite_d",
"rst_cif_lite_rx_p",
};
static const struct cif_reg rv1126_cif_regs[] = {
@@ -859,6 +863,76 @@ static const struct cif_reg rv1126_cif_regs[] = {
[CIF_REG_Y_STAT_VALUE] = CIF_REG(CIF_Y_STAT_VALUE),
};
static const char * const rv1126_cif_lite_clks[] = {
"aclk_cif_lite",
"hclk_cif_lite",
"dclk_cif_lite",
};
static const char * const rv1126_cif_lite_rsts[] = {
"rst_cif_lite_a",
"rst_cif_lite_h",
"rst_cif_lite_d",
"rst_cif_lite_rx_p",
};
static const struct cif_reg rv1126_cif_lite_regs[] = {
[CIF_REG_MIPI_LVDS_ID0_CTRL0] = CIF_REG(CIF_CSI_ID0_CTRL0),
[CIF_REG_MIPI_LVDS_ID0_CTRL1] = CIF_REG(CIF_CSI_ID0_CTRL1),
[CIF_REG_MIPI_LVDS_ID1_CTRL0] = CIF_REG(CIF_CSI_ID1_CTRL0),
[CIF_REG_MIPI_LVDS_ID1_CTRL1] = CIF_REG(CIF_CSI_ID1_CTRL1),
[CIF_REG_MIPI_LVDS_ID2_CTRL0] = CIF_REG(CIF_CSI_ID2_CTRL0),
[CIF_REG_MIPI_LVDS_ID2_CTRL1] = CIF_REG(CIF_CSI_ID2_CTRL1),
[CIF_REG_MIPI_LVDS_ID3_CTRL0] = CIF_REG(CIF_CSI_ID3_CTRL0),
[CIF_REG_MIPI_LVDS_ID3_CTRL1] = CIF_REG(CIF_CSI_ID3_CTRL1),
[CIF_REG_MIPI_LVDS_CTRL] = CIF_REG(CIF_CSI_MIPI_LVDS_CTRL),
[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID0] = CIF_REG(CIF_CSI_FRM0_ADDR_Y_ID0),
[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID0] = CIF_REG(CIF_CSI_FRM1_ADDR_Y_ID0),
[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID0] = CIF_REG(CIF_CSI_FRM0_VLW_Y_ID0),
[CIF_REG_MIPI_LVDS_FRAME1_VLW_Y_ID0] = CIF_REG(CIF_CSI_FRM1_VLW_Y_ID0),
[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID1] = CIF_REG(CIF_CSI_FRM0_ADDR_Y_ID1),
[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID1] = CIF_REG(CIF_CSI_FRM1_ADDR_Y_ID1),
[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID1] = CIF_REG(CIF_CSI_FRM0_VLW_Y_ID1),
[CIF_REG_MIPI_LVDS_FRAME1_VLW_Y_ID1] = CIF_REG(CIF_CSI_FRM1_VLW_Y_ID1),
[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID2] = CIF_REG(CIF_CSI_FRM0_ADDR_Y_ID2),
[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID2] = CIF_REG(CIF_CSI_FRM1_ADDR_Y_ID2),
[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID2] = CIF_REG(CIF_CSI_FRM0_VLW_Y_ID2),
[CIF_REG_MIPI_LVDS_FRAME1_VLW_Y_ID2] = CIF_REG(CIF_CSI_FRM1_VLW_Y_ID2),
[CIF_REG_MIPI_LVDS_FRAME0_ADDR_Y_ID3] = CIF_REG(CIF_CSI_FRM0_ADDR_Y_ID3),
[CIF_REG_MIPI_LVDS_FRAME1_ADDR_Y_ID3] = CIF_REG(CIF_CSI_FRM1_ADDR_Y_ID3),
[CIF_REG_MIPI_LVDS_FRAME0_VLW_Y_ID3] = CIF_REG(CIF_CSI_FRM0_VLW_Y_ID3),
[CIF_REG_MIPI_LVDS_FRAME1_VLW_Y_ID3] = CIF_REG(CIF_CSI_FRM1_VLW_Y_ID3),
[CIF_REG_MIPI_LVDS_INTEN] = CIF_REG(CIF_CSI_INTEN),
[CIF_REG_MIPI_LVDS_INTSTAT] = CIF_REG(CIF_CSI_INTSTAT),
[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID0_1] = CIF_REG(CIF_CSI_LINE_INT_NUM_ID0_1),
[CIF_REG_MIPI_LVDS_LINE_INT_NUM_ID2_3] = CIF_REG(CIF_CSI_LINE_INT_NUM_ID2_3),
[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID0_1] = CIF_REG(CIF_CSI_LINE_CNT_ID0_1),
[CIF_REG_MIPI_LVDS_LINE_LINE_CNT_ID2_3] = CIF_REG(CIF_CSI_LINE_CNT_ID2_3),
[CIF_REG_MIPI_LVDS_ID0_CROP_START] = CIF_REG(CIF_CSI_ID0_CROP_START),
[CIF_REG_MIPI_LVDS_ID1_CROP_START] = CIF_REG(CIF_CSI_ID1_CROP_START),
[CIF_REG_MIPI_LVDS_ID2_CROP_START] = CIF_REG(CIF_CSI_ID2_CROP_START),
[CIF_REG_MIPI_LVDS_ID3_CROP_START] = CIF_REG(CIF_CSI_ID3_CROP_START),
[CIF_REG_LVDS_SAV_EAV_ACT0_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID0),
[CIF_REG_LVDS_SAV_EAV_BLK0_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID0),
[CIF_REG_LVDS_SAV_EAV_ACT1_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID0),
[CIF_REG_LVDS_SAV_EAV_BLK1_ID0] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID0),
[CIF_REG_LVDS_SAV_EAV_ACT0_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID1),
[CIF_REG_LVDS_SAV_EAV_BLK0_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID1),
[CIF_REG_LVDS_SAV_EAV_ACT1_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID1),
[CIF_REG_LVDS_SAV_EAV_BLK1_ID1] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID1),
[CIF_REG_LVDS_SAV_EAV_ACT0_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID2),
[CIF_REG_LVDS_SAV_EAV_BLK0_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID2),
[CIF_REG_LVDS_SAV_EAV_ACT1_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID2),
[CIF_REG_LVDS_SAV_EAV_BLK1_ID2] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID2),
[CIF_REG_LVDS_SAV_EAV_ACT0_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_ACT0_ID3),
[CIF_REG_LVDS_SAV_EAV_BLK0_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_BLK0_ID3),
[CIF_REG_LVDS_SAV_EAV_ACT1_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_ACT1_ID3),
[CIF_REG_LVDS_SAV_EAV_BLK1_ID3] = CIF_REG(CIF_LVDS_SAV_EAV_BLK1_ID3),
[CIF_REG_Y_STAT_CONTROL] = CIF_REG(CIF_Y_STAT_CONTROL),
[CIF_REG_Y_STAT_VALUE] = CIF_REG(CIF_Y_STAT_VALUE),
};
static const struct cif_match_data px30_cif_match_data = {
.chip_id = CHIP_PX30_CIF,
.clks = px30_cif_clks,
@@ -922,6 +996,15 @@ static const struct cif_match_data rv1126_cif_match_data = {
.cif_regs = rv1126_cif_regs,
};
static const struct cif_match_data rv1126_cif_lite_match_data = {
.chip_id = CHIP_RV1126_CIF_LITE,
.clks = rv1126_cif_lite_clks,
.clks_num = ARRAY_SIZE(rv1126_cif_lite_clks),
.rsts = rv1126_cif_lite_rsts,
.rsts_num = ARRAY_SIZE(rv1126_cif_lite_rsts),
.cif_regs = rv1126_cif_lite_regs,
};
static const struct of_device_id rkcif_plat_of_match[] = {
{
.compatible = "rockchip,px30-cif",
@@ -951,6 +1034,10 @@ static const struct of_device_id rkcif_plat_of_match[] = {
.compatible = "rockchip,rv1126-cif",
.data = &rv1126_cif_match_data,
},
{
.compatible = "rockchip,rv1126-cif-lite",
.data = &rv1126_cif_lite_match_data,
},
{},
};
@@ -967,6 +1054,17 @@ static irqreturn_t rkcif_irq_handler(int irq, void *ctx)
return IRQ_HANDLED;
}
static irqreturn_t rkcif_irq_lite_handler(int irq, void *ctx)
{
struct device *dev = ctx;
struct rkcif_device *cif_dev = dev_get_drvdata(dev);
rkcif_irq_lite_lvds(cif_dev);
return IRQ_HANDLED;
}
static void rkcif_disable_sys_clk(struct rkcif_device *cif_dev)
{
int i;
@@ -1055,6 +1153,7 @@ static int rkcif_plat_probe(struct platform_device *pdev)
const struct cif_match_data *data;
struct resource *res;
int i, ret, irq;
char name[V4L2_DEVICE_NAME_SIZE] = {'\0'};
sprintf(rkcif_version, "v%02x.%02x.%02x",
RKCIF_DRIVER_VERSION >> 16,
@@ -1066,6 +1165,7 @@ static int rkcif_plat_probe(struct platform_device *pdev)
match = of_match_node(rkcif_plat_of_match, node);
if (IS_ERR(match))
return PTR_ERR(match);
data = match->data;
cif_dev = devm_kzalloc(dev, sizeof(*cif_dev), GFP_KERNEL);
if (!cif_dev)
@@ -1078,18 +1178,25 @@ static int rkcif_plat_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
ret = devm_request_irq(dev, irq, rkcif_irq_handler, IRQF_SHARED,
dev_driver_string(dev), dev);
if (data->chip_id == CHIP_RV1126_CIF_LITE)
ret = devm_request_irq(dev, irq, rkcif_irq_lite_handler,
IRQF_SHARED,
dev_driver_string(dev), dev);
else
ret = devm_request_irq(dev, irq, rkcif_irq_handler,
IRQF_SHARED,
dev_driver_string(dev), dev);
if (ret < 0) {
dev_err(dev, "request irq failed: %d\n", ret);
return ret;
}
cif_dev->irq = irq;
data = match->data;
cif_dev->chip_id = data->chip_id;
if (data->chip_id == CHIP_RK1808_CIF ||
data->chip_id == CHIP_RV1126_CIF) {
data->chip_id == CHIP_RV1126_CIF ||
data->chip_id == CHIP_RV1126_CIF_LITE) {
res = platform_get_resource_byname(pdev,
IORESOURCE_MEM,
"cif_regs");
@@ -1155,12 +1262,14 @@ static int rkcif_plat_probe(struct platform_device *pdev)
cif_dev->pipe.set_stream = rkcif_pipeline_set_stream;
if (data->chip_id == CHIP_RK1808_CIF ||
data->chip_id == CHIP_RV1126_CIF) {
data->chip_id == CHIP_RV1126_CIF ||
data->chip_id == CHIP_RV1126_CIF_LITE) {
rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID0);
rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID1);
rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID2);
rkcif_stream_init(cif_dev, RKCIF_STREAM_MIPI_ID3);
rkcif_stream_init(cif_dev, RKCIF_STREAM_DVP);
if (data->chip_id != CHIP_RV1126_CIF_LITE)
rkcif_stream_init(cif_dev, RKCIF_STREAM_DVP);
} else {
rkcif_stream_init(cif_dev, RKCIF_STREAM_CIF);
}
@@ -1173,12 +1282,17 @@ static int rkcif_plat_probe(struct platform_device *pdev)
cif_dev->workmode = RKCIF_WORKMODE_PINGPONG;
#endif
strlcpy(cif_dev->media_dev.model, "rkcif",
if (data->chip_id == CHIP_RV1126_CIF_LITE)
strncpy(name, "rkcif_lite", strlen("rkcif_lite"));
else
strncpy(name, "rkcif", strlen("rkcif"));
strlcpy(cif_dev->media_dev.model, name,
sizeof(cif_dev->media_dev.model));
cif_dev->media_dev.dev = &pdev->dev;
v4l2_dev = &cif_dev->v4l2_dev;
v4l2_dev->mdev = &cif_dev->media_dev;
strlcpy(v4l2_dev->name, "rkcif", sizeof(v4l2_dev->name));
strlcpy(v4l2_dev->name, name, sizeof(v4l2_dev->name));
v4l2_ctrl_handler_init(&cif_dev->ctrl_handler, 8);
v4l2_dev->ctrl_handler = &cif_dev->ctrl_handler;
@@ -1199,7 +1313,8 @@ static int rkcif_plat_probe(struct platform_device *pdev)
if (ret < 0)
goto err_unreg_media_dev;
if (data->chip_id == CHIP_RV1126_CIF)
if (data->chip_id == CHIP_RV1126_CIF ||
data->chip_id == CHIP_RV1126_CIF_LITE)
rkcif_register_luma_vdev(&cif_dev->luma_vdev, v4l2_dev, cif_dev);
cif_dev->iommu_en = is_iommu_enable(dev);
@@ -1244,6 +1359,8 @@ static int rkcif_plat_remove(struct platform_device *pdev)
if (cif_dev->chip_id == CHIP_RK1808_CIF ||
cif_dev->chip_id == CHIP_RV1126_CIF)
stream_num = RKCIF_MULTI_STREAMS_NUM;
else if (cif_dev->chip_id == CHIP_RV1126_CIF_LITE)
stream_num = RKCIF_MAX_STREAM_LVDS;
else
stream_num = RKCIF_SINGLE_STREAM;
rkcif_unregister_stream_vdevs(cif_dev, stream_num);

View File

@@ -41,6 +41,7 @@
#define RKCIF_STREAM_MIPI_ID2 2
#define RKCIF_STREAM_MIPI_ID3 3
#define RKCIF_MAX_STREAM_MIPI 4
#define RKCIF_MAX_STREAM_LVDS 4
#define RKCIF_STREAM_DVP 4
#define RKCIF_MAX_BUS_CLK 8
@@ -93,6 +94,7 @@ enum rkcif_chip_id {
CHIP_RK3328_CIF,
CHIP_RK3368_CIF,
CHIP_RV1126_CIF,
CHIP_RV1126_CIF_LITE,
};
enum host_type_t {
@@ -388,5 +390,6 @@ void rkcif_soft_reset(struct rkcif_device *cif_dev,
bool is_rst_iommu);
int rkcif_register_lvds_subdev(struct rkcif_device *dev);
void rkcif_unregister_lvds_subdev(struct rkcif_device *dev);
void rkcif_irq_lite_lvds(struct rkcif_device *cif_dev);
#endif

View File

@@ -448,6 +448,8 @@ enum cif_reg_index {
#define CSI_LINE_ID1_INTST (0x1 << 22)
#define CSI_LINE_ID2_INTST (0x1 << 23)
#define CSI_LINE_ID3_INTST (0x1 << 24)
#define CSI_DMA_LVDS_ID2_FIFO_OVERFLOW (0x1 << 25)
#define CSI_DMA_LVDS_ID3_FIFO_OVERFLOW (0x1 << 26)
#define CSI_FRAME_END_ID0 (CSI_FRAME0_END_ID0 |\
CSI_FRAME1_END_ID0)

View File

@@ -30,6 +30,7 @@
*4. add luma device node for rv1126 vicap
*v0.1.4
*1. support vicap-full lvds interface to work in linear and hdr mode for rv1126
*2. add vicap-lite device for rv1126
*/
#define RKCIF_DRIVER_VERSION KERNEL_VERSION(0, 1, 0x4)