LKML Archive on lore.kernel.org
 help / color / Atom feed
* [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host
@ 2018-10-19 12:52 Luis Oliveira
  2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
                   ` (3 more replies)
  0 siblings, 4 replies; 26+ messages in thread
From: Luis Oliveira @ 2018-10-19 12:52 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: joao.pinto, festevam, Luis Oliveira, Mauro Carvalho Chehab,
	Luis Oliveira, Hans Verkuil, Laurent Pinchart, Arnd Bergmann,
	Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov

This adds support for Synopsys MIPI CSI-2 Host and MIPI D-PHY.
The patch series include support for initialization/configuration of the
DW MIPI CSI-2 controller and DW MIPI D-PHY and both include a reference
platform driver. This way the future PCI integration will be clean.

This will enable future SoCs to use this standard approach and possibly
create a more clean environment.

This series also documents the dt-bindings needed for the platform drivers.

This was applied in: https://git.linuxtv.org/media_tree.git

Luis Oliveira (4):
  Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx
    bindings
  media: platform: dwc: Add DW MIPI DPHY Rx platform
  Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2
    Host
  media: platform: dwc: Add MIPI CSI-2 controller driver

 .../devicetree/bindings/media/snps,dw-csi-plat.txt |  52 ++
 .../devicetree/bindings/phy/snps,dphy-rx.txt       |  28 +
 MAINTAINERS                                        |  11 +
 drivers/media/platform/Kconfig                     |   1 +
 drivers/media/platform/Makefile                    |   3 +
 drivers/media/platform/dwc/Kconfig                 |  52 ++
 drivers/media/platform/dwc/Makefile                |   4 +
 drivers/media/platform/dwc/dw-csi-plat.c           | 699 +++++++++++++++++++++
 drivers/media/platform/dwc/dw-csi-plat.h           |  77 +++
 drivers/media/platform/dwc/dw-dphy-plat.c          | 347 ++++++++++
 drivers/media/platform/dwc/dw-dphy-rx.c            | 596 ++++++++++++++++++
 drivers/media/platform/dwc/dw-dphy-rx.h            | 181 ++++++
 drivers/media/platform/dwc/dw-mipi-csi.c           | 494 +++++++++++++++
 drivers/media/platform/dwc/dw-mipi-csi.h           | 202 ++++++
 include/media/dwc/dw-mipi-csi-pltfrm.h             | 102 +++
 15 files changed, 2849 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
 create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
 create mode 100644 drivers/media/platform/dwc/Kconfig
 create mode 100644 drivers/media/platform/dwc/Makefile
 create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
 create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
 create mode 100644 drivers/media/platform/dwc/dw-dphy-plat.c
 create mode 100644 drivers/media/platform/dwc/dw-dphy-rx.c
 create mode 100644 drivers/media/platform/dwc/dw-dphy-rx.h
 create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
 create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
 create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h

--
2.7.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings
  2018-10-19 12:52 [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host Luis Oliveira
@ 2018-10-19 12:52 ` Luis Oliveira
  2018-10-24 17:36   ` Rob Herring
  2018-11-14 20:08   ` Laurent Pinchart
  2018-10-19 12:52 ` [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform Luis Oliveira
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 26+ messages in thread
From: Luis Oliveira @ 2018-10-19 12:52 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: joao.pinto, festevam, Luis Oliveira, Luis Oliveira, Rob Herring,
	Mark Rutland, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

Add device-tree bindings documentation for SNPS DesignWare MIPI D-PHY in
RX mode.

Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
---
Changelog
v2-V3
- removed gpios reference - it was for a separated driver
- changed address to show complete address

 .../devicetree/bindings/phy/snps,dphy-rx.txt       | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt

diff --git a/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
new file mode 100644
index 0000000..03d17ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
@@ -0,0 +1,28 @@
+Synopsys DesignWare MIPI Rx D-PHY block details
+
+Description
+-----------
+
+The Synopsys MIPI D-PHY controller supports MIPI-DPHY in receiver mode.
+Please refer to phy-bindings.txt for more information.
+
+Required properties:
+- compatible		: Shall be "snps,dphy-rx".
+- #phy-cells		: Must be 1.
+- snps,dphy-frequency	: Output frequency of the D-PHY.
+- snps,dphy-te-len	: Size of the communication interface (8 bits->8 or 12bits->12).
+- reg			: Physical base address and size of the device memory mapped
+		 	  registers;
+
+Example:
+
+	mipi_dphy_rx1: dphy@d00003040 {
+		compatible = "snps,dphy-rx";
+		#phy-cells = <1>;
+		snps,dphy-frequency = <300000>;
+		snps,dphy-te-len = <12>;
+		reg = < 0xd0003040 0x20
+			0xd0008000 0x100
+			0xd0009000 0x100>;
+	};
+
--
2.7.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform
  2018-10-19 12:52 [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host Luis Oliveira
  2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
@ 2018-10-19 12:52 ` Luis Oliveira
  2019-01-07 11:58   ` Sakari Ailus
  2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
  2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
  3 siblings, 1 reply; 26+ messages in thread
From: Luis Oliveira @ 2018-10-19 12:52 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: joao.pinto, festevam, Luis Oliveira, Mauro Carvalho Chehab,
	Luis Oliveira, Hans Verkuil, Laurent Pinchart, Arnd Bergmann,
	Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov

Add of Synopsys MIPI D-PHY in RX mode support.
Separated in the implementation are platform dependent probing functions.

Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
---
Changelog
v2-V3
- merged V2 Patch 1 with Patch 3.
- fixed headers problems.
- add IS_ENABLED to separate implementations of "ASIC" DPHY and
 "TESTCHIP" DPHY flow.

 drivers/media/platform/Kconfig            |   1 +
 drivers/media/platform/Makefile           |   3 +
 drivers/media/platform/dwc/Kconfig        |  24 ++
 drivers/media/platform/dwc/Makefile       |   2 +
 drivers/media/platform/dwc/dw-dphy-plat.c | 347 +++++++++++++++++
 drivers/media/platform/dwc/dw-dphy-rx.c   | 596 ++++++++++++++++++++++++++++++
 drivers/media/platform/dwc/dw-dphy-rx.h   | 181 +++++++++
 7 files changed, 1154 insertions(+)
 create mode 100644 drivers/media/platform/dwc/Kconfig
 create mode 100644 drivers/media/platform/dwc/Makefile
 create mode 100644 drivers/media/platform/dwc/dw-dphy-plat.c
 create mode 100644 drivers/media/platform/dwc/dw-dphy-rx.c
 create mode 100644 drivers/media/platform/dwc/dw-dphy-rx.h

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index f627587..f627a27 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -137,6 +137,7 @@ source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 source "drivers/media/platform/rcar-vin/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
+source "drivers/media/platform/dwc/Kconfig"

 config VIDEO_TI_CAL
 	tristate "TI CAL (Camera Adaptation Layer) driver"
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 6ab6200..def2f33 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -98,3 +98,6 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 obj-y					+= meson/

 obj-y					+= cros-ec-cec/
+
+obj-y					+= dwc/
+
diff --git a/drivers/media/platform/dwc/Kconfig b/drivers/media/platform/dwc/Kconfig
new file mode 100644
index 0000000..353034c
--- /dev/null
+++ b/drivers/media/platform/dwc/Kconfig
@@ -0,0 +1,24 @@
+#
+#  Synopsys DWC Platform drivers
+#	Drivers here are currently for MIPI DPHY support
+
+config DWC_MIPI_DPHY_GEN3
+	tristate "DesignWare platform support using a Gen3 D-PHY"
+	depends on DWC_MIPI_CSI2_HOST
+	select GENERIC_PHY
+	help
+	 Synopsys MIPI D-PHY Generation 3 reference driver.
+
+	  If unsure, say N.
+
+if DWC_MIPI_DPHY_GEN3
+
+config DWC_MIPI_TC_DPHY_GEN3
+	bool "Platform support using a Synopsys Test Chip"
+	help
+	 Synopsys Test Chip is for prototyping purposes.
+
+	  If unsure, say N.
+
+endif # DWC_MIPI_DPHY_GEN3
+
diff --git a/drivers/media/platform/dwc/Makefile b/drivers/media/platform/dwc/Makefile
new file mode 100644
index 0000000..2573e96
--- /dev/null
+++ b/drivers/media/platform/dwc/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_DWC_MIPI_DPHY_GEN3) += dw-dphy-platfrm.o
+dw-dphy-platfrm-objs := dw-dphy-plat.o dw-dphy-rx.o
diff --git a/drivers/media/platform/dwc/dw-dphy-plat.c b/drivers/media/platform/dwc/dw-dphy-plat.c
new file mode 100644
index 0000000..d12a184
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-dphy-plat.c
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI D-PHY controller driver.
+ * Platform dependent functions
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#include "dw-dphy-rx.h"
+
+static struct phy *dw_dphy_xlate(struct device *dev,
+				 struct of_phandle_args *args)
+{
+	struct dw_dphy_rx *dphy = dev_get_drvdata(dev);
+
+	return dphy->phy;
+}
+
+static ssize_t dphy_reset_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	char buffer[15];
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	usleep_range(100, 200);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t dphy_freq_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+	int ret;
+	unsigned long freq;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+
+	ret = kstrtoul(buf, 10, &freq);
+	if (ret < 0)
+		return ret;
+
+	if (freq > 2500) {
+		dev_info(dev, "Freq must be under 2500 Mhz\n");
+		return count;
+	}
+	if (freq < 80) {
+		dev_info(dev, "Freq must be over 80 Mhz\n");
+		return count;
+	}
+
+	dev_info(dev, "Data Rate %lu Mbps\n", freq);
+	dphy->dphy_freq = freq * 1000;
+
+	return count;
+}
+
+static ssize_t dphy_freq_show(struct device *dev, struct device_attribute *attr,
+			      char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	char buffer[15];
+
+	snprintf(buffer, 15, "Freq %d\n", dphy->dphy_freq / 1000);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t dphy_addr_store(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	unsigned long val;
+	int ret;
+	u8 addr, payload;
+
+	ret = kstrtoul(buf, 32, &val);
+	if (ret < 0)
+		return ret;
+
+	payload = (u16)val;
+	addr = (u16)(val >> 16);
+
+	dev_info(dev, "addr 0x%lX\n", val);
+	dev_info(dev, "payload: 0x%X\n", addr);
+	dev_info(dev, "Addr [0x%x] -> 0x%x\n", (unsigned int)addr,
+		 dw_dphy_te_read(dphy, addr));
+
+	return count;
+}
+
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+static ssize_t idelay_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	char buffer[15];
+
+	snprintf(buffer, 15, "idelay %d\n", dw_dphy_if_get_idelay(dphy));
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t idelay_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	int ret;
+	unsigned long val;
+	u8 lane, delay;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret < 0)
+		return ret;
+
+	lane = (u8)val;
+	delay = (u8)(val >> 8);
+
+	dev_dbg(dev, "Lanes %u\n", lane);
+	dev_dbg(dev, "Delay %u\n", delay);
+
+	dw_dphy_if_set_idelay_lane(dphy, delay, lane);
+
+	return count;
+}
+#endif
+
+static ssize_t len_config_store(struct device *dev,
+				struct device_attribute *attr, const char *buf,
+				size_t count)
+{
+	int ret;
+	unsigned long length;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+
+	ret = kstrtoul(buf, 10, &length);
+	if (ret < 0)
+		return ret;
+
+	if (length == BIT8)
+		pr_info("Configured for 8-bit interface\n");
+	else if (length == BIT12)
+		pr_info("Configured for 12-bit interface\n");
+	else
+		return count;
+
+	dphy->dphy_te_len = length;
+
+	return count;
+}
+
+static ssize_t len_config_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	char buffer[20];
+
+	snprintf(buffer, 20, "Length %d\n", dphy->dphy_te_len);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t dw_dphy_g118_settle_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	int ret;
+	unsigned long lp_time;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+
+	ret = kstrtoul(buf, 10, &lp_time);
+	if (ret < 0)
+		return ret;
+
+	if ((lp_time > 1) && (lp_time < 10000))
+		dphy->lp_time = lp_time;
+	else {
+		pr_info("Invalid Value configuring for 1000 ns\n");
+		dphy->lp_time = 1000;
+	}
+
+	dphy->lp_time = lp_time;
+
+	return count;
+}
+
+static ssize_t dw_dphy_g118_settle_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dw_dphy_rx *dphy = platform_get_drvdata(pdev);
+	char buffer[10];
+
+	snprintf(buffer, 10, "Settle %d ns\n", dphy->lp_time);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static DEVICE_ATTR_RO(dphy_reset);
+static DEVICE_ATTR_RW(dphy_freq);
+static DEVICE_ATTR_WO(dphy_addr);
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+static DEVICE_ATTR_RW(idelay);
+#endif
+static DEVICE_ATTR_RW(len_config);
+static DEVICE_ATTR_RW(dw_dphy_g118_settle);
+
+static struct phy_ops dw_dphy_ops = {
+	.init = dw_dphy_init,
+	.reset = dw_dphy_reset,
+	.power_on = dw_dphy_power_on,
+	.power_off = dw_dphy_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int dw_dphy_rx_probe(struct platform_device *pdev)
+{
+	struct dw_dphy_rx *dphy;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct phy_provider *phy_provider;
+	struct phy *phy;
+
+	dphy = devm_kzalloc(dev, sizeof(*dphy), GFP_KERNEL);
+	if (!dphy)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dphy->base_address = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(dphy->base_address)) {
+		dev_err(dev, "error requesting base address\n");
+		return PTR_ERR(dphy->base_address);
+	}
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	dphy->dphy1_if_addr = devm_ioremap_resource(dev, res);
+	if (IS_ERR(dphy->dphy1_if_addr)) {
+		dev_err(dev, "error requesting dphy 1 if regbank\n");
+		return PTR_ERR(dphy->dphy1_if_addr);
+	}
+
+	dphy->max_lanes =
+		dw_dphy_if_read_msk(dphy, DPHYID, DPHY_ID_LANE_SUPPORT, 4);
+
+	dphy->dphy_gen = dw_dphy_if_read_msk(dphy, DPHYID, DPHY_ID_GEN, 4);
+	dev_info(dev, "DPHY GEN %s with maximum %s lanes\n",
+		 dphy->dphy_gen == GEN3 ? "3" : "2",
+		 dphy->max_lanes == CTRL_8_LANES ? "8" : "4");
+
+	if (dphy->max_lanes == CTRL_8_LANES) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+		dphy->dphy2_if_addr =
+			devm_ioremap(dev, res->start, resource_size(res));
+
+		if (IS_ERR(dphy->dphy2_if_addr)) {
+			dev_err(dev, "error requesting dphy 2 if regbank\n");
+			return PTR_ERR(dphy->dphy2_if_addr);
+		}
+
+		dphy->config_gpio = of_get_gpio(dev->of_node, 0);
+		if (!gpio_is_valid(dphy->config_gpio)) {
+			dev_err(dev, "failed to parse config gpio\n");
+			return dphy->config_gpio;
+		}
+	}
+#endif
+	if (of_property_read_u32(dev->of_node, "snps,dphy-frequency",
+				 &dphy->dphy_freq)) {
+		dev_err(dev, "failed to find dphy frequency\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(dev->of_node, "snps,dphy-te-len",
+				 &dphy->dphy_te_len)) {
+		dev_err(dev, "failed to find dphy te length\n");
+		return -EINVAL;
+	}
+
+	dev_set_drvdata(dev, dphy);
+	spin_lock_init(&dphy->slock);
+
+	phy = devm_phy_create(dev, NULL, &dw_dphy_ops);
+	if (IS_ERR(phy)) {
+		dev_err(dev, "failed to create PHY\n");
+		return PTR_ERR(phy);
+	}
+
+	dphy->phy = phy;
+	phy_set_drvdata(phy, dphy);
+
+	phy_provider = devm_of_phy_provider_register(dev, dw_dphy_xlate);
+	if (IS_ERR(phy_provider)) {
+		dev_err(dev, "error getting phy provider\n");
+		return PTR_ERR(phy_provider);
+	}
+
+	dphy->lp_time = 1000; /* 1000 ns */
+	dphy->lanes_config = dw_dphy_setup_config(dphy);
+	dev_dbg(dev, "rx-dphy created\n");
+
+	device_create_file(&pdev->dev, &dev_attr_dphy_reset);
+	device_create_file(&pdev->dev, &dev_attr_dphy_freq);
+	device_create_file(&pdev->dev, &dev_attr_dphy_addr);
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	device_create_file(&pdev->dev, &dev_attr_idelay);
+#endif
+	device_create_file(&pdev->dev, &dev_attr_len_config);
+	device_create_file(&pdev->dev, &dev_attr_dw_dphy_g118_settle);
+
+	return 0;
+}
+
+static const struct of_device_id dw_dphy_rx_of_match[] = {
+	{ .compatible = "snps,dphy-rx" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_dphy_rx_of_match);
+
+static struct platform_driver dw_dphy_rx_driver =
+	{ .probe = dw_dphy_rx_probe,
+	  .driver = {
+		  .of_match_table = dw_dphy_rx_of_match,
+		  .name = "snps-dphy-rx",
+		  .owner = THIS_MODULE,
+	  } };
+module_platform_driver(dw_dphy_rx_driver);
+
+MODULE_DESCRIPTION("Synopsys DesignWare MIPI DPHY Rx driver");
+MODULE_AUTHOR("Luis Oliveira <lolivei@synopsys.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/dwc/dw-dphy-rx.c b/drivers/media/platform/dwc/dw-dphy-rx.c
new file mode 100644
index 0000000..1c45cd7
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-dphy-rx.c
@@ -0,0 +1,596 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI D-PHY controller driver
+ * Core functions
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#include "dw-dphy-rx.h"
+
+struct range_dphy_gen2 {
+	u32 freq;
+	u8 hsfregrange;
+};
+
+struct range_dphy_gen2 range_gen2[] = {
+	{ 80, 0x00 },   { 90, 0x10 },   { 100, 0x20 },  { 110, 0x30 },
+	{ 120, 0x01 },  { 130, 0x11 },  { 140, 0x21 },  { 150, 0x31 },
+	{ 160, 0x02 },  { 170, 0x12 },  { 180, 0x22 },  { 190, 0x32 },
+	{ 205, 0x03 },  { 220, 0x13 },  { 235, 0x23 },  { 250, 0x33 },
+	{ 275, 0x04 },  { 300, 0x14 },  { 325, 0x05 },  { 350, 0x15 },
+	{ 400, 0x25 },  { 450, 0x06 },  { 500, 0x16 },  { 550, 0x07 },
+	{ 600, 0x17 },  { 650, 0x08 },  { 700, 0x18 },  { 750, 0x09 },
+	{ 800, 0x19 },  { 850, 0x29 },  { 900, 0x39 },  { 950, 0x0A },
+	{ 1000, 0x1A }, { 1050, 0x2A }, { 1100, 0x3A }, { 1150, 0x0B },
+	{ 1200, 0x1B }, { 1250, 0x2B }, { 1300, 0x3B }, { 1350, 0x0C },
+	{ 1400, 0x1C }, { 1450, 0x2C }, { 1500, 0x3C }, { 1550, 0x0D },
+	{ 1600, 0x1D }, { 1650, 0x2D }, { 1700, 0x0E }, { 1750, 0x1E },
+	{ 1800, 0x2E }, { 1850, 0x3E }, { 1900, 0x0F }, { 1950, 0x1F },
+	{ 2000, 0x2F },
+};
+
+struct range_dphy_gen3 {
+	u32 freq;
+	u8 hsfregrange;
+	u32 osc_freq_target;
+};
+
+struct range_dphy_gen3 range_gen3[] = {
+
+	{ 80, 0x00, 0x1B6 },   { 90, 0x10, 0x1B6 },   { 100, 0x20, 0x1B6 },
+	{ 110, 0x30, 0x1B6 },  { 120, 0x01, 0x1B6 },  { 130, 0x11, 0x1B6 },
+	{ 140, 0x21, 0x1B6 },  { 150, 0x31, 0x1B6 },  { 160, 0x02, 0x1B6 },
+	{ 170, 0x12, 0x1B6 },  { 180, 0x22, 0x1B6 },  { 190, 0x32, 0x1B6 },
+	{ 205, 0x03, 0x1B6 },  { 220, 0x13, 0x1B6 },  { 235, 0x23, 0x1B6 },
+	{ 250, 0x33, 0x1B6 },  { 275, 0x04, 0x1B6 },  { 300, 0x14, 0x1B6 },
+	{ 325, 0x25, 0x1B6 },  { 350, 0x35, 0x1B6 },  { 400, 0x05, 0x1B6 },
+	{ 450, 0x16, 0x1B6 },  { 500, 0x26, 0x1B6 },  { 550, 0x37, 0x1B6 },
+	{ 600, 0x07, 0x1B6 },  { 650, 0x18, 0x1B6 },  { 700, 0x28, 0x1B6 },
+	{ 750, 0x39, 0x1B6 },  { 800, 0x09, 0x1B6 },  { 850, 0x19, 0x1B6 },
+	{ 900, 0x29, 0x1B6 },  { 950, 0x3A, 0x1B6 },  { 1000, 0x0A, 0x1B6 },
+	{ 1050, 0x1A, 0x1B6 }, { 1100, 0x2A, 0x1B6 }, { 1150, 0x3B, 0x1B6 },
+	{ 1200, 0x0B, 0x1B6 }, { 1250, 0x1B, 0x1B6 }, { 1300, 0x2B, 0x1B6 },
+	{ 1350, 0x3C, 0x1B6 }, { 1400, 0x0C, 0x1B6 }, { 1450, 0x1C, 0x1B6 },
+	{ 1500, 0x2C, 0x1B6 }, { 1550, 0x3D, 0x10F }, { 1600, 0x0D, 0x118 },
+	{ 1650, 0x1D, 0x121 }, { 1700, 0x2E, 0x12A }, { 1750, 0x3E, 0x132 },
+	{ 1800, 0x0E, 0x13B }, { 1850, 0x1E, 0x144 }, { 1900, 0x2F, 0x14D },
+	{ 1950, 0x3F, 0x155 }, { 2000, 0x0F, 0x15E }, { 2050, 0x40, 0x167 },
+	{ 2100, 0x41, 0x170 }, { 2150, 0x42, 0x178 }, { 2200, 0x43, 0x181 },
+	{ 2250, 0x44, 0x18A }, { 2300, 0x45, 0x193 }, { 2350, 0x46, 0x19B },
+	{ 2400, 0x47, 0x1A4 }, { 2450, 0x48, 0x1AD }, { 2500, 0x49, 0x1B6 }
+};
+
+u8 dw_dphy_setup_config(struct dw_dphy_rx *dphy)
+{
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	u8 ret;
+	int setup_config;
+	if (dphy->max_lanes == CTRL_4_LANES)
+#endif
+		return CTRL_4_LANES;
+
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	ret = gpio_request(dphy->config_gpio, "config");
+	if (ret < 0) {
+		pr_err("could not acquire config gpio (err=%d)\n", ret);
+		return ret;
+	}
+
+	setup_config = gpio_get_value(dphy->config_gpio);
+	pr_debug("CONFIG %s\n", setup_config == CTRL_8_LANES ? "8L" : "4+4L");
+	gpio_free(dphy->config_gpio);
+
+	return setup_config;
+#endif
+}
+
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+void dw_dphy_if_write(struct dw_dphy_rx *dphy, u32 address, u32 data)
+{
+	iowrite32(data, dphy->dphy1_if_addr + address);
+
+	if (dphy->lanes_config == CTRL_4_LANES)
+		return;
+
+	iowrite32(data, dphy->dphy2_if_addr + address);
+}
+
+u32 dw_dphy_if_read(struct dw_dphy_rx *dphy, u32 address)
+{
+	u32 if1 = 0, if2 = 0;
+
+	if1 = ioread32(dphy->dphy1_if_addr + address);
+
+	if (dphy->lanes_config == CTRL_4_LANES)
+		goto end;
+
+	if (dphy->lanes_config == DPHYID)
+		goto end;
+
+	if2 = ioread32(dphy->dphy2_if_addr + address);
+
+	if (if1 != if2)
+		pr_debug("Values read different for each interface\n");
+
+end:
+	return if1;
+}
+#endif
+
+void dw_dphy_write(struct dw_dphy_rx *dphy, u32 address, u32 data)
+{
+	iowrite32(data, dphy->base_address + address);
+
+	if (dphy->lanes_config == CTRL_4_LANES)
+		return;
+
+	if (address == R_CSI2_DPHY_TST_CTRL0)
+		iowrite32(data, dphy->base_address + R_CSI2_DPHY2_TST_CTRL0);
+	else if (address == R_CSI2_DPHY_TST_CTRL1)
+		iowrite32(data, dphy->base_address + R_CSI2_DPHY2_TST_CTRL1);
+}
+
+u32 dw_dphy_read(struct dw_dphy_rx *dphy, u32 address)
+{
+	u32 dphy1 = 0, dphy2 = 0;
+
+	dphy1 = ioread32(dphy->base_address + address);
+
+	if (dphy->lanes_config == CTRL_4_LANES)
+		goto end;
+
+	if (address == R_CSI2_DPHY_TST_CTRL0)
+		dphy2 = ioread32(dphy->base_address + R_CSI2_DPHY2_TST_CTRL0);
+	else if (address == R_CSI2_DPHY_TST_CTRL1)
+		dphy2 = ioread32(dphy->base_address + R_CSI2_DPHY2_TST_CTRL1);
+	else
+		return -ENODEV;
+
+	if (dphy1 != dphy2)
+		pr_debug("Values read different for each dphy\n");
+
+end:
+	return dphy1;
+}
+
+void dw_dphy_write_msk(struct dw_dphy_rx *dev, u32 address, u32 data, u8 shift,
+		       u8 width)
+{
+	u32 mask = (1 << width) - 1;
+	u32 temp = dw_dphy_read(dev, address);
+
+	temp &= ~(mask << shift);
+	temp |= (data & mask) << shift;
+	dw_dphy_write(dev, address, temp);
+}
+
+static void dw_dphy_te_12b_write(struct dw_dphy_rx *dphy, u16 addr, u8 data)
+{
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, PHY_TESTDIN, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)(addr >> 8),
+			  PHY_TESTDIN, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)addr, PHY_TESTDIN,
+			  8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)data, PHY_TESTDIN,
+			  8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+}
+
+static void dw_dphy_te_8b_write(struct dw_dphy_rx *dphy, u8 addr, u8 data)
+{
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_TST_CTRL1, addr);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_TST_CTRL1, data);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+}
+
+static void dw_dphy_te_write(struct dw_dphy_rx *dphy, u16 addr, u8 data)
+{
+	if (dphy->dphy_te_len == BIT12)
+		dw_dphy_te_12b_write(dphy, addr, data);
+	else
+		dw_dphy_te_8b_write(dphy, addr, data);
+}
+
+static int dw_dphy_te_12b_read(struct dw_dphy_rx *dphy, u32 addr)
+{
+	u8 ret;
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, PHY_TESTDIN, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)(addr >> 8),
+			  PHY_TESTDIN, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, (u8)addr, PHY_TESTDIN,
+			  8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0x00, 0, PHY_TESTDIN);
+	ret = dw_dphy_read_msk(dphy, R_CSI2_DPHY_TST_CTRL1, PHY_TESTDOUT, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1);
+
+	return ret;
+}
+
+static int dw_dphy_te_8b_read(struct dw_dphy_rx *dphy, u32 addr)
+{
+	u8 ret;
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 1, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, addr, PHY_TESTDIN, 8);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTEN, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL1, 0, PHY_TESTDIN, 8);
+	ret = dw_dphy_read_msk(dphy, R_CSI2_DPHY_TST_CTRL1, PHY_TESTDOUT, 8);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1);
+
+	return ret;
+}
+
+int dw_dphy_te_read(struct dw_dphy_rx *dphy, u32 addr)
+{
+	int ret;
+
+	if (dphy->dphy_te_len == BIT12)
+		ret = dw_dphy_te_12b_read(dphy, addr);
+	else
+		ret = dw_dphy_te_8b_read(dphy, addr);
+
+	return ret;
+}
+
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+static void dw_dphy_if_init(struct dw_dphy_rx *dphy)
+{
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, TX_PHY);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 0);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 1);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, GLUELOGIC);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 0);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 1);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RX_PHY);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 0);
+	dw_dphy_if_write(dphy, DPHYZCALCTRL, 1);
+}
+#endif
+
+static void dw_dphy_gen3_12bit_tc_power_up(struct dw_dphy_rx *dphy)
+{
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, GLUELOGIC);
+#endif
+	dw_dphy_te_write(dphy, CFGCLKFREQRANGE_TX, 0x1C);
+
+	/* CLKSEL | UPDATEPLL | SHADOW_CLEAR | SHADOW_CTRL | FORCEPLL */
+	dw_dphy_te_write(dphy, BYPASS, 0x3F);
+
+	/* IO_DS3 | IO_DS2 | IO_DS1 | IO_DS0 */
+	if (dphy->dphy_freq > 1500)
+		dw_dphy_te_write(dphy, IO_DS, 0x0F);
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RX_PHY);
+#endif
+}
+
+static void dw_dphy_gen3_8bit_tc_power_up(struct dw_dphy_rx *dphy)
+{
+	u32 input_freq = dphy->dphy_freq / 1000;
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, GLUELOGIC);
+	dw_dphy_te_write(dphy, CFGCLKFREQRANGE_RX, 0x1C);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RESET);
+	dw_dphy_if_write(dphy, DPHYGLUEIFTESTER, RX_PHY);
+#endif
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX0_MSB, 0x03);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX0_LSB, 0x02);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX1_MSB, 0x03);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX1_LSB, 0x02);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX2_MSB, 0x03);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX2_LSB, 0x02);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX3_MSB, 0x03);
+	dw_dphy_te_write(dphy, OSC_FREQ_TARGET_RX3_LSB, 0x02);
+	dw_dphy_te_write(dphy, BANDGAP_CTRL, 0x80);
+
+	if (input_freq < 2000)
+		dw_dphy_te_write(dphy, HS_RX_CTRL_LANE0, 0xC0);
+
+	if (input_freq < 1000) {
+		dw_dphy_te_write(dphy, HS_RX_CTRL_LANE1, 0xC0);
+		dw_dphy_te_write(dphy, HS_RX_CTRL_LANE2, 0xC0);
+		dw_dphy_te_write(dphy, HS_RX_CTRL_LANE3, 0xC0);
+	}
+}
+
+int dw_dphy_g118_settle(struct dw_dphy_rx *dphy)
+{
+	u32 input_freq, total_settle, settle_time, byte_clk, lp_time;
+
+	lp_time = dphy->lp_time;
+	input_freq = dphy->dphy_freq / 1000;
+
+	settle_time = (8 * (1000000 / (input_freq))) + 115000;
+	byte_clk = (8000000 / (input_freq));
+	total_settle = (settle_time + lp_time * 1000) / byte_clk;
+
+	if (total_settle > 0xFF)
+		total_settle = 0xFF;
+
+	return total_settle;
+}
+
+static void dw_dphy_pwr_down(struct dw_dphy_rx *dphy)
+{
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLK, 1);
+	if (dphy->lanes_config == CTRL_8_LANES)
+		dw_dphy_write_msk(dphy, R_CSI2_DPHY2_TST_CTRL0, 0, PHY_TESTCLK,
+				  1);
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0);
+}
+
+static void dw_dphy_pwr_up(struct dw_dphy_rx *dphy)
+{
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLK, 1);
+	if (dphy->lanes_config == CTRL_8_LANES)
+		dw_dphy_write_msk(dphy, R_CSI2_DPHY2_TST_CTRL0, 1, PHY_TESTCLK,
+				  1);
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 1);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1);
+}
+
+static int dw_dphy_gen3_12bit_configure(struct dw_dphy_rx *dphy)
+{
+	u32 input_freq = dphy->dphy_freq;
+	u8 range = 0;
+
+	pr_debug("12bit: PHY GEN 3: Freq: %u\n", input_freq);
+	for (range = 0; (range < ARRAY_SIZE(range_gen3) - 1) &&
+			((input_freq / 1000) > range_gen3[range].freq);
+	     range++)
+		;
+	dw_dphy_gen3_12bit_tc_power_up(dphy);
+	dw_dphy_te_write(dphy, RX_SYS_1, range_gen3[range].hsfregrange);
+	dw_dphy_te_write(dphy, RX_SYS_0, 0x20);
+	dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_2,
+			 (u8)range_gen3[range].osc_freq_target);
+	dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_3,
+			 (u8)(range_gen3[range].osc_freq_target >> 8));
+	dw_dphy_te_write(dphy, RX_RX_STARTUP_OVR_4, 0x01);
+
+	return 0;
+}
+
+static int dw_dphy_gen3_8bit_configure(struct dw_dphy_rx *dphy)
+{
+	u32 input_freq = dphy->dphy_freq;
+	u8 data;
+	u8 range = 0;
+
+	pr_debug("8bit: PHY GEN 3: Freq: %u\n", input_freq);
+	for (range = 0; (range < ARRAY_SIZE(range_gen3) - 1) &&
+			((input_freq / 1000) > range_gen3[range].freq);
+	     range++)
+		;
+
+	dw_dphy_te_write(dphy, RX_SKEW_CAL, dw_dphy_g118_settle(dphy));
+	data = 1 << 7 | range_gen3[range].hsfregrange;
+	dw_dphy_te_write(dphy, HSFREQRANGE_8BIT, data);
+	dw_dphy_gen3_8bit_tc_power_up(dphy);
+
+	return 0;
+}
+
+static int dw_dphy_gen2_configure(struct dw_dphy_rx *dphy)
+{
+	u32 input_freq = dphy->dphy_freq;
+	u8 data;
+	u8 range = 0;
+
+	/* provide an initial active-high test clear pulse in TESTCLR  */
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 1, PHY_TESTCLR, 1);
+	dw_dphy_write_msk(dphy, R_CSI2_DPHY_TST_CTRL0, 0, PHY_TESTCLR, 1);
+
+	pr_debug("PHY GEN 2: Freq: %u\n", input_freq);
+	for (range = 0; (range < ARRAY_SIZE(range_gen2) - 1) &&
+			((input_freq / 1000) > range_gen2[range].freq);
+	     range++)
+		;
+
+	data = range_gen2[range].hsfregrange << 1;
+	dw_dphy_te_write(dphy, HSFREQRANGE_8BIT, data);
+
+	return 0;
+}
+
+static int dw_dphy_configure(struct dw_dphy_rx *dphy)
+{
+	dw_dphy_pwr_down(dphy);
+
+	if (dphy->dphy_gen == GEN3) {
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+		dw_dphy_if_init(dphy);
+#endif
+		if (dphy->dphy_te_len == BIT12)
+			dw_dphy_gen3_12bit_configure(dphy);
+		else
+			dw_dphy_gen3_8bit_configure(dphy);
+	} else
+		dw_dphy_gen2_configure(dphy);
+
+	dw_dphy_pwr_up(dphy);
+
+	return 0;
+}
+
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+int dw_dphy_if_set_idelay(struct dw_dphy_rx *dphy, u8 dly, u8 cells)
+{
+	uint32_t val = 0;
+
+	dw_dphy_if_write(dphy, IDLYCFG, 0);
+	dw_dphy_if_write(dphy, IDLYSEL, cells);
+	dw_dphy_if_write(dphy, IDLYCNTINVAL, dly);
+
+	/* Pulse Value Set */
+	dw_dphy_if_write(dphy, IDLYCFG, 1);
+	usleep_range(10, 20);
+	dw_dphy_if_write(dphy, IDLYCFG, 0);
+
+	/* Pulse IDELAY CTRL Reset */
+	dw_dphy_if_write(dphy, DPHY1REGRSTN, 0);
+	usleep_range(10, 20);
+	dw_dphy_if_write(dphy, DPHY1REGRSTN, 1);
+
+	/* Get Value*/
+	val = dw_dphy_if_read(dphy, IDLYCNTOUTVAL);
+
+	if (val != dly) {
+		pr_debug("odelay config failed, set %d get %d", dly, val);
+		return -1;
+	}
+
+	return 0;
+}
+
+int dw_dphy_if_get_idelay(struct dw_dphy_rx *dphy)
+{
+	return dw_dphy_if_read(dphy, IDLYCNTOUTVAL);
+}
+
+int dw_dphy_if_set_idelay_lane(struct dw_dphy_rx *dphy, u8 dly, u8 lane)
+{
+	int cell;
+
+	switch (lane) {
+	case 0:
+		for (cell = 3; cell <= 10; cell++)
+			dw_dphy_if_set_idelay(dphy, dly, cell);
+		break;
+	case 1:
+		for (cell = 14; cell <= 21; cell++)
+			dw_dphy_if_set_idelay(dphy, dly, cell);
+		break;
+	case 2:
+		for (cell = 24; cell <= 31; cell++)
+			dw_dphy_if_set_idelay(dphy, dly, cell);
+		break;
+	case 3:
+		for (cell = 34; cell <= 41; cell++)
+			dw_dphy_if_set_idelay(dphy, dly, cell);
+		break;
+	case 4: /* ALL */
+		dw_dphy_if_set_idelay(dphy, dly, 0x7F);
+		break;
+	default:
+		pr_err("Lane Value not recognized\n");
+		return -1;
+	}
+	return 0;
+}
+#endif
+
+int dw_dphy_init(struct phy *phy)
+{
+	struct dw_dphy_rx *dphy = phy_get_drvdata(phy);
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0);
+
+	return 0;
+}
+
+static int dw_dphy_set_phy_state(struct dw_dphy_rx *dphy, u32 on)
+{
+	u8 hs_freq;
+	dphy->lanes_config = dw_dphy_setup_config(dphy);
+
+	if (dphy->dphy_te_len == BIT12)
+		hs_freq = RX_SYS_1;
+	else
+		hs_freq = HSFREQRANGE_8BIT;
+
+	if (on) {
+		dw_dphy_configure(dphy);
+		pr_debug("HS Code: 0X%x\n", dw_dphy_te_read(dphy, hs_freq));
+	} else {
+		dw_dphy_write(dphy, R_CSI2_DPHY_SHUTDOWNZ, 0);
+		dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	}
+
+	return 0;
+}
+
+int dw_dphy_power_on(struct phy *phy)
+{
+	struct dw_dphy_rx *dphy = phy_get_drvdata(phy);
+
+	return dw_dphy_set_phy_state(dphy, 1);
+}
+
+int dw_dphy_power_off(struct phy *phy)
+{
+	struct dw_dphy_rx *dphy = phy_get_drvdata(phy);
+
+	return dw_dphy_set_phy_state(dphy, 0);
+}
+
+int dw_dphy_reset(struct phy *phy)
+{
+	struct dw_dphy_rx *dphy = phy_get_drvdata(phy);
+
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 0);
+	usleep_range(100, 200);
+	dw_dphy_write(dphy, R_CSI2_DPHY_RSTZ, 1);
+
+	return 0;
+}
diff --git a/drivers/media/platform/dwc/dw-dphy-rx.h b/drivers/media/platform/dwc/dw-dphy-rx.h
new file mode 100644
index 0000000..bab1bb1
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-dphy-rx.h
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI D-PHY controller driver
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#ifndef __PHY_SNPS_DPHY_RX_H__
+#define __PHY_SNPS_DPHY_RX_H__
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+/* DPHY interface register bank*/
+#define R_CSI2_DPHY_SHUTDOWNZ 0x0
+#define R_CSI2_DPHY_RSTZ 0x4
+#define R_CSI2_DPHY_RX 0x8
+#define	R_CSI2_DPHY_STOPSTATE 0xC
+#define R_CSI2_DPHY_TST_CTRL0 0x10
+#define R_CSI2_DPHY_TST_CTRL1 0x14
+#define R_CSI2_DPHY2_TST_CTRL0 0x18
+#define R_CSI2_DPHY2_TST_CTRL1 0x1C
+
+enum dphy_id_mask {
+	DPHY_ID_LANE_SUPPORT = 0,
+	DPHY_ID_IF = 4,
+	DPHY_ID_GEN = 8,
+};
+
+enum dphy_gen_values {
+	GEN1 = 0,
+	GEN2 = 1,
+	GEN3 = 2,
+};
+
+enum dphy_interface_length {
+	BIT8 = 8,
+	BIT12 = 12,
+};
+
+enum tst_ctrl0 {
+	PHY_TESTCLR = 0,
+	PHY_TESTCLK = 1,
+};
+
+enum tst_ctrl1 {
+	PHY_TESTDIN = 0,
+	PHY_TESTDOUT = 8,
+	PHY_TESTEN = 16,
+};
+
+enum lanes_config_values {
+	CTRL_4_LANES = 0,
+	CTRL_8_LANES = 1,
+};
+
+enum dphy_tc {
+	CFGCLKFREQRANGE_TX = 0x02,
+	CFGCLKFREQRANGE_RX = 0x05,
+	BYPASS = 0x20,
+	IO_DS = 0x30,
+};
+
+enum dphy_8bit_interface_addr {
+	BANDGAP_CTRL = 0x24,
+	HS_RX_CTRL_LANE0 = 0x42,
+	HSFREQRANGE_8BIT = 0x44,
+	OSC_FREQ_TARGET_RX0_LSB	= 0x4e,
+	OSC_FREQ_TARGET_RX0_MSB	= 0x4f,
+	HS_RX_CTRL_LANE1 = 0x52,
+	OSC_FREQ_TARGET_RX1_LSB	= 0x5e,
+	OSC_FREQ_TARGET_RX1_MSB	= 0x5f,
+	RX_SKEW_CAL = 0x7e,
+	HS_RX_CTRL_LANE2 = 0x82,
+	OSC_FREQ_TARGET_RX2_LSB	= 0x8e,
+	OSC_FREQ_TARGET_RX2_MSB	= 0x8f,
+	HS_RX_CTRL_LANE3 = 0x92,
+	OSC_FREQ_TARGET_RX3_LSB	= 0x9e,
+	OSC_FREQ_TARGET_RX3_MSB	= 0x9f,
+};
+
+enum dphy_12bit_interface_addr {
+	RX_SYS_0 = 0x01,
+	RX_SYS_1 = 0x02,
+	RX_SYS_7 = 0x08,
+	RX_RX_STARTUP_OVR_0 = 0xe0,
+	RX_RX_STARTUP_OVR_1 = 0xe1,
+	RX_RX_STARTUP_OVR_2 = 0xe2,
+	RX_RX_STARTUP_OVR_3 = 0xe3,
+	RX_RX_STARTUP_OVR_4 = 0xe4,
+};
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+/* Gen3 interface register bank */
+#define IDLYCFG	0x00
+#define IDLYSEL	0x04
+#define IDLYCNTINVAL 0x08
+#define IDLYCNTOUTVAL 0x0c
+#define DPHY1REGRSTN 0x10
+#define DPHYZCALSTAT 0x14
+#define DPHYZCALCTRL 0x18
+#define DPHYLANE0STAT 0x1c
+#define DPHYLANE1STAT 0x20
+#define DPHYLANE2STAT 0x24
+#define DPHYLANE3STAT 0x28
+#define DPHYCLKSTAT 0x2c
+#define DPHYZCLKCTRL 0x30
+#define TCGENPURPOSOUT 0x34
+#define TCGENPURPOSIN 0x38
+#define DPHYGENERICOUT 0x3c
+#define DPHYGENERICIN 0x40
+#define DPHYGLUEIFTESTER 0x44
+#define DPHYID 0x100
+
+enum glueiftester {
+	GLUELOGIC = 0x4,
+	RX_PHY = 0x2,
+	TX_PHY = 0x1,
+	RESET = 0x0,
+};
+#endif
+
+struct dw_dphy_rx {
+	spinlock_t slock;
+	struct phy *phy;
+	u32 dphy_freq;
+	u32 dphy_gen;
+	u32 dphy_te_len;
+	u32 lanes_config;
+	u32 max_lanes;
+	u32 lp_time;
+	void __iomem *base_address; /* test interface */
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+	void __iomem *dphy1_if_addr; /* gluelogic dphy 1 */
+	void __iomem *dphy2_if_addr; /* gluelogic dphy 2 */
+	int config_gpio;
+#endif
+	u8 setup_config;
+};
+
+int dw_dphy_init(struct phy *phy);
+int dw_dphy_reset(struct phy *phy);
+int dw_dphy_power_off(struct phy *phy);
+int dw_dphy_power_on(struct phy *phy);
+u8 dw_dphy_setup_config(struct dw_dphy_rx *dphy);
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+u32 dw_dphy_if_read(struct dw_dphy_rx *dphy, u32 address);
+#endif
+void dw_dphy_write(struct dw_dphy_rx *dphy, u32 address, u32 data);
+u32 dw_dphy_read(struct dw_dphy_rx *dphy, u32 address);
+int dw_dphy_te_read(struct dw_dphy_rx *dphy, u32 addr);
+#if IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3)
+int dw_dphy_if_get_idelay(struct dw_dphy_rx *dphy);
+int dw_dphy_if_set_idelay_lane(struct dw_dphy_rx *dphy, u8 dly, u8 lane);
+
+static inline
+u32 dw_dphy_if_read_msk(struct dw_dphy_rx *dphy,
+		u32 address, u8 shift, u8 width)
+{
+	return (dw_dphy_if_read(dphy, address) >> shift) & ((1 << width) - 1);
+}
+#endif /*IS_ENABLED(CONFIG_DWC_MIPI_TC_DPHY_GEN3) */
+
+static inline
+u32 dw_dphy_read_msk(struct dw_dphy_rx *dev, u32 address, u8 shift,  u8 width)
+{
+	return (dw_dphy_read(dev, address) >> shift) & ((1 << width) - 1);
+}
+
+#endif /*__PHY_SNPS_DPHY_RX_H__*/
--
2.7.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-19 12:52 [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host Luis Oliveira
  2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
  2018-10-19 12:52 ` [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform Luis Oliveira
@ 2018-10-19 12:52 ` Luis Oliveira
  2018-10-24 17:40   ` Rob Herring
                     ` (2 more replies)
  2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
  3 siblings, 3 replies; 26+ messages in thread
From: Luis Oliveira @ 2018-10-19 12:52 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: joao.pinto, festevam, Luis Oliveira, Luis Oliveira,
	Mauro Carvalho Chehab, Rob Herring, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

Add bindings for Synopsys DesignWare MIPI CSI-2 host.

Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
---
Changelog
v2-V3
- removed IPI settings

 .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt

diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
new file mode 100644
index 0000000..be3da05
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
@@ -0,0 +1,52 @@
+Synopsys DesignWare CSI-2 Host controller
+
+Description
+-----------
+
+This HW block is used to receive image coming from an MIPI CSI-2 compatible
+camera.
+
+Required properties:
+- compatible: shall be "snps,dw-csi-plat"
+- reg			: physical base address and size of the device memory mapped
+  registers;
+- interrupts		: CSI-2 Host interrupt
+- snps,output-type	: Core output to be used (IPI-> 0 or IDI->1 or BOTH->2)
+			  These  values choose which of the Core outputs will be used,
+			  it can be Image Data Interface or Image Pixel Interface.
+- phys			: List of one PHY specifier (as defined in
+			  Documentation/devicetree/bindings/phy/phy-bindings.txt).
+			  This PHY is a MIPI DPHY working in RX mode.
+- resets		: Reference to a reset controller (optional)
+
+The per-board settings:
+ - port sub-node describing a single endpoint connected to the camera as
+   described in video-interfaces.txt[1].
+
+Example:
+
+	csi2_1: csi2@3000 {
+		compatible = "snps,dw-csi-plat";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = < 0x03000 0x7FF>;
+		interrupts = <2>;
+		output-type = <2>;
+		resets = <&dw_rst 1>;
+		phys = <&mipi_dphy_rx1 0>;
+		phy-names = "csi2-dphy";
+
+		/* CSI-2 per-board settings */
+		port@1 {
+			reg = <1>;
+			csi1_ep1: endpoint {
+				remote-endpoint = <&camera_1>;
+				data-lanes = <1 2>;
+			};
+		};
+		port@2 {
+			csi1_ep2: endpoint {
+				remote-endpoint = <&vif1_ep>;
+			};
+		};
+	};
--
2.7.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-10-19 12:52 [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host Luis Oliveira
                   ` (2 preceding siblings ...)
  2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
@ 2018-10-19 12:52 ` Luis Oliveira
  2018-11-14 20:22   ` Laurent Pinchart
                     ` (2 more replies)
  3 siblings, 3 replies; 26+ messages in thread
From: Luis Oliveira @ 2018-10-19 12:52 UTC (permalink / raw)
  To: linux-media, linux-kernel
  Cc: joao.pinto, festevam, Luis Oliveira, Mauro Carvalho Chehab,
	Luis Oliveira, Greg Kroah-Hartman, David S. Miller,
	Andrew Morton, Arnd Bergmann, Hans Verkuil, Laurent Pinchart,
	Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Thierry Reding, Maxime Ripard, Todor Tomov

Add the Synopsys MIPI CSI-2 controller driver. This
controller driver is divided in platform dependent functions
and core functions. It also includes a platform for future
DesignWare drivers.

Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
---
Changelog
v2-V3
- exposed IPI settings to userspace
- fixed headers

 MAINTAINERS                              |  11 +
 drivers/media/platform/dwc/Kconfig       |  30 +-
 drivers/media/platform/dwc/Makefile      |   2 +
 drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
 drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
 drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
 drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
 include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
 8 files changed, 1616 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
 create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
 create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
 create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
 create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h

diff --git a/MAINTAINERS b/MAINTAINERS
index da2e509..fd5f1fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14032,6 +14032,16 @@ S:	Maintained
 F:	drivers/dma/dwi-axi-dmac/
 F:	Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt

+SYNOPSYS DESIGNWARE MIPI CSI-2 HOST VIDEO PLATFORM
+M:	Luis Oliveira <luis.oliveira@synopsys.com>
+L:	linux-media@vger.kernel.org
+T:	git git://linuxtv.org/media_tree.git
+S:	Maintained
+F:	drivers/media/platform/dwc
+F:	include/media/dwc/dw-mipi-csi-pltfrm.h
+F:	Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
+F:	Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
+
 SYNOPSYS DESIGNWARE DMAC DRIVER
 M:	Viresh Kumar <vireshk@kernel.org>
 R:	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
@@ -16217,3 +16227,4 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
 S:	Buried alive in reporters
 F:	*
 F:	*/
+
diff --git a/drivers/media/platform/dwc/Kconfig b/drivers/media/platform/dwc/Kconfig
index 353034c..7c3332c 100644
--- a/drivers/media/platform/dwc/Kconfig
+++ b/drivers/media/platform/dwc/Kconfig
@@ -1,6 +1,34 @@
 #
 #  Synopsys DWC Platform drivers
-#	Drivers here are currently for MIPI DPHY support
+#	Most drivers here are currently for MIPI CSI-2 and MIPI DPHY support
+
+config DWC_MIPI_CSI2_HOST
+	bool "Synopsys Designware CSI-2 Host Controller and DPHY-RX support"
+	select VIDEO_DEV
+	select VIDEO_V4L2
+	select VIDEO_V4L2_SUBDEV_API
+	select V4L2_FWNODE
+	help
+	 This selects the CSI-2 host controller support.
+
+	 If you have a controller with this interface, say Y.
+
+	  If unsure, say N.
+
+if DWC_MIPI_CSI2_HOST
+
+config DWC_MIPI_CSI2_HOST_PLATFORM
+	tristate "Platform bus based CSI-2 Host Controller support"
+	depends on HAS_DMA
+	help
+	 This selects the CSI-2 host controller support. Select this if
+	 you have an CSI-2 Host controller on Platform bus.
+
+	 If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
+
+endif # DWC_MIPI_CSI2_HOST

 config DWC_MIPI_DPHY_GEN3
 	tristate "DesignWare platform support using a Gen3 D-PHY"
diff --git a/drivers/media/platform/dwc/Makefile b/drivers/media/platform/dwc/Makefile
index 2573e96..ab0de7d 100644
--- a/drivers/media/platform/dwc/Makefile
+++ b/drivers/media/platform/dwc/Makefile
@@ -1,2 +1,4 @@
 obj-$(CONFIG_DWC_MIPI_DPHY_GEN3) += dw-dphy-platfrm.o
 dw-dphy-platfrm-objs := dw-dphy-plat.o dw-dphy-rx.o
+obj-$(CONFIG_DWC_MIPI_CSI2_HOST_PLATFORM) += dw-csi-platfrm.o
+dw-csi-platfrm-objs := dw-csi-plat.o dw-mipi-csi.o
diff --git a/drivers/media/platform/dwc/dw-csi-plat.c b/drivers/media/platform/dwc/dw-csi-plat.c
new file mode 100644
index 0000000..fa73738
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-csi-plat.c
@@ -0,0 +1,699 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI CSI-2 Host controller driver.
+ * Platform dependent functions
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#include "dw-csi-plat.h"
+
+static const struct mipi_fmt *
+find_dw_mipi_csi_format(struct v4l2_mbus_framefmt *mf)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(dw_mipi_csi_formats); i++)
+		if (mf->code == dw_mipi_csi_formats[i].code)
+			return &dw_mipi_csi_formats[i];
+	return NULL;
+}
+
+static int dw_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
+		struct v4l2_subdev_pad_config *cfg,
+		struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(dw_mipi_csi_formats))
+		return -EINVAL;
+
+	code->code = dw_mipi_csi_formats[code->index].code;
+	return 0;
+}
+
+static struct mipi_fmt const *
+dw_mipi_csi_try_format(struct v4l2_mbus_framefmt *mf)
+{
+	struct mipi_fmt const *fmt;
+
+	fmt = find_dw_mipi_csi_format(mf);
+	if (fmt == NULL)
+		fmt = &dw_mipi_csi_formats[0];
+
+	mf->code = fmt->code;
+	return fmt;
+}
+
+static struct v4l2_mbus_framefmt *
+dw_mipi_csi_get_format(struct mipi_csi_dev *dev,
+		struct v4l2_subdev_pad_config *cfg,
+		enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return cfg ? v4l2_subdev_get_try_format(&dev->sd, cfg,
+							0) : NULL;
+
+	return &dev->format;
+}
+
+static int
+dw_mipi_csi_set_fmt(struct v4l2_subdev *sd,
+		struct v4l2_subdev_pad_config *cfg,
+		struct v4l2_subdev_format *fmt)
+{
+	struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
+	struct mipi_fmt const *dev_fmt;
+	struct v4l2_mbus_framefmt *mf;
+	unsigned int i = 0;
+	const struct v4l2_bt_timings *bt_r = &v4l2_dv_timings_presets[0].bt;
+
+	mf = dw_mipi_csi_get_format(dev, cfg, fmt->which);
+
+	dev_fmt = dw_mipi_csi_try_format(&fmt->format);
+	if (dev_fmt) {
+		*mf = fmt->format;
+		if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+			dev->fmt = dev_fmt;
+		dw_mipi_csi_set_ipi_fmt(dev);
+	}
+	while (v4l2_dv_timings_presets[i].bt.width) {
+		const struct v4l2_bt_timings *bt =
+		    &v4l2_dv_timings_presets[i].bt;
+		if (mf->width == bt->width && mf->height == bt->width) {
+			dw_mipi_csi_fill_timings(dev, bt);
+			return 0;
+		}
+		i++;
+	}
+
+	dw_mipi_csi_fill_timings(dev, bt_r);
+	return 0;
+
+}
+
+static int
+dw_mipi_csi_get_fmt(struct v4l2_subdev *sd,
+		struct v4l2_subdev_pad_config *cfg,
+		struct v4l2_subdev_format *fmt)
+{
+	struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
+	struct v4l2_mbus_framefmt *mf;
+
+	mf = dw_mipi_csi_get_format(dev, cfg, fmt->which);
+	if (!mf)
+		return -EINVAL;
+
+	mutex_lock(&dev->lock);
+	fmt->format = *mf;
+	mutex_unlock(&dev->lock);
+	return 0;
+}
+
+static int
+dw_mipi_csi_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct mipi_csi_dev *dev = sd_to_mipi_csi_dev(sd);
+
+	if (on) {
+		dw_mipi_csi_hw_stdby(dev);
+		dw_mipi_csi_start(dev);
+	} else {
+		phy_power_off(dev->phy);
+		dw_mipi_csi_mask_irq_power_off(dev);
+	}
+	return 0;
+}
+
+static int
+dw_mipi_csi_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg)
+{
+	struct v4l2_mbus_framefmt *format =
+	    v4l2_subdev_get_try_format(sd, cfg, 0);
+
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+	format->code = dw_mipi_csi_formats[0].code;
+	format->width = MIN_WIDTH;
+	format->height = MIN_HEIGHT;
+	format->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops dw_mipi_csi_core_ops = {
+	.s_power = dw_mipi_csi_s_power,
+};
+
+static struct v4l2_subdev_pad_ops dw_mipi_csi_pad_ops = {
+	.init_cfg =	dw_mipi_csi_init_cfg,
+	.enum_mbus_code = dw_mipi_csi_enum_mbus_code,
+	.get_fmt = dw_mipi_csi_get_fmt,
+	.set_fmt = dw_mipi_csi_set_fmt,
+};
+
+static struct v4l2_subdev_ops dw_mipi_csi_subdev_ops = {
+	.core = &dw_mipi_csi_core_ops,
+	.pad = &dw_mipi_csi_pad_ops,
+};
+
+static irqreturn_t dw_mipi_csi_irq1(int irq, void *dev_id)
+{
+	struct mipi_csi_dev *csi_dev = dev_id;
+
+	dw_mipi_csi_irq_handler(csi_dev);
+
+	return IRQ_HANDLED;
+}
+
+static int
+dw_mipi_csi_parse_dt(struct platform_device *pdev, struct mipi_csi_dev *dev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct v4l2_fwnode_endpoint endpoint;
+	int ret;
+
+	node = of_graph_get_next_endpoint(node, NULL);
+	if (!node) {
+		dev_err(&pdev->dev, "No port node at %s\n",
+				pdev->dev.of_node->full_name);
+		return -EINVAL;
+	}
+
+	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
+	if (ret)
+		goto err;
+
+	dev->index = endpoint.base.port - 1;
+	if (dev->index >= CSI_MAX_ENTITIES) {
+		ret = -ENXIO;
+		goto err;
+	}
+	dev->hw.num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
+
+err:
+	of_node_put(node);
+	return ret;
+}
+
+static ssize_t core_version_show(struct device *dev,
+						struct device_attribute *attr,
+						char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "v.%d.%d*\n", csi_dev->hw_version_major,
+					csi_dev->hw_version_minor);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t n_lanes_store(struct device *dev, struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	int ret;
+	unsigned long lanes;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &lanes);
+	if (ret < 0)
+		return ret;
+
+	if (lanes > 8) {
+		dev_err(dev, "Invalid number of lanes %lu\n", lanes);
+		return count;
+	}
+
+	dev_info(dev, "Lanes %lu\n", lanes);
+	csi_dev->hw.num_lanes = lanes;
+
+	return count;
+}
+static ssize_t n_lanes_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.num_lanes);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t core_reset_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	/* Reset Controller and DPHY */
+	phy_reset(csi_dev->phy);
+	dw_mipi_csi_reset(csi_dev);
+
+	snprintf(buffer, 10, "Reset\n");
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t data_type_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long dt;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 16, &dt);
+	if (ret < 0)
+		return ret;
+
+	if ((dt < 0x18) || (dt > 0x2F)) {
+		dev_err(dev, "Invalid data type %lx\n", dt);
+		return count;
+	}
+
+	dev_info(dev, "Data type %lx\n", dt);
+	csi_dev->ipi_dt = dt;
+
+	return count;
+}
+
+static ssize_t data_type_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%x\n", csi_dev->ipi_dt);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t virtual_channel_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long virtual_ch;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &virtual_ch);
+	if (ret < 0)
+		return ret;
+
+	if ((virtual_ch < 0) || (virtual_ch > 8)) {
+		dev_err(dev, "Invalid Virtual Channel %lu\n", virtual_ch);
+		return count;
+	}
+
+	dev_info(dev, "Virtual Channel %lu\n", virtual_ch);
+	csi_dev->hw.virtual_ch = virtual_ch;
+
+	return count;
+}
+
+static ssize_t virtual_channel_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.virtual_ch);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t ipi_color_mode_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long ipi_color_mode;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &ipi_color_mode);
+	if (ret < 0)
+		return ret;
+
+	if ((ipi_color_mode < 0) || (ipi_color_mode > 1)) {
+		dev_err(dev,
+		 		"Invalid Color Mode %lu, (48 bits -> 0 or 16 bits -> 1\n",
+		 		ipi_color_mode);
+		return count;
+	}
+
+	dev_info(dev, "IPI Color mode %lu\n", ipi_color_mode);
+	csi_dev->hw.ipi_color_mode = ipi_color_mode;
+
+	return count;
+}
+
+static ssize_t ipi_color_mode_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_color_mode);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t ipi_auto_flush_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long ipi_auto_flush;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &ipi_auto_flush);
+	if (ret < 0)
+		return ret;
+
+	if ((ipi_auto_flush < 0) || (ipi_auto_flush > 1)) {
+		dev_err(dev,
+		 		"Invalid Auto Flush Mode %lu, (No -> 0 or Yes -> 1\n",
+		 		ipi_auto_flush);
+		return count;
+	}
+
+	dev_info(dev, "IPI Auto Flush %lu\n", ipi_auto_flush);
+	csi_dev->hw.ipi_auto_flush = ipi_auto_flush;
+
+	return count;
+}
+
+static ssize_t ipi_auto_flush_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_auto_flush);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t ipi_timings_mode_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long ipi_mode;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &ipi_mode);
+	if (ret < 0)
+		return ret;
+
+	if ((ipi_mode < 0) || (ipi_mode > 1)) {
+		dev_err(dev,
+		"Invalid Timing Source %lu, (from Camera -> 0 or from Controller -> 1\n",
+		 		ipi_mode);
+		return count;
+	}
+
+	dev_info(dev, "IPI Color mode %lu\n", ipi_mode);
+	csi_dev->hw.ipi_mode = ipi_mode;
+
+	return count;
+}
+
+static ssize_t ipi_timings_mode_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.ipi_mode);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static ssize_t output_type_store(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	int ret;
+	unsigned long output;
+
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	ret = kstrtoul(buf, 10, &output);
+	if (ret < 0)
+		return ret;
+
+	if ((output < 0) || (output > 1)) {
+		dev_err(dev,
+		"Invalid Core output %lu to be used (IPI-> 0 or IDI->1 or BOTH- 2\n",
+		 		output);
+		return count;
+	}
+
+	dev_info(dev, "IPI Color mode %lu\n", output);
+	csi_dev->hw.output = output;
+
+	return count;
+}
+
+static ssize_t output_type_show(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *csi_dev = sd_to_mipi_csi_dev(sd);
+
+	char buffer[10];
+
+	snprintf(buffer, 10, "%d\n", csi_dev->hw.output);
+
+	return strlcpy(buf, buffer, PAGE_SIZE);
+}
+
+static DEVICE_ATTR_RO(core_version);
+static DEVICE_ATTR_RO(core_reset);
+static DEVICE_ATTR_RW(n_lanes);
+static DEVICE_ATTR_RW(data_type);
+static DEVICE_ATTR_RW(virtual_channel);
+static DEVICE_ATTR_RW(ipi_color_mode);
+static DEVICE_ATTR_RW(ipi_auto_flush);
+static DEVICE_ATTR_RW(ipi_timings_mode);
+static DEVICE_ATTR_RW(output_type);
+
+static const struct of_device_id dw_mipi_csi_of_match[];
+
+static int csi_plat_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *of_id;
+	struct device *dev = &pdev->dev;
+	struct resource *res = NULL;
+	struct mipi_csi_dev *mipi_csi;
+	int ret = -ENOMEM;
+
+	mipi_csi = devm_kzalloc(dev, sizeof(*mipi_csi), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+
+	mutex_init(&mipi_csi->lock);
+	spin_lock_init(&mipi_csi->slock);
+	mipi_csi->dev = dev;
+
+	of_id = of_match_node(dw_mipi_csi_of_match, dev->of_node);
+	if (WARN_ON(of_id == NULL))
+		return -EINVAL;
+
+	ret = dw_mipi_csi_parse_dt(pdev, mipi_csi);
+	if (ret < 0)
+		return ret;
+
+	mipi_csi->phy = devm_of_phy_get(dev, dev->of_node, NULL);
+	if (IS_ERR(mipi_csi->phy)) {
+		dev_err(dev, "No DPHY available\n");
+		return PTR_ERR(mipi_csi->phy);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mipi_csi->base_address = devm_ioremap_resource(dev, res);
+
+	if (IS_ERR(mipi_csi->base_address)) {
+		dev_err(dev, "Base address not set.\n");
+		return PTR_ERR(mipi_csi->base_address);
+	}
+
+	mipi_csi->ctrl_irq_number = platform_get_irq(pdev, 0);
+	if (mipi_csi->ctrl_irq_number <= 0) {
+		dev_err(dev, "IRQ number not set.\n");
+		return mipi_csi->ctrl_irq_number;
+	}
+
+	mipi_csi->rst = devm_reset_control_get_optional_shared(dev, NULL);
+	if (IS_ERR(mipi_csi->rst)) {
+		ret = PTR_ERR(mipi_csi->rst);
+		dev_err(dev, "error getting reset control %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_request_irq(dev, mipi_csi->ctrl_irq_number,
+			       dw_mipi_csi_irq1, IRQF_SHARED,
+			       dev_name(dev), mipi_csi);
+	if (ret) {
+		dev_err(dev, "IRQ failed\n");
+		goto end;
+	}
+
+	v4l2_subdev_init(&mipi_csi->sd, &dw_mipi_csi_subdev_ops);
+	mipi_csi->sd.owner = THIS_MODULE;
+	snprintf(mipi_csi->sd.name, sizeof(mipi_csi->sd.name), "%s.%d",
+		 CSI_HOST_NAME, mipi_csi->index);
+	mipi_csi->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	mipi_csi->fmt = &dw_mipi_csi_formats[0];
+
+	mipi_csi->format.code = dw_mipi_csi_formats[0].code;
+	mipi_csi->format.width = MIN_WIDTH;
+	mipi_csi->format.height = MIN_HEIGHT;
+
+	mipi_csi->sd.entity.function = MEDIA_ENT_F_IO_V4L;
+	mipi_csi->pads[CSI_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	mipi_csi->pads[CSI_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_pads_init(&mipi_csi->sd.entity,
+				     CSI_PADS_NUM, mipi_csi->pads);
+
+	if (ret < 0) {
+		dev_err(dev, "Media Entity init failed\n");
+		goto entity_cleanup;
+	}
+
+	v4l2_set_subdevdata(&mipi_csi->sd, pdev);
+
+	platform_set_drvdata(pdev, &mipi_csi->sd);
+
+	device_create_file(&pdev->dev, &dev_attr_core_version);
+	device_create_file(&pdev->dev, &dev_attr_core_reset);
+	device_create_file(&pdev->dev, &dev_attr_n_lanes);
+	device_create_file(&pdev->dev, &dev_attr_data_type);
+	device_create_file(&pdev->dev, &dev_attr_virtual_channel);
+	device_create_file(&pdev->dev, &dev_attr_ipi_color_mode);
+	device_create_file(&pdev->dev, &dev_attr_ipi_auto_flush);
+	device_create_file(&pdev->dev, &dev_attr_ipi_timings_mode);
+	device_create_file(&pdev->dev, &dev_attr_output_type);
+
+	if (mipi_csi->rst)
+		reset_control_deassert(mipi_csi->rst);
+
+	dw_mipi_csi_get_version(mipi_csi);
+	dw_mipi_csi_specific_mappings(mipi_csi);
+	dw_mipi_csi_mask_irq_power_off(mipi_csi);
+
+	dev_info(dev, "DW MIPI CSI-2 Host registered successfully HW v%u.%u\n",
+		mipi_csi->hw_version_major, mipi_csi->hw_version_minor);
+	return 0;
+
+entity_cleanup:
+	media_entity_cleanup(&mipi_csi->sd.entity);
+end:
+	return ret;
+}
+
+/**
+ * @short Exit routine - Exit point of the driver
+ * @param[in] pdev pointer to the platform device structure
+ * @return 0 on success and a negative number on failure
+ * Refer to Linux errors.
+ */
+static int csi_plat_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct mipi_csi_dev *mipi_csi = sd_to_mipi_csi_dev(sd);
+
+	dev_dbg(&pdev->dev, "Removing MIPI CSI-2 module\n");
+
+	if (mipi_csi->rst)
+		reset_control_assert(mipi_csi->rst);
+
+	media_entity_cleanup(&mipi_csi->sd.entity);
+
+	return 0;
+}
+
+/**
+ * @short of_device_id structure
+ */
+static const struct of_device_id dw_mipi_csi_of_match[] = {
+	{
+	 .compatible = "snps,dw-csi-plat"},
+	{ /* sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, dw_mipi_csi_of_match);
+
+/**
+ * @short Platform driver structure
+ */
+static struct platform_driver __refdata dw_mipi_csi_pdrv = {
+	.remove = csi_plat_remove,
+	.probe = csi_plat_probe,
+	.driver = {
+		   .name = CSI_HOST_NAME,
+		   .owner = THIS_MODULE,
+		   .of_match_table = dw_mipi_csi_of_match,
+		   },
+};
+
+module_platform_driver(dw_mipi_csi_pdrv);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Luis Oliveira <lolivei@synopsys.com>");
+MODULE_DESCRIPTION("Synopsys DesignWare MIPI CSI-2 Host Platform driver");
diff --git a/drivers/media/platform/dwc/dw-csi-plat.h b/drivers/media/platform/dwc/dw-csi-plat.h
new file mode 100644
index 0000000..e806edd
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-csi-plat.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI CSI-2 Host controller driver.
+ * Platform dependent functions
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#ifndef _DW_CSI_PLAT_H__
+#define _DW_CSI_PLAT_H__
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_graph.h>
+#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
+#include <linux/reset.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/wait.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-subdev.h>
+
+#include "dw-mipi-csi.h"
+
+#define CSI_HOST_NAME	"dw-mipi-csi"
+
+/* Video formats supported by the MIPI CSI-2 */
+const struct mipi_fmt dw_mipi_csi_formats[] = {
+	{
+		/* RAW 8 */
+		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth = 8,
+	},
+	{
+		/* RAW 10 */
+		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
+		.depth = 10,
+	},
+	{
+		/* RGB 565 */
+		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
+		.depth = 16,
+	},
+	{
+		/* BGR 565 */
+		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
+		.depth = 16,
+	},
+	{
+		/* RGB 888 */
+		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
+		.depth = 24,
+	},
+	{
+		/* BGR 888 */
+		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
+		.depth = 24,
+	},
+};
+
+static inline struct mipi_csi_dev *sd_to_mipi_csi_dev(struct v4l2_subdev *sdev)
+{
+	return container_of(sdev, struct mipi_csi_dev, sd);
+}
+
+#endif	/* _DW_CSI_PLAT_H__ */
diff --git a/drivers/media/platform/dwc/dw-mipi-csi.c b/drivers/media/platform/dwc/dw-mipi-csi.c
new file mode 100644
index 0000000..2d19f18
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-mipi-csi.c
@@ -0,0 +1,494 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI CSI-2 Host controller driver
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#include "dw-mipi-csi.h"
+
+static struct R_CSI2 reg = {
+	.VERSION = 0x00,
+	.N_LANES = 0x04,
+	.CTRL_RESETN = 0x08,
+	.INTERRUPT = 0x0C,
+	.DATA_IDS_1	= 0x10,
+	.DATA_IDS_2	= 0x14,
+	.IPI_MODE = 0x80,
+	.IPI_VCID = 0x84,
+	.IPI_DATA_TYPE = 0x88,
+	.IPI_MEM_FLUSH = 0x8C,
+	.IPI_HSA_TIME = 0x90,
+	.IPI_HBP_TIME = 0x94,
+	.IPI_HSD_TIME = 0x98,
+	.IPI_HLINE_TIME = 0x9C,
+	.IPI_SOFTRSTN = 0xA0,
+	.IPI_ADV_FEATURES = 0xAC,
+	.IPI_VSA_LINES = 0xB0,
+	.IPI_VBP_LINES = 0xB4,
+	.IPI_VFP_LINES = 0xB8,
+	.IPI_VACTIVE_LINES = 0xBC,
+	.INT_PHY_FATAL = 0xe0,
+	.MASK_INT_PHY_FATAL = 0xe4,
+	.FORCE_INT_PHY_FATAL = 0xe8,
+	.INT_PKT_FATAL = 0xf0,
+	.MASK_INT_PKT_FATAL = 0xf4,
+	.FORCE_INT_PKT_FATAL = 0xf8,
+	.INT_PHY = 0x110,
+	.MASK_INT_PHY = 0x114,
+	.FORCE_INT_PHY = 0x118,
+	.INT_LINE = 0x130,
+	.MASK_INT_LINE = 0x134,
+	.FORCE_INT_LINE = 0x138,
+	.INT_IPI = 0x140,
+	.MASK_INT_IPI = 0x144,
+	.FORCE_INT_IPI = 0x148,
+};
+struct interrupt_type csi_int = {
+	.PHY_FATAL = BIT(0),
+	.PKT_FATAL = BIT(1),
+	.PHY = BIT(16),
+};
+static void dw_mipi_csi_write(struct mipi_csi_dev *dev,
+		  unsigned int address, unsigned int data)
+{
+	iowrite32(data, dev->base_address + address);
+}
+
+static u32 dw_mipi_csi_read(struct mipi_csi_dev *dev, unsigned long address)
+{
+	return ioread32(dev->base_address + address);
+}
+
+void dw_mipi_csi_write_part(struct mipi_csi_dev *dev,
+		       unsigned long address, unsigned long data,
+		       unsigned char shift, unsigned char width)
+{
+	u32 mask = (1 << width) - 1;
+	u32 temp = dw_mipi_csi_read(dev, address);
+
+	temp &= ~(mask << shift);
+	temp |= (data & mask) << shift;
+	dw_mipi_csi_write(dev, address, temp);
+}
+
+void dw_mipi_csi_reset(struct mipi_csi_dev *csi_dev)
+{
+	dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 0);
+	usleep_range(100, 200);
+	dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 1);
+}
+
+int dw_mipi_csi_mask_irq_power_off(struct mipi_csi_dev *csi_dev)
+{
+	if ((csi_dev->hw_version_major) == 1) {
+
+		/* set only one lane (lane 0) as active (ON) */
+		dw_mipi_csi_write(csi_dev, reg.N_LANES, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY_FATAL, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT_FATAL, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_LINE, 0);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_IPI, 0);
+
+		/* only for version 1.30 */
+		if ((csi_dev->hw_version_minor) == 30)
+			dw_mipi_csi_write(csi_dev, reg.MASK_INT_FRAME_FATAL, 0);
+
+		dw_mipi_csi_write(csi_dev, reg.CTRL_RESETN, 0);
+
+		/* only for version 1.40 */
+		if ((csi_dev->hw_version_minor) == 40) {
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_BNDRY_FRAME_FATAL, 0);
+			dw_mipi_csi_write(csi_dev, reg.MSK_SEQ_FRAME_FATAL, 0);
+			dw_mipi_csi_write(csi_dev, reg.MSK_CRC_FRAME_FATAL, 0);
+			dw_mipi_csi_write(csi_dev, reg.MSK_PLD_CRC_FATAL, 0);
+			dw_mipi_csi_write(csi_dev, reg.MSK_DATA_ID, 0);
+			dw_mipi_csi_write(csi_dev, reg.MSK_ECC_CORRECT, 0);
+		}
+	}
+
+	return 0;
+}
+
+int dw_mipi_csi_hw_stdby(struct mipi_csi_dev *csi_dev)
+{
+	if ((csi_dev->hw_version_major) == 1) {
+
+		/* set only one lane (lane 0) as active (ON) */
+		dw_mipi_csi_reset(csi_dev);
+		dw_mipi_csi_write(csi_dev, reg.N_LANES, 0);
+		phy_init(csi_dev->phy);
+
+		/* only for version 1.30 */
+		if ((csi_dev->hw_version_minor) == 30)
+			dw_mipi_csi_write(csi_dev,
+					reg.MASK_INT_FRAME_FATAL, 0xFFFFFFFF);
+
+		/* common */
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY_FATAL, 0xFFFFFFFF);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT_FATAL, 0xFFFFFFFF);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PHY, 0xFFFFFFFF);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_PKT, 0xFFFFFFFF);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_LINE, 0xFFFFFFFF);
+		dw_mipi_csi_write(csi_dev, reg.MASK_INT_IPI, 0xFFFFFFFF);
+
+		/* only for version 1.40 */
+		if ((csi_dev->hw_version_minor) == 40) {
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_BNDRY_FRAME_FATAL, 0xFFFFFFFF);
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_SEQ_FRAME_FATAL, 0xFFFFFFFF);
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_CRC_FRAME_FATAL, 0xFFFFFFFF);
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_PLD_CRC_FATAL, 0xFFFFFFFF);
+			dw_mipi_csi_write(csi_dev, reg.MSK_DATA_ID, 0xFFFFFFFF);
+			dw_mipi_csi_write(csi_dev,
+					reg.MSK_ECC_CORRECT, 0xFFFFFFFF);
+		}
+	}
+	return 0;
+}
+
+void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
+{
+	struct device *dev = csi_dev->dev;
+
+	if (csi_dev->ipi_dt)
+		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
+	else {
+		switch (csi_dev->fmt->code) {
+		case MEDIA_BUS_FMT_RGB565_2X8_BE:
+		case MEDIA_BUS_FMT_RGB565_2X8_LE:
+			dw_mipi_csi_write(csi_dev,
+					reg.IPI_DATA_TYPE, CSI_2_RGB565);
+			dev_dbg(dev, "DT: RGB 565");
+			break;
+
+		case MEDIA_BUS_FMT_RGB888_2X12_LE:
+		case MEDIA_BUS_FMT_RGB888_2X12_BE:
+			dw_mipi_csi_write(csi_dev,
+					reg.IPI_DATA_TYPE, CSI_2_RGB888);
+			dev_dbg(dev, "DT: RGB 888");
+			break;
+		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
+			dw_mipi_csi_write(csi_dev,
+					reg.IPI_DATA_TYPE, CSI_2_RAW10);
+			dev_dbg(dev, "DT: RAW 10");
+			break;
+		case MEDIA_BUS_FMT_SBGGR8_1X8:
+			dw_mipi_csi_write(csi_dev,
+					reg.IPI_DATA_TYPE, CSI_2_RAW8);
+			dev_dbg(dev, "DT: RAW 8");
+			break;
+		default:
+			dw_mipi_csi_write(csi_dev,
+					reg.IPI_DATA_TYPE, CSI_2_RGB565);
+			dev_dbg(dev, "Error");
+			break;
+		}
+	}
+}
+
+void dw_mipi_csi_fill_timings(struct mipi_csi_dev *dev,
+			   const struct v4l2_bt_timings *bt)
+{
+	if (bt == NULL)
+		return;
+	dev->hw.virtual_ch = 0;
+	dev->hw.ipi_color_mode = 0;
+	dev->hw.ipi_auto_flush = 1;
+	dev->hw.ipi_mode = 0;
+	dev->hw.hsa = bt->hsync;
+	dev->hw.hbp = bt->hbackporch;
+	dev->hw.hsd = bt->hsync;
+	dev->hw.htotal = bt->height + bt->vfrontporch +
+	    bt->vsync + bt->vbackporch;
+	dev->hw.vsa = bt->vsync;
+	dev->hw.vbp = bt->vbackporch;
+	dev->hw.vfp = bt->vfrontporch;
+	dev->hw.vactive = bt->height;
+	dev->hw.output = 2;
+}
+
+void dw_mipi_csi_start(struct mipi_csi_dev *csi_dev)
+{
+	const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[0].bt;
+	struct device *dev = csi_dev->dev;
+
+	dw_mipi_csi_fill_timings(csi_dev, bt);
+	dw_mipi_csi_write(csi_dev, reg.N_LANES, (csi_dev->hw.num_lanes - 1));
+	dev_dbg(dev, "N Lanes: %d\n", csi_dev->hw.num_lanes);
+
+	/* IPI Related Configuration */
+	if ((csi_dev->hw.output == IPI_OUT)
+		|| (csi_dev->hw.output == BOTH_OUT)) {
+
+		if (csi_dev->hw_version_major >= 1) {
+			if (csi_dev->hw_version_minor >= 20)
+				dw_mipi_csi_write(csi_dev,
+					reg.IPI_ADV_FEATURES, 0x30000);
+
+			if (csi_dev->hw_version_minor >= 30)
+				dw_mipi_csi_write(csi_dev,
+					reg.IPI_SOFTRSTN, 0x1);
+		}
+		/*  address | data, | shift | width */
+		dw_mipi_csi_write_part(csi_dev, reg.IPI_MODE, 1, 24, 1);
+		dw_mipi_csi_write_part(csi_dev,
+					reg.IPI_MODE,
+					csi_dev->hw.ipi_mode,
+					0, 1);
+
+		dw_mipi_csi_write_part(csi_dev,
+					reg.IPI_MODE,
+					csi_dev->hw.ipi_color_mode,
+					8, 1);
+
+		dw_mipi_csi_write_part(csi_dev,
+					reg.IPI_VCID,
+					csi_dev->hw.virtual_ch,
+					0, 2);
+
+		dw_mipi_csi_write_part(csi_dev,
+					reg.IPI_MEM_FLUSH,
+					csi_dev->hw.ipi_auto_flush,
+					8, 1);
+
+		dw_mipi_csi_write(csi_dev,
+					reg.IPI_HSA_TIME, csi_dev->hw.hsa);
+
+		dw_mipi_csi_write(csi_dev,
+					reg.IPI_HBP_TIME, csi_dev->hw.hbp);
+
+		dw_mipi_csi_write(csi_dev,
+					reg.IPI_HSD_TIME, csi_dev->hw.hsd);
+
+		dev_dbg(dev, "IPI enable\n");
+		dev_dbg(dev, "IPI MODE: %d\n", csi_dev->hw.ipi_mode);
+		dev_dbg(dev, "Color Mode: %d\n", csi_dev->hw.ipi_color_mode);
+		dev_dbg(dev, "Virtual Channel: %d\n", csi_dev->hw.virtual_ch);
+		dev_dbg(dev, "Auto-flush: %d\n", csi_dev->hw.ipi_auto_flush);
+		dev_dbg(dev, "HSA: %d\n", csi_dev->hw.hsa);
+		dev_dbg(dev, "HBP: %d\n", csi_dev->hw.hbp);
+		dev_dbg(dev, "HSD: %d\n", csi_dev->hw.hsd);
+
+		if (csi_dev->hw.ipi_mode == AUTO_TIMING) {
+			dw_mipi_csi_write(csi_dev,
+				reg.IPI_HLINE_TIME, csi_dev->hw.htotal);
+			dw_mipi_csi_write(csi_dev,
+				reg.IPI_VSA_LINES, csi_dev->hw.vsa);
+			dw_mipi_csi_write(csi_dev,
+				reg.IPI_VBP_LINES, csi_dev->hw.vbp);
+			dw_mipi_csi_write(csi_dev,
+				reg.IPI_VFP_LINES, csi_dev->hw.vfp);
+			dw_mipi_csi_write(csi_dev,
+				reg.IPI_VACTIVE_LINES, csi_dev->hw.vactive);
+			dev_dbg(dev,
+				"Horizontal Total: %d\n", csi_dev->hw.htotal);
+			dev_dbg(dev,
+				"Vertical Sync Active: %d\n", csi_dev->hw.vsa);
+			dev_dbg(dev,
+				"Vertical Back Porch: %d\n", csi_dev->hw.vbp);
+			dev_dbg(dev,
+				"Vertical Front Porch: %d\n", csi_dev->hw.vfp);
+			dev_dbg(dev,
+				"Vertical Active: %d\n", csi_dev->hw.vactive);
+		}
+	}
+	phy_power_on(csi_dev->phy);
+}
+
+int dw_mipi_csi_irq_handler(struct mipi_csi_dev *csi_dev)
+{
+	struct device *dev = csi_dev->dev;
+	u32 global_int_status, i_sts;
+	unsigned long flags;
+
+	global_int_status = dw_mipi_csi_read(csi_dev, reg.INTERRUPT);
+	spin_lock_irqsave(&csi_dev->slock, flags);
+
+	if (global_int_status & csi_int.PHY_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: PHY FATAL: %08X\n",
+			reg.INT_PHY_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.PKT_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: PKT FATAL: %08X\n",
+			reg.INT_PKT_FATAL, i_sts);
+	}
+
+	if ((global_int_status & csi_int.FRAME_FATAL)
+	&& ((csi_dev->hw_version_major) == 1)
+	&& ((csi_dev->hw_version_minor) == 30)) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_FRAME_FATAL);
+			dev_err_ratelimited(dev,
+			"interrupt %08X: FRAME FATAL: %08X\n",
+			reg.INT_FRAME_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.PHY) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PHY);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: PHY: %08X\n",
+			reg.INT_PHY, i_sts);
+	}
+
+	if (global_int_status & csi_int.PKT) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_PKT);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: PKT: %08X\n",
+			reg.INT_PKT, i_sts);
+	}
+
+	if (global_int_status & csi_int.LINE) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_LINE);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: LINE: %08X\n",
+			reg.INT_LINE, i_sts);
+	}
+
+	if (global_int_status & csi_int.IPI) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.INT_IPI);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: IPI: %08X\n",
+			reg.INT_IPI, i_sts);
+	}
+
+	if (global_int_status & csi_int.BNDRY_FRAME_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_BNDRY_FRAME_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_BNDRY_FRAME_FATAL: %08X\n",
+			reg.ST_BNDRY_FRAME_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.SEQ_FRAME_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_SEQ_FRAME_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_SEQ_FRAME_FATAL: %08X\n",
+			reg.ST_SEQ_FRAME_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.CRC_FRAME_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_CRC_FRAME_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_CRC_FRAME_FATAL: %08X\n",
+			reg.ST_CRC_FRAME_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.PLD_CRC_FATAL) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_PLD_CRC_FATAL);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_PLD_CRC_FATAL: %08X\n",
+			reg.ST_PLD_CRC_FATAL, i_sts);
+	}
+
+	if (global_int_status & csi_int.DATA_ID) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_DATA_ID);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_DATA_ID: %08X\n",
+			reg.ST_DATA_ID, i_sts);
+	}
+
+	if (global_int_status & csi_int.ECC_CORRECTED) {
+		i_sts = dw_mipi_csi_read(csi_dev, reg.ST_ECC_CORRECT);
+		dev_err_ratelimited(dev,
+			"interrupt %08X: ST_ECC_CORRECT: %08X\n",
+			reg.ST_ECC_CORRECT, i_sts);
+	}
+
+	spin_unlock_irqrestore(&csi_dev->slock, flags);
+
+	return 1;
+}
+
+void dw_mipi_csi_get_version(struct mipi_csi_dev *csi_dev)
+{
+	uint32_t hw_version;
+
+	hw_version = dw_mipi_csi_read(csi_dev, reg.VERSION);
+	csi_dev->hw_version_major = (uint8_t) ((hw_version >> 24) - '0');
+	csi_dev->hw_version_minor = (uint8_t) ((hw_version >> 16) - '0');
+	csi_dev->hw_version_minor = csi_dev->hw_version_minor * 10;
+	csi_dev->hw_version_minor += (uint8_t) ((hw_version >> 8) - '0');
+}
+
+int dw_mipi_csi_specific_mappings(struct mipi_csi_dev *csi_dev)
+{
+	struct device *dev = csi_dev->dev;
+
+	if ((csi_dev->hw_version_major) == 1)
+		if ((csi_dev->hw_version_minor) == 30) {
+
+			dev_dbg(dev, "We are version 30");
+			/*
+			 * Hardware registers that were
+			 * exclusive to version < 1.40
+			 */
+			reg.INT_FRAME_FATAL = 0x100;
+			reg.MASK_INT_FRAME_FATAL = 0x104;
+			reg.FORCE_INT_FRAME_FATAL = 0x108;
+			reg.INT_PKT = 0x120;
+			reg.MASK_INT_PKT = 0x124;
+			reg.FORCE_INT_PKT = 0x128;
+
+			/* interrupt source present until this release */
+			csi_int.PKT = BIT(17);
+			csi_int.LINE = BIT(18);
+			csi_int.IPI = BIT(19);
+			csi_int.FRAME_FATAL = BIT(2);
+
+		} else if ((csi_dev->hw_version_minor) == 40) {
+			dev_dbg(dev, "We are version 40");
+			/*
+			 * HW registers that were added
+			 * to version 1.40
+			 */
+			reg.ST_BNDRY_FRAME_FATAL = 0x280;
+			reg.MSK_BNDRY_FRAME_FATAL = 0x284;
+			reg.FORCE_BNDRY_FRAME_FATAL	= 0x288;
+			reg.ST_SEQ_FRAME_FATAL = 0x290;
+			reg.MSK_SEQ_FRAME_FATAL	= 0x294;
+			reg.FORCE_SEQ_FRAME_FATAL = 0x298;
+			reg.ST_CRC_FRAME_FATAL = 0x2a0;
+			reg.MSK_CRC_FRAME_FATAL	= 0x2a4;
+			reg.FORCE_CRC_FRAME_FATAL = 0x2a8;
+			reg.ST_PLD_CRC_FATAL = 0x2b0;
+			reg.MSK_PLD_CRC_FATAL = 0x2b4;
+			reg.FORCE_PLD_CRC_FATAL = 0x2b8;
+			reg.ST_DATA_ID = 0x2c0;
+			reg.MSK_DATA_ID = 0x2c4;
+			reg.FORCE_DATA_ID = 0x2c8;
+			reg.ST_ECC_CORRECT = 0x2d0;
+			reg.MSK_ECC_CORRECT = 0x2d4;
+			reg.FORCE_ECC_CORRECT = 0x2d8;
+			reg.DATA_IDS_VC_1 = 0x0;
+			reg.DATA_IDS_VC_2 = 0x0;
+			reg.VC_EXTENSION = 0x0;
+
+			/* interrupts map were changed */
+			csi_int.LINE = BIT(17);
+			csi_int.IPI = BIT(18);
+			csi_int.BNDRY_FRAME_FATAL = BIT(2);
+			csi_int.SEQ_FRAME_FATAL	= BIT(3);
+			csi_int.CRC_FRAME_FATAL = BIT(4);
+			csi_int.PLD_CRC_FATAL = BIT(5);
+			csi_int.DATA_ID = BIT(6);
+			csi_int.ECC_CORRECTED = BIT(7);
+
+		} else
+			dev_info(dev, "Version minor not supported.");
+	else
+		dev_info(dev, "Version major not supported.");
+
+	return 0;
+}
diff --git a/drivers/media/platform/dwc/dw-mipi-csi.h b/drivers/media/platform/dwc/dw-mipi-csi.h
new file mode 100644
index 0000000..b7163f3
--- /dev/null
+++ b/drivers/media/platform/dwc/dw-mipi-csi.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI CSI-2 Host controller driver
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ */
+
+#ifndef _DW_MIPI_CSI_H__
+#define _DW_MIPI_CSI_H__
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/phy/phy.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/dwc/dw-mipi-csi-pltfrm.h>
+
+/* DW MIPI CSI-2 register addresses*/
+
+struct R_CSI2 {
+	u16 VERSION;
+	u16 N_LANES;
+	u16 CTRL_RESETN;
+	u16 INTERRUPT;
+	u16 DATA_IDS_1;
+	u16 DATA_IDS_2;
+	u16 DATA_IDS_VC_1;
+	u16 DATA_IDS_VC_2;
+	u16 IPI_MODE;
+	u16 IPI_VCID;
+	u16 IPI_DATA_TYPE;
+	u16 IPI_MEM_FLUSH;
+	u16 IPI_HSA_TIME;
+	u16 IPI_HBP_TIME;
+	u16 IPI_HSD_TIME;
+	u16 IPI_HLINE_TIME;
+	u16 IPI_SOFTRSTN;
+	u16 IPI_ADV_FEATURES;
+	u16 IPI_VSA_LINES;
+	u16 IPI_VBP_LINES;
+	u16 IPI_VFP_LINES;
+	u16 IPI_VACTIVE_LINES;
+	u16 VC_EXTENSION;
+	u16 INT_PHY_FATAL;
+	u16 MASK_INT_PHY_FATAL;
+	u16 FORCE_INT_PHY_FATAL;
+	u16 INT_PKT_FATAL;
+	u16 MASK_INT_PKT_FATAL;
+	u16 FORCE_INT_PKT_FATAL;
+	u16 INT_FRAME_FATAL;
+	u16 MASK_INT_FRAME_FATAL;
+	u16 FORCE_INT_FRAME_FATAL;
+	u16 INT_PHY;
+	u16 MASK_INT_PHY;
+	u16 FORCE_INT_PHY;
+	u16 INT_PKT;
+	u16 MASK_INT_PKT;
+	u16 FORCE_INT_PKT;
+	u16 INT_LINE;
+	u16 MASK_INT_LINE;
+	u16 FORCE_INT_LINE;
+	u16 INT_IPI;
+	u16 MASK_INT_IPI;
+	u16 FORCE_INT_IPI;
+	u16 ST_BNDRY_FRAME_FATAL;
+	u16 MSK_BNDRY_FRAME_FATAL;
+	u16 FORCE_BNDRY_FRAME_FATAL;
+	u16 ST_SEQ_FRAME_FATAL;
+	u16 MSK_SEQ_FRAME_FATAL;
+	u16 FORCE_SEQ_FRAME_FATAL;
+	u16 ST_CRC_FRAME_FATAL;
+	u16 MSK_CRC_FRAME_FATAL;
+	u16 FORCE_CRC_FRAME_FATAL;
+	u16 ST_PLD_CRC_FATAL;
+	u16 MSK_PLD_CRC_FATAL;
+	u16 FORCE_PLD_CRC_FATAL;
+	u16 ST_DATA_ID;
+	u16 MSK_DATA_ID;
+	u16 FORCE_DATA_ID;
+	u16 ST_ECC_CORRECT;
+	u16 MSK_ECC_CORRECT;
+	u16 FORCE_ECC_CORRECT;
+};
+/* Interrupt Masks */
+struct interrupt_type {
+	u32 PHY_FATAL;
+	u32 PKT_FATAL;
+	u32 FRAME_FATAL;
+	u32 PHY;
+	u32 PKT;
+	u32 LINE;
+	u32 IPI;
+	u32 BNDRY_FRAME_FATAL;
+	u32 SEQ_FRAME_FATAL;
+	u32 CRC_FRAME_FATAL;
+	u32 PLD_CRC_FATAL;
+	u32 DATA_ID;
+	u32 ECC_CORRECTED;
+};
+
+/* IPI Data Types */
+enum data_type {
+	CSI_2_YUV420_8 = 0x18,
+	CSI_2_YUV420_10 = 0x19,
+	CSI_2_YUV420_8_LEG = 0x1A,
+	CSI_2_YUV420_8_SHIFT = 0x1C,
+	CSI_2_YUV420_10_SHIFT = 0x1D,
+	CSI_2_YUV422_8 = 0x1E,
+	CSI_2_YUV422_10 = 0x1F,
+	CSI_2_RGB444 = 0x20,
+	CSI_2_RGB555 = 0x21,
+	CSI_2_RGB565 = 0x22,
+	CSI_2_RGB666 = 0x23,
+	CSI_2_RGB888 = 0x24,
+	CSI_2_RAW6 = 0x28,
+	CSI_2_RAW7 = 0x29,
+	CSI_2_RAW8 = 0x2A,
+	CSI_2_RAW10 = 0x2B,
+	CSI_2_RAW12 = 0x2C,
+	CSI_2_RAW14 = 0x2D,
+};
+
+/* DWC MIPI CSI-2 output types */
+enum output {
+	IPI_OUT = 0,
+	IDI_OUT = 1,
+	BOTH_OUT = 2
+};
+
+/* IPI output types */
+enum ipi_output {
+	CAMERA_TIMING = 0,
+	AUTO_TIMING = 1
+};
+
+/* Format template */
+struct mipi_fmt {
+	u32 code;
+	u8 depth;
+};
+
+/* CSI specific configuration */
+struct csi_hw {
+
+	uint32_t num_lanes;
+	uint32_t output;
+	uint32_t ipi_mode;
+	uint32_t ipi_color_mode;
+	uint32_t ipi_auto_flush;
+	uint32_t virtual_ch;
+	uint32_t hsa;
+	uint32_t hbp;
+	uint32_t hsd;
+	uint32_t htotal;
+	uint32_t vsa;
+	uint32_t vbp;
+	uint32_t vfp;
+	uint32_t vactive;
+};
+
+/* Structure to embed device driver information */
+struct mipi_csi_dev {
+	struct v4l2_subdev sd;
+	struct video_device vdev;
+	struct device *dev;
+
+	struct mutex lock;
+	spinlock_t slock;
+	struct media_pad pads[CSI_PADS_NUM];
+	u8 index;
+
+	/* Store current format */
+	const struct mipi_fmt *fmt;
+	struct v4l2_mbus_framefmt format;
+
+	/* Device Tree Information */
+	void __iomem *base_address;
+	uint32_t ctrl_irq_number;
+
+	struct csi_hw hw;
+	struct phy *phy;
+	struct reset_control *rst;
+
+	u8 ipi_dt;
+	u8 hw_version_major;
+	u16 hw_version_minor;
+};
+
+void dw_mipi_csi_reset(struct mipi_csi_dev *csi_dev);
+int dw_mipi_csi_mask_irq_power_off(struct mipi_csi_dev *csi_dev);
+int dw_mipi_csi_hw_stdby(struct mipi_csi_dev *csi_dev);
+void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev);
+void dw_mipi_csi_start(struct mipi_csi_dev *csi_dev);
+int dw_mipi_csi_irq_handler(struct mipi_csi_dev *csi_dev);
+void dw_mipi_csi_get_version(struct mipi_csi_dev *csi_dev);
+int dw_mipi_csi_specific_mappings(struct mipi_csi_dev *csi_dev);
+void dw_mipi_csi_fill_timings(struct mipi_csi_dev *dev,
+		const struct v4l2_bt_timings *bt);
+
+#endif /*_DW_MIPI_CSI_H__ */
diff --git a/include/media/dwc/dw-mipi-csi-pltfrm.h b/include/media/dwc/dw-mipi-csi-pltfrm.h
new file mode 100644
index 0000000..c36f206
--- /dev/null
+++ b/include/media/dwc/dw-mipi-csi-pltfrm.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 Synopsys, Inc.
+ *
+ * Synopsys MIPI CSI-2 video platform helper
+ *
+ * Author: Luis Oliveira <Luis.Oliveira@synopsys.com>
+ *
+ */
+
+#ifndef __DW_MIPI_CSI_PLTFRM_INCLUDES_H_
+#define __DW_MIPI_CSI_PLTFRM_INCLUDES_H_
+
+#include <media/media-entity.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX_WIDTH	3280
+#define MAX_HEIGHT	1852
+#define MIN_WIDTH	640
+#define MIN_HEIGHT	480
+
+/* The subdevices' group IDs. */
+#define GRP_ID_SENSOR		(10)
+#define GRP_ID_CSI		(20)
+#define GRP_ID_VIF		(30)
+#define GRP_ID_VIDEODEV		(40)
+
+#define CSI_MAX_ENTITIES	(2)
+#define VIF_MAX_ENTITIES	(2)
+#define PLAT_MAX_SENSORS	(2)
+
+enum video_dev_pads {
+	VIDEO_DEV_SD_PAD_SINK_VIF1	= 0,
+	VIDEO_DEV_SD_PAD_SINK_VIF2	= 1,
+	VIDEO_DEV_SD_PAD_SOURCE_DMA	= 2,
+	VIDEO_DEV_SD_PADS_NUM		= 3,
+};
+enum vif_pads {
+	VIF_PAD_SINK_CSI		= 0,
+	VIF_PAD_SOURCE_DMA		= 1,
+	VIF_PADS_NUM			= 2,
+};
+
+enum mipi_csi_pads {
+	CSI_PAD_SINK			= 0,
+	CSI_PAD_SOURCE			= 1,
+	CSI_PADS_NUM			= 2,
+};
+
+struct plat_csi_source_info {
+	u16 flags;
+	u16 mux_id;
+};
+
+struct plat_csi_fmt {
+	char *name;
+	u32 mbus_code;
+	u32 fourcc;
+	u8 depth;
+};
+
+struct plat_csi_media_pipeline;
+
+/*
+ * Media pipeline operations to be called from within a video node,  i.e. the
+ * last entity within the pipeline. Implemented by related media device driver.
+ */
+struct plat_csi_media_pipeline_ops {
+	int (*prepare)(struct plat_csi_media_pipeline *p,
+		struct media_entity *me);
+	int (*unprepare)(struct plat_csi_media_pipeline *p);
+	int (*open)(struct plat_csi_media_pipeline *p, struct media_entity *me,
+		bool resume);
+	int (*close)(struct plat_csi_media_pipeline *p);
+	int (*set_stream)(struct plat_csi_media_pipeline *p, bool state);
+	int (*set_format)(struct plat_csi_media_pipeline *p,
+		struct v4l2_subdev_format *fmt);
+};
+
+struct plat_csi_video_entity {
+	struct video_device vdev;
+	struct plat_csi_media_pipeline *pipe;
+};
+
+struct plat_csi_media_pipeline {
+	struct media_pipeline mp;
+	const struct plat_csi_media_pipeline_ops *ops;
+};
+
+static inline struct plat_csi_video_entity
+*vdev_to_plat_csi_video_entity(struct video_device *vdev)
+{
+	return container_of(vdev, struct plat_csi_video_entity, vdev);
+}
+
+#define plat_csi_pipeline_call(ent, op, args...)			  \
+	(!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+	(ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD))	  \
+
+#endif /* __DW_MIPI_CSI_PLTFRM_INCLUDES_H_ */
--
2.7.4


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings
  2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
@ 2018-10-24 17:36   ` Rob Herring
  2018-11-13  8:58     ` Luis Oliveira
  2018-11-13  9:30     ` Luis de Oliveira
  2018-11-14 20:08   ` Laurent Pinchart
  1 sibling, 2 replies; 26+ messages in thread
From: Rob Herring @ 2018-10-24 17:36 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam, Mark Rutland,
	Mauro Carvalho Chehab, Hans Verkuil, Laurent Pinchart,
	Arnd Bergmann, Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov, devicetree

On Fri, Oct 19, 2018 at 02:52:23PM +0200, Luis Oliveira wrote:
> Add device-tree bindings documentation for SNPS DesignWare MIPI D-PHY in
> RX mode.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - removed gpios reference - it was for a separated driver
> - changed address to show complete address
> 
>  .../devicetree/bindings/phy/snps,dphy-rx.txt       | 28 ++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> 
> diff --git a/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> new file mode 100644
> index 0000000..03d17ab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> @@ -0,0 +1,28 @@
> +Synopsys DesignWare MIPI Rx D-PHY block details
> +
> +Description
> +-----------
> +
> +The Synopsys MIPI D-PHY controller supports MIPI-DPHY in receiver mode.
> +Please refer to phy-bindings.txt for more information.
> +
> +Required properties:
> +- compatible		: Shall be "snps,dphy-rx".
> +- #phy-cells		: Must be 1.
> +- snps,dphy-frequency	: Output frequency of the D-PHY.

Needs a unit suffix (-hz).

> +- snps,dphy-te-len	: Size of the communication interface (8 bits->8 or 12bits->12).
> +- reg			: Physical base address and size of the device memory mapped
> +		 	  registers;

How many, what are they, and what order? Looks like 3 below.

Also, a tab after spaces error.

> +
> +Example:
> +
> +	mipi_dphy_rx1: dphy@d00003040 {
> +		compatible = "snps,dphy-rx";
> +		#phy-cells = <1>;
> +		snps,dphy-frequency = <300000>;
> +		snps,dphy-te-len = <12>;
> +		reg = < 0xd0003040 0x20
> +			0xd0008000 0x100
> +			0xd0009000 0x100>;
> +	};
> +
> --
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
@ 2018-10-24 17:40   ` Rob Herring
  2018-11-13 10:00     ` Luis de Oliveira
  2018-10-24 17:41   ` Rob Herring
  2019-01-11 15:29   ` Eugen.Hristev
  2 siblings, 1 reply; 26+ messages in thread
From: Rob Herring @ 2018-10-24 17:40 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

On Fri, Oct 19, 2018 at 02:52:25PM +0200, Luis Oliveira wrote:
> Add bindings for Synopsys DesignWare MIPI CSI-2 host.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - removed IPI settings
> 
>  .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> new file mode 100644
> index 0000000..be3da05
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> @@ -0,0 +1,52 @@
> +Synopsys DesignWare CSI-2 Host controller
> +
> +Description
> +-----------
> +
> +This HW block is used to receive image coming from an MIPI CSI-2 compatible
> +camera.
> +
> +Required properties:
> +- compatible: shall be "snps,dw-csi-plat"

'plat' is really part of the name of the h/w block?

> +- reg			: physical base address and size of the device memory mapped
> +  registers;
> +- interrupts		: CSI-2 Host interrupt
> +- snps,output-type	: Core output to be used (IPI-> 0 or IDI->1 or BOTH->2)
> +			  These  values choose which of the Core outputs will be used,
> +			  it can be Image Data Interface or Image Pixel Interface.
> +- phys			: List of one PHY specifier (as defined in
> +			  Documentation/devicetree/bindings/phy/phy-bindings.txt).
> +			  This PHY is a MIPI DPHY working in RX mode.
> +- resets		: Reference to a reset controller (optional)
> +
> +The per-board settings:
> + - port sub-node describing a single endpoint connected to the camera as
> +   described in video-interfaces.txt[1].

Need to say 2 ports and what is each port? Why no port #0?

> +
> +Example:
> +
> +	csi2_1: csi2@3000 {
> +		compatible = "snps,dw-csi-plat";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = < 0x03000 0x7FF>;
> +		interrupts = <2>;
> +		output-type = <2>;
> +		resets = <&dw_rst 1>;
> +		phys = <&mipi_dphy_rx1 0>;
> +		phy-names = "csi2-dphy";

Not documented. Not really needed for a single entry, so I'd just drop 
it.

> +
> +		/* CSI-2 per-board settings */
> +		port@1 {
> +			reg = <1>;
> +			csi1_ep1: endpoint {
> +				remote-endpoint = <&camera_1>;
> +				data-lanes = <1 2>;
> +			};
> +		};
> +		port@2 {
> +			csi1_ep2: endpoint {
> +				remote-endpoint = <&vif1_ep>;
> +			};
> +		};
> +	};
> --
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
  2018-10-24 17:40   ` Rob Herring
@ 2018-10-24 17:41   ` Rob Herring
  2018-11-13 10:00     ` Luis de Oliveira
  2019-01-11 15:29   ` Eugen.Hristev
  2 siblings, 1 reply; 26+ messages in thread
From: Rob Herring @ 2018-10-24 17:41 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

On Fri, Oct 19, 2018 at 02:52:25PM +0200, Luis Oliveira wrote:
> Add bindings for Synopsys DesignWare MIPI CSI-2 host.

Also, drop "Documentation: " from the subject. All bindings are 
documentation and the preferred prefix is 'dt-bindings: <binding dir>: '.

> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - removed IPI settings
> 
>  .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
>  1 file changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings
  2018-10-24 17:36   ` Rob Herring
@ 2018-11-13  8:58     ` Luis Oliveira
  2018-11-13  9:30     ` Luis de Oliveira
  1 sibling, 0 replies; 26+ messages in thread
From: Luis Oliveira @ 2018-11-13  8:58 UTC (permalink / raw)
  To: Rob Herring, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam, Mark Rutland,
	Mauro Carvalho Chehab, Hans Verkuil, Laurent Pinchart,
	Arnd Bergmann, Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov, devicetree

Hi Rob, my responses inline.

On 24-Oct-18 18:36, Rob Herring wrote:
> On Fri, Oct 19, 2018 at 02:52:23PM +0200, Luis Oliveira wrote:
>> Add device-tree bindings documentation for SNPS DesignWare MIPI D-PHY in
>> RX mode.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - removed gpios reference - it was for a separated driver
>> - changed address to show complete address
>>
>>  .../devicetree/bindings/phy/snps,dphy-rx.txt       | 28 ++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>>
>> diff --git a/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>> new file mode 100644
>> index 0000000..03d17ab
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>> @@ -0,0 +1,28 @@
>> +Synopsys DesignWare MIPI Rx D-PHY block details
>> +
>> +Description
>> +-----------
>> +
>> +The Synopsys MIPI D-PHY controller supports MIPI-DPHY in receiver mode.
>> +Please refer to phy-bindings.txt for more information.
>> +
>> +Required properties:
>> +- compatible		: Shall be "snps,dphy-rx".
>> +- #phy-cells		: Must be 1.
>> +- snps,dphy-frequency	: Output frequency of the D-PHY.
> 
> Needs a unit suffix (-hz).
> 

Yes,

>> +- snps,dphy-te-len	: Size of the communication interface (8 bits->8 or 12bits->12).
>> +- reg			: Physical base address and size of the device memory mapped
>> +		 	  registers;
> 
> How many, what are they, and what order? Looks like 3 below.
> 
> Also, a tab after spaces error.
> 

Yep, I will fix it. Thanks

>> +
>> +Example:
>> +
>> +	mipi_dphy_rx1: dphy@d00003040 {
>> +		compatible = "snps,dphy-rx";
>> +		#phy-cells = <1>;
>> +		snps,dphy-frequency = <300000>;
>> +		snps,dphy-te-len = <12>;
>> +		reg = < 0xd0003040 0x20
>> +			0xd0008000 0x100
>> +			0xd0009000 0x100>;
>> +	};
>> +
>> --
>> 2.7.4
>>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings
  2018-10-24 17:36   ` Rob Herring
  2018-11-13  8:58     ` Luis Oliveira
@ 2018-11-13  9:30     ` Luis de Oliveira
  1 sibling, 0 replies; 26+ messages in thread
From: Luis de Oliveira @ 2018-11-13  9:30 UTC (permalink / raw)
  To: Rob Herring, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam, Mark Rutland,
	Mauro Carvalho Chehab, Hans Verkuil, Laurent Pinchart,
	Arnd Bergmann, Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov, devicetree

Hi Rob, my responses inline.

On 24-Oct-18 18:36, Rob Herring wrote:
> On Fri, Oct 19, 2018 at 02:52:23PM +0200, Luis Oliveira wrote:
>> Add device-tree bindings documentation for SNPS DesignWare MIPI D-PHY in
>> RX mode.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - removed gpios reference - it was for a separated driver
>> - changed address to show complete address
>>
>>  .../devicetree/bindings/phy/snps,dphy-rx.txt       | 28 ++++++++++++++++++++++
>>  1 file changed, 28 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>>
>> diff --git a/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>> new file mode 100644
>> index 0000000..03d17ab
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
>> @@ -0,0 +1,28 @@
>> +Synopsys DesignWare MIPI Rx D-PHY block details
>> +
>> +Description
>> +-----------
>> +
>> +The Synopsys MIPI D-PHY controller supports MIPI-DPHY in receiver mode.
>> +Please refer to phy-bindings.txt for more information.
>> +
>> +Required properties:
>> +- compatible		: Shall be "snps,dphy-rx".
>> +- #phy-cells		: Must be 1.
>> +- snps,dphy-frequency	: Output frequency of the D-PHY.
> 
> Needs a unit suffix (-hz).
> 

Yes,

>> +- snps,dphy-te-len	: Size of the communication interface (8 bits->8 or 12bits->12).
>> +- reg			: Physical base address and size of the device memory mapped
>> +		 	  registers;
> 
> How many, what are they, and what order? Looks like 3 below.
> 
> Also, a tab after spaces error.
> 

Yep, I will fix it. Thanks

>> +
>> +Example:
>> +
>> +	mipi_dphy_rx1: dphy@d00003040 {
>> +		compatible = "snps,dphy-rx";
>> +		#phy-cells = <1>;
>> +		snps,dphy-frequency = <300000>;
>> +		snps,dphy-te-len = <12>;
>> +		reg = < 0xd0003040 0x20
>> +			0xd0008000 0x100
>> +			0xd0009000 0x100>;
>> +	};
>> +
>> --
>> 2.7.4
>>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-24 17:40   ` Rob Herring
@ 2018-11-13 10:00     ` Luis de Oliveira
  2018-11-14 20:16       ` Laurent Pinchart
  0 siblings, 1 reply; 26+ messages in thread
From: Luis de Oliveira @ 2018-11-13 10:00 UTC (permalink / raw)
  To: Rob Herring, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree



On 24-Oct-18 18:40, Rob Herring wrote:
> On Fri, Oct 19, 2018 at 02:52:25PM +0200, Luis Oliveira wrote:
>> Add bindings for Synopsys DesignWare MIPI CSI-2 host.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - removed IPI settings
>>
>>  .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
>>  1 file changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
>>
>> diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
>> new file mode 100644
>> index 0000000..be3da05
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
>> @@ -0,0 +1,52 @@
>> +Synopsys DesignWare CSI-2 Host controller
>> +
>> +Description
>> +-----------
>> +
>> +This HW block is used to receive image coming from an MIPI CSI-2 compatible
>> +camera.
>> +
>> +Required properties:
>> +- compatible: shall be "snps,dw-csi-plat"
> 
> 'plat' is really part of the name of the h/w block?
> 

It is the name of the platform driver for CSI compatible with this block. Is
that wrong?

>> +- reg			: physical base address and size of the device memory mapped
>> +  registers;
>> +- interrupts		: CSI-2 Host interrupt
>> +- snps,output-type	: Core output to be used (IPI-> 0 or IDI->1 or BOTH->2)
>> +			  These  values choose which of the Core outputs will be used,
>> +			  it can be Image Data Interface or Image Pixel Interface.
>> +- phys			: List of one PHY specifier (as defined in
>> +			  Documentation/devicetree/bindings/phy/phy-bindings.txt).
>> +			  This PHY is a MIPI DPHY working in RX mode.
>> +- resets		: Reference to a reset controller (optional)
>> +
>> +The per-board settings:
>> + - port sub-node describing a single endpoint connected to the camera as
>> +   described in video-interfaces.txt[1].
> 
> Need to say 2 ports and what is each port? Why no port #0?
> 

I will elaborate on that.

>> +
>> +Example:
>> +
>> +	csi2_1: csi2@3000 {
>> +		compatible = "snps,dw-csi-plat";
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +		reg = < 0x03000 0x7FF>;
>> +		interrupts = <2>;
>> +		output-type = <2>;
>> +		resets = <&dw_rst 1>;
>> +		phys = <&mipi_dphy_rx1 0>;
>> +		phy-names = "csi2-dphy";
> 
> Not documented. Not really needed for a single entry, so I'd just drop 
> it.
> 

I will, thanks.

>> +
>> +		/* CSI-2 per-board settings */
>> +		port@1 {
>> +			reg = <1>;
>> +			csi1_ep1: endpoint {
>> +				remote-endpoint = <&camera_1>;
>> +				data-lanes = <1 2>;
>> +			};
>> +		};
>> +		port@2 {
>> +			csi1_ep2: endpoint {
>> +				remote-endpoint = <&vif1_ep>;
>> +			};
>> +		};
>> +	};
>> --
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-24 17:41   ` Rob Herring
@ 2018-11-13 10:00     ` Luis de Oliveira
  0 siblings, 0 replies; 26+ messages in thread
From: Luis de Oliveira @ 2018-11-13 10:00 UTC (permalink / raw)
  To: Rob Herring, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree



On 24-Oct-18 18:41, Rob Herring wrote:
> On Fri, Oct 19, 2018 at 02:52:25PM +0200, Luis Oliveira wrote:
>> Add bindings for Synopsys DesignWare MIPI CSI-2 host.
> 
> Also, drop "Documentation: " from the subject. All bindings are 
> documentation and the preferred prefix is 'dt-bindings: <binding dir>: '.
> 
>>

Ok, thank you again.

>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - removed IPI settings
>>
>>  .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
>>  1 file changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings
  2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
  2018-10-24 17:36   ` Rob Herring
@ 2018-11-14 20:08   ` Laurent Pinchart
  1 sibling, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-11-14 20:08 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam, Rob Herring,
	Mark Rutland, Mauro Carvalho Chehab, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

Hi Luis,

Thank you for the patch.

On Friday, 19 October 2018 15:52:23 EET Luis Oliveira wrote:
> Add device-tree bindings documentation for SNPS DesignWare MIPI D-PHY in
> RX mode.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - removed gpios reference - it was for a separated driver
> - changed address to show complete address
> 
>  .../devicetree/bindings/phy/snps,dphy-rx.txt       | 28 +++++++++++++++++++
>  1 file changed, 28 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> 
> diff --git a/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt new file mode
> 100644
> index 0000000..03d17ab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> @@ -0,0 +1,28 @@
> +Synopsys DesignWare MIPI Rx D-PHY block details
> +
> +Description
> +-----------
> +
> +The Synopsys MIPI D-PHY controller supports MIPI-DPHY in receiver mode.
> +Please refer to phy-bindings.txt for more information.
> +
> +Required properties:
> +- compatible		: Shall be "snps,dphy-rx".
> +- #phy-cells		: Must be 1.
> +- snps,dphy-frequency	: Output frequency of the D-PHY.

You replied to my review of v2 that you would remove this property. Is this an 
oversight ?

> +- snps,dphy-te-len	: Size of the communication interface (8 bits->8 or
> 12bits->12).
> +- reg			: Physical base address and size of the device memory mapped
> +		 	  registers;

Please document the ranges.

> +Example:
> +
> +	mipi_dphy_rx1: dphy@d00003040 {
> +		compatible = "snps,dphy-rx";
> +		#phy-cells = <1>;
> +		snps,dphy-frequency = <300000>;
> +		snps,dphy-te-len = <12>;
> +		reg = < 0xd0003040 0x20
> +			0xd0008000 0x100
> +			0xd0009000 0x100>;
> +	};
> +

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-11-13 10:00     ` Luis de Oliveira
@ 2018-11-14 20:16       ` Laurent Pinchart
  0 siblings, 0 replies; 26+ messages in thread
From: Laurent Pinchart @ 2018-11-14 20:16 UTC (permalink / raw)
  To: Luis de Oliveira
  Cc: Rob Herring, linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Mark Rutland, Hans Verkuil,
	Laurent Pinchart, Arnd Bergmann, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Keiichi Watanabe, Kate Stewart,
	Todor Tomov, devicetree

Hi Luis,

Thank you for the patch.

On Tuesday, 13 November 2018 12:00:22 EET Luis de Oliveira wrote:
> On 24-Oct-18 18:40, Rob Herring wrote:
> > On Fri, Oct 19, 2018 at 02:52:25PM +0200, Luis Oliveira wrote:
> >> Add bindings for Synopsys DesignWare MIPI CSI-2 host.
> >> 
> >> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> >> ---
> >> Changelog
> >> v2-V3
> >> - removed IPI settings
> >> 
> >>  .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++
> >>  1 file changed, 52 insertions(+)
> >>  create mode 100644
> >>  Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt>> 
> >> diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> >> b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt new file
> >> mode 100644
> >> index 0000000..be3da05
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> >> @@ -0,0 +1,52 @@
> >> +Synopsys DesignWare CSI-2 Host controller
> >> +
> >> +Description
> >> +-----------
> >> +
> >> +This HW block is used to receive image coming from an MIPI CSI-2
> >> compatible +camera.
> >> +
> >> +Required properties:
> >> +- compatible: shall be "snps,dw-csi-plat"
> > 
> > 'plat' is really part of the name of the h/w block?
> 
> It is the name of the platform driver for CSI compatible with this block. Is
> that wrong?

DT bindings describe hardware, not drivers. This should be the name of the IP 
core, regardless of how the drivers are architectured and named.

> >> +- reg			: physical base address and size of the device memory
> >> mapped
> >> +  registers;
> >> +- interrupts		: CSI-2 Host interrupt
> >> +- snps,output-type	: Core output to be used (IPI-> 0 or IDI->1 or
> >> BOTH->2)
> >> +			  These  values choose which of the Core outputs will be used,
> >> +			  it can be Image Data Interface or Image Pixel Interface.

Does this describe what outputs the IP core has been instantiated 
(synthesized) with, or what output(s) are used at runtime ? How does that 
relate to the port nodes ?

> >> +- phys			: List of one PHY specifier (as defined in
> >> +			  Documentation/devicetree/bindings/phy/phy-bindings.txt).
> >> +			  This PHY is a MIPI DPHY working in RX mode.
> >> +- resets		: Reference to a reset controller (optional)
> >> +
> >> +The per-board settings:
> >> + - port sub-node describing a single endpoint connected to the camera as
> >> +   described in video-interfaces.txt[1].
> > 
> > Need to say 2 ports and what is each port? Why no port #0?
> 
> I will elaborate on that.
> 
> >> +
> >> +Example:
> >> +
> >> +	csi2_1: csi2@3000 {
> >> +		compatible = "snps,dw-csi-plat";
> >> +		#address-cells = <1>;
> >> +		#size-cells = <0>;
> >> +		reg = < 0x03000 0x7FF>;
> >> +		interrupts = <2>;
> >> +		output-type = <2>;
> >> +		resets = <&dw_rst 1>;
> >> +		phys = <&mipi_dphy_rx1 0>;
> >> +		phy-names = "csi2-dphy";
> > 
> > Not documented. Not really needed for a single entry, so I'd just drop
> > it.
> 
> I will, thanks.
> 
> >> +
> >> +		/* CSI-2 per-board settings */
> >> +		port@1 {
> >> +			reg = <1>;
> >> +			csi1_ep1: endpoint {
> >> +				remote-endpoint = <&camera_1>;
> >> +				data-lanes = <1 2>;
> >> +			};
> >> +		};
> >> +		port@2 {
> >> +			csi1_ep2: endpoint {
> >> +				remote-endpoint = <&vif1_ep>;
> >> +			};
> >> +		};
> >> +	};

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
@ 2018-11-14 20:22   ` Laurent Pinchart
  2019-01-10 17:00     ` Luis de Oliveira
  2018-12-10 12:39   ` Eugen.Hristev
  2019-01-09 13:07   ` Eugen.Hristev
  2 siblings, 1 reply; 26+ messages in thread
From: Laurent Pinchart @ 2018-11-14 20:22 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, David S. Miller,
	Andrew Morton, Arnd Bergmann, Hans Verkuil, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Thierry Reding, Maxime Ripard,
	Todor Tomov

Hi Luis,

Thank you for the patch.

On Friday, 19 October 2018 15:52:26 EET Luis Oliveira wrote:
> Add the Synopsys MIPI CSI-2 controller driver. This
> controller driver is divided in platform dependent functions
> and core functions. It also includes a platform for future
> DesignWare drivers.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - exposed IPI settings to userspace

Could you please explain why you need this and can't use standard APIs ? 
Custom sysfs attributes are needed, they need to be documented in 
Documentation/ABI/.

> - fixed headers
> 
>  MAINTAINERS                              |  11 +
>  drivers/media/platform/dwc/Kconfig       |  30 +-
>  drivers/media/platform/dwc/Makefile      |   2 +
>  drivers/media/platform/dwc/dw-csi-plat.c | 699 ++++++++++++++++++++++++++++
>  drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>  drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>  drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>  include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>  8 files changed, 1616 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>  create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>  create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>  create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>  create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index da2e509..fd5f1fc 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14032,6 +14032,16 @@ S:	Maintained
>  F:	drivers/dma/dwi-axi-dmac/
>  F:	Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt
> 
> +SYNOPSYS DESIGNWARE MIPI CSI-2 HOST VIDEO PLATFORM
> +M:	Luis Oliveira <luis.oliveira@synopsys.com>
> +L:	linux-media@vger.kernel.org
> +T:	git git://linuxtv.org/media_tree.git
> +S:	Maintained
> +F:	drivers/media/platform/dwc
> +F:	include/media/dwc/dw-mipi-csi-pltfrm.h
> +F:	Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> +F:	Documentation/devicetree/bindings/phy/snps,dphy-rx.txt

These two lines belong to patches 1/4 and 3/4. Doesn't checkpatch.pl warn 
about this ? Now that I mentioned checkpatch.pl, I tried running it on this 
series, and it generates a fair number of warnings and errors. Could you 
please fix them ?

> +
>  SYNOPSYS DESIGNWARE DMAC DRIVER
>  M:	Viresh Kumar <vireshk@kernel.org>
>  R:	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> @@ -16217,3 +16227,4 @@ T:	git
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git S:	Buried
> alive in reporters
>  F:	*
>  F:	*/
> +

Stray new line.

[snip]

-- 
Regards,

Laurent Pinchart




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
  2018-11-14 20:22   ` Laurent Pinchart
@ 2018-12-10 12:39   ` Eugen.Hristev
  2019-01-10 16:11     ` Luis de Oliveira
  2019-01-09 13:07   ` Eugen.Hristev
  2 siblings, 1 reply; 26+ messages in thread
From: Eugen.Hristev @ 2018-12-10 12:39 UTC (permalink / raw)
  To: luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 19.10.2018 15:52, Luis Oliveira wrote:
> Add the Synopsys MIPI CSI-2 controller driver. This
> controller driver is divided in platform dependent functions
> and core functions. It also includes a platform for future
> DesignWare drivers.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - exposed IPI settings to userspace
> - fixed headers
[...]

snip


> +
> +static int
> +dw_mipi_csi_parse_dt(struct platform_device *pdev, struct mipi_csi_dev *dev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct v4l2_fwnode_endpoint endpoint;

Hello Luis,

I believe you have to initialize "endpoint" here correctly, otherwise 
the parsing mechanism (fwnode_endpoint_parse) will consider you have a 
specific mbus type and fail to probe the endpoint: bail out with debug 
message "expecting bus type not found "

(namely, initialize to zero which is the UNKNOWN mbus type, or , to a 
specific mbus (from DT or whatever source))

Eugen


> +	int ret;
> +
> +	node = of_graph_get_next_endpoint(node, NULL);
> +	if (!node) {
> +		dev_err(&pdev->dev, "No port node at %s\n",
> +				pdev->dev.of_node->full_name);
> +		return -EINVAL;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
> +	if (ret)
> +		goto err;
> +
> +	dev->index = endpoint.base.port - 1;
> +	if (dev->index >= CSI_MAX_ENTITIES) {
> +		ret = -ENXIO;
> +		goto err;
> +	}
> +	dev->hw.num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
> +
> +err:
> +	of_node_put(node);
> +	return ret;
> +}
> +

snip

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform
  2018-10-19 12:52 ` [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform Luis Oliveira
@ 2019-01-07 11:58   ` Sakari Ailus
  2019-01-08  9:17     ` Luis de Oliveira
  0 siblings, 1 reply; 26+ messages in thread
From: Sakari Ailus @ 2019-01-07 11:58 UTC (permalink / raw)
  To: Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Hans Verkuil, Laurent Pinchart,
	Arnd Bergmann, Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov

Hi Luis,

On Fri, Oct 19, 2018 at 02:52:24PM +0200, Luis Oliveira wrote:
> Add of Synopsys MIPI D-PHY in RX mode support.
> Separated in the implementation are platform dependent probing functions.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>

Maxime has a patchset adding D-PHY parameters to the PHY API. I think they
could be relevant for this one as well:

<URL:https://www.spinics.net/lists/linux-media/msg144214.html>

-- 
Kind regards,

Sakari Ailus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform
  2019-01-07 11:58   ` Sakari Ailus
@ 2019-01-08  9:17     ` Luis de Oliveira
  0 siblings, 0 replies; 26+ messages in thread
From: Luis de Oliveira @ 2019-01-08  9:17 UTC (permalink / raw)
  To: Sakari Ailus, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Hans Verkuil, Laurent Pinchart,
	Arnd Bergmann, Geert Uytterhoeven, Neil Armstrong, Philipp Zabel,
	Keiichi Watanabe, Kate Stewart, Todor Tomov

Hi Sakari,

On 07-Jan-19 11:58, Sakari Ailus wrote:
> Hi Luis,
> 
> On Fri, Oct 19, 2018 at 02:52:24PM +0200, Luis Oliveira wrote:
>> Add of Synopsys MIPI D-PHY in RX mode support.
>> Separated in the implementation are platform dependent probing functions.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> 
> Maxime has a patchset adding D-PHY parameters to the PHY API. I think they
> could be relevant for this one as well:
> 

Maxime was kind to send me the patchset for me to use.
I was on a different project for the last weeks but I will get back to this and
prepare a V4 with the new PHY API parameters asap.

Thank you,
Luis

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
  2018-11-14 20:22   ` Laurent Pinchart
  2018-12-10 12:39   ` Eugen.Hristev
@ 2019-01-09 13:07   ` Eugen.Hristev
  2019-01-10 16:18     ` Luis de Oliveira
  2 siblings, 1 reply; 26+ messages in thread
From: Eugen.Hristev @ 2019-01-09 13:07 UTC (permalink / raw)
  To: luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 19.10.2018 15:52, Luis Oliveira wrote:
> Add the Synopsys MIPI CSI-2 controller driver. This
> controller driver is divided in platform dependent functions
> and core functions. It also includes a platform for future
> DesignWare drivers.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - exposed IPI settings to userspace
> - fixed headers
> 
>   MAINTAINERS                              |  11 +
>   drivers/media/platform/dwc/Kconfig       |  30 +-
>   drivers/media/platform/dwc/Makefile      |   2 +
>   drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
>   drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>   drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>   drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>   include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>   8 files changed, 1616 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>   create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>   create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>   create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>   create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
> 

[snip]

> +/* Video formats supported by the MIPI CSI-2 */
> +const struct mipi_fmt dw_mipi_csi_formats[] = {
> +	{
> +		/* RAW 8 */
> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.depth = 8,
> +	},
> +	{
> +		/* RAW 10 */
> +		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
> +		.depth = 10,
> +	},

Hi Luis,

Any reason why RAW12 format is not handled here ?

Here, namely MEDIA_BUS_FMT_SBGGR12_1X12 etc.

> +	{
> +		/* RGB 565 */
> +		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
> +		.depth = 16,
> +	},
> +	{
> +		/* BGR 565 */
> +		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
> +		.depth = 16,
> +	},
> +	{
> +		/* RGB 888 */
> +		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
> +		.depth = 24,
> +	},
> +	{
> +		/* BGR 888 */
> +		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
> +		.depth = 24,
> +	},
> +};

[snip]

> +
> +void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
> +{
> +	struct device *dev = csi_dev->dev;
> +
> +	if (csi_dev->ipi_dt)
> +		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
> +	else {
> +		switch (csi_dev->fmt->code) {
> +		case MEDIA_BUS_FMT_RGB565_2X8_BE:
> +		case MEDIA_BUS_FMT_RGB565_2X8_LE:
> +			dw_mipi_csi_write(csi_dev,
> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
> +			dev_dbg(dev, "DT: RGB 565");
> +			break;
> +
> +		case MEDIA_BUS_FMT_RGB888_2X12_LE:
> +		case MEDIA_BUS_FMT_RGB888_2X12_BE:
> +			dw_mipi_csi_write(csi_dev,
> +					reg.IPI_DATA_TYPE, CSI_2_RGB888);
> +			dev_dbg(dev, "DT: RGB 888");
> +			break;
> +		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
> +			dw_mipi_csi_write(csi_dev,
> +					reg.IPI_DATA_TYPE, CSI_2_RAW10);
> +			dev_dbg(dev, "DT: RAW 10");
> +			break;
> +		case MEDIA_BUS_FMT_SBGGR8_1X8:
> +			dw_mipi_csi_write(csi_dev,
> +					reg.IPI_DATA_TYPE, CSI_2_RAW8);
> +			dev_dbg(dev, "DT: RAW 8");
> +			break;

Same here, in CSI_2_RAW12 case it will default to a RGB565 case.

Thanks,

Eugen



> +		default:
> +			dw_mipi_csi_write(csi_dev,
> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
> +			dev_dbg(dev, "Error");
> +			break;
> +		}
> +	}
> +}
> +

[snip]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-12-10 12:39   ` Eugen.Hristev
@ 2019-01-10 16:11     ` Luis de Oliveira
  0 siblings, 0 replies; 26+ messages in thread
From: Luis de Oliveira @ 2019-01-10 16:11 UTC (permalink / raw)
  To: Eugen.Hristev, luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 10-Dec-18 12:39, Eugen.Hristev@microchip.com wrote:
> 
> 
> On 19.10.2018 15:52, Luis Oliveira wrote:
>> Add the Synopsys MIPI CSI-2 controller driver. This
>> controller driver is divided in platform dependent functions
>> and core functions. It also includes a platform for future
>> DesignWare drivers.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - exposed IPI settings to userspace
>> - fixed headers
> [...]
> 
> snip
> 
> 
>> +
>> +static int
>> +dw_mipi_csi_parse_dt(struct platform_device *pdev, struct mipi_csi_dev *dev)
>> +{
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct v4l2_fwnode_endpoint endpoint;
> 
> Hello Luis,
> 
> I believe you have to initialize "endpoint" here correctly, otherwise 
> the parsing mechanism (fwnode_endpoint_parse) will consider you have a 
> specific mbus type and fail to probe the endpoint: bail out with debug 
> message "expecting bus type not found "
> 
> (namely, initialize to zero which is the UNKNOWN mbus type, or , to a 
> specific mbus (from DT or whatever source))
> 
> Eugen
> 
Hi Eugen,

Sorry for my late reply, I was on Christmas break.
You are right, I will add that fix.

> 
>> +	int ret;
>> +
>> +	node = of_graph_get_next_endpoint(node, NULL);
>> +	if (!node) {
>> +		dev_err(&pdev->dev, "No port node at %s\n",
>> +				pdev->dev.of_node->full_name);
>> +		return -EINVAL;
>> +	}
>> +
>> +	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
>> +	if (ret)
>> +		goto err;
>> +
>> +	dev->index = endpoint.base.port - 1;
>> +	if (dev->index >= CSI_MAX_ENTITIES) {
>> +		ret = -ENXIO;
>> +		goto err;
>> +	}
>> +	dev->hw.num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
>> +
>> +err:
>> +	of_node_put(node);
>> +	return ret;
>> +}
>> +
> 
> snip
> 
Thank you.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2019-01-09 13:07   ` Eugen.Hristev
@ 2019-01-10 16:18     ` Luis de Oliveira
  2019-01-11  7:25       ` Eugen.Hristev
  0 siblings, 1 reply; 26+ messages in thread
From: Luis de Oliveira @ 2019-01-10 16:18 UTC (permalink / raw)
  To: Eugen.Hristev, luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 09-Jan-19 13:07, Eugen.Hristev@microchip.com wrote:
> 
> 
> On 19.10.2018 15:52, Luis Oliveira wrote:
>> Add the Synopsys MIPI CSI-2 controller driver. This
>> controller driver is divided in platform dependent functions
>> and core functions. It also includes a platform for future
>> DesignWare drivers.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - exposed IPI settings to userspace
>> - fixed headers
>>
>>   MAINTAINERS                              |  11 +
>>   drivers/media/platform/dwc/Kconfig       |  30 +-
>>   drivers/media/platform/dwc/Makefile      |   2 +
>>   drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
>>   drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>>   drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>>   drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>>   include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>>   8 files changed, 1616 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>>   create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>>   create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>>   create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>>   create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
>>
> 
> [snip]
> 
>> +/* Video formats supported by the MIPI CSI-2 */
>> +const struct mipi_fmt dw_mipi_csi_formats[] = {
>> +	{
>> +		/* RAW 8 */
>> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
>> +		.depth = 8,
>> +	},
>> +	{
>> +		/* RAW 10 */
>> +		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
>> +		.depth = 10,
>> +	},
> 
> Hi Luis,
> 
> Any reason why RAW12 format is not handled here ?
> 
> Here, namely MEDIA_BUS_FMT_SBGGR12_1X12 etc.
> 
Hi Eugen,

My Hw testing setup currently does not support it, so I didn't add it.

>> +	{
>> +		/* RGB 565 */
>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
>> +		.depth = 16,
>> +	},
>> +	{
>> +		/* BGR 565 */
>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
>> +		.depth = 16,
>> +	},
>> +	{
>> +		/* RGB 888 */
>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
>> +		.depth = 24,
>> +	},
>> +	{
>> +		/* BGR 888 */
>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
>> +		.depth = 24,
>> +	},
>> +};
> 
> [snip]
> 
>> +
>> +void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
>> +{
>> +	struct device *dev = csi_dev->dev;
>> +
>> +	if (csi_dev->ipi_dt)
>> +		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
>> +	else {
>> +		switch (csi_dev->fmt->code) {
>> +		case MEDIA_BUS_FMT_RGB565_2X8_BE:
>> +		case MEDIA_BUS_FMT_RGB565_2X8_LE:
>> +			dw_mipi_csi_write(csi_dev,
>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>> +			dev_dbg(dev, "DT: RGB 565");
>> +			break;
>> +
>> +		case MEDIA_BUS_FMT_RGB888_2X12_LE:
>> +		case MEDIA_BUS_FMT_RGB888_2X12_BE:
>> +			dw_mipi_csi_write(csi_dev,
>> +					reg.IPI_DATA_TYPE, CSI_2_RGB888);
>> +			dev_dbg(dev, "DT: RGB 888");
>> +			break;
>> +		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
>> +			dw_mipi_csi_write(csi_dev,
>> +					reg.IPI_DATA_TYPE, CSI_2_RAW10);
>> +			dev_dbg(dev, "DT: RAW 10");
>> +			break;
>> +		case MEDIA_BUS_FMT_SBGGR8_1X8:
>> +			dw_mipi_csi_write(csi_dev,
>> +					reg.IPI_DATA_TYPE, CSI_2_RAW8);
>> +			dev_dbg(dev, "DT: RAW 8");
>> +			break;
> 
> Same here, in CSI_2_RAW12 case it will default to a RGB565 case.
> 
> Thanks,
> 
> Eugen
> 
> 
I will try to add the support for this data type in my next patchset if not I
will flag it as unsupported for now in the commit message and code.

Thanks for your review,
Luis

> 
>> +		default:
>> +			dw_mipi_csi_write(csi_dev,
>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>> +			dev_dbg(dev, "Error");
>> +			break;
>> +		}
>> +	}
>> +}
>> +
> 
> [snip]
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2018-11-14 20:22   ` Laurent Pinchart
@ 2019-01-10 17:00     ` Luis de Oliveira
  0 siblings, 0 replies; 26+ messages in thread
From: Luis de Oliveira @ 2019-01-10 17:00 UTC (permalink / raw)
  To: Laurent Pinchart, Luis Oliveira
  Cc: linux-media, linux-kernel, joao.pinto, festevam,
	Mauro Carvalho Chehab, Greg Kroah-Hartman, David S. Miller,
	Andrew Morton, Arnd Bergmann, Hans Verkuil, Geert Uytterhoeven,
	Neil Armstrong, Philipp Zabel, Thierry Reding, Maxime Ripard,
	Todor Tomov

Hi Laurent,

Sorry for taking so long to answer. I was stuck in other projects and lost track
of this.

My answers inline,

On 14-Nov-18 20:22, Laurent Pinchart wrote:
> Hi Luis,
> 
> Thank you for the patch.
> 
> On Friday, 19 October 2018 15:52:26 EET Luis Oliveira wrote:
>> Add the Synopsys MIPI CSI-2 controller driver. This
>> controller driver is divided in platform dependent functions
>> and core functions. It also includes a platform for future
>> DesignWare drivers.
>>
>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>> ---
>> Changelog
>> v2-V3
>> - exposed IPI settings to userspace
> 
> Could you please explain why you need this and can't use standard APIs ? 
> Custom sysfs attributes are needed, they need to be documented in 
> Documentation/ABI/.
> 

IPI - Image Pixel Interface enables to access direct video stream in our CSI-2
Host IP and needs to be configured to match the video source. I can't hard code
it. But maybe I can think of a way to configure it using the video configuration.
I will try do that in the next patchset.

>> - fixed headers
>>
>>  MAINTAINERS                              |  11 +
>>  drivers/media/platform/dwc/Kconfig       |  30 +-
>>  drivers/media/platform/dwc/Makefile      |   2 +
>>  drivers/media/platform/dwc/dw-csi-plat.c | 699 ++++++++++++++++++++++++++++
>>  drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>>  drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>>  drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>>  include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>>  8 files changed, 1616 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>>  create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>>  create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>>  create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>>  create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index da2e509..fd5f1fc 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -14032,6 +14032,16 @@ S:	Maintained
>>  F:	drivers/dma/dwi-axi-dmac/
>>  F:	Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.txt
>>
>> +SYNOPSYS DESIGNWARE MIPI CSI-2 HOST VIDEO PLATFORM
>> +M:	Luis Oliveira <luis.oliveira@synopsys.com>
>> +L:	linux-media@vger.kernel.org
>> +T:	git git://linuxtv.org/media_tree.git
>> +S:	Maintained
>> +F:	drivers/media/platform/dwc
>> +F:	include/media/dwc/dw-mipi-csi-pltfrm.h
>> +F:	Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
>> +F:	Documentation/devicetree/bindings/phy/snps,dphy-rx.txt
> 
> These two lines belong to patches 1/4 and 3/4. Doesn't checkpatch.pl warn 
> about this ? Now that I mentioned checkpatch.pl, I tried running it on this 
> series, and it generates a fair number of warnings and errors. Could you 
> please fix them ?
> 

I did, but maybe - or probably - i did not fix them all. Sorry.
I am preparing a new patchset and I will make sure everything goes right this time.

>> +
>>  SYNOPSYS DESIGNWARE DMAC DRIVER
>>  M:	Viresh Kumar <vireshk@kernel.org>
>>  R:	Andy Shevchenko <andriy.shevchenko@linux.intel.com>
>> @@ -16217,3 +16227,4 @@ T:	git
>> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git S:	Buried
>> alive in reporters
>>  F:	*
>>  F:	*/
>> +
> 
> Stray new line.
> 
Noted.

> [snip]
> 
Thank you,
Luis

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2019-01-10 16:18     ` Luis de Oliveira
@ 2019-01-11  7:25       ` Eugen.Hristev
  2019-01-11  8:11         ` Luis de Oliveira
  0 siblings, 1 reply; 26+ messages in thread
From: Eugen.Hristev @ 2019-01-11  7:25 UTC (permalink / raw)
  To: luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 10.01.2019 18:18, Luis de Oliveira wrote:
> 
> 
> On 09-Jan-19 13:07, Eugen.Hristev@microchip.com wrote:
>>
>>
>> On 19.10.2018 15:52, Luis Oliveira wrote:
>>> Add the Synopsys MIPI CSI-2 controller driver. This
>>> controller driver is divided in platform dependent functions
>>> and core functions. It also includes a platform for future
>>> DesignWare drivers.
>>>
>>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>>> ---
>>> Changelog
>>> v2-V3
>>> - exposed IPI settings to userspace
>>> - fixed headers
>>>
>>>    MAINTAINERS                              |  11 +
>>>    drivers/media/platform/dwc/Kconfig       |  30 +-
>>>    drivers/media/platform/dwc/Makefile      |   2 +
>>>    drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
>>>    drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>>>    drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>>>    drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>>>    include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>>>    8 files changed, 1616 insertions(+), 1 deletion(-)
>>>    create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>>>    create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>>>    create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>>>    create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>>>    create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
>>>
>>
>> [snip]
>>
>>> +/* Video formats supported by the MIPI CSI-2 */
>>> +const struct mipi_fmt dw_mipi_csi_formats[] = {
>>> +	{
>>> +		/* RAW 8 */
>>> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
>>> +		.depth = 8,
>>> +	},
>>> +	{
>>> +		/* RAW 10 */
>>> +		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
>>> +		.depth = 10,
>>> +	},
>>
>> Hi Luis,
>>
>> Any reason why RAW12 format is not handled here ?
>>
>> Here, namely MEDIA_BUS_FMT_SBGGR12_1X12 etc.
>>
> Hi Eugen,
> 
> My Hw testing setup currently does not support it, so I didn't add it.
> 
>>> +	{
>>> +		/* RGB 565 */
>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
>>> +		.depth = 16,
>>> +	},
>>> +	{
>>> +		/* BGR 565 */
>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
>>> +		.depth = 16,
>>> +	},
>>> +	{
>>> +		/* RGB 888 */
>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
>>> +		.depth = 24,
>>> +	},
>>> +	{
>>> +		/* BGR 888 */
>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
>>> +		.depth = 24,
>>> +	},
>>> +};
>>
>> [snip]
>>
>>> +
>>> +void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
>>> +{
>>> +	struct device *dev = csi_dev->dev;
>>> +
>>> +	if (csi_dev->ipi_dt)
>>> +		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
>>> +	else {
>>> +		switch (csi_dev->fmt->code) {
>>> +		case MEDIA_BUS_FMT_RGB565_2X8_BE:
>>> +		case MEDIA_BUS_FMT_RGB565_2X8_LE:
>>> +			dw_mipi_csi_write(csi_dev,
>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>> +			dev_dbg(dev, "DT: RGB 565");
>>> +			break;
>>> +
>>> +		case MEDIA_BUS_FMT_RGB888_2X12_LE:
>>> +		case MEDIA_BUS_FMT_RGB888_2X12_BE:
>>> +			dw_mipi_csi_write(csi_dev,
>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB888);
>>> +			dev_dbg(dev, "DT: RGB 888");
>>> +			break;
>>> +		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
>>> +			dw_mipi_csi_write(csi_dev,
>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW10);
>>> +			dev_dbg(dev, "DT: RAW 10");
>>> +			break;
>>> +		case MEDIA_BUS_FMT_SBGGR8_1X8:
>>> +			dw_mipi_csi_write(csi_dev,
>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW8);
>>> +			dev_dbg(dev, "DT: RAW 8");
>>> +			break;
>>
>> Same here, in CSI_2_RAW12 case it will default to a RGB565 case.
>>
>> Thanks,
>>
>> Eugen
>>
>>
> I will try to add the support for this data type in my next patchset if not I
> will flag it as unsupported for now in the commit message and code.

Hi Luis,

I am currently trying to see if your driver works , and I need the RAW12 
type, that's why I am asking about it.

One question related to the subdevice you create here, how do you 
register this subdev into the media subsystem ? sync or async, or not at 
all ?
After the driver probes, there is no call to the set format functions, I 
added a node inside the Device tree, I see you are registering media 
pads, but the other endpoint needs to be an async waiting for completion 
node or your subdev registers in some other way ? (maybe some link 
validation required ?)

Thanks for your help,

Eugen

> 
> Thanks for your review,
> Luis
> 
>>
>>> +		default:
>>> +			dw_mipi_csi_write(csi_dev,
>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>> +			dev_dbg(dev, "Error");
>>> +			break;
>>> +		}
>>> +	}
>>> +}
>>> +
>>
>> [snip]
>>
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2019-01-11  7:25       ` Eugen.Hristev
@ 2019-01-11  8:11         ` Luis de Oliveira
  2019-01-11  9:49           ` Eugen.Hristev
  0 siblings, 1 reply; 26+ messages in thread
From: Luis de Oliveira @ 2019-01-11  8:11 UTC (permalink / raw)
  To: Eugen.Hristev, luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 11-Jan-19 7:25, Eugen.Hristev@microchip.com wrote:
> 
> 
> On 10.01.2019 18:18, Luis de Oliveira wrote:
>>
>>
>> On 09-Jan-19 13:07, Eugen.Hristev@microchip.com wrote:
>>>
>>>
>>> On 19.10.2018 15:52, Luis Oliveira wrote:
>>>> Add the Synopsys MIPI CSI-2 controller driver. This
>>>> controller driver is divided in platform dependent functions
>>>> and core functions. It also includes a platform for future
>>>> DesignWare drivers.
>>>>
>>>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>>>> ---
>>>> Changelog
>>>> v2-V3
>>>> - exposed IPI settings to userspace
>>>> - fixed headers
>>>>
>>>>    MAINTAINERS                              |  11 +
>>>>    drivers/media/platform/dwc/Kconfig       |  30 +-
>>>>    drivers/media/platform/dwc/Makefile      |   2 +
>>>>    drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
>>>>    drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>>>>    drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>>>>    drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>>>>    include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>>>>    8 files changed, 1616 insertions(+), 1 deletion(-)
>>>>    create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>>>>    create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>>>>    create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>>>>    create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>>>>    create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
>>>>
>>>
>>> [snip]
>>>
>>>> +/* Video formats supported by the MIPI CSI-2 */
>>>> +const struct mipi_fmt dw_mipi_csi_formats[] = {
>>>> +	{
>>>> +		/* RAW 8 */
>>>> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
>>>> +		.depth = 8,
>>>> +	},
>>>> +	{
>>>> +		/* RAW 10 */
>>>> +		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
>>>> +		.depth = 10,
>>>> +	},
>>>
>>> Hi Luis,
>>>
>>> Any reason why RAW12 format is not handled here ?
>>>
>>> Here, namely MEDIA_BUS_FMT_SBGGR12_1X12 etc.
>>>
>> Hi Eugen,
>>
>> My Hw testing setup currently does not support it, so I didn't add it.
>>
>>>> +	{
>>>> +		/* RGB 565 */
>>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
>>>> +		.depth = 16,
>>>> +	},
>>>> +	{
>>>> +		/* BGR 565 */
>>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
>>>> +		.depth = 16,
>>>> +	},
>>>> +	{
>>>> +		/* RGB 888 */
>>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
>>>> +		.depth = 24,
>>>> +	},
>>>> +	{
>>>> +		/* BGR 888 */
>>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
>>>> +		.depth = 24,
>>>> +	},
>>>> +};
>>>
>>> [snip]
>>>
>>>> +
>>>> +void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
>>>> +{
>>>> +	struct device *dev = csi_dev->dev;
>>>> +
>>>> +	if (csi_dev->ipi_dt)
>>>> +		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
>>>> +	else {
>>>> +		switch (csi_dev->fmt->code) {
>>>> +		case MEDIA_BUS_FMT_RGB565_2X8_BE:
>>>> +		case MEDIA_BUS_FMT_RGB565_2X8_LE:
>>>> +			dw_mipi_csi_write(csi_dev,
>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>>> +			dev_dbg(dev, "DT: RGB 565");
>>>> +			break;
>>>> +
>>>> +		case MEDIA_BUS_FMT_RGB888_2X12_LE:
>>>> +		case MEDIA_BUS_FMT_RGB888_2X12_BE:
>>>> +			dw_mipi_csi_write(csi_dev,
>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB888);
>>>> +			dev_dbg(dev, "DT: RGB 888");
>>>> +			break;
>>>> +		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
>>>> +			dw_mipi_csi_write(csi_dev,
>>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW10);
>>>> +			dev_dbg(dev, "DT: RAW 10");
>>>> +			break;
>>>> +		case MEDIA_BUS_FMT_SBGGR8_1X8:
>>>> +			dw_mipi_csi_write(csi_dev,
>>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW8);
>>>> +			dev_dbg(dev, "DT: RAW 8");
>>>> +			break;
>>>
>>> Same here, in CSI_2_RAW12 case it will default to a RGB565 case.
>>>
>>> Thanks,
>>>
>>> Eugen
>>>
>>>
>> I will try to add the support for this data type in my next patchset if not I
>> will flag it as unsupported for now in the commit message and code.
> 
> Hi Luis,
> 
> I am currently trying to see if your driver works , and I need the RAW12 
> type, that's why I am asking about it.
> 
> One question related to the subdevice you create here, how do you 
> register this subdev into the media subsystem ? sync or async, or not at 
> all ?
> After the driver probes, there is no call to the set format functions, I 
> added a node inside the Device tree, I see you are registering media 
> pads, but the other endpoint needs to be an async waiting for completion 
> node or your subdev registers in some other way ? (maybe some link 
> validation required ?)
> 
> Thanks for your help,
> 
> Eugen
> 
Hi Eugen,

On top of this dphy+controller solution I use a wrapper driver that binds this
two together and create the links.
I use V4L2_ASYNC_MATCH_FWNODE and v4l2_async_notifier_operations to match and
bound all my sensors until completion.

My dt looks like this:

camera wrapper {
 	
	video_dev {
		dma
	}
	vif_1 @reg {
		...
	}
	..
	vif_n @reg {
		...
	}
	csi_1 @reg {
		...
		phy
		port 1..2 {}
	}
	csi_n @reg {
		...
		phy
		port 1..2 {}
	}

Fundamentally It is the same principle as this
drivers/media/platform/exynos4-is/media-dev.c but my solution has more entities
for testing purposes.
Check the exynos4-is because is very similar to my top solution.

When I started doing this patchset I was thinking of sending the wrapper also
but I then decided to not do it because it is very narrow and focused in my
tests. But I can include it in v4 if everyone think its best.

Thank you,
Luis
>>
>> Thanks for your review,
>> Luis
>>
>>>
>>>> +		default:
>>>> +			dw_mipi_csi_write(csi_dev,
>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>>> +			dev_dbg(dev, "Error");
>>>> +			break;
>>>> +		}
>>>> +	}
>>>> +}
>>>> +
>>>
>>> [snip]
>>>
>>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver
  2019-01-11  8:11         ` Luis de Oliveira
@ 2019-01-11  9:49           ` Eugen.Hristev
  0 siblings, 0 replies; 26+ messages in thread
From: Eugen.Hristev @ 2019-01-11  9:49 UTC (permalink / raw)
  To: luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, gregkh, davem, akpm, arnd,
	hans.verkuil, laurent.pinchart, geert, narmstrong, p.zabel,
	treding, maxime.ripard, todor.tomov



On 11.01.2019 10:11, Luis de Oliveira wrote:
> 
> 
> On 11-Jan-19 7:25, Eugen.Hristev@microchip.com wrote:
>>
>>
>> On 10.01.2019 18:18, Luis de Oliveira wrote:
>>>
>>>
>>> On 09-Jan-19 13:07, Eugen.Hristev@microchip.com wrote:
>>>>
>>>>
>>>> On 19.10.2018 15:52, Luis Oliveira wrote:
>>>>> Add the Synopsys MIPI CSI-2 controller driver. This
>>>>> controller driver is divided in platform dependent functions
>>>>> and core functions. It also includes a platform for future
>>>>> DesignWare drivers.
>>>>>
>>>>> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
>>>>> ---
>>>>> Changelog
>>>>> v2-V3
>>>>> - exposed IPI settings to userspace
>>>>> - fixed headers
>>>>>
>>>>>     MAINTAINERS                              |  11 +
>>>>>     drivers/media/platform/dwc/Kconfig       |  30 +-
>>>>>     drivers/media/platform/dwc/Makefile      |   2 +
>>>>>     drivers/media/platform/dwc/dw-csi-plat.c | 699 +++++++++++++++++++++++++++++++
>>>>>     drivers/media/platform/dwc/dw-csi-plat.h |  77 ++++
>>>>>     drivers/media/platform/dwc/dw-mipi-csi.c | 494 ++++++++++++++++++++++
>>>>>     drivers/media/platform/dwc/dw-mipi-csi.h | 202 +++++++++
>>>>>     include/media/dwc/dw-mipi-csi-pltfrm.h   | 102 +++++
>>>>>     8 files changed, 1616 insertions(+), 1 deletion(-)
>>>>>     create mode 100644 drivers/media/platform/dwc/dw-csi-plat.c
>>>>>     create mode 100644 drivers/media/platform/dwc/dw-csi-plat.h
>>>>>     create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.c
>>>>>     create mode 100644 drivers/media/platform/dwc/dw-mipi-csi.h
>>>>>     create mode 100644 include/media/dwc/dw-mipi-csi-pltfrm.h
>>>>>
>>>>
>>>> [snip]
>>>>
>>>>> +/* Video formats supported by the MIPI CSI-2 */
>>>>> +const struct mipi_fmt dw_mipi_csi_formats[] = {
>>>>> +	{
>>>>> +		/* RAW 8 */
>>>>> +		.code = MEDIA_BUS_FMT_SBGGR8_1X8,
>>>>> +		.depth = 8,
>>>>> +	},
>>>>> +	{
>>>>> +		/* RAW 10 */
>>>>> +		.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
>>>>> +		.depth = 10,
>>>>> +	},
>>>>
>>>> Hi Luis,
>>>>
>>>> Any reason why RAW12 format is not handled here ?
>>>>
>>>> Here, namely MEDIA_BUS_FMT_SBGGR12_1X12 etc.
>>>>
>>> Hi Eugen,
>>>
>>> My Hw testing setup currently does not support it, so I didn't add it.
>>>
>>>>> +	{
>>>>> +		/* RGB 565 */
>>>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
>>>>> +		.depth = 16,
>>>>> +	},
>>>>> +	{
>>>>> +		/* BGR 565 */
>>>>> +		.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
>>>>> +		.depth = 16,
>>>>> +	},
>>>>> +	{
>>>>> +		/* RGB 888 */
>>>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
>>>>> +		.depth = 24,
>>>>> +	},
>>>>> +	{
>>>>> +		/* BGR 888 */
>>>>> +		.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
>>>>> +		.depth = 24,
>>>>> +	},
>>>>> +};
>>>>
>>>> [snip]
>>>>
>>>>> +
>>>>> +void dw_mipi_csi_set_ipi_fmt(struct mipi_csi_dev *csi_dev)
>>>>> +{
>>>>> +	struct device *dev = csi_dev->dev;
>>>>> +
>>>>> +	if (csi_dev->ipi_dt)
>>>>> +		dw_mipi_csi_write(csi_dev, reg.IPI_DATA_TYPE, csi_dev->ipi_dt);
>>>>> +	else {
>>>>> +		switch (csi_dev->fmt->code) {
>>>>> +		case MEDIA_BUS_FMT_RGB565_2X8_BE:
>>>>> +		case MEDIA_BUS_FMT_RGB565_2X8_LE:
>>>>> +			dw_mipi_csi_write(csi_dev,
>>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>>>> +			dev_dbg(dev, "DT: RGB 565");
>>>>> +			break;
>>>>> +
>>>>> +		case MEDIA_BUS_FMT_RGB888_2X12_LE:
>>>>> +		case MEDIA_BUS_FMT_RGB888_2X12_BE:
>>>>> +			dw_mipi_csi_write(csi_dev,
>>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB888);
>>>>> +			dev_dbg(dev, "DT: RGB 888");
>>>>> +			break;
>>>>> +		case MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE:
>>>>> +			dw_mipi_csi_write(csi_dev,
>>>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW10);
>>>>> +			dev_dbg(dev, "DT: RAW 10");
>>>>> +			break;
>>>>> +		case MEDIA_BUS_FMT_SBGGR8_1X8:
>>>>> +			dw_mipi_csi_write(csi_dev,
>>>>> +					reg.IPI_DATA_TYPE, CSI_2_RAW8);
>>>>> +			dev_dbg(dev, "DT: RAW 8");
>>>>> +			break;
>>>>
>>>> Same here, in CSI_2_RAW12 case it will default to a RGB565 case.
>>>>
>>>> Thanks,
>>>>
>>>> Eugen
>>>>
>>>>
>>> I will try to add the support for this data type in my next patchset if not I
>>> will flag it as unsupported for now in the commit message and code.
>>
>> Hi Luis,
>>
>> I am currently trying to see if your driver works , and I need the RAW12
>> type, that's why I am asking about it.
>>
>> One question related to the subdevice you create here, how do you
>> register this subdev into the media subsystem ? sync or async, or not at
>> all ?
>> After the driver probes, there is no call to the set format functions, I
>> added a node inside the Device tree, I see you are registering media
>> pads, but the other endpoint needs to be an async waiting for completion
>> node or your subdev registers in some other way ? (maybe some link
>> validation required ?)
>>
>> Thanks for your help,
>>
>> Eugen
>>
> Hi Eugen,
> 
> On top of this dphy+controller solution I use a wrapper driver that binds this
> two together and create the links.
> I use V4L2_ASYNC_MATCH_FWNODE and v4l2_async_notifier_operations to match and
> bound all my sensors until completion.
> 
> My dt looks like this:
> 
> camera wrapper {
>   	
> 	video_dev {
> 		dma
> 	}
> 	vif_1 @reg {
> 		...
> 	}
> 	..
> 	vif_n @reg {
> 		...
> 	}
> 	csi_1 @reg {
> 		...
> 		phy
> 		port 1..2 {}
> 	}
> 	csi_n @reg {
> 		...
> 		phy
> 		port 1..2 {}
> 	}
> 
> Fundamentally It is the same principle as this
> drivers/media/platform/exynos4-is/media-dev.c but my solution has more entities
> for testing purposes.
> Check the exynos4-is because is very similar to my top solution.
> 
> When I started doing this patchset I was thinking of sending the wrapper also
> but I then decided to not do it because it is very narrow and focused in my
> tests. But I can include it in v4 if everyone think its best.

Ok, I understand how you did, but do you have a public tree with this 
code which I can access to have a look on exactly how you connected 
everything ?

Thanks


> 
> Thank you,
> Luis
>>>
>>> Thanks for your review,
>>> Luis
>>>
>>>>
>>>>> +		default:
>>>>> +			dw_mipi_csi_write(csi_dev,
>>>>> +					reg.IPI_DATA_TYPE, CSI_2_RGB565);
>>>>> +			dev_dbg(dev, "Error");
>>>>> +			break;
>>>>> +		}
>>>>> +	}
>>>>> +}
>>>>> +
>>>>
>>>> [snip]
>>>>
>>>
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
  2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
  2018-10-24 17:40   ` Rob Herring
  2018-10-24 17:41   ` Rob Herring
@ 2019-01-11 15:29   ` Eugen.Hristev
  2 siblings, 0 replies; 26+ messages in thread
From: Eugen.Hristev @ 2019-01-11 15:29 UTC (permalink / raw)
  To: luis.oliveira, linux-media, linux-kernel
  Cc: joao.pinto, festevam, mchehab, robh+dt, mark.rutland,
	hans.verkuil, laurent.pinchart+renesas, arnd, geert+renesas,
	narmstrong, p.zabel, keiichiw, kstewart, todor.tomov, devicetree



On 19.10.2018 15:52, Luis Oliveira wrote:
> Add bindings for Synopsys DesignWare MIPI CSI-2 host.
> 
> Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> ---
> Changelog
> v2-V3
> - removed IPI settings
> 
>   .../devicetree/bindings/media/snps,dw-csi-plat.txt | 52 ++++++++++++++++++++++
>   1 file changed, 52 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> 
> diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> new file mode 100644
> index 0000000..be3da05
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/snps,dw-csi-plat.txt
> @@ -0,0 +1,52 @@
> +Synopsys DesignWare CSI-2 Host controller
> +
> +Description
> +-----------
> +
> +This HW block is used to receive image coming from an MIPI CSI-2 compatible
> +camera.
> +
> +Required properties:
> +- compatible: shall be "snps,dw-csi-plat"
> +- reg			: physical base address and size of the device memory mapped
> +  registers;
> +- interrupts		: CSI-2 Host interrupt
> +- snps,output-type	: Core output to be used (IPI-> 0 or IDI->1 or BOTH->2)
> +			  These  values choose which of the Core outputs will be used,
> +			  it can be Image Data Interface or Image Pixel Interface.
> +- phys			: List of one PHY specifier (as defined in
> +			  Documentation/devicetree/bindings/phy/phy-bindings.txt).
> +			  This PHY is a MIPI DPHY working in RX mode.
> +- resets		: Reference to a reset controller (optional)
> +
> +The per-board settings:
> + - port sub-node describing a single endpoint connected to the camera as
> +   described in video-interfaces.txt[1].
> +
> +Example:
> +
> +	csi2_1: csi2@3000 {
> +		compatible = "snps,dw-csi-plat";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		reg = < 0x03000 0x7FF>;
> +		interrupts = <2>;
> +		output-type = <2>;
> +		resets = <&dw_rst 1>;
> +		phys = <&mipi_dphy_rx1 0>;
> +		phy-names = "csi2-dphy";
> +
> +		/* CSI-2 per-board settings */
> +		port@1 {
> +			reg = <1>;
> +			csi1_ep1: endpoint {
> +				remote-endpoint = <&camera_1>;
> +				data-lanes = <1 2>;
> +			};
> +		};
> +		port@2 {
> +			csi1_ep2: endpoint {
> +				remote-endpoint = <&vif1_ep>;

Hi again Luis,

Regarding the output endpoint, in your example port@2, if we use the 
property snps,output-type=2 for example, so IDI output, which bus-type 
you have in mind for this link? IDI is not documented in the 
video-interfaces.txt binding.

Since the MIPI CSI-2 DPHY is actually between camera sensor and 
csi2host, after this we can use either IDI or IPI if my understanding is 
correct, and connect to a different pad/hw block which can further 
handle these packets/pixels.

I am interested on how to specify the connection type between this 
output pad and the next one (until a /dev/video can be registered by the 
last driver for the last hw block).

Thanks,

Eugen

> +			};
> +		};
> +	};
> --
> 2.7.4
> 
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, back to index

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-19 12:52 [V3, 0/4] platform: dwc: Add of DesignWare MIPI CSI-2 Host Luis Oliveira
2018-10-19 12:52 ` [V3, 1/4] Documentation: dt-bindings: phy: Document the Synopsys MIPI DPHY Rx bindings Luis Oliveira
2018-10-24 17:36   ` Rob Herring
2018-11-13  8:58     ` Luis Oliveira
2018-11-13  9:30     ` Luis de Oliveira
2018-11-14 20:08   ` Laurent Pinchart
2018-10-19 12:52 ` [V3, 2/4] media: platform: dwc: Add DW MIPI DPHY Rx platform Luis Oliveira
2019-01-07 11:58   ` Sakari Ailus
2019-01-08  9:17     ` Luis de Oliveira
2018-10-19 12:52 ` [V3, 3/4] Documentation: dt-bindings: media: Document bindings for DW MIPI CSI-2 Host Luis Oliveira
2018-10-24 17:40   ` Rob Herring
2018-11-13 10:00     ` Luis de Oliveira
2018-11-14 20:16       ` Laurent Pinchart
2018-10-24 17:41   ` Rob Herring
2018-11-13 10:00     ` Luis de Oliveira
2019-01-11 15:29   ` Eugen.Hristev
2018-10-19 12:52 ` [V3, 4/4] media: platform: dwc: Add MIPI CSI-2 controller driver Luis Oliveira
2018-11-14 20:22   ` Laurent Pinchart
2019-01-10 17:00     ` Luis de Oliveira
2018-12-10 12:39   ` Eugen.Hristev
2019-01-10 16:11     ` Luis de Oliveira
2019-01-09 13:07   ` Eugen.Hristev
2019-01-10 16:18     ` Luis de Oliveira
2019-01-11  7:25       ` Eugen.Hristev
2019-01-11  8:11         ` Luis de Oliveira
2019-01-11  9:49           ` Eugen.Hristev

LKML Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git
	git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git
	git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git
	git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git
	git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git
	git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git
	git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git
	git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \
		linux-kernel@vger.kernel.org linux-kernel@archiver.kernel.org
	public-inbox-index lkml


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox