From 1f75f765a5d3f6794adecb775dfdf0956bc5a33b Mon Sep 17 00:00:00 2001 From: Mirela Rabulea Date: Wed, 12 Sep 2018 11:50:54 +0300 Subject: [PATCH] MLK-19362: media: csi: Fix "Hresponse" and "Rx fifo overflow" camera errors When the register setting for fifo_send_level is set to high, some residual data of a frame which cannot fill up to the send_level, will be sent with the next frame data. In this case, for CSI receive dma, sometimes, the vertical blanking is too short to finish the storage of the previous frame before the next frame start, depending on the system bandwidth. Tested on imx8mq-evk rev B4 and B3, with OV5640 camera. This patch was proposed by Tom Zheng Signed-off-by: Mirela Rabulea Reviewed-by: Robby Cai (cherry picked from commit 12f811f934b53008a445c3af67f1f22baea98a86) --- .../media/platform/mxc/capture/mx6s_capture.c | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/mxc/capture/mx6s_capture.c b/drivers/media/platform/mxc/capture/mx6s_capture.c index a3ce1ccb26d3..f57817ab2647 100644 --- a/drivers/media/platform/mxc/capture/mx6s_capture.c +++ b/drivers/media/platform/mxc/capture/mx6s_capture.c @@ -295,6 +295,11 @@ struct mx6s_csi_mux { u8 req_bit; }; +struct mx6s_csi_soc { + bool rx_fifo_rst; + int baseaddr_switch; +}; + struct mx6s_csi_dev { struct device *dev; struct video_device *vdev; @@ -341,7 +346,7 @@ struct mx6s_csi_dev { bool csi_mipi_mode; bool csi_two_8bit_sensor_mode; - const bool *rx_fifo_rst; + const struct mx6s_csi_soc *soc; struct mx6s_csi_mux csi_mux; }; @@ -447,7 +452,9 @@ static void csisw_reset(struct mx6s_csi_dev *csi_dev) isr = csi_read(csi_dev, CSI_CSISR); csi_write(csi_dev, isr, CSI_CSISR); - /* Ensable csi */ + cr18 |= csi_dev->soc->baseaddr_switch; + + /* Enable csi */ cr18 |= BIT_CSI_ENABLE; csi_write(csi_dev, cr18, CSI_CSICR18); } @@ -859,7 +866,7 @@ static int mx6s_configure_csi(struct mx6s_csi_dev *csi_dev) csi_write(csi_dev, cr1, CSI_CSICR1); cr18 = csi_read(csi_dev, CSI_CSICR18); - cr18 &= BIT_MIPI_DATA_FORMAT_MASK; + cr18 &= ~BIT_MIPI_DATA_FORMAT_MASK; cr18 |= BIT_DATA_FROM_MIPI; switch (csi_dev->fmt->pixelformat) { @@ -1104,7 +1111,7 @@ static irqreturn_t mx6s_csi_irq_handler(int irq, void *data) if (status & BIT_RFF_OR_INT) { dev_warn(csi_dev->dev, "%s Rx fifo overflow\n", __func__); - if (*csi_dev->rx_fifo_rst) + if (csi_dev->soc->rx_fifo_rst) csi_error_recovery(csi_dev); } @@ -1899,7 +1906,7 @@ static int mx6s_csi_probe(struct platform_device *pdev) of_id = of_match_node(mx6s_csi_dt_ids, csi_dev->dev->of_node); if (!of_id) return -EINVAL; - csi_dev->rx_fifo_rst = of_id->data; + csi_dev->soc = of_id->data; snprintf(csi_dev->v4l2_dev.name, sizeof(csi_dev->v4l2_dev.name), "CSI"); @@ -1999,15 +2006,28 @@ static const struct dev_pm_ops mx6s_csi_pm_ops = { SET_RUNTIME_PM_OPS(mx6s_csi_runtime_suspend, mx6s_csi_runtime_resume, NULL) }; -static const u8 mx6s_fifo_rst = true; -static const u8 mx6sl_fifo_rst = false; +static const struct mx6s_csi_soc mx6s_soc = { + .rx_fifo_rst = true, + .baseaddr_switch = 0, +}; +static const struct mx6s_csi_soc mx6sl_soc = { + .rx_fifo_rst = false, + .baseaddr_switch = 0, +}; +static const struct mx6s_csi_soc mx8mq_soc = { + .rx_fifo_rst = true, + .baseaddr_switch = 0x80030, +}; static const struct of_device_id mx6s_csi_dt_ids[] = { { .compatible = "fsl,imx6s-csi", - .data = &mx6s_fifo_rst, + .data = &mx6s_soc, }, { .compatible = "fsl,imx6sl-csi", - .data = &mx6sl_fifo_rst, + .data = &mx6sl_soc, + }, + { .compatible = "fsl,imx8mq-csi", + .data = &mx8mq_soc, }, { /* sentinel */ } }; -- 2.17.1