This source file includes following definitions.
- dw_hdmi_is_compatible
- dw_hdmi_top_read
- dw_hdmi_g12a_top_read
- dw_hdmi_top_write
- dw_hdmi_g12a_top_write
- dw_hdmi_top_write_bits
- dw_hdmi_dwc_read
- dw_hdmi_g12a_dwc_read
- dw_hdmi_dwc_write
- dw_hdmi_g12a_dwc_write
- dw_hdmi_dwc_write_bits
- meson_hdmi_phy_setup_mode
- meson_dw_hdmi_phy_reset
- dw_hdmi_set_vclk
- dw_hdmi_phy_init
- dw_hdmi_phy_disable
- dw_hdmi_read_hpd
- dw_hdmi_setup_hpd
- dw_hdmi_top_irq
- dw_hdmi_top_thread_irq
- dw_hdmi_mode_valid
- meson_venc_hdmi_encoder_destroy
- meson_venc_hdmi_encoder_atomic_check
- meson_venc_hdmi_encoder_disable
- meson_venc_hdmi_encoder_enable
- meson_venc_hdmi_encoder_mode_set
- meson_dw_hdmi_reg_read
- meson_dw_hdmi_reg_write
- meson_hdmi_connector_is_available
- meson_dw_hdmi_bind
- meson_dw_hdmi_unbind
- meson_dw_hdmi_probe
- meson_dw_hdmi_remove
1
2
3
4
5
6
7
8 #include <linux/clk.h>
9 #include <linux/component.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/of_graph.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/reset.h>
16
17 #include <drm/bridge/dw_hdmi.h>
18 #include <drm/drm_atomic_helper.h>
19 #include <drm/drm_device.h>
20 #include <drm/drm_edid.h>
21 #include <drm/drm_probe_helper.h>
22 #include <drm/drm_print.h>
23
24 #include <linux/media-bus-format.h>
25 #include <linux/videodev2.h>
26
27 #include "meson_drv.h"
28 #include "meson_dw_hdmi.h"
29 #include "meson_registers.h"
30 #include "meson_vclk.h"
31 #include "meson_venc.h"
32
33 #define DRIVER_NAME "meson-dw-hdmi"
34 #define DRIVER_DESC "Amlogic Meson HDMI-TX DRM driver"
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 #define HDMITX_TOP_ADDR_REG 0x0
96 #define HDMITX_TOP_DATA_REG 0x4
97 #define HDMITX_TOP_CTRL_REG 0x8
98 #define HDMITX_TOP_G12A_OFFSET 0x8000
99
100
101 #define HDMITX_DWC_ADDR_REG 0x10
102 #define HDMITX_DWC_DATA_REG 0x14
103 #define HDMITX_DWC_CTRL_REG 0x18
104
105
106 #define HHI_MEM_PD_REG0 0x100
107 #define HHI_HDMI_CLK_CNTL 0x1cc
108 #define HHI_HDMI_PHY_CNTL0 0x3a0
109 #define HHI_HDMI_PHY_CNTL1 0x3a4
110 #define HHI_HDMI_PHY_CNTL2 0x3a8
111 #define HHI_HDMI_PHY_CNTL3 0x3ac
112 #define HHI_HDMI_PHY_CNTL4 0x3b0
113 #define HHI_HDMI_PHY_CNTL5 0x3b4
114
115 static DEFINE_SPINLOCK(reg_lock);
116
117 enum meson_venc_source {
118 MESON_VENC_SOURCE_NONE = 0,
119 MESON_VENC_SOURCE_ENCI = 1,
120 MESON_VENC_SOURCE_ENCP = 2,
121 };
122
123 struct meson_dw_hdmi;
124
125 struct meson_dw_hdmi_data {
126 unsigned int (*top_read)(struct meson_dw_hdmi *dw_hdmi,
127 unsigned int addr);
128 void (*top_write)(struct meson_dw_hdmi *dw_hdmi,
129 unsigned int addr, unsigned int data);
130 unsigned int (*dwc_read)(struct meson_dw_hdmi *dw_hdmi,
131 unsigned int addr);
132 void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
133 unsigned int addr, unsigned int data);
134 };
135
136 struct meson_dw_hdmi {
137 struct drm_encoder encoder;
138 struct dw_hdmi_plat_data dw_plat_data;
139 struct meson_drm *priv;
140 struct device *dev;
141 void __iomem *hdmitx;
142 const struct meson_dw_hdmi_data *data;
143 struct reset_control *hdmitx_apb;
144 struct reset_control *hdmitx_ctrl;
145 struct reset_control *hdmitx_phy;
146 struct clk *hdmi_pclk;
147 struct clk *venci_clk;
148 struct regulator *hdmi_supply;
149 u32 irq_stat;
150 struct dw_hdmi *hdmi;
151 };
152 #define encoder_to_meson_dw_hdmi(x) \
153 container_of(x, struct meson_dw_hdmi, encoder)
154
155 static inline int dw_hdmi_is_compatible(struct meson_dw_hdmi *dw_hdmi,
156 const char *compat)
157 {
158 return of_device_is_compatible(dw_hdmi->dev->of_node, compat);
159 }
160
161
162
163 static unsigned int dw_hdmi_top_read(struct meson_dw_hdmi *dw_hdmi,
164 unsigned int addr)
165 {
166 unsigned long flags;
167 unsigned int data;
168
169 spin_lock_irqsave(®_lock, flags);
170
171
172 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
173 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
174
175
176 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
177 data = readl(dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
178
179 spin_unlock_irqrestore(®_lock, flags);
180
181 return data;
182 }
183
184 static unsigned int dw_hdmi_g12a_top_read(struct meson_dw_hdmi *dw_hdmi,
185 unsigned int addr)
186 {
187 return readl(dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2));
188 }
189
190 static inline void dw_hdmi_top_write(struct meson_dw_hdmi *dw_hdmi,
191 unsigned int addr, unsigned int data)
192 {
193 unsigned long flags;
194
195 spin_lock_irqsave(®_lock, flags);
196
197
198 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
199 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_TOP_ADDR_REG);
200
201
202 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_DATA_REG);
203
204 spin_unlock_irqrestore(®_lock, flags);
205 }
206
207 static inline void dw_hdmi_g12a_top_write(struct meson_dw_hdmi *dw_hdmi,
208 unsigned int addr, unsigned int data)
209 {
210 writel(data, dw_hdmi->hdmitx + HDMITX_TOP_G12A_OFFSET + (addr << 2));
211 }
212
213
214 static inline void dw_hdmi_top_write_bits(struct meson_dw_hdmi *dw_hdmi,
215 unsigned int addr,
216 unsigned int mask,
217 unsigned int val)
218 {
219 unsigned int data = dw_hdmi->data->top_read(dw_hdmi, addr);
220
221 data &= ~mask;
222 data |= val;
223
224 dw_hdmi->data->top_write(dw_hdmi, addr, data);
225 }
226
227 static unsigned int dw_hdmi_dwc_read(struct meson_dw_hdmi *dw_hdmi,
228 unsigned int addr)
229 {
230 unsigned long flags;
231 unsigned int data;
232
233 spin_lock_irqsave(®_lock, flags);
234
235
236 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
237 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
238
239
240 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
241 data = readl(dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
242
243 spin_unlock_irqrestore(®_lock, flags);
244
245 return data;
246 }
247
248 static unsigned int dw_hdmi_g12a_dwc_read(struct meson_dw_hdmi *dw_hdmi,
249 unsigned int addr)
250 {
251 return readb(dw_hdmi->hdmitx + addr);
252 }
253
254 static inline void dw_hdmi_dwc_write(struct meson_dw_hdmi *dw_hdmi,
255 unsigned int addr, unsigned int data)
256 {
257 unsigned long flags;
258
259 spin_lock_irqsave(®_lock, flags);
260
261
262 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
263 writel(addr & 0xffff, dw_hdmi->hdmitx + HDMITX_DWC_ADDR_REG);
264
265
266 writel(data, dw_hdmi->hdmitx + HDMITX_DWC_DATA_REG);
267
268 spin_unlock_irqrestore(®_lock, flags);
269 }
270
271 static inline void dw_hdmi_g12a_dwc_write(struct meson_dw_hdmi *dw_hdmi,
272 unsigned int addr, unsigned int data)
273 {
274 writeb(data, dw_hdmi->hdmitx + addr);
275 }
276
277
278 static inline void dw_hdmi_dwc_write_bits(struct meson_dw_hdmi *dw_hdmi,
279 unsigned int addr,
280 unsigned int mask,
281 unsigned int val)
282 {
283 unsigned int data = dw_hdmi->data->dwc_read(dw_hdmi, addr);
284
285 data &= ~mask;
286 data |= val;
287
288 dw_hdmi->data->dwc_write(dw_hdmi, addr, data);
289 }
290
291
292
293
294 static void meson_hdmi_phy_setup_mode(struct meson_dw_hdmi *dw_hdmi,
295 struct drm_display_mode *mode)
296 {
297 struct meson_drm *priv = dw_hdmi->priv;
298 unsigned int pixel_clock = mode->clock;
299
300 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
301 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi")) {
302 if (pixel_clock >= 371250) {
303
304 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x333d3282);
305 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2136315b);
306 } else if (pixel_clock >= 297000) {
307
308 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303382);
309 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2036315b);
310 } else if (pixel_clock >= 148500) {
311
312 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33303362);
313 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2016315b);
314 } else {
315
316 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33604142);
317 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x0016315b);
318 }
319 } else if (dw_hdmi_is_compatible(dw_hdmi,
320 "amlogic,meson-gxbb-dw-hdmi")) {
321 if (pixel_clock >= 371250) {
322
323 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33353245);
324 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2100115b);
325 } else if (pixel_clock >= 297000) {
326
327 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33634283);
328 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0xb000115b);
329 } else {
330
331 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33632122);
332 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2000115b);
333 }
334 } else if (dw_hdmi_is_compatible(dw_hdmi,
335 "amlogic,meson-g12a-dw-hdmi")) {
336 if (pixel_clock >= 371250) {
337
338 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x37eb65c4);
339 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
340 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x0000080b);
341 } else if (pixel_clock >= 297000) {
342
343 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb6262);
344 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
345 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003);
346 } else {
347
348 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0x33eb4242);
349 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
350 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL5, 0x00000003);
351 }
352 }
353 }
354
355 static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *dw_hdmi)
356 {
357 struct meson_drm *priv = dw_hdmi->priv;
358
359
360 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xf);
361
362 mdelay(2);
363
364
365 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0xe);
366
367 mdelay(2);
368 }
369
370 static void dw_hdmi_set_vclk(struct meson_dw_hdmi *dw_hdmi,
371 struct drm_display_mode *mode)
372 {
373 struct meson_drm *priv = dw_hdmi->priv;
374 int vic = drm_match_cea_mode(mode);
375 unsigned int vclk_freq;
376 unsigned int venc_freq;
377 unsigned int hdmi_freq;
378
379 vclk_freq = mode->clock;
380
381 if (!vic) {
382 meson_vclk_setup(priv, MESON_VCLK_TARGET_DMT, vclk_freq,
383 vclk_freq, vclk_freq, false);
384 return;
385 }
386
387 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
388 vclk_freq *= 2;
389
390 venc_freq = vclk_freq;
391 hdmi_freq = vclk_freq;
392
393 if (meson_venc_hdmi_venc_repeat(vic))
394 venc_freq *= 2;
395
396 vclk_freq = max(venc_freq, hdmi_freq);
397
398 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
399 venc_freq /= 2;
400
401 DRM_DEBUG_DRIVER("vclk:%d venc=%d hdmi=%d enci=%d\n",
402 vclk_freq, venc_freq, hdmi_freq,
403 priv->venc.hdmi_use_enci);
404
405 meson_vclk_setup(priv, MESON_VCLK_TARGET_HDMI, vclk_freq,
406 venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
407 }
408
409 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
410 struct drm_display_mode *mode)
411 {
412 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
413 struct meson_drm *priv = dw_hdmi->priv;
414 unsigned int wr_clk =
415 readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING));
416
417 DRM_DEBUG_DRIVER("\"%s\" div%d\n", mode->name,
418 mode->clock > 340000 ? 40 : 10);
419
420
421 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
422
423
424 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
425
426
427 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0);
428
429
430 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
431 0x3, 0x3);
432
433
434 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
435 0x3 << 4, 0x3 << 4);
436
437
438 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
439
440
441 if (mode->clock > 340000) {
442 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
443 0);
444 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
445 0x03ff03ff);
446 } else {
447 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
448 0x001f001f);
449 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23,
450 0x001f001f);
451 }
452
453
454 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1);
455 msleep(20);
456 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2);
457
458
459 meson_hdmi_phy_setup_mode(dw_hdmi, mode);
460
461
462 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
463 0xffff << 16, 0x0390 << 16);
464
465
466 if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
467 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
468 dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
469 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
470 BIT(17), 0);
471 else
472 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
473 BIT(17), BIT(17));
474
475
476 regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
477
478 dw_hdmi_set_high_tmds_clock_ratio(hdmi);
479
480 msleep(100);
481
482
483 meson_dw_hdmi_phy_reset(dw_hdmi);
484 meson_dw_hdmi_phy_reset(dw_hdmi);
485 meson_dw_hdmi_phy_reset(dw_hdmi);
486
487
488 if (priv->venc.hdmi_use_enci)
489 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
490 else
491 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
492
493
494 writel_bits_relaxed(0x3, 0,
495 priv->io_base + _REG(VPU_HDMI_SETTING));
496 writel_bits_relaxed(0xf << 8, 0,
497 priv->io_base + _REG(VPU_HDMI_SETTING));
498
499
500 if (priv->venc.hdmi_use_enci)
501 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
502 else
503 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
504
505
506 writel_bits_relaxed(0xf << 8, wr_clk & (0xf << 8),
507 priv->io_base + _REG(VPU_HDMI_SETTING));
508
509
510 if (priv->venc.hdmi_use_enci)
511 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCI,
512 priv->io_base + _REG(VPU_HDMI_SETTING));
513 else
514 writel_bits_relaxed(0x3, MESON_VENC_SOURCE_ENCP,
515 priv->io_base + _REG(VPU_HDMI_SETTING));
516
517 return 0;
518 }
519
520 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
521 void *data)
522 {
523 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
524 struct meson_drm *priv = dw_hdmi->priv;
525
526 DRM_DEBUG_DRIVER("\n");
527
528 regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
529 }
530
531 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
532 void *data)
533 {
534 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
535
536 return !!dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_STAT0) ?
537 connector_status_connected : connector_status_disconnected;
538 }
539
540 static void dw_hdmi_setup_hpd(struct dw_hdmi *hdmi,
541 void *data)
542 {
543 struct meson_dw_hdmi *dw_hdmi = (struct meson_dw_hdmi *)data;
544
545
546 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_HPD_FILTER,
547 (0xa << 12) | 0xa0);
548
549
550 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
551 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL);
552
553
554 dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_INTR_MASKN,
555 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL,
556 HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL);
557 }
558
559 static const struct dw_hdmi_phy_ops meson_dw_hdmi_phy_ops = {
560 .init = dw_hdmi_phy_init,
561 .disable = dw_hdmi_phy_disable,
562 .read_hpd = dw_hdmi_read_hpd,
563 .setup_hpd = dw_hdmi_setup_hpd,
564 };
565
566 static irqreturn_t dw_hdmi_top_irq(int irq, void *dev_id)
567 {
568 struct meson_dw_hdmi *dw_hdmi = dev_id;
569 u32 stat;
570
571 stat = dw_hdmi->data->top_read(dw_hdmi, HDMITX_TOP_INTR_STAT);
572 dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, stat);
573
574
575 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) {
576 dw_hdmi->irq_stat = stat;
577 return IRQ_WAKE_THREAD;
578 }
579
580
581 if (stat & 1)
582 return IRQ_NONE;
583
584
585
586 return IRQ_HANDLED;
587 }
588
589
590 static irqreturn_t dw_hdmi_top_thread_irq(int irq, void *dev_id)
591 {
592 struct meson_dw_hdmi *dw_hdmi = dev_id;
593 u32 stat = dw_hdmi->irq_stat;
594
595
596 if (stat & (HDMITX_TOP_INTR_HPD_RISE | HDMITX_TOP_INTR_HPD_FALL)) {
597 bool hpd_connected = false;
598
599 if (stat & HDMITX_TOP_INTR_HPD_RISE)
600 hpd_connected = true;
601
602 dw_hdmi_setup_rx_sense(dw_hdmi->hdmi, hpd_connected,
603 hpd_connected);
604
605 drm_helper_hpd_irq_event(dw_hdmi->encoder.dev);
606 }
607
608 return IRQ_HANDLED;
609 }
610
611 static enum drm_mode_status
612 dw_hdmi_mode_valid(struct drm_connector *connector,
613 const struct drm_display_mode *mode)
614 {
615 struct meson_drm *priv = connector->dev->dev_private;
616 unsigned int vclk_freq;
617 unsigned int venc_freq;
618 unsigned int hdmi_freq;
619 int vic = drm_match_cea_mode(mode);
620 enum drm_mode_status status;
621
622 DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
623
624
625 if (connector->display_info.max_tmds_clock &&
626 mode->clock > connector->display_info.max_tmds_clock)
627 return MODE_BAD;
628
629
630 if (!vic) {
631 status = meson_venc_hdmi_supported_mode(mode);
632 if (status != MODE_OK)
633 return status;
634
635 return meson_vclk_dmt_supported_freq(priv, mode->clock);
636
637 } else if (!meson_venc_hdmi_supported_vic(vic))
638 return MODE_BAD;
639
640 vclk_freq = mode->clock;
641
642
643 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
644 vclk_freq *= 2;
645
646 venc_freq = vclk_freq;
647 hdmi_freq = vclk_freq;
648
649
650 if (meson_venc_hdmi_venc_repeat(vic))
651 venc_freq *= 2;
652
653 vclk_freq = max(venc_freq, hdmi_freq);
654
655 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
656 venc_freq /= 2;
657
658 dev_dbg(connector->dev->dev, "%s: vclk:%d venc=%d hdmi=%d\n", __func__,
659 vclk_freq, venc_freq, hdmi_freq);
660
661 return meson_vclk_vic_supported_freq(vclk_freq);
662 }
663
664
665
666 static void meson_venc_hdmi_encoder_destroy(struct drm_encoder *encoder)
667 {
668 drm_encoder_cleanup(encoder);
669 }
670
671 static const struct drm_encoder_funcs meson_venc_hdmi_encoder_funcs = {
672 .destroy = meson_venc_hdmi_encoder_destroy,
673 };
674
675 static int meson_venc_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
676 struct drm_crtc_state *crtc_state,
677 struct drm_connector_state *conn_state)
678 {
679 return 0;
680 }
681
682 static void meson_venc_hdmi_encoder_disable(struct drm_encoder *encoder)
683 {
684 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
685 struct meson_drm *priv = dw_hdmi->priv;
686
687 DRM_DEBUG_DRIVER("\n");
688
689 writel_bits_relaxed(0x3, 0,
690 priv->io_base + _REG(VPU_HDMI_SETTING));
691
692 writel_relaxed(0, priv->io_base + _REG(ENCI_VIDEO_EN));
693 writel_relaxed(0, priv->io_base + _REG(ENCP_VIDEO_EN));
694 }
695
696 static void meson_venc_hdmi_encoder_enable(struct drm_encoder *encoder)
697 {
698 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
699 struct meson_drm *priv = dw_hdmi->priv;
700
701 DRM_DEBUG_DRIVER("%s\n", priv->venc.hdmi_use_enci ? "VENCI" : "VENCP");
702
703 if (priv->venc.hdmi_use_enci)
704 writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
705 else
706 writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
707 }
708
709 static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder,
710 struct drm_display_mode *mode,
711 struct drm_display_mode *adjusted_mode)
712 {
713 struct meson_dw_hdmi *dw_hdmi = encoder_to_meson_dw_hdmi(encoder);
714 struct meson_drm *priv = dw_hdmi->priv;
715 int vic = drm_match_cea_mode(mode);
716
717 DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic);
718
719
720 meson_venc_hdmi_mode_set(priv, vic, mode);
721
722
723 dw_hdmi_set_vclk(dw_hdmi, mode);
724
725
726 writel_relaxed(0, priv->io_base + _REG(VPU_HDMI_FMT_CTRL));
727 }
728
729 static const struct drm_encoder_helper_funcs
730 meson_venc_hdmi_encoder_helper_funcs = {
731 .atomic_check = meson_venc_hdmi_encoder_atomic_check,
732 .disable = meson_venc_hdmi_encoder_disable,
733 .enable = meson_venc_hdmi_encoder_enable,
734 .mode_set = meson_venc_hdmi_encoder_mode_set,
735 };
736
737
738
739 static int meson_dw_hdmi_reg_read(void *context, unsigned int reg,
740 unsigned int *result)
741 {
742 struct meson_dw_hdmi *dw_hdmi = context;
743
744 *result = dw_hdmi->data->dwc_read(dw_hdmi, reg);
745
746 return 0;
747
748 }
749
750 static int meson_dw_hdmi_reg_write(void *context, unsigned int reg,
751 unsigned int val)
752 {
753 struct meson_dw_hdmi *dw_hdmi = context;
754
755 dw_hdmi->data->dwc_write(dw_hdmi, reg, val);
756
757 return 0;
758 }
759
760 static const struct regmap_config meson_dw_hdmi_regmap_config = {
761 .reg_bits = 32,
762 .val_bits = 8,
763 .reg_read = meson_dw_hdmi_reg_read,
764 .reg_write = meson_dw_hdmi_reg_write,
765 .max_register = 0x10000,
766 .fast_io = true,
767 };
768
769 static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
770 .top_read = dw_hdmi_top_read,
771 .top_write = dw_hdmi_top_write,
772 .dwc_read = dw_hdmi_dwc_read,
773 .dwc_write = dw_hdmi_dwc_write,
774 };
775
776 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
777 .top_read = dw_hdmi_g12a_top_read,
778 .top_write = dw_hdmi_g12a_top_write,
779 .dwc_read = dw_hdmi_g12a_dwc_read,
780 .dwc_write = dw_hdmi_g12a_dwc_write,
781 };
782
783 static bool meson_hdmi_connector_is_available(struct device *dev)
784 {
785 struct device_node *ep, *remote;
786
787
788 ep = of_graph_get_endpoint_by_regs(dev->of_node, 1, 0);
789 if (!ep)
790 return false;
791
792
793 remote = of_graph_get_remote_port(ep);
794 if (remote) {
795 of_node_put(ep);
796 return true;
797 }
798
799 of_node_put(ep);
800 of_node_put(remote);
801
802 return false;
803 }
804
805 static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
806 void *data)
807 {
808 struct platform_device *pdev = to_platform_device(dev);
809 const struct meson_dw_hdmi_data *match;
810 struct meson_dw_hdmi *meson_dw_hdmi;
811 struct drm_device *drm = data;
812 struct meson_drm *priv = drm->dev_private;
813 struct dw_hdmi_plat_data *dw_plat_data;
814 struct drm_encoder *encoder;
815 struct resource *res;
816 int irq;
817 int ret;
818
819 DRM_DEBUG_DRIVER("\n");
820
821 if (!meson_hdmi_connector_is_available(dev)) {
822 dev_info(drm->dev, "HDMI Output connector not available\n");
823 return -ENODEV;
824 }
825
826 match = of_device_get_match_data(&pdev->dev);
827 if (!match) {
828 dev_err(&pdev->dev, "failed to get match data\n");
829 return -ENODEV;
830 }
831
832 meson_dw_hdmi = devm_kzalloc(dev, sizeof(*meson_dw_hdmi),
833 GFP_KERNEL);
834 if (!meson_dw_hdmi)
835 return -ENOMEM;
836
837 meson_dw_hdmi->priv = priv;
838 meson_dw_hdmi->dev = dev;
839 meson_dw_hdmi->data = match;
840 dw_plat_data = &meson_dw_hdmi->dw_plat_data;
841 encoder = &meson_dw_hdmi->encoder;
842
843 meson_dw_hdmi->hdmi_supply = devm_regulator_get_optional(dev, "hdmi");
844 if (IS_ERR(meson_dw_hdmi->hdmi_supply)) {
845 if (PTR_ERR(meson_dw_hdmi->hdmi_supply) == -EPROBE_DEFER)
846 return -EPROBE_DEFER;
847 meson_dw_hdmi->hdmi_supply = NULL;
848 } else {
849 ret = regulator_enable(meson_dw_hdmi->hdmi_supply);
850 if (ret)
851 return ret;
852 }
853
854 meson_dw_hdmi->hdmitx_apb = devm_reset_control_get_exclusive(dev,
855 "hdmitx_apb");
856 if (IS_ERR(meson_dw_hdmi->hdmitx_apb)) {
857 dev_err(dev, "Failed to get hdmitx_apb reset\n");
858 return PTR_ERR(meson_dw_hdmi->hdmitx_apb);
859 }
860
861 meson_dw_hdmi->hdmitx_ctrl = devm_reset_control_get_exclusive(dev,
862 "hdmitx");
863 if (IS_ERR(meson_dw_hdmi->hdmitx_ctrl)) {
864 dev_err(dev, "Failed to get hdmitx reset\n");
865 return PTR_ERR(meson_dw_hdmi->hdmitx_ctrl);
866 }
867
868 meson_dw_hdmi->hdmitx_phy = devm_reset_control_get_exclusive(dev,
869 "hdmitx_phy");
870 if (IS_ERR(meson_dw_hdmi->hdmitx_phy)) {
871 dev_err(dev, "Failed to get hdmitx_phy reset\n");
872 return PTR_ERR(meson_dw_hdmi->hdmitx_phy);
873 }
874
875 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
876 meson_dw_hdmi->hdmitx = devm_ioremap_resource(dev, res);
877 if (IS_ERR(meson_dw_hdmi->hdmitx))
878 return PTR_ERR(meson_dw_hdmi->hdmitx);
879
880 meson_dw_hdmi->hdmi_pclk = devm_clk_get(dev, "isfr");
881 if (IS_ERR(meson_dw_hdmi->hdmi_pclk)) {
882 dev_err(dev, "Unable to get HDMI pclk\n");
883 return PTR_ERR(meson_dw_hdmi->hdmi_pclk);
884 }
885 clk_prepare_enable(meson_dw_hdmi->hdmi_pclk);
886
887 meson_dw_hdmi->venci_clk = devm_clk_get(dev, "venci");
888 if (IS_ERR(meson_dw_hdmi->venci_clk)) {
889 dev_err(dev, "Unable to get venci clk\n");
890 return PTR_ERR(meson_dw_hdmi->venci_clk);
891 }
892 clk_prepare_enable(meson_dw_hdmi->venci_clk);
893
894 dw_plat_data->regm = devm_regmap_init(dev, NULL, meson_dw_hdmi,
895 &meson_dw_hdmi_regmap_config);
896 if (IS_ERR(dw_plat_data->regm))
897 return PTR_ERR(dw_plat_data->regm);
898
899 irq = platform_get_irq(pdev, 0);
900 if (irq < 0) {
901 dev_err(dev, "Failed to get hdmi top irq\n");
902 return irq;
903 }
904
905 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq,
906 dw_hdmi_top_thread_irq, IRQF_SHARED,
907 "dw_hdmi_top_irq", meson_dw_hdmi);
908 if (ret) {
909 dev_err(dev, "Failed to request hdmi top irq\n");
910 return ret;
911 }
912
913
914
915 drm_encoder_helper_add(encoder, &meson_venc_hdmi_encoder_helper_funcs);
916
917 ret = drm_encoder_init(drm, encoder, &meson_venc_hdmi_encoder_funcs,
918 DRM_MODE_ENCODER_TMDS, "meson_hdmi");
919 if (ret) {
920 dev_err(priv->dev, "Failed to init HDMI encoder\n");
921 return ret;
922 }
923
924 encoder->possible_crtcs = BIT(0);
925
926 DRM_DEBUG_DRIVER("encoder initialized\n");
927
928
929 regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
930
931
932 regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
933
934
935 reset_control_reset(meson_dw_hdmi->hdmitx_apb);
936 reset_control_reset(meson_dw_hdmi->hdmitx_ctrl);
937 reset_control_reset(meson_dw_hdmi->hdmitx_phy);
938
939
940 if (!meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
941 writel_bits_relaxed(BIT(15), BIT(15),
942 meson_dw_hdmi->hdmitx + HDMITX_TOP_CTRL_REG);
943 writel_bits_relaxed(BIT(15), BIT(15),
944 meson_dw_hdmi->hdmitx + HDMITX_DWC_CTRL_REG);
945 }
946
947
948 meson_dw_hdmi->data->top_write(meson_dw_hdmi,
949 HDMITX_TOP_SW_RESET, 0);
950
951 msleep(20);
952
953 meson_dw_hdmi->data->top_write(meson_dw_hdmi,
954 HDMITX_TOP_CLK_CNTL, 0xff);
955
956
957 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
958 HDMITX_TOP_INTR_CORE);
959
960 meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_MASKN,
961 HDMITX_TOP_INTR_CORE);
962
963
964
965 dw_plat_data->mode_valid = dw_hdmi_mode_valid;
966 dw_plat_data->phy_ops = &meson_dw_hdmi_phy_ops;
967 dw_plat_data->phy_name = "meson_dw_hdmi_phy";
968 dw_plat_data->phy_data = meson_dw_hdmi;
969 dw_plat_data->input_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
970 dw_plat_data->input_bus_encoding = V4L2_YCBCR_ENC_709;
971
972 platform_set_drvdata(pdev, meson_dw_hdmi);
973
974 meson_dw_hdmi->hdmi = dw_hdmi_bind(pdev, encoder,
975 &meson_dw_hdmi->dw_plat_data);
976 if (IS_ERR(meson_dw_hdmi->hdmi))
977 return PTR_ERR(meson_dw_hdmi->hdmi);
978
979 DRM_DEBUG_DRIVER("HDMI controller initialized\n");
980
981 return 0;
982 }
983
984 static void meson_dw_hdmi_unbind(struct device *dev, struct device *master,
985 void *data)
986 {
987 struct meson_dw_hdmi *meson_dw_hdmi = dev_get_drvdata(dev);
988
989 dw_hdmi_unbind(meson_dw_hdmi->hdmi);
990 }
991
992 static const struct component_ops meson_dw_hdmi_ops = {
993 .bind = meson_dw_hdmi_bind,
994 .unbind = meson_dw_hdmi_unbind,
995 };
996
997 static int meson_dw_hdmi_probe(struct platform_device *pdev)
998 {
999 return component_add(&pdev->dev, &meson_dw_hdmi_ops);
1000 }
1001
1002 static int meson_dw_hdmi_remove(struct platform_device *pdev)
1003 {
1004 component_del(&pdev->dev, &meson_dw_hdmi_ops);
1005
1006 return 0;
1007 }
1008
1009 static const struct of_device_id meson_dw_hdmi_of_table[] = {
1010 { .compatible = "amlogic,meson-gxbb-dw-hdmi",
1011 .data = &meson_dw_hdmi_gx_data },
1012 { .compatible = "amlogic,meson-gxl-dw-hdmi",
1013 .data = &meson_dw_hdmi_gx_data },
1014 { .compatible = "amlogic,meson-gxm-dw-hdmi",
1015 .data = &meson_dw_hdmi_gx_data },
1016 { .compatible = "amlogic,meson-g12a-dw-hdmi",
1017 .data = &meson_dw_hdmi_g12a_data },
1018 { }
1019 };
1020 MODULE_DEVICE_TABLE(of, meson_dw_hdmi_of_table);
1021
1022 static struct platform_driver meson_dw_hdmi_platform_driver = {
1023 .probe = meson_dw_hdmi_probe,
1024 .remove = meson_dw_hdmi_remove,
1025 .driver = {
1026 .name = DRIVER_NAME,
1027 .of_match_table = meson_dw_hdmi_of_table,
1028 },
1029 };
1030 module_platform_driver(meson_dw_hdmi_platform_driver);
1031
1032 MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
1033 MODULE_DESCRIPTION(DRIVER_DESC);
1034 MODULE_LICENSE("GPL");