Skip to contentSkip to conversation

Initial support for Cadence MHDP(HDMI/DP) for i.MX8MQ

PATCH Superseded Sandor Yu 4 participants 20 messages Nov 4, 2022 – Nov 14, 2022

Subsystems (6)

v2 of 20 Superseded Latest is v20 →

lore
Share & tools
lore

Sandor Yu

author
#0 lore raw

v2 cover Initial support for Cadence MHDP(HDMI/DP) for i.MX8MQ

The patch set initial support for Cadence MHDP(HDMI/DP) DRM bridge drivers and Cadence HDP-TX PHY(HDMI/DP) drivers for iMX8MQ.

v2 is a completely different version compared to v1. Previous v1 can be available here [1].

v1->v2:
- Reuse Cadence mailbox access functions from mhdp8546 instead of rockchip DP.
- Mailbox access functions be convert to marco functions that will be referenced by HDP-TX PHY(HDMI/DP) driver too.
- Plain bridge instead of component driver.
- Standalone Cadence HDP-TX PHY(HDMI/DP) driver.
- Audio driver are removed from the patch set, it will be add in another patch set later.

The patch set compose of DRM bridge drivers and PHY drivers. Both of them need the followed two patches to pass build.
drm: bridge: cadence: convert mailbox functions to macro functions
phy: Add HDMI configuration options

DRM bridges driver patches:
dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ
drm: bridge: cadence: Add MHDP DP driver for i.MX8MQ
dts-bindings: display: bridge: Add MHDP DP bindings for i.MX8MQ
drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

PHY driver patches:
dts-bindings: phy: Add Cadence HDP-TX DP PHY bindings
phy: cadence: Add driver for HDP-TX DisplyPort PHY
dts-bindings: phy: Add Cadence HDP-TX HDMI PHY bindings
phy: cadence: Add driver for HDP-TX HDMI PHY

[1] https://patchwork.kernel.org/project/linux-rockchip/cover/[email protected]/

Sandor Yu (10):
drm: bridge: cadence: convert mailbox functions to macro functions
dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ
drm: bridge: cadence: Add MHDP DP driver for i.MX8MQ
phy: Add HDMI configuration options
dts-bindings: display: bridge: Add MHDP DP bindings for i.MX8MQ
drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ
dts-bindings: phy: Add Cadence HDP-TX DP PHY bindings
phy: cadence: Add driver for HDP-TX DisplyPort PHY
dts-bindings: phy: Add Cadence HDP-TX HDMI PHY bindings
phy: cadence: Add driver for HDP-TX HDMI PHY

 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   |   67 ++
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml |   67 ++
 .../bindings/phy/phy-cadence-hdptx-dp.yaml    |   70 ++
 .../bindings/phy/phy-cadence-hdptx-hdmi.yaml  |   54 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |   25 +
 drivers/gpu/drm/bridge/cadence/Makefile       |    3 +
 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1070 +++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038 ++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp-common.h |  402 +++++++
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   |  197 +--
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |    1 -
 drivers/phy/cadence/Kconfig                   |   16 +
 drivers/phy/cadence/Makefile                  |    2 +
 drivers/phy/cadence/phy-cadence-hdptx-dp.c    |  774 ++++++++++++
 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c  |  948 +++++++++++++++
 include/drm/bridge/cdns-mhdp-mailbox.h        |  240 ++++
 include/linux/phy/phy-hdmi.h                  |   33 +
 include/linux/phy/phy.h                       |    7 +-
 18 files changed, 4817 insertions(+), 197 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.h
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-dp.c
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c
 create mode 100644 include/drm/bridge/cdns-mhdp-mailbox.h
 create mode 100644 include/linux/phy/phy-hdmi.h
Signature · 1 line
2.34.1
author
#1 lore raw

PATCH v2 1/10 drm: bridge: cadence: convert mailbox functions to macro functions

Mailbox access functions could be share to other mhdp driver and HDP-TX HDMI/DP PHY drivers, move those functions to head file include/drm/bridge/cdns-mhdp-mailbox.h and convert them to macro functions.

---
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 197 +-------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |   1 -
 include/drm/bridge/cdns-mhdp-mailbox.h        | 240 ++++++++++++++++++
 3 files changed, 242 insertions(+), 196 deletions(-)
 create mode 100644 include/drm/bridge/cdns-mhdp-mailbox.h
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +2 -195
index 31442a922502..b77b0ddcc9b3 100644
@@ -36,6 +36,7 @@
 #include <linux/slab.h>
 #include <linux/wait.h>
 
+#include <drm/bridge/cdns-mhdp-mailbox.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/display/drm_hdcp_helper.h>
 #include <drm/drm_atomic.h>
@@ -55,200 +56,6 @@
 #include "cdns-mhdp8546-hdcp.h"
 #include "cdns-mhdp8546-j721e.h"
 
-static int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp)
-{
-	int ret, empty;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_EMPTY,
-				 empty, !empty, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	return readl(mhdp->regs + CDNS_MAILBOX_RX_DATA) & 0xff;
-}
-
-static int cdns_mhdp_mailbox_write(struct cdns_mhdp_device *mhdp, u8 val)
-{
-	int ret, full;
-
-	WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-	ret = readx_poll_timeout(readl, mhdp->regs + CDNS_MAILBOX_FULL,
-				 full, !full, MAILBOX_RETRY_US,
-				 MAILBOX_TIMEOUT_US);
-	if (ret < 0)
-		return ret;
-
-	writel(val, mhdp->regs + CDNS_MAILBOX_TX_DATA);
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_header(struct cdns_mhdp_device *mhdp,
-					 u8 module_id, u8 opcode,
-					 u16 req_size)
-{
-	u32 mbox_size, i;
-	u8 header[4];
-	int ret;
-
-	/* read the header of the message */
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		header[i] = ret;
-	}
-
-	mbox_size = get_unaligned_be16(header + 2);
-
-	if (opcode != header[0] || module_id != header[1] ||
-	    req_size != mbox_size) {
-		/*
-		 * If the message in mailbox is not what we want, we need to
-		 * clear the mailbox by reading its contents.
-		 */
-		for (i = 0; i < mbox_size; i++)
-			if (cdns_mhdp_mailbox_read(mhdp) < 0)
-				break;
-
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_recv_data(struct cdns_mhdp_device *mhdp,
-				       u8 *buff, u16 buff_size)
-{
-	u32 i;
-	int ret;
-
-	for (i = 0; i < buff_size; i++) {
-		ret = cdns_mhdp_mailbox_read(mhdp);
-		if (ret < 0)
-			return ret;
-
-		buff[i] = ret;
-	}
-
-	return 0;
-}
-
-static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8 module_id,
-				  u8 opcode, u16 size, u8 *message)
-{
-	u8 header[4];
-	int ret, i;
-
-	header[0] = opcode;
-	header[1] = module_id;
-	put_unaligned_be16(size, header + 2);
-
-	for (i = 0; i < sizeof(header); i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, header[i]);
-		if (ret)
-			return ret;
-	}
-
-	for (i = 0; i < size; i++) {
-		ret = cdns_mhdp_mailbox_write(mhdp, message[i]);
-		if (ret)
-			return ret;
-	}
-
-	return 0;
-}
-
-static
-int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr, u32 *value)
-{
-	u8 msg[4], resp[8];
-	int ret;
-
-	put_unaligned_be32(addr, msg);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,
-				     GENERAL_REGISTER_READ,
-				     sizeof(msg), msg);
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,
-					    GENERAL_REGISTER_READ,
-					    sizeof(resp));
-	if (ret)
-		goto out;
-
-	ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));
-	if (ret)
-		goto out;
-
-	/* Returned address value should be the same as requested */
-	if (memcmp(msg, resp, sizeof(msg))) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	*value = get_unaligned_be32(resp + 4);
-
-out:
-	mutex_unlock(&mhdp->mbox_mutex);
-	if (ret) {
-		dev_err(mhdp->dev, "Failed to read register\n");
-		*value = 0;
-	}
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u16 addr, u32 val)
-{
-	u8 msg[6];
-	int ret;
-
-	put_unaligned_be16(addr, msg);
-	put_unaligned_be32(val, msg + 2);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_REGISTER, sizeof(msg), msg);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
-static
-int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,
-			    u8 start_bit, u8 bits_no, u32 val)
-{
-	u8 field[8];
-	int ret;
-
-	put_unaligned_be16(addr, field);
-	field[2] = start_bit;
-	field[3] = bits_no;
-	put_unaligned_be32(val, field + 4);
-
-	mutex_lock(&mhdp->mbox_mutex);
-
-	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
-				     DPTX_WRITE_FIELD, sizeof(field), field);
-
-	mutex_unlock(&mhdp->mbox_mutex);
-
-	return ret;
-}
-
 static
 int cdns_mhdp_dpcd_read(struct cdns_mhdp_device *mhdp,
 			u32 addr, u8 *data, u16 len)
@@ -2058,7 +1865,7 @@ static void cdns_mhdp_atomic_disable(struct drm_bridge *bridge,
 				     struct drm_bridge_state *bridge_state)
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
-	u32 resp;
+	u32 resp = 0;
 
 	dev_dbg(mhdp->dev, "%s\n", __func__);
 
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +0 -1
index bedddd510d17..10c878bf0e63 100644
@@ -212,7 +212,6 @@ struct phy;
 #define MB_MODULE_ID_HDCP_TX			0x07
 #define MB_MODULE_ID_HDCP_RX			0x08
 #define MB_MODULE_ID_HDCP_GENERAL		0x09
-#define MB_MODULE_ID_GENERAL			0x0a
 
 /* firmware and opcodes */
 #define FW_NAME					"cadence/mhdp8546.bin"
include/drm/bridge/cdns-mhdp-mailbox.h new file +240 -0

240 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#2 lore raw

PATCH v2 2/10 dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ

In reply to Sandor Yu

Add bindings for i.MX8MQ MHDP HDMI.

---
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +67 -0
new file mode 100644
index 000000000000..b2a769d4cb82
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence MHDP HDMI bridge
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+description:
+  The Cadence MHDP TX HDMI interface.
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-hdmi
+
+  reg:
+    items:
+      - description:
+          Memory mapped base address and length of mhdptx apb registers.
+
+  phys:
+    description:
+      phandle to the HDMI PHY.
+
+  phy-names:
+    items:
+      - const: hdmiphy
+
+  interrupts:
+    items:
+      - description: Hotplug detect interrupter for cable plugin event.
+      - description: Hotplug detect interrupter for cable plugout event.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the output port of a display controller..
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp: mhdp@32c00000 {
+        compatible = "cdns,mhdp-imx8mq-hdmi";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "plug_in", "plug_out";
+        phys = <&hdmi_phy>;
+        phy-names = "hdmiphy";
+
+        port {
+            mhdp_in: endpoint {
+                remote-endpoint = <&dcss_out>;
+            };
+        };
+    };
Signature · 1 line
2.34.1
#3 lore raw

Re: [v2 02/10] dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ

Quoted 1 line · Sandor Yu

Add bindings for i.MX8MQ MHDP HDMI.

Typo in subject - bindings.

Also in the subject - drop redundant second word "bindings".

Quoted 26 lines
---
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +13 -0
new file mode 100644
index 000000000000..b2a769d4cb82
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence MHDP HDMI bridge
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+description:
+  The Cadence MHDP TX HDMI interface.

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 23

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +10 -0
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-hdmi
+
+  reg:
+    items:
+      - description:
+          Memory mapped base address and length of mhdptx apb registers.

Drop items and descripion and just "maxItems: 1"

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 27

Quoted 4 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +4 -0
+
+  phys:
+    description:
+      phandle to the HDMI PHY.

Drop description, but instead "maxItems: 1"

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 31

Quoted 4 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +4 -0
+
+  phy-names:
+    items:
+      - const: hdmiphy

Drop entire phy-names, not useful with one entry matching the name of theh block.

Quoted 5 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +5 -0
+
+  interrupts:
+    items:
+      - description: Hotplug detect interrupter for cable plugin event.
+      - description: Hotplug detect interrupter for cable plugout event.

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 46

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +10 -0
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the output port of a display controller..

Just one '.' at the end.

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 53

Quoted 7 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +7 -0
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp: mhdp@32c00000 {

Node names should be generic, so hdmi-bridge, display-controller or just "hdmi"
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml line 55

Quoted 2 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +2 -0
+        compatible = "cdns,mhdp-imx8mq-hdmi";
+        reg = <0x32c00000 0x100000>;

Best regards,
Krzysztof

maintainer
#4 lore raw

Re: [v2 02/10] dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ

Quoted 4 lines · Krzysztof Kozlowski
Quoted 1 line · Sandor Yu

Add bindings for i.MX8MQ MHDP HDMI.

Typo in subject - bindings.

And 'dts'. It's 'dt-bindings: display: ...' Same for the rest of the series.

Quoted 9 lines

Also in the subject - drop redundant second word "bindings".

Quoted 6 lines
---
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml
author
#5 lore raw

PATCH v2 3/10 drm: bridge: cadence: Add MHDP DP driver for i.MX8MQ

In reply to Sandor Yu

Add a new DRM DisplayPort bridge driver for Candence MHDP used in i.MX8MQ SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the DisplayPort FW was loaded and activated by SOC ROM code. Bootload binary included HDMI FW was required for the driver.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   13 +
 drivers/gpu/drm/bridge/cadence/Makefile       |    3 +
 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1070 +++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp-common.h |  402 +++++++
 4 files changed, 1488 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.h
drivers/gpu/drm/bridge/cadence/Kconfig +13 -0
index 1d06182bea71..e79ae1af3765 100644
@@ -25,3 +25,16 @@ config DRM_CDNS_MHDP8546_J721E
 	  initializes the J721E Display Port and sets up the
 	  clock and data muxes.
 endif
+
+config DRM_CDNS_DP
+	tristate "Cadence DP DRM driver"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_DP_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP DisplayPort driver.
+	  Cadence MHDP Controller support one or more protocols,
+	  DisplayPort firmware is required for this driver.
drivers/gpu/drm/bridge/cadence/Makefile +3 -0
index 4d2db8df1bc6..269ef500c29d 100644
@@ -2,3 +2,6 @@
 obj-$(CONFIG_DRM_CDNS_MHDP8546) += cdns-mhdp8546.o
 cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-hdcp.o
 cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o
+
+obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o
+obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o
drivers/gpu/drm/bridge/cadence/cdns-dp-core.c new file +1070 -0

1,070 lines not on this page · raw message

drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.h new file +402 -0

402 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#6 lore raw

PATCH v2 4/10 phy: Add HDMI configuration options

In reply to Sandor Yu

Allow HDMI PHYs to be configured through the generic functions through a custom structure added to the generic union.

The parameters added here are based on HDMI PHY implementation practices. The current set of parameters should cover the potential users.

---
 include/linux/phy/phy-hdmi.h | 33 +++++++++++++++++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/phy/phy-hdmi.h
include/linux/phy/phy-hdmi.h new file +33 -0
new file mode 100644
index 000000000000..73a32eb535b0
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+enum hdmi_phy_colorspace {
+	HDMI_PHY_COLORSPACE_RGB,
+	HDMI_PHY_COLORSPACE_YUV422,
+	HDMI_PHY_COLORSPACE_YUV444,
+	HDMI_PHY_COLORSPACE_YUV420,
+	HDMI_PHY_COLORSPACE_RESERVED4,
+	HDMI_PHY_COLORSPACE_RESERVED5,
+	HDMI_PHY_COLORSPACE_RESERVED6,
+};
+
+/**
+ * struct phy_configure_opts_hdmi - HDMI configuration set
+ * @pixel_clk_rate:	Pixel clock of video modes in KHz.
+ * @bpc: Maximum bits per color channel.
+ * @color_space: Colorspace in enum hdmi_phy_colorspace.
+ *
+ * This structure is used to represent the configuration state of a HDMI phy.
+ */
+struct phy_configure_opts_hdmi {
+	unsigned int pixel_clk_rate;
+	unsigned int bpc;
+	enum hdmi_phy_colorspace color_space;
+};
+
+#endif /* __PHY_HDMI_H_ */
include/linux/phy/phy.h +6 -1
index b1413757fcc3..6f6873ea7270 100644
@@ -17,6 +17,7 @@
 #include <linux/regulator/consumer.h>
 
 #include <linux/phy/phy-dp.h>
+#include <linux/phy/phy-hdmi.h>
 #include <linux/phy/phy-lvds.h>
 #include <linux/phy/phy-mipi-dphy.h>
 
@@ -42,7 +43,8 @@ enum phy_mode {
 	PHY_MODE_MIPI_DPHY,
 	PHY_MODE_SATA,
 	PHY_MODE_LVDS,
-	PHY_MODE_DP
+	PHY_MODE_DP,
+	PHY_MODE_HDMI,
 };
 
 enum phy_media {
@@ -60,11 +62,14 @@ enum phy_media {
  *		the DisplayPort protocol.
  * @lvds:	Configuration set applicable for phys supporting
  *		the LVDS phy mode.
+ * @hdmi:	Configuration set applicable for phys supporting
+ *		the HDMI phy mode.
  */
 union phy_configure_opts {
 	struct phy_configure_opts_mipi_dphy	mipi_dphy;
 	struct phy_configure_opts_dp		dp;
 	struct phy_configure_opts_lvds		lvds;
+	struct phy_configure_opts_hdmi		hdmi;
 };
 
 /**
Signature · 1 line
2.34.1
author
#7 lore raw

PATCH v2 5/10 dts-bindings: display: bridge: Add MHDP DP bindings for i.MX8MQ

In reply to Sandor Yu

Add bindings for i.MX8MQ MHDP DisplayPort.

---
 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +67 -0
new file mode 100644
index 000000000000..06ed881247ea
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp-imx8mq-dp.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence MHDP Displayport bridge
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+description:
+  The Cadence MHDP Displayport TX interface.
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-dp
+
+  reg:
+    items:
+      - description:
+          Memory mapped base address and length of mhdptx apb registers.
+
+  phys:
+    description:
+      phandle to the Displayport PHY.
+
+  phy-names:
+    items:
+      - const: dpphy
+
+  interrupts:
+    items:
+      - description: Hotplug detect interrupter for cable plugin event.
+      - description: Hotplug detect interrupter for cable plugout event.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the output port of a display controller..
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp: mhdp@32c00000 {
+        compatible = "cdns,mhdp-imx8mq-dp";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "plug_in", "plug_out";
+        phys = <&dp_phy>;
+        phy-names = "dpphy";
+
+        port {
+            hdmi_in: endpoint {
+                remote-endpoint = <&dcss_out>;
+            };
+        };
+    };
Signature · 1 line
2.34.1
#8 lore raw

Re: [v2 05/10] dts-bindings: display: bridge: Add MHDP DP bindings for i.MX8MQ

Quoted 3 lines · Sandor Yu

Add bindings for i.MX8MQ MHDP DisplayPort.

Same comments as for HDMI bindings patch. Everywhere.

Quoted 54 lines
---
 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +43 -0
new file mode 100644
index 000000000000..06ed881247ea
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/bridge/cdns,mhdp-imx8mq-dp.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence MHDP Displayport bridge
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+description:
+  The Cadence MHDP Displayport TX interface.
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-dp
+
+  reg:
+    items:
+      - description:
+          Memory mapped base address and length of mhdptx apb registers.
+
+  phys:
+    description:
+      phandle to the Displayport PHY.
+
+  phy-names:
+    items:
+      - const: dpphy
+
+  interrupts:
+    items:
+      - description: Hotplug detect interrupter for cable plugin event.
+      - description: Hotplug detect interrupter for cable plugout event.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  port:

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml line 53

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +10 -0
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the output port of a display controller..
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp: mhdp@32c00000 {

dp@

Quoted 4 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +4 -0
+        compatible = "cdns,mhdp-imx8mq-dp";
+        reg = <0x32c00000 0x100000>;
+        interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;

Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml line 67

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +10 -0
+        interrupt-names = "plug_in", "plug_out";
+        phys = <&dp_phy>;
+        phy-names = "dpphy";
+
+        port {
+            hdmi_in: endpoint {
+                remote-endpoint = <&dcss_out>;
+            };
+        };
+    };

Best regards,
Krzysztof

author
#9 lore raw

PATCH v2 6/10 drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

In reply to Sandor Yu

Add a new DRM HDMI bridge driver for Candence MHDP used in i.MX8MQ SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the HDMI FW was loaded and activated by SOC ROM code. Bootload binary included HDMI FW was required for the driver.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   12 +
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038 +++++++++++++++++
 2 files changed, 1050 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
drivers/gpu/drm/bridge/cadence/Kconfig +12 -0
index e79ae1af3765..377452d09992 100644
@@ -26,6 +26,18 @@ config DRM_CDNS_MHDP8546_J721E
 	  clock and data muxes.
 endif
 
+config DRM_CDNS_HDMI
+	tristate "Cadence HDMI DRM driver"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP HDMI driver.
+	  Cadence MHDP Controller support one or more protocols,
+	  HDMI firmware is required for this driver.
+
 config DRM_CDNS_DP
 	tristate "Cadence DP DRM driver"
 	select DRM_KMS_HELPER
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1038 -0

1,038 lines not on this page · raw message

Signature · 1 line
2.34.1
#10 lore raw

Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Hello,

thanks for working on this and the updated version.

Am Freitag, 4. November 2022, 07:44:56 CET schrieb Sandor Yu:

Quoted 67 lines

Add a new DRM HDMI bridge driver for Candence MHDP used in i.MX8MQ SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the HDMI FW was loaded and activated by SOC ROM code. Bootload binary included HDMI FW was required for the driver.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   12 +
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038 +++++++++++++++++
 2 files changed, 1050 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
(quoted diff) +0 -0

b/drivers/gpu/drm/bridge/cadence/Kconfig index e79ae1af3765..377452d09992 100644

drivers/gpu/drm/bridge/cadence/Kconfig +12 -0
@@ -26,6 +26,18 @@ config DRM_CDNS_MHDP8546_J721E
 	  clock and data muxes.
 endif
 
+config DRM_CDNS_HDMI
+	tristate "Cadence HDMI DRM driver"
+	select DRM_KMS_HELPER
+	select DRM_PANEL_BRIDGE
+	select DRM_DISPLAY_HELPER
+	select DRM_CDNS_AUDIO
+	depends on OF
+	help
+	  Support Cadence MHDP HDMI driver.
+	  Cadence MHDP Controller support one or more protocols,
+	  HDMI firmware is required for this driver.
+
 config DRM_CDNS_DP
 	tristate "Cadence DP DRM driver"
 	select DRM_KMS_HELPER
(quoted diff) +0 -0

b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file mode 100644 index 000000000000..b392aac015bd

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +23 -0
@@ -0,0 +1,1038 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence High-Definition Multimedia Interface (HDMI) driver
+ *
+ * Copyright (C) 2019-2022 NXP Semiconductor, Inc.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/hdmi.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-hdmi.h>
+
+#include <drm/bridge/cdns-mhdp-mailbox.h>
+#include <drm/display/drm_hdmi_helper.h>
+#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 33

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+#include <drm/drm_encoder_slave.h>
+#include <drm/drm_of.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "cdns-mhdp-common.h"
+
+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp,
+					u8 entry_id, u8 packet_len, 

u8 *packet, u8 packet_type)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +8 -0
+{
+	u32 *packet32, len32;
+	u32 val, i;
+
+	/* invalidate entry */
+	val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + 

SOURCE_PIF_PKT_ALLOC_WR_EN);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 47

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+
+	/* flush fifo 1 */
+	writel(F_FIFO1_FLUSH(1), mhdp->regs + SOURCE_PIF_FIFO1_FLUSH);
+
+	/* write packet into memory */
+	packet32 = (u32 *)packet;

This only works on little-endian machines, no?

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+	len32 = packet_len / 4;
+	for (i = 0; i < len32; i++)
+		writel(F_DATA_WR(packet32[i]), mhdp->regs + 

SOURCE_PIF_DATA_WR);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+	/* write entry id */
+	writel(F_WR_ADDR(entry_id), mhdp->regs + SOURCE_PIF_WR_ADDR);
+
+	/* write request */
+	writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
+
+	/* update entry */
+	val =  F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
+			F_PACKET_TYPE(packet_type) | 

F_PKT_ALLOC_ADDRESS(entry_id);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+	writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+
+	writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs + 

SOURCE_PIF_PKT_ALLOC_WR_EN);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 75

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+}
+
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+			  u32 block, size_t length)
+{
+	struct cdns_mhdp_device *mhdp = data;
+	u8 msg[2], reg[5], i;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	for (i = 0; i < 4; i++) {

What is i? It is not used inside the loop.

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+		msg[0] = block / 2;
+		msg[1] = block % 2;
+
+		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, 

HDMI_TX_EDID,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+					  sizeof(msg), msg);
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_header(mhdp, 

MB_MODULE_ID_HDMI_TX,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 85

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+						      

HDMI_TX_EDID, sizeof(reg) + length);

Quoted 25 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +25 -0
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+		if (ret)
+			continue;
+
+		ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+		if (ret)
+			continue;
+
+		if ((reg[3] << 8 | reg[4]) == length)
+			break;
+	}
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		DRM_ERROR("get block[%d] edid failed: %d\n", block, ret);
+	return ret;
+}
+
+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data)
+{
+	u8 msg[4], reg[6];

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	int ret;
+
+	msg[0] = 0x54;
+	msg[1] = addr;
+	msg[2] = 0;
+	msg[3] = 1;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, 

HDMI_TX_READ,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+				  sizeof(msg), msg);
+	if (ret)
+		goto err_scdc_read;
+
+	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_HDMI_TX,
+					      HDMI_TX_READ, 

sizeof(reg));

Quoted 22 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +22 -0
+	if (ret)
+		goto err_scdc_read;
+
+	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+	if (ret)
+		goto err_scdc_read;
+
+	*data = reg[5];
+
+err_scdc_read:
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		DRM_ERROR("scdc read failed: %d\n", ret);
+	return ret;
+}
+
+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value)
+{
+	u8 msg[5], reg[5];
+	int ret;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+	msg[0] = 0x54;
+	msg[1] = addr;
+	msg[2] = 0;
+	msg[3] = 1;
+	msg[4] = value;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX, 

HDMI_TX_WRITE,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+				  sizeof(msg), msg);
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_HDMI_TX,
+					      HDMI_TX_WRITE, 

sizeof(reg));

Quoted 19 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +19 -0
+	if (ret)
+		goto err_scdc_write;
+
+	ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+	if (ret)
+		goto err_scdc_write;
+
+	if (reg[0] != 0)
+		ret = -EINVAL;
+
+err_scdc_write:
+
+	mutex_unlock(&mhdp->mbox_mutex);
+
+	if (ret)
+		DRM_ERROR("scdc write failed: %d\n", ret);
+	return ret;
+}
+

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp,
+				 int protocol, u32 char_rate)
+{
+	u32 reg0;
+	u32 reg1;
+	u32 val;
+	int ret;
+
+	/* Set PHY to HDMI data */
+	ret = cdns_mhdp_reg_write(mhdp, PHY_DATA_SEL, 

F_SOURCE_PHY_MHDP_SEL(1));

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+	if (ret < 0)
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_HPD,
+					F_HPD_VALID_WIDTH(4) | 

F_HPD_GLITCH_WIDTH(0));

Quoted 30 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +30 -0
+	if (ret < 0)
+		return ret;
+
+	/* open CARS */
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_PHY_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, 0xFF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_PKT_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_AIF_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_CIPHER_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_CRYPTO_CAR, 0xF);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, SOURCE_CEC_CAR, 3);
+	if (ret < 0)
+		return ret;
+
+	reg0 = reg1 = 0x7c1f;
+	if (protocol == MODE_HDMI_2_0 && char_rate >= 340000) {
+		reg0 = 0;
+		reg1 = 0xFFFFF;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	}
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_0, reg0);
+	if (ret < 0)
+		return ret;
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_1, reg1);
+	if (ret < 0)
+		return ret;
+
+	/* set hdmi mode and preemble mode data enable */
+	val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |  F_DATA_EN(1) 

|

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 239

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+			F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) | 

F_PIC_3D(0XF);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp,
+					      struct 

drm_display_mode *mode,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 247

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+						  struct 

video_info *video_info)

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +8 -0
+{
+	int ret;
+	u32 val;
+	u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+	u32 eof_lines = mode->vsync_start - mode->vdisplay;
+	u32 sof_lines = mode->vtotal - mode->vsync_end;
+	u32 hblank = mode->htotal - mode->hdisplay;
+	u32 hactive = mode->hdisplay;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	u32 vblank = mode->vtotal - mode->vdisplay;
+	u32 vactive = mode->vdisplay;
+	u32 hfront = mode->hsync_start - mode->hdisplay;
+	u32 hback = mode->htotal - mode->hsync_end;
+	u32 vfront = eof_lines;
+	u32 hsync = hblank - hfront - hback;
+	u32 vsync = vsync_lines;
+	u32 vback = sof_lines;
+	u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ? 0 : 1) +
+						((mode->flags & 

DRM_MODE_FLAG_NVSYNC) ? 0 : 2);

Please fix the alignment.

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +2 -0
+
+	ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_H_SIZE, (hactive << 16) +

hblank); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_V_SIZE, (vactive << 16) +

vblank); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_FRONT_WIDTH, (vfront << 

16) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines

hfront); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_SYNC_WIDTH, (vsync << 

16) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines

hsync); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_BACK_WIDTH, (vback << 

16) +

Quoted 88 lines

hback); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +87 -0
+		return ret;
+
+	ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL, v_h_polarity);
+	if (ret < 0)
+		return ret;
+
+	/* Reset Data Enable */
+	cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+	val &= ~F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* Set bpc */
+	val &= ~F_VIF_DATA_WIDTH(3);
+	switch (video_info->bpc) {
+	case 10:
+		val |= F_VIF_DATA_WIDTH(1);
+		break;
+	case 12:
+		val |= F_VIF_DATA_WIDTH(2);
+		break;
+	case 16:
+		val |= F_VIF_DATA_WIDTH(3);
+		break;
+	case 8:
+	default:
+		val |= F_VIF_DATA_WIDTH(0);
+		break;
+	}
+
+	/* select color encoding */
+	val &= ~F_HDMI_ENCODING(3);
+	switch (video_info->color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		val |= F_HDMI_ENCODING(2);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		val |= F_HDMI_ENCODING(1);
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		val |= F_HDMI_ENCODING(3);
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		val |= F_HDMI_ENCODING(0);
+		break;
+	}
+
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+	if (ret < 0)
+		return ret;
+
+	/* set data enable */
+	val |= F_DATA_EN(1);
+	ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+
+	return ret;
+}
+
+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+	val &= ~F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+}
+
+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp)
+{
+	u32 val;
+
+	cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+	val |= F_GCP_EN(1);
+
+	return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+}
+
+static void hdmi_sink_config(struct cdns_mhdp_device *mhdp)
+{
+	struct drm_scdc *scdc = &mhdp->curr_conn->display_info.hdmi.scdc;
+	u8 buff = 0;
+
+	/* Default work in HDMI1.4 */
+	mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+	/* check sink support SCDC or not */
+	if (scdc->supported != true) {
+		DRM_INFO("Sink Not Support SCDC\n");
+		return;
+	}
+
+	if (mhdp->hdmi.char_rate > 340000) {
+		/*
+		 * TMDS Character Rate above 340MHz should working in 

HDMI2.0

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+		 * Enable scrambling and TMDS_Bit_Clock_Ratio
+		 */
+		buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 | 

SCDC_SCRAMBLING_ENABLE;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	} else  if (scdc->scrambling.low_rates) {
+		/*
+		 * Enable scrambling and HDMI2.0 when scrambling 

capability of sink

Quoted 26 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +25 -0
+		 * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+		 */
+		buff = SCDC_SCRAMBLING_ENABLE;
+		mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+	}
+
+	/* TMDS config */
+	cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff);
+}
+
+static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp)
+{
+	u32 lane_mapping = mhdp->plat_data->lane_mapping;
+	/* Line swapping */
+	cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | lane_mapping);
+}
+
+int cdns_mhdp_hdmi_read_hpd(struct cdns_mhdp_device *mhdp)
+{
+	u8 status;
+	int ret;
+
+	mutex_lock(&mhdp->mbox_mutex);
+
+	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX,

HDMI_TX_HPD_STATUS, + 0, NULL);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 422

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_HDMI_TX,
+							

HDMI_TX_HPD_STATUS, sizeof(status));

Quoted 20 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +20 -0
+	if (ret)
+		goto err_get_hpd;
+
+	ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
+	if (ret)
+		goto err_get_hpd;
+
+	mutex_unlock(&mhdp->mbox_mutex);
+	return status;
+
+err_get_hpd:
+	mutex_unlock(&mhdp->mbox_mutex);
+	DRM_ERROR("read hpd  failed: %d\n", ret);
+	return ret;
+}
+
+static int hdmi_avi_info_set(struct cdns_mhdp_device *mhdp,
+			     struct drm_display_mode *mode)
+{
+	struct hdmi_avi_infoframe frame;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	int format = mhdp->video_info.color_fmt;
+	struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+	struct drm_display_mode *adj_mode;
+	enum hdmi_quantization_range qr;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise info frame from DRM mode */
+	drm_hdmi_avi_infoframe_from_display_mode(&frame,
+						mhdp->curr_conn, 

mode);

Quoted 158 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +37 -0
+
+	switch (format) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		frame.colorspace = HDMI_COLORSPACE_YUV444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		frame.colorspace = HDMI_COLORSPACE_YUV422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		frame.colorspace = HDMI_COLORSPACE_YUV420;
+		break;
+	default:
+		frame.colorspace = HDMI_COLORSPACE_RGB;
+		break;
+	}
+
+	drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state);
+
+	adj_mode = &mhdp->bridge.encoder->crtc->state->adjusted_mode;
+
+	qr = drm_default_rgb_quant_range(adj_mode);
+
+	drm_hdmi_avi_infoframe_quant_range(&frame, mhdp->curr_conn,
+					   adj_mode, qr);
+
+	ret = hdmi_avi_infoframe_check(&frame);
+	if (WARN_ON(ret))
+		return -EINVAL;
+
+	ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
+		return -1;
+	}
+
+	buf[0] = 0;
+	cdns_mhdp_infoframe_set(mhdp, 0, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_AVI); +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+	return 0;
+}
+
+static void hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp,
+				struct drm_display_mode *mode)
+{
+	struct hdmi_vendor_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	/* Initialise vendor frame from DRM mode */
+	ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mhdp-

curr_conn,
mode); + if (ret < 0) {

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+		DRM_INFO("No vendor infoframe\n");
+		return;
+	}
+
+	ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		DRM_WARN("Unable to pack vendor infoframe: %d\n", ret);
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_VENDOR); +}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +27 -0
+
+static void hdmi_drm_info_set(struct cdns_mhdp_device *mhdp)
+{
+	struct drm_connector_state *conn_state;
+	struct hdmi_drm_infoframe frame;
+	u8 buf[32];
+	int ret;
+
+	conn_state = mhdp->curr_conn->state;
+
+	if (!conn_state->hdr_output_metadata)
+		return;
+
+	ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("couldn't set HDR metadata in infoframe\n");
+		return;
+	}
+
+	ret = hdmi_drm_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+	if (ret < 0) {
+		DRM_DEBUG_KMS("couldn't pack HDR infoframe\n");
+		return;
+	}
+
+	buf[0] = 0;
+	cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_DRM); +}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +39 -0
+
+static int hdmi_phy_colorspace(int color_fmt)
+{
+	int color_space;
+
+	switch (color_fmt) {
+	case DRM_COLOR_FORMAT_YCBCR444:
+		color_space = HDMI_PHY_COLORSPACE_YUV444;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR422:
+		color_space = HDMI_PHY_COLORSPACE_YUV422;
+		break;
+	case DRM_COLOR_FORMAT_YCBCR420:
+		color_space = HDMI_PHY_COLORSPACE_YUV420;
+		break;
+	case DRM_COLOR_FORMAT_RGB444:
+	default:
+		color_space = HDMI_PHY_COLORSPACE_RGB;
+		break;
+	}
+
+	return color_space;
+}
+
+void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp)
+{
+	struct drm_display_mode *mode = &mhdp->mode;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* video mode check */
+	if (mode->clock == 0 || mode->hdisplay == 0 ||  mode->vdisplay == 0)
+		return;
+
+	hdmi_lanes_config(mhdp);
+
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+	phy_cfg.hdmi.bpc = mhdp->video_info.bpc;
+	phy_cfg.hdmi.color_space =

hdmi_phy_colorspace(mhdp->video_info.color_fmt); + ret =
phy_configure(mhdp->phy, &phy_cfg);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +9 -0
+	if (ret) {
+		dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+			__func__, ret);
+		return;
+	}
+
+	hdmi_sink_config(mhdp);
+
+	ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type,

mhdp->hdmi.char_rate); + if (ret < 0) {

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +14 -0
+		DRM_ERROR("%s, ret = %d\n", __func__, ret);
+		return;
+	}
+
+	/* Config GCP */
+	if (mhdp->video_info.bpc == 8)
+		cdns_hdmi_disable_gcp(mhdp);
+	else
+		cdns_hdmi_enable_gcp(mhdp);
+
+	ret = hdmi_avi_info_set(mhdp, mode);
+	if (ret < 0) {
+		DRM_ERROR("%s ret = %d\n", __func__, ret);
+		return;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	}
+
+	/* vendor info frame is enabled only for HDMI1.4 4K mode */
+	hdmi_vendor_info_set(mhdp, mode);
+
+	hdmi_drm_info_set(mhdp);
+
+	ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
+	if (ret < 0) {
+		DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret = %d\n", 

ret);

Quoted 20 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +20 -0
+		return;
+	}
+}
+static enum drm_connector_status
+cdns_hdmi_detect(struct cdns_mhdp_device *mhdp)
+{
+	u8 hpd = 0xf;
+
+	hpd = cdns_mhdp_hdmi_read_hpd(mhdp);
+	if (hpd == 1)
+		return connector_status_connected;
+	else if (hpd == 0)
+		return connector_status_disconnected;
+
+	DRM_INFO("Unknown cable status, hdp=%u\n", hpd);
+	return connector_status_unknown;
+}
+
+static enum drm_connector_status
+cdns_hdmi_bridge_detect(struct drm_bridge *bridge)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+	return cdns_hdmi_detect(mhdp);
+}
+
+static int cdns_hdmi_connector_get_modes(struct drm_connector *connector)
+{
+	struct cdns_mhdp_device *mhdp =
+				container_of(connector, struct 

cdns_mhdp_device, connector);

Quoted 32 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +32 -0
+	int num_modes = 0;
+	struct edid *edid;
+
+	edid = drm_do_get_edid(connector,
+				   cdns_hdmi_get_edid_block, mhdp);
+	if (edid) {
+		dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
+			 edid->header[0], edid->header[1],
+			 edid->header[2], edid->header[3],
+			 edid->header[4], edid->header[5],
+			 edid->header[6], edid->header[7]);
+		drm_connector_update_edid_property(connector, edid);
+		num_modes = drm_add_edid_modes(connector, edid);
+		kfree(edid);
+	}
+
+	if (num_modes == 0)
+		DRM_ERROR("Invalid edid\n");
+	return num_modes;
+}
+
+static bool blob_equal(const struct drm_property_blob *a,
+		       const struct drm_property_blob *b)
+{
+	if (a && b)
+		return a->length == b->length &&
+			!memcmp(a->data, b->data, a->length);
+
+	return !a == !b;
+}
+
+static int cdns_hdmi_connector_atomic_check(struct drm_connector
Quoted 1 line

*connector, + struct

drm_atomic_state *state)

Quoted 20 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +19 -0
+{
+	struct drm_connector_state *new_con_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_connector_state *old_con_state =
+		drm_atomic_get_old_connector_state(state, connector);
+	struct drm_crtc *crtc = new_con_state->crtc;
+	struct drm_crtc_state *new_crtc_state;
+
+	if (!blob_equal(new_con_state->hdr_output_metadata,
+			old_con_state->hdr_output_metadata) ||
+	    new_con_state->colorspace != old_con_state->colorspace) {
+		new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
+		if (IS_ERR(new_crtc_state))
+			return PTR_ERR(new_crtc_state);
+
+		new_crtc_state->mode_changed =
+			!new_con_state->hdr_output_metadata ||
+			!old_con_state->hdr_output_metadata ||
+			new_con_state->colorspace != old_con_state-

colorspace;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	}
+
+	return 0;
+}
+
+static const struct drm_connector_funcs cdns_hdmi_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = 

drm_atomic_helper_connector_duplicate_state,

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs

cdns_hdmi_connector_helper_funcs = { + .get_modes =
cdns_hdmi_connector_get_modes,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+	.atomic_check = cdns_hdmi_connector_atomic_check,
+};
+
+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
+				 enum drm_bridge_attach_flags flags)
+{

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+	struct drm_mode_config *config = &bridge->dev->mode_config;
+	struct drm_encoder *encoder = bridge->encoder;
+	struct drm_connector *connector = &mhdp->connector;
+
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		connector->interlace_allowed = 0;
+		connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+		drm_connector_helper_add(connector, 

&cdns_hdmi_connector_helper_funcs);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 2 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +2 -0
+
+		drm_connector_init(bridge->dev, connector, 

&cdns_hdmi_connector_funcs,

Quoted 42 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+				   DRM_MODE_CONNECTOR_HDMIA);
+
+		drm_object_attach_property(&connector->base,
+					   config-

hdr_output_metadata_property, 0);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+
+		if (!drm_mode_create_hdmi_colorspace_property(connector))
+			drm_object_attach_property(&connector->base,
+						connector-

colorspace_property, 0);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +32 -0
+
+		drm_connector_attach_encoder(connector, encoder);
+	}
+
+	return 0;
+}
+
+static enum drm_mode_status
+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+				const struct drm_display_info *info,
+				const struct drm_display_mode *mode)
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+	enum drm_mode_status mode_status = MODE_OK;
+	union phy_configure_opts phy_cfg;
+	int ret;
+
+	/* We don't support double-clocked and Interlaced modes */
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+			mode->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_BAD;
+
+	/* MAX support pixel clock rate 594MHz */
+	if (mode->clock > 594000)
+		return MODE_CLOCK_HIGH;
+
+	/* 4096x2160 is not supported */
+	if (mode->hdisplay > 3840 || mode->vdisplay > 2160)
+		return MODE_BAD_HVALUE;
+
+	/* Check modes supported by PHY */
+	phy_cfg.hdmi.pixel_clk_rate = mode->clock;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+	if (ret < 0)
+		return MODE_CLOCK_RANGE;
+
+	return mode_status;
+}
+
+bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode 

*adjusted_mode)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+	struct video_info *video = &mhdp->video_info;
+
+	video->bpc = 8;
+	video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+	return true;
+}
+
+static struct edid *cdns_hdmi_bridge_get_edid(struct drm_bridge *bridge,
+					      struct drm_connector 

*connector)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +8 -0
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+	return drm_do_get_edid(connector, cdns_hdmi_get_edid_block, mhdp);
+}
+
+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+					  struct drm_bridge_state 

*old_state)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+	mhdp->curr_conn = NULL;
+
+	mutex_lock(&mhdp->lock);
+	phy_power_off(mhdp->phy);
+	mutex_unlock(&mhdp->lock);
+}
+
+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+					 struct drm_bridge_state 

*old_state)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 826

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+{
+	struct cdns_mhdp_device *mhdp = bridge->driver_private;
+	struct drm_atomic_state *state = old_state->base.state;
+	struct drm_connector *connector;
+	struct video_info *video = &mhdp->video_info;
+	struct drm_crtc_state *crtc_state;
+	struct drm_connector_state *conn_state;
+	const struct drm_display_mode *mode;
+
+	connector = drm_atomic_get_new_connector_for_encoder(state,
+							     

bridge->encoder);

Quoted 33 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +15 -0
+	if (WARN_ON(!connector))
+		return;
+
+	mhdp->curr_conn = connector;
+
+	conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (WARN_ON(!conn_state))
+		return;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return;
+
+	mode = &crtc_state->adjusted_mode;
+	DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay, mode->vdisplay, mode-

clock);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +17 -0
+	memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+	video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC);
+	video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC);
+
+	mutex_lock(&mhdp->lock);
+	cdns_hdmi_mode_set(mhdp);
+	mutex_unlock(&mhdp->lock);
+}
+
+static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+	.attach = cdns_hdmi_bridge_attach,
+	.detect = cdns_hdmi_bridge_detect,
+	.get_edid = cdns_hdmi_bridge_get_edid,
+	.mode_valid = cdns_hdmi_bridge_mode_valid,
+	.mode_fixup = cdns_hdmi_bridge_mode_fixup,
+	.atomic_enable = cdns_hdmi_bridge_atomic_enable,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	.atomic_disable = cdns_hdmi_bridge_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+static void hotplug_work_func(struct work_struct *work)
+{
+	struct cdns_mhdp_device *mhdp = container_of(work,
+					   struct cdns_mhdp_device, 

hotplug_work.work);

Quoted 40 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +40 -0
+	enum drm_connector_status status = cdns_hdmi_detect(mhdp);
+
+	drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+	if (status == connector_status_connected) {
+		DRM_INFO("HDMI Cable Plug In\n");
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	} else if (status == connector_status_disconnected) {
+		/* Cable Disconnedted  */
+		DRM_INFO("HDMI Cable Plug Out\n");
+		enable_irq(mhdp->irq[IRQ_IN]);
+	}
+}
+
+static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data)
+{
+	struct cdns_mhdp_device *mhdp = data;
+
+	disable_irq_nosync(irq);
+
+	mod_delayed_work(system_wq, &mhdp->hotplug_work,
+			msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+	return IRQ_HANDLED;
+}
+
+static int cdns_mhdp_imx_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct cdns_mhdp_device *mhdp;
+	struct platform_device_info pdevinfo;
+	struct resource *res;
+	u32 reg;
+	int ret;
+
+	mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+	if (!mhdp)
+		return -ENOMEM;
+
+	mutex_init(&mhdp->lock);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 915

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+	mutex_init(&mhdp->mbox_mutex);
+
+	INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(mhdp->regs))
+		return PTR_ERR(mhdp->regs);

Please use devm_platform_get_and_ioremap_resource.

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 921

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
+	if (IS_ERR(mhdp->phy)) {
+		dev_err(dev, "no PHY configured\n");
+		return PTR_ERR(mhdp->phy);
+	}

Please use dev_err_probe().

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 927

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+	mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+	if (mhdp->irq[IRQ_IN] < 0) {
+		dev_info(dev, "No plug_in irq number\n");
+		return -EPROBE_DEFER;
+	}

Please use dev_err_probe().

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 933

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+	mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+	if (mhdp->irq[IRQ_OUT] < 0) {
+		dev_info(dev, "No plug_out irq number\n");
+		return -EPROBE_DEFER;
+	}

Please use dev_err_probe().

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 941

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+	/*
+	 * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+	 * Updated each sched "tick" (~2ms)
+	 */
+	ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+				 reg & CDNS_KEEP_ALIVE_MASK, 500,
+				 CDNS_KEEP_ALIVE_TIMEOUT);

This freezes my board TQMa8MQ (arch/arm64/boot/dts/freescale/imx8mq-tqma8mq- mba8mx.dts) completly if this and the PHY driver are compiled in. I have "pd_ignore_unused clk_ignore_unused" passed to kernel command line, so I have no idea what's wrong here.

Best regards,
Alexander

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+	if (ret) {
+		dev_err(mhdp->dev,
+			"device didn't give any life sign: reg %d\n", 

reg);

Quoted 96 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +18 -0
+		return ret;
+	}
+
+	ret = phy_init(mhdp->phy);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to initialize PHY: %d\n", ret);
+		return -ENODEV;
+	}
+
+	/* Enable Hotplug Detect thread */
+	irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+					NULL, cdns_hdmi_irq_thread,
+					IRQF_ONESHOT, dev_name(dev),
+					mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n",
+						mhdp-

irq[IRQ_IN]);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+		return -EINVAL;
+	}
+
+	irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+	ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+					NULL, cdns_hdmi_irq_thread,
+					IRQF_ONESHOT, dev_name(dev),
+					mhdp);
+	if (ret < 0) {
+		dev_err(dev, "can't claim irq %d\n",
+						mhdp-

irq[IRQ_OUT]);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +65 -0
+		return -EINVAL;
+	}
+
+	mhdp->dev = dev;
+
+	if (cdns_mhdp_hdmi_read_hpd(mhdp))
+		enable_irq(mhdp->irq[IRQ_OUT]);
+	else
+		enable_irq(mhdp->irq[IRQ_IN]);
+
+	mhdp->bridge.driver_private = mhdp;
+	mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+	mhdp->bridge.of_node = dev->of_node;
+	mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
+			   DRM_BRIDGE_OP_HPD;
+	mhdp->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+	drm_bridge_add(&mhdp->bridge);
+
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.parent = dev;
+	pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+	dev_set_drvdata(dev, mhdp);
+	mhdp->plat_data = of_device_get_match_data(dev);
+
+	return 0;
+}
+
+static int cdns_mhdp_imx_remove(struct platform_device *pdev)
+{
+	struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
+	int ret = 0;
+
+	drm_bridge_remove(&mhdp->bridge);
+
+	return ret;
+}
+
+static struct cdns_plat_data imx8mq_hdmi_drv_data = {
+	.lane_mapping = 0xe4,
+};
+
+static const struct of_device_id cdns_mhdp_imx_dt_ids[] = {
+	{ .compatible = "cdns,mhdp-imx8mq-hdmi",
+	  .data = &imx8mq_hdmi_drv_data
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, cdns_mhdp_imx_dt_ids);
+
+static struct platform_driver cdns_mhdp_imx_platform_driver = {
+	.probe  = cdns_mhdp_imx_probe,
+	.remove = cdns_mhdp_imx_remove,
+	.driver = {
+		.name = "cdns-mhdp-imx8mq-hdmi",
+		.of_match_table = cdns_mhdp_imx_dt_ids,
+	},
+};
+
+module_platform_driver(cdns_mhdp_imx_platform_driver);
+
+MODULE_AUTHOR("Sandor Yu <[email protected]>");
+MODULE_DESCRIPTION("Cadence HDMI transmitter driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:cdns-hdmi");
author
#11 lore raw

RE: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Thanks for your comments.

Quoted 117 lines

-----Original Message-----
From: Alexander Stein <[email protected]>
Sent: 2022年11月8日 21:17
To: [email protected]; Sandor Yu <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Oliver Brown <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; Sandor Yu <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Caution: EXT Email

Hello,

thanks for working on this and the updated version.

Am Freitag, 4. November 2022, 07:44:56 CET schrieb Sandor Yu:

Quoted 5 lines

Add a new DRM HDMI bridge driver for Candence MHDP used in i.MX8MQ SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the HDMI FW was loaded and activated by SOC ROM

code.

Quoted 6 lines

Bootload binary included HDMI FW was required for the driver.

---
 drivers/gpu/drm/bridge/cadence/Kconfig        |   12 +
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038

+++++++++++++++++

Quoted 29 lines
 2 files changed, 1050 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
(quoted diff) +0 -0

b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644

drivers/gpu/drm/bridge/cadence/Kconfig +12 -0
@@ -26,6 +26,18 @@ config DRM_CDNS_MHDP8546_J721E
        clock and data muxes.
 endif
 
+config DRM_CDNS_HDMI
+     tristate "Cadence HDMI DRM driver"
+     select DRM_KMS_HELPER
+     select DRM_PANEL_BRIDGE
+     select DRM_DISPLAY_HELPER
+     select DRM_CDNS_AUDIO
+     depends on OF
+     help
+       Support Cadence MHDP HDMI driver.
+       Cadence MHDP Controller support one or more protocols,
+       HDMI firmware is required for this driver.
+
 config DRM_CDNS_DP
      tristate "Cadence DP DRM driver"
      select DRM_KMS_HELPER
(quoted diff) +0 -0
Quoted 1 line

b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file mode

100644

Quoted 16 lines

index 000000000000..b392aac015bd

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
@@ -0,0 +1,1038 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Cadence High-Definition Multimedia Interface (HDMI) driver
+ *
+ * Copyright (C) 2019-2022 NXP Semiconductor, Inc.
+ *
+ */
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/hdmi.h>
+#include <linux/irq.h>
+#include <linux/module.h>

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 22

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+#include <linux/mfd/syscon.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-hdmi.h>
+
+#include <drm/bridge/cdns-mhdp-mailbox.h> #include
+<drm/display/drm_hdmi_helper.h> #include
+<drm/display/drm_scdc_helper.h> #include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h> #include <drm/drm_encoder_slave.h>

#include

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+<drm/drm_of.h> #include <drm/drm_probe_helper.h> #include
+<drm/drm_print.h> #include <drm/drm_vblank.h>
+
+#include "cdns-mhdp-common.h"
+
+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp,
+                                     u8 entry_id, u8 packet_len,

u8 *packet, u8 packet_type)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +8 -0
+{
+     u32 *packet32, len32;
+     u32 val, i;
+
+     /* invalidate entry */
+     val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
+     writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+     writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs +

SOURCE_PIF_PKT_ALLOC_WR_EN);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+
+     /* flush fifo 1 */
+     writel(F_FIFO1_FLUSH(1), mhdp->regs +
Quoted 6 lines

SOURCE_PIF_FIFO1_FLUSH);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 47

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+
+     /* write packet into memory */
+     packet32 = (u32 *)packet;

This only works on little-endian machines, no?

Register SOURCE_PIF_DATA_WR require little-endian data, I will use get_unaligned_le32() to replace it in the next version.

Quoted 21 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+     len32 = packet_len / 4;
+     for (i = 0; i < len32; i++)
+             writel(F_DATA_WR(packet32[i]), mhdp->regs +

SOURCE_PIF_DATA_WR);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+
+     /* write entry id */
+     writel(F_WR_ADDR(entry_id), mhdp->regs +

SOURCE_PIF_WR_ADDR);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+
+     /* write request */
+     writel(F_HOST_WR(1), mhdp->regs + SOURCE_PIF_WR_REQ);
+
+     /* update entry */
+     val =  F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
+                     F_PACKET_TYPE(packet_type) |

F_PKT_ALLOC_ADDRESS(entry_id);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+     writel(val, mhdp->regs + SOURCE_PIF_PKT_ALLOC_REG);
+
+     writel(F_PKT_ALLOC_WR_EN(1), mhdp->regs +

SOURCE_PIF_PKT_ALLOC_WR_EN);

Quoted 13 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 75

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+}
+
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+                       u32 block, size_t length) {
+     struct cdns_mhdp_device *mhdp = data;
+     u8 msg[2], reg[5], i;
+     int ret;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     for (i = 0; i < 4; i++) {

What is i? It is not used inside the loop.

EDID data read by HDMI firmware are not guarantee 100% successful. Base on experiments, try 4 times if EDID read failed.

Quoted 208 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+             msg[0] = block / 2;
+             msg[1] = block % 2;
+
+             ret = cdns_mhdp_mailbox_send(mhdp,

MB_MODULE_ID_HDMI_TX,
HDMI_TX_EDID,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+                                       sizeof(msg), msg);
+             if (ret)
+                     continue;
+
+             ret = cdns_mhdp_mailbox_recv_header(mhdp,

MB_MODULE_ID_HDMI_TX,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 80

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+

HDMI_TX_EDID, sizeof(reg) + length);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+             if (ret)
+                     continue;
+
+             ret = cdns_mhdp_mailbox_recv_data(mhdp, reg,

sizeof(reg));

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+             if (ret)
+                     continue;
+
+             ret = cdns_mhdp_mailbox_recv_data(mhdp, edid, length);
+             if (ret)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+                     continue;
+
+             if ((reg[3] << 8 | reg[4]) == length)
+                     break;
+     }
+
+     mutex_unlock(&mhdp->mbox_mutex);
+
+     if (ret)
+             DRM_ERROR("get block[%d] edid failed: %d\n", block,

ret);

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+     return ret;
+}
+
+int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8
+*data) {
+     u8 msg[4], reg[6];

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     int ret;
+
+     msg[0] = 0x54;
+     msg[1] = addr;
+     msg[2] = 0;
+     msg[3] = 1;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX,

HDMI_TX_READ,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+                               sizeof(msg), msg);
+     if (ret)
+             goto err_scdc_read;
+
+     ret = cdns_mhdp_mailbox_recv_header(mhdp,

MB_MODULE_ID_HDMI_TX,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 121

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+                                           HDMI_TX_READ,

sizeof(reg));

Quoted 22 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +22 -0
+     if (ret)
+             goto err_scdc_read;
+
+     ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+     if (ret)
+             goto err_scdc_read;
+
+     *data = reg[5];
+
+err_scdc_read:
+
+     mutex_unlock(&mhdp->mbox_mutex);
+
+     if (ret)
+             DRM_ERROR("scdc read failed: %d\n", ret);
+     return ret;
+}
+
+int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8
+value) {
+     u8 msg[5], reg[5];
+     int ret;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+     msg[0] = 0x54;
+     msg[1] = addr;
+     msg[2] = 0;
+     msg[3] = 1;
+     msg[4] = value;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX,

HDMI_TX_WRITE,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+                               sizeof(msg), msg);
+     if (ret)
+             goto err_scdc_write;
+
+     ret = cdns_mhdp_mailbox_recv_header(mhdp,

MB_MODULE_ID_HDMI_TX,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 159

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+                                           HDMI_TX_WRITE,

sizeof(reg));

Quoted 18 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +18 -0
+     if (ret)
+             goto err_scdc_write;
+
+     ret = cdns_mhdp_mailbox_recv_data(mhdp, reg, sizeof(reg));
+     if (ret)
+             goto err_scdc_write;
+
+     if (reg[0] != 0)
+             ret = -EINVAL;
+
+err_scdc_write:
+
+     mutex_unlock(&mhdp->mbox_mutex);
+
+     if (ret)
+             DRM_ERROR("scdc write failed: %d\n", ret);
+     return ret;
+}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+int cdns_hdmi_ctrl_init(struct cdns_mhdp_device *mhdp,
+                              int protocol, u32 char_rate) {
+     u32 reg0;
+     u32 reg1;
+     u32 val;
+     int ret;
+
+     /* Set PHY to HDMI data */
+     ret = cdns_mhdp_reg_write(mhdp, PHY_DATA_SEL,

F_SOURCE_PHY_MHDP_SEL(1));

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+     if (ret < 0)
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_HPD,
+                                     F_HPD_VALID_WIDTH(4) |

F_HPD_GLITCH_WIDTH(0));

Quoted 31 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +31 -0
+     if (ret < 0)
+             return ret;
+
+     /* open CARS */
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_PHY_CAR, 0xF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_HDTX_CAR, 0xFF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_PKT_CAR, 0xF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_AIF_CAR, 0xF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_CIPHER_CAR, 0xF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_CRYPTO_CAR, 0xF);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, SOURCE_CEC_CAR, 3);
+     if (ret < 0)
+             return ret;
+
+     reg0 = reg1 = 0x7c1f;
+     if (protocol == MODE_HDMI_2_0 && char_rate >= 340000) {
+             reg0 = 0;
+             reg1 = 0xFFFFF;
+     }

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_0, reg0);
+     if (ret < 0)
+             return ret;
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CLOCK_REG_1, reg1);
+     if (ret < 0)
+             return ret;
+
+     /* set hdmi mode and preemble mode data enable */
+     val = F_HDMI_MODE(protocol) | F_HDMI2_PREAMBLE_EN(1) |
+ F_DATA_EN(1)

|

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 234

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+                     F_HDMI2_CTRL_IL_MODE(1) | F_BCH_EN(1) |

F_PIC_3D(0XF);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+
+     return ret;
+}
+
+int cdns_hdmi_mode_config(struct cdns_mhdp_device *mhdp,
+                                           struct

drm_display_mode *mode,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 242

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+                                               struct

video_info *video_info)

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+{
+     int ret;
+     u32 val;
+     u32 vsync_lines = mode->vsync_end - mode->vsync_start;
+     u32 eof_lines = mode->vsync_start - mode->vdisplay;
+     u32 sof_lines = mode->vtotal - mode->vsync_end;
+     u32 hblank = mode->htotal - mode->hdisplay;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     u32 hactive = mode->hdisplay;
+     u32 vblank = mode->vtotal - mode->vdisplay;
+     u32 vactive = mode->vdisplay;
+     u32 hfront = mode->hsync_start - mode->hdisplay;
+     u32 hback = mode->htotal - mode->hsync_end;
+     u32 vfront = eof_lines;
+     u32 hsync = hblank - hfront - hback;
+     u32 vsync = vsync_lines;
+     u32 vback = sof_lines;
+     u32 v_h_polarity = ((mode->flags & DRM_MODE_FLAG_NHSYNC) ?
Quoted 5 lines

0 : 1) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 260

Quoted 1 line
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+                                             ((mode->flags &

DRM_MODE_FLAG_NVSYNC) ? 0 : 2);

Please fix the alignment.

OK.

Quoted 681 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 13 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+
+     ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_H_SIZE, (hactive <<
+ 16) +

hblank); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, SCHEDULER_V_SIZE, (vactive <<
+ 16) +

vblank); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_FRONT_WIDTH,

(vfront

Quoted 1 line

+ <<

16) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines

hfront); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_SYNC_WIDTH,

(vsync

Quoted 1 line

+ <<

16) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines

hsync); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_SIGNAL_BACK_WIDTH,

(vback

Quoted 1 line

+ <<

16) +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines

hback); + if (ret < 0)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+             return ret;
+
+     ret = cdns_mhdp_reg_write(mhdp, HSYNC2VSYNC_POL_CTRL,

v_h_polarity);

Quoted 65 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +65 -0
+     if (ret < 0)
+             return ret;
+
+     /* Reset Data Enable */
+     cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+     val &= ~F_DATA_EN(1);
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+     if (ret < 0)
+             return ret;
+
+     /* Set bpc */
+     val &= ~F_VIF_DATA_WIDTH(3);
+     switch (video_info->bpc) {
+     case 10:
+             val |= F_VIF_DATA_WIDTH(1);
+             break;
+     case 12:
+             val |= F_VIF_DATA_WIDTH(2);
+             break;
+     case 16:
+             val |= F_VIF_DATA_WIDTH(3);
+             break;
+     case 8:
+     default:
+             val |= F_VIF_DATA_WIDTH(0);
+             break;
+     }
+
+     /* select color encoding */
+     val &= ~F_HDMI_ENCODING(3);
+     switch (video_info->color_fmt) {
+     case DRM_COLOR_FORMAT_YCBCR444:
+             val |= F_HDMI_ENCODING(2);
+             break;
+     case DRM_COLOR_FORMAT_YCBCR422:
+             val |= F_HDMI_ENCODING(1);
+             break;
+     case DRM_COLOR_FORMAT_YCBCR420:
+             val |= F_HDMI_ENCODING(3);
+             break;
+     case DRM_COLOR_FORMAT_RGB444:
+     default:
+             val |= F_HDMI_ENCODING(0);
+             break;
+     }
+
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+     if (ret < 0)
+             return ret;
+
+     /* set data enable */
+     val |= F_DATA_EN(1);
+     ret = cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val);
+
+     return ret;
+}
+
+int cdns_hdmi_disable_gcp(struct cdns_mhdp_device *mhdp) {
+     u32 val;
+
+     cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+     val &= ~F_GCP_EN(1);
+
+     return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); }
+

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+int cdns_hdmi_enable_gcp(struct cdns_mhdp_device *mhdp) {
+     u32 val;
+
+     cdns_mhdp_reg_read(mhdp, HDTX_CONTROLLER, &val);
+     val |= F_GCP_EN(1);
+
+     return cdns_mhdp_reg_write(mhdp, HDTX_CONTROLLER, val); }
+
+static void hdmi_sink_config(struct cdns_mhdp_device *mhdp) {
+     struct drm_scdc *scdc =

&mhdp->curr_conn->display_info.hdmi.scdc;

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     u8 buff = 0;
+
+     /* Default work in HDMI1.4 */
+     mhdp->hdmi.hdmi_type = MODE_HDMI_1_4;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+     /* check sink support SCDC or not */
+     if (scdc->supported != true) {
+             DRM_INFO("Sink Not Support SCDC\n");
+             return;
+     }
+
+     if (mhdp->hdmi.char_rate > 340000) {
+             /*
+              * TMDS Character Rate above 340MHz should working in

HDMI2.0

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+              * Enable scrambling and TMDS_Bit_Clock_Ratio
+              */
+             buff = SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 |

SCDC_SCRAMBLING_ENABLE;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+             mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+     } else  if (scdc->scrambling.low_rates) {
+             /*
+              * Enable scrambling and HDMI2.0 when scrambling

capability of sink

Quoted 23 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +22 -0
+              * be indicated in the HF-VSDB LTE_340Mcsc_scramble bit
+              */
+             buff = SCDC_SCRAMBLING_ENABLE;
+             mhdp->hdmi.hdmi_type = MODE_HDMI_2_0;
+     }
+
+     /* TMDS config */
+     cdns_hdmi_scdc_write(mhdp, SCDC_TMDS_CONFIG, buff); }
+
+static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp) {
+     u32 lane_mapping = mhdp->plat_data->lane_mapping;
+     /* Line swapping */
+     cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 |
+lane_mapping); }
+
+int cdns_mhdp_hdmi_read_hpd(struct cdns_mhdp_device *mhdp) {
+     u8 status;
+     int ret;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_HDMI_TX,

HDMI_TX_HPD_STATUS, + 0, NULL);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     if (ret)
+             goto err_get_hpd;
+
+     ret = cdns_mhdp_mailbox_recv_header(mhdp,

MB_MODULE_ID_HDMI_TX,

Quoted 1 line

+

HDMI_TX_HPD_STATUS, sizeof(status));

Quoted 19 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +19 -0
+     if (ret)
+             goto err_get_hpd;
+
+     ret = cdns_mhdp_mailbox_recv_data(mhdp, &status, sizeof(status));
+     if (ret)
+             goto err_get_hpd;
+
+     mutex_unlock(&mhdp->mbox_mutex);
+     return status;
+
+err_get_hpd:
+     mutex_unlock(&mhdp->mbox_mutex);
+     DRM_ERROR("read hpd  failed: %d\n", ret);
+     return ret;
+}
+
+static int hdmi_avi_info_set(struct cdns_mhdp_device *mhdp,
+                          struct drm_display_mode *mode) {
+     struct hdmi_avi_infoframe frame;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     int format = mhdp->video_info.color_fmt;
+     struct drm_connector_state *conn_state = mhdp->curr_conn->state;
+     struct drm_display_mode *adj_mode;
+     enum hdmi_quantization_range qr;
+     u8 buf[32];
+     int ret;
+
+     /* Initialise info frame from DRM mode */
+     drm_hdmi_avi_infoframe_from_display_mode(&frame,
+                                             mhdp->curr_conn,

mode);

Quoted 39 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +37 -0
+
+     switch (format) {
+     case DRM_COLOR_FORMAT_YCBCR444:
+             frame.colorspace = HDMI_COLORSPACE_YUV444;
+             break;
+     case DRM_COLOR_FORMAT_YCBCR422:
+             frame.colorspace = HDMI_COLORSPACE_YUV422;
+             break;
+     case DRM_COLOR_FORMAT_YCBCR420:
+             frame.colorspace = HDMI_COLORSPACE_YUV420;
+             break;
+     default:
+             frame.colorspace = HDMI_COLORSPACE_RGB;
+             break;
+     }
+
+     drm_hdmi_avi_infoframe_colorimetry(&frame, conn_state);
+
+     adj_mode = &mhdp->bridge.encoder->crtc->state->adjusted_mode;
+
+     qr = drm_default_rgb_quant_range(adj_mode);
+
+     drm_hdmi_avi_infoframe_quant_range(&frame, mhdp->curr_conn,
+                                        adj_mode, qr);
+
+     ret = hdmi_avi_infoframe_check(&frame);
+     if (WARN_ON(ret))
+             return -EINVAL;
+
+     ret = hdmi_avi_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+     if (ret < 0) {
+             DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
+             return -1;
+     }
+
+     buf[0] = 0;
+     cdns_mhdp_infoframe_set(mhdp, 0, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_AVI); +

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +1 -0
+     return 0;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+}
+
+static void hdmi_vendor_info_set(struct cdns_mhdp_device *mhdp,
+                             struct drm_display_mode *mode) {
+     struct hdmi_vendor_infoframe frame;
+     u8 buf[32];
+     int ret;
+
+     /* Initialise vendor frame from DRM mode */
+     ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame,

mhdp-

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 9 lines

curr_conn,
mode); + if (ret < 0) {

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+             DRM_INFO("No vendor infoframe\n");
+             return;
+     }
+
+     ret = hdmi_vendor_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+     if (ret < 0) {
+             DRM_WARN("Unable to pack vendor infoframe: %d\n",

ret);

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+             return;
+     }
+
+     buf[0] = 0;
+     cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_VENDOR); +}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+
+static void hdmi_drm_info_set(struct cdns_mhdp_device *mhdp) {
+     struct drm_connector_state *conn_state;
+     struct hdmi_drm_infoframe frame;
+     u8 buf[32];

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     int ret;
+
+     conn_state = mhdp->curr_conn->state;
+
+     if (!conn_state->hdr_output_metadata)
+             return;
+
+     ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, conn_state);
+     if (ret < 0) {
+             DRM_DEBUG_KMS("couldn't set HDR metadata in

infoframe\n");

Quoted 32 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+             return;
+     }
+
+     ret = hdmi_drm_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
+     if (ret < 0) {
+             DRM_DEBUG_KMS("couldn't pack HDR infoframe\n");
+             return;
+     }
+
+     buf[0] = 0;
+     cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf,

HDMI_INFOFRAME_TYPE_DRM); +}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +20 -0
+
+static int hdmi_phy_colorspace(int color_fmt) {
+     int color_space;
+
+     switch (color_fmt) {
+     case DRM_COLOR_FORMAT_YCBCR444:
+             color_space = HDMI_PHY_COLORSPACE_YUV444;
+             break;
+     case DRM_COLOR_FORMAT_YCBCR422:
+             color_space = HDMI_PHY_COLORSPACE_YUV422;
+             break;
+     case DRM_COLOR_FORMAT_YCBCR420:
+             color_space = HDMI_PHY_COLORSPACE_YUV420;
+             break;
+     case DRM_COLOR_FORMAT_RGB444:
+     default:
+             color_space = HDMI_PHY_COLORSPACE_RGB;
+             break;
+     }
+

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     return color_space;
+}
+
+void cdns_hdmi_mode_set(struct cdns_mhdp_device *mhdp) {
+     struct drm_display_mode *mode = &mhdp->mode;
+     union phy_configure_opts phy_cfg;
+     int ret;
+
+     /* video mode check */
+     if (mode->clock == 0 || mode->hdisplay == 0 ||  mode->vdisplay ==

0)

Quoted 33 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +7 -0
+             return;
+
+     hdmi_lanes_config(mhdp);
+
+     phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+     phy_cfg.hdmi.bpc = mhdp->video_info.bpc;
+     phy_cfg.hdmi.color_space =

hdmi_phy_colorspace(mhdp->video_info.color_fmt); + ret =
phy_configure(mhdp->phy, &phy_cfg);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +9 -0
+     if (ret) {
+             dev_err(mhdp->dev, "%s: phy_configure() failed: %d\n",
+                     __func__, ret);
+             return;
+     }
+
+     hdmi_sink_config(mhdp);
+
+     ret = cdns_hdmi_ctrl_init(mhdp, mhdp->hdmi.hdmi_type,

mhdp->hdmi.char_rate); + if (ret < 0) {

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +14 -0
+             DRM_ERROR("%s, ret = %d\n", __func__, ret);
+             return;
+     }
+
+     /* Config GCP */
+     if (mhdp->video_info.bpc == 8)
+             cdns_hdmi_disable_gcp(mhdp);
+     else
+             cdns_hdmi_enable_gcp(mhdp);
+
+     ret = hdmi_avi_info_set(mhdp, mode);
+     if (ret < 0) {
+             DRM_ERROR("%s ret = %d\n", __func__, ret);
+             return;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     }
+
+     /* vendor info frame is enabled only for HDMI1.4 4K mode */
+     hdmi_vendor_info_set(mhdp, mode);
+
+     hdmi_drm_info_set(mhdp);
+
+     ret = cdns_hdmi_mode_config(mhdp, mode, &mhdp->video_info);
+     if (ret < 0) {
+             DRM_ERROR("CDN_API_HDMITX_SetVic_blocking ret

= %d\n",
ret);

Quoted 17 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +17 -0
+             return;
+     }
+}
+static enum drm_connector_status
+cdns_hdmi_detect(struct cdns_mhdp_device *mhdp) {
+     u8 hpd = 0xf;
+
+     hpd = cdns_mhdp_hdmi_read_hpd(mhdp);
+     if (hpd == 1)
+             return connector_status_connected;
+     else if (hpd == 0)
+             return connector_status_disconnected;
+
+     DRM_INFO("Unknown cable status, hdp=%u\n", hpd);
+     return connector_status_unknown; }
+
+static enum drm_connector_status

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+cdns_hdmi_bridge_detect(struct drm_bridge *bridge) {
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+     return cdns_hdmi_detect(mhdp);
+}
+
+static int cdns_hdmi_connector_get_modes(struct drm_connector
+*connector) {
+     struct cdns_mhdp_device *mhdp =
+                             container_of(connector, struct

cdns_mhdp_device, connector);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+     int num_modes = 0;
+     struct edid *edid;
+
+     edid = drm_do_get_edid(connector,
+                                cdns_hdmi_get_edid_block,

mhdp);

Quoted 26 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +26 -0
+     if (edid) {
+             dev_info(mhdp->dev, "%x,%x,%x,%x,%x,%x,%x,%x\n",
+                      edid->header[0], edid->header[1],
+                      edid->header[2], edid->header[3],
+                      edid->header[4], edid->header[5],
+                      edid->header[6], edid->header[7]);
+             drm_connector_update_edid_property(connector, edid);
+             num_modes = drm_add_edid_modes(connector, edid);
+             kfree(edid);
+     }
+
+     if (num_modes == 0)
+             DRM_ERROR("Invalid edid\n");
+     return num_modes;
+}
+
+static bool blob_equal(const struct drm_property_blob *a,
+                    const struct drm_property_blob *b) {
+     if (a && b)
+             return a->length == b->length &&
+                     !memcmp(a->data, b->data, a->length);
+
+     return !a == !b;
+}
+
+static int cdns_hdmi_connector_atomic_check(struct drm_connector
Quoted 1 line

*connector, + struct

drm_atomic_state *state)

Quoted 20 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +19 -0
+{
+     struct drm_connector_state *new_con_state =
+             drm_atomic_get_new_connector_state(state, connector);
+     struct drm_connector_state *old_con_state =
+             drm_atomic_get_old_connector_state(state, connector);
+     struct drm_crtc *crtc = new_con_state->crtc;
+     struct drm_crtc_state *new_crtc_state;
+
+     if (!blob_equal(new_con_state->hdr_output_metadata,
+                     old_con_state->hdr_output_metadata) ||
+         new_con_state->colorspace != old_con_state->colorspace) {
+             new_crtc_state = drm_atomic_get_crtc_state(state, crtc);
+             if (IS_ERR(new_crtc_state))
+                     return PTR_ERR(new_crtc_state);
+
+             new_crtc_state->mode_changed =
+                     !new_con_state->hdr_output_metadata ||
+                     !old_con_state->hdr_output_metadata ||
+                     new_con_state->colorspace != old_con_state-

colorspace;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     }
+
+     return 0;
+}
+
+static const struct drm_connector_funcs cdns_hdmi_connector_funcs = {
+     .fill_modes = drm_helper_probe_single_connector_modes,
+     .destroy = drm_connector_cleanup,
+     .reset = drm_atomic_helper_connector_reset,
+     .atomic_duplicate_state =

drm_atomic_helper_connector_duplicate_state,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 717

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+     .atomic_destroy_state =
+drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs

cdns_hdmi_connector_helper_funcs = { + .get_modes =
cdns_hdmi_connector_get_modes,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     .atomic_check = cdns_hdmi_connector_atomic_check, };
+
+static int cdns_hdmi_bridge_attach(struct drm_bridge *bridge,
+                              enum drm_bridge_attach_flags flags)

{

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+     struct drm_mode_config *config = &bridge->dev->mode_config;
+     struct drm_encoder *encoder = bridge->encoder;
+     struct drm_connector *connector = &mhdp->connector;
+
+     if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+             connector->interlace_allowed = 0;
+             connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+             drm_connector_helper_add(connector,

&cdns_hdmi_connector_helper_funcs);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 2 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +2 -0
+
+             drm_connector_init(bridge->dev, connector,

&cdns_hdmi_connector_funcs,

Quoted 1 line

+

DRM_MODE_CONNECTOR_HDMIA);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+
+             drm_object_attach_property(&connector->base,
+                                        config-

hdr_output_metadata_property, 0);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +2 -0
+
+             if

(!drm_mode_create_hdmi_colorspace_property(connector))

Quoted 1 line

+

drm_object_attach_property(&connector->base,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 13 lines

+ connector-
colorspace_property, 0);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+
+             drm_connector_attach_encoder(connector, encoder);
+     }
+
+     return 0;
+}
+
+static enum drm_mode_status
+cdns_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+                             const struct drm_display_info *info,
+                             const struct drm_display_mode

*mode) {

Quoted 19 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +19 -0
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+     enum drm_mode_status mode_status = MODE_OK;
+     union phy_configure_opts phy_cfg;
+     int ret;
+
+     /* We don't support double-clocked and Interlaced modes */
+     if (mode->flags & DRM_MODE_FLAG_DBLCLK ||
+                     mode->flags & DRM_MODE_FLAG_INTERLACE)
+             return MODE_BAD;
+
+     /* MAX support pixel clock rate 594MHz */
+     if (mode->clock > 594000)
+             return MODE_CLOCK_HIGH;
+
+     /* 4096x2160 is not supported */
+     if (mode->hdisplay > 3840 || mode->vdisplay > 2160)
+             return MODE_BAD_HVALUE;
+
+     /* Check modes supported by PHY */

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+     phy_cfg.hdmi.pixel_clk_rate = mode->clock;
+     ret = phy_validate(mhdp->phy, PHY_MODE_HDMI, 0, &phy_cfg);
+     if (ret < 0)
+             return MODE_CLOCK_RANGE;
+
+     return mode_status;
+}
+
+bool cdns_hdmi_bridge_mode_fixup(struct drm_bridge *bridge,
+                              const struct drm_display_mode

*mode,

Quoted 1 line

+ struct drm_display_mode

*adjusted_mode)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+{
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+     struct video_info *video = &mhdp->video_info;
+
+     video->bpc = 8;
+     video->color_fmt = DRM_COLOR_FORMAT_RGB444;
+
+     return true;
+}
+
+static struct edid *cdns_hdmi_bridge_get_edid(struct drm_bridge *bridge,
+                                           struct

drm_connector
*connector)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +8 -0
+{
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+     return drm_do_get_edid(connector, cdns_hdmi_get_edid_block,
+mhdp); }
+
+static void cdns_hdmi_bridge_atomic_disable(struct drm_bridge *bridge,
+                                       struct drm_bridge_state

*old_state)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +12 -0
+{
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+
+     mhdp->curr_conn = NULL;
+
+     mutex_lock(&mhdp->lock);
+     phy_power_off(mhdp->phy);
+     mutex_unlock(&mhdp->lock);
+}
+
+static void cdns_hdmi_bridge_atomic_enable(struct drm_bridge *bridge,
+                                      struct drm_bridge_state

*old_state)

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 826

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +11 -0
+{
+     struct cdns_mhdp_device *mhdp = bridge->driver_private;
+     struct drm_atomic_state *state = old_state->base.state;
+     struct drm_connector *connector;
+     struct video_info *video = &mhdp->video_info;
+     struct drm_crtc_state *crtc_state;
+     struct drm_connector_state *conn_state;
+     const struct drm_display_mode *mode;
+
+     connector = drm_atomic_get_new_connector_for_encoder(state,
+

bridge->encoder);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+     if (WARN_ON(!connector))
+             return;
+
+     mhdp->curr_conn = connector;
+
+     conn_state = drm_atomic_get_new_connector_state(state,

connector);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     if (WARN_ON(!conn_state))
+             return;
+
+     crtc_state = drm_atomic_get_new_crtc_state(state,

conn_state->crtc);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+     if (WARN_ON(!crtc_state))
+             return;
+
+     mode = &crtc_state->adjusted_mode;
+     DRM_INFO("Mode: %dx%dp%d\n", mode->hdisplay,

mode->vdisplay,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 5 lines

+ mode-
clock);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+     memcpy(&mhdp->mode, mode, sizeof(struct drm_display_mode));
+
+     video->v_sync_polarity = !!(mode->flags &

DRM_MODE_FLAG_NVSYNC);

Quoted 1 line

+ video->h_sync_polarity = !!(mode->flags &

DRM_MODE_FLAG_NHSYNC);

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+
+     mutex_lock(&mhdp->lock);
+     cdns_hdmi_mode_set(mhdp);
+     mutex_unlock(&mhdp->lock);
+}

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+static const struct drm_bridge_funcs cdns_hdmi_bridge_funcs = {
+     .attach = cdns_hdmi_bridge_attach,
+     .detect = cdns_hdmi_bridge_detect,
+     .get_edid = cdns_hdmi_bridge_get_edid,
+     .mode_valid = cdns_hdmi_bridge_mode_valid,
+     .mode_fixup = cdns_hdmi_bridge_mode_fixup,
+     .atomic_enable = cdns_hdmi_bridge_atomic_enable,
+     .atomic_disable = cdns_hdmi_bridge_atomic_disable,
+     .atomic_duplicate_state =

drm_atomic_helper_bridge_duplicate_state,

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+     .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+     .atomic_reset = drm_atomic_helper_bridge_reset, };
+
+static void hotplug_work_func(struct work_struct *work) {
+     struct cdns_mhdp_device *mhdp = container_of(work,
+                                        struct

cdns_mhdp_device,
hotplug_work.work);

Quoted 42 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +42 -0
+     enum drm_connector_status status = cdns_hdmi_detect(mhdp);
+
+     drm_bridge_hpd_notify(&mhdp->bridge, status);
+
+     if (status == connector_status_connected) {
+             DRM_INFO("HDMI Cable Plug In\n");
+             enable_irq(mhdp->irq[IRQ_OUT]);
+     } else if (status == connector_status_disconnected) {
+             /* Cable Disconnedted  */
+             DRM_INFO("HDMI Cable Plug Out\n");
+             enable_irq(mhdp->irq[IRQ_IN]);
+     }
+}
+
+static irqreturn_t cdns_hdmi_irq_thread(int irq, void *data) {
+     struct cdns_mhdp_device *mhdp = data;
+
+     disable_irq_nosync(irq);
+
+     mod_delayed_work(system_wq, &mhdp->hotplug_work,
+                     msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+
+     return IRQ_HANDLED;
+}
+
+static int cdns_mhdp_imx_probe(struct platform_device *pdev) {
+     struct device *dev = &pdev->dev;
+     struct cdns_mhdp_device *mhdp;
+     struct platform_device_info pdevinfo;
+     struct resource *res;
+     u32 reg;
+     int ret;
+
+     mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+     if (!mhdp)
+             return -ENOMEM;
+
+     mutex_init(&mhdp->lock);
+     mutex_init(&mhdp->mbox_mutex);
+
+     INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
Quoted 8 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 915

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+     if (!res)
+             return -ENODEV;
+     mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+     if (IS_ERR(mhdp->regs))
+             return PTR_ERR(mhdp->regs);

Please use devm_platform_get_and_ioremap_resource.

Both HDMI PHY driver and mhdp HDMI driver should access same APB base register offset for mailbox. devm_ioremap_resource could not support such feature.

Quoted 9 lines
Quoted 2 lines

+ mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node,

0);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 921

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     if (IS_ERR(mhdp->phy)) {
+             dev_err(dev, "no PHY configured\n");
+             return PTR_ERR(mhdp->phy);
+     }

Please use dev_err_probe().

OK.

Quoted 8 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 927

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +5 -0
+     mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+     if (mhdp->irq[IRQ_IN] < 0) {
+             dev_info(dev, "No plug_in irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 9 lines
Quoted 2 lines

+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev,

"plug_out");

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c line 933

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+     if (mhdp->irq[IRQ_OUT] < 0) {
+             dev_info(dev, "No plug_out irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 7 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+     /*
+      * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+      * Updated each sched "tick" (~2ms)
+      */
+     ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+                              reg & CDNS_KEEP_ALIVE_MASK,
Quoted 8 lines

500,

Quoted 1 line

+ CDNS_KEEP_ALIVE_TIMEOUT);

This freezes my board TQMa8MQ (arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-
mba8mx.dts) completly if this and the PHY driver are compiled in. I have "pd_ignore_unused clk_ignore_unused" passed to kernel command line, so I have no idea what's wrong here.

Here is the first time in the driver to access hdmi register when driver probe.
For imx8mq hdmi/dp, mdhp hdmi apb clock and core clock are managed by ROM code, they are always on when device bootup. Could you dump the clock tree without "pd_ignore_unused clk_ignore_unused" ?

Quoted 4 lines

Best regards,
Alexander

B.R
Sandor

Quoted 106 lines

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 3 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +3 -0
+     if (ret) {
+             dev_err(mhdp->dev,
+                     "device didn't give any life sign: reg %d\n",

reg);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 13 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +13 -0
+             return ret;
+     }
+
+     ret = phy_init(mhdp->phy);
+     if (ret) {
+             dev_err(mhdp->dev, "Failed to initialize PHY: %d\n", ret);
+             return -ENODEV;
+     }
+
+     /* Enable Hotplug Detect thread */
+     irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+     ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+                                     NULL,

cdns_hdmi_irq_thread,

Quoted 1 line

+ IRQF_ONESHOT,

dev_name(dev),

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+                                     mhdp);
+     if (ret < 0) {
+             dev_err(dev, "can't claim irq %d\n",
+                                             mhdp-

irq[IRQ_IN]);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +6 -0
+             return -EINVAL;
+     }
+
+     irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+     ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+                                     NULL,

cdns_hdmi_irq_thread,

Quoted 1 line

+ IRQF_ONESHOT,

dev_name(dev),

Quoted 9 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+                                     mhdp);
+     if (ret < 0) {
+             dev_err(dev, "can't claim irq %d\n",
+                                             mhdp-

irq[IRQ_OUT]);

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +4 -0
+             return -EINVAL;
+     }
+
+     mhdp->dev = dev;

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +10 -0
+
+     if (cdns_mhdp_hdmi_read_hpd(mhdp))
+             enable_irq(mhdp->irq[IRQ_OUT]);
+     else
+             enable_irq(mhdp->irq[IRQ_IN]);
+
+     mhdp->bridge.driver_private = mhdp;
+     mhdp->bridge.funcs = &cdns_hdmi_bridge_funcs;
+     mhdp->bridge.of_node = dev->of_node;
+     mhdp->bridge.ops = DRM_BRIDGE_OP_DETECT |

DRM_BRIDGE_OP_EDID |

Quoted 49 lines
drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c new file +49 -0
+                        DRM_BRIDGE_OP_HPD;
+     mhdp->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+     drm_bridge_add(&mhdp->bridge);
+
+     memset(&pdevinfo, 0, sizeof(pdevinfo));
+     pdevinfo.parent = dev;
+     pdevinfo.id = PLATFORM_DEVID_AUTO;
+
+     dev_set_drvdata(dev, mhdp);
+     mhdp->plat_data = of_device_get_match_data(dev);
+
+     return 0;
+}
+
+static int cdns_mhdp_imx_remove(struct platform_device *pdev) {
+     struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
+     int ret = 0;
+
+     drm_bridge_remove(&mhdp->bridge);
+
+     return ret;
+}
+
+static struct cdns_plat_data imx8mq_hdmi_drv_data = {
+     .lane_mapping = 0xe4,
+};
+
+static const struct of_device_id cdns_mhdp_imx_dt_ids[] = {
+     { .compatible = "cdns,mhdp-imx8mq-hdmi",
+       .data = &imx8mq_hdmi_drv_data
+     },
+     {},
+};
+MODULE_DEVICE_TABLE(of, cdns_mhdp_imx_dt_ids);
+
+static struct platform_driver cdns_mhdp_imx_platform_driver = {
+     .probe  = cdns_mhdp_imx_probe,
+     .remove = cdns_mhdp_imx_remove,
+     .driver = {
+             .name = "cdns-mhdp-imx8mq-hdmi",
+             .of_match_table = cdns_mhdp_imx_dt_ids,
+     },
+};
+
+module_platform_driver(cdns_mhdp_imx_platform_driver);
+
+MODULE_AUTHOR("Sandor Yu <[email protected]>");
+MODULE_DESCRIPTION("Cadence HDMI transmitter driver");
+MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:cdns-hdmi");
#12 lore raw

RE: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Hi Sandor,

Am Mittwoch, 9. November 2022, 14:26:14 CET schrieb Sandor Yu:

Quoted 15 lines

Thanks for your comments.

Quoted 12 lines

-----Original Message-----
From: Alexander Stein <[email protected]>
Sent: 2022年11月8日 21:17
To: [email protected]; Sandor Yu <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Oliver Brown <[email protected]>; [email protected]; [email protected]; [email protected];

[email protected]; [email protected];

Quoted 49 lines
Quoted 49 lines

[email protected];
[email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; Sandor Yu <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Caution: EXT Email

Hello,

thanks for working on this and the updated version.

Am Freitag, 4. November 2022, 07:44:56 CET schrieb Sandor Yu:

Quoted 7 lines

Add a new DRM HDMI bridge driver for Candence MHDP used in i.MX8MQ SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the HDMI FW was loaded and activated by SOC ROM

code.

Quoted 9 lines

Bootload binary included HDMI FW was required for the driver.

---

 drivers/gpu/drm/bridge/cadence/Kconfig        |   12 +
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038

+++++++++++++++++

Quoted 11 lines
 2 files changed, 1050 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
(quoted diff) +0 -0

b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644

drivers/gpu/drm/bridge/cadence/Kconfig +0 -0

[snip]

Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
drivers/gpu/drm/bridge/cadence/Kconfig +4 -0
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+                       u32 block, size_t length) {
+     struct cdns_mhdp_device *mhdp = data;
+     u8 msg[2], reg[5], i;
Quoted 8 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/Kconfig +5 -0
+     int ret;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     for (i = 0; i < 4; i++) {

What is i? It is not used inside the loop.

Quoted 2 lines

EDID data read by HDMI firmware are not guarantee 100% successful. Base on experiments, try 4 times if EDID read failed.

Mh, 4 times sounds a bit too arbitrary to me. How about using a timeout in ms, like 50ms, for retrying to read the EDID?

[snip]

Quoted 27 lines
Quoted 18 lines
Quoted 18 lines
drivers/gpu/drm/bridge/cadence/Kconfig +18 -0
+static int cdns_mhdp_imx_probe(struct platform_device *pdev) {
+     struct device *dev = &pdev->dev;
+     struct cdns_mhdp_device *mhdp;
+     struct platform_device_info pdevinfo;
+     struct resource *res;
+     u32 reg;
+     int ret;
+
+     mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+     if (!mhdp)
+             return -ENOMEM;
+
+     mutex_init(&mhdp->lock);
+     mutex_init(&mhdp->mbox_mutex);
+
+     INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Quoted 8 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/Kconfig +5 -0
+     if (!res)
+             return -ENODEV;
+     mhdp->regs = devm_ioremap(dev, res->start, resource_size(res));
+     if (IS_ERR(mhdp->regs))
+             return PTR_ERR(mhdp->regs);

Please use devm_platform_get_and_ioremap_resource.

Quoted 2 lines

Both HDMI PHY driver and mhdp HDMI driver should access same APB base register offset for mailbox.

devm_ioremap_resource could not support such

Quoted 1 line

feature.

Oh I see, both remap the same range. To be honest I do not like this. Is there a need to map overlapping ranges in both drivers? How can you avoid race conditions due to simultaneous accesses?

Quoted 57 lines
Quoted 11 lines
Quoted 1 line

+ mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node,

0);

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/Kconfig +4 -0
+     if (IS_ERR(mhdp->phy)) {
+             dev_err(dev, "no PHY configured\n");
+             return PTR_ERR(mhdp->phy);
+     }

Please use dev_err_probe().

OK.

Quoted 10 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/Kconfig +5 -0
+     mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+     if (mhdp->irq[IRQ_IN] < 0) {
+             dev_info(dev, "No plug_in irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 6 lines
Quoted 3 lines

+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev,

"plug_out");

Quoted 7 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/Kconfig +4 -0
+     if (mhdp->irq[IRQ_OUT] < 0) {
+             dev_info(dev, "No plug_out irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 14 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/Kconfig +6 -0
+     /*
+      * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+      * Updated each sched "tick" (~2ms)
+      */
+     ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+                              reg & CDNS_KEEP_ALIVE_MASK,

500,

Quoted 1 line

+ CDNS_KEEP_ALIVE_TIMEOUT);

Quoted 8 lines
Quoted 5 lines

This freezes my board TQMa8MQ (arch/arm64/boot/dts/freescale/imx8mq-tqma8mq-
mba8mx.dts) completly if this and the PHY driver are compiled in. I have "pd_ignore_unused clk_ignore_unused" passed to kernel command line, so I have no idea what's wrong here.

Here is the first time in the driver to access hdmi register when driver probe.

For imx8mq hdmi/dp, mdhp hdmi apb clock and core clock are managed

Quoted 2 lines

by ROM code, they are always on when device bootup. Could you dump the clock tree without "pd_ignore_unused clk_ignore_unused" ?

I noticed too this is the 1st access, so I have no idea what's wrong here. Here is my /sys/kernel/debug/clk/clk_summary from using the regular DT without enabling 'dcss', 'hdmi_phy' and 'mhdp_hdmi':

enable prepare protect
duty hardware
clock count count count rate
accuracy phase cycle enable
-------------------------------------------------------------------------------------------------------
sys2_pll_out 7 7 0 1000000000
0 0 50000 Y

    sys_pll2_out_monitor              0        0        0  1000000000          
0     0  50000         Y
    sys2_pll_1000m                    0        0        0  1000000000          
0     0  50000         Y
    sys2_pll_500m                     1        2        0   500000000          

0 0 50000 Y
audio_ahb 0 1 0 500000000
0 0 50000 N
ipg_audio_root 0 1 0 250000000
0 0 50000 Y
sdma2_clk 0 2 0 250000000
0 0 50000 N

             sai6_ipg_clk             0        0        0   250000000          
0     0  50000         N
             sai5_ipg_clk             0        0        0   250000000          
0     0  50000         N
             sai4_ipg_clk             0        0        0   250000000          
0     0  50000         N
             sai1_ipg_clk             0        0        0   250000000          

0 0 50000 N
nand 0 0 0 500000000
0 0 50000 N
nand_root_clk 0 0 0 500000000
0 0 50000 N
usb_bus 2 2 0 500000000
0 0 50000 Y

          usb2_ctrl_root_clk          1        1        0   500000000          
0     0  50000         Y
          usb1_ctrl_root_clk          1        1        0   500000000          
0     0  50000         Y
    sys2_pll_333m                     1        1        0   333333333          
0     0  50000         Y
       main_axi                       1        1        0   333333333          
0     0  50000         Y
    sys2_pll_250m                     2        2        0   250000000          
0     0  50000         Y
       pcie1_ctrl                     1        1        0   250000000          
0     0  50000         Y
          pcie1_root_clk              1        1        0   250000000          
0     0  50000         Y
       pcie2_ctrl                     1        1        0   250000000          
0     0  50000         Y
          pcie2_root_clk              1        1        0   250000000          
0     0  50000         Y
    sys2_pll_200m                     3        3        0   200000000          
0     0  50000         Y
       ecspi3                         0        0        0   200000000          
0     0  50000         N
          ecspi3_root_clk             0        0        0   200000000          
0     0  50000         N
       ecspi2                         1        1        0   200000000          
0     0  50000         Y
          ecspi2_root_clk             2        2        0   200000000          
0     0  50000         Y
       ecspi1                         1        1        0   200000000          
0     0  50000         Y
          ecspi1_root_clk             2        2        0   200000000          

0 0 50000 Y
gic 1 1 0 200000000
0 0 50000 Y
arm_m4_core 0 0 0 200000000
0 0 50000 N

    sys2_pll_166m                     0        0        0   166666666          
0     0  50000         Y
    sys2_pll_125m                     1        1        0   125000000          
0     0  50000         Y
       enet_ref                       1        1        0   125000000          
0     0  50000         Y
    sys2_pll_100m                     3        3        0   100000000          

0 0 50000 Y
pcie1_phy 1 1 0 100000000
0 0 50000 Y
pcie2_phy 1 1 0 100000000
0 0 50000 Y
enet_timer 1 1 0 100000000
0 0 50000 Y
sys2_pll_50m 1 1 0 50000000
0 0 50000 Y
enet_phy 1 1 0 50000000
0 0 50000 Y
sys1_pll_out 5 5 0 800000000
0 0 50000 Y
sys_pll1_out_monitor 0 0 0 800000000
0 0 50000 Y

    sys1_pll_800m                     2        2        0   800000000          
0     0  50000         Y
       vpu_bus                        0        0        0   800000000          
0     0  50000         N
          vpu_dec_root_clk            0        0        0   800000000          
0     0  50000         N
       arm_a53_div                    0        0        0   800000000          

0 0 50000 N
dram_apb 1 1 0 160000000
0 0 50000 Y
noc 1 1 0 800000000
0 0 50000 Y
disp_rtrm 0 0 0 400000000
0 0 50000 N

          disp_rtrm_root_clk          0        0        0   400000000          
0     0  50000         N
       disp_apb                       0        0        0   133333334          
0     0  50000         N
          disp_apb_root_clk           0        0        0   133333334          
0     0  50000         N
       disp_axi                       0        0        0   800000000          
0     0  50000         N
          disp_axi_root_clk           0        0        0   800000000          
0     0  50000         N
    sys1_pll_400m                     0        0        0   400000000          
0     0  50000         Y
       usdhc2                         0        0        0   400000000          
0     0  50000         N
          usdhc2_root_clk             0        0        0   400000000          
0     0  50000         N
       usdhc1                         0        0        0   400000000          
0     0  50000         N
          usdhc1_root_clk             0        0        0   400000000          
0     0  50000         N
    sys1_pll_266m                     1        1        0   266666666          

0 0 50000 Y
nand_usdhc_bus 0 0 0 266666666
0 0 50000 N
nand_usdhc_rawnand_clk 0 0 0 266666666
0 0 50000 N
enet_axi 1 1 0 266666666
0 0 50000 Y

          enet1_root_clk              2        2        0   266666666          
0     0  50000         Y
    sys1_pll_200m                     0        0        0   200000000          
0     0  50000         Y
    sys1_pll_160m                     0        0        0   160000000          
0     0  50000         Y
    sys1_pll_133m                     1        1        0   133333333          

0 0 50000 Y
ahb 9 4 0 133333333
0 0 50000 Y
ipg_root 8 8 0 66666667
0 0 50000 Y
sdma1_clk 6 1 0 66666667
0 0 50000 Y
tmu_root_clk 1 1 0 66666667
0 0 50000 Y
sai3_ipg_clk 0 0 0 66666667
0 0 50000 N
sai2_ipg_clk 0 0 0 66666667
0 0 50000 N
ocotp_root_clk 0 0 0 66666667
0 0 50000 N
mu_root_clk 0 0 0 66666667
0 0 50000 N
gpio5_root_clk 1 1 0 66666667
0 0 50000 Y
gpio4_root_clk 1 1 0 66666667
0 0 50000 Y
gpio3_root_clk 1 1 0 66666667
0 0 50000 Y
gpio2_root_clk 1 1 0 66666667
0 0 50000 Y
gpio1_root_clk 1 1 0 66666667
0 0 50000 Y

    sys1_pll_100m                     2        2        0   100000000          
0     0  50000         Y
       usb_phy_ref                    2        2        0   100000000          
0     0  50000         Y
          usb2_phy_root_clk           1        1        0   100000000          
0     0  50000         Y
          usb1_phy_root_clk           1        1        0   100000000          

0 0 50000 Y
usb_core_ref 2 2 0 100000000
0 0 50000 Y
qspi 0 0 0 100000000
0 0 50000 N
qspi_root_clk 0 0 0 100000000
0 0 50000 N
dram_alt 0 0 0 100000000
0 0 50000 N
dram_alt_root 0 0 0 25000000
0 0 50000 Y
sys1_pll_80m 2 2 0 80000000
0 0 50000 Y
pcie1_aux 1 1 0 10000000
0 0 50000 Y
pcie2_aux 1 1 0 10000000
0 0 50000 Y
uart2 0 0 0 80000000
0 0 50000 N
uart2_root_clk 0 0 0 80000000
0 0 50000 N
uart1 0 0 0 80000000
0 0 50000 N
uart1_root_clk 0 0 0 80000000
0 0 50000 N
sys1_pll_40m 0 0 0 40000000
0 0 50000 Y
wrclk 0 0 0 40000000
0 0 50000 N
dummy 0 0 0 0
0 0 50000 Y
clk-xtal25 2 2 0 25000000
0 0 50000 Y
DIF3 0 0 0 100000000
0 0 50000 Y
DIF2 1 1 0 100000000
0 0 50000 Y
DIF1 0 0 0 100000000
0 0 50000 Y
DIF0 1 1 0 100000000
0 0 50000 Y
clock 0 0 0 32768
0 0 50000 Y
clk_ext4 0 0 0 133000000
0 0 50000 Y
clk_ext3 0 0 0 133000000
0 0 50000 Y
clk_ext2 0 0 0 133000000
0 0 50000 Y
clk_ext1 0 0 0 133000000
0 0 50000 Y
hdmi_phy_27m 0 0 0 27000000
0 0 50000 Y
osc_27m 0 0 0 27000000
0 0 50000 Y
osc_25m 7 11 0 25000000
0 0 50000 Y
gpt_3m 0 0 0 3125000
0 0 50000 Y
csi2_esc 0 0 0 25000000
0 0 50000 N
csi2_phy_ref 0 0 0 25000000
0 0 50000 N
csi2_core 0 0 0 25000000
0 0 50000 N
csi2_root_clk 0 0 0 25000000
0 0 50000 N
csi1_esc 0 0 0 25000000
0 0 50000 N
csi1_phy_ref 0 0 0 25000000
0 0 50000 N
csi1_core 0 0 0 25000000
0 0 50000 N
csi1_root_clk 0 0 0 25000000
0 0 50000 N
dsi_ahb 0 0 0 25000000
0 0 50000 N
dsi_ipg_div 0 0 0 12500000
0 0 50000 Y
dsi_esc 0 0 0 25000000
0 0 50000 N
dsi_dbi 0 0 0 25000000
0 0 50000 N
dsi_phy_ref 0 0 0 25000000
0 0 50000 N
dsi_core 0 0 0 25000000
0 0 50000 N
clko2 0 0 0 25000000
0 0 50000 N
clko1 0 0 0 25000000
0 0 50000 N
wdog 1 1 0 25000000
0 0 50000 Y
wdog3_root_clk 0 0 0 25000000
0 0 50000 N
wdog2_root_clk 0 0 0 25000000
0 0 50000 N
wdog1_root_clk 1 1 0 25000000
0 0 50000 Y
gpt1 0 0 0 25000000
0 0 50000 N
gpt1_root_clk 0 0 0 25000000
0 0 50000 N
pwm4 0 0 0 25000000
0 0 50000 N
pwm4_root_clk 0 0 0 25000000
0 0 50000 N
pwm3 0 0 0 25000000
0 0 50000 N
pwm3_root_clk 0 0 0 25000000
0 0 50000 N
pwm2 0 0 0 25000000
0 0 50000 N
pwm2_root_clk 0 0 0 25000000
0 0 50000 N
pwm1 0 0 0 25000000
0 0 50000 N
pwm1_root_clk 0 0 0 25000000
0 0 50000 N
uart4 0 0 0 25000000
0 0 50000 N
uart4_root_clk 0 0 0 25000000
0 0 50000 N
uart3 1 1 0 25000000
0 0 50000 Y
uart3_root_clk 4 4 0 25000000
0 0 50000 Y
i2c4 0 0 0 25000000
0 0 50000 N
i2c4_root_clk 0 0 0 25000000
0 0 50000 N
i2c3 0 1 0 25000000
0 0 50000 N
i2c3_root_clk 0 1 0 25000000
0 0 50000 N
i2c2 0 1 0 25000000
0 0 50000 N
i2c2_root_clk 0 1 0 25000000
0 0 50000 N
i2c1 0 1 0 25000000
0 0 50000 N
i2c1_root_clk 0 1 0 25000000
0 0 50000 N
spdif2 0 0 0 25000000
0 0 50000 N
spdif1 0 0 0 25000000
0 0 50000 N
sai6 0 0 0 25000000
0 0 50000 N
sai6_root_clk 0 0 0 25000000
0 0 50000 N
sai5 0 0 0 25000000
0 0 50000 N
sai5_root_clk 0 0 0 25000000
0 0 50000 N
sai4 0 0 0 25000000
0 0 50000 N
sai4_root_clk 0 0 0 25000000
0 0 50000 N
sai2 0 0 0 25000000
0 0 50000 N
sai2_root_clk 0 0 0 25000000
0 0 50000 N
sai1 0 0 0 25000000
0 0 50000 N
sai1_root_clk 0 0 0 25000000
0 0 50000 N
lcdif_pixel 0 0 0 25000000
0 0 50000 N
disp_dc8000 0 0 0 25000000
0 0 50000 N
disp_root_clk 0 0 0 25000000
0 0 50000 N
disp_dtrc 0 0 0 25000000
0 0 50000 N
noc_apb 1 1 0 25000000
0 0 50000 Y
video2_pll1_ref_sel 0 0 0 25000000
0 0 50000 Y
video2_pll_out 0 0 0 25000000
0 0 50000 Y
video_pll2_out_monitor 0 0 0 25000000
0 0 50000 Y
dram_pll1_ref_sel 1 1 0 25000000
0 0 50000 Y
dram_pll_out 2 2 0 800000000
0 0 50000 Y
dram_core_clk 1 1 0 800000000
0 0 50000 Y

          dram_pll_out_monitor        0        0        0   800000000          

0 0 50000 Y
sys3_pll1_ref_sel 1 1 0 25000000
0 0 50000 Y
sys3_pll_out 1 1 0 25000000
0 0 50000 Y

          sys_pll3_out_monitor        0        0        0    25000000          

0 0 50000 Y
video_pll1_ref_sel 0 0 0 25000000
0 0 50000 Y
video_pll1_bypass 0 0 0 25000000
0 0 50000 Y
video_pll1_out_monitor 0 0 0 25000000
0 0 50000 Y
video_pll1_out 0 0 0 25000000
0 0 50000 N
dc_pixel 0 0 0 5000000
0 0 50000 N
video_pll1_ref_div 0 0 0 5000000
0 0 50000 Y
video_pll1 0 0 0 650000000
0 0 50000 Y
audio_pll2_ref_sel 0 0 0 25000000
0 0 50000 Y
audio_pll2_ref_div 0 0 0 5000000
0 0 50000 Y
audio_pll2 0 0 0 722534397
0 0 50000 Y

             audio_pll2_bypass        0        0        0   722534397          
0     0  50000         Y
                audio_pll2_out_monitor       0        0        0   722534397          
0     0  50000         Y
                audio_pll2_out        0        0        0   722534397          

0 0 50000 N
audio_pll1_ref_sel 0 0 0 25000000
0 0 50000 Y
audio_pll1_ref_div 0 0 0 5000000
0 0 50000 Y
audio_pll1 0 0 0 786431998
0 0 50000 Y

             audio_pll1_bypass        0        0        0   786431998          
0     0  50000         Y
                audio_pll1_out_monitor       0        0        0   786431998          
0     0  50000         Y
                audio_pll1_out        0        0        0   786431998          
0     0  50000         N
                   sai3               0        0        0    49152000          
0     0  50000         N
                      sai3_root_clk       0        0        0    49152000          
0     0  50000         N
                         pll          0        0        0   196608000          
0     0  50000         Y
                            codec_clkin       0        0        0   196608000          
0     0  50000         Y
                               nadc       0        0        0   196608000          
0     0  50000         Y
                                  madc       0        0        0   196608000          
0     0  50000         Y
                               ndac       0        0        0   196608000          
0     0  50000         Y
                                  mdac       0        0        0   196608000          

0 0 50000 Y
bdiv 0 0 0
196608000 0 0 50000 Y
vpu_pll_ref_sel 0 1 0 25000000
0 0 50000 Y
vpu_pll_ref_div 0 1 0 5000000
0 0 50000 Y
vpu_pll 0 1 0 600000000
0 0 50000 Y
vpu_pll_bypass 0 1 0 600000000
0 0 50000 Y

                vpu_pll_out_monitor       0        0        0   600000000          
0     0  50000         Y
                vpu_pll_out           0        2        0   600000000          
0     0  50000         N
                   vpu_g2             0        1        0   600000000          
0     0  50000         N
                      vpu_g2_root_clk       0        1        0   600000000          
0     0  50000         N
                   vpu_g1             0        1        0   600000000          
0     0  50000         N
                      vpu_g1_root_clk       0        1        0   600000000          

0 0 50000 N
gpu_pll_ref_sel 0 0 0 25000000
0 0 50000 Y
gpu_pll_ref_div 0 0 0 5000000
0 0 50000 Y
gpu_pll 0 0 0 800000000
0 0 50000 Y
gpu_pll_bypass 0 0 0 800000000
0 0 50000 Y

                gpu_pll_out_monitor       0        0        0   800000000          

0 0 50000 Y
pllout_monitor_sel 0 0 0 800000000
0 0 50000 Y
pllout_monitor_clk2 0 0 0
800000000 0 0 50000 N

                gpu_pll_out           0        0        0   800000000          
0     0  50000         N
                   gpu_ahb            0        0        0   800000000          
0     0  50000         N
                   gpu_axi            0        0        0   800000000          
0     0  50000         N
                   gpu_shader         0        0        0   800000000          
0     0  50000         N
                   gpu_core           0        0        0   800000000          
0     0  50000         N
                      gpu_root_clk       0        0        0   800000000          

0 0 50000 N
arm_pll_ref_sel 1 1 0 25000000
0 0 50000 Y
arm_pll_ref_div 1 1 0 5000000
0 0 50000 Y
arm_pll 1 1 0 800000000
0 0 50000 Y
arm_pll_bypass 1 1 0 800000000
0 0 50000 Y

                arm_pll_out_monitor       0        0        0   800000000          
0     0  50000         Y
                arm_pll_out           1        1        0   800000000          
0     0  50000         Y
                   arm_a53_core       1        1        0   800000000          
0     0  50000         Y
                      arm             1        1        0   800000000          
0     0  50000         Y
                   vpu_core           0        0        0   800000000          

0 0 50000 N
ckil 2 2 0 32768
0 0 50000 Y

Thanks and best regards
Alexander

author
#13 lore raw

RE: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Hi Alexander,

Quoted 106 lines

-----Original Message-----
From: Alexander Stein <[email protected]>
Sent: 2022年11月10日 23:44
To: Sandor Yu <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Oliver Brown <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]; javierm@redhat. com <[email protected]>; [email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; [email protected]; [email protected]; [email protected]
Subject: RE: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Caution: EXT Email

Hi Sandor,

Am Mittwoch, 9. November 2022, 14:26:14 CET schrieb Sandor Yu:

Quoted 15 lines

Thanks for your comments.

Quoted 12 lines

-----Original Message-----
From: Alexander Stein <[email protected]>
Sent: 2022年11月8日 21:17
To: [email protected]; Sandor Yu <[email protected]>
Cc: [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; Oliver Brown <[email protected]>; [email protected]; [email protected]; [email protected];

[email protected]; [email protected];

Quoted 10 lines
Quoted 10 lines

[email protected];
[email protected]; [email protected]; dl-linux-imx <[email protected]>; [email protected]; Sandor Yu <[email protected]>; [email protected]; [email protected]; [email protected]
Subject: [EXT] Re: [v2 06/10] drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ

Caution: EXT Email

Quoted 7 lines
Quoted 7 lines

Hello,

thanks for working on this and the updated version.

Am Freitag, 4. November 2022, 07:44:56 CET schrieb Sandor Yu:

Quoted 1 line

Add a new DRM HDMI bridge driver for Candence MHDP used in

i.MX8MQ

Quoted 32 lines
Quoted 32 lines
Quoted 6 lines

SOC. MHDP IP could support HDMI or DisplayPort standards according embedded Firmware running in the uCPU.

For iMX8MQ SOC, the HDMI FW was loaded and activated by SOC ROM

code.

Quoted 9 lines

Bootload binary included HDMI FW was required for the driver.

---

 drivers/gpu/drm/bridge/cadence/Kconfig        |   12 +
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1038

+++++++++++++++++

Quoted 11 lines
 2 files changed, 1050 insertions(+)  create mode 100644

drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c

(quoted diff) +0 -0

b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644

drivers/gpu/drm/bridge/cadence/Kconfig +0 -0

[snip]

Quoted 13 lines
Quoted 12 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 9 lines
drivers/gpu/drm/bridge/cadence/Kconfig +9 -0
+static int cdns_hdmi_get_edid_block(void *data, u8 *edid,
+                       u32 block, size_t length) {
+     struct cdns_mhdp_device *mhdp = data;
+     u8 msg[2], reg[5], i;
+     int ret;
+
+     mutex_lock(&mhdp->mbox_mutex);
+
+     for (i = 0; i < 4; i++) {

What is i? It is not used inside the loop.

Quoted 6 lines
Quoted 2 lines

EDID data read by HDMI firmware are not guarantee 100% successful. Base on experiments, try 4 times if EDID read failed.

Mh, 4 times sounds a bit too arbitrary to me. How about using a timeout in ms, like 50ms, for retrying to read the EDID?

For EDID read failed case, the mailbox read will timeout, additional timeout in the loop is not necessary.

Quoted 31 lines

[snip]

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/gpu/drm/bridge/cadence/Kconfig +8 -0
+static int cdns_mhdp_imx_probe(struct platform_device *pdev) {
+     struct device *dev = &pdev->dev;
+     struct cdns_mhdp_device *mhdp;
+     struct platform_device_info pdevinfo;
+     struct resource *res;
+     u32 reg;
+     int ret;
+
Quoted 8 lines
Quoted 8 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/Kconfig +8 -0
+     mhdp = devm_kzalloc(dev, sizeof(*mhdp), GFP_KERNEL);
+     if (!mhdp)
+             return -ENOMEM;
+
+     mutex_init(&mhdp->lock);
+     mutex_init(&mhdp->mbox_mutex);
+
+     INIT_DELAYED_WORK(&mhdp->hotplug_work,

hotplug_work_func);

Quoted 5 lines
Quoted 5 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/Kconfig +5 -0
+
+     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+     if (!res)
+             return -ENODEV;
+     mhdp->regs = devm_ioremap(dev, res->start,

resource_size(res));

Quoted 6 lines
Quoted 5 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 2 lines
drivers/gpu/drm/bridge/cadence/Kconfig +2 -0
+     if (IS_ERR(mhdp->regs))
+             return PTR_ERR(mhdp->regs);

Please use devm_platform_get_and_ioremap_resource.

Quoted 9 lines
Quoted 2 lines

Both HDMI PHY driver and mhdp HDMI driver should access same APB base register offset for mailbox.

devm_ioremap_resource could not support such

Quoted 1 line

feature.

Oh I see, both remap the same range. To be honest I do not like this. Is there a need to map overlapping ranges in both drivers? How can you avoid race conditions due to simultaneous accesses?

To separate HDMI controller driver and PHY driver, I have to remap those registers in different drivers. Race conditions could be avoid in HDMI driver when PHY function is called.

Quoted 805 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line

+ mhdp->phy = devm_of_phy_get_by_index(dev,

pdev->dev.of_node,

Quoted 56 lines
Quoted 10 lines

0);

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/Kconfig +4 -0
+     if (IS_ERR(mhdp->phy)) {
+             dev_err(dev, "no PHY configured\n");
+             return PTR_ERR(mhdp->phy);
+     }

Please use dev_err_probe().

OK.

Quoted 10 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/Kconfig +5 -0
+     mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+     if (mhdp->irq[IRQ_IN] < 0) {
+             dev_info(dev, "No plug_in irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 6 lines
Quoted 3 lines

+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev,

"plug_out");

Quoted 7 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 4 lines
drivers/gpu/drm/bridge/cadence/Kconfig +4 -0
+     if (mhdp->irq[IRQ_OUT] < 0) {
+             dev_info(dev, "No plug_out irq number\n");
+             return -EPROBE_DEFER;
+     }

Please use dev_err_probe().

OK.

Quoted 14 lines

drivers/gpu/drm/bridge/cadence/Kconfig

Quoted 8 lines
drivers/gpu/drm/bridge/cadence/Kconfig +6 -0
+     /*
+      * Wait for the KEEP_ALIVE "message" on the first 8 bits.
+      * Updated each sched "tick" (~2ms)
+      */
+     ret = readl_poll_timeout(mhdp->regs + KEEP_ALIVE, reg,
+                              reg & CDNS_KEEP_ALIVE_MASK,

500,

Quoted 1 line

+ CDNS_KEEP_ALIVE_TIMEOUT);

Quoted 8 lines
Quoted 5 lines

This freezes my board TQMa8MQ (arch/arm64/boot/dts/freescale/imx8mq-tqma8mq- mba8mx.dts) completly if this and the PHY driver are compiled in. I have "pd_ignore_unused clk_ignore_unused" passed to kernel command line, so I have no idea what's wrong here.

Here is the first time in the driver to access hdmi register when driver probe.

For imx8mq hdmi/dp, mdhp hdmi apb clock and core clock are managed

Quoted 2 lines

by ROM code, they are always on when device bootup. Could you dump the clock tree without "pd_ignore_unused clk_ignore_unused" ?

I noticed too this is the 1st access, so I have no idea what's wrong here. Here is my /sys/kernel/debug/clk/clk_summary from using the regular DT without enabling 'dcss', 'hdmi_phy' and 'mhdp_hdmi':

enable prepare protect duty
hardware
clock count count count
rate
accuracy phase cycle enable
---------------------------------------------------------------------------------------------
----------
sys2_pll_out 7 7 0
1000000000
0 0 50000 Y
sys_pll2_out_monitor 0 0 0
1000000000
0 0 50000 Y
sys2_pll_1000m 0 0 0
1000000000
0 0 50000 Y
sys2_pll_500m 1 2 0
500000000
0 0 50000 Y
audio_ahb 0 1 0
500000000
0 0 50000 N
ipg_audio_root 0 1 0
250000000
0 0 50000 Y
sdma2_clk 0 2 0
250000000
0 0 50000 N
sai6_ipg_clk 0 0 0
250000000
0 0 50000 N
sai5_ipg_clk 0 0 0
250000000
0 0 50000 N
sai4_ipg_clk 0 0 0
250000000
0 0 50000 N
sai1_ipg_clk 0 0 0
250000000
0 0 50000 N
nand 0 0 0
500000000
0 0 50000 N
nand_root_clk 0 0 0
500000000
0 0 50000 N
usb_bus 2 2 0
500000000
0 0 50000 Y
usb2_ctrl_root_clk 1 1 0
500000000
0 0 50000 Y
usb1_ctrl_root_clk 1 1 0
500000000
0 0 50000 Y
sys2_pll_333m 1 1 0
333333333
0 0 50000 Y
main_axi 1 1 0
333333333
0 0 50000 Y
sys2_pll_250m 2 2 0
250000000
0 0 50000 Y
pcie1_ctrl 1 1 0
250000000
0 0 50000 Y
pcie1_root_clk 1 1 0
250000000
0 0 50000 Y
pcie2_ctrl 1 1 0
250000000
0 0 50000 Y
pcie2_root_clk 1 1 0
250000000
0 0 50000 Y
sys2_pll_200m 3 3 0
200000000
0 0 50000 Y
ecspi3 0 0 0
200000000
0 0 50000 N
ecspi3_root_clk 0 0 0
200000000
0 0 50000 N
ecspi2 1 1 0
200000000
0 0 50000 Y
ecspi2_root_clk 2 2 0
200000000
0 0 50000 Y
ecspi1 1 1 0
200000000
0 0 50000 Y
ecspi1_root_clk 2 2 0
200000000
0 0 50000 Y
gic 1 1 0
200000000
0 0 50000 Y
arm_m4_core 0 0 0
200000000
0 0 50000 N
sys2_pll_166m 0 0 0
166666666
0 0 50000 Y
sys2_pll_125m 1 1 0
125000000
0 0 50000 Y
enet_ref 1 1 0
125000000
0 0 50000 Y
sys2_pll_100m 3 3 0
100000000
0 0 50000 Y
pcie1_phy 1 1 0
100000000
0 0 50000 Y
pcie2_phy 1 1 0
100000000
0 0 50000 Y
enet_timer 1 1 0
100000000
0 0 50000 Y
sys2_pll_50m 1 1 0
50000000
0 0 50000 Y
enet_phy 1 1 0
50000000
0 0 50000 Y
sys1_pll_out 5 5 0
800000000
0 0 50000 Y
sys_pll1_out_monitor 0 0 0
800000000
0 0 50000 Y
sys1_pll_800m 2 2 0
800000000
0 0 50000 Y
vpu_bus 0 0 0
800000000
0 0 50000 N
vpu_dec_root_clk 0 0 0
800000000
0 0 50000 N
arm_a53_div 0 0 0
800000000
0 0 50000 N
dram_apb 1 1 0
160000000
0 0 50000 Y
noc 1 1 0
800000000
0 0 50000 Y
disp_rtrm 0 0 0
400000000
0 0 50000 N
disp_rtrm_root_clk 0 0 0
400000000
0 0 50000 N
disp_apb 0 0 0
133333334
0 0 50000 N
disp_apb_root_clk 0 0 0
133333334
0 0 50000 N
disp_axi 0 0 0
800000000
0 0 50000 N
disp_axi_root_clk 0 0 0
800000000
0 0 50000 N
sys1_pll_400m 0 0 0
400000000
0 0 50000 Y
usdhc2 0 0 0
400000000
0 0 50000 N
usdhc2_root_clk 0 0 0
400000000
0 0 50000 N
usdhc1 0 0 0
400000000
0 0 50000 N
usdhc1_root_clk 0 0 0
400000000
0 0 50000 N
sys1_pll_266m 1 1 0
266666666
0 0 50000 Y
nand_usdhc_bus 0 0 0
266666666
0 0 50000 N
nand_usdhc_rawnand_clk 0 0 0
266666666
0 0 50000 N
enet_axi 1 1 0
266666666
0 0 50000 Y
enet1_root_clk 2 2 0
266666666
0 0 50000 Y
sys1_pll_200m 0 0 0
200000000
0 0 50000 Y
sys1_pll_160m 0 0 0
160000000
0 0 50000 Y
sys1_pll_133m 1 1 0
133333333
0 0 50000 Y
ahb 9 4 0
133333333
0 0 50000 Y
ipg_root 8 8 0
66666667
0 0 50000 Y
sdma1_clk 6 1 0
66666667
0 0 50000 Y
tmu_root_clk 1 1 0
66666667
0 0 50000 Y
sai3_ipg_clk 0 0 0
66666667
0 0 50000 N
sai2_ipg_clk 0 0 0
66666667
0 0 50000 N
ocotp_root_clk 0 0 0
66666667
0 0 50000 N
mu_root_clk 0 0 0
66666667
0 0 50000 N
gpio5_root_clk 1 1 0
66666667
0 0 50000 Y
gpio4_root_clk 1 1 0
66666667
0 0 50000 Y
gpio3_root_clk 1 1 0
66666667
0 0 50000 Y
gpio2_root_clk 1 1 0
66666667
0 0 50000 Y
gpio1_root_clk 1 1 0
66666667
0 0 50000 Y
sys1_pll_100m 2 2 0
100000000
0 0 50000 Y
usb_phy_ref 2 2 0
100000000
0 0 50000 Y
usb2_phy_root_clk 1 1 0
100000000
0 0 50000 Y
usb1_phy_root_clk 1 1 0
100000000
0 0 50000 Y
usb_core_ref 2 2 0
100000000
0 0 50000 Y
qspi 0 0 0
100000000
0 0 50000 N
qspi_root_clk 0 0 0
100000000
0 0 50000 N
dram_alt 0 0 0
100000000
0 0 50000 N
dram_alt_root 0 0 0
25000000
0 0 50000 Y
sys1_pll_80m 2 2 0
80000000
0 0 50000 Y
pcie1_aux 1 1 0
10000000
0 0 50000 Y
pcie2_aux 1 1 0
10000000
0 0 50000 Y
uart2 0 0 0
80000000
0 0 50000 N
uart2_root_clk 0 0 0
80000000
0 0 50000 N
uart1 0 0 0
80000000
0 0 50000 N
uart1_root_clk 0 0 0
80000000
0 0 50000 N
sys1_pll_40m 0 0 0
40000000
0 0 50000 Y
wrclk 0 0 0
40000000
0 0 50000 N
dummy 0 0 0
0
0 0 50000 Y
clk-xtal25 2 2 0
25000000
0 0 50000 Y
DIF3 0 0 0
100000000
0 0 50000 Y
DIF2 1 1 0
100000000
0 0 50000 Y
DIF1 0 0 0
100000000
0 0 50000 Y
DIF0 1 1 0
100000000
0 0 50000 Y
clock 0 0 0
32768
0 0 50000 Y
clk_ext4 0 0 0
133000000
0 0 50000 Y
clk_ext3 0 0 0
133000000
0 0 50000 Y
clk_ext2 0 0 0
133000000
0 0 50000 Y
clk_ext1 0 0 0
133000000
0 0 50000 Y
hdmi_phy_27m 0 0 0
27000000
0 0 50000 Y
osc_27m 0 0 0
27000000
0 0 50000 Y
osc_25m 7 11 0
25000000
0 0 50000 Y
gpt_3m 0 0 0
3125000
0 0 50000 Y
csi2_esc 0 0 0
25000000
0 0 50000 N
csi2_phy_ref 0 0 0
25000000
0 0 50000 N
csi2_core 0 0 0
25000000
0 0 50000 N
csi2_root_clk 0 0 0
25000000
0 0 50000 N
csi1_esc 0 0 0
25000000
0 0 50000 N
csi1_phy_ref 0 0 0
25000000
0 0 50000 N
csi1_core 0 0 0
25000000
0 0 50000 N
csi1_root_clk 0 0 0
25000000
0 0 50000 N
dsi_ahb 0 0 0
25000000
0 0 50000 N
dsi_ipg_div 0 0 0
12500000
0 0 50000 Y
dsi_esc 0 0 0
25000000
0 0 50000 N
dsi_dbi 0 0 0
25000000
0 0 50000 N
dsi_phy_ref 0 0 0
25000000
0 0 50000 N
dsi_core 0 0 0
25000000
0 0 50000 N
clko2 0 0 0
25000000
0 0 50000 N
clko1 0 0 0
25000000
0 0 50000 N
wdog 1 1 0
25000000
0 0 50000 Y
wdog3_root_clk 0 0 0
25000000
0 0 50000 N
wdog2_root_clk 0 0 0
25000000
0 0 50000 N
wdog1_root_clk 1 1 0
25000000
0 0 50000 Y
gpt1 0 0 0
25000000
0 0 50000 N
gpt1_root_clk 0 0 0
25000000
0 0 50000 N
pwm4 0 0 0
25000000
0 0 50000 N
pwm4_root_clk 0 0 0
25000000
0 0 50000 N
pwm3 0 0 0
25000000
0 0 50000 N
pwm3_root_clk 0 0 0
25000000
0 0 50000 N
pwm2 0 0 0
25000000
0 0 50000 N
pwm2_root_clk 0 0 0
25000000
0 0 50000 N
pwm1 0 0 0
25000000
0 0 50000 N
pwm1_root_clk 0 0 0
25000000
0 0 50000 N
uart4 0 0 0
25000000
0 0 50000 N
uart4_root_clk 0 0 0
25000000
0 0 50000 N
uart3 1 1 0
25000000
0 0 50000 Y
uart3_root_clk 4 4 0
25000000
0 0 50000 Y
i2c4 0 0 0
25000000
0 0 50000 N
i2c4_root_clk 0 0 0
25000000
0 0 50000 N
i2c3 0 1 0
25000000
0 0 50000 N
i2c3_root_clk 0 1 0
25000000
0 0 50000 N
i2c2 0 1 0
25000000
0 0 50000 N
i2c2_root_clk 0 1 0
25000000
0 0 50000 N
i2c1 0 1 0
25000000
0 0 50000 N
i2c1_root_clk 0 1 0
25000000
0 0 50000 N
spdif2 0 0 0
25000000
0 0 50000 N
spdif1 0 0 0
25000000
0 0 50000 N
sai6 0 0 0
25000000
0 0 50000 N
sai6_root_clk 0 0 0
25000000
0 0 50000 N
sai5 0 0 0
25000000
0 0 50000 N
sai5_root_clk 0 0 0
25000000
0 0 50000 N
sai4 0 0 0
25000000
0 0 50000 N
sai4_root_clk 0 0 0
25000000
0 0 50000 N
sai2 0 0 0
25000000
0 0 50000 N
sai2_root_clk 0 0 0
25000000
0 0 50000 N
sai1 0 0 0
25000000
0 0 50000 N
sai1_root_clk 0 0 0
25000000
0 0 50000 N
lcdif_pixel 0 0 0
25000000
0 0 50000 N
disp_dc8000 0 0 0
25000000
0 0 50000 N
disp_root_clk 0 0 0
25000000
0 0 50000 N
disp_dtrc 0 0 0
25000000
0 0 50000 N
noc_apb 1 1 0
25000000
0 0 50000 Y
video2_pll1_ref_sel 0 0 0
25000000
0 0 50000 Y
video2_pll_out 0 0 0
25000000
0 0 50000 Y
video_pll2_out_monitor 0 0 0
25000000
0 0 50000 Y
dram_pll1_ref_sel 1 1 0
25000000
0 0 50000 Y
dram_pll_out 2 2 0
800000000
0 0 50000 Y
dram_core_clk 1 1 0
800000000
0 0 50000 Y
dram_pll_out_monitor 0 0 0
800000000
0 0 50000 Y
sys3_pll1_ref_sel 1 1 0
25000000
0 0 50000 Y
sys3_pll_out 1 1 0
25000000
0 0 50000 Y
sys_pll3_out_monitor 0 0 0
25000000
0 0 50000 Y
video_pll1_ref_sel 0 0 0
25000000
0 0 50000 Y
video_pll1_bypass 0 0 0
25000000
0 0 50000 Y
video_pll1_out_monitor 0 0 0
25000000
0 0 50000 Y
video_pll1_out 0 0 0
25000000
0 0 50000 N
dc_pixel 0 0 0
5000000
0 0 50000 N
video_pll1_ref_div 0 0 0
5000000
0 0 50000 Y
video_pll1 0 0 0
650000000
0 0 50000 Y
audio_pll2_ref_sel 0 0 0
25000000
0 0 50000 Y
audio_pll2_ref_div 0 0 0
5000000
0 0 50000 Y
audio_pll2 0 0 0
722534397
0 0 50000 Y
audio_pll2_bypass 0 0 0
722534397
0 0 50000 Y
audio_pll2_out_monitor 0 0 0
722534397
0 0 50000 Y
audio_pll2_out 0 0 0
722534397
0 0 50000 N
audio_pll1_ref_sel 0 0 0
25000000
0 0 50000 Y
audio_pll1_ref_div 0 0 0
5000000
0 0 50000 Y
audio_pll1 0 0 0
786431998
0 0 50000 Y
audio_pll1_bypass 0 0 0
786431998
0 0 50000 Y
audio_pll1_out_monitor 0 0 0
786431998
0 0 50000 Y
audio_pll1_out 0 0 0
786431998
0 0 50000 N
sai3 0 0 0
49152000
0 0 50000 N
sai3_root_clk 0 0 0
49152000
0 0 50000 N
pll 0 0 0
196608000
0 0 50000 Y
codec_clkin 0 0
0 196608000
0 0 50000 Y
nadc 0 0 0
196608000
0 0 50000 Y
madc 0 0
0 196608000
0 0 50000 Y
ndac 0 0 0
196608000
0 0 50000 Y
mdac 0 0
0 196608000
0 0 50000 Y
bdiv 0 0
0
196608000 0 0 50000 Y
vpu_pll_ref_sel 0 1 0
25000000
0 0 50000 Y
vpu_pll_ref_div 0 1 0
5000000
0 0 50000 Y
vpu_pll 0 1 0
600000000
0 0 50000 Y
vpu_pll_bypass 0 1 0
600000000
0 0 50000 Y
vpu_pll_out_monitor 0 0 0
600000000
0 0 50000 Y
vpu_pll_out 0 2 0
600000000
0 0 50000 N
vpu_g2 0 1 0
600000000
0 0 50000 N
vpu_g2_root_clk 0 1 0
600000000
0 0 50000 N
vpu_g1 0 1 0
600000000
0 0 50000 N
vpu_g1_root_clk 0 1 0
600000000
0 0 50000 N
gpu_pll_ref_sel 0 0 0
25000000
0 0 50000 Y
gpu_pll_ref_div 0 0 0
5000000
0 0 50000 Y
gpu_pll 0 0 0
800000000
0 0 50000 Y
gpu_pll_bypass 0 0 0
800000000
0 0 50000 Y
gpu_pll_out_monitor 0 0 0
800000000
0 0 50000 Y
pllout_monitor_sel 0 0 0
800000000
0 0 50000 Y
pllout_monitor_clk2 0 0
0
800000000 0 0 50000 N
gpu_pll_out 0 0 0
800000000
0 0 50000 N
gpu_ahb 0 0 0
800000000
0 0 50000 N
gpu_axi 0 0 0
800000000
0 0 50000 N
gpu_shader 0 0 0
800000000
0 0 50000 N
gpu_core 0 0 0
800000000
0 0 50000 N
gpu_root_clk 0 0 0
800000000
0 0 50000 N
arm_pll_ref_sel 1 1 0
25000000
0 0 50000 Y
arm_pll_ref_div 1 1 0
5000000
0 0 50000 Y
arm_pll 1 1 0
800000000
0 0 50000 Y
arm_pll_bypass 1 1 0
800000000
0 0 50000 Y
arm_pll_out_monitor 0 0 0
800000000
0 0 50000 Y
arm_pll_out 1 1 0
800000000
0 0 50000 Y
arm_a53_core 1 1 0
800000000
0 0 50000 Y
arm 1 1 0

Quoted 9 lines

800000000
0 0 50000 Y
vpu_core 0 0 0
800000000
0 0 50000 N
ckil 2 2 0
32768
0 0 50000 Y

I will try to duplicate the same clocks status as your on imx8mq evk. Any result will let you know in different mail. Thanks
Sandor

Quoted 4 lines

Thanks and best regards
Alexander

author
#14 lore raw

PATCH v2 7/10 dts-bindings: phy: Add Cadence HDP-TX DP PHY bindings

In reply to Sandor Yu

Add bindings for Cadence HDP-TX DisplayPort PHY.

---
 .../bindings/phy/phy-cadence-hdptx-dp.yaml    | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +70 -0
new file mode 100644
index 000000000000..ab6f4e25c425
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/phy-cadence-hdptx-dp.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence HDP(HDMI/DisplayPort) TX PHY for DisplayPort protocol binding
+
+description:
+  This binding describes the Cadence HDP-TX PHY for DispalyPort protocol.
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-dp-phy
+
+  reg:
+    description:
+      Offset of Cadence HDPTX APB configuration registers.
+
+  clocks:
+    items:
+      description:
+        PHY reference clock. Must contain an entry in clock-names.
+
+  clock-names:
+    items:
+      - const: refclk
+
+  "#phy-cells":
+    const: 0
+
+  cdns,num-lanes:
+    description:
+      Number of lanes.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 4
+
+  cdns,max-bit-rate:
+    description:
+      Maximum DisplayPort link bit rate to use, in Mbps
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [2160, 2430, 2700, 3240, 4320, 5400]
+    default: 5400
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: dp_phy@32c00000 {
+        compatible = "cdns,hdptx-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>;
+        clock-names = "refclk";
+        cdns,num-lanes = <4>;
+        cdns,max-bit-rate = <5400>;
+    };
Signature · 1 line
2.34.1
#15 lore raw

Re: [v2 07/10] dts-bindings: phy: Add Cadence HDP-TX DP PHY bindings

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml

Quoted 13 lines · Sandor Yu

Add bindings for Cadence HDP-TX DisplayPort PHY.

---
 .../bindings/phy/phy-cadence-hdptx-dp.yaml    | 70 +++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +0 -0
new file mode 100644
index 000000000000..ab6f4e25c425

Use filename matching compatible, so cdns,hdptx-dp-phy.yaml

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 5

Quoted 6 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +5 -0
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/phy-cadence-hdptx-dp.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"

Drop quotes from both lines.

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 7

Quoted 2 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +2 -0
+
+title: Cadence HDP(HDMI/DisplayPort) TX PHY for DisplayPort protocol binding

Drop binding

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 10

Quoted 3 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +3 -0
+
+description:
+  This binding describes the Cadence HDP-TX PHY for DispalyPort protocol.

Drop "This binding describes"

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 22

Quoted 12 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +12 -0
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-dp-phy
+
+  reg:
+    description:
+      Offset of Cadence HDPTX APB configuration registers.

Same comments as usual.

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 27

Quoted 5 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +5 -0
+
+  clocks:
+    items:
+      description:
+        PHY reference clock. Must contain an entry in clock-names.

Drop "Must contain an entry in clock-names."

Quoted 25 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +25 -0
+
+  clock-names:
+    items:
+      - const: refclk
+
+  "#phy-cells":
+    const: 0
+
+  cdns,num-lanes:
+    description:
+      Number of lanes.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 4
+
+  cdns,max-bit-rate:
+    description:
+      Maximum DisplayPort link bit rate to use, in Mbps
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [2160, 2430, 2700, 3240, 4320, 5400]
+    default: 5400
+
+required:
+  - compatible
+  - reg

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 62

Quoted 10 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +10 -0
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: dp_phy@32c00000 {

phy
(and no underscores in node names)

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml line 70

Quoted 8 lines
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +8 -0
+        compatible = "cdns,hdptx-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>;
+        clock-names = "refclk";
+        cdns,num-lanes = <4>;
+        cdns,max-bit-rate = <5400>;
+    };

Best regards,
Krzysztof

author
#16 lore raw

PATCH v2 8/10 phy: cadence: Add driver for HDP-TX DisplyPort PHY

In reply to Sandor Yu

Add Cadence HDP-TX DisplayPort PHY driver.

Cadence HDP-TX PHY could be put in either DP mode or HDMI mode base on the configuration chosen. DisplayPort PHY mode is configurated in the driver.

---
 drivers/phy/cadence/Kconfig                |   8 +
 drivers/phy/cadence/Makefile               |   1 +
 drivers/phy/cadence/phy-cadence-hdptx-dp.c | 774 +++++++++++++++++++++
 3 files changed, 783 insertions(+)
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-dp.c
drivers/phy/cadence/Kconfig +8 -0
index 1adde2d99ae7..1e1914d3afdc 100644
@@ -46,3 +46,11 @@ config PHY_CADENCE_SALVO
 	  Enable this to support the Cadence SALVO PHY driver,
 	  this PHY is a legacy PHY, and only are used for USB3
 	  and USB2.
+
+config PHY_CADENCE_HDPTX_DP
+	tristate "Cadence HDPTX DP PHY Driver"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	help
+	  Enable this to support the Cadence HDPTX DP PHY driver
drivers/phy/cadence/Makefile +1 -0
index e17f035ddece..fbdb0bc5ff11 100644
@@ -4,3 +4,4 @@ obj-$(CONFIG_PHY_CADENCE_DPHY)	+= cdns-dphy.o
 obj-$(CONFIG_PHY_CADENCE_DPHY_RX)	+= cdns-dphy-rx.o
 obj-$(CONFIG_PHY_CADENCE_SIERRA)	+= phy-cadence-sierra.o
 obj-$(CONFIG_PHY_CADENCE_SALVO)	+= phy-cadence-salvo.o
+obj-$(CONFIG_PHY_CADENCE_HDPTX_DP)	+= phy-cadence-hdptx-dp.o
drivers/phy/cadence/phy-cadence-hdptx-dp.c new file +774 -0

774 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#17 lore raw

PATCH v2 9/10 dts-bindings: phy: Add Cadence HDP-TX HDMI PHY bindings

In reply to Sandor Yu

Add bindings for Cadence HDP-TX HDMI PHY.

---
 .../bindings/phy/phy-cadence-hdptx-hdmi.yaml  | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml new file +54 -0
new file mode 100644
index 000000000000..edd7bf1c8920
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/phy-cadence-hdptx-hdmi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Cadence HDP(HDMI/DisplayPort) TX PHY for HDMI protocol binding
+
+description:
+  This binding describes the Cadence HDP-TX PHY for HDMI protocol.
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-hdmi-phy
+
+  reg:
+    description:
+      Offset of Cadence HDPTX APB configuration registers.
+
+  clocks:
+    items:
+      description:
+        PHY reference clock. Must contain an entry in clock-names.
+
+  clock-names:
+    items:
+      - const: refclk
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/phy/phy.h>
+    hdmi_phy: hdmi_phy@32c00000 {
+      compatible = "cdns,hdptx-hdmi-phy";
+      reg = <0x32c00000 0x100000>;
+      #phy-cells = <0>;
+      clocks = <&hdmi_phy_27m>;
+      clock-names = "refclk";
+    };
Signature · 1 line
2.34.1
#18 lore raw

Re: [v2 09/10] dts-bindings: phy: Add Cadence HDP-TX HDMI PHY bindings

Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml

Quoted 13 lines · Sandor Yu

Add bindings for Cadence HDP-TX HDMI PHY.

---
 .../bindings/phy/phy-cadence-hdptx-hdmi.yaml  | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml
Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml new file +0 -0
new file mode 100644
index 000000000000..edd7bf1c8920

Same comments apply as for other bindings (also phy)

Best regards,
Krzysztof

author
#19 lore raw

PATCH v2 10/10 phy: cadence: Add driver for HDP-TX HDMI PHY

In reply to Sandor Yu

Add Cadence HDP-TX HDMI PHY driver.

Cadence HDP-TX PHY could be put in either DP mode or HDMI mode base on the configuration chosen. HDMI PHY mode is configurated in the driver.

---
 drivers/phy/cadence/Kconfig                  |   8 +
 drivers/phy/cadence/Makefile                 |   1 +
 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c | 948 +++++++++++++++++++
 3 files changed, 957 insertions(+)
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c
drivers/phy/cadence/Kconfig +8 -0
index 1e1914d3afdc..b6eae2d4a52c 100644
@@ -54,3 +54,11 @@ config PHY_CADENCE_HDPTX_DP
 	select GENERIC_PHY
 	help
 	  Enable this to support the Cadence HDPTX DP PHY driver
+
+config PHY_CADENCE_HDPTX_HDMI
+	tristate "Cadence HDPTX HDMI PHY Driver"
+	depends on OF && HAS_IOMEM
+	depends on COMMON_CLK
+	select GENERIC_PHY
+	help
+	  Enable this to support the Cadence HDPTX HDMI PHY driver.
drivers/phy/cadence/Makefile +1 -0
index fbdb0bc5ff11..b5a676c1c54c 100644
@@ -5,3 +5,4 @@ obj-$(CONFIG_PHY_CADENCE_DPHY_RX)	+= cdns-dphy-rx.o
 obj-$(CONFIG_PHY_CADENCE_SIERRA)	+= phy-cadence-sierra.o
 obj-$(CONFIG_PHY_CADENCE_SALVO)	+= phy-cadence-salvo.o
 obj-$(CONFIG_PHY_CADENCE_HDPTX_DP)	+= phy-cadence-hdptx-dp.o
+obj-$(CONFIG_PHY_CADENCE_HDPTX_HDMI) += phy-cadence-hdptx-hdmi.o
drivers/phy/cadence/phy-cadence-hdptx-hdmi.c new file +948 -0

948 lines not on this page · raw message

Signature · 1 line
2.34.1