From 5f6d039e73b45d4827923d895998d64c99bba3e5 Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Tue, 10 Aug 2021 19:46:22 +0800 Subject: [PATCH] drm/bridge: synopsys: dw-hdmi: Support force logo display Signed-off-by: Algea Cao Change-Id: Ib885ab7064a874a898b1ae005f2a4d8e4e9a1b01 --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 59 ++++++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index d02c1bf563cf..d68476f6c121 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -325,6 +325,7 @@ struct dw_hdmi { bool sink_has_audio; bool hpd_state; bool support_hdmi; + bool force_logo; int force_output; struct delayed_work work; @@ -2688,11 +2689,13 @@ dw_hdmi_connector_detect(struct drm_connector *connector, bool force) connector); int connect_status; - mutex_lock(&hdmi->mutex); - hdmi->force = DRM_FORCE_UNSPECIFIED; - dw_hdmi_update_power(hdmi); - dw_hdmi_update_phy_mask(hdmi); - mutex_unlock(&hdmi->mutex); + if (!hdmi->force_logo) { + mutex_lock(&hdmi->mutex); + hdmi->force = DRM_FORCE_UNSPECIFIED; + dw_hdmi_update_power(hdmi); + dw_hdmi_update_phy_mask(hdmi); + mutex_unlock(&hdmi->mutex); + } connect_status = hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); if (connect_status == connector_status_connected) @@ -3216,7 +3219,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense) { mutex_lock(&hdmi->mutex); - if (!hdmi->force) { + if (!hdmi->force && !hdmi->force_logo) { /* * If the RX sense status indicates we're disconnected, * clear the software rxsense status. @@ -3735,6 +3738,42 @@ static void dw_hdmi_register_hdcp(struct device *dev, struct dw_hdmi *hdmi, hdmi->hdcp = hdmi->hdcp_dev->dev.platform_data; } +static int get_force_logo_property(struct dw_hdmi *hdmi) +{ + struct device_node *dss; + struct device_node *route; + struct device_node *route_hdmi; + + dss = of_find_node_by_name(NULL, "display-subsystem"); + if (!dss) { + dev_err(hdmi->dev, "can't find display-subsystem\n"); + return -ENODEV; + } + + route = of_find_node_by_name(dss, "route"); + if (!route) { + dev_err(hdmi->dev, "can't find route\n"); + of_node_put(dss); + return -ENODEV; + } + of_node_put(dss); + + route_hdmi = of_find_node_by_name(route, "route-hdmi"); + if (!route_hdmi) { + dev_err(hdmi->dev, "can't find route-hdmi\n"); + of_node_put(route); + return -ENODEV; + } + of_node_put(route); + + hdmi->force_logo = + of_property_read_bool(route_hdmi, "force-output"); + + of_node_put(route_hdmi); + + return 0; +} + static struct dw_hdmi * __dw_hdmi_probe(struct platform_device *pdev, const struct dw_hdmi_plat_data *plat_data) @@ -3889,10 +3928,14 @@ __dw_hdmi_probe(struct platform_device *pdev, prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without", hdmi->phy.name); + ret = get_force_logo_property(hdmi); + if (ret) + goto err_iahb; + hdmi->initialized = false; ret = hdmi_readb(hdmi, HDMI_PHY_STAT0); - if ((ret & HDMI_PHY_TX_PHY_LOCK) && (ret & HDMI_PHY_HPD) && - hdmi_readb(hdmi, HDMI_FC_EXCTRLDUR)) { + if (((ret & HDMI_PHY_TX_PHY_LOCK) && (ret & HDMI_PHY_HPD) && + hdmi_readb(hdmi, HDMI_FC_EXCTRLDUR)) || hdmi->force_logo) { hdmi->mc_clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS); hdmi->disabled = false; hdmi->bridge_is_on = true;