mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
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:
@@ -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*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user