blob: 80dc0cc3e5fe8092b0d18b283edcc0de2b5ed47b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From 35e2ec234646f04eb0e17e4c3a4cf21faed3655a Mon Sep 17 00:00:00 2001
2From: Wen He <wen.he_1@nxp.com>
3Date: Wed, 18 Sep 2019 11:05:31 +0800
4Subject: [PATCH] drm: bridge: cadence: Add support for periodically poll the
5 connector
6
7Normally, DP/HDMI PHY use HPD_IRQ to monitor the connector connection
8status, but LS1028A doesn't support HPD_IRQ signals response.
9
10This patch allows periodically poll the connector for connection and
11disconnection.
12
13Signed-off-by: Wen He <wen.he_1@nxp.com>
14---
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(-)
18
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
22
23 connector->interlace_allowed = 1;
24
25- connector->polled = DRM_CONNECTOR_POLL_HPD;
26+ if (mhdp->is_hpd)
27+ connector->polled = DRM_CONNECTOR_POLL_HPD;
28+ else
29+ connector->polled = DRM_CONNECTOR_POLL_CONNECT |
30+ DRM_CONNECTOR_POLL_DISCONNECT;
31
32 drm_connector_helper_add(connector, &cdns_dp_connector_helper_funcs);
33
34@@ -439,22 +443,34 @@ static int __cdns_dp_probe(struct platfo
35 INIT_DELAYED_WORK(&mhdp->hotplug_work, hotplug_work_func);
36
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))
40- return -ENOMEM;
41+ if (iores) {
42+ mhdp->regs_base = devm_ioremap(dev, iores->start,
43+ resource_size(iores));
44+ if (IS_ERR(mhdp->regs_base))
45+ return -ENOMEM;
46+ }
47
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))
51- return -ENOMEM;
52+ if (iores) {
53+ mhdp->regs_sec = devm_ioremap(dev, iores->start,
54+ resource_size(iores));
55+ if (IS_ERR(mhdp->regs_sec))
56+ return -ENOMEM;
57+ }
58+
59+ mhdp->is_hpd = true;
60
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");
66+ }
67
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");
73+ }
74
75 cdns_dp_parse_dt(mhdp);
76
77@@ -474,33 +490,37 @@ static int __cdns_dp_probe(struct platfo
78 cdns_mhdp_plat_call(mhdp, phy_set);
79
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),
85- mhdp);
86- if (ret) {
87- dev_err(dev, "can't claim irq %d\n",
88- mhdp->irq[IRQ_IN]);
89- return -EINVAL;
90- }
91+ if (mhdp->is_hpd) {
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),
96+ mhdp);
97
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),
102- mhdp);
103- if (ret) {
104- dev_err(dev, "can't claim irq %d\n",
105- mhdp->irq[IRQ_OUT]);
106- return -EINVAL;
107+ if (ret) {
108+ dev_err(dev, "can't claim irq %d\n",
109+ mhdp->irq[IRQ_IN]);
110+ return -EINVAL;
111+ }
112+
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),
117+ mhdp);
118+
119+ if (ret) {
120+ dev_err(dev, "can't claim irq %d\n",
121+ mhdp->irq[IRQ_OUT]);
122+ return -EINVAL;
123+ }
124+
125+ if (cdns_mhdp_read_hpd(mhdp))
126+ enable_irq(mhdp->irq[IRQ_OUT]);
127+ else
128+ enable_irq(mhdp->irq[IRQ_IN]);
129 }
130
131- if (cdns_mhdp_read_hpd(mhdp))
132- enable_irq(mhdp->irq[IRQ_OUT]);
133- else
134- enable_irq(mhdp->irq[IRQ_IN]);
135-
136 mhdp->bridge.base.driver_private = mhdp;
137 mhdp->bridge.base.funcs = &cdns_dp_bridge_funcs;
138 #ifdef CONFIG_OF
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 {
142 bool link_up;
143 bool power_up;
144 bool plugged;
145+ bool is_hpd;
146 struct mutex lock;
147
148 int irq[IRQ_NUM];