80dc0cc3e5fe8092b0d18b283edcc0de2b5ed47b
[openwrt/openwrt.git] /
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
5 connector
6
7 Normally, DP/HDMI PHY use HPD_IRQ to monitor the connector connection
8 status, but LS1028A doesn't support HPD_IRQ signals response.
9
10 This patch allows periodically poll the connector for connection and
11 disconnection.
12
13 Signed-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];