Initial support for Cadence MHDP(HDMI/DP) for i.MX8MQ
Subsystems (6)
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
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
@@ -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
@@ -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
PATCH v2 2/10 dts-bingings: display: bridge: Add MHDP HDMI bindings for i.MX8MQ
In reply to Sandor YuAdd 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
@@ -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
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
Signed-off-by Sandor Yu <[email protected]>--- .../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.yamlDocumentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-hdmi.yaml new file +13
-0@@ -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
Rob Herring
maintainerRe: [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
Signed-off-by Sandor Yu <[email protected]>--- .../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
PATCH v2 3/10 drm: bridge: cadence: Add MHDP DP driver for i.MX8MQ
In reply to Sandor YuAdd 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
@@ -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
@@ -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
PATCH v2 4/10 phy: Add HDMI configuration options
In reply to Sandor YuAllow 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
@@ -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
@@ -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
PATCH v2 5/10 dts-bindings: display: bridge: Add MHDP DP bindings for i.MX8MQ
In reply to Sandor YuAdd 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
@@ -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
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.
Signed-off-by Sandor Yu <[email protected]>
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.yamlDocumentation/devicetree/bindings/display/bridge/cdns,mhdp-imx8mq-dp.yaml new file +43
-0@@ -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
PATCH v2 6/10 drm: bridge: cadence: Add MHDP HDMI driver for i.MX8MQ
In reply to Sandor YuAdd 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
@@ -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
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.
Signed-off-by Sandor Yu <[email protected]>--- 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
-0b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992100644drivers/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.cnew file mode 100644 index 000000000000..b392aac015bddrivers/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" );
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.MX8MQCaution: 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.
Signed-off-by Sandor Yu <[email protected]>--- 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
-0b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644drivers/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
-0Quoted 1 line
b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.cnew file mode100644
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 ininfoframe\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_statusdrivers/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_connectorQuoted 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_unusedclk_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" );
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.MX8MQCaution: 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.
Signed-off-by Sandor Yu <[email protected]>---
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
-0b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644drivers/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_unusedclk_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_unusedclk_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
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.MX8MQCaution: 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.MX8MQCaution: 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.
Signed-off-by Sandor Yu <[email protected]>---
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
-0b/drivers/gpu/drm/bridge/cadence/Kconfig index
e79ae1af3765..377452d09992
100644drivers/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_resourcecould not support suchQuoted 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_unusedclk_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_unusedclk_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_summaryfrom 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_out7 7 0
1000000000
0 0 50000 Y
sys_pll2_out_monitor0 0 0
1000000000
0 0 50000 Y
sys2_pll_1000m0 0 0
1000000000
0 0 50000 Y
sys2_pll_500m1 2 0
500000000
0 0 50000 Y
audio_ahb0 1 0
500000000
0 0 50000 N
ipg_audio_root0 1 0
250000000
0 0 50000 Y
sdma2_clk0 2 0
250000000
0 0 50000 N
sai6_ipg_clk0 0 0
250000000
0 0 50000 N
sai5_ipg_clk0 0 0
250000000
0 0 50000 N
sai4_ipg_clk0 0 0
250000000
0 0 50000 N
sai1_ipg_clk0 0 0
250000000
0 0 50000 N
nand 0 0 0
500000000
0 0 50000 N
nand_root_clk0 0 0
500000000
0 0 50000 N
usb_bus2 2 0
500000000
0 0 50000 Y
usb2_ctrl_root_clk1 1 0
500000000
0 0 50000 Y
usb1_ctrl_root_clk1 1 0
500000000
0 0 50000 Y
sys2_pll_333m1 1 0
333333333
0 0 50000 Y
main_axi1 1 0
333333333
0 0 50000 Y
sys2_pll_250m2 2 0
250000000
0 0 50000 Y
pcie1_ctrl1 1 0
250000000
0 0 50000 Y
pcie1_root_clk1 1 0
250000000
0 0 50000 Y
pcie2_ctrl1 1 0
250000000
0 0 50000 Y
pcie2_root_clk1 1 0
250000000
0 0 50000 Y
sys2_pll_200m3 3 0
200000000
0 0 50000 Y
ecspi3 0 0 0
200000000
0 0 50000 N
ecspi3_root_clk0 0 0
200000000
0 0 50000 N
ecspi2 1 1 0
200000000
0 0 50000 Y
ecspi2_root_clk2 2 0
200000000
0 0 50000 Y
ecspi1 1 1 0
200000000
0 0 50000 Y
ecspi1_root_clk2 2 0
200000000
0 0 50000 Y
gic 1 1 0
200000000
0 0 50000 Y
arm_m4_core0 0 0
200000000
0 0 50000 N
sys2_pll_166m0 0 0
166666666
0 0 50000 Y
sys2_pll_125m1 1 0
125000000
0 0 50000 Y
enet_ref1 1 0
125000000
0 0 50000 Y
sys2_pll_100m3 3 0
100000000
0 0 50000 Y
pcie1_phy1 1 0
100000000
0 0 50000 Y
pcie2_phy1 1 0
100000000
0 0 50000 Y
enet_timer1 1 0
100000000
0 0 50000 Y
sys2_pll_50m1 1 0
50000000
0 0 50000 Y
enet_phy1 1 0
50000000
0 0 50000 Y
sys1_pll_out5 5 0
800000000
0 0 50000 Y
sys_pll1_out_monitor0 0 0
800000000
0 0 50000 Y
sys1_pll_800m2 2 0
800000000
0 0 50000 Y
vpu_bus0 0 0
800000000
0 0 50000 N
vpu_dec_root_clk0 0 0
800000000
0 0 50000 N
arm_a53_div0 0 0
800000000
0 0 50000 N
dram_apb1 1 0
160000000
0 0 50000 Y
noc 1 1 0
800000000
0 0 50000 Y
disp_rtrm0 0 0
400000000
0 0 50000 N
disp_rtrm_root_clk0 0 0
400000000
0 0 50000 N
disp_apb0 0 0
133333334
0 0 50000 N
disp_apb_root_clk0 0 0
133333334
0 0 50000 N
disp_axi0 0 0
800000000
0 0 50000 N
disp_axi_root_clk0 0 0
800000000
0 0 50000 N
sys1_pll_400m0 0 0
400000000
0 0 50000 Y
usdhc2 0 0 0
400000000
0 0 50000 N
usdhc2_root_clk0 0 0
400000000
0 0 50000 N
usdhc1 0 0 0
400000000
0 0 50000 N
usdhc1_root_clk0 0 0
400000000
0 0 50000 N
sys1_pll_266m1 1 0
266666666
0 0 50000 Y
nand_usdhc_bus0 0 0
266666666
0 0 50000 N
nand_usdhc_rawnand_clk0 0 0
266666666
0 0 50000 N
enet_axi1 1 0
266666666
0 0 50000 Y
enet1_root_clk2 2 0
266666666
0 0 50000 Y
sys1_pll_200m0 0 0
200000000
0 0 50000 Y
sys1_pll_160m0 0 0
160000000
0 0 50000 Y
sys1_pll_133m1 1 0
133333333
0 0 50000 Y
ahb 9 4 0
133333333
0 0 50000 Y
ipg_root8 8 0
66666667
0 0 50000 Y
sdma1_clk6 1 0
66666667
0 0 50000 Y
tmu_root_clk1 1 0
66666667
0 0 50000 Y
sai3_ipg_clk0 0 0
66666667
0 0 50000 N
sai2_ipg_clk0 0 0
66666667
0 0 50000 N
ocotp_root_clk0 0 0
66666667
0 0 50000 N
mu_root_clk0 0 0
66666667
0 0 50000 N
gpio5_root_clk1 1 0
66666667
0 0 50000 Y
gpio4_root_clk1 1 0
66666667
0 0 50000 Y
gpio3_root_clk1 1 0
66666667
0 0 50000 Y
gpio2_root_clk1 1 0
66666667
0 0 50000 Y
gpio1_root_clk1 1 0
66666667
0 0 50000 Y
sys1_pll_100m2 2 0
100000000
0 0 50000 Y
usb_phy_ref2 2 0
100000000
0 0 50000 Y
usb2_phy_root_clk1 1 0
100000000
0 0 50000 Y
usb1_phy_root_clk1 1 0
100000000
0 0 50000 Y
usb_core_ref2 2 0
100000000
0 0 50000 Y
qspi 0 0 0
100000000
0 0 50000 N
qspi_root_clk0 0 0
100000000
0 0 50000 N
dram_alt0 0 0
100000000
0 0 50000 N
dram_alt_root0 0 0
25000000
0 0 50000 Y
sys1_pll_80m2 2 0
80000000
0 0 50000 Y
pcie1_aux1 1 0
10000000
0 0 50000 Y
pcie2_aux1 1 0
10000000
0 0 50000 Y
uart2 0 0 0
80000000
0 0 50000 N
uart2_root_clk0 0 0
80000000
0 0 50000 N
uart1 0 0 0
80000000
0 0 50000 N
uart1_root_clk0 0 0
80000000
0 0 50000 N
sys1_pll_40m0 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_ext40 0 0
133000000
0 0 50000 Y
clk_ext30 0 0
133000000
0 0 50000 Y
clk_ext20 0 0
133000000
0 0 50000 Y
clk_ext10 0 0
133000000
0 0 50000 Y
hdmi_phy_27m0 0 0
27000000
0 0 50000 Y
osc_27m0 0 0
27000000
0 0 50000 Y
osc_25m7 11 0
25000000
0 0 50000 Y
gpt_3m0 0 0
3125000
0 0 50000 Y
csi2_esc0 0 0
25000000
0 0 50000 N
csi2_phy_ref0 0 0
25000000
0 0 50000 N
csi2_core0 0 0
25000000
0 0 50000 N
csi2_root_clk0 0 0
25000000
0 0 50000 N
csi1_esc0 0 0
25000000
0 0 50000 N
csi1_phy_ref0 0 0
25000000
0 0 50000 N
csi1_core0 0 0
25000000
0 0 50000 N
csi1_root_clk0 0 0
25000000
0 0 50000 N
dsi_ahb0 0 0
25000000
0 0 50000 N
dsi_ipg_div0 0 0
12500000
0 0 50000 Y
dsi_esc0 0 0
25000000
0 0 50000 N
dsi_dbi0 0 0
25000000
0 0 50000 N
dsi_phy_ref0 0 0
25000000
0 0 50000 N
dsi_core0 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_clk0 0 0
25000000
0 0 50000 N
wdog2_root_clk0 0 0
25000000
0 0 50000 N
wdog1_root_clk1 1 0
25000000
0 0 50000 Y
gpt1 0 0 0
25000000
0 0 50000 N
gpt1_root_clk0 0 0
25000000
0 0 50000 N
pwm4 0 0 0
25000000
0 0 50000 N
pwm4_root_clk0 0 0
25000000
0 0 50000 N
pwm3 0 0 0
25000000
0 0 50000 N
pwm3_root_clk0 0 0
25000000
0 0 50000 N
pwm2 0 0 0
25000000
0 0 50000 N
pwm2_root_clk0 0 0
25000000
0 0 50000 N
pwm1 0 0 0
25000000
0 0 50000 N
pwm1_root_clk0 0 0
25000000
0 0 50000 N
uart4 0 0 0
25000000
0 0 50000 N
uart4_root_clk0 0 0
25000000
0 0 50000 N
uart3 1 1 0
25000000
0 0 50000 Y
uart3_root_clk4 4 0
25000000
0 0 50000 Y
i2c4 0 0 0
25000000
0 0 50000 N
i2c4_root_clk0 0 0
25000000
0 0 50000 N
i2c3 0 1 0
25000000
0 0 50000 N
i2c3_root_clk0 1 0
25000000
0 0 50000 N
i2c2 0 1 0
25000000
0 0 50000 N
i2c2_root_clk0 1 0
25000000
0 0 50000 N
i2c1 0 1 0
25000000
0 0 50000 N
i2c1_root_clk0 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_clk0 0 0
25000000
0 0 50000 N
sai5 0 0 0
25000000
0 0 50000 N
sai5_root_clk0 0 0
25000000
0 0 50000 N
sai4 0 0 0
25000000
0 0 50000 N
sai4_root_clk0 0 0
25000000
0 0 50000 N
sai2 0 0 0
25000000
0 0 50000 N
sai2_root_clk0 0 0
25000000
0 0 50000 N
sai1 0 0 0
25000000
0 0 50000 N
sai1_root_clk0 0 0
25000000
0 0 50000 N
lcdif_pixel0 0 0
25000000
0 0 50000 N
disp_dc80000 0 0
25000000
0 0 50000 N
disp_root_clk0 0 0
25000000
0 0 50000 N
disp_dtrc0 0 0
25000000
0 0 50000 N
noc_apb1 1 0
25000000
0 0 50000 Y
video2_pll1_ref_sel0 0 0
25000000
0 0 50000 Y
video2_pll_out0 0 0
25000000
0 0 50000 Y
video_pll2_out_monitor0 0 0
25000000
0 0 50000 Y
dram_pll1_ref_sel1 1 0
25000000
0 0 50000 Y
dram_pll_out2 2 0
800000000
0 0 50000 Y
dram_core_clk1 1 0
800000000
0 0 50000 Y
dram_pll_out_monitor0 0 0
800000000
0 0 50000 Y
sys3_pll1_ref_sel1 1 0
25000000
0 0 50000 Y
sys3_pll_out1 1 0
25000000
0 0 50000 Y
sys_pll3_out_monitor0 0 0
25000000
0 0 50000 Y
video_pll1_ref_sel0 0 0
25000000
0 0 50000 Y
video_pll1_bypass0 0 0
25000000
0 0 50000 Y
video_pll1_out_monitor0 0 0
25000000
0 0 50000 Y
video_pll1_out0 0 0
25000000
0 0 50000 N
dc_pixel0 0 0
5000000
0 0 50000 N
video_pll1_ref_div0 0 0
5000000
0 0 50000 Y
video_pll10 0 0
650000000
0 0 50000 Y
audio_pll2_ref_sel0 0 0
25000000
0 0 50000 Y
audio_pll2_ref_div0 0 0
5000000
0 0 50000 Y
audio_pll20 0 0
722534397
0 0 50000 Y
audio_pll2_bypass0 0 0
722534397
0 0 50000 Y
audio_pll2_out_monitor0 0 0
722534397
0 0 50000 Y
audio_pll2_out0 0 0
722534397
0 0 50000 N
audio_pll1_ref_sel0 0 0
25000000
0 0 50000 Y
audio_pll1_ref_div0 0 0
5000000
0 0 50000 Y
audio_pll10 0 0
786431998
0 0 50000 Y
audio_pll1_bypass0 0 0
786431998
0 0 50000 Y
audio_pll1_out_monitor0 0 0
786431998
0 0 50000 Y
audio_pll1_out0 0 0
786431998
0 0 50000 N
sai3 0 0 0
49152000
0 0 50000 N
sai3_root_clk0 0 0
49152000
0 0 50000 N
pll 0 0 0
196608000
0 0 50000 Y
codec_clkin0 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_sel0 1 0
25000000
0 0 50000 Y
vpu_pll_ref_div0 1 0
5000000
0 0 50000 Y
vpu_pll0 1 0
600000000
0 0 50000 Y
vpu_pll_bypass0 1 0
600000000
0 0 50000 Y
vpu_pll_out_monitor0 0 0
600000000
0 0 50000 Y
vpu_pll_out0 2 0
600000000
0 0 50000 N
vpu_g20 1 0
600000000
0 0 50000 N
vpu_g2_root_clk0 1 0
600000000
0 0 50000 N
vpu_g10 1 0
600000000
0 0 50000 N
vpu_g1_root_clk0 1 0
600000000
0 0 50000 N
gpu_pll_ref_sel0 0 0
25000000
0 0 50000 Y
gpu_pll_ref_div0 0 0
5000000
0 0 50000 Y
gpu_pll0 0 0
800000000
0 0 50000 Y
gpu_pll_bypass0 0 0
800000000
0 0 50000 Y
gpu_pll_out_monitor0 0 0
800000000
0 0 50000 Y
pllout_monitor_sel0 0 0
800000000
0 0 50000 Y
pllout_monitor_clk20 0
0
800000000 0 0 50000 N
gpu_pll_out0 0 0
800000000
0 0 50000 N
gpu_ahb0 0 0
800000000
0 0 50000 N
gpu_axi0 0 0
800000000
0 0 50000 N
gpu_shader0 0 0
800000000
0 0 50000 N
gpu_core0 0 0
800000000
0 0 50000 N
gpu_root_clk0 0 0
800000000
0 0 50000 N
arm_pll_ref_sel1 1 0
25000000
0 0 50000 Y
arm_pll_ref_div1 1 0
5000000
0 0 50000 Y
arm_pll1 1 0
800000000
0 0 50000 Y
arm_pll_bypass1 1 0
800000000
0 0 50000 Y
arm_pll_out_monitor0 0 0
800000000
0 0 50000 Y
arm_pll_out1 1 0
800000000
0 0 50000 Y
arm_a53_core1 1 0
800000000
0 0 50000 Y
arm 1 1 0
Quoted 9 lines
800000000
0 0 50000 Y
vpu_core0 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
PATCH v2 7/10 dts-bindings: phy: Add Cadence HDP-TX DP PHY bindings
In reply to Sandor YuAdd 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
@@ -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
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.
Signed-off-by Sandor Yu <[email protected]>--- .../bindings/phy/phy-cadence-hdptx-dp.yaml | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yamlDocumentation/devicetree/bindings/phy/phy-cadence-hdptx-dp.yaml new file +0
-0
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
PATCH v2 8/10 phy: cadence: Add driver for HDP-TX DisplyPort PHY
In reply to Sandor YuAdd 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
@@ -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
@@ -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
PATCH v2 9/10 dts-bindings: phy: Add Cadence HDP-TX HDMI PHY bindings
In reply to Sandor YuAdd 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
@@ -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
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.
Signed-off-by Sandor Yu <[email protected]>--- .../bindings/phy/phy-cadence-hdptx-hdmi.yaml | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yamlDocumentation/devicetree/bindings/phy/phy-cadence-hdptx-hdmi.yaml new file +0
-0
Same comments apply as for other bindings (also phy)
Best regards,
Krzysztof
PATCH v2 10/10 phy: cadence: Add driver for HDP-TX HDMI PHY
In reply to Sandor YuAdd 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
@@ -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
@@ -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