media: rockchip: isp: switch hdr frame mode for read back

Change-Id: I4077f35579023b30e42952dd2c2ac917b49cbfbf
Signed-off-by: Cai YiWei <cyw@rock-chips.com>
This commit is contained in:
Cai YiWei
2020-08-24 15:11:39 +08:00
committed by Tao Huang
parent af20c0f5f6
commit 10232a98b0
8 changed files with 62 additions and 39 deletions

View File

@@ -733,8 +733,8 @@ void rkisp_bridge_isr(u32 *mis_val, struct rkisp_device *dev)
/* dmarx isr is unreliable, MI frame end to replace it */
if (*mis_val & (MI_MP_FRAME | MI_MPFBC_FRAME) &&
IS_HDR_RDBK(dev->hdr.op_mode)) {
switch (dev->hdr.op_mode) {
IS_HDR_RDBK(dev->csi_dev.rd_mode)) {
switch (dev->csi_dev.rd_mode) {
case HDR_RDBK_FRAME3://for rd1 rd0 rd2
val |= RAW1_RD_FRAME;
/* FALLTHROUGH */

View File

@@ -3227,7 +3227,7 @@ void rkisp_mi_isr(u32 mis_val, struct rkisp_device *dev)
end_tx0 = false;
end_tx1 = false;
end_tx2 = false;
rkisp_trigger_read_back(&dev->csi_dev, false);
rkisp_trigger_read_back(&dev->csi_dev, false, false);
}
}
}

View File

@@ -133,7 +133,6 @@ static int rkisp_csi_s_stream(struct v4l2_subdev *sd, int on)
struct rkisp_device *dev = csi->ispdev;
memset(csi->tx_first, 0, sizeof(csi->tx_first));
memset(csi->filt_state, 0, sizeof(csi->filt_state));
if (!IS_HDR_RDBK(dev->hdr.op_mode))
return 0;
@@ -452,10 +451,11 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
rkisp_write(dev, CSI2RX_MASK_STAT, 0x7FFFFF7F, true);
}
if (IS_HDR_RDBK(dev->hdr.op_mode))
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
dev->csi_dev.rd_mode = dev->hdr.op_mode;
rkisp_set_bits(dev, CTRL_SWS_CFG,
0, SW_MPIP_DROP_FRM_DIS, true);
dev->csi_dev.is_isp_end = true;
}
return ret;
}
@@ -463,32 +463,38 @@ int rkisp_csi_config_patch(struct rkisp_device *dev)
* for hdr read back mode, rawrd read back data
* this will update rawrd base addr to shadow.
*/
void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm)
void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm, u32 mode)
{
struct rkisp_device *dev = csi->ispdev;
struct rkisp_hw_dev *hw = dev->hw_dev;
struct rkisp_isp_params_vdev *params_vdev = &dev->params_vdev;
u32 val, cur_frame_id;
u32 val, cur_frame_id, tmp;
bool is_upd = false;
rkisp_dmarx_get_frame(dev, &cur_frame_id, NULL, true);
if (dma2frm > 2)
dma2frm = 2;
memset(csi->filt_state, 0, sizeof(csi->filt_state));
switch (dev->hdr.op_mode) {
case HDR_RDBK_FRAME3://is rawrd1 rawrd0 rawrd2
csi->filt_state[CSI_F_RD1] = dma2frm;
case HDR_RDBK_FRAME2://is rawrd0 and rawrd2
csi->filt_state[CSI_F_RD0] = dma2frm;
case HDR_RDBK_FRAME1://only rawrd2
csi->filt_state[CSI_F_RD2] = dma2frm;
break;
default://other no support readback
return;
}
/* configure hdr params in rdbk mode */
rkisp_params_cfg(params_vdev, cur_frame_id, dma2frm + 1);
val = 0;
if (mode & T_START_X1) {
csi->rd_mode = HDR_RDBK_FRAME1;
} else if (mode & T_START_X2) {
csi->rd_mode = HDR_RDBK_FRAME2;
val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX2;
} else if (mode & T_START_X3) {
csi->rd_mode = HDR_RDBK_FRAME3;
val = SW_HDRMGE_EN | SW_HDRMGE_MODE_FRAMEX3;
}
tmp = rkisp_read(dev, ISP_HDRMGE_BASE, false) & 0xf;
if (val != tmp) {
rkisp_write(dev, ISP_HDRMGE_BASE, val, false);
is_upd = true;
}
if (!hw->is_single) {
rkisp_update_regs(dev, CTRL_VI_ISP_PATH, SUPER_IMP_COLOR_CR);
rkisp_update_regs(dev, ISP_ACQ_PROP, CSI2RX_VERSION);
@@ -499,7 +505,9 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm)
val = ISP_LSC_LUT_EN | ISP_LSC_EN;
rkisp_set_bits(dev, ISP_LSC_CTRL, val, val, true);
}
is_upd = true;
}
if (is_upd) {
val = rkisp_read(dev, ISP_CTRL, false);
val |= CIF_ISP_CTRL_ISP_CFG_UPD;
rkisp_write(dev, ISP_CTRL, val, true);
@@ -507,15 +515,13 @@ void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm)
/* wait 50 us to load lsc table, otherwise lsc lut error will occur */
udelay(50);
}
/* not using isp V_START irq to generate sof event */
csi->filt_state[CSI_F_VS] = dma2frm + 1;
v4l2_dbg(2, rkisp_debug, &dev->v4l2_dev,
"readback frame:%d time:%d\n",
cur_frame_id, dma2frm + 1);
val = rkisp_read(dev, CSI2RX_CTRL0, true);
val &= ~SW_IBUF_OP_MODE(0xf);
val |= SW_CSI2RX_EN | SW_DMA_2FRM_MODE(dma2frm) |
SW_IBUF_OP_MODE(dev->hdr.op_mode);
SW_IBUF_OP_MODE(csi->rd_mode);
rkisp_write(dev, CSI2RX_CTRL0, val, true);
}
@@ -527,6 +533,7 @@ static void rkisp_dev_trigger_handle(struct rkisp_device *dev, u32 cmd)
unsigned long lock_flags = 0;
int i, times = -1, max = 0, id = 0;
int len[DEV_MAX] = { 0 };
u32 mode = 0;
spin_lock_irqsave(&hw->rdbk_lock, lock_flags);
if (cmd == T_CMD_END)
@@ -553,6 +560,7 @@ static void rkisp_dev_trigger_handle(struct rkisp_device *dev, u32 cmd)
isp->dmarx_dev.pre_frame = isp->dmarx_dev.cur_frame;
isp->dmarx_dev.cur_frame.id = t.frame_id;
isp->dmarx_dev.cur_frame.timestamp = t.frame_timestamp;
mode = t.mode;
times = t.times;
hw->cur_dev_id = id;
hw->is_idle = false;
@@ -560,7 +568,7 @@ static void rkisp_dev_trigger_handle(struct rkisp_device *dev, u32 cmd)
end:
spin_unlock_irqrestore(&hw->rdbk_lock, lock_flags);
if (times >= 0)
rkisp_trigger_read_back(&isp->csi_dev, times);
rkisp_trigger_read_back(&isp->csi_dev, times, mode);
}
/* handle read back event from user or isp idle isr */

View File

@@ -70,10 +70,8 @@ struct sink_info {
* rdbk_kfifo: read back event fifo
* rdbk_lock: lock for read back event
* mipi_di: Data Identifier (vc[7:6],dt[5:0])
* filt_state: multiframe read back mode to filt irq event
* tx_first: flags for dmatx first Y_STATE irq
* memory: compact or big/little endian byte order for tx/rx
* is_isp_end: flags of isp frame end
*/
struct rkisp_csi_device {
struct rkisp_device *ispdev;
@@ -83,11 +81,10 @@ struct rkisp_csi_device {
struct kfifo rdbk_kfifo;
spinlock_t rdbk_lock;
int max_pad;
u32 rd_mode;
u8 mipi_di[CSI_PAD_MAX - 1];
u8 filt_state[CSI_F_MAX];
u8 tx_first[HDR_DMA_MAX];
u8 memory;
bool is_isp_end;
};
int rkisp_register_csi_subdev(struct rkisp_device *dev,
@@ -95,7 +92,7 @@ int rkisp_register_csi_subdev(struct rkisp_device *dev,
void rkisp_unregister_csi_subdev(struct rkisp_device *dev);
int rkisp_csi_config_patch(struct rkisp_device *dev);
void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm);
void rkisp_trigger_read_back(struct rkisp_csi_device *csi, u8 dma2frm, u32 mode);
int rkisp_csi_trigger_event(struct rkisp_device *dev, u32 cmd, void *arg);
void rkisp_csi_sof(struct rkisp_device *dev, u8 id);
#endif

View File

@@ -948,7 +948,7 @@ void rkisp_dmarx_get_frame(struct rkisp_device *dev,
}
spin_lock_irqsave(&dev->csi_dev.rdbk_lock, flag);
if (sync || dev->csi_dev.is_isp_end) {
if (sync) {
frame_id = dev->dmarx_dev.cur_frame.id;
frame_timestamp = dev->dmarx_dev.cur_frame.timestamp;
} else {

View File

@@ -3435,8 +3435,8 @@ isp_gain_config(struct rkisp_isp_params_vdev *params_vdev,
u32 value, i, gain_wsize;
u8 tmo_en, mge_en;
if (dev->hdr.op_mode != HDR_NORMAL &&
dev->hdr.op_mode != HDR_RDBK_FRAME1) {
if (dev->csi_dev.rd_mode != HDR_NORMAL &&
dev->csi_dev.rd_mode != HDR_RDBK_FRAME1) {
tmo_en = 1;
mge_en = 1;
} else {
@@ -4255,7 +4255,7 @@ rkisp_params_cfg_v2x(struct rkisp_isp_params_vdev *params_vdev,
cur_buf = list_first_entry(&params_vdev->params,
struct rkisp_buffer, queue);
if (!IS_HDR_RDBK(dev->hdr.op_mode)) {
if (!IS_HDR_RDBK(dev->csi_dev.rd_mode)) {
list_del(&cur_buf->queue);
break;
}
@@ -4312,13 +4312,13 @@ rkisp_params_isr_v2x(struct rkisp_isp_params_vdev *params_vdev,
return;
params_vdev->rdbk_times--;
if (IS_HDR_RDBK(dev->hdr.op_mode) && !params_vdev->rdbk_times) {
if (IS_HDR_RDBK(dev->csi_dev.rd_mode) && !params_vdev->rdbk_times) {
rkisp_params_cfg_v2x(params_vdev, cur_frame_id, 0, RKISP_PARAMS_SHD);
return;
}
}
if ((isp_mis & CIF_ISP_FRAME) && !IS_HDR_RDBK(dev->hdr.op_mode))
if ((isp_mis & CIF_ISP_FRAME) && !IS_HDR_RDBK(dev->csi_dev.rd_mode))
rkisp_params_cfg_v2x(params_vdev, cur_frame_id, 0, RKISP_PARAMS_ALL);
}

View File

@@ -2162,9 +2162,7 @@ void rkisp_isp_isr(unsigned int isp_mis,
/* start edge of v_sync */
if (isp_mis & CIF_ISP_V_START) {
rkisp_set_state(dev, ISP_FRAME_VS);
dev->csi_dev.is_isp_end = false;
/* filt v_sync when frame read back mode */
if (dev->csi_dev.filt_state[CSI_F_VS]) {
if (IS_HDR_RDBK(dev->hdr.op_mode)) {
rkisp_stats_rdbk_enable(&dev->stats_vdev, true);
goto vs_skip;
}

View File

@@ -151,11 +151,31 @@
#define ISP2X_THUNDERBOOT_VIDEO_BUF_NUM 30
/* trigger event mode
* T_TRY: trigger maybe with retry
* T_TRY_YES: trigger to retry
* T_TRY_NO: trigger no to retry
*
* T_START_X1: isp read one frame
* T_START_X2: isp read hdr two frame
* T_START_X3: isp read hdr three frame
*/
enum isp2x_trigger_mode {
T_TRY = BIT(0),
T_TRY_YES = BIT(1),
T_TRY_NO = BIT(2),
T_START_X1 = BIT(4),
T_START_X2 = BIT(5),
T_START_X3 = BIT(6),
};
struct isp2x_csi_trigger {
/* timestamp in ns */
u64 frame_timestamp;
u32 frame_id;
int times;
enum isp2x_trigger_mode mode;
} __attribute__ ((packed));
enum isp2x_csi_memory {