#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/of_graph.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#define BIT_DATA_FROM_MIPI BIT(22)
#define BIT_MIPI_YU_SWAP BIT(21)
#define BIT_MIPI_DOUBLE_CMPNT BIT(20)
+#define BIT_MASK_OPTION_FIRST_FRAME (0 << 18)
+#define BIT_MASK_OPTION_CSI_EN (1 << 18)
+#define BIT_MASK_OPTION_SECOND_FRAME (2 << 18)
+#define BIT_MASK_OPTION_ON_DATA (3 << 18)
#define BIT_BASEADDR_CHG_ERR_EN BIT(9)
#define BIT_BASEADDR_SWITCH_SEL BIT(5)
#define BIT_BASEADDR_SWITCH_EN BIT(4)
#define CSI_CSICR18 0x48
#define CSI_CSICR19 0x4c
+enum imx_csi_model {
+ IMX7_CSI_IMX7 = 0,
+ IMX7_CSI_IMX8MQ,
+};
+
struct imx7_csi {
struct device *dev;
struct v4l2_subdev sd;
bool is_csi2;
struct completion last_eof_completion;
+
+ enum imx_csi_model model;
};
static struct imx7_csi *
clk_disable_unprepare(csi->mclk);
}
+static void imx7_csi_baseaddr_switch_on_second_frame(struct imx7_csi *csi)
+{
+ u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
+
+ cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
+ BIT_BASEADDR_CHG_ERR_EN;
+ cr18 |= BIT_MASK_OPTION_SECOND_FRAME;
+ imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
+}
+
static void imx7_csi_enable(struct imx7_csi *csi)
{
/* Clear the Rx FIFO and reflash the DMA controller. */
/* Enable the RxFIFO DMA and the CSI. */
imx7_csi_dmareq_rff_enable(csi);
imx7_csi_hw_enable(csi);
+
+ if (csi->model == IMX7_CSI_IMX8MQ)
+ imx7_csi_baseaddr_switch_on_second_frame(csi);
}
static void imx7_csi_disable(struct imx7_csi *csi)
if (IS_ERR(csi->regbase))
return PTR_ERR(csi->regbase);
+ csi->model = (enum imx_csi_model)(uintptr_t)of_device_get_match_data(&pdev->dev);
+
spin_lock_init(&csi->irqlock);
mutex_init(&csi->lock);
}
static const struct of_device_id imx7_csi_of_match[] = {
- { .compatible = "fsl,imx7-csi" },
- { .compatible = "fsl,imx6ul-csi" },
+ { .compatible = "fsl,imx8mq-csi", .data = (void *)IMX7_CSI_IMX8MQ },
+ { .compatible = "fsl,imx7-csi", .data = (void *)IMX7_CSI_IMX7 },
+ { .compatible = "fsl,imx6ul-csi", .data = (void *)IMX7_CSI_IMX7 },
{ },
};
MODULE_DEVICE_TABLE(of, imx7_csi_of_match);