1 From 35e2ec234646f04eb0e17e4c3a4cf21faed3655a Mon Sep 17 00:00:00 2001
2 From: Wen He <wen.he_1@nxp.com>
3 Date: Wed, 18 Sep 2019 11:05:31 +0800
4 Subject: [PATCH] drm: bridge: cadence: Add support for periodically poll the
7 Normally, DP/HDMI PHY use HPD_IRQ to monitor the connector connection
8 status, but LS1028A doesn't support HPD_IRQ signals response.
10 This patch allows periodically poll the connector for connection and
13 Signed-off-by: Wen He <wen.he_1@nxp.com>
15 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 86 +++++++++++++++++----------
16 include/drm/bridge/cdns-mhdp-common.h | 1 +
17 2 files changed, 54 insertions(+), 33 deletions(-)
19 --- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
20 +++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
21 @@ -276,7 +276,11 @@ static int cdns_dp_bridge_attach(struct
23 connector->interlace_allowed = 1;
25 - connector->polled = DRM_CONNECTOR_POLL_HPD;
27 + connector->polled = DRM_CONNECTOR_POLL_HPD;
29 + connector->polled = DRM_CONNECTOR_POLL_CONNECT |
30 + DRM_CONNECTOR_POLL_DISCONNECT;
32 drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs);
34 @@ -439,22 +443,34 @@ static int __cdns_dp_probe(struct platfo
35 INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
37 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
38 - mhdp->regs_base = devm_ioremap(dev, iores->start, resource_size(iores));
39 - if (IS_ERR(mhdp->regs_base))
42 + mhdp->regs_base = devm_ioremap(dev, iores->start,
43 + resource_size(iores));
44 + if (IS_ERR(mhdp->regs_base))
48 iores = platform_get_resource(pdev, IORESOURCE_MEM, 1);
49 - mhdp->regs_sec = devm_ioremap(dev, iores->start, resource_size(iores));
50 - if (IS_ERR(mhdp->regs_sec))
53 + mhdp->regs_sec = devm_ioremap(dev, iores->start,
54 + resource_size(iores));
55 + if (IS_ERR(mhdp->regs_sec))
59 + mhdp->is_hpd = true;
61 mhdp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
62 - if (mhdp->irq[IRQ_IN] < 0)
63 + if (mhdp->irq[IRQ_IN] < 0) {
64 + mhdp->is_hpd = false;
65 dev_info(dev, "No plug_in irq number\n");
68 mhdp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
69 - if (mhdp->irq[IRQ_OUT] < 0)
70 + if (mhdp->irq[IRQ_OUT] < 0) {
71 + mhdp->is_hpd = false;
72 dev_info(dev, "No plug_out irq number\n");
75 cdns_dp_parse_dt(mhdp);
77 @@ -474,33 +490,37 @@ static int __cdns_dp_probe(struct platfo
78 cdns_mhdp_plat_call(mhdp, phy_set);
80 /* Enable Hotplug Detect IRQ thread */
81 - irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
82 - ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
83 - NULL, cdns_dp_irq_thread,
84 - IRQF_ONESHOT, dev_name(dev),
87 - dev_err(dev, "can't claim irq %d\n",
92 + irq_set_status_flags(mhdp->irq[IRQ_IN], IRQ_NOAUTOEN);
93 + ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_IN],
94 + NULL, cdns_dp_irq_thread,
95 + IRQF_ONESHOT, dev_name(dev),
98 - irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
99 - ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
100 - NULL, cdns_dp_irq_thread,
101 - IRQF_ONESHOT, dev_name(dev),
104 - dev_err(dev, "can't claim irq %d\n",
105 - mhdp->irq[IRQ_OUT]);
108 + dev_err(dev, "can't claim irq %d\n",
109 + mhdp->irq[IRQ_IN]);
113 + irq_set_status_flags(mhdp->irq[IRQ_OUT], IRQ_NOAUTOEN);
114 + ret = devm_request_threaded_irq(dev, mhdp->irq[IRQ_OUT],
115 + NULL, cdns_dp_irq_thread,
116 + IRQF_ONESHOT, dev_name(dev),
120 + dev_err(dev, "can't claim irq %d\n",
121 + mhdp->irq[IRQ_OUT]);
125 + if (cdns_mhdp_read_hpd(mhdp))
126 + enable_irq(mhdp->irq[IRQ_OUT]);
128 + enable_irq(mhdp->irq[IRQ_IN]);
131 - if (cdns_mhdp_read_hpd(mhdp))
132 - enable_irq(mhdp->irq[IRQ_OUT]);
134 - enable_irq(mhdp->irq[IRQ_IN]);
136 mhdp->bridge.base.driver_private = mhdp;
137 mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs;
139 --- a/include/drm/bridge/cdns-mhdp-common.h
140 +++ b/include/drm/bridge/cdns-mhdp-common.h
141 @@ -683,6 +683,7 @@ struct cdns_mhdp_device {