Skip to contentSkip to conversation

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

PATCH Superseded Sandor Yu 3 participants 16 messages Nov 28, 2022 – Dec 12, 2022

Subsystems (6)

v5 of 20 Superseded Latest is v20 →

lore
Share & tools
lore

Sandor Yu

author
#0 lore raw

v5 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.

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

v4->v5:
- Drop "clk" suffix in clock name.
- Add output port property in the example of hdmi/dp.

v3->v4:
dt-bindings:
- Correct dt-bindings coding style and address review comments.
- Add apb_clk description.
- Add output port for HDMI/DP connector
PHY:
- Alphabetically sorted in Kconfig and Makefile for DP and HDMI PHY
- Remove unused registers define from HDMI and DP PHY drivers.
- More description in phy_hdmi.h.
- Add apb_clk to HDMI and DP phy driver.
HDMI/DP:
- Use get_unaligned_le32() to replace hardcode type conversion in HDMI AVI infoframe data fill function.
- Add mailbox mutex lock in HDMI/DP driver for phy functions to reslove race conditions between HDMI/DP and PHY drivers.
- Add apb_clk to both HDMI and DP driver.
- Rename some function names and add prefix with "cdns_hdmi/cdns_dp".
- Remove bpc 12 and 16 optional that not supported.

v2->v3:
Address comments for dt-bindings files.
- Correct dts-bindings file names
Rename phy-cadence-hdptx-dp.yaml to cdns,mhdp-imx8mq-dp.yaml Rename phy-cadence-hdptx-hdmi.yaml to cdns,mhdp-imx8mq-hdmi.yaml
- Drop redundant words and descriptions.
- Correct hdmi/dp node name.

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.

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

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

 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   |  102 ++
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml |  102 ++
 .../bindings/phy/cdns,hdptx-dp-phy.yaml       |   68 ++
 .../bindings/phy/cdns,hdptx-hdmi-phy.yaml     |   52 +
 drivers/gpu/drm/bridge/cadence/Kconfig        |   25 +
 drivers/gpu/drm/bridge/cadence/Makefile       |    3 +
 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 1071 +++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-hdmi-core.c   | 1018 ++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp-common.h |  400 ++++++
 .../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    |  737 ++++++++++++
 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c  |  891 ++++++++++++++
 include/drm/bridge/cdns-mhdp-mailbox.h        |  240 ++++
 include/linux/phy/phy-hdmi.h                  |   38 +
 include/linux/phy/phy.h                       |    7 +-
 18 files changed, 4773 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/cdns,hdptx-dp-phy.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,hdptx-hdmi-phy.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 v5 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
#2 lore raw

Re: [PATCH v5 01/10] drm: bridge: cadence: convert mailbox functions to macro functions

Hi Sandor,

Am Montag, dem 28.11.2022 um 15:36 +0800 schrieb Sandor Yu:

Quoted 5 lines

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.

This does not look right. If those functions need to be called from other units and implemented in the header, they should simply be static inline functions rather than macros. Those macros obfuscate the code a lot.

However, I don't believe those should be called by other units directly. From what I can see this is mostly used by the PHY drivers, to interact with the mailbox and read/write PHY registers. However, there is no locking between the bridge and the core driver in any form, so they could corrupt the mailbox state. The PHY drivers have mailbox mutexes, but as far as I can see they aren't used and even if they were they would not guard against concurrent access to the mailbox between the bridge and the PHY driver.

I think the right thing to do here would be to have a regmap implementation in the bridge driver, which uses the mailbox functions to implement the register access. Then this regmap could be passed down from the bridge driver to the PHY, which should simply be a child node of the bridge in DT.

Regards,
Lucas

Quoted 488 lines
---
 .../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
new file mode 100644
index 000000000000..0249322a74b0
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cadence MHDP Firmware Access API function by Malibox.
+ *
+ * Copyright (C) 2022 NXP Semiconductor, Inc.
+ *
+ */
+#ifndef CDNS_MHDP_MAILBOX_H
+#define CDNS_MHDP_MAILBOX_H
+
+#include <asm/unaligned.h>
+#include <linux/iopoll.h>
+
+/* mailbox regs offset */
+#define CDNS_MAILBOX_FULL			0x00008
+#define CDNS_MAILBOX_EMPTY			0x0000c
+#define CDNS_MAILBOX_TX_DATA		0x00010
+#define CDNS_MAILBOX_RX_DATA		0x00014
+
+#define MAILBOX_RETRY_US			1000
+#define MAILBOX_TIMEOUT_US			2000000
+
+/* Module ID Code */
+#define MB_MODULE_ID_GENERAL		0x0A
+#define MB_MODULE_ID_DP_TX			0x01
+
+/* General Commands */
+#define GENERAL_REGISTER_WRITE		0x05
+#define GENERAL_REGISTER_READ		0x07
+
+/* DP TX Command */
+#define DPTX_WRITE_FIELD			0x08
+
+/* MHDP Firmware access functions by Mailbox */
+#define cdns_mhdp_mailbox_read(__mhdp) \
+({ \
+	int ret, empty, val; \
+\
+	WARN_ON(!mutex_is_locked(&(__mhdp)->mbox_mutex)); \
+\
+	do {  \
+		ret = readx_poll_timeout(readl, (__mhdp)->regs + CDNS_MAILBOX_EMPTY,  \
+					 empty, !empty, MAILBOX_RETRY_US,  \
+					 MAILBOX_TIMEOUT_US);  \
+		if (ret < 0)  \
+			break;  \
+\
+		val = readl((__mhdp)->regs + CDNS_MAILBOX_RX_DATA) & 0xff; \
+	} while (0);  \
+\
+	(ret < 0) ? ret : val;  \
+})
+
+#define cdns_mhdp_mailbox_write(__mhdp, __val) \
+({ \
+	int ret, full;  \
+\
+	WARN_ON(!mutex_is_locked(&(__mhdp)->mbox_mutex)); \
+\
+	do {  \
+		ret = readx_poll_timeout(readl, (__mhdp)->regs + CDNS_MAILBOX_FULL,  \
+					 full, !full, MAILBOX_RETRY_US,  \
+					 MAILBOX_TIMEOUT_US);  \
+		if (ret < 0)  \
+			break;  \
+\
+		writel((__val), (__mhdp)->regs + CDNS_MAILBOX_TX_DATA); \
+	} while (0);  \
+\
+	ret; \
+})
+
+#define  cdns_mhdp_mailbox_recv_header(__mhdp, __module_id, __opcode, __req_size) \
+({  \
+	u32 mbox_size, i;  \
+	u8 header[4];  \
+	int ret;  \
+\
+	do {  \
+		/* read the header of the message */ \
+		for (i = 0; i < sizeof(header); i++) {  \
+			ret = cdns_mhdp_mailbox_read(__mhdp);  \
+			if (ret < 0)  \
+				break;  \
+\
+			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;  \
+\
+			ret = -EINVAL;  \
+		}  \
+\
+		ret = 0; \
+\
+	} while (0);  \
+\
+	ret;  \
+})
+
+#define cdns_mhdp_mailbox_recv_data(mhdp, buff, buff_size)  \
+({  \
+	u32 i;  \
+	int ret;  \
+\
+	do {  \
+		for (i = 0; i < buff_size; i++) {  \
+			ret = cdns_mhdp_mailbox_read(mhdp);  \
+			if (ret < 0)  \
+				break;  \
+\
+			((u8 *)buff)[i] = ret;  \
+		}  \
+\
+		ret = 0;  \
+\
+	} while (0);  \
+\
+	ret; \
+})
+
+#define cdns_mhdp_mailbox_send(mhdp, module_id, opcode, size, message)  \
+({  \
+	u8 header[4];  \
+	int ret, i;  \
+\
+	header[0] = opcode;  \
+	header[1] = module_id;  \
+	put_unaligned_be16(size, header + 2);  \
+\
+	do {  \
+		for (i = 0; i < sizeof(header); i++) {  \
+			ret = cdns_mhdp_mailbox_write(mhdp, header[i]);  \
+			if (ret < 0)  \
+				break;  \
+		}  \
+\
+		for (i = 0; i < size; i++) {  \
+			ret = cdns_mhdp_mailbox_write(mhdp, ((u8 *)message)[i]);  \
+			if (ret < 0)  \
+				break;;  \
+		}  \
+		ret = 0;  \
+	} while (0);  \
+\
+	ret;  \
+})
+
+#define cdns_mhdp_reg_read(mhdp, addr, value)  \
+({  \
+	u8 msg[4], resp[8];  \
+	int ret;  \
+\
+	put_unaligned_be32(addr, msg);  \
+\
+	mutex_lock(&mhdp->mbox_mutex);  \
+\
+	do {  \
+		ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,  \
+					     GENERAL_REGISTER_READ,  \
+					     sizeof(msg), msg);  \
+		if (ret < 0)  \
+			break;  \
+\
+		ret = cdns_mhdp_mailbox_recv_header(mhdp, MB_MODULE_ID_GENERAL,  \
+						    GENERAL_REGISTER_READ,  \
+						    sizeof(resp));  \
+		if (ret < 0)  \
+			break;  \
+\
+		ret = cdns_mhdp_mailbox_recv_data(mhdp, resp, sizeof(resp));  \
+		if (ret < 0)  \
+			break;  \
+\
+		/* Returned address value should be the same as requested */  \
+		if (memcmp(msg, resp, sizeof(msg))) {  \
+			ret = -EINVAL;  \
+			break;  \
+		}  \
+\
+		*((u32 *)value) = get_unaligned_be32(resp + 4);  \
+			ret = 0;  \
+	} while (0);  \
+\
+	mutex_unlock(&mhdp->mbox_mutex);  \
+	if (ret < 0) {  \
+		dev_err(mhdp->dev, "Failed to read register\n");  \
+		*((u32 *)value) = 0;  \
+	}  \
+\
+	ret;  \
+})
+
+#define cdns_mhdp_reg_write(mhdp, addr, val)  \
+({  \
+	u8 msg[8];  \
+	int ret;  \
+\
+	put_unaligned_be32(addr, msg);  \
+	put_unaligned_be32(val, msg + 4);  \
+\
+	mutex_lock(&mhdp->mbox_mutex);  \
+\
+	ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,  \
+				      GENERAL_REGISTER_WRITE, sizeof(msg), msg);  \
+\
+	mutex_unlock(&mhdp->mbox_mutex);  \
+\
+	ret;  \
+})
+
+#define cdns_mhdp_reg_write_bit(mhdp, addr, start_bit, bits_no, 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);  \
+\
+	ret; \
+})
+
+#endif
author
#3 lore raw

RE: [EXT] Re: [PATCH v5 01/10] drm: bridge: cadence: convert mailbox functions to macro functions

Hi Lucas,

Thanks your comments,

Quoted 32 lines

-----Original Message-----
From: Lucas Stach <[email protected]>
Sent: 2022年12月9日 19:30
To: Sandor Yu <[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]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]; [email protected]
Cc: Oliver Brown <[email protected]>; dl-linux-imx <[email protected]>; [email protected]
Subject: [EXT] Re: [PATCH v5 01/10] drm: bridge: cadence: convert mailbox functions to macro functions

Caution: EXT Email

Hi Sandor,

Am Montag, dem 28.11.2022 um 15:36 +0800 schrieb Sandor Yu:

Quoted 5 lines

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.

This does not look right. If those functions need to be called from other units and implemented in the header, they should simply be static inline functions rather than macros. Those macros obfuscate the code a lot.

Quoted 7 lines

However, I don't believe those should be called by other units directly. From what I can see this is mostly used by the PHY drivers, to interact with the mailbox and read/write PHY registers. However, there is no locking between the bridge and the core driver in any form, so they could corrupt the mailbox state. The PHY drivers have mailbox mutexes, but as far as I can see they aren't used and even if they were they would not guard against concurrent access to the mailbox between the bridge and the PHY driver.

Both PHY and bridge have its owner mutex to lock mailbox read/write.
In bridge driver, this mutex also lock for PHY API function access to avoid PHY and bridge driver race condition.

Quoted 6 lines

I think the right thing to do here would be to have a regmap implementation in the bridge driver, which uses the mailbox functions to implement the register access. Then this regmap could be passed down from the bridge driver to the PHY, which should simply be a child node of the bridge in DT.

I'm not sure got your point " regmap implementation in the bridge driver". Those mailbox functions also should be reused by mhdp8546. Could you please explain detail or provide a sample?

Regards,
Sandor

Quoted 509 lines

Regards,
Lucas

Quoted 5 lines
---
 .../drm/bridge/cadence/cdns-mhdp8546-core.c   | 197 +-------------
 .../drm/bridge/cadence/cdns-mhdp8546-core.h   |   1 -
 include/drm/bridge/cdns-mhdp-mailbox.h        | 240

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

Quoted 18 lines
 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 +1 -0
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"

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

Quoted 6 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -6
-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,

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -9
-                              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) -{

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

Quoted 5 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -5
-     int ret, full;
-
-     WARN_ON(!mutex_is_locked(&mhdp->mbox_mutex));
-
-     ret = readx_poll_timeout(readl, mhdp->regs +

CDNS_MAILBOX_FULL,

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

Quoted 11 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -11
-                              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,

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -12
-                                      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;

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

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -10
-
-             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

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

Quoted 13 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -13
-              * 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,

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -7
-                                    u8 *buff, u16 buff_size)
-{
-     u32 i;
-     int ret;
-
-     for (i = 0; i < buff_size; i++) {
-             ret = cdns_mhdp_mailbox_read(mhdp);

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

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -10
-             if (ret < 0)
-                     return ret;
-
-             buff[i] = ret;
-     }
-
-     return 0;
-}
-
-static int cdns_mhdp_mailbox_send(struct cdns_mhdp_device *mhdp, u8

module_id,

Quoted 31 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -26
-                               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) -{

drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -4
-     u8 msg[4], resp[8];
-     int ret;
-
-     put_unaligned_be32(addr, msg);

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

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -10
-
-     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,

Quoted 1 line

-

GENERAL_REGISTER_READ,

Quoted 29 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -28
-                                         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) -{

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

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -10
-     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);

Quoted 12 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -12
-
-     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;

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

Quoted 10 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -10
-
-     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);

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

Quoted 9 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +0 -6
-
-     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

Quoted 15 lines

@@ 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);
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +1 -1
-     u32 resp;
+     u32 resp = 0;
 
      dev_dbg(mhdp->dev, "%s\n", __func__);
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +0 -0
index bedddd510d17..10c878bf0e63 100644

drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h struct phy; · line 217

Quoted 7 lines
drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.h +0 -1
@@ -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"

Quoted 37 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +30 -0
new file mode 100644
index 000000000000..0249322a74b0
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Cadence MHDP Firmware Access API function by Malibox.
+ *
+ * Copyright (C) 2022 NXP Semiconductor, Inc.
+ *
+ */
+#ifndef CDNS_MHDP_MAILBOX_H
+#define CDNS_MHDP_MAILBOX_H
+
+#include <asm/unaligned.h>
+#include <linux/iopoll.h>
+
+/* mailbox regs offset */
+#define CDNS_MAILBOX_FULL                    0x00008
+#define CDNS_MAILBOX_EMPTY                   0x0000c
+#define CDNS_MAILBOX_TX_DATA         0x00010
+#define CDNS_MAILBOX_RX_DATA         0x00014
+
+#define MAILBOX_RETRY_US                     1000
+#define MAILBOX_TIMEOUT_US                   2000000
+
+/* Module ID Code */
+#define MB_MODULE_ID_GENERAL         0x0A
+#define MB_MODULE_ID_DP_TX                   0x01
+
+/* General Commands */
+#define GENERAL_REGISTER_WRITE               0x05
+#define GENERAL_REGISTER_READ                0x07
+

include/drm/bridge/cdns-mhdp-mailbox.h line 40

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+/* DP TX Command */
+#define DPTX_WRITE_FIELD                     0x08
+
+/* MHDP Firmware access functions by Mailbox */ #define
+cdns_mhdp_mailbox_read(__mhdp) \ ({ \
+     int ret, empty, val; \
+\
+     WARN_ON(!mutex_is_locked(&(__mhdp)->mbox_mutex)); \ \
+     do {  \
+             ret = readx_poll_timeout(readl, (__mhdp)->regs +

CDNS_MAILBOX_EMPTY, \

include/drm/bridge/cdns-mhdp-mailbox.h line 41

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                                      empty, !empty,

MAILBOX_RETRY_US, \

include/drm/bridge/cdns-mhdp-mailbox.h line 42

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                                      MAILBOX_TIMEOUT_US);

\

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 4 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +4 -0
+             if (ret < 0)  \
+                     break;  \
+\
+             val = readl((__mhdp)->regs + CDNS_MAILBOX_RX_DATA)

& 0xff; \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 11 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +11 -0
+     } while (0);  \
+\
+     (ret < 0) ? ret : val;  \
+})
+
+#define cdns_mhdp_mailbox_write(__mhdp, __val) \ ({ \
+     int ret, full;  \
+\
+     WARN_ON(!mutex_is_locked(&(__mhdp)->mbox_mutex)); \ \
+     do {  \
+             ret = readx_poll_timeout(readl, (__mhdp)->regs +

CDNS_MAILBOX_FULL, \

include/drm/bridge/cdns-mhdp-mailbox.h line 58

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                                      full, !full,

MAILBOX_RETRY_US, \

include/drm/bridge/cdns-mhdp-mailbox.h line 59

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                                      MAILBOX_TIMEOUT_US);

\

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 4 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +4 -0
+             if (ret < 0)  \
+                     break;  \
+\
+             writel((__val), (__mhdp)->regs +

CDNS_MAILBOX_TX_DATA); \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 6 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +6 -0
+     } while (0);  \
+\
+     ret; \
+})
+
+#define  cdns_mhdp_mailbox_recv_header(__mhdp, __module_id,

__opcode,

Quoted 6 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +6 -0
+__req_size) \ ({  \
+     u32 mbox_size, i;  \
+     u8 header[4];  \
+     int ret;  \
+\
+     do {  \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+             /* read the header of the message */ \
+             for (i = 0; i < sizeof(header); i++) {  \
+                     ret = cdns_mhdp_mailbox_read(__mhdp);  \
+                     if (ret < 0)  \
+                             break;  \ \
+                     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

include/drm/bridge/cdns-mhdp-mailbox.h line 86

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                      * clear the mailbox by reading its contents. */

\

include/drm/bridge/cdns-mhdp-mailbox.h line 88

Quoted 2 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +2 -0
+                     for (i = 0; i < mbox_size; i++)   \
+                             if (cdns_mhdp_mailbox_read(__mhdp)

< 0) \

Quoted 31 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +31 -0
+                                     break;  \ \
+                     ret = -EINVAL;  \
+             }  \
+\
+             ret = 0; \
+\
+     } while (0);  \
+\
+     ret;  \
+})
+
+#define cdns_mhdp_mailbox_recv_data(mhdp, buff, buff_size)  \ ({  \
+     u32 i;  \
+     int ret;  \
+\
+     do {  \
+             for (i = 0; i < buff_size; i++) {  \
+                     ret = cdns_mhdp_mailbox_read(mhdp);  \
+                     if (ret < 0)  \
+                             break;  \ \
+                     ((u8 *)buff)[i] = ret;  \
+             }  \
+\
+             ret = 0;  \
+\
+     } while (0);  \
+\
+     ret; \
+})
+
+#define cdns_mhdp_mailbox_send(mhdp, module_id, opcode, size,

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+message)  \ ({  \
+     u8 header[4];  \
+     int ret, i;  \
+\
+     header[0] = opcode;  \
+     header[1] = module_id;  \
+     put_unaligned_be16(size, header + 2);  \ \
+     do {  \
+             for (i = 0; i < sizeof(header); i++) {  \
+                     ret = cdns_mhdp_mailbox_write(mhdp,

header[i]); \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 6 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +6 -0
+                     if (ret < 0)  \
+                             break;  \
+             }  \
+\
+             for (i = 0; i < size; i++) {  \
+                     ret = cdns_mhdp_mailbox_write(mhdp, ((u8

*)message)[i]); \

Quoted 7 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +7 -0
+                     if (ret < 0)  \
+                             break;;  \
+             }  \
+             ret = 0;  \
+     } while (0);  \
+\
+     ret;  \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+})
+
+#define cdns_mhdp_reg_read(mhdp, addr, value)  \ ({  \
+     u8 msg[4], resp[8];  \
+     int ret;  \
+\
+     put_unaligned_be32(addr, msg);  \ \
+     mutex_lock(&mhdp->mbox_mutex);  \ \
+     do {  \
+             ret = cdns_mhdp_mailbox_send(mhdp,

MB_MODULE_ID_GENERAL, \

include/drm/bridge/cdns-mhdp-mailbox.h line 153

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+

GENERAL_REGISTER_READ, \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 5 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +5 -0
+                                          sizeof(msg), msg);  \
+             if (ret < 0)  \
+                     break;  \
+\
+             ret = cdns_mhdp_mailbox_recv_header(mhdp,

MB_MODULE_ID_GENERAL, \

include/drm/bridge/cdns-mhdp-mailbox.h line 159

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+

GENERAL_REGISTER_READ, \

include/drm/bridge/cdns-mhdp-mailbox.h line 160

Quoted 1 line
include/drm/bridge/cdns-mhdp-mailbox.h new file +1 -0
+                                                 sizeof(resp));

\

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 4 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +4 -0
+             if (ret < 0)  \
+                     break;  \
+\
+             ret = cdns_mhdp_mailbox_recv_data(mhdp, resp,

sizeof(resp)); \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 4 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +4 -0
+             if (ret < 0)  \
+                     break;  \
+\
+             /* Returned address value should be the same as

requested */ \

Quoted 16 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +16 -0
+             if (memcmp(msg, resp, sizeof(msg))) {  \
+                     ret = -EINVAL;  \
+                     break;  \
+             }  \
+\
+             *((u32 *)value) = get_unaligned_be32(resp + 4);  \
+                     ret = 0;  \
+     } while (0);  \
+\
+     mutex_unlock(&mhdp->mbox_mutex);  \
+     if (ret < 0) {  \
+             dev_err(mhdp->dev, "Failed to read register\n");  \
+             *((u32 *)value) = 0;  \
+     }  \
+\
+     ret;  \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+})
+
+#define cdns_mhdp_reg_write(mhdp, addr, val)  \ ({  \
+     u8 msg[8];  \
+     int ret;  \
+\
+     put_unaligned_be32(addr, msg);  \
+     put_unaligned_be32(val, msg + 4);  \ \
+     mutex_lock(&mhdp->mbox_mutex);  \ \
+     ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_GENERAL,

\

Quoted 8 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +8 -0
+                                   GENERAL_REGISTER_WRITE,
+sizeof(msg), msg);  \ \
+     mutex_unlock(&mhdp->mbox_mutex);  \ \
+     ret;  \
+})
+
+#define cdns_mhdp_reg_write_bit(mhdp, addr, start_bit, bits_no, val)
+\ ({  \

include/drm/bridge/cdns-mhdp-mailbox.h

Quoted 10 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +10 -0
+     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),

Quoted 6 lines
include/drm/bridge/cdns-mhdp-mailbox.h new file +6 -0
+field);  \ \
+     mutex_unlock(&mhdp->mbox_mutex);  \ \
+     ret; \
+})
+
+#endif
author
#4 lore raw

PATCH v5 2/10 dt-bindings: display: bridge: Add MHDP DP for i.MX8MQ

In reply to Sandor Yu

Add bindings for i.MX8MQ MHDP DisplayPort.

---
 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   | 102 ++++++++++++++++++
 1 file changed, 102 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 +102 -0
new file mode 100644
index 000000000000..21cf87c79766
@@ -0,0 +1,102 @@
+# 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:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP DP APB clock.
+
+  phys:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to DP connector.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mhdp_dp: dp-bridge@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";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&dp_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&dp_con>;
+                };
+            };
+        };
+    };
Signature · 1 line
2.34.1
maintainer
#5 lore raw

Re: [PATCH v5 02/10] dt-bindings: display: bridge: Add MHDP DP for i.MX8MQ

Quoted 22 lines · Sandor Yu

Add bindings for i.MX8MQ MHDP DisplayPort.

---
 .../display/bridge/cdns,mhdp-imx8mq-dp.yaml   | 102 ++++++++++++++++++
 1 file changed, 102 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 +8 -0
new file mode 100644
index 000000000000..21cf87c79766
@@ -0,0 +1,102 @@
+# 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
+

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

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +10 -0
+maintainers:
+  - Sandor Yu <[email protected]>
+
+description:
+  The Cadence MHDP Displayport TX interface.
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-dp

nxp,ixm8mq-mhdp

Cadence is not the vendor for imx8mq. It is doubtful that every vendor using this IP block will be the same because that rarely/never happens.

And I assume the 'dp in 'mhdp' stands for DisplayPort, so we don't need it twice.

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

Quoted 7 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +7 -0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP DP APB clock.

Seems like there would be more than just a bus clock unless all the function clocks come from the display controller or phy.

Quoted 81 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +77 -0
+
+  phys:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to DP connector.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    mhdp_dp: dp-bridge@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";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&dp_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&dp_con>;
+                };
+            };
+        };
+    };
Signature · 1 line
2.34.1
author
#6 lore raw

PATCH v5 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 | 1071 +++++++++++++++++
 .../gpu/drm/bridge/cadence/cdns-mhdp-common.h |  400 ++++++
 4 files changed, 1487 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 +1071 -0

1,071 lines not on this page · raw message

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

400 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#7 lore raw

PATCH v5 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 | 38 ++++++++++++++++++++++++++++++++++++
 include/linux/phy/phy.h      |  7 ++++++-
 2 files changed, 44 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/phy/phy-hdmi.h
include/linux/phy/phy-hdmi.h new file +38 -0
new file mode 100644
index 000000000000..5765aa5bc175
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2022 NXP
+ */
+
+#ifndef __PHY_HDMI_H_
+#define __PHY_HDMI_H_
+
+/**
+ * Pixel Encoding as HDMI Specification
+ * RGB, YUV422, YUV444:HDMI Specification 1.4a Section 6.5
+ * YUV420: HDMI Specification 2.a Section 7.1
+ */
+enum hdmi_phy_colorspace {
+	HDMI_PHY_COLORSPACE_RGB,        /* RGB 4:4:4 */
+	HDMI_PHY_COLORSPACE_YUV422,     /* YCbCr 4:2:2 */
+	HDMI_PHY_COLORSPACE_YUV444,     /* YCbCr 4:4:4 */
+	HDMI_PHY_COLORSPACE_YUV420,     /* YCbCr 4:2:0 */
+	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
#8 lore raw

PATCH v5 5/10 dt-bindings: display: bridge: Add MHDP HDMI for i.MX8MQ

In reply to Sandor Yu

Add bindings for i.MX8MQ MHDP HDMI.

---
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml | 102 ++++++++++++++++++
 1 file changed, 102 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 +102 -0
new file mode 100644
index 000000000000..cca6954a84ff
@@ -0,0 +1,102 @@
+# 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:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP HDMI APB clock.
+
+  phys:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to HDMI connector.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp_hdmi: hdmi-bridge@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";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&hdmi_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&hdmi_con>;
+                };
+            };
+        };
+    };
Signature · 1 line
2.34.1
maintainer
#9 lore raw

Re: [PATCH v5 05/10] dt-bindings: display: bridge: Add MHDP HDMI for i.MX8MQ

Quoted 17 lines · Sandor Yu

Add bindings for i.MX8MQ MHDP HDMI.

---
 .../display/bridge/cdns,mhdp-imx8mq-hdmi.yaml | 102 ++++++++++++++++++
 1 file changed, 102 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 +3 -0
new file mode 100644
index 000000000000..cca6954a84ff
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---

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

Quoted 10 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +10 -0
+$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.

What's the difference between this block and the DP block? The binding looks the same other than compatible, so can they be combined?

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

Quoted 5 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +5 -0
+
+properties:
+  compatible:
+    enum:
+      - cdns,mhdp-imx8mq-hdmi

Same comment here on naming.

Quoted 88 lines
Documentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +84 -0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: MHDP HDMI APB clock.
+
+  phys:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Hotplug cable plugin.
+      - description: Hotplug cable plugout.
+
+  interrupt-names:
+    items:
+      - const: plug_in
+      - const: plug_out
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port@0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Input port from display controller output.
+
+      port@1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output port to HDMI connector.
+
+    required:
+      - port@0
+      - port@1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - interrupts
+  - interrupt-names
+  - phys
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    mhdp_hdmi: hdmi-bridge@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";
+        clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        phys = <&hdmi_phy>;
+
+        ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+
+                mhdp_in: endpoint {
+                    remote-endpoint = <&dcss_out>;
+                };
+            };
+
+            port@1 {
+                reg = <1>;
+
+                mhdp_out: endpoint {
+                    remote-endpoint = <&hdmi_con>;
+                };
+            };
+        };
+    };
Signature · 1 line
2.34.1
author
#10 lore raw

PATCH v5 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   | 1018 +++++++++++++++++
 2 files changed, 1030 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 +1018 -0

1,018 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#11 lore raw

PATCH v5 7/10 dt-bindings: phy: Add Cadence HDP-TX DP PHY

In reply to Sandor Yu

Add bindings for Cadence HDP-TX DisplayPort PHY.

---
 .../bindings/phy/cdns,hdptx-dp-phy.yaml       | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +68 -0
new file mode 100644
index 000000000000..f4f741150c12
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,hdptx-dp-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence HDP-TX(HDMI/DisplayPort) PHY for DisplayPort protocol
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-dp-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#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/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: phy@32c00000 {
+        compatible = "cdns,hdptx-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+        cdns,num-lanes = <4>;
+        cdns,max-bit-rate = <5400>;
+    };
Signature · 1 line
2.34.1
maintainer
#12 lore raw

Re: [PATCH v5 07/10] dt-bindings: phy: Add Cadence HDP-TX DP PHY

Quoted 19 lines · Sandor Yu

Add bindings for Cadence HDP-TX DisplayPort PHY.

---
 .../bindings/phy/cdns,hdptx-dp-phy.yaml       | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +5 -0
new file mode 100644
index 000000000000..f4f741150c12
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,hdptx-dp-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#

Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml line 15

Quoted 10 lines
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +10 -0
+
+title: Cadence HDP-TX(HDMI/DisplayPort) PHY for DisplayPort protocol
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-dp-phy

Again, name based on SoC and SoC vendor.

Quoted 8 lines
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +8 -0
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.

Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml line 33

Quoted 10 lines
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +10 -0
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+  cdns,num-lanes:

There is a standard way to define the number of lanes. That goes in output endpoint for the DP node. Not that convenient to the phy, but the information is already there, don't duplicate it.

Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml line 40

Quoted 7 lines
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +7 -0
+    description:
+      Number of lanes.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2, 3, 4]
+    default: 4
+
+  cdns,max-bit-rate:

Same with this.

Quoted 32 lines
Documentation/devicetree/bindings/phy/cdns,hdptx-dp-phy.yaml new file +28 -0
+    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/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    dp_phy: phy@32c00000 {
+        compatible = "cdns,hdptx-dp-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+        cdns,num-lanes = <4>;
+        cdns,max-bit-rate = <5400>;
+    };
Signature · 1 line
2.34.1
author
#13 lore raw

PATCH v5 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 | 737 +++++++++++++++++++++
 3 files changed, 746 insertions(+)
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-dp.c
drivers/phy/cadence/Kconfig +8 -0
index 1adde2d99ae7..7c662a57b812 100644
@@ -30,6 +30,14 @@ config PHY_CADENCE_DPHY_RX
 	help
 	  Support for Cadence D-PHY in Rx configuration.
 
+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
+
 config PHY_CADENCE_SIERRA
 	tristate "Cadence Sierra PHY Driver"
 	depends on OF && HAS_IOMEM && RESET_CONTROLLER
drivers/phy/cadence/Makefile +1 -0
index e17f035ddece..5e7d92a4c9aa 100644
@@ -2,5 +2,6 @@
 obj-$(CONFIG_PHY_CADENCE_TORRENT)	+= phy-cadence-torrent.o
 obj-$(CONFIG_PHY_CADENCE_DPHY)	+= cdns-dphy.o
 obj-$(CONFIG_PHY_CADENCE_DPHY_RX)	+= cdns-dphy-rx.o
+obj-$(CONFIG_PHY_CADENCE_HDPTX_DP)	+= phy-cadence-hdptx-dp.o
 obj-$(CONFIG_PHY_CADENCE_SIERRA)	+= phy-cadence-sierra.o
 obj-$(CONFIG_PHY_CADENCE_SALVO)	+= phy-cadence-salvo.o
drivers/phy/cadence/phy-cadence-hdptx-dp.c new file +737 -0

737 lines not on this page · raw message

Signature · 1 line
2.34.1
author
#14 lore raw

PATCH v5 9/10 dt-bindings: phy: Add Cadence HDP-TX HDMI PHY

In reply to Sandor Yu

Add bindings for Cadence HDP-TX HDMI PHY.

---
 .../bindings/phy/cdns,hdptx-hdmi-phy.yaml     | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/cdns,hdptx-hdmi-phy.yaml
Documentation/devicetree/bindings/phy/cdns,hdptx-hdmi-phy.yaml new file +52 -0
new file mode 100644
index 000000000000..9de824635a03
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/cdns,hdptx-hdmi-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cadence HDP-TX(HDMI/DisplayPort) PHY for HDMI protocol
+
+maintainers:
+  - Sandor Yu <[email protected]>
+
+properties:
+  compatible:
+    enum:
+      - cdns,hdptx-hdmi-phy
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: PHY reference clock.
+      - description: APB clock.
+
+  clock-names:
+    items:
+      - const: ref
+      - const: apb
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/phy/phy.h>
+    hdmi_phy: phy@32c00000 {
+        compatible = "cdns,hdptx-hdmi-phy";
+        reg = <0x32c00000 0x100000>;
+        #phy-cells = <0>;
+        clocks = <&hdmi_phy_27m>, <&clk IMX8MQ_CLK_DISP_APB_ROOT>;
+        clock-names = "ref", "apb";
+    };
Signature · 1 line
2.34.1
author
#15 lore raw

PATCH v5 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 | 891 +++++++++++++++++++
 3 files changed, 900 insertions(+)
 create mode 100644 drivers/phy/cadence/phy-cadence-hdptx-hdmi.c
drivers/phy/cadence/Kconfig +8 -0
index 7c662a57b812..84e81c473a51 100644
@@ -38,6 +38,14 @@ config PHY_CADENCE_HDPTX_DP
 	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.
+
 config PHY_CADENCE_SIERRA
 	tristate "Cadence Sierra PHY Driver"
 	depends on OF && HAS_IOMEM && RESET_CONTROLLER
drivers/phy/cadence/Makefile +1 -0
index 5e7d92a4c9aa..98702b7d2903 100644
@@ -3,5 +3,6 @@ obj-$(CONFIG_PHY_CADENCE_TORRENT)	+= phy-cadence-torrent.o
 obj-$(CONFIG_PHY_CADENCE_DPHY)	+= cdns-dphy.o
 obj-$(CONFIG_PHY_CADENCE_DPHY_RX)	+= cdns-dphy-rx.o
 obj-$(CONFIG_PHY_CADENCE_HDPTX_DP)	+= phy-cadence-hdptx-dp.o
+obj-$(CONFIG_PHY_CADENCE_HDPTX_HDMI) += phy-cadence-hdptx-hdmi.o
 obj-$(CONFIG_PHY_CADENCE_SIERRA)	+= phy-cadence-sierra.o
 obj-$(CONFIG_PHY_CADENCE_SALVO)	+= phy-cadence-salvo.o
drivers/phy/cadence/phy-cadence-hdptx-hdmi.c new file +891 -0

891 lines not on this page · raw message

Signature · 1 line
2.34.1