From: Robby Cai Date: Wed, 23 May 2018 13:03:27 +0000 (+0800) Subject: MLK-18362-2 midea: mipi_csi: add mipi phy reset on imx8mm X-Git-Tag: rel_imx_4.19.35_1.1.0~751 X-Git-Url: https://git.somdevices.com/?a=commitdiff_plain;h=ce2ca652b113530cece2f5835a97a95013e36263;p=linux.git MLK-18362-2 midea: mipi_csi: add mipi phy reset on imx8mm on imx8mm, use different way rather than via SRC. so use different device id to distinguish different MIPI-PHY reset method. Signed-off-by: Robby Cai (cherry picked from commit 59e5fa6d4e8ad5c3d4fcd54aa8fa0a0d98e148b6) --- diff --git a/drivers/media/platform/mxc/capture/mxc_mipi_csi.c b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c index 90ff09600f74..cd94b79cb4e8 100644 --- a/drivers/media/platform/mxc/capture/mxc_mipi_csi.c +++ b/drivers/media/platform/mxc/capture/mxc_mipi_csi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -192,6 +193,9 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); #define GPR_MIPI_RESET 0x08 #define GPR_MIPI_S_RESETN BIT(16) +#define MIPI_CSIS_MISC 0x8008 + + #define DEFAULT_SCLK_CSIS_FREQ 166000000UL enum { @@ -331,6 +335,8 @@ static const struct csis_pix_format mipi_csis_formats[] = { } }; +typedef int (*mipi_csis_phy_reset_t)(struct csi_state *state); + #define mipi_csis_write(__csis, __r, __v) writel(__v, __csis->regs + __r) #define mipi_csis_read(__csis, __r) readl(__csis->regs + __r) @@ -386,6 +392,25 @@ static int mipi_csis_phy_init(struct csi_state *state) return ret; } +static int mipi_csis_phy_reset_mx8mm(struct csi_state *state) +{ + struct device_node *np; + void __iomem *reg; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-csi"); + if (WARN_ON(!np)) + return -ENXIO; + + reg = of_iomap(np, 0); + + writel(0, reg + MIPI_CSIS_MISC); + usleep_range(10, 20); + writel(0x30000, reg + MIPI_CSIS_MISC); + usleep_range(10, 20); + + return 0; +} + static int mipi_csis_phy_reset(struct csi_state *state) { struct device_node *np = state->dev->of_node; @@ -1033,6 +1058,8 @@ static int mipi_csis_probe(struct platform_device *pdev) struct v4l2_subdev *mipi_sd; struct resource *mem_res; struct csi_state *state; + const struct of_device_id *of_id; + mipi_csis_phy_reset_t phy_reset_fn; int ret = -ENOMEM; state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); @@ -1057,7 +1084,12 @@ static int mipi_csis_probe(struct platform_device *pdev) } mipi_csis_phy_init(state); - mipi_csis_phy_reset(state); + of_id = of_match_node(mipi_csis_of_match, dev->of_node); + if (!of_id || !of_id->data) + return -EINVAL; + + phy_reset_fn = of_id->data; + phy_reset_fn(state); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); state->regs = devm_ioremap_resource(dev, mem_res); @@ -1240,7 +1272,12 @@ static const struct dev_pm_ops mipi_csis_pm_ops = { }; static const struct of_device_id mipi_csis_of_match[] = { - { .compatible = "fsl,imx7d-mipi-csi",}, + { .compatible = "fsl,imx7d-mipi-csi", + .data = (void *)&mipi_csis_phy_reset, + }, + { .compatible = "fsl,imx8mm-mipi-csi", + .data = (void *)&mipi_csis_phy_reset_mx8mm, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mipi_csis_of_match);