aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch148
1 files changed, 148 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch b/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch
new file mode 100644
index 0000000000..80dc0cc3e5
--- /dev/null
+++ b/target/linux/layerscape/patches-5.4/805-display-0015-drm-bridge-cadence-Add-support-for-periodically-poll.patch
@@ -0,0 +1,148 @@
+From 35e2ec234646f04eb0e17e4c3a4cf21faed3655a Mon Sep 17 00:00:00 2001
+From: Wen He <wen.he_1@nxp.com>
+Date: Wed, 18 Sep 2019 11:05:31 +0800
+Subject: [PATCH] drm: bridge: cadence: Add support for periodically poll the
+ connector
+
+Normally, DP/HDMI PHY use HPD_IRQ to monitor the connector connection
+status, but LS1028A doesn't support HPD_IRQ signals response.
+
+This patch allows periodically poll the connector for connection and
+disconnection.
+
+Signed-off-by: Wen He <wen.he_1@nxp.com>
+---
+ drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 86 +++++++++++++++++----------
+ include/drm/bridge/cdns-mhdp-common.h | 1 +
+ 2 files changed, 54 insertions(+), 33 deletions(-)
+
+--- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
++++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
+@@ -276,7 +276,11 @@ static int cdns_dp_bridge_attach(struct
+
+ connector->interlace_allowed = 1;
+
+- connector->polled = DRM_CONNECTOR_POLL_HPD;
++ if (mhdp->is_hpd)
++ connector->polled = DRM_CONNECTOR_POLL_HPD;
++ else
++ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
++ DRM_CONNECTOR_POLL_DISCONNECT;
+
+ drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs);
+
+@@ -439,22 +443,34 @@ static int __cdns_dp_probe(struct platfo
+ INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores));
+- if (IS_ERR(mhdp->regs_base))
+- return -ENOMEM;
++ if (iores) {
++ mhdp->regs_base = devm_ioremap(dev, iores->start,
++ resource_size(iores));
++ if (IS_ERR(mhdp->regs_base))
++ return -ENOMEM;
++ }
+
+ iores = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+- mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores));
+- if (IS_ERR(mhdp->regs_sec))
+- return -ENOMEM;
++ if (iores) {
++ mhdp->regs_sec = devm_ioremap(dev, iores->start,
++ resource_size(iores));
++ if (IS_ERR(mhdp->regs_sec))
++ return -ENOMEM;
++ }
++
++ mhdp->is_hpd = true;
+
+ mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
+- if (mhdp->irq[IRQ_IN] < 0)
++ if (mhdp->irq[IRQ_IN] < 0) {
++ mhdp->is_hpd = false;
+ dev_info(dev, "No plug_in irq number\n");
++ }
+
+ mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
+- if (mhdp->irq[IRQ_OUT] < 0)
++ if (mhdp->irq[IRQ_OUT] < 0) {
++ mhdp->is_hpd = false;
+ dev_info(dev, "No plug_out irq number\n");
++ }
+
+ cdns_dp_parse_dt(mhdp);
+
+@@ -474,33 +490,37 @@ static int __cdns_dp_probe(struct platfo
+ cdns_mhdp_plat_call(mhdp, phy_set);
+
+ /* Enable Hotplug Detect IRQ thread */
+- irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
+- ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
+- NULL, cdns_dp_irq_thread,
+- IRQF_ONESHOT, dev_name(dev),
+- mhdp);
+- if (ret) {
+- dev_err(dev, "can't claim irq %d\n",
+- mhdp->irq[IRQ_IN]);
+- return -EINVAL;
+- }
++ if (mhdp->is_hpd) {
++ irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
++ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
++ NULL, cdns_dp_irq_thread,
++ IRQF_ONESHOT, dev_name(dev),
++ mhdp);
+
+- irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
+- ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
+- NULL, cdns_dp_irq_thread,
+- IRQF_ONESHOT, dev_name(dev),
+- mhdp);
+- if (ret) {
+- dev_err(dev, "can't claim irq %d\n",
+- mhdp->irq[IRQ_OUT]);
+- return -EINVAL;
++ if (ret) {
++ dev_err(dev, "can't claim irq %d\n",
++ mhdp->irq[IRQ_IN]);
++ return -EINVAL;
++ }
++
++ irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
++ ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
++ NULL, cdns_dp_irq_thread,
++ IRQF_ONESHOT, dev_name(dev),
++ mhdp);
++
++ if (ret) {
++ dev_err(dev, "can't claim irq %d\n",
++ mhdp->irq[IRQ_OUT]);
++ return -EINVAL;
++ }
++
++ if (cdns_mhdp_read_hpd(mhdp))
++ enable_irq(mhdp->irq[IRQ_OUT]);
++ else
++ enable_irq(mhdp->irq[IRQ_IN]);
+ }
+
+- if (cdns_mhdp_read_hpd(mhdp))
+- enable_irq(mhdp->irq[IRQ_OUT]);
+- else
+- enable_irq(mhdp->irq[IRQ_IN]);
+-
+ mhdp->bridge.base.driver_private = mhdp;
+ mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs;
+ #ifdef CONFIG_OF
+--- a/include/drm/bridge/cdns-mhdp-common.h
++++ b/include/drm/bridge/cdns-mhdp-common.h
+@@ -683,6 +683,7 @@ struct cdns_mhdp_device {
+ bool link_up;
+ bool power_up;
+ bool plugged;
++ bool is_hpd;
+ struct mutex lock;
+
+ int irq[IRQ_NUM];