blob: d41acfed2c955dc115439d5ed70ba896af3ab5c0 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From ae4d4a1aa913eaafe72b252cfe93f6fad68b39f2 Mon Sep 17 00:00:00 2001
2From: Sandor Yu <Sandor.yu@nxp.com>
3Date: Fri, 30 Aug 2019 15:02:13 +0800
4Subject: [PATCH] drm: bridge: cadence: Add new api functions
5
6Add variable lane_mapping for hdmi.
7Add new API function cdns_mhdp_bus_read/cdns_mhdp_bus_write,
8cdns_mhdp_get_fw_clk and cdns_mhdp_infoframe_set.
9Adjust some API function interface.
10
11Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
12---
13 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 34 ++---
14 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 131 +++++------------
15 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 167 +++++++++++++++-------
16 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c | 36 +++++
17 include/drm/bridge/cdns-mhdp-common.h | 16 ++-
18 5 files changed, 219 insertions(+), 165 deletions(-)
19 mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
20 mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
21 mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
22 mode change 100644 => 100755 drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c
23 mode change 100644 => 100755 include/drm/bridge/cdns-mhdp-common.h
24
25--- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
26+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
27@@ -116,7 +116,7 @@ static void cdns_dp_mode_set(struct imx_
28 {
29 struct drm_dp_link link;
30 struct cdns_mhdp_device *mhdp = &dp->mhdp;
31- u32 lane_mapping = mhdp->dp.lane_mapping;
32+ u32 lane_mapping = mhdp->lane_mapping;
33 int ret;
34 char linkid[6];
35
36@@ -405,12 +405,12 @@ static void cdns_dp_parse_dt(struct cdns
37 int ret;
38
39 ret = of_property_read_u32(of_node, "lane-mapping",
40- &mhdp->dp.lane_mapping);
41+ &mhdp->lane_mapping);
42 if (ret) {
43- mhdp->dp.lane_mapping = 0xc6;
44+ mhdp->lane_mapping = 0xc6;
45 dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n");
46 }
47- dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->dp.lane_mapping);
48+ dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping);
49
50 ret = of_property_read_u32(of_node, "link-rate", &mhdp->dp.link_rate);
51 if (ret) {
52@@ -470,11 +470,11 @@ __cdns_dp_probe(struct platform_device *
53
54 dp->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
55 if (dp->irq[IRQ_IN] < 0)
56- dev_info(&pdev->dev, "No plug_in irq number\n");
57+ dev_info(dev, "No plug_in irq number\n");
58
59 dp->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
60 if (dp->irq[IRQ_OUT] < 0)
61- dev_info(&pdev->dev, "No plug_out irq number\n");
62+ dev_info(dev, "No plug_out irq number\n");
63
64 cdns_dp_parse_dt(&dp->mhdp);
65
66@@ -498,7 +498,7 @@ __cdns_dp_probe(struct platform_device *
67 IRQF_ONESHOT, dev_name(dev),
68 dp);
69 if (ret) {
70- dev_err(&pdev->dev, "can't claim irq %d\n",
71+ dev_err(dev, "can't claim irq %d\n",
72 dp->irq[IRQ_IN]);
73 goto err_out;
74 }
75@@ -509,7 +509,7 @@ __cdns_dp_probe(struct platform_device *
76 IRQF_ONESHOT, dev_name(dev),
77 dp);
78 if (ret) {
79- dev_err(&pdev->dev, "can't claim irq %d\n",
80+ dev_err(dev, "can't claim irq %d\n",
81 dp->irq[IRQ_OUT]);
82 goto err_out;
83 }
84@@ -521,10 +521,10 @@ __cdns_dp_probe(struct platform_device *
85 dp->mhdp.bridge.base.driver_private = dp;
86 dp->mhdp.bridge.base.funcs = &cdns_dp_bridge_funcs;
87 #ifdef CONFIG_OF
88- dp->mhdp.bridge.base.of_node = pdev->dev.of_node;
89+ dp->mhdp.bridge.base.of_node = dev->of_node;
90 #endif
91
92- platform_set_drvdata(pdev, dp);
93+ dev_set_drvdata(dev, &dp->mhdp);
94
95 dp_aux_init(&dp->mhdp, dev);
96
97@@ -534,9 +534,9 @@ err_out:
98 return ERR_PTR(ret);
99 }
100
101-static void __cdns_dp_remove(struct imx_mhdp_device *dp)
102+static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp)
103 {
104- dp_aux_destroy(&dp->mhdp);
105+ dp_aux_destroy(mhdp);
106 }
107
108 /* -----------------------------------------------------------------------------
109@@ -559,11 +559,11 @@ EXPORT_SYMBOL_GPL(cdns_dp_probe);
110
111 void cdns_dp_remove(struct platform_device *pdev)
112 {
113- struct imx_mhdp_device *dp = platform_get_drvdata(pdev);
114+ struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
115
116- drm_bridge_remove(&dp->mhdp.bridge.base);
117+ drm_bridge_remove(&mhdp->bridge.base);
118
119- __cdns_dp_remove(dp);
120+ __cdns_dp_remove(mhdp);
121 }
122 EXPORT_SYMBOL_GPL(cdns_dp_remove);
123
124@@ -593,9 +593,9 @@ EXPORT_SYMBOL_GPL(cdns_dp_bind);
125
126 void cdns_dp_unbind(struct device *dev)
127 {
128- struct imx_mhdp_device *dp = dev_get_drvdata(dev);
129+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
130
131- __cdns_dp_remove(dp);
132+ __cdns_dp_remove(mhdp);
133 }
134 EXPORT_SYMBOL_GPL(cdns_dp_unbind);
135
136--- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
137+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
138@@ -25,25 +25,8 @@
139 #include <linux/module.h>
140 #include <linux/mfd/syscon.h>
141 #include <linux/mutex.h>
142-#include <linux/regmap.h>
143 #include <linux/of_device.h>
144
145-static void hdmi_writel(struct cdns_mhdp_device *mhdp, u32 val, u32 offset)
146-{
147- struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp);
148-
149- /* TODO */
150- if (offset >= 0x1000 && hdmi->regmap_csr) {
151- /* Remap address to low 4K memory */
152- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12);
153- writel(val, (offset & 0xfff) + mhdp->regs);
154- /* Restore address mapping */
155- regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0);
156-
157- } else
158- writel(val, mhdp->regs + offset);
159-}
160-
161 static int hdmi_sink_config(struct cdns_mhdp_device *mhdp)
162 {
163 struct drm_scdc *scdc = &mhdp->connector.base.display_info.hdmi.scdc;
164@@ -75,65 +58,12 @@ static int hdmi_sink_config(struct cdns_
165 return ret;
166 }
167
168-static int hdmi_lanes_config(struct cdns_mhdp_device *mhdp)
169-{
170- int ret;
171-
172- /* TODO */
173- /* Set the lane swapping */
174-// if (cpu_is_imx8qm())
175- ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG,
176- F_SOURCE_PHY_LANE0_SWAP(3) |
177- F_SOURCE_PHY_LANE1_SWAP(0) |
178- F_SOURCE_PHY_LANE2_SWAP(1) |
179- F_SOURCE_PHY_LANE3_SWAP(2) |
180- F_SOURCE_PHY_COMB_BYPASS(0) |
181- F_SOURCE_PHY_20_10(1));
182-#if 0
183- else
184- ret = cdns_mhdp_reg_write(mhdp, LANES_CONFIG,
185- F_SOURCE_PHY_LANE0_SWAP(0) |
186- F_SOURCE_PHY_LANE1_SWAP(1) |
187- F_SOURCE_PHY_LANE2_SWAP(2) |
188- F_SOURCE_PHY_LANE3_SWAP(3) |
189- F_SOURCE_PHY_COMB_BYPASS(0) |
190- F_SOURCE_PHY_20_10(1));
191-#endif
192- return ret;
193-}
194-
195-static void hdmi_info_frame_set(struct cdns_mhdp_device *mhdp,
196- u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type)
197+static void hdmi_lanes_config(struct cdns_mhdp_device *mhdp)
198 {
199- u32 *packet32, len32;
200- u32 val, i;
201-
202- /* invalidate entry */
203- val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
204- hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG);
205- hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN);
206-
207- /* flush fifo 1 */
208- hdmi_writel(mhdp, F_FIFO1_FLUSH(1), SOURCE_PIF_FIFO1_FLUSH);
209-
210- /* write packet into memory */
211- packet32 = (u32 *)packet;
212- len32 = packet_len / 4;
213- for (i = 0; i < len32; i++)
214- hdmi_writel(mhdp, F_DATA_WR(packet32[i]), SOURCE_PIF_DATA_WR);
215-
216- /* write entry id */
217- hdmi_writel(mhdp, F_WR_ADDR(entry_id), SOURCE_PIF_WR_ADDR);
218-
219- /* write request */
220- hdmi_writel(mhdp, F_HOST_WR(1), SOURCE_PIF_WR_REQ);
221-
222- /* update entry */
223- val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
224- F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id);
225- hdmi_writel(mhdp, val, SOURCE_PIF_PKT_ALLOC_REG);
226-
227- hdmi_writel(mhdp, F_PKT_ALLOC_WR_EN(1), SOURCE_PIF_PKT_ALLOC_WR_EN);
228+ /* Line swaping */
229+ /* For imx8qm lane_mapping = 0x93
230+ * For imx8mq lane_mapping = 0xe4*/
231+ cdns_mhdp_reg_write(mhdp, LANES_CONFIG, 0x00400000 | mhdp->lane_mapping);
232 }
233
234 #define RGB_ALLOWED_COLORIMETRY (BIT(HDMI_EXTENDED_COLORIMETRY_BT2020) |\
235@@ -148,9 +78,11 @@ static int hdmi_avi_info_set(struct cdns
236 struct drm_display_mode *mode)
237 {
238 struct hdmi_avi_infoframe frame;
239-// struct drm_display_info *di = &mhdp->connector.base.display_info;
240-// enum hdmi_extended_colorimetry ext_col;
241-// u32 sink_col, allowed_col;
242+#if 0
243+ struct drm_display_info *di = &mhdp->connector.base.display_info;
244+ enum hdmi_extended_colorimetry ext_col;
245+ u32 sink_col, allowed_col;
246+#endif
247 int format = mhdp->video_info.color_fmt;
248 u8 buf[32];
249 int ret;
250@@ -209,7 +141,7 @@ static int hdmi_avi_info_set(struct cdns
251 }
252
253 buf[0] = 0;
254- hdmi_info_frame_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI);
255+ cdns_mhdp_infoframe_set(mhdp, 0, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AVI);
256 return 0;
257 }
258
259@@ -234,7 +166,7 @@ static int hdmi_vendor_info_set(struct c
260 }
261
262 buf[0] = 0;
263- hdmi_info_frame_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR);
264+ cdns_mhdp_infoframe_set(mhdp, 3, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_VENDOR);
265 return 0;
266 }
267
268@@ -464,6 +396,19 @@ static irqreturn_t cdns_hdmi_irq_thread(
269 return IRQ_HANDLED;
270 }
271
272+static void cdns_hdmi_parse_dt(struct cdns_mhdp_device *mhdp)
273+{
274+ struct device_node *of_node = mhdp->dev->of_node;
275+ int ret;
276+
277+ ret = of_property_read_u32(of_node, "lane-mapping", &mhdp->lane_mapping);
278+ if (ret) {
279+ mhdp->lane_mapping = 0xc6;
280+ dev_warn(mhdp->dev, "Failed to get lane_mapping - using default 0xc6\n");
281+ }
282+ dev_info(mhdp->dev, "lane-mapping 0x%02x\n", mhdp->lane_mapping);
283+}
284+
285 static struct imx_mhdp_device *
286 __cdns_hdmi_probe(struct platform_device *pdev,
287 const struct cdn_plat_data *plat_data)
288@@ -503,13 +448,13 @@ __cdns_hdmi_probe(struct platform_device
289
290 hdmi->irq[IRQ_IN] = platform_get_irq_byname(pdev, "plug_in");
291 if (hdmi->irq[IRQ_IN] < 0) {
292- dev_info(&pdev->dev, "No plug_in irq number\n");
293+ dev_info(dev, "No plug_in irq number\n");
294 return ERR_PTR(-EPROBE_DEFER);
295 }
296
297 hdmi->irq[IRQ_OUT] = platform_get_irq_byname(pdev, "plug_out");
298 if (hdmi->irq[IRQ_OUT] < 0) {
299- dev_info(&pdev->dev, "No plug_out irq number\n");
300+ dev_info(dev, "No plug_out irq number\n");
301 return ERR_PTR(-EPROBE_DEFER);
302 }
303
304@@ -533,7 +478,7 @@ __cdns_hdmi_probe(struct platform_device
305 IRQF_ONESHOT, dev_name(dev),
306 hdmi);
307 if (ret) {
308- dev_err(&pdev->dev, "can't claim irq %d\n",
309+ dev_err(dev, "can't claim irq %d\n",
310 hdmi->irq[IRQ_IN]);
311 goto err_out;
312 }
313@@ -544,11 +489,13 @@ __cdns_hdmi_probe(struct platform_device
314 IRQF_ONESHOT, dev_name(dev),
315 hdmi);
316 if (ret) {
317- dev_err(&pdev->dev, "can't claim irq %d\n",
318+ dev_err(dev, "can't claim irq %d\n",
319 hdmi->irq[IRQ_OUT]);
320 goto err_out;
321 }
322
323+ cdns_hdmi_parse_dt(&hdmi->mhdp);
324+
325 if (cdns_mhdp_read_hpd(&hdmi->mhdp))
326 enable_irq(hdmi->irq[IRQ_OUT]);
327 else
328@@ -557,14 +504,14 @@ __cdns_hdmi_probe(struct platform_device
329 hdmi->mhdp.bridge.base.driver_private = hdmi;
330 hdmi->mhdp.bridge.base.funcs = &cdns_hdmi_bridge_funcs;
331 #ifdef CONFIG_OF
332- hdmi->mhdp.bridge.base.of_node = pdev->dev.of_node;
333+ hdmi->mhdp.bridge.base.of_node = dev->of_node;
334 #endif
335
336 memset(&pdevinfo, 0, sizeof(pdevinfo));
337 pdevinfo.parent = dev;
338 pdevinfo.id = PLATFORM_DEVID_AUTO;
339
340- platform_set_drvdata(pdev, hdmi);
341+ dev_set_drvdata(dev, &hdmi->mhdp);
342
343 return hdmi;
344
345@@ -573,7 +520,7 @@ err_out:
346 return ERR_PTR(ret);
347 }
348
349-static void __cdns_hdmi_remove(struct imx_mhdp_device *hdmi)
350+static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp)
351 {
352 }
353
354@@ -597,11 +544,11 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_probe);
355
356 void cdns_hdmi_remove(struct platform_device *pdev)
357 {
358- struct imx_mhdp_device *hdmi = platform_get_drvdata(pdev);
359+ struct cdns_mhdp_device *mhdp = platform_get_drvdata(pdev);
360
361- drm_bridge_remove(&hdmi->mhdp.bridge.base);
362+ drm_bridge_remove(&mhdp->bridge.base);
363
364- __cdns_hdmi_remove(hdmi);
365+ __cdns_hdmi_remove(mhdp);
366 }
367 EXPORT_SYMBOL_GPL(cdns_hdmi_remove);
368
369@@ -631,9 +578,9 @@ EXPORT_SYMBOL_GPL(cdns_hdmi_bind);
370
371 void cdns_hdmi_unbind(struct device *dev)
372 {
373- struct imx_mhdp_device *hdmi = dev_get_drvdata(dev);
374+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
375
376- __cdns_hdmi_remove(hdmi);
377+ __cdns_hdmi_remove(mhdp);
378 }
379 EXPORT_SYMBOL_GPL(cdns_hdmi_unbind);
380
381--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
382+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
383@@ -23,8 +23,10 @@
384 #include <asm/unaligned.h>
385
386 #include <drm/bridge/cdns-mhdp-common.h>
387+#include <drm/bridge/cdns-mhdp-imx.h>
388 #include <drm/drm_modes.h>
389 #include <drm/drm_print.h>
390+#include <linux/regmap.h>
391
392 #define CDNS_DP_SPDIF_CLK 200000000
393 #define FW_ALIVE_TIMEOUT_US 1000000
394@@ -33,6 +35,27 @@
395 #define LINK_TRAINING_RETRY_MS 20
396 #define LINK_TRAINING_TIMEOUT_MS 500
397
398+#define mhdp_readx_poll_timeout(op, addr, offset, val, cond, sleep_us, timeout_us) \
399+({ \
400+ u64 __timeout_us = (timeout_us); \
401+ unsigned long __sleep_us = (sleep_us); \
402+ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
403+ might_sleep_if((__sleep_us) != 0); \
404+ for (;;) { \
405+ (val) = op(addr, offset); \
406+ if (cond) \
407+ break; \
408+ if (__timeout_us && \
409+ ktime_compare(ktime_get(), __timeout) > 0) { \
410+ (val) = op(addr, offset); \
411+ break; \
412+ } \
413+ if (__sleep_us) \
414+ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
415+ } \
416+ (cond) ? 0 : -ETIMEDOUT; \
417+})
418+
419 static inline u32 get_unaligned_be24(const void *p)
420 {
421 const u8 *_p = p;
422@@ -49,9 +72,51 @@ static inline void put_unaligned_be24(u3
423 _p[2] = val;
424 }
425
426+u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset)
427+{
428+ struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp);
429+ u32 val;
430+
431+ /* TODO */
432+ if (offset >= 0x1000 && hdmi->regmap_csr) {
433+ /* Remap address to low 4K memory */
434+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12);
435+ val = readl((offset & 0xfff) + mhdp->regs);
436+ /* Restore address mapping */
437+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0);
438+ } else
439+ val = readl(mhdp->regs + offset);
440+
441+ return val;
442+}
443+EXPORT_SYMBOL(cdns_mhdp_bus_read);
444+
445+void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset)
446+{
447+ struct imx_mhdp_device *hdmi = container_of(mhdp, struct imx_mhdp_device, mhdp);
448+
449+ /* TODO */
450+ if (offset >= 0x1000 && hdmi->regmap_csr) {
451+ /* Remap address to low 4K memory */
452+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, offset >> 12);
453+ writel(val, (offset & 0xfff) + mhdp->regs);
454+ /* Restore address mapping */
455+ regmap_write(hdmi->regmap_csr, hdmi->csr_ctrl0_reg, 0);
456+
457+ } else
458+ writel(val, mhdp->regs + offset);
459+}
460+EXPORT_SYMBOL(cdns_mhdp_bus_write);
461+
462+u32 cdns_mhdp_get_fw_clk(struct cdns_mhdp_device *mhdp)
463+{
464+ return cdns_mhdp_bus_read(mhdp, SW_CLK_H);
465+}
466+EXPORT_SYMBOL(cdns_mhdp_get_fw_clk);
467+
468 void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk)
469 {
470- writel(clk / 1000000, mhdp->regs + SW_CLK_H);
471+ cdns_mhdp_bus_write(clk / 1000000, mhdp, SW_CLK_H);
472 }
473 EXPORT_SYMBOL(cdns_mhdp_set_fw_clk);
474
475@@ -71,16 +136,16 @@ void cdns_mhdp_clock_reset(struct cdns_m
476 DPTX_SYS_CLK_EN |
477 CFG_DPTX_VIF_CLK_RSTN_EN |
478 CFG_DPTX_VIF_CLK_EN;
479- writel(val, mhdp->regs + SOURCE_DPTX_CAR);
480+ cdns_mhdp_bus_write(val, mhdp, SOURCE_DPTX_CAR);
481
482 val = SOURCE_PHY_RSTN_EN | SOURCE_PHY_CLK_EN;
483- writel(val, mhdp->regs + SOURCE_PHY_CAR);
484+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PHY_CAR);
485
486 val = SOURCE_PKT_SYS_RSTN_EN |
487 SOURCE_PKT_SYS_CLK_EN |
488 SOURCE_PKT_DATA_RSTN_EN |
489 SOURCE_PKT_DATA_CLK_EN;
490- writel(val, mhdp->regs + SOURCE_PKT_CAR);
491+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PKT_CAR);
492
493 val = SPDIF_CDR_CLK_RSTN_EN |
494 SPDIF_CDR_CLK_EN |
495@@ -88,20 +153,20 @@ void cdns_mhdp_clock_reset(struct cdns_m
496 SOURCE_AIF_SYS_CLK_EN |
497 SOURCE_AIF_CLK_RSTN_EN |
498 SOURCE_AIF_CLK_EN;
499- writel(val, mhdp->regs + SOURCE_AIF_CAR);
500+ cdns_mhdp_bus_write(val, mhdp, SOURCE_AIF_CAR);
501
502 val = SOURCE_CIPHER_SYSTEM_CLK_RSTN_EN |
503 SOURCE_CIPHER_SYS_CLK_EN |
504 SOURCE_CIPHER_CHAR_CLK_RSTN_EN |
505 SOURCE_CIPHER_CHAR_CLK_EN;
506- writel(val, mhdp->regs + SOURCE_CIPHER_CAR);
507+ cdns_mhdp_bus_write(val, mhdp, SOURCE_CIPHER_CAR);
508
509 val = SOURCE_CRYPTO_SYS_CLK_RSTN_EN |
510 SOURCE_CRYPTO_SYS_CLK_EN;
511- writel(val, mhdp->regs + SOURCE_CRYPTO_CAR);
512+ cdns_mhdp_bus_write(val, mhdp, SOURCE_CRYPTO_CAR);
513
514 /* enable Mailbox and PIF interrupt */
515- writel(0, mhdp->regs + APB_INT_MASK);
516+ cdns_mhdp_bus_write(0, mhdp, APB_INT_MASK);
517 }
518 EXPORT_SYMBOL(cdns_mhdp_clock_reset);
519
520@@ -109,13 +174,13 @@ int cdns_mhdp_mailbox_read(struct cdns_m
521 {
522 int val, ret;
523
524- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_EMPTY_ADDR,
525+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, MAILBOX_EMPTY_ADDR,
526 val, !val, MAILBOX_RETRY_US,
527 MAILBOX_TIMEOUT_US);
528 if (ret < 0)
529 return ret;
530
531- return readl(mhdp->regs + MAILBOX0_RD_DATA) & 0xff;
532+ return cdns_mhdp_bus_read(mhdp, MAILBOX0_RD_DATA) & 0xff;
533 }
534 EXPORT_SYMBOL(cdns_mhdp_mailbox_read);
535
536@@ -123,13 +188,13 @@ static int cdp_dp_mailbox_write(struct c
537 {
538 int ret, full;
539
540- ret = readx_poll_timeout(readl, mhdp->regs + MAILBOX_FULL_ADDR,
541+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, MAILBOX_FULL_ADDR,
542 full, !full, MAILBOX_RETRY_US,
543 MAILBOX_TIMEOUT_US);
544 if (ret < 0)
545 return ret;
546
547- writel(val, mhdp->regs + MAILBOX0_WR_DATA);
548+ cdns_mhdp_bus_write(val, mhdp, MAILBOX0_WR_DATA);
549
550 return 0;
551 }
552@@ -357,20 +422,20 @@ int cdns_mhdp_load_firmware(struct cdns_
553 int i, ret;
554
555 /* reset ucpu before load firmware*/
556- writel(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
557- mhdp->regs + APB_CTRL);
558+ cdns_mhdp_bus_write(APB_IRAM_PATH | APB_DRAM_PATH | APB_XT_RESET,
559+ mhdp, APB_CTRL);
560
561 for (i = 0; i < i_size; i += 4)
562- writel(*i_mem++, mhdp->regs + ADDR_IMEM + i);
563+ cdns_mhdp_bus_write(*i_mem++, mhdp, ADDR_IMEM + i);
564
565 for (i = 0; i < d_size; i += 4)
566- writel(*d_mem++, mhdp->regs + ADDR_DMEM + i);
567+ cdns_mhdp_bus_write(*d_mem++, mhdp, ADDR_DMEM + i);
568
569 /* un-reset ucpu */
570- writel(0, mhdp->regs + APB_CTRL);
571+ cdns_mhdp_bus_write(0, mhdp, APB_CTRL);
572
573 /* check the keep alive register to make sure fw working */
574- ret = readx_poll_timeout(readl, mhdp->regs + KEEP_ALIVE,
575+ ret = mhdp_readx_poll_timeout(cdns_mhdp_bus_read, mhdp, KEEP_ALIVE,
576 reg, reg, 2000, FW_ALIVE_TIMEOUT_US);
577 if (ret < 0) {
578 DRM_DEV_ERROR(mhdp->dev, "failed to loaded the FW reg = %x\n",
579@@ -378,13 +443,13 @@ int cdns_mhdp_load_firmware(struct cdns_
580 return -EINVAL;
581 }
582
583- reg = readl(mhdp->regs + VER_L) & 0xff;
584+ reg = cdns_mhdp_bus_read(mhdp, VER_L) & 0xff;
585 mhdp->fw_version = reg;
586- reg = readl(mhdp->regs + VER_H) & 0xff;
587+ reg = cdns_mhdp_bus_read(mhdp, VER_H) & 0xff;
588 mhdp->fw_version |= reg << 8;
589- reg = readl(mhdp->regs + VER_LIB_L_ADDR) & 0xff;
590+ reg = cdns_mhdp_bus_read(mhdp, VER_LIB_L_ADDR) & 0xff;
591 mhdp->fw_version |= reg << 16;
592- reg = readl(mhdp->regs + VER_LIB_H_ADDR) & 0xff;
593+ reg = cdns_mhdp_bus_read(mhdp, VER_LIB_H_ADDR) & 0xff;
594 mhdp->fw_version |= reg << 24;
595
596 DRM_DEV_DEBUG(mhdp->dev, "firmware version: %x\n", mhdp->fw_version);
597@@ -466,7 +531,7 @@ int cdns_mhdp_event_config(struct cdns_m
598
599 memset(msg, 0, sizeof(msg));
600
601- msg[0] = DPTX_EVENT_ENABLE_HPD | DPTX_EVENT_ENABLE_TRAINING;
602+ msg[0] = MHDP_EVENT_ENABLE_HPD | MHDP_EVENT_ENABLE_TRAINING;
603
604 ret = cdns_mhdp_mailbox_send(mhdp, MB_MODULE_ID_DP_TX,
605 DPTX_ENABLE_EVENT, sizeof(msg), msg);
606@@ -479,7 +544,7 @@ EXPORT_SYMBOL(cdns_mhdp_event_config);
607
608 u32 cdns_mhdp_get_event(struct cdns_mhdp_device *mhdp)
609 {
610- return readl(mhdp->regs + SW_EVENTS0);
611+ return cdns_mhdp_bus_read(mhdp, SW_EVENTS0);
612 }
613 EXPORT_SYMBOL(cdns_mhdp_get_event);
614
615@@ -883,24 +948,24 @@ int cdns_mhdp_audio_stop(struct cdns_mhd
616 return ret;
617 }
618
619- writel(0, mhdp->regs + SPDIF_CTRL_ADDR);
620+ cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR);
621
622 /* clearn the audio config and reset */
623- writel(0, mhdp->regs + AUDIO_SRC_CNTL);
624- writel(0, mhdp->regs + AUDIO_SRC_CNFG);
625- writel(AUDIO_SW_RST, mhdp->regs + AUDIO_SRC_CNTL);
626- writel(0, mhdp->regs + AUDIO_SRC_CNTL);
627+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
628+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG);
629+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL);
630+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
631
632 /* reset smpl2pckt component */
633- writel(0, mhdp->regs + SMPL2PKT_CNTL);
634- writel(AUDIO_SW_RST, mhdp->regs + SMPL2PKT_CNTL);
635- writel(0, mhdp->regs + SMPL2PKT_CNTL);
636+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
637+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL);
638+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
639
640 /* reset FIFO */
641- writel(AUDIO_SW_RST, mhdp->regs + FIFO_CNTL);
642- writel(0, mhdp->regs + FIFO_CNTL);
643+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL);
644+ cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL);
645
646- if (audio->format == AFMT_SPDIF)
647+ if (audio->format == AFMT_SPDIF_INT)
648 clk_disable_unprepare(mhdp->spdif_clk);
649
650 return 0;
651@@ -936,15 +1001,15 @@ static void cdns_mhdp_audio_config_i2s(s
652 i2s_port_en_val = 3;
653 }
654
655- writel(0x0, mhdp->regs + SPDIF_CTRL_ADDR);
656+ cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR);
657
658- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL);
659+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
660
661 val = MAX_NUM_CH(audio->channels);
662 val |= NUM_OF_I2S_PORTS(audio->channels);
663 val |= AUDIO_TYPE_LPCM;
664 val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
665- writel(val, mhdp->regs + SMPL2PKT_CNFG);
666+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
667
668 if (audio->sample_width == 16)
669 val = 0;
670@@ -956,7 +1021,7 @@ static void cdns_mhdp_audio_config_i2s(s
671 val |= AUDIO_CH_NUM(audio->channels);
672 val |= I2S_DEC_PORT_EN(i2s_port_en_val);
673 val |= TRANS_SMPL_WIDTH_32;
674- writel(val, mhdp->regs + AUDIO_SRC_CNFG);
675+ cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG);
676
677 for (i = 0; i < (audio->channels + 1) / 2; i++) {
678 if (audio->sample_width == 16)
679@@ -965,7 +1030,7 @@ static void cdns_mhdp_audio_config_i2s(s
680 val = (0x0b << 8) | (0x0b << 20);
681
682 val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
683- writel(val, mhdp->regs + STTS_BIT_CH(i));
684+ cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i));
685 }
686
687 switch (audio->sample_rate) {
688@@ -999,24 +1064,24 @@ static void cdns_mhdp_audio_config_i2s(s
689 break;
690 }
691 val |= 4;
692- writel(val, mhdp->regs + COM_CH_STTS_BITS);
693+ cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS);
694
695- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL);
696- writel(I2S_DEC_START, mhdp->regs + AUDIO_SRC_CNTL);
697+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
698+ cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL);
699 }
700
701 static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp)
702 {
703 u32 val;
704
705- writel(SYNC_WR_TO_CH_ZERO, mhdp->regs + FIFO_CNTL);
706+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
707
708 val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
709- writel(val, mhdp->regs + SMPL2PKT_CNFG);
710- writel(SMPL2PKT_EN, mhdp->regs + SMPL2PKT_CNTL);
711+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
712+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
713
714 val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
715- writel(val, mhdp->regs + SPDIF_CTRL_ADDR);
716+ cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR);
717
718 clk_prepare_enable(mhdp->spdif_clk);
719 clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK);
720@@ -1028,7 +1093,7 @@ int cdns_mhdp_audio_config(struct cdns_m
721 int ret;
722
723 /* reset the spdif clk before config */
724- if (audio->format == AFMT_SPDIF) {
725+ if (audio->format == AFMT_SPDIF_INT) {
726 reset_control_assert(mhdp->spdif_rst);
727 reset_control_deassert(mhdp->spdif_rst);
728 }
729@@ -1043,7 +1108,7 @@ int cdns_mhdp_audio_config(struct cdns_m
730
731 if (audio->format == AFMT_I2S)
732 cdns_mhdp_audio_config_i2s(mhdp, audio);
733- else if (audio->format == AFMT_SPDIF)
734+ else if (audio->format == AFMT_SPDIF_INT)
735 cdns_mhdp_audio_config_spdif(mhdp);
736
737 ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
738@@ -1150,12 +1215,12 @@ bool cdns_mhdp_check_alive(struct cdns_m
739 u32 alive, newalive;
740 u8 retries_left = 10;
741
742- alive = readl(mhdp->regs + KEEP_ALIVE);
743+ alive = cdns_mhdp_bus_read(mhdp, KEEP_ALIVE);
744
745 while (retries_left--) {
746 udelay(2);
747
748- newalive = readl(mhdp->regs + KEEP_ALIVE);
749+ newalive = cdns_mhdp_bus_read(mhdp, KEEP_ALIVE);
750 if (alive == newalive)
751 continue;
752 return true;
753--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c
754+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-hdmi.c
755@@ -10,6 +10,42 @@
756 #include <drm/drmP.h>
757 #include <linux/io.h>
758 #include <drm/bridge/cdns-mhdp-common.h>
759+#include <drm/bridge/cdns-mhdp-imx.h>
760+#include <linux/regmap.h>
761+
762+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp,
763+ u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type)
764+{
765+ u32 *packet32, len32;
766+ u32 val, i;
767+
768+ /* invalidate entry */
769+ val = F_ACTIVE_IDLE_TYPE(1) | F_PKT_ALLOC_ADDRESS(entry_id);
770+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PIF_PKT_ALLOC_REG);
771+ cdns_mhdp_bus_write(F_PKT_ALLOC_WR_EN(1), mhdp, SOURCE_PIF_PKT_ALLOC_WR_EN);
772+
773+ /* flush fifo 1 */
774+ cdns_mhdp_bus_write(F_FIFO1_FLUSH(1), mhdp, SOURCE_PIF_FIFO1_FLUSH);
775+
776+ /* write packet into memory */
777+ packet32 = (u32 *)packet;
778+ len32 = packet_len / 4;
779+ for (i = 0; i < len32; i++)
780+ cdns_mhdp_bus_write(F_DATA_WR(packet32[i]), mhdp, SOURCE_PIF_DATA_WR);
781+
782+ /* write entry id */
783+ cdns_mhdp_bus_write(F_WR_ADDR(entry_id), mhdp, SOURCE_PIF_WR_ADDR);
784+
785+ /* write request */
786+ cdns_mhdp_bus_write(F_HOST_WR(1), mhdp, SOURCE_PIF_WR_REQ);
787+
788+ /* update entry */
789+ val = F_ACTIVE_IDLE_TYPE(1) | F_TYPE_VALID(1) |
790+ F_PACKET_TYPE(packet_type) | F_PKT_ALLOC_ADDRESS(entry_id);
791+ cdns_mhdp_bus_write(val, mhdp, SOURCE_PIF_PKT_ALLOC_REG);
792+
793+ cdns_mhdp_bus_write(F_PKT_ALLOC_WR_EN(1), mhdp, SOURCE_PIF_PKT_ALLOC_WR_EN);
794+}
795
796 int cdns_hdmi_get_edid_block(void *data, u8 *edid,
797 u32 block, size_t length)
798--- a/include/drm/bridge/cdns-mhdp-common.h
799+++ b/include/drm/bridge/cdns-mhdp-common.h
800@@ -391,8 +391,8 @@
801 #define FW_STANDBY 0
802 #define FW_ACTIVE 1
803
804-#define DPTX_EVENT_ENABLE_HPD BIT(0)
805-#define DPTX_EVENT_ENABLE_TRAINING BIT(1)
806+#define MHDP_EVENT_ENABLE_HPD BIT(0)
807+#define MHDP_EVENT_ENABLE_TRAINING BIT(1)
808
809 #define LINK_TRAINING_NOT_ACTIVE 0
810 #define LINK_TRAINING_RUN 1
811@@ -532,7 +532,8 @@ enum vic_bt_type {
812
813 enum audio_format {
814 AFMT_I2S = 0,
815- AFMT_SPDIF = 1,
816+ AFMT_SPDIF_INT = 1,
817+ AFMT_SPDIF_EXT = 2,
818 AFMT_UNUSED,
819 };
820
821@@ -625,12 +626,13 @@ struct cdns_mhdp_device {
822 struct drm_dp_mst_topology_mgr mst_mgr;
823 struct delayed_work hotplug_work;
824
825+ u32 lane_mapping;
826 bool link_up;
827 bool power_up;
828 bool plugged;
829
830 union {
831- struct _dp_data {
832+ struct cdn_dp_data {
833 struct drm_dp_link link;
834 struct drm_dp_aux aux;
835 struct cdns_mhdp_host host;
836@@ -638,7 +640,6 @@ struct cdns_mhdp_device {
837 struct cdns_mhdp_mst_cbs cbs;
838 bool is_mst;
839 bool can_mst;
840- u32 lane_mapping;
841 u32 link_rate;
842 u32 num_lanes;
843 } dp;
844@@ -649,8 +650,11 @@ struct cdns_mhdp_device {
845 };
846 };
847
848+u32 cdns_mhdp_bus_read(struct cdns_mhdp_device *mhdp, u32 offset);
849+void cdns_mhdp_bus_write(u32 val, struct cdns_mhdp_device *mhdp, u32 offset);
850 void cdns_mhdp_clock_reset(struct cdns_mhdp_device *mhdp);
851 void cdns_mhdp_set_fw_clk(struct cdns_mhdp_device *mhdp, unsigned long clk);
852+u32 cdns_mhdp_get_fw_clk(struct cdns_mhdp_device *mhdp);
853 int cdns_mhdp_load_firmware(struct cdns_mhdp_device *mhdp, const u32 *i_mem,
854 u32 i_size, const u32 *d_mem, u32 d_size);
855 int cdns_mhdp_set_firmware_active(struct cdns_mhdp_device *mhdp, bool enable);
856@@ -691,6 +695,8 @@ int cdns_mhdp_mailbox_validate_receive(s
857 u16 req_size);
858 int cdns_mhdp_mailbox_read(struct cdns_mhdp_device *mhdp);
859
860+void cdns_mhdp_infoframe_set(struct cdns_mhdp_device *mhdp,
861+ u8 entry_id, u8 packet_len, u8 *packet, u8 packet_type);
862 int cdns_hdmi_get_edid_block(void *data, u8 *edid, u32 block, size_t length);
863 int cdns_hdmi_scdc_read(struct cdns_mhdp_device *mhdp, u8 addr, u8 *data);
864 int cdns_hdmi_scdc_write(struct cdns_mhdp_device *mhdp, u8 addr, u8 value);