All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-05-26 15:22 ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Hi,

This series adds support for CSI2 capture on J721E. It includes some
fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
driver, and finally adds the TI CSI2RX wrapper driver.

Tested on TI's J721E with OV5640 sensor.

Changes in v2:
- Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
  calls to set PHY mode, etc. to make sure it is ready.
- Add all 64 threads, instead of having only the one thread being
  currently used by the driver.
- Use dmaengine_get_dma_device() instead of directly accessing
  dma->device->dev.
- Do not set dst_addr_width when configuring slave DMA.
- Move to a separate subdir and rename to j721e-csi2rx.c
- Convert compatible to ti,j721e-csi2rx.
- Move to use Media Controller centric APIs.
- Improve cleanup in probe when one of the steps fails.
- Add colorspace to formats database.
- Set hw_revision on media_device.
- Move video device initialization to probe time instead of register time.
- Rename to ti,j721e-csi2rx.yaml
- Add an entry in MAINTAINERS.
- Add a description for the binding.
- Change compatible to ti,j721e-csi2rx to make it SoC specific.
- Remove description from dmas, reg, power-domains.
- Remove a limit of 2 from #address-cells and #size-cells.
- Fix add ^ to csi-bridge subnode regex.
- Make ranges mandatory.
- Add unit address in example.
- Add a reference to cdns,csi2rx in csi-bridge subnode.
- Expand the example to include the csi-bridge subnode as well.
- Re-order subject prefixes.
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy@... to phy@... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.
- Re-order subject prefixes.
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.
- Convert OV5640 to use runtime PM and drop Cadence CSI2RX s_power patch.
- Drop subdev call wrappers from cdns-csi2rx.
- Move VPE and CAL to a separate subdir.
- Rename ti-csi2rx.c to j721e-csi2rx.c

Paul Kocialkowski (1):
  phy: Distinguish between Rx and Tx for MIPI D-PHY with submodes

Pratyush Yadav (17):
  phy: cdns-dphy: Prepare for Rx support
  phy: cdns-dphy: Allow setting mode
  phy: cdns-dphy: Add Rx support
  media: ov5640: Use runtime PM to control sensor power
  media: cadence: csi2rx: Add external DPHY support
  media: cadence: csi2rx: Soft reset the streams before starting capture
  media: cadence: csi2rx: Set the STOP bit when stopping a stream
  media: cadence: csi2rx: Fix stream data configuration
  media: cadence: csi2rx: Populate subdev devnode
  dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
  media: Re-structure TI platform drivers
  media: ti: Add CSI2RX support for J721E
  media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
  media: dt-bindings: Convert Cadence CSI2RX binding to YAML
  phy: dt-bindings: Convert Cadence DPHY binding to YAML
  phy: dt-bindings: cdns,dphy: make clocks optional
  phy: dt-bindings: cdns,dphy: add power-domains property

 .../devicetree/bindings/media/cdns,csi2rx.txt | 100 --
 .../bindings/media/cdns,csi2rx.yaml           | 164 ++++
 .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++
 .../devicetree/bindings/phy/cdns,dphy.txt     |  20 -
 .../devicetree/bindings/phy/cdns,dphy.yaml    |  54 ++
 MAINTAINERS                                   |  10 +-
 drivers/dma/ti/k3-psil-j721e.c                |  73 ++
 drivers/media/i2c/Kconfig                     |   2 +-
 drivers/media/i2c/ov5640.c                    | 124 ++-
 drivers/media/platform/Kconfig                |  12 +
 drivers/media/platform/Makefile               |   2 +-
 drivers/media/platform/cadence/cdns-csi2rx.c  | 196 +++-
 drivers/media/platform/ti/Makefile            |   4 +
 drivers/media/platform/ti/cal/Makefile        |   3 +
 .../{ti-vpe => ti/cal}/cal-camerarx.c         |   0
 .../platform/{ti-vpe => ti/cal}/cal-video.c   |   0
 .../media/platform/{ti-vpe => ti/cal}/cal.c   |   0
 .../media/platform/{ti-vpe => ti/cal}/cal.h   |   0
 .../platform/{ti-vpe => ti/cal}/cal_regs.h    |   0
 .../media/platform/ti/j721e-csi2rx/Makefile   |   2 +
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 884 ++++++++++++++++++
 .../platform/{ti-vpe => ti/vpe}/Makefile      |   4 -
 .../media/platform/{ti-vpe => ti/vpe}/csc.c   |   0
 .../media/platform/{ti-vpe => ti/vpe}/csc.h   |   0
 .../media/platform/{ti-vpe => ti/vpe}/sc.c    |   0
 .../media/platform/{ti-vpe => ti/vpe}/sc.h    |   0
 .../platform/{ti-vpe => ti/vpe}/sc_coeff.h    |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpdma.c |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpdma.h |   0
 .../platform/{ti-vpe => ti/vpe}/vpdma_priv.h  |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpe.c   |   0
 .../platform/{ti-vpe => ti/vpe}/vpe_regs.h    |   0
 drivers/phy/cadence/cdns-dphy.c               | 407 +++++++-
 include/linux/phy/phy-mipi-dphy.h             |  13 +
 34 files changed, 1950 insertions(+), 225 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
 create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
 create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml
 create mode 100644 drivers/media/platform/ti/Makefile
 create mode 100644 drivers/media/platform/ti/cal/Makefile
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h (100%)
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/Makefile
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
 rename drivers/media/platform/{ti-vpe => ti/vpe}/Makefile (78%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h (100%)

-- 
2.30.0


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

* [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-05-26 15:22 ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Hi,

This series adds support for CSI2 capture on J721E. It includes some
fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
driver, and finally adds the TI CSI2RX wrapper driver.

Tested on TI's J721E with OV5640 sensor.

Changes in v2:
- Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
  calls to set PHY mode, etc. to make sure it is ready.
- Add all 64 threads, instead of having only the one thread being
  currently used by the driver.
- Use dmaengine_get_dma_device() instead of directly accessing
  dma->device->dev.
- Do not set dst_addr_width when configuring slave DMA.
- Move to a separate subdir and rename to j721e-csi2rx.c
- Convert compatible to ti,j721e-csi2rx.
- Move to use Media Controller centric APIs.
- Improve cleanup in probe when one of the steps fails.
- Add colorspace to formats database.
- Set hw_revision on media_device.
- Move video device initialization to probe time instead of register time.
- Rename to ti,j721e-csi2rx.yaml
- Add an entry in MAINTAINERS.
- Add a description for the binding.
- Change compatible to ti,j721e-csi2rx to make it SoC specific.
- Remove description from dmas, reg, power-domains.
- Remove a limit of 2 from #address-cells and #size-cells.
- Fix add ^ to csi-bridge subnode regex.
- Make ranges mandatory.
- Add unit address in example.
- Add a reference to cdns,csi2rx in csi-bridge subnode.
- Expand the example to include the csi-bridge subnode as well.
- Re-order subject prefixes.
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy@... to phy@... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.
- Re-order subject prefixes.
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.
- Convert OV5640 to use runtime PM and drop Cadence CSI2RX s_power patch.
- Drop subdev call wrappers from cdns-csi2rx.
- Move VPE and CAL to a separate subdir.
- Rename ti-csi2rx.c to j721e-csi2rx.c

Paul Kocialkowski (1):
  phy: Distinguish between Rx and Tx for MIPI D-PHY with submodes

Pratyush Yadav (17):
  phy: cdns-dphy: Prepare for Rx support
  phy: cdns-dphy: Allow setting mode
  phy: cdns-dphy: Add Rx support
  media: ov5640: Use runtime PM to control sensor power
  media: cadence: csi2rx: Add external DPHY support
  media: cadence: csi2rx: Soft reset the streams before starting capture
  media: cadence: csi2rx: Set the STOP bit when stopping a stream
  media: cadence: csi2rx: Fix stream data configuration
  media: cadence: csi2rx: Populate subdev devnode
  dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
  media: Re-structure TI platform drivers
  media: ti: Add CSI2RX support for J721E
  media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
  media: dt-bindings: Convert Cadence CSI2RX binding to YAML
  phy: dt-bindings: Convert Cadence DPHY binding to YAML
  phy: dt-bindings: cdns,dphy: make clocks optional
  phy: dt-bindings: cdns,dphy: add power-domains property

 .../devicetree/bindings/media/cdns,csi2rx.txt | 100 --
 .../bindings/media/cdns,csi2rx.yaml           | 164 ++++
 .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++
 .../devicetree/bindings/phy/cdns,dphy.txt     |  20 -
 .../devicetree/bindings/phy/cdns,dphy.yaml    |  54 ++
 MAINTAINERS                                   |  10 +-
 drivers/dma/ti/k3-psil-j721e.c                |  73 ++
 drivers/media/i2c/Kconfig                     |   2 +-
 drivers/media/i2c/ov5640.c                    | 124 ++-
 drivers/media/platform/Kconfig                |  12 +
 drivers/media/platform/Makefile               |   2 +-
 drivers/media/platform/cadence/cdns-csi2rx.c  | 196 +++-
 drivers/media/platform/ti/Makefile            |   4 +
 drivers/media/platform/ti/cal/Makefile        |   3 +
 .../{ti-vpe => ti/cal}/cal-camerarx.c         |   0
 .../platform/{ti-vpe => ti/cal}/cal-video.c   |   0
 .../media/platform/{ti-vpe => ti/cal}/cal.c   |   0
 .../media/platform/{ti-vpe => ti/cal}/cal.h   |   0
 .../platform/{ti-vpe => ti/cal}/cal_regs.h    |   0
 .../media/platform/ti/j721e-csi2rx/Makefile   |   2 +
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 884 ++++++++++++++++++
 .../platform/{ti-vpe => ti/vpe}/Makefile      |   4 -
 .../media/platform/{ti-vpe => ti/vpe}/csc.c   |   0
 .../media/platform/{ti-vpe => ti/vpe}/csc.h   |   0
 .../media/platform/{ti-vpe => ti/vpe}/sc.c    |   0
 .../media/platform/{ti-vpe => ti/vpe}/sc.h    |   0
 .../platform/{ti-vpe => ti/vpe}/sc_coeff.h    |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpdma.c |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpdma.h |   0
 .../platform/{ti-vpe => ti/vpe}/vpdma_priv.h  |   0
 .../media/platform/{ti-vpe => ti/vpe}/vpe.c   |   0
 .../platform/{ti-vpe => ti/vpe}/vpe_regs.h    |   0
 drivers/phy/cadence/cdns-dphy.c               | 407 +++++++-
 include/linux/phy/phy-mipi-dphy.h             |  13 +
 34 files changed, 1950 insertions(+), 225 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
 create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
 create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml
 create mode 100644 drivers/media/platform/ti/Makefile
 create mode 100644 drivers/media/platform/ti/cal/Makefile
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h (100%)
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/Makefile
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
 rename drivers/media/platform/{ti-vpe => ti/vpe}/Makefile (78%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h (100%)

-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 01/18] phy: Distinguish between Rx and Tx for MIPI D-PHY with submodes
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

As some D-PHY controllers support both Rx and Tx mode, we need a way for
users to explicitly request one or the other. For instance, Rx mode can
be used along with MIPI CSI-2 while Tx mode can be used with MIPI DSI.

Introduce new MIPI D-PHY PHY submodes to use with PHY_MODE_MIPI_DPHY.
The default (zero value) is kept to Tx so only the rkisp1 driver, which
uses D-PHY in Rx mode, needs to be adapted.

Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 include/linux/phy/phy-mipi-dphy.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..0f57ef46a8b5 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -6,6 +6,19 @@
 #ifndef __PHY_MIPI_DPHY_H_
 #define __PHY_MIPI_DPHY_H_
 
+/**
+ * enum phy_mipi_dphy_submode - MIPI D-PHY sub-mode
+ *
+ * A MIPI D-PHY can be used to transmit or receive data.
+ * Since some controllers can support both, the direction to enable is specified
+ * with the PHY sub-mode. Transmit is assumed by default with phy_set_mode.
+ */
+
+enum phy_mipi_dphy_submode {
+	PHY_MIPI_DPHY_SUBMODE_TX = 0,
+	PHY_MIPI_DPHY_SUBMODE_RX,
+};
+
 /**
  * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
  *
-- 
2.30.0


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

* [PATCH v2 01/18] phy: Distinguish between Rx and Tx for MIPI D-PHY with submodes
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

From: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

As some D-PHY controllers support both Rx and Tx mode, we need a way for
users to explicitly request one or the other. For instance, Rx mode can
be used along with MIPI CSI-2 while Tx mode can be used with MIPI DSI.

Introduce new MIPI D-PHY PHY submodes to use with PHY_MODE_MIPI_DPHY.
The default (zero value) is kept to Tx so only the rkisp1 driver, which
uses D-PHY in Rx mode, needs to be adapted.

Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 include/linux/phy/phy-mipi-dphy.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..0f57ef46a8b5 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -6,6 +6,19 @@
 #ifndef __PHY_MIPI_DPHY_H_
 #define __PHY_MIPI_DPHY_H_
 
+/**
+ * enum phy_mipi_dphy_submode - MIPI D-PHY sub-mode
+ *
+ * A MIPI D-PHY can be used to transmit or receive data.
+ * Since some controllers can support both, the direction to enable is specified
+ * with the PHY sub-mode. Transmit is assumed by default with phy_set_mode.
+ */
+
+enum phy_mipi_dphy_submode {
+	PHY_MIPI_DPHY_SUBMODE_TX = 0,
+	PHY_MIPI_DPHY_SUBMODE_RX,
+};
+
 /**
  * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
  *
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 02/18] phy: cdns-dphy: Prepare for Rx support
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The Rx programming sequence differs from the Tx programming sequence.
Currently only Tx mode is supported. Move all the Tx related parts into
a set of Tx-specific hooks that are then called by the main PHY
framework hooks. This way when Rx support is added all that is needed to
be done is to plug in the Rx hooks.

The clocks "psm" and "pll_ref" are not used by the Rx path so make them
optional in the probe and then check if they exist in the power_on()
hook.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 140 ++++++++++++++++++++++++--------
 1 file changed, 104 insertions(+), 36 deletions(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ba042e39cfaf..8656f2102a91 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -75,6 +75,11 @@ struct cdns_dphy;
 struct cdns_dphy_ops {
 	int (*probe)(struct cdns_dphy *dphy);
 	void (*remove)(struct cdns_dphy *dphy);
+	int (*power_on)(struct cdns_dphy *dphy);
+	int (*power_off)(struct cdns_dphy *dphy);
+	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
+			union phy_configure_opts *opts);
+	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
 	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
 	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
 				 enum cdns_dphy_clk_lane_cfg cfg);
@@ -86,12 +91,18 @@ struct cdns_dphy_ops {
 struct cdns_dphy {
 	struct cdns_dphy_cfg cfg;
 	void __iomem *regs;
+	struct device *dev;
 	struct clk *psm_clk;
 	struct clk *pll_ref_clk;
 	const struct cdns_dphy_ops *ops;
 	struct phy *phy;
 };
 
+struct cdns_dphy_driver_data {
+	const struct cdns_dphy_ops *tx;
+	const struct cdns_dphy_ops *rx;
+};
+
 static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 				     struct cdns_dphy_cfg *cfg,
 				     struct phy_configure_opts_mipi_dphy *opts,
@@ -199,20 +210,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
 	       dphy->regs + DPHY_PSM_CFG);
 }
 
-/*
- * This is the reference implementation of DPHY hooks. Specific integration of
- * this IP may have to re-implement some of them depending on how they decided
- * to wire things in the SoC.
- */
-static const struct cdns_dphy_ops ref_dphy_ops = {
-	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
-	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
-	.set_psm_div = cdns_dphy_ref_set_psm_div,
-};
-
-static int cdns_dphy_config_from_opts(struct phy *phy,
-				      struct phy_configure_opts_mipi_dphy *opts,
-				      struct cdns_dphy_cfg *cfg)
+static int cdns_dphy_tx_config_from_opts(struct phy *phy,
+					 struct phy_configure_opts_mipi_dphy *opts,
+					 struct cdns_dphy_cfg *cfg)
 {
 	struct cdns_dphy *dphy = phy_get_drvdata(phy);
 	unsigned int dsi_hfp_ext = 0;
@@ -232,24 +232,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
 	return 0;
 }
 
-static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
-			      union phy_configure_opts *opts)
+static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
 {
 	struct cdns_dphy_cfg cfg = { 0 };
-
-	if (mode != PHY_MODE_MIPI_DPHY)
-		return -EINVAL;
-
-	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
-}
-
-static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-{
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-	struct cdns_dphy_cfg cfg = { 0 };
 	int ret;
 
-	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
+	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
 	if (ret)
 		return ret;
 
@@ -279,9 +268,21 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 	return 0;
 }
 
-static int cdns_dphy_power_on(struct phy *phy)
+static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+	struct cdns_dphy_cfg cfg = { 0 };
+
+	if (submode != PHY_MIPI_DPHY_SUBMODE_TX)
+		return -EINVAL;
+
+	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
+}
+
+static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
+{
+	if (!dphy->psm_clk || !dphy->pll_ref_clk)
+		return -EINVAL;
 
 	clk_prepare_enable(dphy->psm_clk);
 	clk_prepare_enable(dphy->pll_ref_clk);
@@ -293,16 +294,77 @@ static int cdns_dphy_power_on(struct phy *phy)
 	return 0;
 }
 
-static int cdns_dphy_power_off(struct phy *phy)
+static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-
 	clk_disable_unprepare(dphy->pll_ref_clk);
 	clk_disable_unprepare(dphy->psm_clk);
 
 	return 0;
 }
 
+static const struct cdns_dphy_ops tx_ref_dphy_ops = {
+	.power_on = cdns_dphy_tx_power_on,
+	.power_off = cdns_dphy_tx_power_off,
+	.validate = cdns_dphy_tx_validate,
+	.configure = cdns_dphy_tx_configure,
+	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
+	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
+	.set_psm_div = cdns_dphy_ref_set_psm_div,
+};
+
+/*
+ * This is the reference implementation of DPHY hooks. Specific integration of
+ * this IP may have to re-implement some of them depending on how they decided
+ * to wire things in the SoC.
+ */
+static const struct cdns_dphy_driver_data ref_dphy_ops = {
+	.tx = &tx_ref_dphy_ops,
+};
+
+static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
+			      union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_MIPI_DPHY)
+		return -EINVAL;
+
+	if (dphy->ops->validate)
+		return dphy->ops->validate(dphy, mode, submode, opts);
+
+	return 0;
+}
+
+static int cdns_dphy_power_on(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_on)
+		return dphy->ops->power_on(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_power_off(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_off)
+		return dphy->ops->power_off(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->configure)
+		return dphy->ops->configure(dphy, opts);
+
+	return 0;
+}
+
 static const struct phy_ops cdns_dphy_ops = {
 	.configure	= cdns_dphy_configure,
 	.validate	= cdns_dphy_validate,
@@ -314,14 +376,20 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct cdns_dphy *dphy;
+	const struct cdns_dphy_driver_data *ddata;
 	int ret;
 
 	dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
 	if (!dphy)
 		return -ENOMEM;
 	dev_set_drvdata(&pdev->dev, dphy);
+	dphy->dev = &pdev->dev;
 
-	dphy->ops = of_device_get_match_data(&pdev->dev);
+	ddata = of_device_get_match_data(&pdev->dev);
+	if (!ddata)
+		return -EINVAL;
+
+	dphy->ops = ddata->tx;
 	if (!dphy->ops)
 		return -EINVAL;
 
@@ -329,11 +397,11 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 	if (IS_ERR(dphy->regs))
 		return PTR_ERR(dphy->regs);
 
-	dphy->psm_clk = devm_clk_get(&pdev->dev, "psm");
+	dphy->psm_clk = devm_clk_get_optional(dphy->dev, "psm");
 	if (IS_ERR(dphy->psm_clk))
 		return PTR_ERR(dphy->psm_clk);
 
-	dphy->pll_ref_clk = devm_clk_get(&pdev->dev, "pll_ref");
+	dphy->pll_ref_clk = devm_clk_get_optional(dphy->dev, "pll_ref");
 	if (IS_ERR(dphy->pll_ref_clk))
 		return PTR_ERR(dphy->pll_ref_clk);
 
-- 
2.30.0


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

* [PATCH v2 02/18] phy: cdns-dphy: Prepare for Rx support
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The Rx programming sequence differs from the Tx programming sequence.
Currently only Tx mode is supported. Move all the Tx related parts into
a set of Tx-specific hooks that are then called by the main PHY
framework hooks. This way when Rx support is added all that is needed to
be done is to plug in the Rx hooks.

The clocks "psm" and "pll_ref" are not used by the Rx path so make them
optional in the probe and then check if they exist in the power_on()
hook.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 140 ++++++++++++++++++++++++--------
 1 file changed, 104 insertions(+), 36 deletions(-)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index ba042e39cfaf..8656f2102a91 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -75,6 +75,11 @@ struct cdns_dphy;
 struct cdns_dphy_ops {
 	int (*probe)(struct cdns_dphy *dphy);
 	void (*remove)(struct cdns_dphy *dphy);
+	int (*power_on)(struct cdns_dphy *dphy);
+	int (*power_off)(struct cdns_dphy *dphy);
+	int (*validate)(struct cdns_dphy *dphy, enum phy_mode mode, int submode,
+			union phy_configure_opts *opts);
+	int (*configure)(struct cdns_dphy *dphy, union phy_configure_opts *opts);
 	void (*set_psm_div)(struct cdns_dphy *dphy, u8 div);
 	void (*set_clk_lane_cfg)(struct cdns_dphy *dphy,
 				 enum cdns_dphy_clk_lane_cfg cfg);
@@ -86,12 +91,18 @@ struct cdns_dphy_ops {
 struct cdns_dphy {
 	struct cdns_dphy_cfg cfg;
 	void __iomem *regs;
+	struct device *dev;
 	struct clk *psm_clk;
 	struct clk *pll_ref_clk;
 	const struct cdns_dphy_ops *ops;
 	struct phy *phy;
 };
 
+struct cdns_dphy_driver_data {
+	const struct cdns_dphy_ops *tx;
+	const struct cdns_dphy_ops *rx;
+};
+
 static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy,
 				     struct cdns_dphy_cfg *cfg,
 				     struct phy_configure_opts_mipi_dphy *opts,
@@ -199,20 +210,9 @@ static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div)
 	       dphy->regs + DPHY_PSM_CFG);
 }
 
-/*
- * This is the reference implementation of DPHY hooks. Specific integration of
- * this IP may have to re-implement some of them depending on how they decided
- * to wire things in the SoC.
- */
-static const struct cdns_dphy_ops ref_dphy_ops = {
-	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
-	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
-	.set_psm_div = cdns_dphy_ref_set_psm_div,
-};
-
-static int cdns_dphy_config_from_opts(struct phy *phy,
-				      struct phy_configure_opts_mipi_dphy *opts,
-				      struct cdns_dphy_cfg *cfg)
+static int cdns_dphy_tx_config_from_opts(struct phy *phy,
+					 struct phy_configure_opts_mipi_dphy *opts,
+					 struct cdns_dphy_cfg *cfg)
 {
 	struct cdns_dphy *dphy = phy_get_drvdata(phy);
 	unsigned int dsi_hfp_ext = 0;
@@ -232,24 +232,13 @@ static int cdns_dphy_config_from_opts(struct phy *phy,
 	return 0;
 }
 
-static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
-			      union phy_configure_opts *opts)
+static int cdns_dphy_tx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
 {
 	struct cdns_dphy_cfg cfg = { 0 };
-
-	if (mode != PHY_MODE_MIPI_DPHY)
-		return -EINVAL;
-
-	return cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
-}
-
-static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-{
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-	struct cdns_dphy_cfg cfg = { 0 };
 	int ret;
 
-	ret = cdns_dphy_config_from_opts(phy, &opts->mipi_dphy, &cfg);
+	ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
 	if (ret)
 		return ret;
 
@@ -279,9 +268,21 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 	return 0;
 }
 
-static int cdns_dphy_power_on(struct phy *phy)
+static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+	struct cdns_dphy_cfg cfg = { 0 };
+
+	if (submode != PHY_MIPI_DPHY_SUBMODE_TX)
+		return -EINVAL;
+
+	return cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg);
+}
+
+static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy)
+{
+	if (!dphy->psm_clk || !dphy->pll_ref_clk)
+		return -EINVAL;
 
 	clk_prepare_enable(dphy->psm_clk);
 	clk_prepare_enable(dphy->pll_ref_clk);
@@ -293,16 +294,77 @@ static int cdns_dphy_power_on(struct phy *phy)
 	return 0;
 }
 
-static int cdns_dphy_power_off(struct phy *phy)
+static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy)
 {
-	struct cdns_dphy *dphy = phy_get_drvdata(phy);
-
 	clk_disable_unprepare(dphy->pll_ref_clk);
 	clk_disable_unprepare(dphy->psm_clk);
 
 	return 0;
 }
 
+static const struct cdns_dphy_ops tx_ref_dphy_ops = {
+	.power_on = cdns_dphy_tx_power_on,
+	.power_off = cdns_dphy_tx_power_off,
+	.validate = cdns_dphy_tx_validate,
+	.configure = cdns_dphy_tx_configure,
+	.get_wakeup_time_ns = cdns_dphy_ref_get_wakeup_time_ns,
+	.set_pll_cfg = cdns_dphy_ref_set_pll_cfg,
+	.set_psm_div = cdns_dphy_ref_set_psm_div,
+};
+
+/*
+ * This is the reference implementation of DPHY hooks. Specific integration of
+ * this IP may have to re-implement some of them depending on how they decided
+ * to wire things in the SoC.
+ */
+static const struct cdns_dphy_driver_data ref_dphy_ops = {
+	.tx = &tx_ref_dphy_ops,
+};
+
+static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
+			      union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_MIPI_DPHY)
+		return -EINVAL;
+
+	if (dphy->ops->validate)
+		return dphy->ops->validate(dphy, mode, submode, opts);
+
+	return 0;
+}
+
+static int cdns_dphy_power_on(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_on)
+		return dphy->ops->power_on(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_power_off(struct phy *phy)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->power_off)
+		return dphy->ops->power_off(dphy);
+
+	return 0;
+}
+
+static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+
+	if (dphy->ops->configure)
+		return dphy->ops->configure(dphy, opts);
+
+	return 0;
+}
+
 static const struct phy_ops cdns_dphy_ops = {
 	.configure	= cdns_dphy_configure,
 	.validate	= cdns_dphy_validate,
@@ -314,14 +376,20 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 {
 	struct phy_provider *phy_provider;
 	struct cdns_dphy *dphy;
+	const struct cdns_dphy_driver_data *ddata;
 	int ret;
 
 	dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
 	if (!dphy)
 		return -ENOMEM;
 	dev_set_drvdata(&pdev->dev, dphy);
+	dphy->dev = &pdev->dev;
 
-	dphy->ops = of_device_get_match_data(&pdev->dev);
+	ddata = of_device_get_match_data(&pdev->dev);
+	if (!ddata)
+		return -EINVAL;
+
+	dphy->ops = ddata->tx;
 	if (!dphy->ops)
 		return -EINVAL;
 
@@ -329,11 +397,11 @@ static int cdns_dphy_probe(struct platform_device *pdev)
 	if (IS_ERR(dphy->regs))
 		return PTR_ERR(dphy->regs);
 
-	dphy->psm_clk = devm_clk_get(&pdev->dev, "psm");
+	dphy->psm_clk = devm_clk_get_optional(dphy->dev, "psm");
 	if (IS_ERR(dphy->psm_clk))
 		return PTR_ERR(dphy->psm_clk);
 
-	dphy->pll_ref_clk = devm_clk_get(&pdev->dev, "pll_ref");
+	dphy->pll_ref_clk = devm_clk_get_optional(dphy->dev, "pll_ref");
 	if (IS_ERR(dphy->pll_ref_clk))
 		return PTR_ERR(dphy->pll_ref_clk);
 
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 03/18] phy: cdns-dphy: Allow setting mode
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Allow callers to set the PHY mode. The main mode should always be
PHY_MODE_MIPI_DPHY but the submode can either be
PHY_MIPI_DPHY_SUBMODE_RX or PHY_MIPI_DPHY_SUBMODE_TX. Update the ops
based on the requested submode.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index 8656f2102a91..7d5f7b333893 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -365,11 +365,41 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 	return 0;
 }
 
+static int cdns_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+	const struct cdns_dphy_driver_data *ddata;
+
+	ddata = of_device_get_match_data(dphy->dev);
+	if (!ddata)
+		return -EINVAL;
+
+	if (mode != PHY_MODE_MIPI_DPHY)
+		return -EINVAL;
+
+	if (submode == PHY_MIPI_DPHY_SUBMODE_TX) {
+		if (!ddata->tx)
+			return -EOPNOTSUPP;
+
+		dphy->ops = ddata->tx;
+	} else if (submode == PHY_MIPI_DPHY_SUBMODE_RX) {
+		if (!ddata->rx)
+			return -EOPNOTSUPP;
+
+		dphy->ops = ddata->rx;
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static const struct phy_ops cdns_dphy_ops = {
 	.configure	= cdns_dphy_configure,
 	.validate	= cdns_dphy_validate,
 	.power_on	= cdns_dphy_power_on,
 	.power_off	= cdns_dphy_power_off,
+	.set_mode	= cdns_dphy_set_mode,
 };
 
 static int cdns_dphy_probe(struct platform_device *pdev)
-- 
2.30.0


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

* [PATCH v2 03/18] phy: cdns-dphy: Allow setting mode
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Allow callers to set the PHY mode. The main mode should always be
PHY_MODE_MIPI_DPHY but the submode can either be
PHY_MIPI_DPHY_SUBMODE_RX or PHY_MIPI_DPHY_SUBMODE_TX. Update the ops
based on the requested submode.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index 8656f2102a91..7d5f7b333893 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -365,11 +365,41 @@ static int cdns_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
 	return 0;
 }
 
+static int cdns_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct cdns_dphy *dphy = phy_get_drvdata(phy);
+	const struct cdns_dphy_driver_data *ddata;
+
+	ddata = of_device_get_match_data(dphy->dev);
+	if (!ddata)
+		return -EINVAL;
+
+	if (mode != PHY_MODE_MIPI_DPHY)
+		return -EINVAL;
+
+	if (submode == PHY_MIPI_DPHY_SUBMODE_TX) {
+		if (!ddata->tx)
+			return -EOPNOTSUPP;
+
+		dphy->ops = ddata->tx;
+	} else if (submode == PHY_MIPI_DPHY_SUBMODE_RX) {
+		if (!ddata->rx)
+			return -EOPNOTSUPP;
+
+		dphy->ops = ddata->rx;
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
 static const struct phy_ops cdns_dphy_ops = {
 	.configure	= cdns_dphy_configure,
 	.validate	= cdns_dphy_validate,
 	.power_on	= cdns_dphy_power_on,
 	.power_off	= cdns_dphy_power_off,
+	.set_mode	= cdns_dphy_set_mode,
 };
 
 static int cdns_dphy_probe(struct platform_device *pdev)
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 04/18] phy: cdns-dphy: Add Rx support
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The Cadence DPHY can be used to receive image data over the CSI-2
protocol. Add support for Rx mode. The programming sequence differs from
the Tx mode so it is added as a separate set of hooks to isolate the two
paths.

The PHY is in Tx mode by default and it needs to be set in Rx mode by
setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
callback.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 237 ++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index 7d5f7b333893..7bbca679e2bb 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -1,11 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright: 2017-2018 Cadence Design Systems, Inc.
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -25,10 +28,14 @@
 #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
 #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
 #define DPHY_PCS(reg)			(0xb00 + (reg))
+#define DPHY_ISO(reg)			(0xc00 + (reg))
 
 #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
 #define DPHY_CMN_SSM_EN			BIT(0)
+#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
 #define DPHY_CMN_TX_MODE_EN		BIT(9)
+#define DPHY_CMN_RX_MODE_EN		BIT(10)
+#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
 
 #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
 #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
@@ -45,10 +52,27 @@
 #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
 #define DPHY_CMN_OPDIV(x)		((x) << 7)
 
+#define DPHY_BAND_CFG			DPHY_PCS(0x0)
+#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
+#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
+
 #define DPHY_PSM_CFG			DPHY_PCS(0x4)
 #define DPHY_PSM_CFG_FROM_REG		BIT(0)
 #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
 
+#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
+#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
+#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
+#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
+
+#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
+#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
+#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
+#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
+#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
+#define DPHY_ISO_LANE_READY_BIT		0
+#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
+
 #define DSI_HBP_FRAME_OVERHEAD		12
 #define DSI_HSA_FRAME_OVERHEAD		14
 #define DSI_HFP_FRAME_OVERHEAD		6
@@ -57,6 +81,9 @@
 #define DSI_NULL_FRAME_OVERHEAD		6
 #define DSI_EOT_PKT_SIZE		4
 
+#define DPHY_LANES_MIN			1
+#define DPHY_LANES_MAX			4
+
 struct cdns_dphy_cfg {
 	u8 pll_ipdiv;
 	u8 pll_opdiv;
@@ -312,6 +339,214 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
 	.set_psm_div = cdns_dphy_ref_set_psm_div,
 };
 
+static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
+{
+	/* Start RX state machine. */
+	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
+	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
+			  DPHY_CMN_RX_BANDGAP_TIMER),
+	       dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
+{
+	writel(0, dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
+{
+	unsigned int rate = hs_clk_rate / 1000000UL;
+
+	if (rate < 80 || rate >= 2500)
+		return -EOPNOTSUPP;
+
+	if (rate >= 80 && rate < 100)
+		return 0;
+
+	if (rate >= 100 && rate < 120)
+		return 1;
+
+	if (rate >= 120 && rate < 160)
+		return 2;
+
+	if (rate >= 160 && rate < 200)
+		return 3;
+
+	if (rate >= 200 && rate < 240)
+		return 4;
+
+	if (rate >= 240 && rate < 280)
+		return 5;
+
+	if (rate >= 280 && rate < 320)
+		return 6;
+
+	if (rate >= 320 && rate < 360)
+		return 7;
+
+	if (rate >= 360 && rate < 400)
+		return 8;
+
+	if (rate >= 400 && rate < 480)
+		return 9;
+
+	if (rate >= 480 && rate < 560)
+		return 10;
+
+	if (rate >= 560 && rate < 640)
+		return 11;
+
+	if (rate >= 640 && rate < 720)
+		return 12;
+
+	if (rate >= 720 && rate < 800)
+		return 13;
+
+	if (rate >= 800 && rate < 880)
+		return 14;
+
+	if (rate >= 880 && rate < 1040)
+		return 15;
+
+	if (rate >= 1040 && rate < 1200)
+		return 16;
+
+	if (rate >= 1200 && rate < 1350)
+		return 17;
+
+	if (rate >= 1350 && rate < 1500)
+		return 18;
+
+	if (rate >= 1500 && rate < 1750)
+		return 19;
+
+	if (rate >= 1750 && rate < 2000)
+		return 20;
+
+	if (rate >= 2000 && rate < 2250)
+		return 21;
+
+	if (rate >= 2250 && rate < 2500)
+		return 22;
+
+	/* Unreachable. */
+	WARN(1, "Reached unreachable code.");
+	return -EINVAL;
+}
+
+static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
+{
+	u32 val;
+
+	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
+					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
+}
+
+static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
+{
+	void __iomem *reg = dphy->regs;
+	int ret;
+
+	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
+		return -EINVAL;
+
+	/* Clock lane */
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	/* Data lanes. Minimum one lane is mandatory. */
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L0,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 2)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L1,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 3)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L2,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 4)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L3,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
+{
+	unsigned int reg;
+	int band_ctrl, ret;
+
+	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (band_ctrl < 0)
+		return band_ctrl;
+
+	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
+	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
+	writel(reg, dphy->regs + DPHY_BAND_CFG);
+
+	/*
+	 * Set the required power island phase 2 time. This is mandated by DPHY
+	 * specs.
+	 */
+	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
+	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
+
+	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
+	if (ret) {
+		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
+{
+	int ret;
+
+	if (submode != PHY_MIPI_DPHY_SUBMODE_RX)
+		return -EINVAL;
+
+	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (ret < 0)
+		return ret;
+
+	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
+}
+
+static const struct cdns_dphy_ops rx_ref_dphy_ops = {
+	.power_on = cdns_dphy_rx_power_on,
+	.power_off = cdns_dphy_rx_power_off,
+	.configure = cdns_dphy_rx_configure,
+	.validate = cdns_dphy_rx_validate,
+};
+
 /*
  * This is the reference implementation of DPHY hooks. Specific integration of
  * this IP may have to re-implement some of them depending on how they decided
@@ -319,6 +554,7 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
  */
 static const struct cdns_dphy_driver_data ref_dphy_ops = {
 	.tx = &tx_ref_dphy_ops,
+	.rx = &rx_ref_dphy_ops,
 };
 
 static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
@@ -483,5 +719,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
 module_platform_driver(cdns_dphy_platform_driver);
 
 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
+MODULE_AUTHOR("Pratyush Yadav <p.yadav@ti.com>");
 MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
 MODULE_LICENSE("GPL");
-- 
2.30.0


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

* [PATCH v2 04/18] phy: cdns-dphy: Add Rx support
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The Cadence DPHY can be used to receive image data over the CSI-2
protocol. Add support for Rx mode. The programming sequence differs from
the Tx mode so it is added as a separate set of hooks to isolate the two
paths.

The PHY is in Tx mode by default and it needs to be set in Rx mode by
setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
callback.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/phy/cadence/cdns-dphy.c | 237 ++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)

diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
index 7d5f7b333893..7bbca679e2bb 100644
--- a/drivers/phy/cadence/cdns-dphy.c
+++ b/drivers/phy/cadence/cdns-dphy.c
@@ -1,11 +1,14 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright: 2017-2018 Cadence Design Systems, Inc.
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -25,10 +28,14 @@
 #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
 #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
 #define DPHY_PCS(reg)			(0xb00 + (reg))
+#define DPHY_ISO(reg)			(0xc00 + (reg))
 
 #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
 #define DPHY_CMN_SSM_EN			BIT(0)
+#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
 #define DPHY_CMN_TX_MODE_EN		BIT(9)
+#define DPHY_CMN_RX_MODE_EN		BIT(10)
+#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
 
 #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
 #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
@@ -45,10 +52,27 @@
 #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
 #define DPHY_CMN_OPDIV(x)		((x) << 7)
 
+#define DPHY_BAND_CFG			DPHY_PCS(0x0)
+#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
+#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
+
 #define DPHY_PSM_CFG			DPHY_PCS(0x4)
 #define DPHY_PSM_CFG_FROM_REG		BIT(0)
 #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
 
+#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
+#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
+#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
+#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
+
+#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
+#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
+#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
+#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
+#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
+#define DPHY_ISO_LANE_READY_BIT		0
+#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
+
 #define DSI_HBP_FRAME_OVERHEAD		12
 #define DSI_HSA_FRAME_OVERHEAD		14
 #define DSI_HFP_FRAME_OVERHEAD		6
@@ -57,6 +81,9 @@
 #define DSI_NULL_FRAME_OVERHEAD		6
 #define DSI_EOT_PKT_SIZE		4
 
+#define DPHY_LANES_MIN			1
+#define DPHY_LANES_MAX			4
+
 struct cdns_dphy_cfg {
 	u8 pll_ipdiv;
 	u8 pll_opdiv;
@@ -312,6 +339,214 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
 	.set_psm_div = cdns_dphy_ref_set_psm_div,
 };
 
+static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
+{
+	/* Start RX state machine. */
+	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
+	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
+			  DPHY_CMN_RX_BANDGAP_TIMER),
+	       dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
+{
+	writel(0, dphy->regs + DPHY_CMN_SSM);
+
+	return 0;
+}
+
+static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
+{
+	unsigned int rate = hs_clk_rate / 1000000UL;
+
+	if (rate < 80 || rate >= 2500)
+		return -EOPNOTSUPP;
+
+	if (rate >= 80 && rate < 100)
+		return 0;
+
+	if (rate >= 100 && rate < 120)
+		return 1;
+
+	if (rate >= 120 && rate < 160)
+		return 2;
+
+	if (rate >= 160 && rate < 200)
+		return 3;
+
+	if (rate >= 200 && rate < 240)
+		return 4;
+
+	if (rate >= 240 && rate < 280)
+		return 5;
+
+	if (rate >= 280 && rate < 320)
+		return 6;
+
+	if (rate >= 320 && rate < 360)
+		return 7;
+
+	if (rate >= 360 && rate < 400)
+		return 8;
+
+	if (rate >= 400 && rate < 480)
+		return 9;
+
+	if (rate >= 480 && rate < 560)
+		return 10;
+
+	if (rate >= 560 && rate < 640)
+		return 11;
+
+	if (rate >= 640 && rate < 720)
+		return 12;
+
+	if (rate >= 720 && rate < 800)
+		return 13;
+
+	if (rate >= 800 && rate < 880)
+		return 14;
+
+	if (rate >= 880 && rate < 1040)
+		return 15;
+
+	if (rate >= 1040 && rate < 1200)
+		return 16;
+
+	if (rate >= 1200 && rate < 1350)
+		return 17;
+
+	if (rate >= 1350 && rate < 1500)
+		return 18;
+
+	if (rate >= 1500 && rate < 1750)
+		return 19;
+
+	if (rate >= 1750 && rate < 2000)
+		return 20;
+
+	if (rate >= 2000 && rate < 2250)
+		return 21;
+
+	if (rate >= 2250 && rate < 2500)
+		return 22;
+
+	/* Unreachable. */
+	WARN(1, "Reached unreachable code.");
+	return -EINVAL;
+}
+
+static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
+{
+	u32 val;
+
+	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
+					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
+}
+
+static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
+{
+	void __iomem *reg = dphy->regs;
+	int ret;
+
+	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
+		return -EINVAL;
+
+	/* Clock lane */
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	/* Data lanes. Minimum one lane is mandatory. */
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L0,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 2)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L1,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 3)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L2,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	if (lanes < 4)
+		return 0;
+
+	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L3,
+					DPHY_ISO_LANE_READY_BIT);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int cdns_dphy_rx_configure(struct cdns_dphy *dphy,
+				  union phy_configure_opts *opts)
+{
+	unsigned int reg;
+	int band_ctrl, ret;
+
+	band_ctrl = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (band_ctrl < 0)
+		return band_ctrl;
+
+	reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) |
+	      FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl);
+	writel(reg, dphy->regs + DPHY_BAND_CFG);
+
+	/*
+	 * Set the required power island phase 2 time. This is mandated by DPHY
+	 * specs.
+	 */
+	reg = DPHY_POWER_ISLAND_EN_DATA_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_DATA);
+	reg = DPHY_POWER_ISLAND_EN_CLK_VAL;
+	writel(reg, dphy->regs + DPHY_POWER_ISLAND_EN_CLK);
+
+	ret = cdns_dphy_rx_wait_lane_ready(dphy, opts->mipi_dphy.lanes);
+	if (ret) {
+		dev_err(dphy->dev, "DPHY wait for lane ready timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int cdns_dphy_rx_validate(struct cdns_dphy *dphy, enum phy_mode mode,
+				 int submode, union phy_configure_opts *opts)
+{
+	int ret;
+
+	if (submode != PHY_MIPI_DPHY_SUBMODE_RX)
+		return -EINVAL;
+
+	ret = cdns_dphy_rx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate);
+	if (ret < 0)
+		return ret;
+
+	return phy_mipi_dphy_config_validate(&opts->mipi_dphy);
+}
+
+static const struct cdns_dphy_ops rx_ref_dphy_ops = {
+	.power_on = cdns_dphy_rx_power_on,
+	.power_off = cdns_dphy_rx_power_off,
+	.configure = cdns_dphy_rx_configure,
+	.validate = cdns_dphy_rx_validate,
+};
+
 /*
  * This is the reference implementation of DPHY hooks. Specific integration of
  * this IP may have to re-implement some of them depending on how they decided
@@ -319,6 +554,7 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
  */
 static const struct cdns_dphy_driver_data ref_dphy_ops = {
 	.tx = &tx_ref_dphy_ops,
+	.rx = &rx_ref_dphy_ops,
 };
 
 static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode,
@@ -483,5 +719,6 @@ static struct platform_driver cdns_dphy_platform_driver = {
 module_platform_driver(cdns_dphy_platform_driver);
 
 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
+MODULE_AUTHOR("Pratyush Yadav <p.yadav@ti.com>");
 MODULE_DESCRIPTION("Cadence MIPI D-PHY Driver");
 MODULE_LICENSE("GPL");
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Calling s_power subdev callback is discouraged. Instead, the subdevs
should use runtime PM to control its power. Use runtime PM callbacks to
control sensor power. The pm counter is incremented when the stream is
started and decremented when the stream is stopped.

Refactor s_stream() a bit to make this new control flow easier. Add a
helper to choose whether mipi or dvp set_stream needs to be called. The
logic flow is also changed to make it a bit clearer.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- New in v2.

 drivers/media/i2c/Kconfig  |   2 +-
 drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
 2 files changed, 77 insertions(+), 49 deletions(-)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 462c0e059754..5588fc1cc14a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -914,7 +914,7 @@ config VIDEO_OV2740
 
 config VIDEO_OV5640
 	tristate "OmniVision OV5640 sensor support"
-	depends on OF
+	depends on OF && PM
 	depends on GPIOLIB && VIDEO_V4L2 && I2C
 	select MEDIA_CONTROLLER
 	select VIDEO_V4L2_SUBDEV_API
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 5b9cc71df473..4ed5758e2398 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -238,8 +239,6 @@ struct ov5640_dev {
 	/* lock to protect all members below */
 	struct mutex lock;
 
-	int power_count;
-
 	struct v4l2_mbus_framefmt fmt;
 	bool pending_fmt_change;
 
@@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
 				on ? 0x00 : 0x0f);
 }
 
+static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
+{
+	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
+		return ov5640_set_stream_mipi(sensor, on);
+	else
+		return ov5640_set_stream_dvp(sensor, on);
+}
+
 static int ov5640_get_sysclk(struct ov5640_dev *sensor)
 {
 	 /* calculate sysclk */
@@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
 
 /* --------------- Subdev Operations --------------- */
 
-static int ov5640_s_power(struct v4l2_subdev *sd, int on)
-{
-	struct ov5640_dev *sensor = to_ov5640_dev(sd);
-	int ret = 0;
-
-	mutex_lock(&sensor->lock);
-
-	/*
-	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
-	 * update the power state.
-	 */
-	if (sensor->power_count == !on) {
-		ret = ov5640_set_power(sensor, !!on);
-		if (ret)
-			goto out;
-	}
-
-	/* Update the power count. */
-	sensor->power_count += on ? 1 : -1;
-	WARN_ON(sensor->power_count < 0);
-out:
-	mutex_unlock(&sensor->lock);
-
-	if (on && !ret && sensor->power_count == 1) {
-		/* restore controls */
-		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
-	}
-
-	return ret;
-}
-
 static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
 				     struct v4l2_fract *fi,
 				     u32 width, u32 height)
@@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
+	struct device *dev = &sensor->i2c_client->dev;
 	int ret;
 
 	/* v4l2_ctrl_lock() locks our own mutex */
@@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
 	 * not apply any controls to H/W at this time. Instead
 	 * the controls will be restored right after power-up.
 	 */
-	if (sensor->power_count == 0)
+	if (pm_runtime_suspended(dev))
 		return 0;
 
 	switch (ctrl->id) {
@@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
 static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
+	struct device *dev = &sensor->i2c_client->dev;
 	int ret = 0;
 
 	mutex_lock(&sensor->lock);
 
-	if (sensor->streaming == !enable) {
-		if (enable && sensor->pending_mode_change) {
+	if (sensor->streaming == enable)
+		goto out;
+
+	if (enable) {
+		ret = pm_runtime_get_sync(dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(dev);
+			goto out;
+		}
+
+		if (sensor->pending_mode_change) {
 			ret = ov5640_set_mode(sensor);
 			if (ret)
-				goto out;
+				goto put_pm;
 		}
 
-		if (enable && sensor->pending_fmt_change) {
+		if (sensor->pending_fmt_change) {
 			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
 			if (ret)
-				goto out;
+				goto put_pm;
 			sensor->pending_fmt_change = false;
 		}
 
-		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
-			ret = ov5640_set_stream_mipi(sensor, enable);
-		else
-			ret = ov5640_set_stream_dvp(sensor, enable);
+		ret = ov5640_set_stream(sensor, enable);
+		if (ret)
+			goto put_pm;
+	} else {
+		ret = ov5640_set_stream(sensor, enable);
+		if (ret)
+			goto out;
 
-		if (!ret)
-			sensor->streaming = enable;
+		pm_runtime_put(dev);
 	}
+
+	sensor->streaming = enable;
+	goto out;
+
+put_pm:
+	pm_runtime_put(dev);
 out:
 	mutex_unlock(&sensor->lock);
 	return ret;
 }
 
 static const struct v4l2_subdev_core_ops ov5640_core_ops = {
-	.s_power = ov5640_s_power,
 	.log_status = v4l2_ctrl_subdev_log_status,
 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
@@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
 	return ret;
 }
 
+static int ov5640_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
+
+	return ov5640_set_power(sensor, false);
+}
+
+static int ov5640_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
+	int ret = 0;
+
+	ret = ov5640_set_power(sensor, true);
+	if (ret)
+		return ret;
+
+	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+}
+
 static int ov5640_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
 	if (ret)
 		goto entity_cleanup;
 
+	pm_runtime_enable(dev);
+	pm_runtime_set_suspended(dev);
+
 	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
 	if (ret)
-		goto free_ctrls;
+		goto error_pm;
 
 	return 0;
 
-free_ctrls:
+error_pm:
+	pm_runtime_disable(dev);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 entity_cleanup:
 	media_entity_cleanup(&sensor->sd.entity);
@@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
 
 static int ov5640_remove(struct i2c_client *client)
 {
+	struct device *dev = &client->dev;
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
 
 	v4l2_async_unregister_subdev(&sensor->sd);
 	media_entity_cleanup(&sensor->sd.entity);
+	pm_runtime_disable(dev);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 	mutex_destroy(&sensor->lock);
 
 	return 0;
 }
 
+static const struct dev_pm_ops ov5640_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
+};
+
 static const struct i2c_device_id ov5640_id[] = {
 	{"ov5640", 0},
 	{},
@@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
 	.driver = {
 		.name  = "ov5640",
 		.of_match_table	= ov5640_dt_ids,
+		.pm = &ov5640_pm_ops,
 	},
 	.id_table = ov5640_id,
 	.probe_new = ov5640_probe,
-- 
2.30.0


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

* [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Calling s_power subdev callback is discouraged. Instead, the subdevs
should use runtime PM to control its power. Use runtime PM callbacks to
control sensor power. The pm counter is incremented when the stream is
started and decremented when the stream is stopped.

Refactor s_stream() a bit to make this new control flow easier. Add a
helper to choose whether mipi or dvp set_stream needs to be called. The
logic flow is also changed to make it a bit clearer.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- New in v2.

 drivers/media/i2c/Kconfig  |   2 +-
 drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
 2 files changed, 77 insertions(+), 49 deletions(-)

diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 462c0e059754..5588fc1cc14a 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -914,7 +914,7 @@ config VIDEO_OV2740
 
 config VIDEO_OV5640
 	tristate "OmniVision OV5640 sensor support"
-	depends on OF
+	depends on OF && PM
 	depends on GPIOLIB && VIDEO_V4L2 && I2C
 	select MEDIA_CONTROLLER
 	select VIDEO_V4L2_SUBDEV_API
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index 5b9cc71df473..4ed5758e2398 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -238,8 +239,6 @@ struct ov5640_dev {
 	/* lock to protect all members below */
 	struct mutex lock;
 
-	int power_count;
-
 	struct v4l2_mbus_framefmt fmt;
 	bool pending_fmt_change;
 
@@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
 				on ? 0x00 : 0x0f);
 }
 
+static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
+{
+	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
+		return ov5640_set_stream_mipi(sensor, on);
+	else
+		return ov5640_set_stream_dvp(sensor, on);
+}
+
 static int ov5640_get_sysclk(struct ov5640_dev *sensor)
 {
 	 /* calculate sysclk */
@@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
 
 /* --------------- Subdev Operations --------------- */
 
-static int ov5640_s_power(struct v4l2_subdev *sd, int on)
-{
-	struct ov5640_dev *sensor = to_ov5640_dev(sd);
-	int ret = 0;
-
-	mutex_lock(&sensor->lock);
-
-	/*
-	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
-	 * update the power state.
-	 */
-	if (sensor->power_count == !on) {
-		ret = ov5640_set_power(sensor, !!on);
-		if (ret)
-			goto out;
-	}
-
-	/* Update the power count. */
-	sensor->power_count += on ? 1 : -1;
-	WARN_ON(sensor->power_count < 0);
-out:
-	mutex_unlock(&sensor->lock);
-
-	if (on && !ret && sensor->power_count == 1) {
-		/* restore controls */
-		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
-	}
-
-	return ret;
-}
-
 static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
 				     struct v4l2_fract *fi,
 				     u32 width, u32 height)
@@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
+	struct device *dev = &sensor->i2c_client->dev;
 	int ret;
 
 	/* v4l2_ctrl_lock() locks our own mutex */
@@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
 	 * not apply any controls to H/W at this time. Instead
 	 * the controls will be restored right after power-up.
 	 */
-	if (sensor->power_count == 0)
+	if (pm_runtime_suspended(dev))
 		return 0;
 
 	switch (ctrl->id) {
@@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
 static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
+	struct device *dev = &sensor->i2c_client->dev;
 	int ret = 0;
 
 	mutex_lock(&sensor->lock);
 
-	if (sensor->streaming == !enable) {
-		if (enable && sensor->pending_mode_change) {
+	if (sensor->streaming == enable)
+		goto out;
+
+	if (enable) {
+		ret = pm_runtime_get_sync(dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(dev);
+			goto out;
+		}
+
+		if (sensor->pending_mode_change) {
 			ret = ov5640_set_mode(sensor);
 			if (ret)
-				goto out;
+				goto put_pm;
 		}
 
-		if (enable && sensor->pending_fmt_change) {
+		if (sensor->pending_fmt_change) {
 			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
 			if (ret)
-				goto out;
+				goto put_pm;
 			sensor->pending_fmt_change = false;
 		}
 
-		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
-			ret = ov5640_set_stream_mipi(sensor, enable);
-		else
-			ret = ov5640_set_stream_dvp(sensor, enable);
+		ret = ov5640_set_stream(sensor, enable);
+		if (ret)
+			goto put_pm;
+	} else {
+		ret = ov5640_set_stream(sensor, enable);
+		if (ret)
+			goto out;
 
-		if (!ret)
-			sensor->streaming = enable;
+		pm_runtime_put(dev);
 	}
+
+	sensor->streaming = enable;
+	goto out;
+
+put_pm:
+	pm_runtime_put(dev);
 out:
 	mutex_unlock(&sensor->lock);
 	return ret;
 }
 
 static const struct v4l2_subdev_core_ops ov5640_core_ops = {
-	.s_power = ov5640_s_power,
 	.log_status = v4l2_ctrl_subdev_log_status,
 	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
 	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
@@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
 	return ret;
 }
 
+static int ov5640_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
+
+	return ov5640_set_power(sensor, false);
+}
+
+static int ov5640_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
+	int ret = 0;
+
+	ret = ov5640_set_power(sensor, true);
+	if (ret)
+		return ret;
+
+	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
+}
+
 static int ov5640_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
 	if (ret)
 		goto entity_cleanup;
 
+	pm_runtime_enable(dev);
+	pm_runtime_set_suspended(dev);
+
 	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
 	if (ret)
-		goto free_ctrls;
+		goto error_pm;
 
 	return 0;
 
-free_ctrls:
+error_pm:
+	pm_runtime_disable(dev);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 entity_cleanup:
 	media_entity_cleanup(&sensor->sd.entity);
@@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
 
 static int ov5640_remove(struct i2c_client *client)
 {
+	struct device *dev = &client->dev;
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct ov5640_dev *sensor = to_ov5640_dev(sd);
 
 	v4l2_async_unregister_subdev(&sensor->sd);
 	media_entity_cleanup(&sensor->sd.entity);
+	pm_runtime_disable(dev);
 	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
 	mutex_destroy(&sensor->lock);
 
 	return 0;
 }
 
+static const struct dev_pm_ops ov5640_pm_ops = {
+	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
+};
+
 static const struct i2c_device_id ov5640_id[] = {
 	{"ov5640", 0},
 	{},
@@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
 	.driver = {
 		.name  = "ov5640",
 		.of_match_table	= ov5640_dt_ids,
+		.pm = &ov5640_pm_ops,
 	},
 	.id_table = ov5640_id,
 	.probe_new = ov5640_probe,
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Some platforms like TI's J721E can have the CSI2RX paired with an
external DPHY. Add support to enable and configure the DPHY using the
generic PHY framework.

Get the pixel rate and bpp from the subdev and pass them on to the DPHY
along with the number of lanes. All other settings are left to their
default values.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
  calls to set PHY mode, etc. to make sure it is ready.

 drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
 1 file changed, 148 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index c68a3eac62cd..459326de2eff 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -30,6 +30,12 @@
 #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
 #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
 
+#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
+#define CSI2RX_DPHY_CL_RST			BIT(16)
+#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
+#define CSI2RX_DPHY_CL_EN			BIT(4)
+#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
+
 #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
@@ -54,6 +60,11 @@ enum csi2rx_pads {
 	CSI2RX_PAD_MAX,
 };
 
+struct csi2rx_fmt {
+	u32				code;
+	u8				bpp;
+};
+
 struct csi2rx_priv {
 	struct device			*dev;
 	unsigned int			count;
@@ -85,6 +96,52 @@ struct csi2rx_priv {
 	int				source_pad;
 };
 
+static const struct csi2rx_fmt formats[] = {
+	{
+		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.bpp	= 16,
+	},
+};
+
+static u8 csi2rx_get_bpp(u32 code)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].code == code)
+			return formats[i].bpp;
+	}
+
+	return 0;
+}
+
+static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
+{
+	struct v4l2_ctrl *ctrl;
+
+	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
+			      V4L2_CID_PIXEL_RATE);
+	if (!ctrl) {
+		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
+			csi2rx->source_subdev->name);
+		return -EINVAL;
+	}
+
+	return v4l2_ctrl_g_ctrl_int64(ctrl);
+}
+
 static inline
 struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
 {
@@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
 	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
 }
 
+static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
+{
+	union phy_configure_opts opts = { };
+	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+	struct v4l2_subdev_format sd_fmt;
+	s64 pixel_rate;
+	int ret;
+	u8 bpp;
+	bool got_pm = true;
+
+	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	sd_fmt.pad = 0;
+
+	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
+			       &sd_fmt);
+	if (ret)
+		return ret;
+
+	bpp = csi2rx_get_bpp(sd_fmt.format.code);
+	if (!bpp)
+		return -EINVAL;
+
+	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
+	if (pixel_rate < 0)
+		return pixel_rate;
+
+	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
+					       csi2rx->num_lanes, cfg);
+	if (ret)
+		return ret;
+
+	ret = phy_pm_runtime_get_sync(csi2rx->dphy);
+	if (ret == -ENOTSUPP)
+		got_pm = false;
+	else if (ret)
+		return ret;
+
+	ret = phy_set_mode_ext(csi2rx->dphy, PHY_MODE_MIPI_DPHY,
+			       PHY_MIPI_DPHY_SUBMODE_RX);
+	if (ret)
+		goto out;
+
+	ret = phy_power_on(csi2rx->dphy);
+	if (ret)
+		goto out;
+
+	ret = phy_configure(csi2rx->dphy, &opts);
+	if (ret) {
+		/* Can't do anything if it fails. Ignore the return value. */
+		phy_power_off(csi2rx->dphy);
+		goto out;
+	}
+
+out:
+	if (got_pm)
+		phy_pm_runtime_put(csi2rx->dphy);
+
+	return ret;
+}
+
 static int csi2rx_start(struct csi2rx_priv *csi2rx)
 {
 	unsigned int i;
@@ -139,6 +256,17 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 	if (ret)
 		goto err_disable_pclk;
 
+	/* Enable DPHY clk and data lanes. */
+	if (csi2rx->dphy) {
+		reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
+		for (i = 0; i < csi2rx->num_lanes; i++) {
+			reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
+			reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
+		}
+
+		writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+	}
+
 	/*
 	 * Create a static mapping between the CSI virtual channels
 	 * and the output stream.
@@ -169,10 +297,21 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 	if (ret)
 		goto err_disable_pixclk;
 
+	if (csi2rx->dphy) {
+		ret = csi2rx_configure_external_dphy(csi2rx);
+		if (ret) {
+			dev_err(csi2rx->dev,
+				"Failed to configure external DPHY: %d\n", ret);
+			goto err_disable_sysclk;
+		}
+	}
+
 	clk_disable_unprepare(csi2rx->p_clk);
 
 	return 0;
 
+err_disable_sysclk:
+	clk_disable_unprepare(csi2rx->sys_clk);
 err_disable_pixclk:
 	for (; i > 0; i--)
 		clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
@@ -200,6 +339,13 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx)
 
 	if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
 		dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
+
+	if (csi2rx->dphy) {
+		writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+
+		if (phy_power_off(csi2rx->dphy))
+			dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
+	}
 }
 
 static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
@@ -306,15 +452,6 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 		return PTR_ERR(csi2rx->dphy);
 	}
 
-	/*
-	 * FIXME: Once we'll have external D-PHY support, the check
-	 * will need to be removed.
-	 */
-	if (csi2rx->dphy) {
-		dev_err(&pdev->dev, "External D-PHY not supported yet\n");
-		return -EINVAL;
-	}
-
 	clk_prepare_enable(csi2rx->p_clk);
 	dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG);
 	clk_disable_unprepare(csi2rx->p_clk);
@@ -339,7 +476,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 	 * FIXME: Once we'll have internal D-PHY support, the check
 	 * will need to be removed.
 	 */
-	if (csi2rx->has_internal_dphy) {
+	if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
 		dev_err(&pdev->dev, "Internal D-PHY not supported yet\n");
 		return -EINVAL;
 	}
@@ -460,6 +597,7 @@ static int csi2rx_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev,
 		 "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
 		 csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
+		 csi2rx->dphy ? "external" :
 		 csi2rx->has_internal_dphy ? "internal" : "no");
 
 	return 0;
-- 
2.30.0


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

* [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Some platforms like TI's J721E can have the CSI2RX paired with an
external DPHY. Add support to enable and configure the DPHY using the
generic PHY framework.

Get the pixel rate and bpp from the subdev and pass them on to the DPHY
along with the number of lanes. All other settings are left to their
default values.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
  calls to set PHY mode, etc. to make sure it is ready.

 drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
 1 file changed, 148 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index c68a3eac62cd..459326de2eff 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -30,6 +30,12 @@
 #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
 #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
 
+#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
+#define CSI2RX_DPHY_CL_RST			BIT(16)
+#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
+#define CSI2RX_DPHY_CL_EN			BIT(4)
+#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
+
 #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
@@ -54,6 +60,11 @@ enum csi2rx_pads {
 	CSI2RX_PAD_MAX,
 };
 
+struct csi2rx_fmt {
+	u32				code;
+	u8				bpp;
+};
+
 struct csi2rx_priv {
 	struct device			*dev;
 	unsigned int			count;
@@ -85,6 +96,52 @@ struct csi2rx_priv {
 	int				source_pad;
 };
 
+static const struct csi2rx_fmt formats[] = {
+	{
+		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
+		.bpp	= 16,
+	},
+	{
+		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
+		.bpp	= 16,
+	},
+};
+
+static u8 csi2rx_get_bpp(u32 code)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].code == code)
+			return formats[i].bpp;
+	}
+
+	return 0;
+}
+
+static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
+{
+	struct v4l2_ctrl *ctrl;
+
+	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
+			      V4L2_CID_PIXEL_RATE);
+	if (!ctrl) {
+		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
+			csi2rx->source_subdev->name);
+		return -EINVAL;
+	}
+
+	return v4l2_ctrl_g_ctrl_int64(ctrl);
+}
+
 static inline
 struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
 {
@@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
 	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
 }
 
+static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
+{
+	union phy_configure_opts opts = { };
+	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
+	struct v4l2_subdev_format sd_fmt;
+	s64 pixel_rate;
+	int ret;
+	u8 bpp;
+	bool got_pm = true;
+
+	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	sd_fmt.pad = 0;
+
+	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
+			       &sd_fmt);
+	if (ret)
+		return ret;
+
+	bpp = csi2rx_get_bpp(sd_fmt.format.code);
+	if (!bpp)
+		return -EINVAL;
+
+	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
+	if (pixel_rate < 0)
+		return pixel_rate;
+
+	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
+					       csi2rx->num_lanes, cfg);
+	if (ret)
+		return ret;
+
+	ret = phy_pm_runtime_get_sync(csi2rx->dphy);
+	if (ret == -ENOTSUPP)
+		got_pm = false;
+	else if (ret)
+		return ret;
+
+	ret = phy_set_mode_ext(csi2rx->dphy, PHY_MODE_MIPI_DPHY,
+			       PHY_MIPI_DPHY_SUBMODE_RX);
+	if (ret)
+		goto out;
+
+	ret = phy_power_on(csi2rx->dphy);
+	if (ret)
+		goto out;
+
+	ret = phy_configure(csi2rx->dphy, &opts);
+	if (ret) {
+		/* Can't do anything if it fails. Ignore the return value. */
+		phy_power_off(csi2rx->dphy);
+		goto out;
+	}
+
+out:
+	if (got_pm)
+		phy_pm_runtime_put(csi2rx->dphy);
+
+	return ret;
+}
+
 static int csi2rx_start(struct csi2rx_priv *csi2rx)
 {
 	unsigned int i;
@@ -139,6 +256,17 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 	if (ret)
 		goto err_disable_pclk;
 
+	/* Enable DPHY clk and data lanes. */
+	if (csi2rx->dphy) {
+		reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
+		for (i = 0; i < csi2rx->num_lanes; i++) {
+			reg |= CSI2RX_DPHY_DL_EN(csi2rx->lanes[i] - 1);
+			reg |= CSI2RX_DPHY_DL_RST(csi2rx->lanes[i] - 1);
+		}
+
+		writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+	}
+
 	/*
 	 * Create a static mapping between the CSI virtual channels
 	 * and the output stream.
@@ -169,10 +297,21 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 	if (ret)
 		goto err_disable_pixclk;
 
+	if (csi2rx->dphy) {
+		ret = csi2rx_configure_external_dphy(csi2rx);
+		if (ret) {
+			dev_err(csi2rx->dev,
+				"Failed to configure external DPHY: %d\n", ret);
+			goto err_disable_sysclk;
+		}
+	}
+
 	clk_disable_unprepare(csi2rx->p_clk);
 
 	return 0;
 
+err_disable_sysclk:
+	clk_disable_unprepare(csi2rx->sys_clk);
 err_disable_pixclk:
 	for (; i > 0; i--)
 		clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
@@ -200,6 +339,13 @@ static void csi2rx_stop(struct csi2rx_priv *csi2rx)
 
 	if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false))
 		dev_warn(csi2rx->dev, "Couldn't disable our subdev\n");
+
+	if (csi2rx->dphy) {
+		writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+
+		if (phy_power_off(csi2rx->dphy))
+			dev_warn(csi2rx->dev, "Couldn't power off DPHY\n");
+	}
 }
 
 static int csi2rx_s_stream(struct v4l2_subdev *subdev, int enable)
@@ -306,15 +452,6 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 		return PTR_ERR(csi2rx->dphy);
 	}
 
-	/*
-	 * FIXME: Once we'll have external D-PHY support, the check
-	 * will need to be removed.
-	 */
-	if (csi2rx->dphy) {
-		dev_err(&pdev->dev, "External D-PHY not supported yet\n");
-		return -EINVAL;
-	}
-
 	clk_prepare_enable(csi2rx->p_clk);
 	dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG);
 	clk_disable_unprepare(csi2rx->p_clk);
@@ -339,7 +476,7 @@ static int csi2rx_get_resources(struct csi2rx_priv *csi2rx,
 	 * FIXME: Once we'll have internal D-PHY support, the check
 	 * will need to be removed.
 	 */
-	if (csi2rx->has_internal_dphy) {
+	if (!csi2rx->dphy && csi2rx->has_internal_dphy) {
 		dev_err(&pdev->dev, "Internal D-PHY not supported yet\n");
 		return -EINVAL;
 	}
@@ -460,6 +597,7 @@ static int csi2rx_probe(struct platform_device *pdev)
 	dev_info(&pdev->dev,
 		 "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n",
 		 csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams,
+		 csi2rx->dphy ? "external" :
 		 csi2rx->has_internal_dphy ? "internal" : "no");
 
 	return 0;
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 07/18] media: cadence: csi2rx: Soft reset the streams before starting capture
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

This resets the stream state machines and FIFOs, giving them a clean
slate. On J721E if the streams are not reset before starting the
capture, the captured frame gets wrapped around vertically on every run
after the first.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 459326de2eff..80a50284e525 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -39,6 +39,7 @@
 #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
+#define CSI2RX_STREAM_CTRL_SOFT_RST			BIT(4)
 #define CSI2RX_STREAM_CTRL_START			BIT(0)
 
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
@@ -150,12 +151,22 @@ struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
 
 static void csi2rx_reset(struct csi2rx_priv *csi2rx)
 {
+	int i;
+
 	writel(CSI2RX_SOFT_RESET_PROTOCOL | CSI2RX_SOFT_RESET_FRONT,
 	       csi2rx->base + CSI2RX_SOFT_RESET_REG);
 
 	udelay(10);
 
 	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
+
+	/* Reset individual streams. */
+	for (i = 0; i < csi2rx->max_streams; i++) {
+		writel(CSI2RX_STREAM_CTRL_SOFT_RST,
+		       csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+		usleep_range(10, 20);
+		writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+	}
 }
 
 static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
-- 
2.30.0


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

* [PATCH v2 07/18] media: cadence: csi2rx: Soft reset the streams before starting capture
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

This resets the stream state machines and FIFOs, giving them a clean
slate. On J721E if the streams are not reset before starting the
capture, the captured frame gets wrapped around vertically on every run
after the first.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 459326de2eff..80a50284e525 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -39,6 +39,7 @@
 #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
+#define CSI2RX_STREAM_CTRL_SOFT_RST			BIT(4)
 #define CSI2RX_STREAM_CTRL_START			BIT(0)
 
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
@@ -150,12 +151,22 @@ struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
 
 static void csi2rx_reset(struct csi2rx_priv *csi2rx)
 {
+	int i;
+
 	writel(CSI2RX_SOFT_RESET_PROTOCOL | CSI2RX_SOFT_RESET_FRONT,
 	       csi2rx->base + CSI2RX_SOFT_RESET_REG);
 
 	udelay(10);
 
 	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
+
+	/* Reset individual streams. */
+	for (i = 0; i < csi2rx->max_streams; i++) {
+		writel(CSI2RX_STREAM_CTRL_SOFT_RST,
+		       csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+		usleep_range(10, 20);
+		writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+	}
 }
 
 static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 08/18] media: cadence: csi2rx: Set the STOP bit when stopping a stream
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The stream stop procedure says that the STOP bit should be set when the
stream is to be stopped, and then the ready bit in stream status
register polled to make sure the STOP operation is finished.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 80a50284e525..ecc43a618c34 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -40,8 +41,12 @@
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
 #define CSI2RX_STREAM_CTRL_SOFT_RST			BIT(4)
+#define CSI2RX_STREAM_CTRL_STOP				BIT(1)
 #define CSI2RX_STREAM_CTRL_START			BIT(0)
 
+#define CSI2RX_STREAM_STATUS_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x004)
+#define CSI2RX_STREAM_STATUS_RDY			BIT(31)
+
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
 #define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT		BIT(31)
 #define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n)		BIT((n) + 16)
@@ -336,12 +341,23 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 static void csi2rx_stop(struct csi2rx_priv *csi2rx)
 {
 	unsigned int i;
+	u32 val;
+	int ret;
 
 	clk_prepare_enable(csi2rx->p_clk);
 	clk_disable_unprepare(csi2rx->sys_clk);
 
 	for (i = 0; i < csi2rx->max_streams; i++) {
-		writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+		writel(CSI2RX_STREAM_CTRL_STOP,
+		       csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+
+		ret = readl_relaxed_poll_timeout(csi2rx->base +
+						 CSI2RX_STREAM_STATUS_REG(i),
+						 val,
+						 (val & CSI2RX_STREAM_STATUS_RDY),
+						 10, 10000);
+		if (ret)
+			dev_warn(csi2rx->dev, "Failed to stop stream%d\n", i);
 
 		clk_disable_unprepare(csi2rx->pixel_clk[i]);
 	}
-- 
2.30.0


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

* [PATCH v2 08/18] media: cadence: csi2rx: Set the STOP bit when stopping a stream
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The stream stop procedure says that the STOP bit should be set when the
stream is to be stopped, and then the ready bit in stream status
register polled to make sure the STOP operation is finished.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 80a50284e525..ecc43a618c34 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_graph.h>
@@ -40,8 +41,12 @@
 
 #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
 #define CSI2RX_STREAM_CTRL_SOFT_RST			BIT(4)
+#define CSI2RX_STREAM_CTRL_STOP				BIT(1)
 #define CSI2RX_STREAM_CTRL_START			BIT(0)
 
+#define CSI2RX_STREAM_STATUS_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x004)
+#define CSI2RX_STREAM_STATUS_RDY			BIT(31)
+
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
 #define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT		BIT(31)
 #define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n)		BIT((n) + 16)
@@ -336,12 +341,23 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 static void csi2rx_stop(struct csi2rx_priv *csi2rx)
 {
 	unsigned int i;
+	u32 val;
+	int ret;
 
 	clk_prepare_enable(csi2rx->p_clk);
 	clk_disable_unprepare(csi2rx->sys_clk);
 
 	for (i = 0; i < csi2rx->max_streams; i++) {
-		writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+		writel(CSI2RX_STREAM_CTRL_STOP,
+		       csi2rx->base + CSI2RX_STREAM_CTRL_REG(i));
+
+		ret = readl_relaxed_poll_timeout(csi2rx->base +
+						 CSI2RX_STREAM_STATUS_REG(i),
+						 val,
+						 (val & CSI2RX_STREAM_STATUS_RDY),
+						 10, 10000);
+		if (ret)
+			dev_warn(csi2rx->dev, "Failed to stop stream%d\n", i);
 
 		clk_disable_unprepare(csi2rx->pixel_clk[i]);
 	}
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 09/18] media: cadence: csi2rx: Fix stream data configuration
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:22   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Firstly, there is no VC_EN bit present in the STREAM_DATA_CFG register.
Bit 31 is part of the VL_SELECT field. Remove it completely.

Secondly, it makes little sense to enable ith virtual channel for ith
stream. Sure, there might be a use-case that demands it. But there might
also be a use case that demands all streams to use the 0th virtual
channel. Prefer this case over the former because it is less arbitrary
and also makes it very clear what the limitations of the current driver
is instead of giving a false impression that multiple virtual channels
are supported.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index ecc43a618c34..1df21f462f3c 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -48,7 +48,6 @@
 #define CSI2RX_STREAM_STATUS_RDY			BIT(31)
 
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
-#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT		BIT(31)
 #define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n)		BIT((n) + 16)
 
 #define CSI2RX_STREAM_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x00c)
@@ -301,8 +300,11 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 		writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
 		       csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
 
-		writel(CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT |
-		       CSI2RX_STREAM_DATA_CFG_VC_SELECT(i),
+		/*
+		 * Enable one virtual channel. When multiple virtual channels
+		 * are supported this will have to be changed.
+		 */
+		writel(CSI2RX_STREAM_DATA_CFG_VC_SELECT(0),
 		       csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));
 
 		writel(CSI2RX_STREAM_CTRL_START,
-- 
2.30.0


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

* [PATCH v2 09/18] media: cadence: csi2rx: Fix stream data configuration
@ 2021-05-26 15:22   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:22 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Firstly, there is no VC_EN bit present in the STREAM_DATA_CFG register.
Bit 31 is part of the VL_SELECT field. Remove it completely.

Secondly, it makes little sense to enable ith virtual channel for ith
stream. Sure, there might be a use-case that demands it. But there might
also be a use case that demands all streams to use the 0th virtual
channel. Prefer this case over the former because it is less arbitrary
and also makes it very clear what the limitations of the current driver
is instead of giving a false impression that multiple virtual channels
are supported.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index ecc43a618c34..1df21f462f3c 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -48,7 +48,6 @@
 #define CSI2RX_STREAM_STATUS_RDY			BIT(31)
 
 #define CSI2RX_STREAM_DATA_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x008)
-#define CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT		BIT(31)
 #define CSI2RX_STREAM_DATA_CFG_VC_SELECT(n)		BIT((n) + 16)
 
 #define CSI2RX_STREAM_CFG_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x00c)
@@ -301,8 +300,11 @@ static int csi2rx_start(struct csi2rx_priv *csi2rx)
 		writel(CSI2RX_STREAM_CFG_FIFO_MODE_LARGE_BUF,
 		       csi2rx->base + CSI2RX_STREAM_CFG_REG(i));
 
-		writel(CSI2RX_STREAM_DATA_CFG_EN_VC_SELECT |
-		       CSI2RX_STREAM_DATA_CFG_VC_SELECT(i),
+		/*
+		 * Enable one virtual channel. When multiple virtual channels
+		 * are supported this will have to be changed.
+		 */
+		writel(CSI2RX_STREAM_DATA_CFG_VC_SELECT(0),
 		       csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i));
 
 		writel(CSI2RX_STREAM_CTRL_START,
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The devnode can be used by media-ctl and other userspace tools to
perform configurations on the subdev. Without it, media-ctl returns
ENOENT when setting format on the sensor subdev.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 1df21f462f3c..49bed63d5faa 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
 	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
 		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
 				     csi2rx->pads);
-- 
2.30.0


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

* [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The devnode can be used by media-ctl and other userspace tools to
perform configurations on the subdev. Without it, media-ctl returns
ENOENT when setting format on the sensor subdev.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
---

(no changes since v1)

 drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
index 1df21f462f3c..49bed63d5faa 100644
--- a/drivers/media/platform/cadence/cdns-csi2rx.c
+++ b/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
 	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
 		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 
 	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
 				     csi2rx->pads);
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
have up to 32 threads but the current driver only supports using one. So
add an entry for that one thread.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Add all 64 threads, instead of having only the one thread being
  currently used by the driver.

 drivers/dma/ti/k3-psil-j721e.c | 73 ++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c
index 7580870ed746..34e3fc565a37 100644
--- a/drivers/dma/ti/k3-psil-j721e.c
+++ b/drivers/dma/ti/k3-psil-j721e.c
@@ -58,6 +58,14 @@
 		},					\
 	}
 
+#define PSIL_CSI2RX(x)					\
+	{						\
+		.thread_id = x,				\
+		.ep_config = {				\
+			.ep_type = PSIL_EP_NATIVE,	\
+		},					\
+	}
+
 /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
 static struct psil_ep j721e_src_ep_map[] = {
 	/* SA2UL */
@@ -138,6 +146,71 @@ static struct psil_ep j721e_src_ep_map[] = {
 	PSIL_PDMA_XY_PKT(0x4707),
 	PSIL_PDMA_XY_PKT(0x4708),
 	PSIL_PDMA_XY_PKT(0x4709),
+	/* CSI2RX */
+	PSIL_CSI2RX(0x4940),
+	PSIL_CSI2RX(0x4941),
+	PSIL_CSI2RX(0x4942),
+	PSIL_CSI2RX(0x4943),
+	PSIL_CSI2RX(0x4944),
+	PSIL_CSI2RX(0x4945),
+	PSIL_CSI2RX(0x4946),
+	PSIL_CSI2RX(0x4947),
+	PSIL_CSI2RX(0x4948),
+	PSIL_CSI2RX(0x4949),
+	PSIL_CSI2RX(0x494a),
+	PSIL_CSI2RX(0x494b),
+	PSIL_CSI2RX(0x494c),
+	PSIL_CSI2RX(0x494d),
+	PSIL_CSI2RX(0x494e),
+	PSIL_CSI2RX(0x494f),
+	PSIL_CSI2RX(0x4950),
+	PSIL_CSI2RX(0x4951),
+	PSIL_CSI2RX(0x4952),
+	PSIL_CSI2RX(0x4953),
+	PSIL_CSI2RX(0x4954),
+	PSIL_CSI2RX(0x4955),
+	PSIL_CSI2RX(0x4956),
+	PSIL_CSI2RX(0x4957),
+	PSIL_CSI2RX(0x4958),
+	PSIL_CSI2RX(0x4959),
+	PSIL_CSI2RX(0x495a),
+	PSIL_CSI2RX(0x495b),
+	PSIL_CSI2RX(0x495c),
+	PSIL_CSI2RX(0x495d),
+	PSIL_CSI2RX(0x495e),
+	PSIL_CSI2RX(0x495f),
+	PSIL_CSI2RX(0x4960),
+	PSIL_CSI2RX(0x4961),
+	PSIL_CSI2RX(0x4962),
+	PSIL_CSI2RX(0x4963),
+	PSIL_CSI2RX(0x4964),
+	PSIL_CSI2RX(0x4965),
+	PSIL_CSI2RX(0x4966),
+	PSIL_CSI2RX(0x4967),
+	PSIL_CSI2RX(0x4968),
+	PSIL_CSI2RX(0x4969),
+	PSIL_CSI2RX(0x496a),
+	PSIL_CSI2RX(0x496b),
+	PSIL_CSI2RX(0x496c),
+	PSIL_CSI2RX(0x496d),
+	PSIL_CSI2RX(0x496e),
+	PSIL_CSI2RX(0x496f),
+	PSIL_CSI2RX(0x4970),
+	PSIL_CSI2RX(0x4971),
+	PSIL_CSI2RX(0x4972),
+	PSIL_CSI2RX(0x4973),
+	PSIL_CSI2RX(0x4974),
+	PSIL_CSI2RX(0x4975),
+	PSIL_CSI2RX(0x4976),
+	PSIL_CSI2RX(0x4977),
+	PSIL_CSI2RX(0x4978),
+	PSIL_CSI2RX(0x4979),
+	PSIL_CSI2RX(0x497a),
+	PSIL_CSI2RX(0x497b),
+	PSIL_CSI2RX(0x497c),
+	PSIL_CSI2RX(0x497d),
+	PSIL_CSI2RX(0x497e),
+	PSIL_CSI2RX(0x497f),
 	/* CPSW9 */
 	PSIL_ETHERNET(0x4a00),
 	/* CPSW0 */
-- 
2.30.0


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

* [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
have up to 32 threads but the current driver only supports using one. So
add an entry for that one thread.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Add all 64 threads, instead of having only the one thread being
  currently used by the driver.

 drivers/dma/ti/k3-psil-j721e.c | 73 ++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c
index 7580870ed746..34e3fc565a37 100644
--- a/drivers/dma/ti/k3-psil-j721e.c
+++ b/drivers/dma/ti/k3-psil-j721e.c
@@ -58,6 +58,14 @@
 		},					\
 	}
 
+#define PSIL_CSI2RX(x)					\
+	{						\
+		.thread_id = x,				\
+		.ep_config = {				\
+			.ep_type = PSIL_EP_NATIVE,	\
+		},					\
+	}
+
 /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
 static struct psil_ep j721e_src_ep_map[] = {
 	/* SA2UL */
@@ -138,6 +146,71 @@ static struct psil_ep j721e_src_ep_map[] = {
 	PSIL_PDMA_XY_PKT(0x4707),
 	PSIL_PDMA_XY_PKT(0x4708),
 	PSIL_PDMA_XY_PKT(0x4709),
+	/* CSI2RX */
+	PSIL_CSI2RX(0x4940),
+	PSIL_CSI2RX(0x4941),
+	PSIL_CSI2RX(0x4942),
+	PSIL_CSI2RX(0x4943),
+	PSIL_CSI2RX(0x4944),
+	PSIL_CSI2RX(0x4945),
+	PSIL_CSI2RX(0x4946),
+	PSIL_CSI2RX(0x4947),
+	PSIL_CSI2RX(0x4948),
+	PSIL_CSI2RX(0x4949),
+	PSIL_CSI2RX(0x494a),
+	PSIL_CSI2RX(0x494b),
+	PSIL_CSI2RX(0x494c),
+	PSIL_CSI2RX(0x494d),
+	PSIL_CSI2RX(0x494e),
+	PSIL_CSI2RX(0x494f),
+	PSIL_CSI2RX(0x4950),
+	PSIL_CSI2RX(0x4951),
+	PSIL_CSI2RX(0x4952),
+	PSIL_CSI2RX(0x4953),
+	PSIL_CSI2RX(0x4954),
+	PSIL_CSI2RX(0x4955),
+	PSIL_CSI2RX(0x4956),
+	PSIL_CSI2RX(0x4957),
+	PSIL_CSI2RX(0x4958),
+	PSIL_CSI2RX(0x4959),
+	PSIL_CSI2RX(0x495a),
+	PSIL_CSI2RX(0x495b),
+	PSIL_CSI2RX(0x495c),
+	PSIL_CSI2RX(0x495d),
+	PSIL_CSI2RX(0x495e),
+	PSIL_CSI2RX(0x495f),
+	PSIL_CSI2RX(0x4960),
+	PSIL_CSI2RX(0x4961),
+	PSIL_CSI2RX(0x4962),
+	PSIL_CSI2RX(0x4963),
+	PSIL_CSI2RX(0x4964),
+	PSIL_CSI2RX(0x4965),
+	PSIL_CSI2RX(0x4966),
+	PSIL_CSI2RX(0x4967),
+	PSIL_CSI2RX(0x4968),
+	PSIL_CSI2RX(0x4969),
+	PSIL_CSI2RX(0x496a),
+	PSIL_CSI2RX(0x496b),
+	PSIL_CSI2RX(0x496c),
+	PSIL_CSI2RX(0x496d),
+	PSIL_CSI2RX(0x496e),
+	PSIL_CSI2RX(0x496f),
+	PSIL_CSI2RX(0x4970),
+	PSIL_CSI2RX(0x4971),
+	PSIL_CSI2RX(0x4972),
+	PSIL_CSI2RX(0x4973),
+	PSIL_CSI2RX(0x4974),
+	PSIL_CSI2RX(0x4975),
+	PSIL_CSI2RX(0x4976),
+	PSIL_CSI2RX(0x4977),
+	PSIL_CSI2RX(0x4978),
+	PSIL_CSI2RX(0x4979),
+	PSIL_CSI2RX(0x497a),
+	PSIL_CSI2RX(0x497b),
+	PSIL_CSI2RX(0x497c),
+	PSIL_CSI2RX(0x497d),
+	PSIL_CSI2RX(0x497e),
+	PSIL_CSI2RX(0x497f),
 	/* CPSW9 */
 	PSIL_ETHERNET(0x4a00),
 	/* CPSW0 */
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 12/18] media: Re-structure TI platform drivers
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The ti-vpe/ sub-directory does not only contain the VPE-specific things.
It also contains the CAL driver, which is a completely different
subsystem. This is also not a good place to add new drivers for other TI
platforms since they will all get mixed up.

Separate the VPE and CAL parts into different sub-directories and rename
the ti-vpe/ sub-directory to ti/. This is now the place where new TI
platform drivers can be added.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---
Compile tested only. There should be no functional change.

Changes in v2:
- New in v2.

 MAINTAINERS                                              | 3 ++-
 drivers/media/platform/Makefile                          | 2 +-
 drivers/media/platform/ti/Makefile                       | 3 +++
 drivers/media/platform/ti/cal/Makefile                   | 3 +++
 drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c    | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal.c          | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal.h          | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h     | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/Makefile       | 4 ----
 drivers/media/platform/{ti-vpe => ti/vpe}/csc.c          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/csc.h          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc.c           | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc.h           | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h     | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c        | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h        | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h   | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h     | 0
 20 files changed, 9 insertions(+), 6 deletions(-)
 create mode 100644 drivers/media/platform/ti/Makefile
 create mode 100644 drivers/media/platform/ti/cal/Makefile
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/Makefile (78%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 710203d794d7..607dd5e18e7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18449,7 +18449,8 @@ W:	http://linuxtv.org/
 Q:	http://patchwork.linuxtv.org/project/linux-media/list/
 F:	Documentation/devicetree/bindings/media/ti,cal.yaml
 F:	Documentation/devicetree/bindings/media/ti,vpe.yaml
-F:	drivers/media/platform/ti-vpe/
+F:	drivers/media/platform/ti/cal/
+F:	drivers/media/platform/ti/vpe/
 
 TI WILINK WIRELESS DRIVERS
 L:	linux-wireless@vger.kernel.org
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index eedc14aafb32..5ddfa5bc02e1 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_VIDEO_PXA27x)	+= pxa_camera.o
 
 obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
 
-obj-y	+= ti-vpe/
+obj-y	+= ti/
 
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)		+= mx2_emmaprp.o
 obj-$(CONFIG_VIDEO_CODA)		+= coda/
diff --git a/drivers/media/platform/ti/Makefile b/drivers/media/platform/ti/Makefile
new file mode 100644
index 000000000000..bbc737ccbbea
--- /dev/null
+++ b/drivers/media/platform/ti/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += cal/
+obj-y += vpe/
diff --git a/drivers/media/platform/ti/cal/Makefile b/drivers/media/platform/ti/cal/Makefile
new file mode 100644
index 000000000000..45ac35585f0b
--- /dev/null
+++ b/drivers/media/platform/ti/cal/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
+ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal-camerarx.c
rename to drivers/media/platform/ti/cal/cal-camerarx.c
diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal-video.c
rename to drivers/media/platform/ti/cal/cal-video.c
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti/cal/cal.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal.c
rename to drivers/media/platform/ti/cal/cal.c
diff --git a/drivers/media/platform/ti-vpe/cal.h b/drivers/media/platform/ti/cal/cal.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal.h
rename to drivers/media/platform/ti/cal/cal.h
diff --git a/drivers/media/platform/ti-vpe/cal_regs.h b/drivers/media/platform/ti/cal/cal_regs.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal_regs.h
rename to drivers/media/platform/ti/cal/cal_regs.h
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti/vpe/Makefile
similarity index 78%
rename from drivers/media/platform/ti-vpe/Makefile
rename to drivers/media/platform/ti/vpe/Makefile
index ad624056e039..3fadfe084f87 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti/vpe/Makefile
@@ -10,7 +10,3 @@ ti-sc-y := sc.o
 ti-csc-y := csc.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
-
-obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
-
-ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti/vpe/csc.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/csc.c
rename to drivers/media/platform/ti/vpe/csc.c
diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti/vpe/csc.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/csc.h
rename to drivers/media/platform/ti/vpe/csc.h
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti/vpe/sc.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc.c
rename to drivers/media/platform/ti/vpe/sc.c
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti/vpe/sc.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc.h
rename to drivers/media/platform/ti/vpe/sc.h
diff --git a/drivers/media/platform/ti-vpe/sc_coeff.h b/drivers/media/platform/ti/vpe/sc_coeff.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc_coeff.h
rename to drivers/media/platform/ti/vpe/sc_coeff.h
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti/vpe/vpdma.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma.c
rename to drivers/media/platform/ti/vpe/vpdma.c
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti/vpe/vpdma.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma.h
rename to drivers/media/platform/ti/vpe/vpdma.h
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti/vpe/vpdma_priv.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma_priv.h
rename to drivers/media/platform/ti/vpe/vpdma_priv.h
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti/vpe/vpe.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpe.c
rename to drivers/media/platform/ti/vpe/vpe.c
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti/vpe/vpe_regs.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpe_regs.h
rename to drivers/media/platform/ti/vpe/vpe_regs.h
-- 
2.30.0


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

* [PATCH v2 12/18] media: Re-structure TI platform drivers
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The ti-vpe/ sub-directory does not only contain the VPE-specific things.
It also contains the CAL driver, which is a completely different
subsystem. This is also not a good place to add new drivers for other TI
platforms since they will all get mixed up.

Separate the VPE and CAL parts into different sub-directories and rename
the ti-vpe/ sub-directory to ti/. This is now the place where new TI
platform drivers can be added.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---
Compile tested only. There should be no functional change.

Changes in v2:
- New in v2.

 MAINTAINERS                                              | 3 ++-
 drivers/media/platform/Makefile                          | 2 +-
 drivers/media/platform/ti/Makefile                       | 3 +++
 drivers/media/platform/ti/cal/Makefile                   | 3 +++
 drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c    | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal.c          | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal.h          | 0
 drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h     | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/Makefile       | 4 ----
 drivers/media/platform/{ti-vpe => ti/vpe}/csc.c          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/csc.h          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc.c           | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc.h           | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h     | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c        | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h        | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h   | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c          | 0
 drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h     | 0
 20 files changed, 9 insertions(+), 6 deletions(-)
 create mode 100644 drivers/media/platform/ti/Makefile
 create mode 100644 drivers/media/platform/ti/cal/Makefile
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-camerarx.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal-video.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/cal}/cal_regs.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/Makefile (78%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/csc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/sc_coeff.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpdma_priv.h (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe.c (100%)
 rename drivers/media/platform/{ti-vpe => ti/vpe}/vpe_regs.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 710203d794d7..607dd5e18e7d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18449,7 +18449,8 @@ W:	http://linuxtv.org/
 Q:	http://patchwork.linuxtv.org/project/linux-media/list/
 F:	Documentation/devicetree/bindings/media/ti,cal.yaml
 F:	Documentation/devicetree/bindings/media/ti,vpe.yaml
-F:	drivers/media/platform/ti-vpe/
+F:	drivers/media/platform/ti/cal/
+F:	drivers/media/platform/ti/vpe/
 
 TI WILINK WIRELESS DRIVERS
 L:	linux-wireless@vger.kernel.org
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index eedc14aafb32..5ddfa5bc02e1 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_VIDEO_PXA27x)	+= pxa_camera.o
 
 obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
 
-obj-y	+= ti-vpe/
+obj-y	+= ti/
 
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP)		+= mx2_emmaprp.o
 obj-$(CONFIG_VIDEO_CODA)		+= coda/
diff --git a/drivers/media/platform/ti/Makefile b/drivers/media/platform/ti/Makefile
new file mode 100644
index 000000000000..bbc737ccbbea
--- /dev/null
+++ b/drivers/media/platform/ti/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-y += cal/
+obj-y += vpe/
diff --git a/drivers/media/platform/ti/cal/Makefile b/drivers/media/platform/ti/cal/Makefile
new file mode 100644
index 000000000000..45ac35585f0b
--- /dev/null
+++ b/drivers/media/platform/ti/cal/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
+ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti-vpe/cal-camerarx.c b/drivers/media/platform/ti/cal/cal-camerarx.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal-camerarx.c
rename to drivers/media/platform/ti/cal/cal-camerarx.c
diff --git a/drivers/media/platform/ti-vpe/cal-video.c b/drivers/media/platform/ti/cal/cal-video.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal-video.c
rename to drivers/media/platform/ti/cal/cal-video.c
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti/cal/cal.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal.c
rename to drivers/media/platform/ti/cal/cal.c
diff --git a/drivers/media/platform/ti-vpe/cal.h b/drivers/media/platform/ti/cal/cal.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal.h
rename to drivers/media/platform/ti/cal/cal.h
diff --git a/drivers/media/platform/ti-vpe/cal_regs.h b/drivers/media/platform/ti/cal/cal_regs.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/cal_regs.h
rename to drivers/media/platform/ti/cal/cal_regs.h
diff --git a/drivers/media/platform/ti-vpe/Makefile b/drivers/media/platform/ti/vpe/Makefile
similarity index 78%
rename from drivers/media/platform/ti-vpe/Makefile
rename to drivers/media/platform/ti/vpe/Makefile
index ad624056e039..3fadfe084f87 100644
--- a/drivers/media/platform/ti-vpe/Makefile
+++ b/drivers/media/platform/ti/vpe/Makefile
@@ -10,7 +10,3 @@ ti-sc-y := sc.o
 ti-csc-y := csc.o
 
 ccflags-$(CONFIG_VIDEO_TI_VPE_DEBUG) += -DDEBUG
-
-obj-$(CONFIG_VIDEO_TI_CAL) += ti-cal.o
-
-ti-cal-y := cal.o cal-camerarx.o cal-video.o
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti/vpe/csc.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/csc.c
rename to drivers/media/platform/ti/vpe/csc.c
diff --git a/drivers/media/platform/ti-vpe/csc.h b/drivers/media/platform/ti/vpe/csc.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/csc.h
rename to drivers/media/platform/ti/vpe/csc.h
diff --git a/drivers/media/platform/ti-vpe/sc.c b/drivers/media/platform/ti/vpe/sc.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc.c
rename to drivers/media/platform/ti/vpe/sc.c
diff --git a/drivers/media/platform/ti-vpe/sc.h b/drivers/media/platform/ti/vpe/sc.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc.h
rename to drivers/media/platform/ti/vpe/sc.h
diff --git a/drivers/media/platform/ti-vpe/sc_coeff.h b/drivers/media/platform/ti/vpe/sc_coeff.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/sc_coeff.h
rename to drivers/media/platform/ti/vpe/sc_coeff.h
diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti/vpe/vpdma.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma.c
rename to drivers/media/platform/ti/vpe/vpdma.c
diff --git a/drivers/media/platform/ti-vpe/vpdma.h b/drivers/media/platform/ti/vpe/vpdma.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma.h
rename to drivers/media/platform/ti/vpe/vpdma.h
diff --git a/drivers/media/platform/ti-vpe/vpdma_priv.h b/drivers/media/platform/ti/vpe/vpdma_priv.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpdma_priv.h
rename to drivers/media/platform/ti/vpe/vpdma_priv.h
diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti/vpe/vpe.c
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpe.c
rename to drivers/media/platform/ti/vpe/vpe.c
diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti/vpe/vpe_regs.h
similarity index 100%
rename from drivers/media/platform/ti-vpe/vpe_regs.h
rename to drivers/media/platform/ti/vpe/vpe_regs.h
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
capture over a CSI-2 bus.

The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
called the SHIM layer. It takes in data from stream 0, repacks it, and
sends it to memory over PSI-L DMA.

This driver acts as the "front end" to V4L2 client applications. It
implements the required ioctls and buffer operations, passes the
necessary calls on to the bridge, programs the SHIM layer, and performs
DMA via the dmaengine API to finally return the data to a buffer
supplied by the application.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Use dmaengine_get_dma_device() instead of directly accessing
  dma->device->dev.
- Do not set dst_addr_width when configuring slave DMA.
- Move to a separate subdir and rename to j721e-csi2rx.c
- Convert compatible to ti,j721e-csi2rx.
- Move to use Media Controller centric APIs.
- Improve cleanup in probe when one of the steps fails.
- Add colorspace to formats database.
- Set hw_revision on media_device.
- Move video device initialization to probe time instead of register time.

 MAINTAINERS                                   |   6 +
 drivers/media/platform/Kconfig                |  12 +
 drivers/media/platform/ti/Makefile            |   1 +
 .../media/platform/ti/j721e-csi2rx/Makefile   |   2 +
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 884 ++++++++++++++++++
 5 files changed, 905 insertions(+)
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/Makefile
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 607dd5e18e7d..2cf140a02063 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18332,6 +18332,12 @@ S:	Odd Fixes
 F:	drivers/clk/ti/
 F:	include/linux/clk/ti.h
 
+TI J721E CSI2RX DRIVER
+M:	Pratyush Yadav <p.yadav@ti.com>
+L:	linux-media@vger.kernel.org
+S:	Supported
+F:	drivers/media/platform/ti/j721e-csi2rx/
+
 TI DAVINCI MACHINE SUPPORT
 M:	Sekhar Nori <nsekhar@ti.com>
 R:	Bartosz Golaszewski <bgolaszewski@baylibre.com>
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 157c924686e4..732a942b3b29 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -200,6 +200,18 @@ config VIDEO_TI_CAL_MC
 
 endif # VIDEO_TI_CAL
 
+config VIDEO_TI_J721E_CSI2RX
+	tristate "TI J721E CSI2RX wrapper layer driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_SUPPORT && MEDIA_CONTROLLER
+	depends on PHY_CADENCE_DPHY && VIDEO_CADENCE_CSI2RX
+	depends on ARCH_K3 || COMPILE_TEST
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  Support for TI CSI2RX wrapper layer. This just enables the wrapper driver.
+	  The Cadence CSI2RX bridge driver needs to be enabled separately.
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/ti/Makefile b/drivers/media/platform/ti/Makefile
index bbc737ccbbea..17c9cfb74f66 100644
--- a/drivers/media/platform/ti/Makefile
+++ b/drivers/media/platform/ti/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y += cal/
 obj-y += vpe/
+obj-y += j721e-csi2rx/
diff --git a/drivers/media/platform/ti/j721e-csi2rx/Makefile b/drivers/media/platform/ti/j721e-csi2rx/Makefile
new file mode 100644
index 000000000000..377afc1d6280
--- /dev/null
+++ b/drivers/media/platform/ti/j721e-csi2rx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_J721E_CSI2RX) += j721e-csi2rx.o
diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
new file mode 100644
index 000000000000..b8d31a0af6d8
--- /dev/null
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -0,0 +1,884 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI CSI2 RX driver.
+ *
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Author: Pratyush Yadav <p.yadav@ti.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/of_platform.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define TI_CSI2RX_MODULE_NAME		"j721e-csi2rx"
+
+#define SHIM_CNTL			0x10
+#define SHIM_CNTL_PIX_RST		BIT(0)
+
+#define SHIM_DMACNTX			0x20
+#define SHIM_DMACNTX_EN			BIT(31)
+#define SHIM_DMACNTX_YUV422		GENMASK(27, 26)
+#define SHIM_DMACNTX_FMT		GENMASK(5, 0)
+#define SHIM_DMACNTX_UYVY		0
+#define SHIM_DMACNTX_VYUY		1
+#define SHIM_DMACNTX_YUYV		2
+#define SHIM_DMACNTX_YVYU		3
+
+#define SHIM_PSI_CFG0			0x24
+#define SHIM_PSI_CFG0_SRC_TAG		GENMASK(15, 0)
+#define SHIM_PSI_CFG0_DST_TAG		GENMASK(31, 15)
+
+#define CSI_DF_YUV420			0x18
+#define CSI_DF_YUV422			0x1e
+#define CSI_DF_RGB444			0x20
+#define CSI_DF_RGB888			0x24
+
+#define PSIL_WORD_SIZE_BYTES		16
+
+struct ti_csi2rx_fmt {
+	u32				fourcc;	/* Four character code. */
+	u32				code;	/* Mbus code. */
+	enum v4l2_colorspace		colorspace;
+	u32				csi_df;	/* CSI Data format. */
+	u8				bpp;	/* Bits per pixel. */
+};
+
+struct ti_csi2rx_buffer {
+	/* Common v4l2 buffer. Must be first. */
+	struct vb2_v4l2_buffer		vb;
+	struct list_head		list;
+};
+
+struct ti_csi2rx_dmaq {
+	struct list_head		list;
+};
+
+struct ti_csi2rx_dev {
+	struct device			*dev;
+	void __iomem			*shim;
+	struct v4l2_device		v4l2_dev;
+	struct video_device		vdev;
+	struct media_device		mdev;
+	struct media_pipeline		pipe;
+	struct media_pad		pad;
+	struct v4l2_async_notifier	notifier;
+	struct v4l2_subdev		*subdev;
+	struct vb2_queue		vidq;
+	struct mutex			mutex; /* To serialize ioctls. */
+	struct v4l2_format		v_fmt;
+	struct dma_chan			*dma;
+	struct ti_csi2rx_dmaq		dmaq;
+	u32				sequence;
+};
+
+static const struct ti_csi2rx_fmt formats[] = {
+	{
+		.fourcc			= V4L2_PIX_FMT_YUYV,
+		.code			= MEDIA_BUS_FMT_YUYV8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_UYVY,
+		.code			= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_YVYU,
+		.code			= MEDIA_BUS_FMT_YVYU8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_VYUY,
+		.code			= MEDIA_BUS_FMT_VYUY8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	},
+
+	/* More formats can be supported but they are not listed for now. */
+};
+
+static const unsigned int num_formats = ARRAY_SIZE(formats);
+
+/* Forward declaration needed by ti_csi2rx_dma_callback. */
+static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+			       struct ti_csi2rx_buffer *buf);
+
+static const struct ti_csi2rx_fmt *find_format_by_pix(u32 pixelformat)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_formats; i++) {
+		if (formats[i].fourcc == pixelformat)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static void ti_csi2rx_fill_fmt(const struct ti_csi2rx_fmt *csi_fmt,
+			       struct v4l2_format *v4l2_fmt)
+{
+	struct v4l2_pix_format *pix = &v4l2_fmt->fmt.pix;
+	u32 bpl;
+
+	v4l2_fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	pix->pixelformat = csi_fmt->fourcc;
+	pix->colorspace = csi_fmt->colorspace;
+	pix->sizeimage = pix->height * pix->width * (csi_fmt->bpp / 8);
+
+	bpl = (pix->width * ALIGN(csi_fmt->bpp, 8)) >> 3;
+	pix->bytesperline = ALIGN(bpl, 16);
+}
+
+static int ti_csi2rx_querycap(struct file *file, void *priv,
+			      struct v4l2_capability *cap)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+
+	strscpy(cap->driver, TI_CSI2RX_MODULE_NAME, sizeof(cap->driver));
+	strscpy(cap->card, TI_CSI2RX_MODULE_NAME, sizeof(cap->card));
+
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+		 dev_name(csi->dev));
+
+	return 0;
+}
+
+static int ti_csi2rx_enum_fmt_vid_cap(struct file *file, void *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	if (f->index >= num_formats)
+		return -EINVAL;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	f->pixelformat = formats[f->index].fourcc;
+
+	return 0;
+}
+
+static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *prov,
+				   struct v4l2_format *f)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+
+	*f = csi->v_fmt;
+
+	return 0;
+}
+
+static int ti_csi2rx_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	const struct ti_csi2rx_fmt *fmt;
+
+	/*
+	 * Default to the first format if the requested pixel format code isn't
+	 * supported.
+	 */
+	fmt = find_format_by_pix(f->fmt.pix.pixelformat);
+	if (!fmt)
+		fmt = &formats[0];
+
+	if (f->fmt.pix.field == V4L2_FIELD_ANY)
+		f->fmt.pix.field = V4L2_FIELD_NONE;
+
+	if (f->fmt.pix.field != V4L2_FIELD_NONE)
+		return -EINVAL;
+
+	ti_csi2rx_fill_fmt(fmt, f);
+
+	return 0;
+}
+
+static int ti_csi2rx_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+	struct vb2_queue *q = &csi->vidq;
+	int ret;
+
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	ret = ti_csi2rx_try_fmt_vid_cap(file, priv, f);
+	if (ret < 0)
+		return ret;
+
+	csi->v_fmt = *f;
+
+	return 0;
+}
+
+static int ti_csi2rx_enum_framesizes(struct file *file, void *fh,
+				     struct v4l2_frmsizeenum *fsize)
+{
+	const struct ti_csi2rx_fmt *fmt;
+	u8 bpp;
+
+	fmt = find_format_by_pix(fsize->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	bpp = ALIGN(fmt->bpp, 8);
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = PSIL_WORD_SIZE_BYTES * 8 / bpp;
+	fsize->stepwise.max_width = UINT_MAX;
+	fsize->stepwise.step_width = PSIL_WORD_SIZE_BYTES * 8 / bpp;
+	fsize->stepwise.min_height = 1;
+	fsize->stepwise.max_height = UINT_MAX;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops csi_ioctl_ops = {
+	.vidioc_querycap      = ti_csi2rx_querycap,
+	.vidioc_enum_fmt_vid_cap = ti_csi2rx_enum_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = ti_csi2rx_try_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = ti_csi2rx_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = ti_csi2rx_s_fmt_vid_cap,
+	.vidioc_enum_framesizes = ti_csi2rx_enum_framesizes,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs   = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_expbuf        = vb2_ioctl_expbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
+};
+
+static const struct v4l2_file_operations csi_fops = {
+	.owner = THIS_MODULE,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.read = vb2_fop_read,
+	.poll = vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap = vb2_fop_mmap,
+};
+
+static int ti_csi2rx_video_register(struct ti_csi2rx_dev *csi)
+{
+	struct video_device *vdev = &csi->vdev;
+	int ret, src_pad;
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret)
+		return ret;
+
+	src_pad = media_entity_get_fwnode_pad(&csi->subdev->entity,
+					      csi->subdev->fwnode,
+					      MEDIA_PAD_FL_SOURCE);
+	if (src_pad < 0) {
+		dev_err(csi->dev, "Couldn't find source pad for subdev\n");
+		return src_pad;
+	}
+
+	ret = media_create_pad_link(&csi->subdev->entity, src_pad,
+				    &vdev->entity, 0,
+				    MEDIA_LNK_FL_IMMUTABLE |
+				    MEDIA_LNK_FL_ENABLED);
+	if (ret) {
+		video_unregister_device(vdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int csi_async_notifier_bound(struct v4l2_async_notifier *notifier,
+				    struct v4l2_subdev *subdev,
+				    struct v4l2_async_subdev *asd)
+{
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev);
+
+	csi->subdev = subdev;
+
+	return 0;
+}
+
+static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev);
+	int ret;
+
+	ret = ti_csi2rx_video_register(csi);
+	if (ret)
+		return ret;
+
+	return v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations csi_async_notifier_ops = {
+	.bound = csi_async_notifier_bound,
+	.complete = csi_async_notifier_complete,
+};
+
+static int ti_csi2rx_init_subdev(struct ti_csi2rx_dev *csi)
+{
+	struct fwnode_handle *fwnode;
+	struct v4l2_async_subdev *asd;
+	struct device_node *node;
+	int ret;
+
+	node = of_get_child_by_name(csi->dev->of_node, "csi-bridge");
+	if (!node)
+		return -EINVAL;
+
+	fwnode = of_fwnode_handle(node);
+	of_node_put(node);
+	if (!fwnode)
+		return -EINVAL;
+
+	v4l2_async_notifier_init(&csi->notifier);
+	csi->notifier.ops = &csi_async_notifier_ops;
+
+	asd = v4l2_async_notifier_add_fwnode_subdev(&csi->notifier, fwnode,
+						    struct v4l2_async_subdev);
+	if (IS_ERR(asd)) {
+		v4l2_async_notifier_cleanup(&csi->notifier);
+		return PTR_ERR(asd);
+	}
+
+	ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier);
+	if (ret) {
+		v4l2_async_notifier_cleanup(&csi->notifier);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
+{
+	const struct ti_csi2rx_fmt *fmt;
+	unsigned int reg;
+
+	fmt = find_format_by_pix(csi->v_fmt.fmt.pix.pixelformat);
+	if (!fmt) {
+		dev_err(csi->dev, "Unknown format\n");
+		return;
+	}
+
+	/* De-assert the pixel interface reset. */
+	reg = SHIM_CNTL_PIX_RST;
+	writel(reg, csi->shim + SHIM_CNTL);
+
+	reg = SHIM_DMACNTX_EN;
+	reg |= FIELD_PREP(SHIM_DMACNTX_FMT, fmt->csi_df);
+
+	/*
+	 * Using the values from the documentation gives incorrect ordering for
+	 * the luma and chroma components. In practice, the "reverse" format
+	 * gives the correct image. So for example, if the image is in UYVY, the
+	 * reverse would be YVYU.
+	 */
+	switch (fmt->fourcc) {
+	case V4L2_PIX_FMT_UYVY:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_YVYU);
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_YUYV);
+		break;
+	case V4L2_PIX_FMT_YUYV:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_VYUY);
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_UYVY);
+		break;
+	default:
+		/* Ignore if not YUV 4:2:2 */
+		break;
+	}
+
+	writel(reg, csi->shim + SHIM_DMACNTX);
+
+	reg = FIELD_PREP(SHIM_PSI_CFG0_SRC_TAG, 0) |
+	      FIELD_PREP(SHIM_PSI_CFG0_DST_TAG, 1);
+	writel(reg, csi->shim + SHIM_PSI_CFG0);
+}
+
+static void ti_csi2rx_dma_callback(void *param)
+{
+	struct ti_csi2rx_dev *csi = param;
+	struct ti_csi2rx_buffer *buf;
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+	list_del(&buf->list);
+
+	buf->vb.vb2_buf.timestamp = ktime_get_ns();
+	buf->vb.sequence = csi->sequence++;
+
+	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+	/* If there are more buffers to process then start their transfer. */
+	if (list_empty(&dmaq->list))
+		return;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+
+	if (ti_csi2rx_start_dma(csi, buf))
+		dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");
+}
+
+static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+			       struct ti_csi2rx_buffer *buf)
+{
+	unsigned long addr;
+	struct dma_async_tx_descriptor *desc;
+	size_t len = csi->v_fmt.fmt.pix.sizeimage;
+	dma_cookie_t cookie;
+	int ret = 0;
+
+	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+	desc = dmaengine_prep_slave_single(csi->dma, addr, len, DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EIO;
+
+	desc->callback = ti_csi2rx_dma_callback;
+	desc->callback_param = csi;
+
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret)
+		return ret;
+
+	dma_async_issue_pending(csi->dma);
+
+	return 0;
+}
+
+static int ti_csi2rx_queue_setup(struct vb2_queue *q, unsigned int *nbuffers,
+				 unsigned int *nplanes, unsigned int sizes[],
+				 struct device *alloc_devs[])
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(q);
+	unsigned int size = csi->v_fmt.fmt.pix.sizeimage;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+		size = sizes[0];
+	}
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	return 0;
+}
+
+static int ti_csi2rx_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = csi->v_fmt.fmt.pix.sizeimage;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(csi->dev, "Data will not fit into plane\n");
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, size);
+	return 0;
+}
+
+static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
+	struct ti_csi2rx_buffer *buf;
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+
+	buf = container_of(vb, struct ti_csi2rx_buffer, vb.vb2_buf);
+
+	list_add_tail(&buf->list, &dmaq->list);
+}
+
+/*
+ * Find the input format. This is done by finding the first device in the
+ * pipeline which can tell us the current format. This could be the sensor, or
+ * this could be another device in the middle which is capable of format
+ * conversions.
+ */
+static int ti_csi2rx_validate_pipeline(struct ti_csi2rx_dev *csi)
+{
+	struct media_pipeline *pipe = &csi->pipe;
+	struct media_entity *entity;
+	struct v4l2_subdev *sd;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_pix_format *pix = &csi->v_fmt.fmt.pix;
+	const struct ti_csi2rx_fmt *ti_fmt;
+	int ret;
+
+	media_graph_walk_start(&pipe->graph, &csi->vdev.entity);
+
+	while ((entity = media_graph_walk_next(&pipe->graph))) {
+		if (!is_media_entity_v4l2_subdev(entity))
+			continue;
+
+		sd = media_entity_to_v4l2_subdev(entity);
+
+		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		fmt.pad = media_get_pad_index(entity, 0, PAD_SIGNAL_DEFAULT);
+
+		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
+		if (ret && ret != -ENOIOCTLCMD)
+			return ret;
+		if (!ret)
+			break;
+	}
+
+	/* Could not find input format. */
+	if (!entity)
+		return -EPIPE;
+
+	if (fmt.format.width != pix->width)
+		return -EPIPE;
+	if (fmt.format.height != pix->height)
+		return -EPIPE;
+
+	ti_fmt = find_format_by_pix(pix->pixelformat);
+	if (WARN_ON(!ti_fmt))
+		return -EINVAL;
+
+	if (fmt.format.code == MEDIA_BUS_FMT_YUYV8_2X8 ||
+	    fmt.format.code == MEDIA_BUS_FMT_VYUY8_2X8 ||
+	    fmt.format.code == MEDIA_BUS_FMT_YVYU8_2X8) {
+		dev_err(csi->dev,
+			"Only UYVY input allowed for YUV422 8-bit. Output format can be configured.\n");
+		return -EPIPE;
+	}
+
+	if (fmt.format.code == MEDIA_BUS_FMT_UYVY8_2X8) {
+		/* Format conversion between YUV422 formats can be done. */
+		if (ti_fmt->code != MEDIA_BUS_FMT_UYVY8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_YUYV8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_VYUY8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_YVYU8_2X8)
+			return -EPIPE;
+	} else if (fmt.format.code != ti_fmt->code) {
+		return -EPIPE;
+	}
+
+	if (fmt.format.field != V4L2_FIELD_NONE &&
+	    fmt.format.field != V4L2_FIELD_ANY)
+		return -EPIPE;
+
+	return 0;
+}
+
+static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+	struct ti_csi2rx_buffer *buf, *tmp;
+	int ret;
+
+	if (list_empty(&dmaq->list))
+		return -EIO;
+
+	ret = media_pipeline_start(&csi->vdev.entity, &csi->pipe);
+	if (ret)
+		return ret;
+
+	ret = ti_csi2rx_validate_pipeline(csi);
+	if (ret) {
+		dev_err(csi->dev,
+			"Format mismatch between source and video node\n");
+		goto err;
+	}
+
+	ti_csi2rx_setup_shim(csi);
+
+	ret = v4l2_subdev_call(csi->subdev, video, s_stream, 1);
+	if (ret)
+		goto err;
+
+	csi->sequence = 0;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+	ret = ti_csi2rx_start_dma(csi, buf);
+	if (ret) {
+		dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
+		goto err_stream;
+	}
+
+	return 0;
+
+err_stream:
+	v4l2_subdev_call(csi->subdev, video, s_stream, 0);
+err:
+	media_pipeline_stop(&csi->vdev.entity);
+	list_for_each_entry_safe(buf, tmp, &dmaq->list, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+	}
+
+	return ret;
+}
+
+static void ti_csi2rx_stop_streaming(struct vb2_queue *vq)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_buffer *buf = NULL, *tmp;
+	int ret;
+
+	media_pipeline_stop(&csi->vdev.entity);
+
+	ret = v4l2_subdev_call(csi->subdev, video, s_stream, 0);
+	if (ret)
+		dev_err(csi->dev, "Failed to stop subdev stream\n");
+
+	writel(0, csi->shim + SHIM_CNTL);
+
+	ret = dmaengine_terminate_sync(csi->dma);
+	if (ret)
+		dev_err(csi->dev, "Failed to stop DMA\n");
+
+	writel(0, csi->shim + SHIM_DMACNTX);
+
+	list_for_each_entry_safe(buf, tmp, &csi->dmaq.list, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+}
+
+static const struct vb2_ops csi_vb2_qops = {
+	.queue_setup = ti_csi2rx_queue_setup,
+	.buf_prepare = ti_csi2rx_buffer_prepare,
+	.buf_queue = ti_csi2rx_buffer_queue,
+	.start_streaming = ti_csi2rx_start_streaming,
+	.stop_streaming = ti_csi2rx_stop_streaming,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+};
+
+static int ti_csi2rx_init_vb2q(struct ti_csi2rx_dev *csi)
+{
+	struct vb2_queue *q = &csi->vidq;
+	int ret;
+
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->drv_priv = csi;
+	q->buf_struct_size = sizeof(struct ti_csi2rx_buffer);
+	q->ops = &csi_vb2_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->dev = dmaengine_get_dma_device(csi->dma);
+	q->lock = &csi->mutex;
+
+	ret = vb2_queue_init(q);
+	if (ret)
+		return ret;
+
+	csi->vdev.queue = q;
+
+	return 0;
+}
+
+static int ti_csi2rx_init_dma(struct ti_csi2rx_dev *csi)
+{
+	struct dma_slave_config cfg;
+	int ret;
+
+	INIT_LIST_HEAD(&csi->dmaq.list);
+
+	csi->dma = NULL;
+
+	csi->dma = dma_request_chan(csi->dev, "rx0");
+	if (IS_ERR(csi->dma))
+		return PTR_ERR(csi->dma);
+
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_16_BYTES;
+
+	ret = dmaengine_slave_config(csi->dma, &cfg);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi)
+{
+	struct media_device *mdev = &csi->mdev;
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	mdev->dev = csi->dev;
+	mdev->hw_revision = 1;
+	strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model));
+	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
+		 dev_name(mdev->dev));
+
+	media_device_init(mdev);
+
+	strscpy(vdev->name, TI_CSI2RX_MODULE_NAME, sizeof(vdev->name));
+	vdev->v4l2_dev = &csi->v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	vdev->fops = &csi_fops;
+	vdev->ioctl_ops = &csi_ioctl_ops;
+	vdev->release = video_device_release_empty;
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+			    V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+	vdev->lock = &csi->mutex;
+	video_set_drvdata(vdev, csi);
+
+	csi->pad.flags = MEDIA_PAD_FL_SINK;
+	ret = media_entity_pads_init(&csi->vdev.entity, 1, &csi->pad);
+	if (ret)
+		return ret;
+
+	csi->v4l2_dev.mdev = mdev;
+
+	ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
+	if (ret)
+		return ret;
+
+	ret = media_device_register(mdev);
+	if (ret) {
+		v4l2_device_unregister(&csi->v4l2_dev);
+		media_device_cleanup(mdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_dev *csi)
+{
+	dma_release_channel(csi->dma);
+}
+
+static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi)
+{
+	media_device_unregister(&csi->mdev);
+	v4l2_device_unregister(&csi->v4l2_dev);
+	media_device_cleanup(&csi->mdev);
+}
+
+static void ti_csi2rx_cleanup_subdev(struct ti_csi2rx_dev *csi)
+{
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
+}
+
+static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_dev *csi)
+{
+	vb2_queue_release(&csi->vidq);
+}
+
+static int ti_csi2rx_probe(struct platform_device *pdev)
+{
+	struct ti_csi2rx_dev *csi;
+	struct resource *res;
+	int ret;
+
+	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
+	if (!csi)
+		return -ENOMEM;
+
+	csi->dev = &pdev->dev;
+	platform_set_drvdata(pdev, csi);
+
+	mutex_init(&csi->mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	csi->shim = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(csi->shim))
+		return PTR_ERR(csi->shim);
+
+	ret = ti_csi2rx_init_dma(csi);
+	if (ret)
+		return ret;
+
+	ret = ti_csi2rx_v4l2_init(csi);
+	if (ret)
+		goto err_dma;
+
+	ret = ti_csi2rx_init_vb2q(csi);
+	if (ret)
+		goto err_v4l2;
+
+	ret = ti_csi2rx_init_subdev(csi);
+	if (ret)
+		goto err_vb2q;
+
+	ret = of_platform_populate(csi->dev->of_node, NULL, NULL, csi->dev);
+	if (ret) {
+		dev_err(csi->dev, "Failed to create children: %d\n", ret);
+		goto err_subdev;
+	}
+
+	return 0;
+
+err_subdev:
+	ti_csi2rx_cleanup_subdev(csi);
+err_vb2q:
+	ti_csi2rx_cleanup_vb2q(csi);
+err_v4l2:
+	ti_csi2rx_cleanup_v4l2(csi);
+err_dma:
+	ti_csi2rx_cleanup_dma(csi);
+	return ret;
+}
+
+static int ti_csi2rx_remove(struct platform_device *pdev)
+{
+	struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev);
+
+	if (vb2_is_busy(&csi->vidq))
+		return -EBUSY;
+
+	video_unregister_device(&csi->vdev);
+
+	ti_csi2rx_cleanup_vb2q(csi);
+	ti_csi2rx_cleanup_subdev(csi);
+	ti_csi2rx_cleanup_v4l2(csi);
+	ti_csi2rx_cleanup_dma(csi);
+
+	return 0;
+}
+
+static const struct of_device_id ti_csi2rx_of_match[] = {
+	{ .compatible = "ti,j721e-csi2rx", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ti_csi2rx_of_match);
+
+static struct platform_driver ti_csi2rx_pdrv = {
+	.probe = ti_csi2rx_probe,
+	.remove = ti_csi2rx_remove,
+	.driver = {
+		.name = TI_CSI2RX_MODULE_NAME,
+		.of_match_table = ti_csi2rx_of_match,
+	},
+};
+
+module_platform_driver(ti_csi2rx_pdrv);
+
+MODULE_DESCRIPTION("TI J721E CSI2 RX Driver");
+MODULE_AUTHOR("Pratyush Yadav <p.yadav@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
-- 
2.30.0


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

* [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
capture over a CSI-2 bus.

The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
called the SHIM layer. It takes in data from stream 0, repacks it, and
sends it to memory over PSI-L DMA.

This driver acts as the "front end" to V4L2 client applications. It
implements the required ioctls and buffer operations, passes the
necessary calls on to the bridge, programs the SHIM layer, and performs
DMA via the dmaengine API to finally return the data to a buffer
supplied by the application.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Use dmaengine_get_dma_device() instead of directly accessing
  dma->device->dev.
- Do not set dst_addr_width when configuring slave DMA.
- Move to a separate subdir and rename to j721e-csi2rx.c
- Convert compatible to ti,j721e-csi2rx.
- Move to use Media Controller centric APIs.
- Improve cleanup in probe when one of the steps fails.
- Add colorspace to formats database.
- Set hw_revision on media_device.
- Move video device initialization to probe time instead of register time.

 MAINTAINERS                                   |   6 +
 drivers/media/platform/Kconfig                |  12 +
 drivers/media/platform/ti/Makefile            |   1 +
 .../media/platform/ti/j721e-csi2rx/Makefile   |   2 +
 .../platform/ti/j721e-csi2rx/j721e-csi2rx.c   | 884 ++++++++++++++++++
 5 files changed, 905 insertions(+)
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/Makefile
 create mode 100644 drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 607dd5e18e7d..2cf140a02063 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18332,6 +18332,12 @@ S:	Odd Fixes
 F:	drivers/clk/ti/
 F:	include/linux/clk/ti.h
 
+TI J721E CSI2RX DRIVER
+M:	Pratyush Yadav <p.yadav@ti.com>
+L:	linux-media@vger.kernel.org
+S:	Supported
+F:	drivers/media/platform/ti/j721e-csi2rx/
+
 TI DAVINCI MACHINE SUPPORT
 M:	Sekhar Nori <nsekhar@ti.com>
 R:	Bartosz Golaszewski <bgolaszewski@baylibre.com>
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 157c924686e4..732a942b3b29 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -200,6 +200,18 @@ config VIDEO_TI_CAL_MC
 
 endif # VIDEO_TI_CAL
 
+config VIDEO_TI_J721E_CSI2RX
+	tristate "TI J721E CSI2RX wrapper layer driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on MEDIA_SUPPORT && MEDIA_CONTROLLER
+	depends on PHY_CADENCE_DPHY && VIDEO_CADENCE_CSI2RX
+	depends on ARCH_K3 || COMPILE_TEST
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  Support for TI CSI2RX wrapper layer. This just enables the wrapper driver.
+	  The Cadence CSI2RX bridge driver needs to be enabled separately.
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/ti/Makefile b/drivers/media/platform/ti/Makefile
index bbc737ccbbea..17c9cfb74f66 100644
--- a/drivers/media/platform/ti/Makefile
+++ b/drivers/media/platform/ti/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y += cal/
 obj-y += vpe/
+obj-y += j721e-csi2rx/
diff --git a/drivers/media/platform/ti/j721e-csi2rx/Makefile b/drivers/media/platform/ti/j721e-csi2rx/Makefile
new file mode 100644
index 000000000000..377afc1d6280
--- /dev/null
+++ b/drivers/media/platform/ti/j721e-csi2rx/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_VIDEO_TI_J721E_CSI2RX) += j721e-csi2rx.o
diff --git a/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
new file mode 100644
index 000000000000..b8d31a0af6d8
--- /dev/null
+++ b/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -0,0 +1,884 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI CSI2 RX driver.
+ *
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ * Author: Pratyush Yadav <p.yadav@ti.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dmaengine.h>
+#include <linux/of_platform.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-contig.h>
+
+#define TI_CSI2RX_MODULE_NAME		"j721e-csi2rx"
+
+#define SHIM_CNTL			0x10
+#define SHIM_CNTL_PIX_RST		BIT(0)
+
+#define SHIM_DMACNTX			0x20
+#define SHIM_DMACNTX_EN			BIT(31)
+#define SHIM_DMACNTX_YUV422		GENMASK(27, 26)
+#define SHIM_DMACNTX_FMT		GENMASK(5, 0)
+#define SHIM_DMACNTX_UYVY		0
+#define SHIM_DMACNTX_VYUY		1
+#define SHIM_DMACNTX_YUYV		2
+#define SHIM_DMACNTX_YVYU		3
+
+#define SHIM_PSI_CFG0			0x24
+#define SHIM_PSI_CFG0_SRC_TAG		GENMASK(15, 0)
+#define SHIM_PSI_CFG0_DST_TAG		GENMASK(31, 15)
+
+#define CSI_DF_YUV420			0x18
+#define CSI_DF_YUV422			0x1e
+#define CSI_DF_RGB444			0x20
+#define CSI_DF_RGB888			0x24
+
+#define PSIL_WORD_SIZE_BYTES		16
+
+struct ti_csi2rx_fmt {
+	u32				fourcc;	/* Four character code. */
+	u32				code;	/* Mbus code. */
+	enum v4l2_colorspace		colorspace;
+	u32				csi_df;	/* CSI Data format. */
+	u8				bpp;	/* Bits per pixel. */
+};
+
+struct ti_csi2rx_buffer {
+	/* Common v4l2 buffer. Must be first. */
+	struct vb2_v4l2_buffer		vb;
+	struct list_head		list;
+};
+
+struct ti_csi2rx_dmaq {
+	struct list_head		list;
+};
+
+struct ti_csi2rx_dev {
+	struct device			*dev;
+	void __iomem			*shim;
+	struct v4l2_device		v4l2_dev;
+	struct video_device		vdev;
+	struct media_device		mdev;
+	struct media_pipeline		pipe;
+	struct media_pad		pad;
+	struct v4l2_async_notifier	notifier;
+	struct v4l2_subdev		*subdev;
+	struct vb2_queue		vidq;
+	struct mutex			mutex; /* To serialize ioctls. */
+	struct v4l2_format		v_fmt;
+	struct dma_chan			*dma;
+	struct ti_csi2rx_dmaq		dmaq;
+	u32				sequence;
+};
+
+static const struct ti_csi2rx_fmt formats[] = {
+	{
+		.fourcc			= V4L2_PIX_FMT_YUYV,
+		.code			= MEDIA_BUS_FMT_YUYV8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_UYVY,
+		.code			= MEDIA_BUS_FMT_UYVY8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_YVYU,
+		.code			= MEDIA_BUS_FMT_YVYU8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	}, {
+		.fourcc			= V4L2_PIX_FMT_VYUY,
+		.code			= MEDIA_BUS_FMT_VYUY8_2X8,
+		.colorspace		= V4L2_COLORSPACE_SRGB,
+		.csi_df			= CSI_DF_YUV422,
+		.bpp			= 16,
+	},
+
+	/* More formats can be supported but they are not listed for now. */
+};
+
+static const unsigned int num_formats = ARRAY_SIZE(formats);
+
+/* Forward declaration needed by ti_csi2rx_dma_callback. */
+static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+			       struct ti_csi2rx_buffer *buf);
+
+static const struct ti_csi2rx_fmt *find_format_by_pix(u32 pixelformat)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_formats; i++) {
+		if (formats[i].fourcc == pixelformat)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static void ti_csi2rx_fill_fmt(const struct ti_csi2rx_fmt *csi_fmt,
+			       struct v4l2_format *v4l2_fmt)
+{
+	struct v4l2_pix_format *pix = &v4l2_fmt->fmt.pix;
+	u32 bpl;
+
+	v4l2_fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	pix->pixelformat = csi_fmt->fourcc;
+	pix->colorspace = csi_fmt->colorspace;
+	pix->sizeimage = pix->height * pix->width * (csi_fmt->bpp / 8);
+
+	bpl = (pix->width * ALIGN(csi_fmt->bpp, 8)) >> 3;
+	pix->bytesperline = ALIGN(bpl, 16);
+}
+
+static int ti_csi2rx_querycap(struct file *file, void *priv,
+			      struct v4l2_capability *cap)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+
+	strscpy(cap->driver, TI_CSI2RX_MODULE_NAME, sizeof(cap->driver));
+	strscpy(cap->card, TI_CSI2RX_MODULE_NAME, sizeof(cap->card));
+
+	snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
+		 dev_name(csi->dev));
+
+	return 0;
+}
+
+static int ti_csi2rx_enum_fmt_vid_cap(struct file *file, void *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	if (f->index >= num_formats)
+		return -EINVAL;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	f->pixelformat = formats[f->index].fourcc;
+
+	return 0;
+}
+
+static int ti_csi2rx_g_fmt_vid_cap(struct file *file, void *prov,
+				   struct v4l2_format *f)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+
+	*f = csi->v_fmt;
+
+	return 0;
+}
+
+static int ti_csi2rx_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	const struct ti_csi2rx_fmt *fmt;
+
+	/*
+	 * Default to the first format if the requested pixel format code isn't
+	 * supported.
+	 */
+	fmt = find_format_by_pix(f->fmt.pix.pixelformat);
+	if (!fmt)
+		fmt = &formats[0];
+
+	if (f->fmt.pix.field == V4L2_FIELD_ANY)
+		f->fmt.pix.field = V4L2_FIELD_NONE;
+
+	if (f->fmt.pix.field != V4L2_FIELD_NONE)
+		return -EINVAL;
+
+	ti_csi2rx_fill_fmt(fmt, f);
+
+	return 0;
+}
+
+static int ti_csi2rx_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct ti_csi2rx_dev *csi = video_drvdata(file);
+	struct vb2_queue *q = &csi->vidq;
+	int ret;
+
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	ret = ti_csi2rx_try_fmt_vid_cap(file, priv, f);
+	if (ret < 0)
+		return ret;
+
+	csi->v_fmt = *f;
+
+	return 0;
+}
+
+static int ti_csi2rx_enum_framesizes(struct file *file, void *fh,
+				     struct v4l2_frmsizeenum *fsize)
+{
+	const struct ti_csi2rx_fmt *fmt;
+	u8 bpp;
+
+	fmt = find_format_by_pix(fsize->pixel_format);
+	if (!fmt)
+		return -EINVAL;
+
+	bpp = ALIGN(fmt->bpp, 8);
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = PSIL_WORD_SIZE_BYTES * 8 / bpp;
+	fsize->stepwise.max_width = UINT_MAX;
+	fsize->stepwise.step_width = PSIL_WORD_SIZE_BYTES * 8 / bpp;
+	fsize->stepwise.min_height = 1;
+	fsize->stepwise.max_height = UINT_MAX;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops csi_ioctl_ops = {
+	.vidioc_querycap      = ti_csi2rx_querycap,
+	.vidioc_enum_fmt_vid_cap = ti_csi2rx_enum_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap = ti_csi2rx_try_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap = ti_csi2rx_g_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap = ti_csi2rx_s_fmt_vid_cap,
+	.vidioc_enum_framesizes = ti_csi2rx_enum_framesizes,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs   = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_expbuf        = vb2_ioctl_expbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
+};
+
+static const struct v4l2_file_operations csi_fops = {
+	.owner = THIS_MODULE,
+	.open = v4l2_fh_open,
+	.release = vb2_fop_release,
+	.read = vb2_fop_read,
+	.poll = vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2,
+	.mmap = vb2_fop_mmap,
+};
+
+static int ti_csi2rx_video_register(struct ti_csi2rx_dev *csi)
+{
+	struct video_device *vdev = &csi->vdev;
+	int ret, src_pad;
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret)
+		return ret;
+
+	src_pad = media_entity_get_fwnode_pad(&csi->subdev->entity,
+					      csi->subdev->fwnode,
+					      MEDIA_PAD_FL_SOURCE);
+	if (src_pad < 0) {
+		dev_err(csi->dev, "Couldn't find source pad for subdev\n");
+		return src_pad;
+	}
+
+	ret = media_create_pad_link(&csi->subdev->entity, src_pad,
+				    &vdev->entity, 0,
+				    MEDIA_LNK_FL_IMMUTABLE |
+				    MEDIA_LNK_FL_ENABLED);
+	if (ret) {
+		video_unregister_device(vdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int csi_async_notifier_bound(struct v4l2_async_notifier *notifier,
+				    struct v4l2_subdev *subdev,
+				    struct v4l2_async_subdev *asd)
+{
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev);
+
+	csi->subdev = subdev;
+
+	return 0;
+}
+
+static int csi_async_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+	struct ti_csi2rx_dev *csi = dev_get_drvdata(notifier->v4l2_dev->dev);
+	int ret;
+
+	ret = ti_csi2rx_video_register(csi);
+	if (ret)
+		return ret;
+
+	return v4l2_device_register_subdev_nodes(&csi->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations csi_async_notifier_ops = {
+	.bound = csi_async_notifier_bound,
+	.complete = csi_async_notifier_complete,
+};
+
+static int ti_csi2rx_init_subdev(struct ti_csi2rx_dev *csi)
+{
+	struct fwnode_handle *fwnode;
+	struct v4l2_async_subdev *asd;
+	struct device_node *node;
+	int ret;
+
+	node = of_get_child_by_name(csi->dev->of_node, "csi-bridge");
+	if (!node)
+		return -EINVAL;
+
+	fwnode = of_fwnode_handle(node);
+	of_node_put(node);
+	if (!fwnode)
+		return -EINVAL;
+
+	v4l2_async_notifier_init(&csi->notifier);
+	csi->notifier.ops = &csi_async_notifier_ops;
+
+	asd = v4l2_async_notifier_add_fwnode_subdev(&csi->notifier, fwnode,
+						    struct v4l2_async_subdev);
+	if (IS_ERR(asd)) {
+		v4l2_async_notifier_cleanup(&csi->notifier);
+		return PTR_ERR(asd);
+	}
+
+	ret = v4l2_async_notifier_register(&csi->v4l2_dev, &csi->notifier);
+	if (ret) {
+		v4l2_async_notifier_cleanup(&csi->notifier);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ti_csi2rx_setup_shim(struct ti_csi2rx_dev *csi)
+{
+	const struct ti_csi2rx_fmt *fmt;
+	unsigned int reg;
+
+	fmt = find_format_by_pix(csi->v_fmt.fmt.pix.pixelformat);
+	if (!fmt) {
+		dev_err(csi->dev, "Unknown format\n");
+		return;
+	}
+
+	/* De-assert the pixel interface reset. */
+	reg = SHIM_CNTL_PIX_RST;
+	writel(reg, csi->shim + SHIM_CNTL);
+
+	reg = SHIM_DMACNTX_EN;
+	reg |= FIELD_PREP(SHIM_DMACNTX_FMT, fmt->csi_df);
+
+	/*
+	 * Using the values from the documentation gives incorrect ordering for
+	 * the luma and chroma components. In practice, the "reverse" format
+	 * gives the correct image. So for example, if the image is in UYVY, the
+	 * reverse would be YVYU.
+	 */
+	switch (fmt->fourcc) {
+	case V4L2_PIX_FMT_UYVY:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_YVYU);
+		break;
+	case V4L2_PIX_FMT_VYUY:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_YUYV);
+		break;
+	case V4L2_PIX_FMT_YUYV:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_VYUY);
+		break;
+	case V4L2_PIX_FMT_YVYU:
+		reg |= FIELD_PREP(SHIM_DMACNTX_YUV422,
+					SHIM_DMACNTX_UYVY);
+		break;
+	default:
+		/* Ignore if not YUV 4:2:2 */
+		break;
+	}
+
+	writel(reg, csi->shim + SHIM_DMACNTX);
+
+	reg = FIELD_PREP(SHIM_PSI_CFG0_SRC_TAG, 0) |
+	      FIELD_PREP(SHIM_PSI_CFG0_DST_TAG, 1);
+	writel(reg, csi->shim + SHIM_PSI_CFG0);
+}
+
+static void ti_csi2rx_dma_callback(void *param)
+{
+	struct ti_csi2rx_dev *csi = param;
+	struct ti_csi2rx_buffer *buf;
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+	list_del(&buf->list);
+
+	buf->vb.vb2_buf.timestamp = ktime_get_ns();
+	buf->vb.sequence = csi->sequence++;
+
+	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+	/* If there are more buffers to process then start their transfer. */
+	if (list_empty(&dmaq->list))
+		return;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+
+	if (ti_csi2rx_start_dma(csi, buf))
+		dev_err(csi->dev, "Failed to queue the next buffer for DMA\n");
+}
+
+static int ti_csi2rx_start_dma(struct ti_csi2rx_dev *csi,
+			       struct ti_csi2rx_buffer *buf)
+{
+	unsigned long addr;
+	struct dma_async_tx_descriptor *desc;
+	size_t len = csi->v_fmt.fmt.pix.sizeimage;
+	dma_cookie_t cookie;
+	int ret = 0;
+
+	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+	desc = dmaengine_prep_slave_single(csi->dma, addr, len, DMA_DEV_TO_MEM,
+					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!desc)
+		return -EIO;
+
+	desc->callback = ti_csi2rx_dma_callback;
+	desc->callback_param = csi;
+
+	cookie = dmaengine_submit(desc);
+	ret = dma_submit_error(cookie);
+	if (ret)
+		return ret;
+
+	dma_async_issue_pending(csi->dma);
+
+	return 0;
+}
+
+static int ti_csi2rx_queue_setup(struct vb2_queue *q, unsigned int *nbuffers,
+				 unsigned int *nplanes, unsigned int sizes[],
+				 struct device *alloc_devs[])
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(q);
+	unsigned int size = csi->v_fmt.fmt.pix.sizeimage;
+
+	if (*nplanes) {
+		if (sizes[0] < size)
+			return -EINVAL;
+		size = sizes[0];
+	}
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	return 0;
+}
+
+static int ti_csi2rx_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
+	unsigned long size = csi->v_fmt.fmt.pix.sizeimage;
+
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(csi->dev, "Data will not fit into plane\n");
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(vb, 0, size);
+	return 0;
+}
+
+static void ti_csi2rx_buffer_queue(struct vb2_buffer *vb)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vb->vb2_queue);
+	struct ti_csi2rx_buffer *buf;
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+
+	buf = container_of(vb, struct ti_csi2rx_buffer, vb.vb2_buf);
+
+	list_add_tail(&buf->list, &dmaq->list);
+}
+
+/*
+ * Find the input format. This is done by finding the first device in the
+ * pipeline which can tell us the current format. This could be the sensor, or
+ * this could be another device in the middle which is capable of format
+ * conversions.
+ */
+static int ti_csi2rx_validate_pipeline(struct ti_csi2rx_dev *csi)
+{
+	struct media_pipeline *pipe = &csi->pipe;
+	struct media_entity *entity;
+	struct v4l2_subdev *sd;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_pix_format *pix = &csi->v_fmt.fmt.pix;
+	const struct ti_csi2rx_fmt *ti_fmt;
+	int ret;
+
+	media_graph_walk_start(&pipe->graph, &csi->vdev.entity);
+
+	while ((entity = media_graph_walk_next(&pipe->graph))) {
+		if (!is_media_entity_v4l2_subdev(entity))
+			continue;
+
+		sd = media_entity_to_v4l2_subdev(entity);
+
+		fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		fmt.pad = media_get_pad_index(entity, 0, PAD_SIGNAL_DEFAULT);
+
+		ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
+		if (ret && ret != -ENOIOCTLCMD)
+			return ret;
+		if (!ret)
+			break;
+	}
+
+	/* Could not find input format. */
+	if (!entity)
+		return -EPIPE;
+
+	if (fmt.format.width != pix->width)
+		return -EPIPE;
+	if (fmt.format.height != pix->height)
+		return -EPIPE;
+
+	ti_fmt = find_format_by_pix(pix->pixelformat);
+	if (WARN_ON(!ti_fmt))
+		return -EINVAL;
+
+	if (fmt.format.code == MEDIA_BUS_FMT_YUYV8_2X8 ||
+	    fmt.format.code == MEDIA_BUS_FMT_VYUY8_2X8 ||
+	    fmt.format.code == MEDIA_BUS_FMT_YVYU8_2X8) {
+		dev_err(csi->dev,
+			"Only UYVY input allowed for YUV422 8-bit. Output format can be configured.\n");
+		return -EPIPE;
+	}
+
+	if (fmt.format.code == MEDIA_BUS_FMT_UYVY8_2X8) {
+		/* Format conversion between YUV422 formats can be done. */
+		if (ti_fmt->code != MEDIA_BUS_FMT_UYVY8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_YUYV8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_VYUY8_2X8 &&
+		    ti_fmt->code != MEDIA_BUS_FMT_YVYU8_2X8)
+			return -EPIPE;
+	} else if (fmt.format.code != ti_fmt->code) {
+		return -EPIPE;
+	}
+
+	if (fmt.format.field != V4L2_FIELD_NONE &&
+	    fmt.format.field != V4L2_FIELD_ANY)
+		return -EPIPE;
+
+	return 0;
+}
+
+static int ti_csi2rx_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_dmaq *dmaq = &csi->dmaq;
+	struct ti_csi2rx_buffer *buf, *tmp;
+	int ret;
+
+	if (list_empty(&dmaq->list))
+		return -EIO;
+
+	ret = media_pipeline_start(&csi->vdev.entity, &csi->pipe);
+	if (ret)
+		return ret;
+
+	ret = ti_csi2rx_validate_pipeline(csi);
+	if (ret) {
+		dev_err(csi->dev,
+			"Format mismatch between source and video node\n");
+		goto err;
+	}
+
+	ti_csi2rx_setup_shim(csi);
+
+	ret = v4l2_subdev_call(csi->subdev, video, s_stream, 1);
+	if (ret)
+		goto err;
+
+	csi->sequence = 0;
+
+	buf = list_entry(dmaq->list.next, struct ti_csi2rx_buffer, list);
+	ret = ti_csi2rx_start_dma(csi, buf);
+	if (ret) {
+		dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
+		goto err_stream;
+	}
+
+	return 0;
+
+err_stream:
+	v4l2_subdev_call(csi->subdev, video, s_stream, 0);
+err:
+	media_pipeline_stop(&csi->vdev.entity);
+	list_for_each_entry_safe(buf, tmp, &dmaq->list, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
+	}
+
+	return ret;
+}
+
+static void ti_csi2rx_stop_streaming(struct vb2_queue *vq)
+{
+	struct ti_csi2rx_dev *csi = vb2_get_drv_priv(vq);
+	struct ti_csi2rx_buffer *buf = NULL, *tmp;
+	int ret;
+
+	media_pipeline_stop(&csi->vdev.entity);
+
+	ret = v4l2_subdev_call(csi->subdev, video, s_stream, 0);
+	if (ret)
+		dev_err(csi->dev, "Failed to stop subdev stream\n");
+
+	writel(0, csi->shim + SHIM_CNTL);
+
+	ret = dmaengine_terminate_sync(csi->dma);
+	if (ret)
+		dev_err(csi->dev, "Failed to stop DMA\n");
+
+	writel(0, csi->shim + SHIM_DMACNTX);
+
+	list_for_each_entry_safe(buf, tmp, &csi->dmaq.list, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
+	}
+}
+
+static const struct vb2_ops csi_vb2_qops = {
+	.queue_setup = ti_csi2rx_queue_setup,
+	.buf_prepare = ti_csi2rx_buffer_prepare,
+	.buf_queue = ti_csi2rx_buffer_queue,
+	.start_streaming = ti_csi2rx_start_streaming,
+	.stop_streaming = ti_csi2rx_stop_streaming,
+	.wait_prepare = vb2_ops_wait_prepare,
+	.wait_finish = vb2_ops_wait_finish,
+};
+
+static int ti_csi2rx_init_vb2q(struct ti_csi2rx_dev *csi)
+{
+	struct vb2_queue *q = &csi->vidq;
+	int ret;
+
+	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+	q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+	q->drv_priv = csi;
+	q->buf_struct_size = sizeof(struct ti_csi2rx_buffer);
+	q->ops = &csi_vb2_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->dev = dmaengine_get_dma_device(csi->dma);
+	q->lock = &csi->mutex;
+
+	ret = vb2_queue_init(q);
+	if (ret)
+		return ret;
+
+	csi->vdev.queue = q;
+
+	return 0;
+}
+
+static int ti_csi2rx_init_dma(struct ti_csi2rx_dev *csi)
+{
+	struct dma_slave_config cfg;
+	int ret;
+
+	INIT_LIST_HEAD(&csi->dmaq.list);
+
+	csi->dma = NULL;
+
+	csi->dma = dma_request_chan(csi->dev, "rx0");
+	if (IS_ERR(csi->dma))
+		return PTR_ERR(csi->dma);
+
+	memset(&cfg, 0, sizeof(cfg));
+
+	cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_16_BYTES;
+
+	ret = dmaengine_slave_config(csi->dma, &cfg);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int ti_csi2rx_v4l2_init(struct ti_csi2rx_dev *csi)
+{
+	struct media_device *mdev = &csi->mdev;
+	struct video_device *vdev = &csi->vdev;
+	int ret;
+
+	mdev->dev = csi->dev;
+	mdev->hw_revision = 1;
+	strscpy(mdev->model, "TI-CSI2RX", sizeof(mdev->model));
+	snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
+		 dev_name(mdev->dev));
+
+	media_device_init(mdev);
+
+	strscpy(vdev->name, TI_CSI2RX_MODULE_NAME, sizeof(vdev->name));
+	vdev->v4l2_dev = &csi->v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	vdev->fops = &csi_fops;
+	vdev->ioctl_ops = &csi_ioctl_ops;
+	vdev->release = video_device_release_empty;
+	vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
+			    V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+	vdev->lock = &csi->mutex;
+	video_set_drvdata(vdev, csi);
+
+	csi->pad.flags = MEDIA_PAD_FL_SINK;
+	ret = media_entity_pads_init(&csi->vdev.entity, 1, &csi->pad);
+	if (ret)
+		return ret;
+
+	csi->v4l2_dev.mdev = mdev;
+
+	ret = v4l2_device_register(csi->dev, &csi->v4l2_dev);
+	if (ret)
+		return ret;
+
+	ret = media_device_register(mdev);
+	if (ret) {
+		v4l2_device_unregister(&csi->v4l2_dev);
+		media_device_cleanup(mdev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void ti_csi2rx_cleanup_dma(struct ti_csi2rx_dev *csi)
+{
+	dma_release_channel(csi->dma);
+}
+
+static void ti_csi2rx_cleanup_v4l2(struct ti_csi2rx_dev *csi)
+{
+	media_device_unregister(&csi->mdev);
+	v4l2_device_unregister(&csi->v4l2_dev);
+	media_device_cleanup(&csi->mdev);
+}
+
+static void ti_csi2rx_cleanup_subdev(struct ti_csi2rx_dev *csi)
+{
+	v4l2_async_notifier_unregister(&csi->notifier);
+	v4l2_async_notifier_cleanup(&csi->notifier);
+}
+
+static void ti_csi2rx_cleanup_vb2q(struct ti_csi2rx_dev *csi)
+{
+	vb2_queue_release(&csi->vidq);
+}
+
+static int ti_csi2rx_probe(struct platform_device *pdev)
+{
+	struct ti_csi2rx_dev *csi;
+	struct resource *res;
+	int ret;
+
+	csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
+	if (!csi)
+		return -ENOMEM;
+
+	csi->dev = &pdev->dev;
+	platform_set_drvdata(pdev, csi);
+
+	mutex_init(&csi->mutex);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	csi->shim = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(csi->shim))
+		return PTR_ERR(csi->shim);
+
+	ret = ti_csi2rx_init_dma(csi);
+	if (ret)
+		return ret;
+
+	ret = ti_csi2rx_v4l2_init(csi);
+	if (ret)
+		goto err_dma;
+
+	ret = ti_csi2rx_init_vb2q(csi);
+	if (ret)
+		goto err_v4l2;
+
+	ret = ti_csi2rx_init_subdev(csi);
+	if (ret)
+		goto err_vb2q;
+
+	ret = of_platform_populate(csi->dev->of_node, NULL, NULL, csi->dev);
+	if (ret) {
+		dev_err(csi->dev, "Failed to create children: %d\n", ret);
+		goto err_subdev;
+	}
+
+	return 0;
+
+err_subdev:
+	ti_csi2rx_cleanup_subdev(csi);
+err_vb2q:
+	ti_csi2rx_cleanup_vb2q(csi);
+err_v4l2:
+	ti_csi2rx_cleanup_v4l2(csi);
+err_dma:
+	ti_csi2rx_cleanup_dma(csi);
+	return ret;
+}
+
+static int ti_csi2rx_remove(struct platform_device *pdev)
+{
+	struct ti_csi2rx_dev *csi = platform_get_drvdata(pdev);
+
+	if (vb2_is_busy(&csi->vidq))
+		return -EBUSY;
+
+	video_unregister_device(&csi->vdev);
+
+	ti_csi2rx_cleanup_vb2q(csi);
+	ti_csi2rx_cleanup_subdev(csi);
+	ti_csi2rx_cleanup_v4l2(csi);
+	ti_csi2rx_cleanup_dma(csi);
+
+	return 0;
+}
+
+static const struct of_device_id ti_csi2rx_of_match[] = {
+	{ .compatible = "ti,j721e-csi2rx", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ti_csi2rx_of_match);
+
+static struct platform_driver ti_csi2rx_pdrv = {
+	.probe = ti_csi2rx_probe,
+	.remove = ti_csi2rx_remove,
+	.driver = {
+		.name = TI_CSI2RX_MODULE_NAME,
+		.of_match_table = ti_csi2rx_of_match,
+	},
+};
+
+module_platform_driver(ti_csi2rx_pdrv);
+
+MODULE_DESCRIPTION("TI J721E CSI2 RX Driver");
+MODULE_AUTHOR("Pratyush Yadav <p.yadav@ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
parts together.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Rename to ti,j721e-csi2rx.yaml
- Add an entry in MAINTAINERS.
- Add a description for the binding.
- Change compatible to ti,j721e-csi2rx to make it SoC specific.
- Remove description from dmas, reg, power-domains.
- Remove a limit of 2 from #address-cells and #size-cells.
- Fix add ^ to csi-bridge subnode regex.
- Make ranges mandatory.
- Add unit address in example.
- Add a reference to cdns,csi2rx in csi-bridge subnode.
- Expand the example to include the csi-bridge subnode as well.
- Re-order subject prefixes.

 .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml

diff --git a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
new file mode 100644
index 000000000000..db87cfd65bed
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/ti,j721e-csi2rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI J721E CSI2RX Wrapper Device Tree Bindings
+
+description: |
+  The TI J721E CSI2RX Wrapper is a wrapper around Cadence CSI2RX bridge that
+  enables sending captured frames to memory over PSI-L DMA. In the J721E
+  Technical Reference Manual (SPRUIL1B) it is referred to as "SHIM" under the
+  CSI_RX_IF section.
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: ti,j721e-csi2rx
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    items:
+      - const: rx0
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  ranges: true
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+patternProperties:
+  "^csi-bridge@":
+    type: object
+    description: CSI2 bridge node.
+    $ref: cdns,csi2rx.yaml#
+
+required:
+  - compatible
+  - reg
+  - dmas
+  - dma-names
+  - power-domains
+  - ranges
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    ti_csi2rx0: ticsi2rx@4500000 {
+        compatible = "ti,j721e-csi2rx";
+        dmas = <&main_udmap 0x4940>;
+        dma-names = "rx0";
+        reg = <0x4500000 0x1000>;
+        power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        cdns_csi2rx: csi-bridge@4504000 {
+            compatible = "cdns,csi2rx";
+            reg = <0x4504000 0x1000>;
+            clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+              <&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+            clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+              "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+            phys = <&dphy0>;
+            phy-names = "dphy";
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                csi2_0: port@0 {
+
+                    reg = <0>;
+
+                    csi2rx0_in_sensor: endpoint {
+                        remote-endpoint = <&csi2_cam0>;
+                        bus-type = <4>; /* CSI2 DPHY. */
+                        clock-lanes = <0>;
+                        data-lanes = <1 2>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 2cf140a02063..1f9de488564d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18336,6 +18336,7 @@ TI J721E CSI2RX DRIVER
 M:	Pratyush Yadav <p.yadav@ti.com>
 L:	linux-media@vger.kernel.org
 S:	Supported
+F:	Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
 F:	drivers/media/platform/ti/j721e-csi2rx/
 
 TI DAVINCI MACHINE SUPPORT
-- 
2.30.0


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

* [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
parts together.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Rename to ti,j721e-csi2rx.yaml
- Add an entry in MAINTAINERS.
- Add a description for the binding.
- Change compatible to ti,j721e-csi2rx to make it SoC specific.
- Remove description from dmas, reg, power-domains.
- Remove a limit of 2 from #address-cells and #size-cells.
- Fix add ^ to csi-bridge subnode regex.
- Make ranges mandatory.
- Add unit address in example.
- Add a reference to cdns,csi2rx in csi-bridge subnode.
- Expand the example to include the csi-bridge subnode as well.
- Re-order subject prefixes.

 .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
 MAINTAINERS                                   |   1 +
 2 files changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml

diff --git a/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
new file mode 100644
index 000000000000..db87cfd65bed
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/ti,j721e-csi2rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI J721E CSI2RX Wrapper Device Tree Bindings
+
+description: |
+  The TI J721E CSI2RX Wrapper is a wrapper around Cadence CSI2RX bridge that
+  enables sending captured frames to memory over PSI-L DMA. In the J721E
+  Technical Reference Manual (SPRUIL1B) it is referred to as "SHIM" under the
+  CSI_RX_IF section.
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: ti,j721e-csi2rx
+
+  dmas:
+    maxItems: 1
+
+  dma-names:
+    items:
+      - const: rx0
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  ranges: true
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+patternProperties:
+  "^csi-bridge@":
+    type: object
+    description: CSI2 bridge node.
+    $ref: cdns,csi2rx.yaml#
+
+required:
+  - compatible
+  - reg
+  - dmas
+  - dma-names
+  - power-domains
+  - ranges
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
+
+    ti_csi2rx0: ticsi2rx@4500000 {
+        compatible = "ti,j721e-csi2rx";
+        dmas = <&main_udmap 0x4940>;
+        dma-names = "rx0";
+        reg = <0x4500000 0x1000>;
+        power-domains = <&k3_pds 26 TI_SCI_PD_EXCLUSIVE>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        cdns_csi2rx: csi-bridge@4504000 {
+            compatible = "cdns,csi2rx";
+            reg = <0x4504000 0x1000>;
+            clocks = <&k3_clks 26 2>, <&k3_clks 26 0>, <&k3_clks 26 2>,
+              <&k3_clks 26 2>, <&k3_clks 26 3>, <&k3_clks 26 3>;
+            clock-names = "sys_clk", "p_clk", "pixel_if0_clk",
+              "pixel_if1_clk", "pixel_if2_clk", "pixel_if3_clk";
+            phys = <&dphy0>;
+            phy-names = "dphy";
+
+            ports {
+                #address-cells = <1>;
+                #size-cells = <0>;
+
+                csi2_0: port@0 {
+
+                    reg = <0>;
+
+                    csi2rx0_in_sensor: endpoint {
+                        remote-endpoint = <&csi2_cam0>;
+                        bus-type = <4>; /* CSI2 DPHY. */
+                        clock-lanes = <0>;
+                        data-lanes = <1 2>;
+                    };
+                };
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 2cf140a02063..1f9de488564d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18336,6 +18336,7 @@ TI J721E CSI2RX DRIVER
 M:	Pratyush Yadav <p.yadav@ti.com>
 L:	linux-media@vger.kernel.org
 S:	Supported
+F:	Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
 F:	drivers/media/platform/ti/j721e-csi2rx/
 
 TI DAVINCI MACHINE SUPPORT
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Convert the Cadence CSI2RX binding to use YAML schema.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- New in v2.

 .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
 .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
 2 files changed, 164 insertions(+), 100 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
 create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml

diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
deleted file mode 100644
index 6b02a0657ad9..000000000000
--- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-Cadence MIPI-CSI2 RX controller
-===============================
-
-The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
-lanes in input, and 4 different pixel streams in output.
-
-Required properties:
-  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
-  - reg: base address and size of the memory mapped region
-  - clocks: phandles to the clocks driving the controller
-  - clock-names: must contain:
-    * sys_clk: main clock
-    * p_clk: register bank clock
-    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
-                         implemented in hardware, between 0 and 3
-
-Optional properties:
-  - phys: phandle to the external D-PHY, phy-names must be provided
-  - phy-names: must contain "dphy", if the implementation uses an
-               external D-PHY
-
-Required subnodes:
-  - ports: A ports node with one port child node per device input and output
-           port, in accordance with the video interface bindings defined in
-           Documentation/devicetree/bindings/media/video-interfaces.txt. The
-           port nodes are numbered as follows:
-
-           Port Description
-           -----------------------------
-           0    CSI-2 input
-           1    Stream 0 output
-           2    Stream 1 output
-           3    Stream 2 output
-           4    Stream 3 output
-
-           The stream output port nodes are optional if they are not
-           connected to anything at the hardware level or implemented
-           in the design.Since there is only one endpoint per port,
-           the endpoints are not numbered.
-
-
-Example:
-
-csi2rx: csi-bridge@0d060000 {
-	compatible = "cdns,csi2rx";
-	reg = <0x0d060000 0x1000>;
-	clocks = <&byteclock>, <&byteclock>
-		 <&coreclock>, <&coreclock>,
-		 <&coreclock>, <&coreclock>;
-	clock-names = "sys_clk", "p_clk",
-		      "pixel_if0_clk", "pixel_if1_clk",
-		      "pixel_if2_clk", "pixel_if3_clk";
-
-	ports {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		port@0 {
-			reg = <0>;
-
-			csi2rx_in_sensor: endpoint {
-				remote-endpoint = <&sensor_out_csi2rx>;
-				clock-lanes = <0>;
-				data-lanes = <1 2>;
-			};
-		};
-
-		port@1 {
-			reg = <1>;
-
-			csi2rx_out_grabber0: endpoint {
-				remote-endpoint = <&grabber0_in_csi2rx>;
-			};
-		};
-
-		port@2 {
-			reg = <2>;
-
-			csi2rx_out_grabber1: endpoint {
-				remote-endpoint = <&grabber1_in_csi2rx>;
-			};
-		};
-
-		port@3 {
-			reg = <3>;
-
-			csi2rx_out_grabber2: endpoint {
-				remote-endpoint = <&grabber2_in_csi2rx>;
-			};
-		};
-
-		port@4 {
-			reg = <4>;
-
-			csi2rx_out_grabber3: endpoint {
-				remote-endpoint = <&grabber3_in_csi2rx>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
new file mode 100644
index 000000000000..ff5dd4211ac9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence MIPI-CSI2 RX controller
+
+description: |
+  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
+  lanes in input, and 4 different pixel streams in output.
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: cdns,csi2rx
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+    maxItems: 6
+
+  clock-names:
+    minItems: 3
+    maxItems: 6
+    items:
+      - const: sys_clk # main clock
+      - const: p_clk # register bank clock
+      - const: pixel_if0_clk # pixel stream 0 output clock
+      - const: pixel_if1_clk # pixel stream 1 output clock
+      - const: pixel_if2_clk # pixel stream 2 output clock
+      - const: pixel_if3_clk # pixel stream 3 output clock
+
+  phys:
+    maxItems: 1
+    description: phandle to the external D-PHY
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: CSI-2 input
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                maxItems: 1
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 0 output
+
+      port@2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 1 output
+
+      port@3:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 2 output
+
+      port@4:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 3 output
+
+    required:
+      - port@0
+
+
+dependencies:
+  phys: [ 'phy-names' ]
+  phy-names: [ 'phys' ]
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    csi2rx: csi-bridge@d060000 {
+      compatible = "cdns,csi2rx";
+      reg = <0x0d060000 0x1000>;
+      clocks = <&byteclock>, <&byteclock>,
+        <&coreclock>, <&coreclock>,
+        <&coreclock>, <&coreclock>;
+      clock-names = "sys_clk", "p_clk",
+              "pixel_if0_clk", "pixel_if1_clk",
+              "pixel_if2_clk", "pixel_if3_clk";
+      phys = <&dphy0>;
+      phy-names = "dphy";
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+          reg = <0>;
+
+          csi2rx_in_sensor: endpoint {
+            remote-endpoint = <&sensor_out_csi2rx>;
+            clock-lanes = <0>;
+            data-lanes = <1 2>;
+          };
+        };
+
+        port@1 {
+          reg = <1>;
+
+          csi2rx_out_grabber0: endpoint {
+            remote-endpoint = <&grabber0_in_csi2rx>;
+          };
+        };
+
+        port@2 {
+          reg = <2>;
+
+          csi2rx_out_grabber1: endpoint {
+            remote-endpoint = <&grabber1_in_csi2rx>;
+          };
+        };
+
+        port@3 {
+          reg = <3>;
+
+          csi2rx_out_grabber2: endpoint {
+            remote-endpoint = <&grabber2_in_csi2rx>;
+          };
+        };
+
+        port@4 {
+          reg = <4>;
+
+          csi2rx_out_grabber3: endpoint {
+            remote-endpoint = <&grabber3_in_csi2rx>;
+          };
+        };
+      };
+    };
-- 
2.30.0


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

* [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Convert the Cadence CSI2RX binding to use YAML schema.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- New in v2.

 .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
 .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
 2 files changed, 164 insertions(+), 100 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
 create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml

diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
deleted file mode 100644
index 6b02a0657ad9..000000000000
--- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-Cadence MIPI-CSI2 RX controller
-===============================
-
-The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
-lanes in input, and 4 different pixel streams in output.
-
-Required properties:
-  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
-  - reg: base address and size of the memory mapped region
-  - clocks: phandles to the clocks driving the controller
-  - clock-names: must contain:
-    * sys_clk: main clock
-    * p_clk: register bank clock
-    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
-                         implemented in hardware, between 0 and 3
-
-Optional properties:
-  - phys: phandle to the external D-PHY, phy-names must be provided
-  - phy-names: must contain "dphy", if the implementation uses an
-               external D-PHY
-
-Required subnodes:
-  - ports: A ports node with one port child node per device input and output
-           port, in accordance with the video interface bindings defined in
-           Documentation/devicetree/bindings/media/video-interfaces.txt. The
-           port nodes are numbered as follows:
-
-           Port Description
-           -----------------------------
-           0    CSI-2 input
-           1    Stream 0 output
-           2    Stream 1 output
-           3    Stream 2 output
-           4    Stream 3 output
-
-           The stream output port nodes are optional if they are not
-           connected to anything at the hardware level or implemented
-           in the design.Since there is only one endpoint per port,
-           the endpoints are not numbered.
-
-
-Example:
-
-csi2rx: csi-bridge@0d060000 {
-	compatible = "cdns,csi2rx";
-	reg = <0x0d060000 0x1000>;
-	clocks = <&byteclock>, <&byteclock>
-		 <&coreclock>, <&coreclock>,
-		 <&coreclock>, <&coreclock>;
-	clock-names = "sys_clk", "p_clk",
-		      "pixel_if0_clk", "pixel_if1_clk",
-		      "pixel_if2_clk", "pixel_if3_clk";
-
-	ports {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		port@0 {
-			reg = <0>;
-
-			csi2rx_in_sensor: endpoint {
-				remote-endpoint = <&sensor_out_csi2rx>;
-				clock-lanes = <0>;
-				data-lanes = <1 2>;
-			};
-		};
-
-		port@1 {
-			reg = <1>;
-
-			csi2rx_out_grabber0: endpoint {
-				remote-endpoint = <&grabber0_in_csi2rx>;
-			};
-		};
-
-		port@2 {
-			reg = <2>;
-
-			csi2rx_out_grabber1: endpoint {
-				remote-endpoint = <&grabber1_in_csi2rx>;
-			};
-		};
-
-		port@3 {
-			reg = <3>;
-
-			csi2rx_out_grabber2: endpoint {
-				remote-endpoint = <&grabber2_in_csi2rx>;
-			};
-		};
-
-		port@4 {
-			reg = <4>;
-
-			csi2rx_out_grabber3: endpoint {
-				remote-endpoint = <&grabber3_in_csi2rx>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
new file mode 100644
index 000000000000..ff5dd4211ac9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
@@ -0,0 +1,164 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence MIPI-CSI2 RX controller
+
+description: |
+  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
+  lanes in input, and 4 different pixel streams in output.
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: cdns,csi2rx
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 3
+    maxItems: 6
+
+  clock-names:
+    minItems: 3
+    maxItems: 6
+    items:
+      - const: sys_clk # main clock
+      - const: p_clk # register bank clock
+      - const: pixel_if0_clk # pixel stream 0 output clock
+      - const: pixel_if1_clk # pixel stream 1 output clock
+      - const: pixel_if2_clk # pixel stream 2 output clock
+      - const: pixel_if3_clk # pixel stream 3 output clock
+
+  phys:
+    maxItems: 1
+    description: phandle to the external D-PHY
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: CSI-2 input
+
+        properties:
+          endpoint:
+            $ref: video-interfaces.yaml#
+            unevaluatedProperties: false
+
+            properties:
+              clock-lanes:
+                maxItems: 1
+
+              data-lanes:
+                maxItems: 1
+
+            required:
+              - clock-lanes
+              - data-lanes
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 0 output
+
+      port@2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 1 output
+
+      port@3:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 2 output
+
+      port@4:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Stream 3 output
+
+    required:
+      - port@0
+
+
+dependencies:
+  phys: [ 'phy-names' ]
+  phy-names: [ 'phys' ]
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    csi2rx: csi-bridge@d060000 {
+      compatible = "cdns,csi2rx";
+      reg = <0x0d060000 0x1000>;
+      clocks = <&byteclock>, <&byteclock>,
+        <&coreclock>, <&coreclock>,
+        <&coreclock>, <&coreclock>;
+      clock-names = "sys_clk", "p_clk",
+              "pixel_if0_clk", "pixel_if1_clk",
+              "pixel_if2_clk", "pixel_if3_clk";
+      phys = <&dphy0>;
+      phy-names = "dphy";
+
+      ports {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        port@0 {
+          reg = <0>;
+
+          csi2rx_in_sensor: endpoint {
+            remote-endpoint = <&sensor_out_csi2rx>;
+            clock-lanes = <0>;
+            data-lanes = <1 2>;
+          };
+        };
+
+        port@1 {
+          reg = <1>;
+
+          csi2rx_out_grabber0: endpoint {
+            remote-endpoint = <&grabber0_in_csi2rx>;
+          };
+        };
+
+        port@2 {
+          reg = <2>;
+
+          csi2rx_out_grabber1: endpoint {
+            remote-endpoint = <&grabber1_in_csi2rx>;
+          };
+        };
+
+        port@3 {
+          reg = <3>;
+
+          csi2rx_out_grabber2: endpoint {
+            remote-endpoint = <&grabber2_in_csi2rx>;
+          };
+        };
+
+        port@4 {
+          reg = <4>;
+
+          csi2rx_out_grabber3: endpoint {
+            remote-endpoint = <&grabber3_in_csi2rx>;
+          };
+        };
+      };
+    };
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 16/18] phy: dt-bindings: Convert Cadence DPHY binding to YAML
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Convert Cadence DPHY binding to YAML.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

---

Changes in v2:
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy@... to phy@... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 .../devicetree/bindings/phy/cdns,dphy.txt     | 20 --------
 .../devicetree/bindings/phy/cdns,dphy.yaml    | 51 +++++++++++++++++++
 2 files changed, 51 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.txt b/Documentation/devicetree/bindings/phy/cdns,dphy.txt
deleted file mode 100644
index 1095bc4e72d9..000000000000
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Cadence DPHY
-============
-
-Cadence DPHY block.
-
-Required properties:
-- compatible: should be set to "cdns,dphy".
-- reg: physical base address and length of the DPHY registers.
-- clocks: DPHY reference clocks.
-- clock-names: must contain "psm" and "pll_ref".
-- #phy-cells: must be set to 0.
-
-Example:
-	dphy0: dphy@fd0e0000{
-		compatible = "cdns,dphy";
-		reg = <0x0 0xfd0e0000 0x0 0x1000>;
-		clocks = <&psm_clk>, <&pll_ref_clk>;
-		clock-names = "psm", "pll_ref";
-		#phy-cells = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
new file mode 100644
index 000000000000..b90a58773bf2
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,dphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence DPHY Device Tree Bindings
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: cdns,dphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PMA state machine clock
+      - description: PLL reference clock
+
+  clock-names:
+    items:
+      - const: psm
+      - const: pll_ref
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dphy0: phy@fd0e0000{
+        compatible = "cdns,dphy";
+        reg = <0xfd0e0000 0x1000>;
+        clocks = <&psm_clk>, <&pll_ref_clk>;
+        clock-names = "psm", "pll_ref";
+        #phy-cells = <0>;
+    };
-- 
2.30.0


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

* [PATCH v2 16/18] phy: dt-bindings: Convert Cadence DPHY binding to YAML
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

Convert Cadence DPHY binding to YAML.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

---

Changes in v2:
- Drop reg description.
- Add a description for each DPHY clock.
- Rename dphy@... to phy@... in example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 .../devicetree/bindings/phy/cdns,dphy.txt     | 20 --------
 .../devicetree/bindings/phy/cdns,dphy.yaml    | 51 +++++++++++++++++++
 2 files changed, 51 insertions(+), 20 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.txt b/Documentation/devicetree/bindings/phy/cdns,dphy.txt
deleted file mode 100644
index 1095bc4e72d9..000000000000
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-Cadence DPHY
-============
-
-Cadence DPHY block.
-
-Required properties:
-- compatible: should be set to "cdns,dphy".
-- reg: physical base address and length of the DPHY registers.
-- clocks: DPHY reference clocks.
-- clock-names: must contain "psm" and "pll_ref".
-- #phy-cells: must be set to 0.
-
-Example:
-	dphy0: dphy@fd0e0000{
-		compatible = "cdns,dphy";
-		reg = <0x0 0xfd0e0000 0x0 0x1000>;
-		clocks = <&psm_clk>, <&pll_ref_clk>;
-		clock-names = "psm", "pll_ref";
-		#phy-cells = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
new file mode 100644
index 000000000000..b90a58773bf2
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,dphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence DPHY Device Tree Bindings
+
+maintainers:
+  - Pratyush Yadav <p.yadav@ti.com>
+
+properties:
+  compatible:
+    items:
+      - const: cdns,dphy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PMA state machine clock
+      - description: PLL reference clock
+
+  clock-names:
+    items:
+      - const: psm
+      - const: pll_ref
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dphy0: phy@fd0e0000{
+        compatible = "cdns,dphy";
+        reg = <0xfd0e0000 0x1000>;
+        clocks = <&psm_clk>, <&pll_ref_clk>;
+        clock-names = "psm", "pll_ref";
+        #phy-cells = <0>;
+    };
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The clocks are not used by the DPHY when used in Rx mode so make them
optional.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index b90a58773bf2..3bb5be05e825 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -33,8 +33,6 @@ properties:
 required:
   - compatible
   - reg
-  - clocks
-  - clock-names
   - "#phy-cells"
 
 additionalProperties: false
-- 
2.30.0


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

* [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

The clocks are not used by the DPHY when used in Rx mode so make them
optional.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

---

Changes in v2:
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index b90a58773bf2..3bb5be05e825 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -33,8 +33,6 @@ properties:
 required:
   - compatible
   - reg
-  - clocks
-  - clock-names
   - "#phy-cells"
 
 additionalProperties: false
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [PATCH v2 18/18] phy: dt-bindings: cdns,dphy: add power-domains property
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-26 15:23   ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

This property is needed on TI platforms to enable the PD of the DPHY
before it can be used.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

---

Changes in v2:
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index 3bb5be05e825..d5a5e1f0b671 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -30,6 +30,9 @@ properties:
   "#phy-cells":
     const: 0
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -39,11 +42,13 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
     dphy0: phy@fd0e0000{
         compatible = "cdns,dphy";
         reg = <0xfd0e0000 0x1000>;
         clocks = <&psm_clk>, <&pll_ref_clk>;
         clock-names = "psm", "pll_ref";
+        power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
         #phy-cells = <0>;
     };
-- 
2.30.0


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

* [PATCH v2 18/18] phy: dt-bindings: cdns, dphy: add power-domains property
@ 2021-05-26 15:23   ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-26 15:23 UTC (permalink / raw)
  To: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Pratyush Yadav, Kishon Vijay Abraham I, Vinod Koul,
	Peter Ujfalusi, Steve Longerbeam, Benoit Parrot, linux-media,
	devicetree, linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart

This property is needed on TI platforms to enable the PD of the DPHY
before it can be used.

Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

---

Changes in v2:
- Add power-domain to the example.
- Add Laurent's R-by.
- Re-order subject prefixes.

 Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
index 3bb5be05e825..d5a5e1f0b671 100644
--- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
+++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
@@ -30,6 +30,9 @@ properties:
   "#phy-cells":
     const: 0
 
+  power-domains:
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -39,11 +42,13 @@ additionalProperties: false
 
 examples:
   - |
+    #include <dt-bindings/soc/ti,sci_pm_domain.h>
 
     dphy0: phy@fd0e0000{
         compatible = "cdns,dphy";
         reg = <0xfd0e0000 0x1000>;
         clocks = <&psm_clk>, <&pll_ref_clk>;
         clock-names = "psm", "pll_ref";
+        power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
         #phy-cells = <0>;
     };
-- 
2.30.0


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-27 12:42   ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 12:42 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Hi,
> 
> This series adds support for CSI2 capture on J721E. It includes some
> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> driver, and finally adds the TI CSI2RX wrapper driver.
> 
> Tested on TI's J721E with OV5640 sensor.

I'm having some trouble unloading and reloading the modules:

rmmod ti_cal
rmmod j721e_csi2rx
rmmod cdns_csi2rx
rmmod cdns_dphy
rmmod ov5640
[   37.943128] ------------[ cut here ]------------
[   37.947752] WARNING: CPU: 1 PID: 628 at drivers/media/v4l2-core/v4l2-ctrls-core.c:1807 __v4l2_ctrl_handler_setup+0x15c/0x170
[   37.958963] Modules linked in: ov5640(-) v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper drm drm_panel_orientation_quirks cfbfill
rect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent [last unloaded: cdns_dphy]
[   37.982455] CPU: 1 PID: 628 Comm: rmmod Not tainted 5.13.0-rc1-00205-g93acc23badc8 #3
[   37.990271] Hardware name: Texas Instruments K3 J721E SoC (DT)
[   37.996090] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[   38.002085] pc : __v4l2_ctrl_handler_setup+0x15c/0x170
[   38.007214] lr : __v4l2_ctrl_handler_setup+0x158/0x170
[   38.012343] sp : ffff80001476fae0
[   38.015648] x29: ffff80001476fae0 x28: ffff000806780000 x27: 0000000000000000
[   38.022781] x26: ffff00080300b448 x25: ffff000804ad4ac0 x24: 0000000000000001
[   38.029912] x23: 0000000000000000 x22: 0000000000000005 x21: ffff000801fa7880
[   38.037043] x20: ffff000801fa7888 x19: ffff000801fa7ba8 x18: 0000000000000000
[   38.044173] x17: 0000000000000000 x16: 0000000000000010 x15: 0000000000000001
[   38.051305] x14: 000000000000003b x13: 00000000aaaaaaab x12: ffff800011a915b8
[   38.058436] x11: 00000000000c001c x10: 000000008260a2b7 x9 : ffff800009362d9c
[   38.065566] x8 : ffff800011887100 x7 : 0000000000000000 x6 : 0000000000000001
[   38.072698] x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff800011260000
[   38.079829] x2 : 00000000000000c0 x1 : 00000000000000c0 x0 : 0000000000000000
[   38.086960] Call trace:
[   38.089399]  __v4l2_ctrl_handler_setup+0x15c/0x170
[   38.094181]  ov5640_resume+0x1fc/0x270 [ov5640]
[   38.098709]  __rpm_callback+0x98/0x160
[   38.102452]  rpm_callback+0x2c/0x90
[   38.105934]  rpm_resume+0x45c/0x6f4
[   38.109415]  __pm_runtime_resume+0x54/0xc0
[   38.113503]  __device_release_driver+0x40/0x240
[   38.118025]  driver_detach+0xd0/0x160
[   38.121680]  bus_remove_driver+0x68/0xe0
[   38.125595]  driver_unregister+0x3c/0x6c
[   38.129509]  i2c_del_driver+0x64/0xb0
[   38.133166]  ov5640_i2c_driver_exit+0x1c/0xc948 [ov5640]
[   38.138469]  __arm64_sys_delete_module+0x1b0/0x27c
[   38.143251]  invoke_syscall+0x50/0x120
[   38.146995]  el0_svc_common.constprop.0+0x68/0x104
[   38.151777]  do_el0_svc+0x30/0x9c
[   38.155086]  el0_svc+0x2c/0x54
[   38.158135]  el0_sync_handler+0x1a8/0x1ac
[   38.162136]  el0_sync+0x198/0x1c0
[   38.165444] irq event stamp: 11302
[   38.168837] hardirqs last  enabled at (11301): [<ffff800010bf4e40>] _raw_spin_unlock_irq+0x50/0xa0
[   38.177781] hardirqs last disabled at (11302): [<ffff800010be7a64>] el1_dbg+0x24/0xa0
[   38.185595] softirqs last  enabled at (10378): [<ffff800010010ba0>] __do_softirq+0x500/0x6bc
[   38.194017] softirqs last disabled at (10373): [<ffff80001005d4c4>] __irq_exit_rcu+0x1d4/0x1e0
[   38.202614] ---[ end trace 7037324a951cb149 ]---
rmmod v4l2_fwnode
insmod /root/nfs/work/linux/drivers/media/v4l2-core/v4l2-fwnode.ko
insmod /root/nfs/work/linux/drivers/phy/cadence/cdns-dphy.ko
insmod /root/nfs/work/linux/drivers/media/platform/cadence/cdns-csi2rx.ko
ERROR:   Unhandled External Abort received on 0x80000001 from S-EL1
ERROR:   exception reason=0 syndrome=0xbf000000
Unhandled Exception from EL1
x0             = 0x0000000000000000
x1             = 0xffff000804d59800
x2             = 0xffff8000146c4000
x3             = 0xffff800011260000
x4             = 0x0000000000000001
x5             = 0x0000000000000001
x6             = 0x0000000000000001
x7             = 0x0000000000000000
x8             = 0xffff800011887100
x9             = 0xffff800010bf5190
x10            = 0x000000008260a2b7
x11            = 0x00000000000c821d
x12            = 0xffff800011a915b8
x13            = 0x0000000000000001
x14            = 0x0000000000000000
x15            = 0x0000000000000020
x16            = 0x0000000000000000
x17            = 0x0000000000000000
x18            = 0x00000000fffffffb
x19            = 0xffff000806d44c00
x20            = 0x0000000000000000
x21            = 0xffff800009280058
x22            = 0xffff00080583c810
x23            = 0xffff00080583c800
x24            = 0xffff800009280058
x25            = 0x0000000000000047
x26            = 0xffff8000116d71d8
x27            = 0xffff800009280350
x28            = 0xffff800009280148
x29            = 0xffff80001432f850
x30            = 0xffff8000092506b8
scr_el3        = 0x000000000000073d
sctlr_el3      = 0x0000000030cd183f
cptr_el3       = 0x0000000000000000
tcr_el3        = 0x0000000080803520
daif           = 0x00000000000002c0
mair_el3       = 0x00000000004404ff
spsr_el3       = 0x0000000000000005
elr_el3        = 0xffff80000925043c
ttbr0_el3      = 0x0000000070010b00
esr_el3        = 0x00000000bf000000
far_el3        = 0x0000000000000000
spsr_el1       = 0x0000000060000005
elr_el1        = 0xffff800010be8cb0
spsr_abt       = 0x0000000000000000
spsr_und       = 0x0000000000000000
spsr_irq       = 0x0000000000000000
spsr_fiq       = 0x0000000000000000
sctlr_el1      = 0x0000000034d4d91d
actlr_el1      = 0x0000000000000000
cpacr_el1      = 0x0000000000300000
csselr_el1     = 0x0000000000000000
sp_el1         = 0xffff80001432f850
esr_el1        = 0x0000000056000000
ttbr0_el1      = 0x0000000882773200
ttbr1_el1      = 0x06d8000083180000
mair_el1       = 0x000c0400bb44ffff
amair_el1      = 0x0000000000000000
tcr_el1        = 0x00000034f5d07590
tpidr_el1      = 0xffff80086e790000
tpidr_el0      = 0x0000ffff895c6910
tpidrro_el0    = 0x0000000000000000
par_el1        = 0x0000000000000000
mpidr_el1      = 0x0000000080000001
afsr0_el1      = 0x0000000000000000
afsr1_el1      = 0x0000000000000000
contextidr_el1 = 0x0000000000000000
vbar_el1       = 0xffff800010011000
cntp_ctl_el0   = 0x0000000000000005
cntp_cval_el0  = 0x000000023f77b7a1
cntv_ctl_el0   = 0x0000000000000000
cntv_cval_el0  = 0x0000000000000000
cntkctl_el1    = 0x00000000000000d6
sp_el0         = 0x000000007000abd0
isr_el1        = 0x0000000000000040
dacr32_el2     = 0x0000000000000000
ifsr32_el2     = 0x0000000000000000
cpuectlr_el1   = 0x0000001b00000040
cpumerrsr_el1  = 0x0000000000000000
l2merrsr_el1   = 0x0000000000000000

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-05-27 12:42   ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 12:42 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Hi,
> 
> This series adds support for CSI2 capture on J721E. It includes some
> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> driver, and finally adds the TI CSI2RX wrapper driver.
> 
> Tested on TI's J721E with OV5640 sensor.

I'm having some trouble unloading and reloading the modules:

rmmod ti_cal
rmmod j721e_csi2rx
rmmod cdns_csi2rx
rmmod cdns_dphy
rmmod ov5640
[   37.943128] ------------[ cut here ]------------
[   37.947752] WARNING: CPU: 1 PID: 628 at drivers/media/v4l2-core/v4l2-ctrls-core.c:1807 __v4l2_ctrl_handler_setup+0x15c/0x170
[   37.958963] Modules linked in: ov5640(-) v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper drm drm_panel_orientation_quirks cfbfill
rect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent [last unloaded: cdns_dphy]
[   37.982455] CPU: 1 PID: 628 Comm: rmmod Not tainted 5.13.0-rc1-00205-g93acc23badc8 #3
[   37.990271] Hardware name: Texas Instruments K3 J721E SoC (DT)
[   37.996090] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[   38.002085] pc : __v4l2_ctrl_handler_setup+0x15c/0x170
[   38.007214] lr : __v4l2_ctrl_handler_setup+0x158/0x170
[   38.012343] sp : ffff80001476fae0
[   38.015648] x29: ffff80001476fae0 x28: ffff000806780000 x27: 0000000000000000
[   38.022781] x26: ffff00080300b448 x25: ffff000804ad4ac0 x24: 0000000000000001
[   38.029912] x23: 0000000000000000 x22: 0000000000000005 x21: ffff000801fa7880
[   38.037043] x20: ffff000801fa7888 x19: ffff000801fa7ba8 x18: 0000000000000000
[   38.044173] x17: 0000000000000000 x16: 0000000000000010 x15: 0000000000000001
[   38.051305] x14: 000000000000003b x13: 00000000aaaaaaab x12: ffff800011a915b8
[   38.058436] x11: 00000000000c001c x10: 000000008260a2b7 x9 : ffff800009362d9c
[   38.065566] x8 : ffff800011887100 x7 : 0000000000000000 x6 : 0000000000000001
[   38.072698] x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff800011260000
[   38.079829] x2 : 00000000000000c0 x1 : 00000000000000c0 x0 : 0000000000000000
[   38.086960] Call trace:
[   38.089399]  __v4l2_ctrl_handler_setup+0x15c/0x170
[   38.094181]  ov5640_resume+0x1fc/0x270 [ov5640]
[   38.098709]  __rpm_callback+0x98/0x160
[   38.102452]  rpm_callback+0x2c/0x90
[   38.105934]  rpm_resume+0x45c/0x6f4
[   38.109415]  __pm_runtime_resume+0x54/0xc0
[   38.113503]  __device_release_driver+0x40/0x240
[   38.118025]  driver_detach+0xd0/0x160
[   38.121680]  bus_remove_driver+0x68/0xe0
[   38.125595]  driver_unregister+0x3c/0x6c
[   38.129509]  i2c_del_driver+0x64/0xb0
[   38.133166]  ov5640_i2c_driver_exit+0x1c/0xc948 [ov5640]
[   38.138469]  __arm64_sys_delete_module+0x1b0/0x27c
[   38.143251]  invoke_syscall+0x50/0x120
[   38.146995]  el0_svc_common.constprop.0+0x68/0x104
[   38.151777]  do_el0_svc+0x30/0x9c
[   38.155086]  el0_svc+0x2c/0x54
[   38.158135]  el0_sync_handler+0x1a8/0x1ac
[   38.162136]  el0_sync+0x198/0x1c0
[   38.165444] irq event stamp: 11302
[   38.168837] hardirqs last  enabled at (11301): [<ffff800010bf4e40>] _raw_spin_unlock_irq+0x50/0xa0
[   38.177781] hardirqs last disabled at (11302): [<ffff800010be7a64>] el1_dbg+0x24/0xa0
[   38.185595] softirqs last  enabled at (10378): [<ffff800010010ba0>] __do_softirq+0x500/0x6bc
[   38.194017] softirqs last disabled at (10373): [<ffff80001005d4c4>] __irq_exit_rcu+0x1d4/0x1e0
[   38.202614] ---[ end trace 7037324a951cb149 ]---
rmmod v4l2_fwnode
insmod /root/nfs/work/linux/drivers/media/v4l2-core/v4l2-fwnode.ko
insmod /root/nfs/work/linux/drivers/phy/cadence/cdns-dphy.ko
insmod /root/nfs/work/linux/drivers/media/platform/cadence/cdns-csi2rx.ko
ERROR:   Unhandled External Abort received on 0x80000001 from S-EL1
ERROR:   exception reason=0 syndrome=0xbf000000
Unhandled Exception from EL1
x0             = 0x0000000000000000
x1             = 0xffff000804d59800
x2             = 0xffff8000146c4000
x3             = 0xffff800011260000
x4             = 0x0000000000000001
x5             = 0x0000000000000001
x6             = 0x0000000000000001
x7             = 0x0000000000000000
x8             = 0xffff800011887100
x9             = 0xffff800010bf5190
x10            = 0x000000008260a2b7
x11            = 0x00000000000c821d
x12            = 0xffff800011a915b8
x13            = 0x0000000000000001
x14            = 0x0000000000000000
x15            = 0x0000000000000020
x16            = 0x0000000000000000
x17            = 0x0000000000000000
x18            = 0x00000000fffffffb
x19            = 0xffff000806d44c00
x20            = 0x0000000000000000
x21            = 0xffff800009280058
x22            = 0xffff00080583c810
x23            = 0xffff00080583c800
x24            = 0xffff800009280058
x25            = 0x0000000000000047
x26            = 0xffff8000116d71d8
x27            = 0xffff800009280350
x28            = 0xffff800009280148
x29            = 0xffff80001432f850
x30            = 0xffff8000092506b8
scr_el3        = 0x000000000000073d
sctlr_el3      = 0x0000000030cd183f
cptr_el3       = 0x0000000000000000
tcr_el3        = 0x0000000080803520
daif           = 0x00000000000002c0
mair_el3       = 0x00000000004404ff
spsr_el3       = 0x0000000000000005
elr_el3        = 0xffff80000925043c
ttbr0_el3      = 0x0000000070010b00
esr_el3        = 0x00000000bf000000
far_el3        = 0x0000000000000000
spsr_el1       = 0x0000000060000005
elr_el1        = 0xffff800010be8cb0
spsr_abt       = 0x0000000000000000
spsr_und       = 0x0000000000000000
spsr_irq       = 0x0000000000000000
spsr_fiq       = 0x0000000000000000
sctlr_el1      = 0x0000000034d4d91d
actlr_el1      = 0x0000000000000000
cpacr_el1      = 0x0000000000300000
csselr_el1     = 0x0000000000000000
sp_el1         = 0xffff80001432f850
esr_el1        = 0x0000000056000000
ttbr0_el1      = 0x0000000882773200
ttbr1_el1      = 0x06d8000083180000
mair_el1       = 0x000c0400bb44ffff
amair_el1      = 0x0000000000000000
tcr_el1        = 0x00000034f5d07590
tpidr_el1      = 0xffff80086e790000
tpidr_el0      = 0x0000ffff895c6910
tpidrro_el0    = 0x0000000000000000
par_el1        = 0x0000000000000000
mpidr_el1      = 0x0000000080000001
afsr0_el1      = 0x0000000000000000
afsr1_el1      = 0x0000000000000000
contextidr_el1 = 0x0000000000000000
vbar_el1       = 0xffff800010011000
cntp_ctl_el0   = 0x0000000000000005
cntp_cval_el0  = 0x000000023f77b7a1
cntv_ctl_el0   = 0x0000000000000000
cntv_cval_el0  = 0x0000000000000000
cntkctl_el1    = 0x00000000000000d6
sp_el0         = 0x000000007000abd0
isr_el1        = 0x0000000000000040
dacr32_el2     = 0x0000000000000000
ifsr32_el2     = 0x0000000000000000
cpuectlr_el1   = 0x0000001b00000040
cpumerrsr_el1  = 0x0000000000000000
l2merrsr_el1   = 0x0000000000000000

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
  2021-05-26 15:22 ` Pratyush Yadav
@ 2021-05-27 13:23   ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 13:23 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Hi,
> 
> This series adds support for CSI2 capture on J721E. It includes some
> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> driver, and finally adds the TI CSI2RX wrapper driver.
> 
> Tested on TI's J721E with OV5640 sensor.

I also see this after a few captures:

[   84.115503] ------------[ cut here ]------------
[   84.120144] DMA-API: ti-udma 31150000.dma-controller: mapping sg segment longer than device claims to support [len=1900544] [max=65536]
[   84.132376] WARNING: CPU: 1 PID: 594 at kernel/dma/debug.c:1172 debug_dma_map_sg+0x304/0x390
[   84.140804] Modules linked in: ov5640 ti_cal j721e_csi2rx cdns_csi2rx cdns_dphy v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper d
rm drm_panel_orientation_quirks cfbfillrect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent
[   84.165298] CPU: 1 PID: 594 Comm: cam-mplex.py Not tainted 5.13.0-rc1-00206-g98bb91e95a28-dirty #5
[   84.174236] Hardware name: Texas Instruments K3 J721E SoC (DT)
[   84.180051] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[   84.186041] pc : debug_dma_map_sg+0x304/0x390
[   84.190383] lr : debug_dma_map_sg+0x304/0x390
[   84.194725] sp : ffff800014d0f730
[   84.198026] x29: ffff800014d0f730 x28: ffff000801544680 x27: ffffffffffffffff
[   84.205148] x26: 0000000000000000 x25: 0000000000000002 x24: 0000000000000001
[   84.212269] x23: ffff80001163abe0 x22: 0000000000000000 x21: 0000000000000001
[   84.219390] x20: ffff000801fa3010 x19: ffff0008075c7580 x18: 0000000000000000
[   84.226510] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000030
[   84.233630] x14: 6e61687420726567 x13: 6e6f6c20746e656d x12: 7420736d69616c63
[   84.240751] x11: 2065636976656420 x10: ffff8000116b18f8 x9 : ffff8000100eb920
[   84.247871] x8 : ffff8000116598f8 x7 : ffff8000116b18f8 x6 : 0000000000000001
[   84.254991] x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000
[   84.262111] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008066f8000
[   84.269230] Call trace:
[   84.271665]  debug_dma_map_sg+0x304/0x390
[   84.275660]  dma_map_sg_attrs+0x70/0xb0
[   84.279486]  drm_gem_map_dma_buf+0x6c/0xf0 [drm]
[   84.284177]  __map_dma_buf+0x28/0x80
[   84.287742]  dma_buf_map_attachment+0xe4/0x200
[   84.292172]  vb2_dc_map_dmabuf+0x3c/0x150
[   84.296171]  __prepare_dmabuf+0x1dc/0x514
[   84.300168]  __buf_prepare+0x1a0/0x25c
[   84.303903]  vb2_core_qbuf+0x3d4/0x72c
[   84.307638]  vb2_qbuf+0x9c/0xf4
[   84.310767]  vb2_ioctl_qbuf+0x68/0x7c
[   84.314416]  v4l_qbuf+0x54/0x70
[   84.317545]  __video_do_ioctl+0x194/0x400
[   84.321541]  video_usercopy+0x19c/0x910
[   84.325362]  video_ioctl2+0x24/0x40
[   84.328837]  v4l2_ioctl+0x4c/0x70
[   84.332141]  __arm64_sys_ioctl+0xb4/0xfc
[   84.336053]  invoke_syscall+0x50/0x120
[   84.339791]  el0_svc_common.constprop.0+0x68/0x104
[   84.344569]  do_el0_svc+0x30/0x9c
[   84.347872]  el0_svc+0x2c/0x54
[   84.350916]  el0_sync_handler+0x1a8/0x1ac
[   84.354911]  el0_sync+0x198/0x1c0
[   84.358215] irq event stamp: 0
[   84.361256] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[   84.367507] hardirqs last disabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
[   84.375667] softirqs last  enabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
[   84.383824] softirqs last disabled at (0): [<0000000000000000>] 0x0
[   84.390073] ---[ end trace af3448c784059129 ]---

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-05-27 13:23   ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 13:23 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Hi,
> 
> This series adds support for CSI2 capture on J721E. It includes some
> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> driver, and finally adds the TI CSI2RX wrapper driver.
> 
> Tested on TI's J721E with OV5640 sensor.

I also see this after a few captures:

[   84.115503] ------------[ cut here ]------------
[   84.120144] DMA-API: ti-udma 31150000.dma-controller: mapping sg segment longer than device claims to support [len=1900544] [max=65536]
[   84.132376] WARNING: CPU: 1 PID: 594 at kernel/dma/debug.c:1172 debug_dma_map_sg+0x304/0x390
[   84.140804] Modules linked in: ov5640 ti_cal j721e_csi2rx cdns_csi2rx cdns_dphy v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper d
rm drm_panel_orientation_quirks cfbfillrect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent
[   84.165298] CPU: 1 PID: 594 Comm: cam-mplex.py Not tainted 5.13.0-rc1-00206-g98bb91e95a28-dirty #5
[   84.174236] Hardware name: Texas Instruments K3 J721E SoC (DT)
[   84.180051] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
[   84.186041] pc : debug_dma_map_sg+0x304/0x390
[   84.190383] lr : debug_dma_map_sg+0x304/0x390
[   84.194725] sp : ffff800014d0f730
[   84.198026] x29: ffff800014d0f730 x28: ffff000801544680 x27: ffffffffffffffff
[   84.205148] x26: 0000000000000000 x25: 0000000000000002 x24: 0000000000000001
[   84.212269] x23: ffff80001163abe0 x22: 0000000000000000 x21: 0000000000000001
[   84.219390] x20: ffff000801fa3010 x19: ffff0008075c7580 x18: 0000000000000000
[   84.226510] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000030
[   84.233630] x14: 6e61687420726567 x13: 6e6f6c20746e656d x12: 7420736d69616c63
[   84.240751] x11: 2065636976656420 x10: ffff8000116b18f8 x9 : ffff8000100eb920
[   84.247871] x8 : ffff8000116598f8 x7 : ffff8000116b18f8 x6 : 0000000000000001
[   84.254991] x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000
[   84.262111] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008066f8000
[   84.269230] Call trace:
[   84.271665]  debug_dma_map_sg+0x304/0x390
[   84.275660]  dma_map_sg_attrs+0x70/0xb0
[   84.279486]  drm_gem_map_dma_buf+0x6c/0xf0 [drm]
[   84.284177]  __map_dma_buf+0x28/0x80
[   84.287742]  dma_buf_map_attachment+0xe4/0x200
[   84.292172]  vb2_dc_map_dmabuf+0x3c/0x150
[   84.296171]  __prepare_dmabuf+0x1dc/0x514
[   84.300168]  __buf_prepare+0x1a0/0x25c
[   84.303903]  vb2_core_qbuf+0x3d4/0x72c
[   84.307638]  vb2_qbuf+0x9c/0xf4
[   84.310767]  vb2_ioctl_qbuf+0x68/0x7c
[   84.314416]  v4l_qbuf+0x54/0x70
[   84.317545]  __video_do_ioctl+0x194/0x400
[   84.321541]  video_usercopy+0x19c/0x910
[   84.325362]  video_ioctl2+0x24/0x40
[   84.328837]  v4l2_ioctl+0x4c/0x70
[   84.332141]  __arm64_sys_ioctl+0xb4/0xfc
[   84.336053]  invoke_syscall+0x50/0x120
[   84.339791]  el0_svc_common.constprop.0+0x68/0x104
[   84.344569]  do_el0_svc+0x30/0x9c
[   84.347872]  el0_svc+0x2c/0x54
[   84.350916]  el0_sync_handler+0x1a8/0x1ac
[   84.354911]  el0_sync+0x198/0x1c0
[   84.358215] irq event stamp: 0
[   84.361256] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[   84.367507] hardirqs last disabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
[   84.375667] softirqs last  enabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
[   84.383824] softirqs last disabled at (0): [<0000000000000000>] 0x0
[   84.390073] ---[ end trace af3448c784059129 ]---

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-05-27 13:29     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 13:29 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:23, Pratyush Yadav wrote:
> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> capture over a CSI-2 bus.
> 
> The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
> the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
> called the SHIM layer. It takes in data from stream 0, repacks it, and
> sends it to memory over PSI-L DMA.
> 
> This driver acts as the "front end" to V4L2 client applications. It
> implements the required ioctls and buffer operations, passes the
> necessary calls on to the bridge, programs the SHIM layer, and performs
> DMA via the dmaengine API to finally return the data to a buffer
> supplied by the application.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

I noticed that my test app didn't work at all with this, and I also 
wasn't able to use v4l2-ctl to set the format.

At least for my test app the problem was that this driver doesn't 
initialize the format at all. My app first calls VIDIOC_G_FMT with 
v4l2_format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call 
modifies the fields it wants to change and calls VIDIOC_S_FMT. This 
failed, as G_FMT returned uninitialized fmt, i.e. type was 0, which my 
app didn't set again.

I believe the driver should have an initial format, something that it 
will accept if an app calls G_FMT and then S_FMT.

  Tomi

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
@ 2021-05-27 13:29     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-27 13:29 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

Hi Pratyush,

On 26/05/2021 18:23, Pratyush Yadav wrote:
> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> capture over a CSI-2 bus.
> 
> The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
> the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
> called the SHIM layer. It takes in data from stream 0, repacks it, and
> sends it to memory over PSI-L DMA.
> 
> This driver acts as the "front end" to V4L2 client applications. It
> implements the required ioctls and buffer operations, passes the
> necessary calls on to the bridge, programs the SHIM layer, and performs
> DMA via the dmaengine API to finally return the data to a buffer
> supplied by the application.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>

I noticed that my test app didn't work at all with this, and I also 
wasn't able to use v4l2-ctl to set the format.

At least for my test app the problem was that this driver doesn't 
initialize the format at all. My app first calls VIDIOC_G_FMT with 
v4l2_format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call 
modifies the fields it wants to change and calls VIDIOC_S_FMT. This 
failed, as G_FMT returned uninitialized fmt, i.e. type was 0, which my 
app didn't set again.

I believe the driver should have an initial format, something that it 
will accept if an app calls G_FMT and then S_FMT.

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-05-27 14:23     ` Rob Herring
  -1 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-05-27 14:23 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, linux-kernel, Vinod Koul, Kishon Vijay Abraham I,
	Laurent Pinchart, devicetree, Benoit Parrot, dmaengine,
	Steve Longerbeam, Tomi Valkeinen, Mauro Carvalho Chehab,
	linux-media, Chunfeng Yun, Peter Ujfalusi, Vignesh Raghavendra,
	linux-phy, Rob Herring

On Wed, 26 May 2021 20:53:04 +0530, Pratyush Yadav wrote:
> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
> parts together.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Rename to ti,j721e-csi2rx.yaml
> - Add an entry in MAINTAINERS.
> - Add a description for the binding.
> - Change compatible to ti,j721e-csi2rx to make it SoC specific.
> - Remove description from dmas, reg, power-domains.
> - Remove a limit of 2 from #address-cells and #size-cells.
> - Fix add ^ to csi-bridge subnode regex.
> - Make ranges mandatory.
> - Add unit address in example.
> - Add a reference to cdns,csi2rx in csi-bridge subnode.
> - Expand the example to include the csi-bridge subnode as well.
> - Re-order subject prefixes.
> 
>  .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 102 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
xargs: dt-doc-validate: exited with status 255; aborting
make[1]: *** Deleting file 'Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml'
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml] Error 255
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1416: dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1484096

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


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

* Re: [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
@ 2021-05-27 14:23     ` Rob Herring
  0 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-05-27 14:23 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, linux-kernel, Vinod Koul, Kishon Vijay Abraham I,
	Laurent Pinchart, devicetree, Benoit Parrot, dmaengine,
	Steve Longerbeam, Tomi Valkeinen, Mauro Carvalho Chehab,
	linux-media, Chunfeng Yun, Peter Ujfalusi, Vignesh Raghavendra,
	linux-phy, Rob Herring

On Wed, 26 May 2021 20:53:04 +0530, Pratyush Yadav wrote:
> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
> parts together.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Rename to ti,j721e-csi2rx.yaml
> - Add an entry in MAINTAINERS.
> - Add a description for the binding.
> - Change compatible to ti,j721e-csi2rx to make it SoC specific.
> - Remove description from dmas, reg, power-domains.
> - Remove a limit of 2 from #address-cells and #size-cells.
> - Fix add ^ to csi-bridge subnode regex.
> - Make ranges mandatory.
> - Add unit address in example.
> - Add a reference to cdns,csi2rx in csi-bridge subnode.
> - Expand the example to include the csi-bridge subnode as well.
> - Re-order subject prefixes.
> 
>  .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
>  MAINTAINERS                                   |   1 +
>  2 files changed, 102 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
xargs: dt-doc-validate: exited with status 255; aborting
make[1]: *** Deleting file 'Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml'
Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml] Error 255
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1416: dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1484096

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 04/18] phy: cdns-dphy: Add Rx support
  2021-05-26 15:22   ` Pratyush Yadav
@ 2021-05-28  6:09     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  6:09 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> The Cadence DPHY can be used to receive image data over the CSI-2
> protocol. Add support for Rx mode. The programming sequence differs from
> the Tx mode so it is added as a separate set of hooks to isolate the two
> paths.
> 
> The PHY is in Tx mode by default and it needs to be set in Rx mode by
> setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
> callback.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> ---
> 
> (no changes since v1)
> 
>   drivers/phy/cadence/cdns-dphy.c | 237 ++++++++++++++++++++++++++++++++
>   1 file changed, 237 insertions(+)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index 7d5f7b333893..7bbca679e2bb 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -1,11 +1,14 @@
>   // SPDX-License-Identifier: GPL-2.0+
>   /*
>    * Copyright: 2017-2018 Cadence Design Systems, Inc.
> + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
>    */
>   
>   #include <linux/bitops.h>
> +#include <linux/bitfield.h>
>   #include <linux/clk.h>
>   #include <linux/io.h>
> +#include <linux/iopoll.h>
>   #include <linux/module.h>
>   #include <linux/of_address.h>
>   #include <linux/of_device.h>
> @@ -25,10 +28,14 @@
>   #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
>   #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
>   #define DPHY_PCS(reg)			(0xb00 + (reg))
> +#define DPHY_ISO(reg)			(0xc00 + (reg))
>   
>   #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
>   #define DPHY_CMN_SSM_EN			BIT(0)
> +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
>   #define DPHY_CMN_TX_MODE_EN		BIT(9)
> +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
>   
>   #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
>   #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> @@ -45,10 +52,27 @@
>   #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
>   #define DPHY_CMN_OPDIV(x)		((x) << 7)
>   
> +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> +
>   #define DPHY_PSM_CFG			DPHY_PCS(0x4)
>   #define DPHY_PSM_CFG_FROM_REG		BIT(0)
>   #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
>   
> +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> +
> +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> +#define DPHY_ISO_LANE_READY_BIT		0
> +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> +
>   #define DSI_HBP_FRAME_OVERHEAD		12
>   #define DSI_HSA_FRAME_OVERHEAD		14
>   #define DSI_HFP_FRAME_OVERHEAD		6
> @@ -57,6 +81,9 @@
>   #define DSI_NULL_FRAME_OVERHEAD		6
>   #define DSI_EOT_PKT_SIZE		4
>   
> +#define DPHY_LANES_MIN			1
> +#define DPHY_LANES_MAX			4
> +
>   struct cdns_dphy_cfg {
>   	u8 pll_ipdiv;
>   	u8 pll_opdiv;
> @@ -312,6 +339,214 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
>   	.set_psm_div = cdns_dphy_ref_set_psm_div,
>   };
>   
> +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> +{
> +	/* Start RX state machine. */
> +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> +			  DPHY_CMN_RX_BANDGAP_TIMER),
> +	       dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> +{
> +	writel(0, dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> +{
> +	unsigned int rate = hs_clk_rate / 1000000UL;
> +
> +	if (rate < 80 || rate >= 2500)
> +		return -EOPNOTSUPP;
> +
> +	if (rate >= 80 && rate < 100)
> +		return 0;
> +
> +	if (rate >= 100 && rate < 120)
> +		return 1;
> +
> +	if (rate >= 120 && rate < 160)
> +		return 2;
> +
> +	if (rate >= 160 && rate < 200)
> +		return 3;
> +
> +	if (rate >= 200 && rate < 240)
> +		return 4;
> +
> +	if (rate >= 240 && rate < 280)
> +		return 5;
> +
> +	if (rate >= 280 && rate < 320)
> +		return 6;
> +
> +	if (rate >= 320 && rate < 360)
> +		return 7;
> +
> +	if (rate >= 360 && rate < 400)
> +		return 8;
> +
> +	if (rate >= 400 && rate < 480)
> +		return 9;
> +
> +	if (rate >= 480 && rate < 560)
> +		return 10;
> +
> +	if (rate >= 560 && rate < 640)
> +		return 11;
> +
> +	if (rate >= 640 && rate < 720)
> +		return 12;
> +
> +	if (rate >= 720 && rate < 800)
> +		return 13;
> +
> +	if (rate >= 800 && rate < 880)
> +		return 14;
> +
> +	if (rate >= 880 && rate < 1040)
> +		return 15;
> +
> +	if (rate >= 1040 && rate < 1200)
> +		return 16;
> +
> +	if (rate >= 1200 && rate < 1350)
> +		return 17;
> +
> +	if (rate >= 1350 && rate < 1500)
> +		return 18;
> +
> +	if (rate >= 1500 && rate < 1750)
> +		return 19;
> +
> +	if (rate >= 1750 && rate < 2000)
> +		return 20;
> +
> +	if (rate >= 2000 && rate < 2250)
> +		return 21;
> +
> +	if (rate >= 2250 && rate < 2500)
> +		return 22;
> +

All the above could be handled with a simple table and a for loop.

> +	/* Unreachable. */
> +	WARN(1, "Reached unreachable code.");
> +	return -EINVAL;
> +}
> +
> +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> +{
> +	u32 val;
> +
> +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
> +}
> +
> +static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
> +{
> +	void __iomem *reg = dphy->regs;
> +	int ret;
> +
> +	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
> +		return -EINVAL;
> +
> +	/* Clock lane */
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	/* Data lanes. Minimum one lane is mandatory. */
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L0,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 2)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L1,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 3)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L2,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 4)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L3,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +

This, too, could be handled with an array (for the regs) and a for loop.

  Tomi

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

* Re: [PATCH v2 04/18] phy: cdns-dphy: Add Rx support
@ 2021-05-28  6:09     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  6:09 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> The Cadence DPHY can be used to receive image data over the CSI-2
> protocol. Add support for Rx mode. The programming sequence differs from
> the Tx mode so it is added as a separate set of hooks to isolate the two
> paths.
> 
> The PHY is in Tx mode by default and it needs to be set in Rx mode by
> setting the submode to PHY_MIPI_DPHY_SUBMODE_RX in the set_mode()
> callback.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> ---
> 
> (no changes since v1)
> 
>   drivers/phy/cadence/cdns-dphy.c | 237 ++++++++++++++++++++++++++++++++
>   1 file changed, 237 insertions(+)
> 
> diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c
> index 7d5f7b333893..7bbca679e2bb 100644
> --- a/drivers/phy/cadence/cdns-dphy.c
> +++ b/drivers/phy/cadence/cdns-dphy.c
> @@ -1,11 +1,14 @@
>   // SPDX-License-Identifier: GPL-2.0+
>   /*
>    * Copyright: 2017-2018 Cadence Design Systems, Inc.
> + * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
>    */
>   
>   #include <linux/bitops.h>
> +#include <linux/bitfield.h>
>   #include <linux/clk.h>
>   #include <linux/io.h>
> +#include <linux/iopoll.h>
>   #include <linux/module.h>
>   #include <linux/of_address.h>
>   #include <linux/of_device.h>
> @@ -25,10 +28,14 @@
>   #define DPHY_PMA_RCLK(reg)		(0x600 + (reg))
>   #define DPHY_PMA_RDATA(lane, reg)	(0x700 + ((lane) * 0x100) + (reg))
>   #define DPHY_PCS(reg)			(0xb00 + (reg))
> +#define DPHY_ISO(reg)			(0xc00 + (reg))
>   
>   #define DPHY_CMN_SSM			DPHY_PMA_CMN(0x20)
>   #define DPHY_CMN_SSM_EN			BIT(0)
> +#define DPHY_CMN_RX_BANDGAP_TIMER_MASK	GENMASK(8, 1)
>   #define DPHY_CMN_TX_MODE_EN		BIT(9)
> +#define DPHY_CMN_RX_MODE_EN		BIT(10)
> +#define DPHY_CMN_RX_BANDGAP_TIMER	0x14
>   
>   #define DPHY_CMN_PWM			DPHY_PMA_CMN(0x40)
>   #define DPHY_CMN_PWM_DIV(x)		((x) << 20)
> @@ -45,10 +52,27 @@
>   #define DPHY_CMN_OPDIV_FROM_REG		BIT(6)
>   #define DPHY_CMN_OPDIV(x)		((x) << 7)
>   
> +#define DPHY_BAND_CFG			DPHY_PCS(0x0)
> +#define DPHY_BAND_CFG_LEFT_BAND		GENMASK(4, 0)
> +#define DPHY_BAND_CFG_RIGHT_BAND	GENMASK(9, 5)
> +
>   #define DPHY_PSM_CFG			DPHY_PCS(0x4)
>   #define DPHY_PSM_CFG_FROM_REG		BIT(0)
>   #define DPHY_PSM_CLK_DIV(x)		((x) << 1)
>   
> +#define DPHY_POWER_ISLAND_EN_DATA	DPHY_PCS(0x8)
> +#define DPHY_POWER_ISLAND_EN_DATA_VAL	0xaaaaaaaa
> +#define DPHY_POWER_ISLAND_EN_CLK	DPHY_PCS(0xc)
> +#define DPHY_POWER_ISLAND_EN_CLK_VAL	0xaa
> +
> +#define DPHY_ISO_CL_CTRL_L		DPHY_ISO(0x10)
> +#define DPHY_ISO_DL_CTRL_L0		DPHY_ISO(0x14)
> +#define DPHY_ISO_DL_CTRL_L1		DPHY_ISO(0x20)
> +#define DPHY_ISO_DL_CTRL_L2		DPHY_ISO(0x30)
> +#define DPHY_ISO_DL_CTRL_L3		DPHY_ISO(0x3c)
> +#define DPHY_ISO_LANE_READY_BIT		0
> +#define DPHY_ISO_LANE_READY_TIMEOUT_MS	100UL
> +
>   #define DSI_HBP_FRAME_OVERHEAD		12
>   #define DSI_HSA_FRAME_OVERHEAD		14
>   #define DSI_HFP_FRAME_OVERHEAD		6
> @@ -57,6 +81,9 @@
>   #define DSI_NULL_FRAME_OVERHEAD		6
>   #define DSI_EOT_PKT_SIZE		4
>   
> +#define DPHY_LANES_MIN			1
> +#define DPHY_LANES_MAX			4
> +
>   struct cdns_dphy_cfg {
>   	u8 pll_ipdiv;
>   	u8 pll_opdiv;
> @@ -312,6 +339,214 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = {
>   	.set_psm_div = cdns_dphy_ref_set_psm_div,
>   };
>   
> +static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy)
> +{
> +	/* Start RX state machine. */
> +	writel(DPHY_CMN_SSM_EN | DPHY_CMN_RX_MODE_EN |
> +	       FIELD_PREP(DPHY_CMN_RX_BANDGAP_TIMER_MASK,
> +			  DPHY_CMN_RX_BANDGAP_TIMER),
> +	       dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_power_off(struct cdns_dphy *dphy)
> +{
> +	writel(0, dphy->regs + DPHY_CMN_SSM);
> +
> +	return 0;
> +}
> +
> +static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate)
> +{
> +	unsigned int rate = hs_clk_rate / 1000000UL;
> +
> +	if (rate < 80 || rate >= 2500)
> +		return -EOPNOTSUPP;
> +
> +	if (rate >= 80 && rate < 100)
> +		return 0;
> +
> +	if (rate >= 100 && rate < 120)
> +		return 1;
> +
> +	if (rate >= 120 && rate < 160)
> +		return 2;
> +
> +	if (rate >= 160 && rate < 200)
> +		return 3;
> +
> +	if (rate >= 200 && rate < 240)
> +		return 4;
> +
> +	if (rate >= 240 && rate < 280)
> +		return 5;
> +
> +	if (rate >= 280 && rate < 320)
> +		return 6;
> +
> +	if (rate >= 320 && rate < 360)
> +		return 7;
> +
> +	if (rate >= 360 && rate < 400)
> +		return 8;
> +
> +	if (rate >= 400 && rate < 480)
> +		return 9;
> +
> +	if (rate >= 480 && rate < 560)
> +		return 10;
> +
> +	if (rate >= 560 && rate < 640)
> +		return 11;
> +
> +	if (rate >= 640 && rate < 720)
> +		return 12;
> +
> +	if (rate >= 720 && rate < 800)
> +		return 13;
> +
> +	if (rate >= 800 && rate < 880)
> +		return 14;
> +
> +	if (rate >= 880 && rate < 1040)
> +		return 15;
> +
> +	if (rate >= 1040 && rate < 1200)
> +		return 16;
> +
> +	if (rate >= 1200 && rate < 1350)
> +		return 17;
> +
> +	if (rate >= 1350 && rate < 1500)
> +		return 18;
> +
> +	if (rate >= 1500 && rate < 1750)
> +		return 19;
> +
> +	if (rate >= 1750 && rate < 2000)
> +		return 20;
> +
> +	if (rate >= 2000 && rate < 2250)
> +		return 21;
> +
> +	if (rate >= 2250 && rate < 2500)
> +		return 22;
> +

All the above could be handled with a simple table and a for loop.

> +	/* Unreachable. */
> +	WARN(1, "Reached unreachable code.");
> +	return -EINVAL;
> +}
> +
> +static int cdns_dphy_rx_wait_for_bit(void __iomem *addr, unsigned int bit)
> +{
> +	u32 val;
> +
> +	return readl_relaxed_poll_timeout(addr, val, val & BIT(bit), 10,
> +					  DPHY_ISO_LANE_READY_TIMEOUT_MS * 1000);
> +}
> +
> +static int cdns_dphy_rx_wait_lane_ready(struct cdns_dphy *dphy, int lanes)
> +{
> +	void __iomem *reg = dphy->regs;
> +	int ret;
> +
> +	if (lanes < DPHY_LANES_MIN || lanes > DPHY_LANES_MAX)
> +		return -EINVAL;
> +
> +	/* Clock lane */
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_CL_CTRL_L,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	/* Data lanes. Minimum one lane is mandatory. */
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L0,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 2)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L1,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 3)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L2,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +
> +	if (lanes < 4)
> +		return 0;
> +
> +	ret = cdns_dphy_rx_wait_for_bit(reg + DPHY_ISO_DL_CTRL_L3,
> +					DPHY_ISO_LANE_READY_BIT);
> +	if (ret)
> +		return ret;
> +

This, too, could be handled with an array (for the regs) and a for loop.

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
  2021-05-26 15:22   ` Pratyush Yadav
@ 2021-05-28  6:44     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  6:44 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Calling s_power subdev callback is discouraged. Instead, the subdevs
> should use runtime PM to control its power. Use runtime PM callbacks to
> control sensor power. The pm counter is incremented when the stream is
> started and decremented when the stream is stopped.
> 
> Refactor s_stream() a bit to make this new control flow easier. Add a
> helper to choose whether mipi or dvp set_stream needs to be called. The
> logic flow is also changed to make it a bit clearer.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - New in v2.
> 
>   drivers/media/i2c/Kconfig  |   2 +-
>   drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
>   2 files changed, 77 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 462c0e059754..5588fc1cc14a 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -914,7 +914,7 @@ config VIDEO_OV2740
>   
>   config VIDEO_OV5640
>   	tristate "OmniVision OV5640 sensor support"
> -	depends on OF
> +	depends on OF && PM
>   	depends on GPIOLIB && VIDEO_V4L2 && I2C
>   	select MEDIA_CONTROLLER
>   	select VIDEO_V4L2_SUBDEV_API
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 5b9cc71df473..4ed5758e2398 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -15,6 +15,7 @@
>   #include <linux/init.h>
>   #include <linux/module.h>
>   #include <linux/of_device.h>
> +#include <linux/pm_runtime.h>
>   #include <linux/regulator/consumer.h>
>   #include <linux/slab.h>
>   #include <linux/types.h>
> @@ -238,8 +239,6 @@ struct ov5640_dev {
>   	/* lock to protect all members below */
>   	struct mutex lock;
>   
> -	int power_count;
> -
>   	struct v4l2_mbus_framefmt fmt;
>   	bool pending_fmt_change;
>   
> @@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
>   				on ? 0x00 : 0x0f);
>   }
>   
> +static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
> +{
> +	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> +		return ov5640_set_stream_mipi(sensor, on);
> +	else
> +		return ov5640_set_stream_dvp(sensor, on);
> +}
> +
>   static int ov5640_get_sysclk(struct ov5640_dev *sensor)
>   {
>   	 /* calculate sysclk */
> @@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
>   
>   /* --------------- Subdev Operations --------------- */
>   
> -static int ov5640_s_power(struct v4l2_subdev *sd, int on)
> -{
> -	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> -	int ret = 0;
> -
> -	mutex_lock(&sensor->lock);
> -
> -	/*
> -	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
> -	 * update the power state.
> -	 */
> -	if (sensor->power_count == !on) {
> -		ret = ov5640_set_power(sensor, !!on);
> -		if (ret)
> -			goto out;
> -	}
> -
> -	/* Update the power count. */
> -	sensor->power_count += on ? 1 : -1;
> -	WARN_ON(sensor->power_count < 0);
> -out:
> -	mutex_unlock(&sensor->lock);
> -
> -	if (on && !ret && sensor->power_count == 1) {
> -		/* restore controls */
> -		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> -	}
> -
> -	return ret;
> -}
> -
>   static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
>   				     struct v4l2_fract *fi,
>   				     u32 width, u32 height)
> @@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
>   {
>   	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> +	struct device *dev = &sensor->i2c_client->dev;
>   	int ret;
>   
>   	/* v4l2_ctrl_lock() locks our own mutex */
> @@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
>   	 * not apply any controls to H/W at this time. Instead
>   	 * the controls will be restored right after power-up.
>   	 */
> -	if (sensor->power_count == 0)
> +	if (pm_runtime_suspended(dev))
>   		return 0;
>   
>   	switch (ctrl->id) {
> @@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
>   static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
>   {
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> +	struct device *dev = &sensor->i2c_client->dev;
>   	int ret = 0;
>   
>   	mutex_lock(&sensor->lock);
>   
> -	if (sensor->streaming == !enable) {
> -		if (enable && sensor->pending_mode_change) {
> +	if (sensor->streaming == enable)
> +		goto out;
> +
> +	if (enable) {
> +		ret = pm_runtime_get_sync(dev);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(dev);
> +			goto out;
> +		}

There now seems to be a function to do the above steps: 
pm_runtime_resume_and_get.

> +
> +		if (sensor->pending_mode_change) {
>   			ret = ov5640_set_mode(sensor);
>   			if (ret)
> -				goto out;
> +				goto put_pm;
>   		}
>   
> -		if (enable && sensor->pending_fmt_change) {
> +		if (sensor->pending_fmt_change) {
>   			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
>   			if (ret)
> -				goto out;
> +				goto put_pm;
>   			sensor->pending_fmt_change = false;
>   		}
>   
> -		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> -			ret = ov5640_set_stream_mipi(sensor, enable);
> -		else
> -			ret = ov5640_set_stream_dvp(sensor, enable);
> +		ret = ov5640_set_stream(sensor, enable);
> +		if (ret)
> +			goto put_pm;
> +	} else {
> +		ret = ov5640_set_stream(sensor, enable);

Instead of using "enable" here (and in the enable path above), just use 
true/false. It'll be more readable.

> +		if (ret)
> +			goto out;
>   
> -		if (!ret)
> -			sensor->streaming = enable;
> +		pm_runtime_put(dev);
>   	}
> +
> +	sensor->streaming = enable;
> +	goto out;
> +
> +put_pm:
> +	pm_runtime_put(dev);
>   out:
>   	mutex_unlock(&sensor->lock);
>   	return ret;
>   }

The flow in the above function is quite confusing. I think you should 
either 1) have a separate error paths via gotos and a return 0 before 
the error labels, or 2) common error and success path, without that 
final "goto out" you have above.

Maybe if you move the code in the "if (enable) {} else {}" to the 
ov5640_set_stream(), the flow will be easier to manage.

>   
>   static const struct v4l2_subdev_core_ops ov5640_core_ops = {
> -	.s_power = ov5640_s_power,
>   	.log_status = v4l2_ctrl_subdev_log_status,
>   	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
>   	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> @@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
>   	return ret;
>   }
>   
> +static int ov5640_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> +
> +	return ov5640_set_power(sensor, false);
> +}
> +
> +static int ov5640_resume(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> +	int ret = 0;
> +
> +	ret = ov5640_set_power(sensor, true);
> +	if (ret)
> +		return ret;
> +
> +	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> +}
> +
>   static int ov5640_probe(struct i2c_client *client)
>   {
>   	struct device *dev = &client->dev;
> @@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
>   	if (ret)
>   		goto entity_cleanup;
>   
> +	pm_runtime_enable(dev);
> +	pm_runtime_set_suspended(dev);
> +
>   	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
>   	if (ret)
> -		goto free_ctrls;
> +		goto error_pm;
>   
>   	return 0;
>   
> -free_ctrls:
> +error_pm:
> +	pm_runtime_disable(dev);

The label style used here seems to be the 
"label-tells-what-will-be-done", so I think instead of "error_pm", it 
should be, perhaps, "pm_disable".

>   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>   entity_cleanup:
>   	media_entity_cleanup(&sensor->sd.entity);
> @@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
>   
>   static int ov5640_remove(struct i2c_client *client)
>   {
> +	struct device *dev = &client->dev;
>   	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
>   
>   	v4l2_async_unregister_subdev(&sensor->sd);
>   	media_entity_cleanup(&sensor->sd.entity);
> +	pm_runtime_disable(dev);
>   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>   	mutex_destroy(&sensor->lock);
>   
>   	return 0;
>   }
>   
> +static const struct dev_pm_ops ov5640_pm_ops = {
> +	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
> +};
> +
>   static const struct i2c_device_id ov5640_id[] = {
>   	{"ov5640", 0},
>   	{},
> @@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
>   	.driver = {
>   		.name  = "ov5640",
>   		.of_match_table	= ov5640_dt_ids,
> +		.pm = &ov5640_pm_ops,
>   	},
>   	.id_table = ov5640_id,
>   	.probe_new = ov5640_probe,
> 


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

* Re: [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
@ 2021-05-28  6:44     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  6:44 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Calling s_power subdev callback is discouraged. Instead, the subdevs
> should use runtime PM to control its power. Use runtime PM callbacks to
> control sensor power. The pm counter is incremented when the stream is
> started and decremented when the stream is stopped.
> 
> Refactor s_stream() a bit to make this new control flow easier. Add a
> helper to choose whether mipi or dvp set_stream needs to be called. The
> logic flow is also changed to make it a bit clearer.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - New in v2.
> 
>   drivers/media/i2c/Kconfig  |   2 +-
>   drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
>   2 files changed, 77 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 462c0e059754..5588fc1cc14a 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -914,7 +914,7 @@ config VIDEO_OV2740
>   
>   config VIDEO_OV5640
>   	tristate "OmniVision OV5640 sensor support"
> -	depends on OF
> +	depends on OF && PM
>   	depends on GPIOLIB && VIDEO_V4L2 && I2C
>   	select MEDIA_CONTROLLER
>   	select VIDEO_V4L2_SUBDEV_API
> diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> index 5b9cc71df473..4ed5758e2398 100644
> --- a/drivers/media/i2c/ov5640.c
> +++ b/drivers/media/i2c/ov5640.c
> @@ -15,6 +15,7 @@
>   #include <linux/init.h>
>   #include <linux/module.h>
>   #include <linux/of_device.h>
> +#include <linux/pm_runtime.h>
>   #include <linux/regulator/consumer.h>
>   #include <linux/slab.h>
>   #include <linux/types.h>
> @@ -238,8 +239,6 @@ struct ov5640_dev {
>   	/* lock to protect all members below */
>   	struct mutex lock;
>   
> -	int power_count;
> -
>   	struct v4l2_mbus_framefmt fmt;
>   	bool pending_fmt_change;
>   
> @@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
>   				on ? 0x00 : 0x0f);
>   }
>   
> +static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
> +{
> +	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> +		return ov5640_set_stream_mipi(sensor, on);
> +	else
> +		return ov5640_set_stream_dvp(sensor, on);
> +}
> +
>   static int ov5640_get_sysclk(struct ov5640_dev *sensor)
>   {
>   	 /* calculate sysclk */
> @@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
>   
>   /* --------------- Subdev Operations --------------- */
>   
> -static int ov5640_s_power(struct v4l2_subdev *sd, int on)
> -{
> -	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> -	int ret = 0;
> -
> -	mutex_lock(&sensor->lock);
> -
> -	/*
> -	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
> -	 * update the power state.
> -	 */
> -	if (sensor->power_count == !on) {
> -		ret = ov5640_set_power(sensor, !!on);
> -		if (ret)
> -			goto out;
> -	}
> -
> -	/* Update the power count. */
> -	sensor->power_count += on ? 1 : -1;
> -	WARN_ON(sensor->power_count < 0);
> -out:
> -	mutex_unlock(&sensor->lock);
> -
> -	if (on && !ret && sensor->power_count == 1) {
> -		/* restore controls */
> -		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> -	}
> -
> -	return ret;
> -}
> -
>   static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
>   				     struct v4l2_fract *fi,
>   				     u32 width, u32 height)
> @@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
>   {
>   	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> +	struct device *dev = &sensor->i2c_client->dev;
>   	int ret;
>   
>   	/* v4l2_ctrl_lock() locks our own mutex */
> @@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
>   	 * not apply any controls to H/W at this time. Instead
>   	 * the controls will be restored right after power-up.
>   	 */
> -	if (sensor->power_count == 0)
> +	if (pm_runtime_suspended(dev))
>   		return 0;
>   
>   	switch (ctrl->id) {
> @@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
>   static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
>   {
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> +	struct device *dev = &sensor->i2c_client->dev;
>   	int ret = 0;
>   
>   	mutex_lock(&sensor->lock);
>   
> -	if (sensor->streaming == !enable) {
> -		if (enable && sensor->pending_mode_change) {
> +	if (sensor->streaming == enable)
> +		goto out;
> +
> +	if (enable) {
> +		ret = pm_runtime_get_sync(dev);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(dev);
> +			goto out;
> +		}

There now seems to be a function to do the above steps: 
pm_runtime_resume_and_get.

> +
> +		if (sensor->pending_mode_change) {
>   			ret = ov5640_set_mode(sensor);
>   			if (ret)
> -				goto out;
> +				goto put_pm;
>   		}
>   
> -		if (enable && sensor->pending_fmt_change) {
> +		if (sensor->pending_fmt_change) {
>   			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
>   			if (ret)
> -				goto out;
> +				goto put_pm;
>   			sensor->pending_fmt_change = false;
>   		}
>   
> -		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> -			ret = ov5640_set_stream_mipi(sensor, enable);
> -		else
> -			ret = ov5640_set_stream_dvp(sensor, enable);
> +		ret = ov5640_set_stream(sensor, enable);
> +		if (ret)
> +			goto put_pm;
> +	} else {
> +		ret = ov5640_set_stream(sensor, enable);

Instead of using "enable" here (and in the enable path above), just use 
true/false. It'll be more readable.

> +		if (ret)
> +			goto out;
>   
> -		if (!ret)
> -			sensor->streaming = enable;
> +		pm_runtime_put(dev);
>   	}
> +
> +	sensor->streaming = enable;
> +	goto out;
> +
> +put_pm:
> +	pm_runtime_put(dev);
>   out:
>   	mutex_unlock(&sensor->lock);
>   	return ret;
>   }

The flow in the above function is quite confusing. I think you should 
either 1) have a separate error paths via gotos and a return 0 before 
the error labels, or 2) common error and success path, without that 
final "goto out" you have above.

Maybe if you move the code in the "if (enable) {} else {}" to the 
ov5640_set_stream(), the flow will be easier to manage.

>   
>   static const struct v4l2_subdev_core_ops ov5640_core_ops = {
> -	.s_power = ov5640_s_power,
>   	.log_status = v4l2_ctrl_subdev_log_status,
>   	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
>   	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> @@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
>   	return ret;
>   }
>   
> +static int ov5640_suspend(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> +
> +	return ov5640_set_power(sensor, false);
> +}
> +
> +static int ov5640_resume(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> +	int ret = 0;
> +
> +	ret = ov5640_set_power(sensor, true);
> +	if (ret)
> +		return ret;
> +
> +	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> +}
> +
>   static int ov5640_probe(struct i2c_client *client)
>   {
>   	struct device *dev = &client->dev;
> @@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
>   	if (ret)
>   		goto entity_cleanup;
>   
> +	pm_runtime_enable(dev);
> +	pm_runtime_set_suspended(dev);
> +
>   	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
>   	if (ret)
> -		goto free_ctrls;
> +		goto error_pm;
>   
>   	return 0;
>   
> -free_ctrls:
> +error_pm:
> +	pm_runtime_disable(dev);

The label style used here seems to be the 
"label-tells-what-will-be-done", so I think instead of "error_pm", it 
should be, perhaps, "pm_disable".

>   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>   entity_cleanup:
>   	media_entity_cleanup(&sensor->sd.entity);
> @@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
>   
>   static int ov5640_remove(struct i2c_client *client)
>   {
> +	struct device *dev = &client->dev;
>   	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
>   
>   	v4l2_async_unregister_subdev(&sensor->sd);
>   	media_entity_cleanup(&sensor->sd.entity);
> +	pm_runtime_disable(dev);
>   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
>   	mutex_destroy(&sensor->lock);
>   
>   	return 0;
>   }
>   
> +static const struct dev_pm_ops ov5640_pm_ops = {
> +	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
> +};
> +
>   static const struct i2c_device_id ov5640_id[] = {
>   	{"ov5640", 0},
>   	{},
> @@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
>   	.driver = {
>   		.name  = "ov5640",
>   		.of_match_table	= ov5640_dt_ids,
> +		.pm = &ov5640_pm_ops,
>   	},
>   	.id_table = ov5640_id,
>   	.probe_new = ov5640_probe,
> 


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-05-28  7:16     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:16 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:23, Pratyush Yadav wrote:
> The devnode can be used by media-ctl and other userspace tools to
> perform configurations on the subdev. Without it, media-ctl returns
> ENOENT when setting format on the sensor subdev.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> ---
> 
> (no changes since v1)
> 
>   drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index 1df21f462f3c..49bed63d5faa 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
>   	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>   	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
>   		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>   
>   	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
>   				     csi2rx->pads);
> 

I don't understand this one. There's nothing to configure in cdns-csi2rx 
from userspace, as far as I can see, so why is the dev node needed? And 
why would the lack of csi2rx dev node cause sensor subdev config to fail?

  Tomi

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
@ 2021-05-28  7:16     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:16 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:23, Pratyush Yadav wrote:
> The devnode can be used by media-ctl and other userspace tools to
> perform configurations on the subdev. Without it, media-ctl returns
> ENOENT when setting format on the sensor subdev.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> ---
> 
> (no changes since v1)
> 
>   drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index 1df21f462f3c..49bed63d5faa 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
>   	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>   	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
>   		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>   
>   	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
>   				     csi2rx->pads);
> 

I don't understand this one. There's nothing to configure in cdns-csi2rx 
from userspace, as far as I can see, so why is the dev node needed? And 
why would the lack of csi2rx dev node cause sensor subdev config to fail?

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
  2021-05-26 15:22   ` Pratyush Yadav
@ 2021-05-28  7:23     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:23 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Some platforms like TI's J721E can have the CSI2RX paired with an
> external DPHY. Add support to enable and configure the DPHY using the
> generic PHY framework.
> 
> Get the pixel rate and bpp from the subdev and pass them on to the DPHY
> along with the number of lanes. All other settings are left to their
> default values.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
>    calls to set PHY mode, etc. to make sure it is ready.
> 
>   drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
>   1 file changed, 148 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index c68a3eac62cd..459326de2eff 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -30,6 +30,12 @@
>   #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
>   #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
>   
> +#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
> +#define CSI2RX_DPHY_CL_RST			BIT(16)
> +#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
> +#define CSI2RX_DPHY_CL_EN			BIT(4)
> +#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
> +
>   #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
>   
>   #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
> @@ -54,6 +60,11 @@ enum csi2rx_pads {
>   	CSI2RX_PAD_MAX,
>   };
>   
> +struct csi2rx_fmt {
> +	u32				code;
> +	u8				bpp;
> +};
> +
>   struct csi2rx_priv {
>   	struct device			*dev;
>   	unsigned int			count;
> @@ -85,6 +96,52 @@ struct csi2rx_priv {
>   	int				source_pad;
>   };
>   
> +static const struct csi2rx_fmt formats[] = {
> +	{
> +		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
> +		.bpp	= 16,
> +	},
> +};
> +
> +static u8 csi2rx_get_bpp(u32 code)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(formats); i++) {
> +		if (formats[i].code == code)
> +			return formats[i].bpp;
> +	}
> +
> +	return 0;
> +}
> +
> +static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
> +{
> +	struct v4l2_ctrl *ctrl;
> +
> +	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
> +			      V4L2_CID_PIXEL_RATE);
> +	if (!ctrl) {
> +		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
> +			csi2rx->source_subdev->name);
> +		return -EINVAL;
> +	}
> +
> +	return v4l2_ctrl_g_ctrl_int64(ctrl);
> +}
> +
>   static inline
>   struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
>   {
> @@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
>   	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
>   }
>   
> +static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
> +{
> +	union phy_configure_opts opts = { };
> +	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> +	struct v4l2_subdev_format sd_fmt;
> +	s64 pixel_rate;
> +	int ret;
> +	u8 bpp;
> +	bool got_pm = true;
> +
> +	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +	sd_fmt.pad = 0;
> +
> +	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
> +			       &sd_fmt);
> +	if (ret)
> +		return ret;
> +
> +	bpp = csi2rx_get_bpp(sd_fmt.format.code);
> +	if (!bpp)
> +		return -EINVAL;
> +
> +	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
> +	if (pixel_rate < 0)
> +		return pixel_rate;
> +
> +	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
> +					       csi2rx->num_lanes, cfg);
> +	if (ret)
> +		return ret;

I guess the above code works for now, but with multiple streams it 
won't. There's no (single) pixel rate or bpp with multiple streams, and 
the link freq is the one that needs to be used. There's 
v4l2_get_link_freq() helper which makes it easier to support both pixel 
rate and link freq.

  Tomi

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

* Re: [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
@ 2021-05-28  7:23     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:23 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:22, Pratyush Yadav wrote:
> Some platforms like TI's J721E can have the CSI2RX paired with an
> external DPHY. Add support to enable and configure the DPHY using the
> generic PHY framework.
> 
> Get the pixel rate and bpp from the subdev and pass them on to the DPHY
> along with the number of lanes. All other settings are left to their
> default values.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
>    calls to set PHY mode, etc. to make sure it is ready.
> 
>   drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
>   1 file changed, 148 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> index c68a3eac62cd..459326de2eff 100644
> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> @@ -30,6 +30,12 @@
>   #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
>   #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
>   
> +#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
> +#define CSI2RX_DPHY_CL_RST			BIT(16)
> +#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
> +#define CSI2RX_DPHY_CL_EN			BIT(4)
> +#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
> +
>   #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
>   
>   #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
> @@ -54,6 +60,11 @@ enum csi2rx_pads {
>   	CSI2RX_PAD_MAX,
>   };
>   
> +struct csi2rx_fmt {
> +	u32				code;
> +	u8				bpp;
> +};
> +
>   struct csi2rx_priv {
>   	struct device			*dev;
>   	unsigned int			count;
> @@ -85,6 +96,52 @@ struct csi2rx_priv {
>   	int				source_pad;
>   };
>   
> +static const struct csi2rx_fmt formats[] = {
> +	{
> +		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
> +		.bpp	= 16,
> +	},
> +	{
> +		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
> +		.bpp	= 16,
> +	},
> +};
> +
> +static u8 csi2rx_get_bpp(u32 code)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(formats); i++) {
> +		if (formats[i].code == code)
> +			return formats[i].bpp;
> +	}
> +
> +	return 0;
> +}
> +
> +static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
> +{
> +	struct v4l2_ctrl *ctrl;
> +
> +	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
> +			      V4L2_CID_PIXEL_RATE);
> +	if (!ctrl) {
> +		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
> +			csi2rx->source_subdev->name);
> +		return -EINVAL;
> +	}
> +
> +	return v4l2_ctrl_g_ctrl_int64(ctrl);
> +}
> +
>   static inline
>   struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
>   {
> @@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
>   	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
>   }
>   
> +static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
> +{
> +	union phy_configure_opts opts = { };
> +	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> +	struct v4l2_subdev_format sd_fmt;
> +	s64 pixel_rate;
> +	int ret;
> +	u8 bpp;
> +	bool got_pm = true;
> +
> +	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +	sd_fmt.pad = 0;
> +
> +	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
> +			       &sd_fmt);
> +	if (ret)
> +		return ret;
> +
> +	bpp = csi2rx_get_bpp(sd_fmt.format.code);
> +	if (!bpp)
> +		return -EINVAL;
> +
> +	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
> +	if (pixel_rate < 0)
> +		return pixel_rate;
> +
> +	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
> +					       csi2rx->num_lanes, cfg);
> +	if (ret)
> +		return ret;

I guess the above code works for now, but with multiple streams it 
won't. There's no (single) pixel rate or bpp with multiple streams, and 
the link freq is the one that needs to be used. There's 
v4l2_get_link_freq() helper which makes it easier to support both pixel 
rate and link freq.

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
  2021-05-28  7:16     ` Tomi Valkeinen
@ 2021-05-28  7:24       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:24 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:16AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > The devnode can be used by media-ctl and other userspace tools to
> > perform configurations on the subdev. Without it, media-ctl returns
> > ENOENT when setting format on the sensor subdev.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > ---
> > 
> > (no changes since v1)
> > 
> >   drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > index 1df21f462f3c..49bed63d5faa 100644
> > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
> >   	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> >   	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
> >   		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> > +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> >   	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
> >   				     csi2rx->pads);
> > 
> 
> I don't understand this one. There's nothing to configure in cdns-csi2rx
> from userspace, as far as I can see, so why is the dev node needed? And why
> would the lack of csi2rx dev node cause sensor subdev config to fail?

Sensor config does not fail. But when I run media-ctl to set the format 
on /dev/media0, I get an error message that comes because the devnode 
for the bridge does not exist. I was not 100% sure about this patch but 
I figured if media-ctl expects it then it should be exposed.

I don't mind dropping this patch. Just want to make sure what the right 
thing to do here is. Should every element of the pipeline have a devnode 
or not?

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
@ 2021-05-28  7:24       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:24 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:16AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > The devnode can be used by media-ctl and other userspace tools to
> > perform configurations on the subdev. Without it, media-ctl returns
> > ENOENT when setting format on the sensor subdev.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > ---
> > 
> > (no changes since v1)
> > 
> >   drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
> >   1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > index 1df21f462f3c..49bed63d5faa 100644
> > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
> >   	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> >   	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
> >   		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> > +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> >   	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
> >   				     csi2rx->pads);
> > 
> 
> I don't understand this one. There's nothing to configure in cdns-csi2rx
> from userspace, as far as I can see, so why is the dev node needed? And why
> would the lack of csi2rx dev node cause sensor subdev config to fail?

Sensor config does not fail. But when I run media-ctl to set the format 
on /dev/media0, I get an error message that comes because the devnode 
for the bridge does not exist. I was not 100% sure about this patch but 
I figured if media-ctl expects it then it should be exposed.

I don't mind dropping this patch. Just want to make sure what the right 
thing to do here is. Should every element of the pipeline have a devnode 
or not?

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
  2021-05-28  6:44     ` Tomi Valkeinen
@ 2021-05-28  7:25       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:25 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 09:44AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Calling s_power subdev callback is discouraged. Instead, the subdevs
> > should use runtime PM to control its power. Use runtime PM callbacks to
> > control sensor power. The pm counter is incremented when the stream is
> > started and decremented when the stream is stopped.
> > 
> > Refactor s_stream() a bit to make this new control flow easier. Add a
> > helper to choose whether mipi or dvp set_stream needs to be called. The
> > logic flow is also changed to make it a bit clearer.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - New in v2.
> > 
> >   drivers/media/i2c/Kconfig  |   2 +-
> >   drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
> >   2 files changed, 77 insertions(+), 49 deletions(-)
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 462c0e059754..5588fc1cc14a 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -914,7 +914,7 @@ config VIDEO_OV2740
> >   config VIDEO_OV5640
> >   	tristate "OmniVision OV5640 sensor support"
> > -	depends on OF
> > +	depends on OF && PM
> >   	depends on GPIOLIB && VIDEO_V4L2 && I2C
> >   	select MEDIA_CONTROLLER
> >   	select VIDEO_V4L2_SUBDEV_API
> > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> > index 5b9cc71df473..4ed5758e2398 100644
> > --- a/drivers/media/i2c/ov5640.c
> > +++ b/drivers/media/i2c/ov5640.c
> > @@ -15,6 +15,7 @@
> >   #include <linux/init.h>
> >   #include <linux/module.h>
> >   #include <linux/of_device.h>
> > +#include <linux/pm_runtime.h>
> >   #include <linux/regulator/consumer.h>
> >   #include <linux/slab.h>
> >   #include <linux/types.h>
> > @@ -238,8 +239,6 @@ struct ov5640_dev {
> >   	/* lock to protect all members below */
> >   	struct mutex lock;
> > -	int power_count;
> > -
> >   	struct v4l2_mbus_framefmt fmt;
> >   	bool pending_fmt_change;
> > @@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
> >   				on ? 0x00 : 0x0f);
> >   }
> > +static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
> > +{
> > +	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> > +		return ov5640_set_stream_mipi(sensor, on);
> > +	else
> > +		return ov5640_set_stream_dvp(sensor, on);
> > +}
> > +
> >   static int ov5640_get_sysclk(struct ov5640_dev *sensor)
> >   {
> >   	 /* calculate sysclk */
> > @@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
> >   /* --------------- Subdev Operations --------------- */
> > -static int ov5640_s_power(struct v4l2_subdev *sd, int on)
> > -{
> > -	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > -	int ret = 0;
> > -
> > -	mutex_lock(&sensor->lock);
> > -
> > -	/*
> > -	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
> > -	 * update the power state.
> > -	 */
> > -	if (sensor->power_count == !on) {
> > -		ret = ov5640_set_power(sensor, !!on);
> > -		if (ret)
> > -			goto out;
> > -	}
> > -
> > -	/* Update the power count. */
> > -	sensor->power_count += on ? 1 : -1;
> > -	WARN_ON(sensor->power_count < 0);
> > -out:
> > -	mutex_unlock(&sensor->lock);
> > -
> > -	if (on && !ret && sensor->power_count == 1) {
> > -		/* restore controls */
> > -		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> > -	}
> > -
> > -	return ret;
> > -}
> > -
> >   static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
> >   				     struct v4l2_fract *fi,
> >   				     u32 width, u32 height)
> > @@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
> >   {
> >   	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > +	struct device *dev = &sensor->i2c_client->dev;
> >   	int ret;
> >   	/* v4l2_ctrl_lock() locks our own mutex */
> > @@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
> >   	 * not apply any controls to H/W at this time. Instead
> >   	 * the controls will be restored right after power-up.
> >   	 */
> > -	if (sensor->power_count == 0)
> > +	if (pm_runtime_suspended(dev))
> >   		return 0;
> >   	switch (ctrl->id) {
> > @@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
> >   static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
> >   {
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > +	struct device *dev = &sensor->i2c_client->dev;
> >   	int ret = 0;
> >   	mutex_lock(&sensor->lock);
> > -	if (sensor->streaming == !enable) {
> > -		if (enable && sensor->pending_mode_change) {
> > +	if (sensor->streaming == enable)
> > +		goto out;
> > +
> > +	if (enable) {
> > +		ret = pm_runtime_get_sync(dev);
> > +		if (ret < 0) {
> > +			pm_runtime_put_noidle(dev);
> > +			goto out;
> > +		}
> 
> There now seems to be a function to do the above steps:
> pm_runtime_resume_and_get.

Ok.

> 
> > +
> > +		if (sensor->pending_mode_change) {
> >   			ret = ov5640_set_mode(sensor);
> >   			if (ret)
> > -				goto out;
> > +				goto put_pm;
> >   		}
> > -		if (enable && sensor->pending_fmt_change) {
> > +		if (sensor->pending_fmt_change) {
> >   			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
> >   			if (ret)
> > -				goto out;
> > +				goto put_pm;
> >   			sensor->pending_fmt_change = false;
> >   		}
> > -		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> > -			ret = ov5640_set_stream_mipi(sensor, enable);
> > -		else
> > -			ret = ov5640_set_stream_dvp(sensor, enable);
> > +		ret = ov5640_set_stream(sensor, enable);
> > +		if (ret)
> > +			goto put_pm;
> > +	} else {
> > +		ret = ov5640_set_stream(sensor, enable);
> 
> Instead of using "enable" here (and in the enable path above), just use
> true/false. It'll be more readable.

Ok.

> 
> > +		if (ret)
> > +			goto out;
> > -		if (!ret)
> > -			sensor->streaming = enable;
> > +		pm_runtime_put(dev);
> >   	}
> > +
> > +	sensor->streaming = enable;
> > +	goto out;
> > +
> > +put_pm:
> > +	pm_runtime_put(dev);
> >   out:
> >   	mutex_unlock(&sensor->lock);
> >   	return ret;
> >   }
> 
> The flow in the above function is quite confusing. I think you should either
> 1) have a separate error paths via gotos and a return 0 before the error
> labels, or 2) common error and success path, without that final "goto out"
> you have above.
> 
> Maybe if you move the code in the "if (enable) {} else {}" to the
> ov5640_set_stream(), the flow will be easier to manage.

Ok. I'll take a look and see what works better.

> 
> >   static const struct v4l2_subdev_core_ops ov5640_core_ops = {
> > -	.s_power = ov5640_s_power,
> >   	.log_status = v4l2_ctrl_subdev_log_status,
> >   	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> >   	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > @@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
> >   	return ret;
> >   }
> > +static int ov5640_suspend(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> > +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> > +
> > +	return ov5640_set_power(sensor, false);
> > +}
> > +
> > +static int ov5640_resume(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> > +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> > +	int ret = 0;
> > +
> > +	ret = ov5640_set_power(sensor, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> > +}
> > +
> >   static int ov5640_probe(struct i2c_client *client)
> >   {
> >   	struct device *dev = &client->dev;
> > @@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
> >   	if (ret)
> >   		goto entity_cleanup;
> > +	pm_runtime_enable(dev);
> > +	pm_runtime_set_suspended(dev);
> > +
> >   	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
> >   	if (ret)
> > -		goto free_ctrls;
> > +		goto error_pm;
> >   	return 0;
> > -free_ctrls:
> > +error_pm:
> > +	pm_runtime_disable(dev);
> 
> The label style used here seems to be the "label-tells-what-will-be-done",
> so I think instead of "error_pm", it should be, perhaps, "pm_disable".

Ok.

> 
> >   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
> >   entity_cleanup:
> >   	media_entity_cleanup(&sensor->sd.entity);
> > @@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
> >   static int ov5640_remove(struct i2c_client *client)
> >   {
> > +	struct device *dev = &client->dev;
> >   	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> >   	v4l2_async_unregister_subdev(&sensor->sd);
> >   	media_entity_cleanup(&sensor->sd.entity);
> > +	pm_runtime_disable(dev);
> >   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
> >   	mutex_destroy(&sensor->lock);
> >   	return 0;
> >   }
> > +static const struct dev_pm_ops ov5640_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
> > +};
> > +
> >   static const struct i2c_device_id ov5640_id[] = {
> >   	{"ov5640", 0},
> >   	{},
> > @@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
> >   	.driver = {
> >   		.name  = "ov5640",
> >   		.of_match_table	= ov5640_dt_ids,
> > +		.pm = &ov5640_pm_ops,
> >   	},
> >   	.id_table = ov5640_id,
> >   	.probe_new = ov5640_probe,
> > 
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power
@ 2021-05-28  7:25       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:25 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 09:44AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Calling s_power subdev callback is discouraged. Instead, the subdevs
> > should use runtime PM to control its power. Use runtime PM callbacks to
> > control sensor power. The pm counter is incremented when the stream is
> > started and decremented when the stream is stopped.
> > 
> > Refactor s_stream() a bit to make this new control flow easier. Add a
> > helper to choose whether mipi or dvp set_stream needs to be called. The
> > logic flow is also changed to make it a bit clearer.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - New in v2.
> > 
> >   drivers/media/i2c/Kconfig  |   2 +-
> >   drivers/media/i2c/ov5640.c | 124 +++++++++++++++++++++++--------------
> >   2 files changed, 77 insertions(+), 49 deletions(-)
> > 
> > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > index 462c0e059754..5588fc1cc14a 100644
> > --- a/drivers/media/i2c/Kconfig
> > +++ b/drivers/media/i2c/Kconfig
> > @@ -914,7 +914,7 @@ config VIDEO_OV2740
> >   config VIDEO_OV5640
> >   	tristate "OmniVision OV5640 sensor support"
> > -	depends on OF
> > +	depends on OF && PM
> >   	depends on GPIOLIB && VIDEO_V4L2 && I2C
> >   	select MEDIA_CONTROLLER
> >   	select VIDEO_V4L2_SUBDEV_API
> > diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
> > index 5b9cc71df473..4ed5758e2398 100644
> > --- a/drivers/media/i2c/ov5640.c
> > +++ b/drivers/media/i2c/ov5640.c
> > @@ -15,6 +15,7 @@
> >   #include <linux/init.h>
> >   #include <linux/module.h>
> >   #include <linux/of_device.h>
> > +#include <linux/pm_runtime.h>
> >   #include <linux/regulator/consumer.h>
> >   #include <linux/slab.h>
> >   #include <linux/types.h>
> > @@ -238,8 +239,6 @@ struct ov5640_dev {
> >   	/* lock to protect all members below */
> >   	struct mutex lock;
> > -	int power_count;
> > -
> >   	struct v4l2_mbus_framefmt fmt;
> >   	bool pending_fmt_change;
> > @@ -1277,6 +1276,14 @@ static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
> >   				on ? 0x00 : 0x0f);
> >   }
> > +static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
> > +{
> > +	if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> > +		return ov5640_set_stream_mipi(sensor, on);
> > +	else
> > +		return ov5640_set_stream_dvp(sensor, on);
> > +}
> > +
> >   static int ov5640_get_sysclk(struct ov5640_dev *sensor)
> >   {
> >   	 /* calculate sysclk */
> > @@ -2155,37 +2162,6 @@ static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
> >   /* --------------- Subdev Operations --------------- */
> > -static int ov5640_s_power(struct v4l2_subdev *sd, int on)
> > -{
> > -	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > -	int ret = 0;
> > -
> > -	mutex_lock(&sensor->lock);
> > -
> > -	/*
> > -	 * If the power count is modified from 0 to != 0 or from != 0 to 0,
> > -	 * update the power state.
> > -	 */
> > -	if (sensor->power_count == !on) {
> > -		ret = ov5640_set_power(sensor, !!on);
> > -		if (ret)
> > -			goto out;
> > -	}
> > -
> > -	/* Update the power count. */
> > -	sensor->power_count += on ? 1 : -1;
> > -	WARN_ON(sensor->power_count < 0);
> > -out:
> > -	mutex_unlock(&sensor->lock);
> > -
> > -	if (on && !ret && sensor->power_count == 1) {
> > -		/* restore controls */
> > -		ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> > -	}
> > -
> > -	return ret;
> > -}
> > -
> >   static int ov5640_try_frame_interval(struct ov5640_dev *sensor,
> >   				     struct v4l2_fract *fi,
> >   				     u32 width, u32 height)
> > @@ -2681,6 +2657,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
> >   {
> >   	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > +	struct device *dev = &sensor->i2c_client->dev;
> >   	int ret;
> >   	/* v4l2_ctrl_lock() locks our own mutex */
> > @@ -2690,7 +2667,7 @@ static int ov5640_s_ctrl(struct v4l2_ctrl *ctrl)
> >   	 * not apply any controls to H/W at this time. Instead
> >   	 * the controls will be restored right after power-up.
> >   	 */
> > -	if (sensor->power_count == 0)
> > +	if (pm_runtime_suspended(dev))
> >   		return 0;
> >   	switch (ctrl->id) {
> > @@ -2939,39 +2916,56 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
> >   static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
> >   {
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> > +	struct device *dev = &sensor->i2c_client->dev;
> >   	int ret = 0;
> >   	mutex_lock(&sensor->lock);
> > -	if (sensor->streaming == !enable) {
> > -		if (enable && sensor->pending_mode_change) {
> > +	if (sensor->streaming == enable)
> > +		goto out;
> > +
> > +	if (enable) {
> > +		ret = pm_runtime_get_sync(dev);
> > +		if (ret < 0) {
> > +			pm_runtime_put_noidle(dev);
> > +			goto out;
> > +		}
> 
> There now seems to be a function to do the above steps:
> pm_runtime_resume_and_get.

Ok.

> 
> > +
> > +		if (sensor->pending_mode_change) {
> >   			ret = ov5640_set_mode(sensor);
> >   			if (ret)
> > -				goto out;
> > +				goto put_pm;
> >   		}
> > -		if (enable && sensor->pending_fmt_change) {
> > +		if (sensor->pending_fmt_change) {
> >   			ret = ov5640_set_framefmt(sensor, &sensor->fmt);
> >   			if (ret)
> > -				goto out;
> > +				goto put_pm;
> >   			sensor->pending_fmt_change = false;
> >   		}
> > -		if (sensor->ep.bus_type == V4L2_MBUS_CSI2_DPHY)
> > -			ret = ov5640_set_stream_mipi(sensor, enable);
> > -		else
> > -			ret = ov5640_set_stream_dvp(sensor, enable);
> > +		ret = ov5640_set_stream(sensor, enable);
> > +		if (ret)
> > +			goto put_pm;
> > +	} else {
> > +		ret = ov5640_set_stream(sensor, enable);
> 
> Instead of using "enable" here (and in the enable path above), just use
> true/false. It'll be more readable.

Ok.

> 
> > +		if (ret)
> > +			goto out;
> > -		if (!ret)
> > -			sensor->streaming = enable;
> > +		pm_runtime_put(dev);
> >   	}
> > +
> > +	sensor->streaming = enable;
> > +	goto out;
> > +
> > +put_pm:
> > +	pm_runtime_put(dev);
> >   out:
> >   	mutex_unlock(&sensor->lock);
> >   	return ret;
> >   }
> 
> The flow in the above function is quite confusing. I think you should either
> 1) have a separate error paths via gotos and a return 0 before the error
> labels, or 2) common error and success path, without that final "goto out"
> you have above.
> 
> Maybe if you move the code in the "if (enable) {} else {}" to the
> ov5640_set_stream(), the flow will be easier to manage.

Ok. I'll take a look and see what works better.

> 
> >   static const struct v4l2_subdev_core_ops ov5640_core_ops = {
> > -	.s_power = ov5640_s_power,
> >   	.log_status = v4l2_ctrl_subdev_log_status,
> >   	.subscribe_event = v4l2_ctrl_subdev_subscribe_event,
> >   	.unsubscribe_event = v4l2_event_subdev_unsubscribe,
> > @@ -3037,6 +3031,29 @@ static int ov5640_check_chip_id(struct ov5640_dev *sensor)
> >   	return ret;
> >   }
> > +static int ov5640_suspend(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> > +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> > +
> > +	return ov5640_set_power(sensor, false);
> > +}
> > +
> > +static int ov5640_resume(struct device *dev)
> > +{
> > +	struct i2c_client *client = to_i2c_client(dev);
> > +	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
> > +	struct ov5640_dev *sensor = to_ov5640_dev(subdev);
> > +	int ret = 0;
> > +
> > +	ret = ov5640_set_power(sensor, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return __v4l2_ctrl_handler_setup(&sensor->ctrls.handler);
> > +}
> > +
> >   static int ov5640_probe(struct i2c_client *client)
> >   {
> >   	struct device *dev = &client->dev;
> > @@ -3162,13 +3179,17 @@ static int ov5640_probe(struct i2c_client *client)
> >   	if (ret)
> >   		goto entity_cleanup;
> > +	pm_runtime_enable(dev);
> > +	pm_runtime_set_suspended(dev);
> > +
> >   	ret = v4l2_async_register_subdev_sensor(&sensor->sd);
> >   	if (ret)
> > -		goto free_ctrls;
> > +		goto error_pm;
> >   	return 0;
> > -free_ctrls:
> > +error_pm:
> > +	pm_runtime_disable(dev);
> 
> The label style used here seems to be the "label-tells-what-will-be-done",
> so I think instead of "error_pm", it should be, perhaps, "pm_disable".

Ok.

> 
> >   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
> >   entity_cleanup:
> >   	media_entity_cleanup(&sensor->sd.entity);
> > @@ -3178,17 +3199,23 @@ static int ov5640_probe(struct i2c_client *client)
> >   static int ov5640_remove(struct i2c_client *client)
> >   {
> > +	struct device *dev = &client->dev;
> >   	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> >   	struct ov5640_dev *sensor = to_ov5640_dev(sd);
> >   	v4l2_async_unregister_subdev(&sensor->sd);
> >   	media_entity_cleanup(&sensor->sd.entity);
> > +	pm_runtime_disable(dev);
> >   	v4l2_ctrl_handler_free(&sensor->ctrls.handler);
> >   	mutex_destroy(&sensor->lock);
> >   	return 0;
> >   }
> > +static const struct dev_pm_ops ov5640_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(ov5640_suspend, ov5640_resume, NULL)
> > +};
> > +
> >   static const struct i2c_device_id ov5640_id[] = {
> >   	{"ov5640", 0},
> >   	{},
> > @@ -3205,6 +3232,7 @@ static struct i2c_driver ov5640_i2c_driver = {
> >   	.driver = {
> >   		.name  = "ov5640",
> >   		.of_match_table	= ov5640_dt_ids,
> > +		.pm = &ov5640_pm_ops,
> >   	},
> >   	.id_table = ov5640_id,
> >   	.probe_new = ov5640_probe,
> > 
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
  2021-05-28  7:23     ` Tomi Valkeinen
@ 2021-05-28  7:30       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:30 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:23AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Some platforms like TI's J721E can have the CSI2RX paired with an
> > external DPHY. Add support to enable and configure the DPHY using the
> > generic PHY framework.
> > 
> > Get the pixel rate and bpp from the subdev and pass them on to the DPHY
> > along with the number of lanes. All other settings are left to their
> > default values.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
> >    calls to set PHY mode, etc. to make sure it is ready.
> > 
> >   drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
> >   1 file changed, 148 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > index c68a3eac62cd..459326de2eff 100644
> > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > @@ -30,6 +30,12 @@
> >   #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
> >   #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
> > +#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
> > +#define CSI2RX_DPHY_CL_RST			BIT(16)
> > +#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
> > +#define CSI2RX_DPHY_CL_EN			BIT(4)
> > +#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
> > +
> >   #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
> >   #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
> > @@ -54,6 +60,11 @@ enum csi2rx_pads {
> >   	CSI2RX_PAD_MAX,
> >   };
> > +struct csi2rx_fmt {
> > +	u32				code;
> > +	u8				bpp;
> > +};
> > +
> >   struct csi2rx_priv {
> >   	struct device			*dev;
> >   	unsigned int			count;
> > @@ -85,6 +96,52 @@ struct csi2rx_priv {
> >   	int				source_pad;
> >   };
> > +static const struct csi2rx_fmt formats[] = {
> > +	{
> > +		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +};
> > +
> > +static u8 csi2rx_get_bpp(u32 code)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(formats); i++) {
> > +		if (formats[i].code == code)
> > +			return formats[i].bpp;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
> > +{
> > +	struct v4l2_ctrl *ctrl;
> > +
> > +	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
> > +			      V4L2_CID_PIXEL_RATE);
> > +	if (!ctrl) {
> > +		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
> > +			csi2rx->source_subdev->name);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return v4l2_ctrl_g_ctrl_int64(ctrl);
> > +}
> > +
> >   static inline
> >   struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
> >   {
> > @@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
> >   	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
> >   }
> > +static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
> > +{
> > +	union phy_configure_opts opts = { };
> > +	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> > +	struct v4l2_subdev_format sd_fmt;
> > +	s64 pixel_rate;
> > +	int ret;
> > +	u8 bpp;
> > +	bool got_pm = true;
> > +
> > +	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > +	sd_fmt.pad = 0;
> > +
> > +	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
> > +			       &sd_fmt);
> > +	if (ret)
> > +		return ret;
> > +
> > +	bpp = csi2rx_get_bpp(sd_fmt.format.code);
> > +	if (!bpp)
> > +		return -EINVAL;
> > +
> > +	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
> > +	if (pixel_rate < 0)
> > +		return pixel_rate;
> > +
> > +	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
> > +					       csi2rx->num_lanes, cfg);
> > +	if (ret)
> > +		return ret;
> 
> I guess the above code works for now, but with multiple streams it won't.
> There's no (single) pixel rate or bpp with multiple streams, and the link
> freq is the one that needs to be used. There's v4l2_get_link_freq() helper
> which makes it easier to support both pixel rate and link freq.

Ok. I will use it instead. The less changes needed when adding 
multistream support the better.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support
@ 2021-05-28  7:30       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-28  7:30 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:23AM, Tomi Valkeinen wrote:
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Some platforms like TI's J721E can have the CSI2RX paired with an
> > external DPHY. Add support to enable and configure the DPHY using the
> > generic PHY framework.
> > 
> > Get the pixel rate and bpp from the subdev and pass them on to the DPHY
> > along with the number of lanes. All other settings are left to their
> > default values.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Use phy_pm_runtime_get_sync() and phy_pm_runtime_put() before making
> >    calls to set PHY mode, etc. to make sure it is ready.
> > 
> >   drivers/media/platform/cadence/cdns-csi2rx.c | 158 +++++++++++++++++--
> >   1 file changed, 148 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > index c68a3eac62cd..459326de2eff 100644
> > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > @@ -30,6 +30,12 @@
> >   #define CSI2RX_STATIC_CFG_DLANE_MAP(llane, plane)	((plane) << (16 + (llane) * 4))
> >   #define CSI2RX_STATIC_CFG_LANES_MASK			GENMASK(11, 8)
> > +#define CSI2RX_DPHY_LANE_CTRL_REG		0x40
> > +#define CSI2RX_DPHY_CL_RST			BIT(16)
> > +#define CSI2RX_DPHY_DL_RST(i)			BIT((i) + 12)
> > +#define CSI2RX_DPHY_CL_EN			BIT(4)
> > +#define CSI2RX_DPHY_DL_EN(i)			BIT(i)
> > +
> >   #define CSI2RX_STREAM_BASE(n)		(((n) + 1) * 0x100)
> >   #define CSI2RX_STREAM_CTRL_REG(n)		(CSI2RX_STREAM_BASE(n) + 0x000)
> > @@ -54,6 +60,11 @@ enum csi2rx_pads {
> >   	CSI2RX_PAD_MAX,
> >   };
> > +struct csi2rx_fmt {
> > +	u32				code;
> > +	u8				bpp;
> > +};
> > +
> >   struct csi2rx_priv {
> >   	struct device			*dev;
> >   	unsigned int			count;
> > @@ -85,6 +96,52 @@ struct csi2rx_priv {
> >   	int				source_pad;
> >   };
> > +static const struct csi2rx_fmt formats[] = {
> > +	{
> > +		.code	= MEDIA_BUS_FMT_YUYV8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_UYVY8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_YVYU8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +	{
> > +		.code	= MEDIA_BUS_FMT_VYUY8_2X8,
> > +		.bpp	= 16,
> > +	},
> > +};
> > +
> > +static u8 csi2rx_get_bpp(u32 code)
> > +{
> > +	int i;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(formats); i++) {
> > +		if (formats[i].code == code)
> > +			return formats[i].bpp;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static s64 csi2rx_get_pixel_rate(struct csi2rx_priv *csi2rx)
> > +{
> > +	struct v4l2_ctrl *ctrl;
> > +
> > +	ctrl = v4l2_ctrl_find(csi2rx->source_subdev->ctrl_handler,
> > +			      V4L2_CID_PIXEL_RATE);
> > +	if (!ctrl) {
> > +		dev_err(csi2rx->dev, "no pixel rate control in subdev: %s\n",
> > +			csi2rx->source_subdev->name);
> > +		return -EINVAL;
> > +	}
> > +
> > +	return v4l2_ctrl_g_ctrl_int64(ctrl);
> > +}
> > +
> >   static inline
> >   struct csi2rx_priv *v4l2_subdev_to_csi2rx(struct v4l2_subdev *subdev)
> >   {
> > @@ -101,6 +158,66 @@ static void csi2rx_reset(struct csi2rx_priv *csi2rx)
> >   	writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG);
> >   }
> > +static int csi2rx_configure_external_dphy(struct csi2rx_priv *csi2rx)
> > +{
> > +	union phy_configure_opts opts = { };
> > +	struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> > +	struct v4l2_subdev_format sd_fmt;
> > +	s64 pixel_rate;
> > +	int ret;
> > +	u8 bpp;
> > +	bool got_pm = true;
> > +
> > +	sd_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> > +	sd_fmt.pad = 0;
> > +
> > +	ret = v4l2_subdev_call(csi2rx->source_subdev, pad, get_fmt, NULL,
> > +			       &sd_fmt);
> > +	if (ret)
> > +		return ret;
> > +
> > +	bpp = csi2rx_get_bpp(sd_fmt.format.code);
> > +	if (!bpp)
> > +		return -EINVAL;
> > +
> > +	pixel_rate = csi2rx_get_pixel_rate(csi2rx);
> > +	if (pixel_rate < 0)
> > +		return pixel_rate;
> > +
> > +	ret = phy_mipi_dphy_get_default_config(pixel_rate, bpp,
> > +					       csi2rx->num_lanes, cfg);
> > +	if (ret)
> > +		return ret;
> 
> I guess the above code works for now, but with multiple streams it won't.
> There's no (single) pixel rate or bpp with multiple streams, and the link
> freq is the one that needs to be used. There's v4l2_get_link_freq() helper
> which makes it easier to support both pixel rate and link freq.

Ok. I will use it instead. The less changes needed when adding 
multistream support the better.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
  2021-05-28  7:24       ` Pratyush Yadav
@ 2021-05-28  7:35         ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:35 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/2021 10:24, Pratyush Yadav wrote:
> On 28/05/21 10:16AM, Tomi Valkeinen wrote:
>> On 26/05/2021 18:23, Pratyush Yadav wrote:
>>> The devnode can be used by media-ctl and other userspace tools to
>>> perform configurations on the subdev. Without it, media-ctl returns
>>> ENOENT when setting format on the sensor subdev.
>>>
>>> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
>>> ---
>>>
>>> (no changes since v1)
>>>
>>>    drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
>>>    1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
>>> index 1df21f462f3c..49bed63d5faa 100644
>>> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
>>> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
>>> @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
>>>    	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>>>    	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
>>>    		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
>>> +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>>>    	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
>>>    				     csi2rx->pads);
>>>
>>
>> I don't understand this one. There's nothing to configure in cdns-csi2rx
>> from userspace, as far as I can see, so why is the dev node needed? And why
>> would the lack of csi2rx dev node cause sensor subdev config to fail?
> 
> Sensor config does not fail. But when I run media-ctl to set the format
> on /dev/media0, I get an error message that comes because the devnode
> for the bridge does not exist. I was not 100% sure about this patch but
> I figured if media-ctl expects it then it should be exposed.
> 
> I don't mind dropping this patch. Just want to make sure what the right
> thing to do here is. Should every element of the pipeline have a devnode
> or not?

Tbh, I don't know. But I don't see why they should have. Also, my test 
works fine if I remove the devnode here.

What media-ctl parameters did you use which fails?

  Tomi

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
@ 2021-05-28  7:35         ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  7:35 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/2021 10:24, Pratyush Yadav wrote:
> On 28/05/21 10:16AM, Tomi Valkeinen wrote:
>> On 26/05/2021 18:23, Pratyush Yadav wrote:
>>> The devnode can be used by media-ctl and other userspace tools to
>>> perform configurations on the subdev. Without it, media-ctl returns
>>> ENOENT when setting format on the sensor subdev.
>>>
>>> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
>>> ---
>>>
>>> (no changes since v1)
>>>
>>>    drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
>>>    1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
>>> index 1df21f462f3c..49bed63d5faa 100644
>>> --- a/drivers/media/platform/cadence/cdns-csi2rx.c
>>> +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
>>> @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
>>>    	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>>>    	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
>>>    		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
>>> +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>>>    	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
>>>    				     csi2rx->pads);
>>>
>>
>> I don't understand this one. There's nothing to configure in cdns-csi2rx
>> from userspace, as far as I can see, so why is the dev node needed? And why
>> would the lack of csi2rx dev node cause sensor subdev config to fail?
> 
> Sensor config does not fail. But when I run media-ctl to set the format
> on /dev/media0, I get an error message that comes because the devnode
> for the bridge does not exist. I was not 100% sure about this patch but
> I figured if media-ctl expects it then it should be exposed.
> 
> I don't mind dropping this patch. Just want to make sure what the right
> thing to do here is. Should every element of the pipeline have a devnode
> or not?

Tbh, I don't know. But I don't see why they should have. Also, my test 
works fine if I remove the devnode here.

What media-ctl parameters did you use which fails?

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 12/18] media: Re-structure TI platform drivers
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-05-28  8:29     ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  8:29 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:23, Pratyush Yadav wrote:
> The ti-vpe/ sub-directory does not only contain the VPE-specific things.
> It also contains the CAL driver, which is a completely different
> subsystem. This is also not a good place to add new drivers for other TI
> platforms since they will all get mixed up.
> 
> Separate the VPE and CAL parts into different sub-directories and rename
> the ti-vpe/ sub-directory to ti/. This is now the place where new TI
> platform drivers can be added.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> Compile tested only. There should be no functional change.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi


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

* Re: [PATCH v2 12/18] media: Re-structure TI platform drivers
@ 2021-05-28  8:29     ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-05-28  8:29 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Chunfeng Yun, Laurent Pinchart

On 26/05/2021 18:23, Pratyush Yadav wrote:
> The ti-vpe/ sub-directory does not only contain the VPE-specific things.
> It also contains the CAL driver, which is a completely different
> subsystem. This is also not a good place to add new drivers for other TI
> platforms since they will all get mixed up.
> 
> Separate the VPE and CAL parts into different sub-directories and rename
> the ti-vpe/ sub-directory to ti/. This is now the place where new TI
> platform drivers can be added.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> Compile tested only. There should be no functional change.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

  Tomi


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-05-31  6:51     ` Péter Ujfalusi
  -1 siblings, 0 replies; 96+ messages in thread
From: Péter Ujfalusi @ 2021-05-31  6:51 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart



On 26/05/2021 18:23, Pratyush Yadav wrote:
> The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
> have up to 32 threads but the current driver only supports using one. So
> add an entry for that one thread.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Add all 64 threads, instead of having only the one thread being
>   currently used by the driver.

How many threads CSI2RX have? 32 (as per commit message) or 64? If I
recall right, it is 32.

> 
>  drivers/dma/ti/k3-psil-j721e.c | 73 ++++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
> 
> diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c
> index 7580870ed746..34e3fc565a37 100644
> --- a/drivers/dma/ti/k3-psil-j721e.c
> +++ b/drivers/dma/ti/k3-psil-j721e.c
> @@ -58,6 +58,14 @@
>  		},					\
>  	}
>  
> +#define PSIL_CSI2RX(x)					\
> +	{						\
> +		.thread_id = x,				\
> +		.ep_config = {				\
> +			.ep_type = PSIL_EP_NATIVE,	\
> +		},					\
> +	}
> +
>  /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
>  static struct psil_ep j721e_src_ep_map[] = {
>  	/* SA2UL */
> @@ -138,6 +146,71 @@ static struct psil_ep j721e_src_ep_map[] = {
>  	PSIL_PDMA_XY_PKT(0x4707),
>  	PSIL_PDMA_XY_PKT(0x4708),
>  	PSIL_PDMA_XY_PKT(0x4709),
> +	/* CSI2RX */
> +	PSIL_CSI2RX(0x4940),
> +	PSIL_CSI2RX(0x4941),
> +	PSIL_CSI2RX(0x4942),
> +	PSIL_CSI2RX(0x4943),
> +	PSIL_CSI2RX(0x4944),
> +	PSIL_CSI2RX(0x4945),
> +	PSIL_CSI2RX(0x4946),
> +	PSIL_CSI2RX(0x4947),
> +	PSIL_CSI2RX(0x4948),
> +	PSIL_CSI2RX(0x4949),
> +	PSIL_CSI2RX(0x494a),
> +	PSIL_CSI2RX(0x494b),
> +	PSIL_CSI2RX(0x494c),
> +	PSIL_CSI2RX(0x494d),
> +	PSIL_CSI2RX(0x494e),
> +	PSIL_CSI2RX(0x494f),
> +	PSIL_CSI2RX(0x4950),
> +	PSIL_CSI2RX(0x4951),
> +	PSIL_CSI2RX(0x4952),
> +	PSIL_CSI2RX(0x4953),
> +	PSIL_CSI2RX(0x4954),
> +	PSIL_CSI2RX(0x4955),
> +	PSIL_CSI2RX(0x4956),
> +	PSIL_CSI2RX(0x4957),
> +	PSIL_CSI2RX(0x4958),
> +	PSIL_CSI2RX(0x4959),
> +	PSIL_CSI2RX(0x495a),
> +	PSIL_CSI2RX(0x495b),
> +	PSIL_CSI2RX(0x495c),
> +	PSIL_CSI2RX(0x495d),
> +	PSIL_CSI2RX(0x495e),
> +	PSIL_CSI2RX(0x495f),
> +	PSIL_CSI2RX(0x4960),
> +	PSIL_CSI2RX(0x4961),
> +	PSIL_CSI2RX(0x4962),
> +	PSIL_CSI2RX(0x4963),
> +	PSIL_CSI2RX(0x4964),
> +	PSIL_CSI2RX(0x4965),
> +	PSIL_CSI2RX(0x4966),
> +	PSIL_CSI2RX(0x4967),
> +	PSIL_CSI2RX(0x4968),
> +	PSIL_CSI2RX(0x4969),
> +	PSIL_CSI2RX(0x496a),
> +	PSIL_CSI2RX(0x496b),
> +	PSIL_CSI2RX(0x496c),
> +	PSIL_CSI2RX(0x496d),
> +	PSIL_CSI2RX(0x496e),
> +	PSIL_CSI2RX(0x496f),
> +	PSIL_CSI2RX(0x4970),
> +	PSIL_CSI2RX(0x4971),
> +	PSIL_CSI2RX(0x4972),
> +	PSIL_CSI2RX(0x4973),
> +	PSIL_CSI2RX(0x4974),
> +	PSIL_CSI2RX(0x4975),
> +	PSIL_CSI2RX(0x4976),
> +	PSIL_CSI2RX(0x4977),
> +	PSIL_CSI2RX(0x4978),
> +	PSIL_CSI2RX(0x4979),
> +	PSIL_CSI2RX(0x497a),
> +	PSIL_CSI2RX(0x497b),
> +	PSIL_CSI2RX(0x497c),
> +	PSIL_CSI2RX(0x497d),
> +	PSIL_CSI2RX(0x497e),
> +	PSIL_CSI2RX(0x497f),
>  	/* CPSW9 */
>  	PSIL_ETHERNET(0x4a00),
>  	/* CPSW0 */
> 

-- 
Péter

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

* Re: [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
@ 2021-05-31  6:51     ` Péter Ujfalusi
  0 siblings, 0 replies; 96+ messages in thread
From: Péter Ujfalusi @ 2021-05-31  6:51 UTC (permalink / raw)
  To: Pratyush Yadav, Maxime Ripard, Mauro Carvalho Chehab,
	Rob Herring, Kishon Vijay Abraham I, Vinod Koul,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine
  Cc: Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun, Laurent Pinchart



On 26/05/2021 18:23, Pratyush Yadav wrote:
> The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
> have up to 32 threads but the current driver only supports using one. So
> add an entry for that one thread.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Add all 64 threads, instead of having only the one thread being
>   currently used by the driver.

How many threads CSI2RX have? 32 (as per commit message) or 64? If I
recall right, it is 32.

> 
>  drivers/dma/ti/k3-psil-j721e.c | 73 ++++++++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
> 
> diff --git a/drivers/dma/ti/k3-psil-j721e.c b/drivers/dma/ti/k3-psil-j721e.c
> index 7580870ed746..34e3fc565a37 100644
> --- a/drivers/dma/ti/k3-psil-j721e.c
> +++ b/drivers/dma/ti/k3-psil-j721e.c
> @@ -58,6 +58,14 @@
>  		},					\
>  	}
>  
> +#define PSIL_CSI2RX(x)					\
> +	{						\
> +		.thread_id = x,				\
> +		.ep_config = {				\
> +			.ep_type = PSIL_EP_NATIVE,	\
> +		},					\
> +	}
> +
>  /* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */
>  static struct psil_ep j721e_src_ep_map[] = {
>  	/* SA2UL */
> @@ -138,6 +146,71 @@ static struct psil_ep j721e_src_ep_map[] = {
>  	PSIL_PDMA_XY_PKT(0x4707),
>  	PSIL_PDMA_XY_PKT(0x4708),
>  	PSIL_PDMA_XY_PKT(0x4709),
> +	/* CSI2RX */
> +	PSIL_CSI2RX(0x4940),
> +	PSIL_CSI2RX(0x4941),
> +	PSIL_CSI2RX(0x4942),
> +	PSIL_CSI2RX(0x4943),
> +	PSIL_CSI2RX(0x4944),
> +	PSIL_CSI2RX(0x4945),
> +	PSIL_CSI2RX(0x4946),
> +	PSIL_CSI2RX(0x4947),
> +	PSIL_CSI2RX(0x4948),
> +	PSIL_CSI2RX(0x4949),
> +	PSIL_CSI2RX(0x494a),
> +	PSIL_CSI2RX(0x494b),
> +	PSIL_CSI2RX(0x494c),
> +	PSIL_CSI2RX(0x494d),
> +	PSIL_CSI2RX(0x494e),
> +	PSIL_CSI2RX(0x494f),
> +	PSIL_CSI2RX(0x4950),
> +	PSIL_CSI2RX(0x4951),
> +	PSIL_CSI2RX(0x4952),
> +	PSIL_CSI2RX(0x4953),
> +	PSIL_CSI2RX(0x4954),
> +	PSIL_CSI2RX(0x4955),
> +	PSIL_CSI2RX(0x4956),
> +	PSIL_CSI2RX(0x4957),
> +	PSIL_CSI2RX(0x4958),
> +	PSIL_CSI2RX(0x4959),
> +	PSIL_CSI2RX(0x495a),
> +	PSIL_CSI2RX(0x495b),
> +	PSIL_CSI2RX(0x495c),
> +	PSIL_CSI2RX(0x495d),
> +	PSIL_CSI2RX(0x495e),
> +	PSIL_CSI2RX(0x495f),
> +	PSIL_CSI2RX(0x4960),
> +	PSIL_CSI2RX(0x4961),
> +	PSIL_CSI2RX(0x4962),
> +	PSIL_CSI2RX(0x4963),
> +	PSIL_CSI2RX(0x4964),
> +	PSIL_CSI2RX(0x4965),
> +	PSIL_CSI2RX(0x4966),
> +	PSIL_CSI2RX(0x4967),
> +	PSIL_CSI2RX(0x4968),
> +	PSIL_CSI2RX(0x4969),
> +	PSIL_CSI2RX(0x496a),
> +	PSIL_CSI2RX(0x496b),
> +	PSIL_CSI2RX(0x496c),
> +	PSIL_CSI2RX(0x496d),
> +	PSIL_CSI2RX(0x496e),
> +	PSIL_CSI2RX(0x496f),
> +	PSIL_CSI2RX(0x4970),
> +	PSIL_CSI2RX(0x4971),
> +	PSIL_CSI2RX(0x4972),
> +	PSIL_CSI2RX(0x4973),
> +	PSIL_CSI2RX(0x4974),
> +	PSIL_CSI2RX(0x4975),
> +	PSIL_CSI2RX(0x4976),
> +	PSIL_CSI2RX(0x4977),
> +	PSIL_CSI2RX(0x4978),
> +	PSIL_CSI2RX(0x4979),
> +	PSIL_CSI2RX(0x497a),
> +	PSIL_CSI2RX(0x497b),
> +	PSIL_CSI2RX(0x497c),
> +	PSIL_CSI2RX(0x497d),
> +	PSIL_CSI2RX(0x497e),
> +	PSIL_CSI2RX(0x497f),
>  	/* CPSW9 */
>  	PSIL_ETHERNET(0x4a00),
>  	/* CPSW0 */
> 

-- 
Péter

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
  2021-05-31  6:51     ` Péter Ujfalusi
@ 2021-05-31  9:16       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-31  9:16 UTC (permalink / raw)
  To: Péter Ujfalusi
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Steve Longerbeam,
	Benoit Parrot, linux-media, devicetree, linux-kernel, linux-phy,
	dmaengine, Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 31/05/21 09:51AM, Péter Ujfalusi wrote:
> 
> 
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
> > have up to 32 threads but the current driver only supports using one. So
> > add an entry for that one thread.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Add all 64 threads, instead of having only the one thread being
> >   currently used by the driver.
> 
> How many threads CSI2RX have? 32 (as per commit message) or 64? If I
> recall right, it is 32.

Ah, sorry I forgot to update the commit message. Each instance of CSI2RX 
has 32 threads, and J721E has 2 instances. So 64 threads total.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX
@ 2021-05-31  9:16       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-05-31  9:16 UTC (permalink / raw)
  To: Péter Ujfalusi
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Steve Longerbeam,
	Benoit Parrot, linux-media, devicetree, linux-kernel, linux-phy,
	dmaengine, Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 31/05/21 09:51AM, Péter Ujfalusi wrote:
> 
> 
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > The CSI2RX subsystem uses PSI-L DMA to transfer frames to memory. It can
> > have up to 32 threads but the current driver only supports using one. So
> > add an entry for that one thread.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Add all 64 threads, instead of having only the one thread being
> >   currently used by the driver.
> 
> How many threads CSI2RX have? 32 (as per commit message) or 64? If I
> recall right, it is 32.

Ah, sorry I forgot to update the commit message. Each instance of CSI2RX 
has 32 threads, and J721E has 2 instances. So 64 threads total.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-06-01 17:45     ` Rob Herring
  -1 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-01 17:45 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On Wed, May 26, 2021 at 08:53:05PM +0530, Pratyush Yadav wrote:
> Convert the Cadence CSI2RX binding to use YAML schema.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - New in v2.
> 
>  .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
>  .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
>  2 files changed, 164 insertions(+), 100 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
>  create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> deleted file mode 100644
> index 6b02a0657ad9..000000000000
> --- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -Cadence MIPI-CSI2 RX controller
> -===============================
> -
> -The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> -lanes in input, and 4 different pixel streams in output.
> -
> -Required properties:
> -  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
> -  - reg: base address and size of the memory mapped region
> -  - clocks: phandles to the clocks driving the controller
> -  - clock-names: must contain:
> -    * sys_clk: main clock
> -    * p_clk: register bank clock
> -    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
> -                         implemented in hardware, between 0 and 3
> -
> -Optional properties:
> -  - phys: phandle to the external D-PHY, phy-names must be provided
> -  - phy-names: must contain "dphy", if the implementation uses an
> -               external D-PHY
> -
> -Required subnodes:
> -  - ports: A ports node with one port child node per device input and output
> -           port, in accordance with the video interface bindings defined in
> -           Documentation/devicetree/bindings/media/video-interfaces.txt. The
> -           port nodes are numbered as follows:
> -
> -           Port Description
> -           -----------------------------
> -           0    CSI-2 input
> -           1    Stream 0 output
> -           2    Stream 1 output
> -           3    Stream 2 output
> -           4    Stream 3 output
> -
> -           The stream output port nodes are optional if they are not
> -           connected to anything at the hardware level or implemented
> -           in the design.Since there is only one endpoint per port,
> -           the endpoints are not numbered.
> -
> -
> -Example:
> -
> -csi2rx: csi-bridge@0d060000 {
> -	compatible = "cdns,csi2rx";
> -	reg = <0x0d060000 0x1000>;
> -	clocks = <&byteclock>, <&byteclock>
> -		 <&coreclock>, <&coreclock>,
> -		 <&coreclock>, <&coreclock>;
> -	clock-names = "sys_clk", "p_clk",
> -		      "pixel_if0_clk", "pixel_if1_clk",
> -		      "pixel_if2_clk", "pixel_if3_clk";
> -
> -	ports {
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -
> -		port@0 {
> -			reg = <0>;
> -
> -			csi2rx_in_sensor: endpoint {
> -				remote-endpoint = <&sensor_out_csi2rx>;
> -				clock-lanes = <0>;
> -				data-lanes = <1 2>;
> -			};
> -		};
> -
> -		port@1 {
> -			reg = <1>;
> -
> -			csi2rx_out_grabber0: endpoint {
> -				remote-endpoint = <&grabber0_in_csi2rx>;
> -			};
> -		};
> -
> -		port@2 {
> -			reg = <2>;
> -
> -			csi2rx_out_grabber1: endpoint {
> -				remote-endpoint = <&grabber1_in_csi2rx>;
> -			};
> -		};
> -
> -		port@3 {
> -			reg = <3>;
> -
> -			csi2rx_out_grabber2: endpoint {
> -				remote-endpoint = <&grabber2_in_csi2rx>;
> -			};
> -		};
> -
> -		port@4 {
> -			reg = <4>;
> -
> -			csi2rx_out_grabber3: endpoint {
> -				remote-endpoint = <&grabber3_in_csi2rx>;
> -			};
> -		};
> -	};
> -};
> diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> new file mode 100644
> index 000000000000..ff5dd4211ac9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> @@ -0,0 +1,164 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cadence MIPI-CSI2 RX controller
> +
> +description: |
> +  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> +  lanes in input, and 4 different pixel streams in output.
> +
> +maintainers:
> +  - Pratyush Yadav <p.yadav@ti.com>
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: cdns,csi2rx

Since there has to be an SoC specific compatible, this should be:

compatible:
  contains:
    const: cdns,csi2rx

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 3
> +    maxItems: 6
> +
> +  clock-names:
> +    minItems: 3
> +    maxItems: 6
> +    items:
> +      - const: sys_clk # main clock
> +      - const: p_clk # register bank clock
> +      - const: pixel_if0_clk # pixel stream 0 output clock
> +      - const: pixel_if1_clk # pixel stream 1 output clock
> +      - const: pixel_if2_clk # pixel stream 2 output clock
> +      - const: pixel_if3_clk # pixel stream 3 output clock
> +
> +  phys:
> +    maxItems: 1
> +    description: phandle to the external D-PHY
> +
> +  phy-names:
> +    items:
> +      - const: dphy
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port@0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description: CSI-2 input
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                maxItems: 1

If there's only 1 lane, are you assigning between clock and data lanes? 
If not, then there's no mapping needed.

> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 0 output
> +
> +      port@2:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 1 output
> +
> +      port@3:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 2 output
> +
> +      port@4:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 3 output
> +
> +    required:
> +      - port@0
> +
> +
> +dependencies:
> +  phys: [ 'phy-names' ]
> +  phy-names: [ 'phys' ]
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    csi2rx: csi-bridge@d060000 {
> +      compatible = "cdns,csi2rx";
> +      reg = <0x0d060000 0x1000>;
> +      clocks = <&byteclock>, <&byteclock>,
> +        <&coreclock>, <&coreclock>,
> +        <&coreclock>, <&coreclock>;
> +      clock-names = "sys_clk", "p_clk",
> +              "pixel_if0_clk", "pixel_if1_clk",
> +              "pixel_if2_clk", "pixel_if3_clk";
> +      phys = <&dphy0>;
> +      phy-names = "dphy";
> +
> +      ports {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port@0 {
> +          reg = <0>;
> +
> +          csi2rx_in_sensor: endpoint {
> +            remote-endpoint = <&sensor_out_csi2rx>;
> +            clock-lanes = <0>;
> +            data-lanes = <1 2>;
> +          };
> +        };
> +
> +        port@1 {
> +          reg = <1>;
> +
> +          csi2rx_out_grabber0: endpoint {
> +            remote-endpoint = <&grabber0_in_csi2rx>;
> +          };
> +        };
> +
> +        port@2 {
> +          reg = <2>;
> +
> +          csi2rx_out_grabber1: endpoint {
> +            remote-endpoint = <&grabber1_in_csi2rx>;
> +          };
> +        };
> +
> +        port@3 {
> +          reg = <3>;
> +
> +          csi2rx_out_grabber2: endpoint {
> +            remote-endpoint = <&grabber2_in_csi2rx>;
> +          };
> +        };
> +
> +        port@4 {
> +          reg = <4>;
> +
> +          csi2rx_out_grabber3: endpoint {
> +            remote-endpoint = <&grabber3_in_csi2rx>;
> +          };
> +        };
> +      };
> +    };
> -- 
> 2.30.0

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

* Re: [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
@ 2021-06-01 17:45     ` Rob Herring
  0 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-01 17:45 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On Wed, May 26, 2021 at 08:53:05PM +0530, Pratyush Yadav wrote:
> Convert the Cadence CSI2RX binding to use YAML schema.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - New in v2.
> 
>  .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
>  .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
>  2 files changed, 164 insertions(+), 100 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
>  create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> deleted file mode 100644
> index 6b02a0657ad9..000000000000
> --- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> +++ /dev/null
> @@ -1,100 +0,0 @@
> -Cadence MIPI-CSI2 RX controller
> -===============================
> -
> -The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> -lanes in input, and 4 different pixel streams in output.
> -
> -Required properties:
> -  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
> -  - reg: base address and size of the memory mapped region
> -  - clocks: phandles to the clocks driving the controller
> -  - clock-names: must contain:
> -    * sys_clk: main clock
> -    * p_clk: register bank clock
> -    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
> -                         implemented in hardware, between 0 and 3
> -
> -Optional properties:
> -  - phys: phandle to the external D-PHY, phy-names must be provided
> -  - phy-names: must contain "dphy", if the implementation uses an
> -               external D-PHY
> -
> -Required subnodes:
> -  - ports: A ports node with one port child node per device input and output
> -           port, in accordance with the video interface bindings defined in
> -           Documentation/devicetree/bindings/media/video-interfaces.txt. The
> -           port nodes are numbered as follows:
> -
> -           Port Description
> -           -----------------------------
> -           0    CSI-2 input
> -           1    Stream 0 output
> -           2    Stream 1 output
> -           3    Stream 2 output
> -           4    Stream 3 output
> -
> -           The stream output port nodes are optional if they are not
> -           connected to anything at the hardware level or implemented
> -           in the design.Since there is only one endpoint per port,
> -           the endpoints are not numbered.
> -
> -
> -Example:
> -
> -csi2rx: csi-bridge@0d060000 {
> -	compatible = "cdns,csi2rx";
> -	reg = <0x0d060000 0x1000>;
> -	clocks = <&byteclock>, <&byteclock>
> -		 <&coreclock>, <&coreclock>,
> -		 <&coreclock>, <&coreclock>;
> -	clock-names = "sys_clk", "p_clk",
> -		      "pixel_if0_clk", "pixel_if1_clk",
> -		      "pixel_if2_clk", "pixel_if3_clk";
> -
> -	ports {
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -
> -		port@0 {
> -			reg = <0>;
> -
> -			csi2rx_in_sensor: endpoint {
> -				remote-endpoint = <&sensor_out_csi2rx>;
> -				clock-lanes = <0>;
> -				data-lanes = <1 2>;
> -			};
> -		};
> -
> -		port@1 {
> -			reg = <1>;
> -
> -			csi2rx_out_grabber0: endpoint {
> -				remote-endpoint = <&grabber0_in_csi2rx>;
> -			};
> -		};
> -
> -		port@2 {
> -			reg = <2>;
> -
> -			csi2rx_out_grabber1: endpoint {
> -				remote-endpoint = <&grabber1_in_csi2rx>;
> -			};
> -		};
> -
> -		port@3 {
> -			reg = <3>;
> -
> -			csi2rx_out_grabber2: endpoint {
> -				remote-endpoint = <&grabber2_in_csi2rx>;
> -			};
> -		};
> -
> -		port@4 {
> -			reg = <4>;
> -
> -			csi2rx_out_grabber3: endpoint {
> -				remote-endpoint = <&grabber3_in_csi2rx>;
> -			};
> -		};
> -	};
> -};
> diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> new file mode 100644
> index 000000000000..ff5dd4211ac9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> @@ -0,0 +1,164 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cadence MIPI-CSI2 RX controller
> +
> +description: |
> +  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> +  lanes in input, and 4 different pixel streams in output.
> +
> +maintainers:
> +  - Pratyush Yadav <p.yadav@ti.com>
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: cdns,csi2rx

Since there has to be an SoC specific compatible, this should be:

compatible:
  contains:
    const: cdns,csi2rx

> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 3
> +    maxItems: 6
> +
> +  clock-names:
> +    minItems: 3
> +    maxItems: 6
> +    items:
> +      - const: sys_clk # main clock
> +      - const: p_clk # register bank clock
> +      - const: pixel_if0_clk # pixel stream 0 output clock
> +      - const: pixel_if1_clk # pixel stream 1 output clock
> +      - const: pixel_if2_clk # pixel stream 2 output clock
> +      - const: pixel_if3_clk # pixel stream 3 output clock
> +
> +  phys:
> +    maxItems: 1
> +    description: phandle to the external D-PHY
> +
> +  phy-names:
> +    items:
> +      - const: dphy
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port@0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false
> +        description: CSI-2 input
> +
> +        properties:
> +          endpoint:
> +            $ref: video-interfaces.yaml#
> +            unevaluatedProperties: false
> +
> +            properties:
> +              clock-lanes:
> +                maxItems: 1
> +
> +              data-lanes:
> +                maxItems: 1

If there's only 1 lane, are you assigning between clock and data lanes? 
If not, then there's no mapping needed.

> +
> +            required:
> +              - clock-lanes
> +              - data-lanes
> +
> +      port@1:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 0 output
> +
> +      port@2:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 1 output
> +
> +      port@3:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 2 output
> +
> +      port@4:
> +        $ref: /schemas/graph.yaml#/properties/port
> +        description: Stream 3 output
> +
> +    required:
> +      - port@0
> +
> +
> +dependencies:
> +  phys: [ 'phy-names' ]
> +  phy-names: [ 'phys' ]
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    csi2rx: csi-bridge@d060000 {
> +      compatible = "cdns,csi2rx";
> +      reg = <0x0d060000 0x1000>;
> +      clocks = <&byteclock>, <&byteclock>,
> +        <&coreclock>, <&coreclock>,
> +        <&coreclock>, <&coreclock>;
> +      clock-names = "sys_clk", "p_clk",
> +              "pixel_if0_clk", "pixel_if1_clk",
> +              "pixel_if2_clk", "pixel_if3_clk";
> +      phys = <&dphy0>;
> +      phy-names = "dphy";
> +
> +      ports {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        port@0 {
> +          reg = <0>;
> +
> +          csi2rx_in_sensor: endpoint {
> +            remote-endpoint = <&sensor_out_csi2rx>;
> +            clock-lanes = <0>;
> +            data-lanes = <1 2>;
> +          };
> +        };
> +
> +        port@1 {
> +          reg = <1>;
> +
> +          csi2rx_out_grabber0: endpoint {
> +            remote-endpoint = <&grabber0_in_csi2rx>;
> +          };
> +        };
> +
> +        port@2 {
> +          reg = <2>;
> +
> +          csi2rx_out_grabber1: endpoint {
> +            remote-endpoint = <&grabber1_in_csi2rx>;
> +          };
> +        };
> +
> +        port@3 {
> +          reg = <3>;
> +
> +          csi2rx_out_grabber2: endpoint {
> +            remote-endpoint = <&grabber2_in_csi2rx>;
> +          };
> +        };
> +
> +        port@4 {
> +          reg = <4>;
> +
> +          csi2rx_out_grabber3: endpoint {
> +            remote-endpoint = <&grabber3_in_csi2rx>;
> +          };
> +        };
> +      };
> +    };
> -- 
> 2.30.0

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-06-02 13:27     ` Maxime Ripard
  -1 siblings, 0 replies; 96+ messages in thread
From: Maxime Ripard @ 2021-06-02 13:27 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Mauro Carvalho Chehab, Rob Herring, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

Hi,

On Wed, May 26, 2021 at 08:53:07PM +0530, Pratyush Yadav wrote:
> The clocks are not used by the DPHY when used in Rx mode so make them
> optional.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> index b90a58773bf2..3bb5be05e825 100644
> --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> @@ -33,8 +33,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - clocks
> -  - clock-names

As far as I can remember from the cadence documentation, those clocks
were required. I guess this is the integration that provides a few fixed
clocks?

Maxime

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
@ 2021-06-02 13:27     ` Maxime Ripard
  0 siblings, 0 replies; 96+ messages in thread
From: Maxime Ripard @ 2021-06-02 13:27 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Mauro Carvalho Chehab, Rob Herring, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

Hi,

On Wed, May 26, 2021 at 08:53:07PM +0530, Pratyush Yadav wrote:
> The clocks are not used by the DPHY when used in Rx mode so make them
> optional.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> index b90a58773bf2..3bb5be05e825 100644
> --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> @@ -33,8 +33,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - clocks
> -  - clock-names

As far as I can remember from the cadence documentation, those clocks
were required. I guess this is the integration that provides a few fixed
clocks?

Maxime

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 16/18] phy: dt-bindings: Convert Cadence DPHY binding to YAML
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-06-02 19:51     ` Rob Herring
  -1 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 19:51 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Kishon Vijay Abraham I, Tomi Valkeinen, Maxime Ripard,
	Laurent Pinchart, Vignesh Raghavendra, linux-kernel, devicetree,
	linux-phy, Rob Herring, Steve Longerbeam, Mauro Carvalho Chehab,
	linux-media, Peter Ujfalusi, dmaengine, Benoit Parrot,
	Vinod Koul, Chunfeng Yun

On Wed, 26 May 2021 20:53:06 +0530, Pratyush Yadav wrote:
> Convert Cadence DPHY binding to YAML.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> ---
> 
> Changes in v2:
> - Drop reg description.
> - Add a description for each DPHY clock.
> - Rename dphy@... to phy@... in example.
> - Add Laurent's R-by.
> - Re-order subject prefixes.
> 
>  .../devicetree/bindings/phy/cdns,dphy.txt     | 20 --------
>  .../devicetree/bindings/phy/cdns,dphy.yaml    | 51 +++++++++++++++++++
>  2 files changed, 51 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
>  create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v2 16/18] phy: dt-bindings: Convert Cadence DPHY binding to YAML
@ 2021-06-02 19:51     ` Rob Herring
  0 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 19:51 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Kishon Vijay Abraham I, Tomi Valkeinen, Maxime Ripard,
	Laurent Pinchart, Vignesh Raghavendra, linux-kernel, devicetree,
	linux-phy, Rob Herring, Steve Longerbeam, Mauro Carvalho Chehab,
	linux-media, Peter Ujfalusi, dmaengine, Benoit Parrot,
	Vinod Koul, Chunfeng Yun

On Wed, 26 May 2021 20:53:06 +0530, Pratyush Yadav wrote:
> Convert Cadence DPHY binding to YAML.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> ---
> 
> Changes in v2:
> - Drop reg description.
> - Add a description for each DPHY clock.
> - Rename dphy@... to phy@... in example.
> - Add Laurent's R-by.
> - Re-order subject prefixes.
> 
>  .../devicetree/bindings/phy/cdns,dphy.txt     | 20 --------
>  .../devicetree/bindings/phy/cdns,dphy.yaml    | 51 +++++++++++++++++++
>  2 files changed, 51 insertions(+), 20 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.txt
>  create mode 100644 Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
  2021-05-26 15:23   ` Pratyush Yadav
@ 2021-06-02 20:03     ` Rob Herring
  -1 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 20:03 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: devicetree, linux-media, Vinod Koul, Steve Longerbeam,
	Benoit Parrot, Mauro Carvalho Chehab, Vignesh Raghavendra,
	Rob Herring, Kishon Vijay Abraham I, Peter Ujfalusi, linux-phy,
	dmaengine, Maxime Ripard, Chunfeng Yun, Tomi Valkeinen,
	Laurent Pinchart, linux-kernel

On Wed, 26 May 2021 20:53:07 +0530, Pratyush Yadav wrote:
> The clocks are not used by the DPHY when used in Rx mode so make them
> optional.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
>  1 file changed, 2 deletions(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
@ 2021-06-02 20:03     ` Rob Herring
  0 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 20:03 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: devicetree, linux-media, Vinod Koul, Steve Longerbeam,
	Benoit Parrot, Mauro Carvalho Chehab, Vignesh Raghavendra,
	Rob Herring, Kishon Vijay Abraham I, Peter Ujfalusi, linux-phy,
	dmaengine, Maxime Ripard, Chunfeng Yun, Tomi Valkeinen,
	Laurent Pinchart, linux-kernel

On Wed, 26 May 2021 20:53:07 +0530, Pratyush Yadav wrote:
> The clocks are not used by the DPHY when used in Rx mode so make them
> optional.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> ---
> 
> Changes in v2:
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
>  1 file changed, 2 deletions(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 18/18] phy: dt-bindings: cdns,dphy: add power-domains property
  2021-05-26 15:23   ` [PATCH v2 18/18] phy: dt-bindings: cdns, dphy: " Pratyush Yadav
@ 2021-06-02 20:03     ` Rob Herring
  -1 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 20:03 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: devicetree, Laurent Pinchart, Maxime Ripard, linux-kernel,
	Steve Longerbeam, linux-phy, dmaengine, Vignesh Raghavendra,
	Tomi Valkeinen, Kishon Vijay Abraham I, Peter Ujfalusi,
	Rob Herring, Chunfeng Yun, Mauro Carvalho Chehab, linux-media,
	Vinod Koul, Benoit Parrot

On Wed, 26 May 2021 20:53:08 +0530, Pratyush Yadav wrote:
> This property is needed on TI platforms to enable the PD of the DPHY
> before it can be used.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> ---
> 
> Changes in v2:
> - Add power-domain to the example.
> - Add Laurent's R-by.
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v2 18/18] phy: dt-bindings: cdns,dphy: add power-domains property
@ 2021-06-02 20:03     ` Rob Herring
  0 siblings, 0 replies; 96+ messages in thread
From: Rob Herring @ 2021-06-02 20:03 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: devicetree, Laurent Pinchart, Maxime Ripard, linux-kernel,
	Steve Longerbeam, linux-phy, dmaengine, Vignesh Raghavendra,
	Tomi Valkeinen, Kishon Vijay Abraham I, Peter Ujfalusi,
	Rob Herring, Chunfeng Yun, Mauro Carvalho Chehab, linux-media,
	Vinod Koul, Benoit Parrot

On Wed, 26 May 2021 20:53:08 +0530, Pratyush Yadav wrote:
> This property is needed on TI platforms to enable the PD of the DPHY
> before it can be used.
> 
> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
> ---
> 
> Changes in v2:
> - Add power-domain to the example.
> - Add Laurent's R-by.
> - Re-order subject prefixes.
> 
>  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
  2021-06-02 13:27     ` Maxime Ripard
@ 2021-06-03  8:16       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03  8:16 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mauro Carvalho Chehab, Rob Herring, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 02/06/21 03:27PM, Maxime Ripard wrote:
> Hi,
> 
> On Wed, May 26, 2021 at 08:53:07PM +0530, Pratyush Yadav wrote:
> > The clocks are not used by the DPHY when used in Rx mode so make them
> > optional.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Re-order subject prefixes.
> > 
> >  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > index b90a58773bf2..3bb5be05e825 100644
> > --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > @@ -33,8 +33,6 @@ properties:
> >  required:
> >    - compatible
> >    - reg
> > -  - clocks
> > -  - clock-names
> 
> As far as I can remember from the cadence documentation, those clocks
> were required. I guess this is the integration that provides a few fixed
> clocks?

Yes. The clock divider/frequency has been set via the DPHY pins so no 
need to set them via software.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional
@ 2021-06-03  8:16       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03  8:16 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Mauro Carvalho Chehab, Rob Herring, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 02/06/21 03:27PM, Maxime Ripard wrote:
> Hi,
> 
> On Wed, May 26, 2021 at 08:53:07PM +0530, Pratyush Yadav wrote:
> > The clocks are not used by the DPHY when used in Rx mode so make them
> > optional.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Re-order subject prefixes.
> > 
> >  Documentation/devicetree/bindings/phy/cdns,dphy.yaml | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > index b90a58773bf2..3bb5be05e825 100644
> > --- a/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/cdns,dphy.yaml
> > @@ -33,8 +33,6 @@ properties:
> >  required:
> >    - compatible
> >    - reg
> > -  - clocks
> > -  - clock-names
> 
> As far as I can remember from the cadence documentation, those clocks
> were required. I guess this is the integration that provides a few fixed
> clocks?

Yes. The clock divider/frequency has been set via the DPHY pins so no 
need to set them via software.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
  2021-06-01 17:45     ` Rob Herring
@ 2021-06-03 12:23       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 01/06/21 12:45PM, Rob Herring wrote:
> On Wed, May 26, 2021 at 08:53:05PM +0530, Pratyush Yadav wrote:
> > Convert the Cadence CSI2RX binding to use YAML schema.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - New in v2.
> > 
> >  .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
> >  .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
> >  2 files changed, 164 insertions(+), 100 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> >  create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> > deleted file mode 100644
> > index 6b02a0657ad9..000000000000
> > --- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> > +++ /dev/null
> > @@ -1,100 +0,0 @@
> > -Cadence MIPI-CSI2 RX controller
> > -===============================
> > -
> > -The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> > -lanes in input, and 4 different pixel streams in output.
> > -
> > -Required properties:
> > -  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
> > -  - reg: base address and size of the memory mapped region
> > -  - clocks: phandles to the clocks driving the controller
> > -  - clock-names: must contain:
> > -    * sys_clk: main clock
> > -    * p_clk: register bank clock
> > -    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
> > -                         implemented in hardware, between 0 and 3
> > -
> > -Optional properties:
> > -  - phys: phandle to the external D-PHY, phy-names must be provided
> > -  - phy-names: must contain "dphy", if the implementation uses an
> > -               external D-PHY
> > -
> > -Required subnodes:
> > -  - ports: A ports node with one port child node per device input and output
> > -           port, in accordance with the video interface bindings defined in
> > -           Documentation/devicetree/bindings/media/video-interfaces.txt. The
> > -           port nodes are numbered as follows:
> > -
> > -           Port Description
> > -           -----------------------------
> > -           0    CSI-2 input
> > -           1    Stream 0 output
> > -           2    Stream 1 output
> > -           3    Stream 2 output
> > -           4    Stream 3 output
> > -
> > -           The stream output port nodes are optional if they are not
> > -           connected to anything at the hardware level or implemented
> > -           in the design.Since there is only one endpoint per port,
> > -           the endpoints are not numbered.
> > -
> > -
> > -Example:
> > -
> > -csi2rx: csi-bridge@0d060000 {
> > -	compatible = "cdns,csi2rx";
> > -	reg = <0x0d060000 0x1000>;
> > -	clocks = <&byteclock>, <&byteclock>
> > -		 <&coreclock>, <&coreclock>,
> > -		 <&coreclock>, <&coreclock>;
> > -	clock-names = "sys_clk", "p_clk",
> > -		      "pixel_if0_clk", "pixel_if1_clk",
> > -		      "pixel_if2_clk", "pixel_if3_clk";
> > -
> > -	ports {
> > -		#address-cells = <1>;
> > -		#size-cells = <0>;
> > -
> > -		port@0 {
> > -			reg = <0>;
> > -
> > -			csi2rx_in_sensor: endpoint {
> > -				remote-endpoint = <&sensor_out_csi2rx>;
> > -				clock-lanes = <0>;
> > -				data-lanes = <1 2>;
> > -			};
> > -		};
> > -
> > -		port@1 {
> > -			reg = <1>;
> > -
> > -			csi2rx_out_grabber0: endpoint {
> > -				remote-endpoint = <&grabber0_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@2 {
> > -			reg = <2>;
> > -
> > -			csi2rx_out_grabber1: endpoint {
> > -				remote-endpoint = <&grabber1_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@3 {
> > -			reg = <3>;
> > -
> > -			csi2rx_out_grabber2: endpoint {
> > -				remote-endpoint = <&grabber2_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@4 {
> > -			reg = <4>;
> > -
> > -			csi2rx_out_grabber3: endpoint {
> > -				remote-endpoint = <&grabber3_in_csi2rx>;
> > -			};
> > -		};
> > -	};
> > -};
> > diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > new file mode 100644
> > index 000000000000..ff5dd4211ac9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > @@ -0,0 +1,164 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Cadence MIPI-CSI2 RX controller
> > +
> > +description: |
> > +  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> > +  lanes in input, and 4 different pixel streams in output.
> > +
> > +maintainers:
> > +  - Pratyush Yadav <p.yadav@ti.com>
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: cdns,csi2rx
> 
> Since there has to be an SoC specific compatible, this should be:
> 
> compatible:
>   contains:
>     const: cdns,csi2rx

Ok.

> 
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    minItems: 3
> > +    maxItems: 6
> > +
> > +  clock-names:
> > +    minItems: 3
> > +    maxItems: 6
> > +    items:
> > +      - const: sys_clk # main clock
> > +      - const: p_clk # register bank clock
> > +      - const: pixel_if0_clk # pixel stream 0 output clock
> > +      - const: pixel_if1_clk # pixel stream 1 output clock
> > +      - const: pixel_if2_clk # pixel stream 2 output clock
> > +      - const: pixel_if3_clk # pixel stream 3 output clock
> > +
> > +  phys:
> > +    maxItems: 1
> > +    description: phandle to the external D-PHY
> > +
> > +  phy-names:
> > +    items:
> > +      - const: dphy
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port@0:
> > +        $ref: /schemas/graph.yaml#/$defs/port-base
> > +        unevaluatedProperties: false
> > +        description: CSI-2 input
> > +
> > +        properties:
> > +          endpoint:
> > +            $ref: video-interfaces.yaml#
> > +            unevaluatedProperties: false
> > +
> > +            properties:
> > +              clock-lanes:
> > +                maxItems: 1
> > +
> > +              data-lanes:
> > +                maxItems: 1
> 
> If there's only 1 lane, are you assigning between clock and data lanes? 
> If not, then there's no mapping needed.

There can be 4 data lanes, so my first thought after reading your 
message was that this should have minItems: 1 and maxItems: 4. I 
wondered why dt_binding_check never picked this up because the example 
uses 2 data lanes.

I went and looked at it a bit more. It seems like maxItems: 1 is the 
right thing to do. There will only be one element in the data-lanes 
property. The list of data lanes is a tuple with multiple members like: 
data-lanes = <1 2 3>. So we need a way to add constraints on the members 
of a tuple. I am not sure how that can be done. I need to learn more 
about JSON schema I guess (any hints welcome though ;-)

> 
> > +
> > +            required:
> > +              - clock-lanes
> > +              - data-lanes
> > +
> > +      port@1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 0 output
> > +
> > +      port@2:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 1 output
> > +
> > +      port@3:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 2 output
> > +
> > +      port@4:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 3 output
> > +
> > +    required:
> > +      - port@0
> > +
> > +
> > +dependencies:
> > +  phys: [ 'phy-names' ]
> > +  phy-names: [ 'phys' ]
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    csi2rx: csi-bridge@d060000 {
> > +      compatible = "cdns,csi2rx";
> > +      reg = <0x0d060000 0x1000>;
> > +      clocks = <&byteclock>, <&byteclock>,
> > +        <&coreclock>, <&coreclock>,
> > +        <&coreclock>, <&coreclock>;
> > +      clock-names = "sys_clk", "p_clk",
> > +              "pixel_if0_clk", "pixel_if1_clk",
> > +              "pixel_if2_clk", "pixel_if3_clk";
> > +      phys = <&dphy0>;
> > +      phy-names = "dphy";
> > +
> > +      ports {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        port@0 {
> > +          reg = <0>;
> > +
> > +          csi2rx_in_sensor: endpoint {
> > +            remote-endpoint = <&sensor_out_csi2rx>;
> > +            clock-lanes = <0>;
> > +            data-lanes = <1 2>;
> > +          };
> > +        };
> > +
> > +        port@1 {
> > +          reg = <1>;
> > +
> > +          csi2rx_out_grabber0: endpoint {
> > +            remote-endpoint = <&grabber0_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@2 {
> > +          reg = <2>;
> > +
> > +          csi2rx_out_grabber1: endpoint {
> > +            remote-endpoint = <&grabber1_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@3 {
> > +          reg = <3>;
> > +
> > +          csi2rx_out_grabber2: endpoint {
> > +            remote-endpoint = <&grabber2_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@4 {
> > +          reg = <4>;
> > +
> > +          csi2rx_out_grabber3: endpoint {
> > +            remote-endpoint = <&grabber3_in_csi2rx>;
> > +          };
> > +        };
> > +      };
> > +    };
> > -- 
> > 2.30.0

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML
@ 2021-06-03 12:23       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Kishon Vijay Abraham I,
	Vinod Koul, Peter Ujfalusi, Steve Longerbeam, Benoit Parrot,
	linux-media, devicetree, linux-kernel, linux-phy, dmaengine,
	Vignesh Raghavendra, Tomi Valkeinen, Chunfeng Yun,
	Laurent Pinchart

On 01/06/21 12:45PM, Rob Herring wrote:
> On Wed, May 26, 2021 at 08:53:05PM +0530, Pratyush Yadav wrote:
> > Convert the Cadence CSI2RX binding to use YAML schema.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - New in v2.
> > 
> >  .../devicetree/bindings/media/cdns,csi2rx.txt | 100 -----------
> >  .../bindings/media/cdns,csi2rx.yaml           | 164 ++++++++++++++++++
> >  2 files changed, 164 insertions(+), 100 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> >  create mode 100644 Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt b/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> > deleted file mode 100644
> > index 6b02a0657ad9..000000000000
> > --- a/Documentation/devicetree/bindings/media/cdns,csi2rx.txt
> > +++ /dev/null
> > @@ -1,100 +0,0 @@
> > -Cadence MIPI-CSI2 RX controller
> > -===============================
> > -
> > -The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> > -lanes in input, and 4 different pixel streams in output.
> > -
> > -Required properties:
> > -  - compatible: must be set to "cdns,csi2rx" and an SoC-specific compatible
> > -  - reg: base address and size of the memory mapped region
> > -  - clocks: phandles to the clocks driving the controller
> > -  - clock-names: must contain:
> > -    * sys_clk: main clock
> > -    * p_clk: register bank clock
> > -    * pixel_if[0-3]_clk: pixel stream output clock, one for each stream
> > -                         implemented in hardware, between 0 and 3
> > -
> > -Optional properties:
> > -  - phys: phandle to the external D-PHY, phy-names must be provided
> > -  - phy-names: must contain "dphy", if the implementation uses an
> > -               external D-PHY
> > -
> > -Required subnodes:
> > -  - ports: A ports node with one port child node per device input and output
> > -           port, in accordance with the video interface bindings defined in
> > -           Documentation/devicetree/bindings/media/video-interfaces.txt. The
> > -           port nodes are numbered as follows:
> > -
> > -           Port Description
> > -           -----------------------------
> > -           0    CSI-2 input
> > -           1    Stream 0 output
> > -           2    Stream 1 output
> > -           3    Stream 2 output
> > -           4    Stream 3 output
> > -
> > -           The stream output port nodes are optional if they are not
> > -           connected to anything at the hardware level or implemented
> > -           in the design.Since there is only one endpoint per port,
> > -           the endpoints are not numbered.
> > -
> > -
> > -Example:
> > -
> > -csi2rx: csi-bridge@0d060000 {
> > -	compatible = "cdns,csi2rx";
> > -	reg = <0x0d060000 0x1000>;
> > -	clocks = <&byteclock>, <&byteclock>
> > -		 <&coreclock>, <&coreclock>,
> > -		 <&coreclock>, <&coreclock>;
> > -	clock-names = "sys_clk", "p_clk",
> > -		      "pixel_if0_clk", "pixel_if1_clk",
> > -		      "pixel_if2_clk", "pixel_if3_clk";
> > -
> > -	ports {
> > -		#address-cells = <1>;
> > -		#size-cells = <0>;
> > -
> > -		port@0 {
> > -			reg = <0>;
> > -
> > -			csi2rx_in_sensor: endpoint {
> > -				remote-endpoint = <&sensor_out_csi2rx>;
> > -				clock-lanes = <0>;
> > -				data-lanes = <1 2>;
> > -			};
> > -		};
> > -
> > -		port@1 {
> > -			reg = <1>;
> > -
> > -			csi2rx_out_grabber0: endpoint {
> > -				remote-endpoint = <&grabber0_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@2 {
> > -			reg = <2>;
> > -
> > -			csi2rx_out_grabber1: endpoint {
> > -				remote-endpoint = <&grabber1_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@3 {
> > -			reg = <3>;
> > -
> > -			csi2rx_out_grabber2: endpoint {
> > -				remote-endpoint = <&grabber2_in_csi2rx>;
> > -			};
> > -		};
> > -
> > -		port@4 {
> > -			reg = <4>;
> > -
> > -			csi2rx_out_grabber3: endpoint {
> > -				remote-endpoint = <&grabber3_in_csi2rx>;
> > -			};
> > -		};
> > -	};
> > -};
> > diff --git a/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > new file mode 100644
> > index 000000000000..ff5dd4211ac9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/media/cdns,csi2rx.yaml
> > @@ -0,0 +1,164 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/media/cdns,csi2rx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Cadence MIPI-CSI2 RX controller
> > +
> > +description: |
> > +  The Cadence MIPI-CSI2 RX controller is a CSI-2 bridge supporting up to 4 CSI
> > +  lanes in input, and 4 different pixel streams in output.
> > +
> > +maintainers:
> > +  - Pratyush Yadav <p.yadav@ti.com>
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - const: cdns,csi2rx
> 
> Since there has to be an SoC specific compatible, this should be:
> 
> compatible:
>   contains:
>     const: cdns,csi2rx

Ok.

> 
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    minItems: 3
> > +    maxItems: 6
> > +
> > +  clock-names:
> > +    minItems: 3
> > +    maxItems: 6
> > +    items:
> > +      - const: sys_clk # main clock
> > +      - const: p_clk # register bank clock
> > +      - const: pixel_if0_clk # pixel stream 0 output clock
> > +      - const: pixel_if1_clk # pixel stream 1 output clock
> > +      - const: pixel_if2_clk # pixel stream 2 output clock
> > +      - const: pixel_if3_clk # pixel stream 3 output clock
> > +
> > +  phys:
> > +    maxItems: 1
> > +    description: phandle to the external D-PHY
> > +
> > +  phy-names:
> > +    items:
> > +      - const: dphy
> > +
> > +  ports:
> > +    $ref: /schemas/graph.yaml#/properties/ports
> > +
> > +    properties:
> > +      port@0:
> > +        $ref: /schemas/graph.yaml#/$defs/port-base
> > +        unevaluatedProperties: false
> > +        description: CSI-2 input
> > +
> > +        properties:
> > +          endpoint:
> > +            $ref: video-interfaces.yaml#
> > +            unevaluatedProperties: false
> > +
> > +            properties:
> > +              clock-lanes:
> > +                maxItems: 1
> > +
> > +              data-lanes:
> > +                maxItems: 1
> 
> If there's only 1 lane, are you assigning between clock and data lanes? 
> If not, then there's no mapping needed.

There can be 4 data lanes, so my first thought after reading your 
message was that this should have minItems: 1 and maxItems: 4. I 
wondered why dt_binding_check never picked this up because the example 
uses 2 data lanes.

I went and looked at it a bit more. It seems like maxItems: 1 is the 
right thing to do. There will only be one element in the data-lanes 
property. The list of data lanes is a tuple with multiple members like: 
data-lanes = <1 2 3>. So we need a way to add constraints on the members 
of a tuple. I am not sure how that can be done. I need to learn more 
about JSON schema I guess (any hints welcome though ;-)

> 
> > +
> > +            required:
> > +              - clock-lanes
> > +              - data-lanes
> > +
> > +      port@1:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 0 output
> > +
> > +      port@2:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 1 output
> > +
> > +      port@3:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 2 output
> > +
> > +      port@4:
> > +        $ref: /schemas/graph.yaml#/properties/port
> > +        description: Stream 3 output
> > +
> > +    required:
> > +      - port@0
> > +
> > +
> > +dependencies:
> > +  phys: [ 'phy-names' ]
> > +  phy-names: [ 'phys' ]
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - clocks
> > +  - clock-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +    csi2rx: csi-bridge@d060000 {
> > +      compatible = "cdns,csi2rx";
> > +      reg = <0x0d060000 0x1000>;
> > +      clocks = <&byteclock>, <&byteclock>,
> > +        <&coreclock>, <&coreclock>,
> > +        <&coreclock>, <&coreclock>;
> > +      clock-names = "sys_clk", "p_clk",
> > +              "pixel_if0_clk", "pixel_if1_clk",
> > +              "pixel_if2_clk", "pixel_if3_clk";
> > +      phys = <&dphy0>;
> > +      phy-names = "dphy";
> > +
> > +      ports {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        port@0 {
> > +          reg = <0>;
> > +
> > +          csi2rx_in_sensor: endpoint {
> > +            remote-endpoint = <&sensor_out_csi2rx>;
> > +            clock-lanes = <0>;
> > +            data-lanes = <1 2>;
> > +          };
> > +        };
> > +
> > +        port@1 {
> > +          reg = <1>;
> > +
> > +          csi2rx_out_grabber0: endpoint {
> > +            remote-endpoint = <&grabber0_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@2 {
> > +          reg = <2>;
> > +
> > +          csi2rx_out_grabber1: endpoint {
> > +            remote-endpoint = <&grabber1_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@3 {
> > +          reg = <3>;
> > +
> > +          csi2rx_out_grabber2: endpoint {
> > +            remote-endpoint = <&grabber2_in_csi2rx>;
> > +          };
> > +        };
> > +
> > +        port@4 {
> > +          reg = <4>;
> > +
> > +          csi2rx_out_grabber3: endpoint {
> > +            remote-endpoint = <&grabber3_in_csi2rx>;
> > +          };
> > +        };
> > +      };
> > +    };
> > -- 
> > 2.30.0

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
  2021-05-28  7:35         ` Tomi Valkeinen
@ 2021-06-03 12:42           ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:42 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:35AM, Tomi Valkeinen wrote:
> On 28/05/2021 10:24, Pratyush Yadav wrote:
> > On 28/05/21 10:16AM, Tomi Valkeinen wrote:
> > > On 26/05/2021 18:23, Pratyush Yadav wrote:
> > > > The devnode can be used by media-ctl and other userspace tools to
> > > > perform configurations on the subdev. Without it, media-ctl returns
> > > > ENOENT when setting format on the sensor subdev.
> > > > 
> > > > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > > > ---
> > > > 
> > > > (no changes since v1)
> > > > 
> > > >    drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
> > > >    1 file changed, 1 insertion(+)
> > > > 
> > > > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > index 1df21f462f3c..49bed63d5faa 100644
> > > > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
> > > >    	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> > > >    	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
> > > >    		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> > > > +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > > >    	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
> > > >    				     csi2rx->pads);
> > > > 
> > > 
> > > I don't understand this one. There's nothing to configure in cdns-csi2rx
> > > from userspace, as far as I can see, so why is the dev node needed? And why
> > > would the lack of csi2rx dev node cause sensor subdev config to fail?
> > 
> > Sensor config does not fail. But when I run media-ctl to set the format
> > on /dev/media0, I get an error message that comes because the devnode
> > for the bridge does not exist. I was not 100% sure about this patch but
> > I figured if media-ctl expects it then it should be exposed.
> > 
> > I don't mind dropping this patch. Just want to make sure what the right
> > thing to do here is. Should every element of the pipeline have a devnode
> > or not?
> 
> Tbh, I don't know. But I don't see why they should have. Also, my test works
> fine if I remove the devnode here.
> 
> What media-ctl parameters did you use which fails?

Media controller topology:

  root@j7-evm:~# media-ctl -p
  Media controller API version 5.13.0
  
  Media device information
  ------------------------
  driver         j721e-csi2rx
  model          TI-CSI2RX
  serial
  bus info       platform:4500000.ticsi2rx
  hw revision    0x1
  driver version 5.13.0
  
  Device topology
  - entity 1: cdns_csi2rx.4504000.csi-bridge (5 pads, 2 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev0
         pad0: Sink
                 <- "ov5640 9-003c":0 [ENABLED,IMMUTABLE]
         pad1: Source
                 -> "j721e-csi2rx":0 [ENABLED,IMMUTABLE]
         pad2: Source
         pad3: Source
         pad4: Source
  
  - entity 7: ov5640 9-003c (1 pad, 1 link)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev1
         pad0: Source
                 [fmt:UYVY8_2X8/640x480@1/30 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
                 -> "cdns_csi2rx.4504000.csi-bridge":0 [ENABLED,IMMUTABLE]
  
  - entity 11: j721e-csi2rx (1 pad, 1 link)
              type Node subtype V4L flags 0
              device node name /dev/video0
         pad0: Sink
                 <- "cdns_csi2rx.4504000.csi-bridge":1 [ENABLED,IMMUTABLE]


Setting resolution on the sensor (with cdns-csi2rx devnode present):

  root@j7-evm:~# media-ctl --set-v4l2 '"ov5640 9-003c":0 [fmt:UYVY8_2X8/1920x1080@1/30]'

The above command works. Setting resolution on the sensor (without the 
devnode present):

  root@j7-evm:~# media-ctl --set-v4l2 '"ov5640 9-003c":0 [fmt:UYVY8_2X8/1920x1080@1/30]'
  Unable to setup formats: No such file or directory (2)

This sets the format correctly on the sensor but fails when it tried to 
set it on the bridge.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode
@ 2021-06-03 12:42           ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:42 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 28/05/21 10:35AM, Tomi Valkeinen wrote:
> On 28/05/2021 10:24, Pratyush Yadav wrote:
> > On 28/05/21 10:16AM, Tomi Valkeinen wrote:
> > > On 26/05/2021 18:23, Pratyush Yadav wrote:
> > > > The devnode can be used by media-ctl and other userspace tools to
> > > > perform configurations on the subdev. Without it, media-ctl returns
> > > > ENOENT when setting format on the sensor subdev.
> > > > 
> > > > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > > > ---
> > > > 
> > > > (no changes since v1)
> > > > 
> > > >    drivers/media/platform/cadence/cdns-csi2rx.c | 1 +
> > > >    1 file changed, 1 insertion(+)
> > > > 
> > > > diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > index 1df21f462f3c..49bed63d5faa 100644
> > > > --- a/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > +++ b/drivers/media/platform/cadence/cdns-csi2rx.c
> > > > @@ -613,6 +613,7 @@ static int csi2rx_probe(struct platform_device *pdev)
> > > >    	csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> > > >    	for (i = CSI2RX_PAD_SOURCE_STREAM0; i < CSI2RX_PAD_MAX; i++)
> > > >    		csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE;
> > > > +	csi2rx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> > > >    	ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX,
> > > >    				     csi2rx->pads);
> > > > 
> > > 
> > > I don't understand this one. There's nothing to configure in cdns-csi2rx
> > > from userspace, as far as I can see, so why is the dev node needed? And why
> > > would the lack of csi2rx dev node cause sensor subdev config to fail?
> > 
> > Sensor config does not fail. But when I run media-ctl to set the format
> > on /dev/media0, I get an error message that comes because the devnode
> > for the bridge does not exist. I was not 100% sure about this patch but
> > I figured if media-ctl expects it then it should be exposed.
> > 
> > I don't mind dropping this patch. Just want to make sure what the right
> > thing to do here is. Should every element of the pipeline have a devnode
> > or not?
> 
> Tbh, I don't know. But I don't see why they should have. Also, my test works
> fine if I remove the devnode here.
> 
> What media-ctl parameters did you use which fails?

Media controller topology:

  root@j7-evm:~# media-ctl -p
  Media controller API version 5.13.0
  
  Media device information
  ------------------------
  driver         j721e-csi2rx
  model          TI-CSI2RX
  serial
  bus info       platform:4500000.ticsi2rx
  hw revision    0x1
  driver version 5.13.0
  
  Device topology
  - entity 1: cdns_csi2rx.4504000.csi-bridge (5 pads, 2 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev0
         pad0: Sink
                 <- "ov5640 9-003c":0 [ENABLED,IMMUTABLE]
         pad1: Source
                 -> "j721e-csi2rx":0 [ENABLED,IMMUTABLE]
         pad2: Source
         pad3: Source
         pad4: Source
  
  - entity 7: ov5640 9-003c (1 pad, 1 link)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev1
         pad0: Source
                 [fmt:UYVY8_2X8/640x480@1/30 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:full-range]
                 -> "cdns_csi2rx.4504000.csi-bridge":0 [ENABLED,IMMUTABLE]
  
  - entity 11: j721e-csi2rx (1 pad, 1 link)
              type Node subtype V4L flags 0
              device node name /dev/video0
         pad0: Sink
                 <- "cdns_csi2rx.4504000.csi-bridge":1 [ENABLED,IMMUTABLE]


Setting resolution on the sensor (with cdns-csi2rx devnode present):

  root@j7-evm:~# media-ctl --set-v4l2 '"ov5640 9-003c":0 [fmt:UYVY8_2X8/1920x1080@1/30]'

The above command works. Setting resolution on the sensor (without the 
devnode present):

  root@j7-evm:~# media-ctl --set-v4l2 '"ov5640 9-003c":0 [fmt:UYVY8_2X8/1920x1080@1/30]'
  Unable to setup formats: No such file or directory (2)

This sets the format correctly on the sensor but fails when it tried to 
set it on the bridge.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
  2021-05-27 14:23     ` Rob Herring
@ 2021-06-03 12:43       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:43 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, linux-kernel, Vinod Koul, Kishon Vijay Abraham I,
	Laurent Pinchart, devicetree, Benoit Parrot, dmaengine,
	Steve Longerbeam, Tomi Valkeinen, Mauro Carvalho Chehab,
	linux-media, Chunfeng Yun, Peter Ujfalusi, Vignesh Raghavendra,
	linux-phy, Rob Herring

On 27/05/21 09:23AM, Rob Herring wrote:
> On Wed, 26 May 2021 20:53:04 +0530, Pratyush Yadav wrote:
> > TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> > capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
> > parts together.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Rename to ti,j721e-csi2rx.yaml
> > - Add an entry in MAINTAINERS.
> > - Add a description for the binding.
> > - Change compatible to ti,j721e-csi2rx to make it SoC specific.
> > - Remove description from dmas, reg, power-domains.
> > - Remove a limit of 2 from #address-cells and #size-cells.
> > - Fix add ^ to csi-bridge subnode regex.
> > - Make ranges mandatory.
> > - Add unit address in example.
> > - Add a reference to cdns,csi2rx in csi-bridge subnode.
> > - Expand the example to include the csi-bridge subnode as well.
> > - Re-order subject prefixes.
> > 
> >  .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
> >  MAINTAINERS                                   |   1 +
> >  2 files changed, 102 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
> xargs: dt-doc-validate: exited with status 255; aborting
> make[1]: *** Deleting file 'Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml'
> Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
> make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml] Error 255
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1416: dt_binding_check] Error 2
> 
> See https://patchwork.ozlabs.org/patch/1484096
> 
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.

I think this is the case here since it can't find the 
ti,j721e-csi2rx.yaml file.

> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver
@ 2021-06-03 12:43       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:43 UTC (permalink / raw)
  To: Rob Herring
  Cc: Maxime Ripard, linux-kernel, Vinod Koul, Kishon Vijay Abraham I,
	Laurent Pinchart, devicetree, Benoit Parrot, dmaengine,
	Steve Longerbeam, Tomi Valkeinen, Mauro Carvalho Chehab,
	linux-media, Chunfeng Yun, Peter Ujfalusi, Vignesh Raghavendra,
	linux-phy, Rob Herring

On 27/05/21 09:23AM, Rob Herring wrote:
> On Wed, 26 May 2021 20:53:04 +0530, Pratyush Yadav wrote:
> > TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> > capture over a CSI-2 bus. The TI CSI2RX platform driver glues all the
> > parts together.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - Rename to ti,j721e-csi2rx.yaml
> > - Add an entry in MAINTAINERS.
> > - Add a description for the binding.
> > - Change compatible to ti,j721e-csi2rx to make it SoC specific.
> > - Remove description from dmas, reg, power-domains.
> > - Remove a limit of 2 from #address-cells and #size-cells.
> > - Fix add ^ to csi-bridge subnode regex.
> > - Make ranges mandatory.
> > - Add unit address in example.
> > - Add a reference to cdns,csi2rx in csi-bridge subnode.
> > - Expand the example to include the csi-bridge subnode as well.
> > - Re-order subject prefixes.
> > 
> >  .../bindings/media/ti,j721e-csi2rx.yaml       | 101 ++++++++++++++++++
> >  MAINTAINERS                                   |   1 +
> >  2 files changed, 102 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/media/ti,j721e-csi2rx.yaml
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
> xargs: dt-doc-validate: exited with status 255; aborting
> make[1]: *** Deleting file 'Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml'
> Unknown file referenced: [Errno 2] No such file or directory: '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/media/cdns,csi2rx.yaml'
> make[1]: *** [scripts/Makefile.lib:380: Documentation/devicetree/bindings/media/ti,j721e-csi2rx.example.dt.yaml] Error 255
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1416: dt_binding_check] Error 2
> 
> See https://patchwork.ozlabs.org/patch/1484096
> 
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.

I think this is the case here since it can't find the 
ti,j721e-csi2rx.yaml file.

> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
  2021-05-27 13:29     ` Tomi Valkeinen
@ 2021-06-03 12:49       ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:49 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 04:29PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> > capture over a CSI-2 bus.
> > 
> > The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
> > the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
> > called the SHIM layer. It takes in data from stream 0, repacks it, and
> > sends it to memory over PSI-L DMA.
> > 
> > This driver acts as the "front end" to V4L2 client applications. It
> > implements the required ioctls and buffer operations, passes the
> > necessary calls on to the bridge, programs the SHIM layer, and performs
> > DMA via the dmaengine API to finally return the data to a buffer
> > supplied by the application.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> I noticed that my test app didn't work at all with this, and I also wasn't
> able to use v4l2-ctl to set the format.

I have not used v4l2-ctl, but I can see yavta works fine. What command 
did you use for setting format via v4l2-ctl?

> 
> At least for my test app the problem was that this driver doesn't initialize
> the format at all. My app first calls VIDIOC_G_FMT with v4l2_format.type ==
> V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call modifies the fields it
> wants to change and calls VIDIOC_S_FMT. This failed, as G_FMT returned
> uninitialized fmt, i.e. type was 0, which my app didn't set again.
> 
> I believe the driver should have an initial format, something that it will
> accept if an app calls G_FMT and then S_FMT.

Right. This is a bug. The question is what should the initial format be? 
It is more or less arbitrary since there is no configuration made yet 
and we don't know what the camera can or will send. So for example, what 
if I use UYVY 640x480? The camera might not support it at all. Is it 
still OK to have it as the default?

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
@ 2021-06-03 12:49       ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:49 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 04:29PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:23, Pratyush Yadav wrote:
> > TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
> > capture over a CSI-2 bus.
> > 
> > The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
> > the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
> > called the SHIM layer. It takes in data from stream 0, repacks it, and
> > sends it to memory over PSI-L DMA.
> > 
> > This driver acts as the "front end" to V4L2 client applications. It
> > implements the required ioctls and buffer operations, passes the
> > necessary calls on to the bridge, programs the SHIM layer, and performs
> > DMA via the dmaengine API to finally return the data to a buffer
> > supplied by the application.
> > 
> > Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
> 
> I noticed that my test app didn't work at all with this, and I also wasn't
> able to use v4l2-ctl to set the format.

I have not used v4l2-ctl, but I can see yavta works fine. What command 
did you use for setting format via v4l2-ctl?

> 
> At least for my test app the problem was that this driver doesn't initialize
> the format at all. My app first calls VIDIOC_G_FMT with v4l2_format.type ==
> V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call modifies the fields it
> wants to change and calls VIDIOC_S_FMT. This failed, as G_FMT returned
> uninitialized fmt, i.e. type was 0, which my app didn't set again.
> 
> I believe the driver should have an initial format, something that it will
> accept if an app calls G_FMT and then S_FMT.

Right. This is a bug. The question is what should the initial format be? 
It is more or less arbitrary since there is no configuration made yet 
and we don't know what the camera can or will send. So for example, what 
if I use UYVY 640x480? The camera might not support it at all. Is it 
still OK to have it as the default?

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
  2021-05-27 13:23   ` Tomi Valkeinen
@ 2021-06-03 12:52     ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:52 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 04:23PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Hi,
> > 
> > This series adds support for CSI2 capture on J721E. It includes some
> > fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> > driver, and finally adds the TI CSI2RX wrapper driver.
> > 
> > Tested on TI's J721E with OV5640 sensor.
> 
> I also see this after a few captures:

Can you share the application/command you are using to test? I used 
yavta to test and didn't see any problems after leaving the stream on 
for around 10 minutes.

> 
> [   84.115503] ------------[ cut here ]------------
> [   84.120144] DMA-API: ti-udma 31150000.dma-controller: mapping sg segment longer than device claims to support [len=1900544] [max=65536]
> [   84.132376] WARNING: CPU: 1 PID: 594 at kernel/dma/debug.c:1172 debug_dma_map_sg+0x304/0x390
> [   84.140804] Modules linked in: ov5640 ti_cal j721e_csi2rx cdns_csi2rx cdns_dphy v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper d
> rm drm_panel_orientation_quirks cfbfillrect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent
> [   84.165298] CPU: 1 PID: 594 Comm: cam-mplex.py Not tainted 5.13.0-rc1-00206-g98bb91e95a28-dirty #5
> [   84.174236] Hardware name: Texas Instruments K3 J721E SoC (DT)
> [   84.180051] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [   84.186041] pc : debug_dma_map_sg+0x304/0x390
> [   84.190383] lr : debug_dma_map_sg+0x304/0x390
> [   84.194725] sp : ffff800014d0f730
> [   84.198026] x29: ffff800014d0f730 x28: ffff000801544680 x27: ffffffffffffffff
> [   84.205148] x26: 0000000000000000 x25: 0000000000000002 x24: 0000000000000001
> [   84.212269] x23: ffff80001163abe0 x22: 0000000000000000 x21: 0000000000000001
> [   84.219390] x20: ffff000801fa3010 x19: ffff0008075c7580 x18: 0000000000000000
> [   84.226510] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000030
> [   84.233630] x14: 6e61687420726567 x13: 6e6f6c20746e656d x12: 7420736d69616c63
> [   84.240751] x11: 2065636976656420 x10: ffff8000116b18f8 x9 : ffff8000100eb920
> [   84.247871] x8 : ffff8000116598f8 x7 : ffff8000116b18f8 x6 : 0000000000000001
> [   84.254991] x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000
> [   84.262111] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008066f8000
> [   84.269230] Call trace:
> [   84.271665]  debug_dma_map_sg+0x304/0x390
> [   84.275660]  dma_map_sg_attrs+0x70/0xb0
> [   84.279486]  drm_gem_map_dma_buf+0x6c/0xf0 [drm]
> [   84.284177]  __map_dma_buf+0x28/0x80
> [   84.287742]  dma_buf_map_attachment+0xe4/0x200
> [   84.292172]  vb2_dc_map_dmabuf+0x3c/0x150
> [   84.296171]  __prepare_dmabuf+0x1dc/0x514
> [   84.300168]  __buf_prepare+0x1a0/0x25c
> [   84.303903]  vb2_core_qbuf+0x3d4/0x72c
> [   84.307638]  vb2_qbuf+0x9c/0xf4
> [   84.310767]  vb2_ioctl_qbuf+0x68/0x7c
> [   84.314416]  v4l_qbuf+0x54/0x70
> [   84.317545]  __video_do_ioctl+0x194/0x400
> [   84.321541]  video_usercopy+0x19c/0x910
> [   84.325362]  video_ioctl2+0x24/0x40
> [   84.328837]  v4l2_ioctl+0x4c/0x70
> [   84.332141]  __arm64_sys_ioctl+0xb4/0xfc
> [   84.336053]  invoke_syscall+0x50/0x120
> [   84.339791]  el0_svc_common.constprop.0+0x68/0x104
> [   84.344569]  do_el0_svc+0x30/0x9c
> [   84.347872]  el0_svc+0x2c/0x54
> [   84.350916]  el0_sync_handler+0x1a8/0x1ac
> [   84.354911]  el0_sync+0x198/0x1c0
> [   84.358215] irq event stamp: 0
> [   84.361256] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
> [   84.367507] hardirqs last disabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
> [   84.375667] softirqs last  enabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
> [   84.383824] softirqs last disabled at (0): [<0000000000000000>] 0x0
> [   84.390073] ---[ end trace af3448c784059129 ]---

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-06-03 12:52     ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:52 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 04:23PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Hi,
> > 
> > This series adds support for CSI2 capture on J721E. It includes some
> > fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> > driver, and finally adds the TI CSI2RX wrapper driver.
> > 
> > Tested on TI's J721E with OV5640 sensor.
> 
> I also see this after a few captures:

Can you share the application/command you are using to test? I used 
yavta to test and didn't see any problems after leaving the stream on 
for around 10 minutes.

> 
> [   84.115503] ------------[ cut here ]------------
> [   84.120144] DMA-API: ti-udma 31150000.dma-controller: mapping sg segment longer than device claims to support [len=1900544] [max=65536]
> [   84.132376] WARNING: CPU: 1 PID: 594 at kernel/dma/debug.c:1172 debug_dma_map_sg+0x304/0x390
> [   84.140804] Modules linked in: ov5640 ti_cal j721e_csi2rx cdns_csi2rx cdns_dphy v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper d
> rm drm_panel_orientation_quirks cfbfillrect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent
> [   84.165298] CPU: 1 PID: 594 Comm: cam-mplex.py Not tainted 5.13.0-rc1-00206-g98bb91e95a28-dirty #5
> [   84.174236] Hardware name: Texas Instruments K3 J721E SoC (DT)
> [   84.180051] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [   84.186041] pc : debug_dma_map_sg+0x304/0x390
> [   84.190383] lr : debug_dma_map_sg+0x304/0x390
> [   84.194725] sp : ffff800014d0f730
> [   84.198026] x29: ffff800014d0f730 x28: ffff000801544680 x27: ffffffffffffffff
> [   84.205148] x26: 0000000000000000 x25: 0000000000000002 x24: 0000000000000001
> [   84.212269] x23: ffff80001163abe0 x22: 0000000000000000 x21: 0000000000000001
> [   84.219390] x20: ffff000801fa3010 x19: ffff0008075c7580 x18: 0000000000000000
> [   84.226510] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000030
> [   84.233630] x14: 6e61687420726567 x13: 6e6f6c20746e656d x12: 7420736d69616c63
> [   84.240751] x11: 2065636976656420 x10: ffff8000116b18f8 x9 : ffff8000100eb920
> [   84.247871] x8 : ffff8000116598f8 x7 : ffff8000116b18f8 x6 : 0000000000000001
> [   84.254991] x5 : 0000000000000001 x4 : 0000000000000001 x3 : 0000000000000000
> [   84.262111] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff0008066f8000
> [   84.269230] Call trace:
> [   84.271665]  debug_dma_map_sg+0x304/0x390
> [   84.275660]  dma_map_sg_attrs+0x70/0xb0
> [   84.279486]  drm_gem_map_dma_buf+0x6c/0xf0 [drm]
> [   84.284177]  __map_dma_buf+0x28/0x80
> [   84.287742]  dma_buf_map_attachment+0xe4/0x200
> [   84.292172]  vb2_dc_map_dmabuf+0x3c/0x150
> [   84.296171]  __prepare_dmabuf+0x1dc/0x514
> [   84.300168]  __buf_prepare+0x1a0/0x25c
> [   84.303903]  vb2_core_qbuf+0x3d4/0x72c
> [   84.307638]  vb2_qbuf+0x9c/0xf4
> [   84.310767]  vb2_ioctl_qbuf+0x68/0x7c
> [   84.314416]  v4l_qbuf+0x54/0x70
> [   84.317545]  __video_do_ioctl+0x194/0x400
> [   84.321541]  video_usercopy+0x19c/0x910
> [   84.325362]  video_ioctl2+0x24/0x40
> [   84.328837]  v4l2_ioctl+0x4c/0x70
> [   84.332141]  __arm64_sys_ioctl+0xb4/0xfc
> [   84.336053]  invoke_syscall+0x50/0x120
> [   84.339791]  el0_svc_common.constprop.0+0x68/0x104
> [   84.344569]  do_el0_svc+0x30/0x9c
> [   84.347872]  el0_svc+0x2c/0x54
> [   84.350916]  el0_sync_handler+0x1a8/0x1ac
> [   84.354911]  el0_sync+0x198/0x1c0
> [   84.358215] irq event stamp: 0
> [   84.361256] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
> [   84.367507] hardirqs last disabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
> [   84.375667] softirqs last  enabled at (0): [<ffff80001004fe2c>] copy_process+0x44c/0x1800
> [   84.383824] softirqs last disabled at (0): [<0000000000000000>] 0x0
> [   84.390073] ---[ end trace af3448c784059129 ]---

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
  2021-05-27 12:42   ` Tomi Valkeinen
@ 2021-06-03 12:54     ` Pratyush Yadav
  -1 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 03:42PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Hi,
> > 
> > This series adds support for CSI2 capture on J721E. It includes some
> > fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> > driver, and finally adds the TI CSI2RX wrapper driver.
> > 
> > Tested on TI's J721E with OV5640 sensor.
> 
> I'm having some trouble unloading and reloading the modules:
> 
> rmmod ti_cal
> rmmod j721e_csi2rx
> rmmod cdns_csi2rx
> rmmod cdns_dphy
> rmmod ov5640

I did some basic module insertion/removal testing but I didn't try 
removing the sensor module. I will check and see what the problem is.

> [   37.943128] ------------[ cut here ]------------
> [   37.947752] WARNING: CPU: 1 PID: 628 at drivers/media/v4l2-core/v4l2-ctrls-core.c:1807 __v4l2_ctrl_handler_setup+0x15c/0x170
> [   37.958963] Modules linked in: ov5640(-) v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper drm drm_panel_orientation_quirks cfbfill
> rect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent [last unloaded: cdns_dphy]
> [   37.982455] CPU: 1 PID: 628 Comm: rmmod Not tainted 5.13.0-rc1-00205-g93acc23badc8 #3
> [   37.990271] Hardware name: Texas Instruments K3 J721E SoC (DT)
> [   37.996090] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [   38.002085] pc : __v4l2_ctrl_handler_setup+0x15c/0x170
> [   38.007214] lr : __v4l2_ctrl_handler_setup+0x158/0x170
> [   38.012343] sp : ffff80001476fae0
> [   38.015648] x29: ffff80001476fae0 x28: ffff000806780000 x27: 0000000000000000
> [   38.022781] x26: ffff00080300b448 x25: ffff000804ad4ac0 x24: 0000000000000001
> [   38.029912] x23: 0000000000000000 x22: 0000000000000005 x21: ffff000801fa7880
> [   38.037043] x20: ffff000801fa7888 x19: ffff000801fa7ba8 x18: 0000000000000000
> [   38.044173] x17: 0000000000000000 x16: 0000000000000010 x15: 0000000000000001
> [   38.051305] x14: 000000000000003b x13: 00000000aaaaaaab x12: ffff800011a915b8
> [   38.058436] x11: 00000000000c001c x10: 000000008260a2b7 x9 : ffff800009362d9c
> [   38.065566] x8 : ffff800011887100 x7 : 0000000000000000 x6 : 0000000000000001
> [   38.072698] x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff800011260000
> [   38.079829] x2 : 00000000000000c0 x1 : 00000000000000c0 x0 : 0000000000000000
> [   38.086960] Call trace:
> [   38.089399]  __v4l2_ctrl_handler_setup+0x15c/0x170
> [   38.094181]  ov5640_resume+0x1fc/0x270 [ov5640]
> [   38.098709]  __rpm_callback+0x98/0x160
> [   38.102452]  rpm_callback+0x2c/0x90
> [   38.105934]  rpm_resume+0x45c/0x6f4
> [   38.109415]  __pm_runtime_resume+0x54/0xc0
> [   38.113503]  __device_release_driver+0x40/0x240
> [   38.118025]  driver_detach+0xd0/0x160
> [   38.121680]  bus_remove_driver+0x68/0xe0
> [   38.125595]  driver_unregister+0x3c/0x6c
> [   38.129509]  i2c_del_driver+0x64/0xb0
> [   38.133166]  ov5640_i2c_driver_exit+0x1c/0xc948 [ov5640]
> [   38.138469]  __arm64_sys_delete_module+0x1b0/0x27c
> [   38.143251]  invoke_syscall+0x50/0x120
> [   38.146995]  el0_svc_common.constprop.0+0x68/0x104
> [   38.151777]  do_el0_svc+0x30/0x9c
> [   38.155086]  el0_svc+0x2c/0x54
> [   38.158135]  el0_sync_handler+0x1a8/0x1ac
> [   38.162136]  el0_sync+0x198/0x1c0
> [   38.165444] irq event stamp: 11302
> [   38.168837] hardirqs last  enabled at (11301): [<ffff800010bf4e40>] _raw_spin_unlock_irq+0x50/0xa0
> [   38.177781] hardirqs last disabled at (11302): [<ffff800010be7a64>] el1_dbg+0x24/0xa0
> [   38.185595] softirqs last  enabled at (10378): [<ffff800010010ba0>] __do_softirq+0x500/0x6bc
> [   38.194017] softirqs last disabled at (10373): [<ffff80001005d4c4>] __irq_exit_rcu+0x1d4/0x1e0
> [   38.202614] ---[ end trace 7037324a951cb149 ]---
> rmmod v4l2_fwnode
> insmod /root/nfs/work/linux/drivers/media/v4l2-core/v4l2-fwnode.ko
> insmod /root/nfs/work/linux/drivers/phy/cadence/cdns-dphy.ko
> insmod /root/nfs/work/linux/drivers/media/platform/cadence/cdns-csi2rx.ko
> ERROR:   Unhandled External Abort received on 0x80000001 from S-EL1
> ERROR:   exception reason=0 syndrome=0xbf000000
> Unhandled Exception from EL1
> x0             = 0x0000000000000000
> x1             = 0xffff000804d59800
> x2             = 0xffff8000146c4000
> x3             = 0xffff800011260000
> x4             = 0x0000000000000001
> x5             = 0x0000000000000001
> x6             = 0x0000000000000001
> x7             = 0x0000000000000000
> x8             = 0xffff800011887100
> x9             = 0xffff800010bf5190
> x10            = 0x000000008260a2b7
> x11            = 0x00000000000c821d
> x12            = 0xffff800011a915b8
> x13            = 0x0000000000000001
> x14            = 0x0000000000000000
> x15            = 0x0000000000000020
> x16            = 0x0000000000000000
> x17            = 0x0000000000000000
> x18            = 0x00000000fffffffb
> x19            = 0xffff000806d44c00
> x20            = 0x0000000000000000
> x21            = 0xffff800009280058
> x22            = 0xffff00080583c810
> x23            = 0xffff00080583c800
> x24            = 0xffff800009280058
> x25            = 0x0000000000000047
> x26            = 0xffff8000116d71d8
> x27            = 0xffff800009280350
> x28            = 0xffff800009280148
> x29            = 0xffff80001432f850
> x30            = 0xffff8000092506b8
> scr_el3        = 0x000000000000073d
> sctlr_el3      = 0x0000000030cd183f
> cptr_el3       = 0x0000000000000000
> tcr_el3        = 0x0000000080803520
> daif           = 0x00000000000002c0
> mair_el3       = 0x00000000004404ff
> spsr_el3       = 0x0000000000000005
> elr_el3        = 0xffff80000925043c
> ttbr0_el3      = 0x0000000070010b00
> esr_el3        = 0x00000000bf000000
> far_el3        = 0x0000000000000000
> spsr_el1       = 0x0000000060000005
> elr_el1        = 0xffff800010be8cb0
> spsr_abt       = 0x0000000000000000
> spsr_und       = 0x0000000000000000
> spsr_irq       = 0x0000000000000000
> spsr_fiq       = 0x0000000000000000
> sctlr_el1      = 0x0000000034d4d91d
> actlr_el1      = 0x0000000000000000
> cpacr_el1      = 0x0000000000300000
> csselr_el1     = 0x0000000000000000
> sp_el1         = 0xffff80001432f850
> esr_el1        = 0x0000000056000000
> ttbr0_el1      = 0x0000000882773200
> ttbr1_el1      = 0x06d8000083180000
> mair_el1       = 0x000c0400bb44ffff
> amair_el1      = 0x0000000000000000
> tcr_el1        = 0x00000034f5d07590
> tpidr_el1      = 0xffff80086e790000
> tpidr_el0      = 0x0000ffff895c6910
> tpidrro_el0    = 0x0000000000000000
> par_el1        = 0x0000000000000000
> mpidr_el1      = 0x0000000080000001
> afsr0_el1      = 0x0000000000000000
> afsr1_el1      = 0x0000000000000000
> contextidr_el1 = 0x0000000000000000
> vbar_el1       = 0xffff800010011000
> cntp_ctl_el0   = 0x0000000000000005
> cntp_cval_el0  = 0x000000023f77b7a1
> cntv_ctl_el0   = 0x0000000000000000
> cntv_cval_el0  = 0x0000000000000000
> cntkctl_el1    = 0x00000000000000d6
> sp_el0         = 0x000000007000abd0
> isr_el1        = 0x0000000000000040
> dacr32_el2     = 0x0000000000000000
> ifsr32_el2     = 0x0000000000000000
> cpuectlr_el1   = 0x0000001b00000040
> cpumerrsr_el1  = 0x0000000000000000
> l2merrsr_el1   = 0x0000000000000000

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-06-03 12:54     ` Pratyush Yadav
  0 siblings, 0 replies; 96+ messages in thread
From: Pratyush Yadav @ 2021-06-03 12:54 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 27/05/21 03:42PM, Tomi Valkeinen wrote:
> Hi Pratyush,
> 
> On 26/05/2021 18:22, Pratyush Yadav wrote:
> > Hi,
> > 
> > This series adds support for CSI2 capture on J721E. It includes some
> > fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
> > driver, and finally adds the TI CSI2RX wrapper driver.
> > 
> > Tested on TI's J721E with OV5640 sensor.
> 
> I'm having some trouble unloading and reloading the modules:
> 
> rmmod ti_cal
> rmmod j721e_csi2rx
> rmmod cdns_csi2rx
> rmmod cdns_dphy
> rmmod ov5640

I did some basic module insertion/removal testing but I didn't try 
removing the sensor module. I will check and see what the problem is.

> [   37.943128] ------------[ cut here ]------------
> [   37.947752] WARNING: CPU: 1 PID: 628 at drivers/media/v4l2-core/v4l2-ctrls-core.c:1807 __v4l2_ctrl_handler_setup+0x15c/0x170
> [   37.958963] Modules linked in: ov5640(-) v4l2_fwnode tidss ti_tfp410 tc358767 display_connector cdns_mhdp8546 panel_simple drm_kms_helper drm drm_panel_orientation_quirks cfbfill
> rect cfbimgblt cfbcopyarea phy_j721e_wiz phy_cadence_torrent [last unloaded: cdns_dphy]
> [   37.982455] CPU: 1 PID: 628 Comm: rmmod Not tainted 5.13.0-rc1-00205-g93acc23badc8 #3
> [   37.990271] Hardware name: Texas Instruments K3 J721E SoC (DT)
> [   37.996090] pstate: 60000005 (nZCv daif -PAN -UAO -TCO BTYPE=--)
> [   38.002085] pc : __v4l2_ctrl_handler_setup+0x15c/0x170
> [   38.007214] lr : __v4l2_ctrl_handler_setup+0x158/0x170
> [   38.012343] sp : ffff80001476fae0
> [   38.015648] x29: ffff80001476fae0 x28: ffff000806780000 x27: 0000000000000000
> [   38.022781] x26: ffff00080300b448 x25: ffff000804ad4ac0 x24: 0000000000000001
> [   38.029912] x23: 0000000000000000 x22: 0000000000000005 x21: ffff000801fa7880
> [   38.037043] x20: ffff000801fa7888 x19: ffff000801fa7ba8 x18: 0000000000000000
> [   38.044173] x17: 0000000000000000 x16: 0000000000000010 x15: 0000000000000001
> [   38.051305] x14: 000000000000003b x13: 00000000aaaaaaab x12: ffff800011a915b8
> [   38.058436] x11: 00000000000c001c x10: 000000008260a2b7 x9 : ffff800009362d9c
> [   38.065566] x8 : ffff800011887100 x7 : 0000000000000000 x6 : 0000000000000001
> [   38.072698] x5 : 0000000000000001 x4 : 0000000000000001 x3 : ffff800011260000
> [   38.079829] x2 : 00000000000000c0 x1 : 00000000000000c0 x0 : 0000000000000000
> [   38.086960] Call trace:
> [   38.089399]  __v4l2_ctrl_handler_setup+0x15c/0x170
> [   38.094181]  ov5640_resume+0x1fc/0x270 [ov5640]
> [   38.098709]  __rpm_callback+0x98/0x160
> [   38.102452]  rpm_callback+0x2c/0x90
> [   38.105934]  rpm_resume+0x45c/0x6f4
> [   38.109415]  __pm_runtime_resume+0x54/0xc0
> [   38.113503]  __device_release_driver+0x40/0x240
> [   38.118025]  driver_detach+0xd0/0x160
> [   38.121680]  bus_remove_driver+0x68/0xe0
> [   38.125595]  driver_unregister+0x3c/0x6c
> [   38.129509]  i2c_del_driver+0x64/0xb0
> [   38.133166]  ov5640_i2c_driver_exit+0x1c/0xc948 [ov5640]
> [   38.138469]  __arm64_sys_delete_module+0x1b0/0x27c
> [   38.143251]  invoke_syscall+0x50/0x120
> [   38.146995]  el0_svc_common.constprop.0+0x68/0x104
> [   38.151777]  do_el0_svc+0x30/0x9c
> [   38.155086]  el0_svc+0x2c/0x54
> [   38.158135]  el0_sync_handler+0x1a8/0x1ac
> [   38.162136]  el0_sync+0x198/0x1c0
> [   38.165444] irq event stamp: 11302
> [   38.168837] hardirqs last  enabled at (11301): [<ffff800010bf4e40>] _raw_spin_unlock_irq+0x50/0xa0
> [   38.177781] hardirqs last disabled at (11302): [<ffff800010be7a64>] el1_dbg+0x24/0xa0
> [   38.185595] softirqs last  enabled at (10378): [<ffff800010010ba0>] __do_softirq+0x500/0x6bc
> [   38.194017] softirqs last disabled at (10373): [<ffff80001005d4c4>] __irq_exit_rcu+0x1d4/0x1e0
> [   38.202614] ---[ end trace 7037324a951cb149 ]---
> rmmod v4l2_fwnode
> insmod /root/nfs/work/linux/drivers/media/v4l2-core/v4l2-fwnode.ko
> insmod /root/nfs/work/linux/drivers/phy/cadence/cdns-dphy.ko
> insmod /root/nfs/work/linux/drivers/media/platform/cadence/cdns-csi2rx.ko
> ERROR:   Unhandled External Abort received on 0x80000001 from S-EL1
> ERROR:   exception reason=0 syndrome=0xbf000000
> Unhandled Exception from EL1
> x0             = 0x0000000000000000
> x1             = 0xffff000804d59800
> x2             = 0xffff8000146c4000
> x3             = 0xffff800011260000
> x4             = 0x0000000000000001
> x5             = 0x0000000000000001
> x6             = 0x0000000000000001
> x7             = 0x0000000000000000
> x8             = 0xffff800011887100
> x9             = 0xffff800010bf5190
> x10            = 0x000000008260a2b7
> x11            = 0x00000000000c821d
> x12            = 0xffff800011a915b8
> x13            = 0x0000000000000001
> x14            = 0x0000000000000000
> x15            = 0x0000000000000020
> x16            = 0x0000000000000000
> x17            = 0x0000000000000000
> x18            = 0x00000000fffffffb
> x19            = 0xffff000806d44c00
> x20            = 0x0000000000000000
> x21            = 0xffff800009280058
> x22            = 0xffff00080583c810
> x23            = 0xffff00080583c800
> x24            = 0xffff800009280058
> x25            = 0x0000000000000047
> x26            = 0xffff8000116d71d8
> x27            = 0xffff800009280350
> x28            = 0xffff800009280148
> x29            = 0xffff80001432f850
> x30            = 0xffff8000092506b8
> scr_el3        = 0x000000000000073d
> sctlr_el3      = 0x0000000030cd183f
> cptr_el3       = 0x0000000000000000
> tcr_el3        = 0x0000000080803520
> daif           = 0x00000000000002c0
> mair_el3       = 0x00000000004404ff
> spsr_el3       = 0x0000000000000005
> elr_el3        = 0xffff80000925043c
> ttbr0_el3      = 0x0000000070010b00
> esr_el3        = 0x00000000bf000000
> far_el3        = 0x0000000000000000
> spsr_el1       = 0x0000000060000005
> elr_el1        = 0xffff800010be8cb0
> spsr_abt       = 0x0000000000000000
> spsr_und       = 0x0000000000000000
> spsr_irq       = 0x0000000000000000
> spsr_fiq       = 0x0000000000000000
> sctlr_el1      = 0x0000000034d4d91d
> actlr_el1      = 0x0000000000000000
> cpacr_el1      = 0x0000000000300000
> csselr_el1     = 0x0000000000000000
> sp_el1         = 0xffff80001432f850
> esr_el1        = 0x0000000056000000
> ttbr0_el1      = 0x0000000882773200
> ttbr1_el1      = 0x06d8000083180000
> mair_el1       = 0x000c0400bb44ffff
> amair_el1      = 0x0000000000000000
> tcr_el1        = 0x00000034f5d07590
> tpidr_el1      = 0xffff80086e790000
> tpidr_el0      = 0x0000ffff895c6910
> tpidrro_el0    = 0x0000000000000000
> par_el1        = 0x0000000000000000
> mpidr_el1      = 0x0000000080000001
> afsr0_el1      = 0x0000000000000000
> afsr1_el1      = 0x0000000000000000
> contextidr_el1 = 0x0000000000000000
> vbar_el1       = 0xffff800010011000
> cntp_ctl_el0   = 0x0000000000000005
> cntp_cval_el0  = 0x000000023f77b7a1
> cntv_ctl_el0   = 0x0000000000000000
> cntv_cval_el0  = 0x0000000000000000
> cntkctl_el1    = 0x00000000000000d6
> sp_el0         = 0x000000007000abd0
> isr_el1        = 0x0000000000000040
> dacr32_el2     = 0x0000000000000000
> ifsr32_el2     = 0x0000000000000000
> cpuectlr_el1   = 0x0000001b00000040
> cpumerrsr_el1  = 0x0000000000000000
> l2merrsr_el1   = 0x0000000000000000

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
  2021-06-03 12:52     ` Pratyush Yadav
@ 2021-06-04  7:54       ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-06-04  7:54 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 03/06/2021 15:52, Pratyush Yadav wrote:
> On 27/05/21 04:23PM, Tomi Valkeinen wrote:
>> Hi Pratyush,
>>
>> On 26/05/2021 18:22, Pratyush Yadav wrote:
>>> Hi,
>>>
>>> This series adds support for CSI2 capture on J721E. It includes some
>>> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
>>> driver, and finally adds the TI CSI2RX wrapper driver.
>>>
>>> Tested on TI's J721E with OV5640 sensor.
>>
>> I also see this after a few captures:
> 
> Can you share the application/command you are using to test? I used
> yavta to test and didn't see any problems after leaving the stream on
> for around 10 minutes.

You need to have CONFIG_DMA_API_DEBUG enabled. I think that's not 
enabled by default on TI configs.

  Tomi

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

* Re: [PATCH v2 00/18] CSI2RX support on J721E
@ 2021-06-04  7:54       ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-06-04  7:54 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 03/06/2021 15:52, Pratyush Yadav wrote:
> On 27/05/21 04:23PM, Tomi Valkeinen wrote:
>> Hi Pratyush,
>>
>> On 26/05/2021 18:22, Pratyush Yadav wrote:
>>> Hi,
>>>
>>> This series adds support for CSI2 capture on J721E. It includes some
>>> fixes to the Cadence CSI2RX driver, adds Rx support to Cadence DPHY
>>> driver, and finally adds the TI CSI2RX wrapper driver.
>>>
>>> Tested on TI's J721E with OV5640 sensor.
>>
>> I also see this after a few captures:
> 
> Can you share the application/command you are using to test? I used
> yavta to test and didn't see any problems after leaving the stream on
> for around 10 minutes.

You need to have CONFIG_DMA_API_DEBUG enabled. I think that's not 
enabled by default on TI configs.

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
  2021-06-03 12:49       ` Pratyush Yadav
@ 2021-06-04  8:04         ` Tomi Valkeinen
  -1 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-06-04  8:04 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 03/06/2021 15:49, Pratyush Yadav wrote:
> On 27/05/21 04:29PM, Tomi Valkeinen wrote:
>> Hi Pratyush,
>>
>> On 26/05/2021 18:23, Pratyush Yadav wrote:
>>> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
>>> capture over a CSI-2 bus.
>>>
>>> The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
>>> the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
>>> called the SHIM layer. It takes in data from stream 0, repacks it, and
>>> sends it to memory over PSI-L DMA.
>>>
>>> This driver acts as the "front end" to V4L2 client applications. It
>>> implements the required ioctls and buffer operations, passes the
>>> necessary calls on to the bridge, programs the SHIM layer, and performs
>>> DMA via the dmaengine API to finally return the data to a buffer
>>> supplied by the application.
>>>
>>> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
>>
>> I noticed that my test app didn't work at all with this, and I also wasn't
>> able to use v4l2-ctl to set the format.
> 
> I have not used v4l2-ctl, but I can see yavta works fine. What command
> did you use for setting format via v4l2-ctl?
> 
>>
>> At least for my test app the problem was that this driver doesn't initialize
>> the format at all. My app first calls VIDIOC_G_FMT with v4l2_format.type ==
>> V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call modifies the fields it
>> wants to change and calls VIDIOC_S_FMT. This failed, as G_FMT returned
>> uninitialized fmt, i.e. type was 0, which my app didn't set again.
>>
>> I believe the driver should have an initial format, something that it will
>> accept if an app calls G_FMT and then S_FMT.
> 
> Right. This is a bug. The question is what should the initial format be?
> It is more or less arbitrary since there is no configuration made yet
> and we don't know what the camera can or will send. So for example, what
> if I use UYVY 640x480? The camera might not support it at all. Is it
> still OK to have it as the default?

I think it doesn't really matter what the initial format is, as long as 
it's valid for the subdev itself. There are two separate things:

1) Subdev config, where the subdev is considered independently from the 
other subdevs. E.g. the formats in the input pads and output pads should 
be valid, taking into account the capabilities of the subdev. The subdev 
driver has to take care of these, i.e. if the user sets a format on a 
pad, the driver must adjust the other pads (if needed) to keep the 
subdev config valid.

2) pipeline validation, where all the subdevs in the pipeline are looked 
at and validated that the settings are compatible.

We're talking about 1) here, and it doesn't matter if the camera 
supports the csirx initial format or not.

  Tomi

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

* Re: [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E
@ 2021-06-04  8:04         ` Tomi Valkeinen
  0 siblings, 0 replies; 96+ messages in thread
From: Tomi Valkeinen @ 2021-06-04  8:04 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Maxime Ripard, Mauro Carvalho Chehab, Rob Herring,
	Kishon Vijay Abraham I, Vinod Koul, Peter Ujfalusi,
	Steve Longerbeam, Benoit Parrot, linux-media, devicetree,
	linux-kernel, linux-phy, dmaengine, Vignesh Raghavendra,
	Chunfeng Yun, Laurent Pinchart

On 03/06/2021 15:49, Pratyush Yadav wrote:
> On 27/05/21 04:29PM, Tomi Valkeinen wrote:
>> Hi Pratyush,
>>
>> On 26/05/2021 18:23, Pratyush Yadav wrote:
>>> TI's J721E uses the Cadence CSI2RX and DPHY peripherals to facilitate
>>> capture over a CSI-2 bus.
>>>
>>> The Cadence CSI2RX IP acts as a bridge between the TI specific parts and
>>> the CSI-2 protocol parts. TI then has a wrapper on top of this bridge
>>> called the SHIM layer. It takes in data from stream 0, repacks it, and
>>> sends it to memory over PSI-L DMA.
>>>
>>> This driver acts as the "front end" to V4L2 client applications. It
>>> implements the required ioctls and buffer operations, passes the
>>> necessary calls on to the bridge, programs the SHIM layer, and performs
>>> DMA via the dmaengine API to finally return the data to a buffer
>>> supplied by the application.
>>>
>>> Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
>>
>> I noticed that my test app didn't work at all with this, and I also wasn't
>> able to use v4l2-ctl to set the format.
> 
> I have not used v4l2-ctl, but I can see yavta works fine. What command
> did you use for setting format via v4l2-ctl?
> 
>>
>> At least for my test app the problem was that this driver doesn't initialize
>> the format at all. My app first calls VIDIOC_G_FMT with v4l2_format.type ==
>> V4L2_BUF_TYPE_VIDEO_CAPTURE, then after the call modifies the fields it
>> wants to change and calls VIDIOC_S_FMT. This failed, as G_FMT returned
>> uninitialized fmt, i.e. type was 0, which my app didn't set again.
>>
>> I believe the driver should have an initial format, something that it will
>> accept if an app calls G_FMT and then S_FMT.
> 
> Right. This is a bug. The question is what should the initial format be?
> It is more or less arbitrary since there is no configuration made yet
> and we don't know what the camera can or will send. So for example, what
> if I use UYVY 640x480? The camera might not support it at all. Is it
> still OK to have it as the default?

I think it doesn't really matter what the initial format is, as long as 
it's valid for the subdev itself. There are two separate things:

1) Subdev config, where the subdev is considered independently from the 
other subdevs. E.g. the formats in the input pads and output pads should 
be valid, taking into account the capabilities of the subdev. The subdev 
driver has to take care of these, i.e. if the user sets a format on a 
pad, the driver must adjust the other pads (if needed) to keep the 
subdev config valid.

2) pipeline validation, where all the subdevs in the pipeline are looked 
at and validated that the settings are compatible.

We're talking about 1) here, and it doesn't matter if the camera 
supports the csirx initial format or not.

  Tomi

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

end of thread, other threads:[~2021-06-04  8:04 UTC | newest]

Thread overview: 96+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-26 15:22 [PATCH v2 00/18] CSI2RX support on J721E Pratyush Yadav
2021-05-26 15:22 ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 01/18] phy: Distinguish between Rx and Tx for MIPI D-PHY with submodes Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 02/18] phy: cdns-dphy: Prepare for Rx support Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 03/18] phy: cdns-dphy: Allow setting mode Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 04/18] phy: cdns-dphy: Add Rx support Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-28  6:09   ` Tomi Valkeinen
2021-05-28  6:09     ` Tomi Valkeinen
2021-05-26 15:22 ` [PATCH v2 05/18] media: ov5640: Use runtime PM to control sensor power Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-28  6:44   ` Tomi Valkeinen
2021-05-28  6:44     ` Tomi Valkeinen
2021-05-28  7:25     ` Pratyush Yadav
2021-05-28  7:25       ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 06/18] media: cadence: csi2rx: Add external DPHY support Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-28  7:23   ` Tomi Valkeinen
2021-05-28  7:23     ` Tomi Valkeinen
2021-05-28  7:30     ` Pratyush Yadav
2021-05-28  7:30       ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 07/18] media: cadence: csi2rx: Soft reset the streams before starting capture Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 08/18] media: cadence: csi2rx: Set the STOP bit when stopping a stream Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:22 ` [PATCH v2 09/18] media: cadence: csi2rx: Fix stream data configuration Pratyush Yadav
2021-05-26 15:22   ` Pratyush Yadav
2021-05-26 15:23 ` [PATCH v2 10/18] media: cadence: csi2rx: Populate subdev devnode Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-05-28  7:16   ` Tomi Valkeinen
2021-05-28  7:16     ` Tomi Valkeinen
2021-05-28  7:24     ` Pratyush Yadav
2021-05-28  7:24       ` Pratyush Yadav
2021-05-28  7:35       ` Tomi Valkeinen
2021-05-28  7:35         ` Tomi Valkeinen
2021-06-03 12:42         ` Pratyush Yadav
2021-06-03 12:42           ` Pratyush Yadav
2021-05-26 15:23 ` [PATCH v2 11/18] dmaengine: ti: k3-psil-j721e: Add entry for CSI2RX Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-05-31  6:51   ` Péter Ujfalusi
2021-05-31  6:51     ` Péter Ujfalusi
2021-05-31  9:16     ` Pratyush Yadav
2021-05-31  9:16       ` Pratyush Yadav
2021-05-26 15:23 ` [PATCH v2 12/18] media: Re-structure TI platform drivers Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-05-28  8:29   ` Tomi Valkeinen
2021-05-28  8:29     ` Tomi Valkeinen
2021-05-26 15:23 ` [PATCH v2 13/18] media: ti: Add CSI2RX support for J721E Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-05-27 13:29   ` Tomi Valkeinen
2021-05-27 13:29     ` Tomi Valkeinen
2021-06-03 12:49     ` Pratyush Yadav
2021-06-03 12:49       ` Pratyush Yadav
2021-06-04  8:04       ` Tomi Valkeinen
2021-06-04  8:04         ` Tomi Valkeinen
2021-05-26 15:23 ` [PATCH v2 14/18] media: dt-bindings: Add DT bindings for TI J721E CSI2RX driver Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-05-27 14:23   ` Rob Herring
2021-05-27 14:23     ` Rob Herring
2021-06-03 12:43     ` Pratyush Yadav
2021-06-03 12:43       ` Pratyush Yadav
2021-05-26 15:23 ` [PATCH v2 15/18] media: dt-bindings: Convert Cadence CSI2RX binding to YAML Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-06-01 17:45   ` Rob Herring
2021-06-01 17:45     ` Rob Herring
2021-06-03 12:23     ` Pratyush Yadav
2021-06-03 12:23       ` Pratyush Yadav
2021-05-26 15:23 ` [PATCH v2 16/18] phy: dt-bindings: Convert Cadence DPHY " Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-06-02 19:51   ` Rob Herring
2021-06-02 19:51     ` Rob Herring
2021-05-26 15:23 ` [PATCH v2 17/18] phy: dt-bindings: cdns,dphy: make clocks optional Pratyush Yadav
2021-05-26 15:23   ` Pratyush Yadav
2021-06-02 13:27   ` Maxime Ripard
2021-06-02 13:27     ` Maxime Ripard
2021-06-03  8:16     ` Pratyush Yadav
2021-06-03  8:16       ` Pratyush Yadav
2021-06-02 20:03   ` Rob Herring
2021-06-02 20:03     ` Rob Herring
2021-05-26 15:23 ` [PATCH v2 18/18] phy: dt-bindings: cdns,dphy: add power-domains property Pratyush Yadav
2021-05-26 15:23   ` [PATCH v2 18/18] phy: dt-bindings: cdns, dphy: " Pratyush Yadav
2021-06-02 20:03   ` [PATCH v2 18/18] phy: dt-bindings: cdns,dphy: " Rob Herring
2021-06-02 20:03     ` Rob Herring
2021-05-27 12:42 ` [PATCH v2 00/18] CSI2RX support on J721E Tomi Valkeinen
2021-05-27 12:42   ` Tomi Valkeinen
2021-06-03 12:54   ` Pratyush Yadav
2021-06-03 12:54     ` Pratyush Yadav
2021-05-27 13:23 ` Tomi Valkeinen
2021-05-27 13:23   ` Tomi Valkeinen
2021-06-03 12:52   ` Pratyush Yadav
2021-06-03 12:52     ` Pratyush Yadav
2021-06-04  7:54     ` Tomi Valkeinen
2021-06-04  7:54       ` Tomi Valkeinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.