1
2
3
4
5
6
7
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/err.h>
12#include <linux/hdmi.h>
13#include <linux/irq.h>
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/of_device.h>
17#include <linux/pinctrl/consumer.h>
18#include <linux/regmap.h>
19#include <linux/dma-mapping.h>
20#include <linux/spinlock.h>
21
22#include <media/cec-notifier.h>
23
24#include <uapi/linux/media-bus-format.h>
25#include <uapi/linux/videodev2.h>
26
27#include <drm/bridge/dw_hdmi.h>
28#include <drm/drm_atomic_helper.h>
29#include <drm/drm_edid.h>
30#include <drm/drm_encoder_slave.h>
31#include <drm/drm_of.h>
32#include <drm/drm_print.h>
33#include <drm/drm_probe_helper.h>
34#include <drm/drm_scdc_helper.h>
35
36#include "dw-hdmi-audio.h"
37#include "dw-hdmi-cec.h"
38#include "dw-hdmi.h"
39
40#define DDC_SEGMENT_ADDR 0x30
41
42#define HDMI_EDID_LEN 512
43
44
45#define SCDC_MIN_SOURCE_VERSION 0x1
46
47#define HDMI14_MAX_TMDSCLK 340000000
48
49enum hdmi_datamap {
50 RGB444_8B = 0x01,
51 RGB444_10B = 0x03,
52 RGB444_12B = 0x05,
53 RGB444_16B = 0x07,
54 YCbCr444_8B = 0x09,
55 YCbCr444_10B = 0x0B,
56 YCbCr444_12B = 0x0D,
57 YCbCr444_16B = 0x0F,
58 YCbCr422_8B = 0x16,
59 YCbCr422_10B = 0x14,
60 YCbCr422_12B = 0x12,
61};
62
63static const u16 csc_coeff_default[3][4] = {
64 { 0x2000, 0x0000, 0x0000, 0x0000 },
65 { 0x0000, 0x2000, 0x0000, 0x0000 },
66 { 0x0000, 0x0000, 0x2000, 0x0000 }
67};
68
69static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
70 { 0x2000, 0x6926, 0x74fd, 0x010e },
71 { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
72 { 0x2000, 0x0000, 0x38b4, 0x7e3b }
73};
74
75static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
76 { 0x2000, 0x7106, 0x7a02, 0x00a7 },
77 { 0x2000, 0x3264, 0x0000, 0x7e6d },
78 { 0x2000, 0x0000, 0x3b61, 0x7e25 }
79};
80
81static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
82 { 0x2591, 0x1322, 0x074b, 0x0000 },
83 { 0x6535, 0x2000, 0x7acc, 0x0200 },
84 { 0x6acd, 0x7534, 0x2000, 0x0200 }
85};
86
87static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
88 { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
89 { 0x62f0, 0x2000, 0x7d11, 0x0200 },
90 { 0x6756, 0x78ab, 0x2000, 0x0200 }
91};
92
93struct hdmi_vmode {
94 bool mdataenablepolarity;
95
96 unsigned int mpixelclock;
97 unsigned int mpixelrepetitioninput;
98 unsigned int mpixelrepetitionoutput;
99 unsigned int mtmdsclock;
100};
101
102struct hdmi_data_info {
103 unsigned int enc_in_bus_format;
104 unsigned int enc_out_bus_format;
105 unsigned int enc_in_encoding;
106 unsigned int enc_out_encoding;
107 unsigned int pix_repet_factor;
108 unsigned int hdcp_enable;
109 struct hdmi_vmode video_mode;
110};
111
112struct dw_hdmi_i2c {
113 struct i2c_adapter adap;
114
115 struct mutex lock;
116 struct completion cmp;
117 u8 stat;
118
119 u8 slave_reg;
120 bool is_regaddr;
121 bool is_segment;
122};
123
124struct dw_hdmi_phy_data {
125 enum dw_hdmi_phy_type type;
126 const char *name;
127 unsigned int gen;
128 bool has_svsret;
129 int (*configure)(struct dw_hdmi *hdmi,
130 const struct dw_hdmi_plat_data *pdata,
131 unsigned long mpixelclock);
132};
133
134struct dw_hdmi {
135 struct drm_connector connector;
136 struct drm_bridge bridge;
137
138 unsigned int version;
139
140 struct platform_device *audio;
141 struct platform_device *cec;
142 struct device *dev;
143 struct clk *isfr_clk;
144 struct clk *iahb_clk;
145 struct clk *cec_clk;
146 struct dw_hdmi_i2c *i2c;
147
148 struct hdmi_data_info hdmi_data;
149 const struct dw_hdmi_plat_data *plat_data;
150
151 int vic;
152
153 u8 edid[HDMI_EDID_LEN];
154
155 struct {
156 const struct dw_hdmi_phy_ops *ops;
157 const char *name;
158 void *data;
159 bool enabled;
160 } phy;
161
162 struct drm_display_mode previous_mode;
163
164 struct i2c_adapter *ddc;
165 void __iomem *regs;
166 bool sink_is_hdmi;
167 bool sink_has_audio;
168
169 struct pinctrl *pinctrl;
170 struct pinctrl_state *default_state;
171 struct pinctrl_state *unwedge_state;
172
173 struct mutex mutex;
174 enum drm_connector_force force;
175 bool disabled;
176 bool bridge_is_on;
177 bool rxsense;
178 u8 phy_mask;
179 u8 mc_clkdis;
180
181 spinlock_t audio_lock;
182 struct mutex audio_mutex;
183 unsigned int sample_rate;
184 unsigned int audio_cts;
185 unsigned int audio_n;
186 bool audio_enable;
187
188 unsigned int reg_shift;
189 struct regmap *regm;
190 void (*enable_audio)(struct dw_hdmi *hdmi);
191 void (*disable_audio)(struct dw_hdmi *hdmi);
192
193 struct cec_notifier *cec_notifier;
194};
195
196#define HDMI_IH_PHY_STAT0_RX_SENSE \
197 (HDMI_IH_PHY_STAT0_RX_SENSE0 | HDMI_IH_PHY_STAT0_RX_SENSE1 | \
198 HDMI_IH_PHY_STAT0_RX_SENSE2 | HDMI_IH_PHY_STAT0_RX_SENSE3)
199
200#define HDMI_PHY_RX_SENSE \
201 (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 | \
202 HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3)
203
204static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset)
205{
206 regmap_write(hdmi->regm, offset << hdmi->reg_shift, val);
207}
208
209static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset)
210{
211 unsigned int val = 0;
212
213 regmap_read(hdmi->regm, offset << hdmi->reg_shift, &val);
214
215 return val;
216}
217
218static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
219{
220 regmap_update_bits(hdmi->regm, reg << hdmi->reg_shift, mask, data);
221}
222
223static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg,
224 u8 shift, u8 mask)
225{
226 hdmi_modb(hdmi, data << shift, mask, reg);
227}
228
229static void dw_hdmi_i2c_init(struct dw_hdmi *hdmi)
230{
231 hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
232 HDMI_PHY_I2CM_INT_ADDR);
233
234 hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
235 HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
236 HDMI_PHY_I2CM_CTLINT_ADDR);
237
238
239 hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ);
240
241
242 hdmi_writeb(hdmi, 0x00, HDMI_I2CM_DIV);
243
244
245 hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT);
246 hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | HDMI_I2CM_CTLINT_ARB_POL,
247 HDMI_I2CM_CTLINT);
248
249
250 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
251 HDMI_IH_I2CM_STAT0);
252
253
254 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
255 HDMI_IH_MUTE_I2CM_STAT0);
256}
257
258static bool dw_hdmi_i2c_unwedge(struct dw_hdmi *hdmi)
259{
260
261 if (!hdmi->unwedge_state)
262 return false;
263
264 dev_info(hdmi->dev, "Attempting to unwedge stuck i2c bus\n");
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298 pinctrl_select_state(hdmi->pinctrl, hdmi->unwedge_state);
299 msleep(10);
300 pinctrl_select_state(hdmi->pinctrl, hdmi->default_state);
301
302 return true;
303}
304
305static int dw_hdmi_i2c_wait(struct dw_hdmi *hdmi)
306{
307 struct dw_hdmi_i2c *i2c = hdmi->i2c;
308 int stat;
309
310 stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
311 if (!stat) {
312
313 if (!dw_hdmi_i2c_unwedge(hdmi))
314 return -EAGAIN;
315
316
317 stat = wait_for_completion_timeout(&i2c->cmp, HZ / 10);
318 if (!stat)
319 return -EAGAIN;
320 }
321
322
323 if (i2c->stat & HDMI_IH_I2CM_STAT0_ERROR)
324 return -EIO;
325
326 return 0;
327}
328
329static int dw_hdmi_i2c_read(struct dw_hdmi *hdmi,
330 unsigned char *buf, unsigned int length)
331{
332 struct dw_hdmi_i2c *i2c = hdmi->i2c;
333 int ret;
334
335 if (!i2c->is_regaddr) {
336 dev_dbg(hdmi->dev, "set read register address to 0\n");
337 i2c->slave_reg = 0x00;
338 i2c->is_regaddr = true;
339 }
340
341 while (length--) {
342 reinit_completion(&i2c->cmp);
343
344 hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
345 if (i2c->is_segment)
346 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT,
347 HDMI_I2CM_OPERATION);
348 else
349 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
350 HDMI_I2CM_OPERATION);
351
352 ret = dw_hdmi_i2c_wait(hdmi);
353 if (ret)
354 return ret;
355
356 *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
357 }
358 i2c->is_segment = false;
359
360 return 0;
361}
362
363static int dw_hdmi_i2c_write(struct dw_hdmi *hdmi,
364 unsigned char *buf, unsigned int length)
365{
366 struct dw_hdmi_i2c *i2c = hdmi->i2c;
367 int ret;
368
369 if (!i2c->is_regaddr) {
370
371 i2c->slave_reg = buf[0];
372 length--;
373 buf++;
374 i2c->is_regaddr = true;
375 }
376
377 while (length--) {
378 reinit_completion(&i2c->cmp);
379
380 hdmi_writeb(hdmi, *buf++, HDMI_I2CM_DATAO);
381 hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
382 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE,
383 HDMI_I2CM_OPERATION);
384
385 ret = dw_hdmi_i2c_wait(hdmi);
386 if (ret)
387 return ret;
388 }
389
390 return 0;
391}
392
393static int dw_hdmi_i2c_xfer(struct i2c_adapter *adap,
394 struct i2c_msg *msgs, int num)
395{
396 struct dw_hdmi *hdmi = i2c_get_adapdata(adap);
397 struct dw_hdmi_i2c *i2c = hdmi->i2c;
398 u8 addr = msgs[0].addr;
399 int i, ret = 0;
400
401 dev_dbg(hdmi->dev, "xfer: num: %d, addr: %#x\n", num, addr);
402
403 for (i = 0; i < num; i++) {
404 if (msgs[i].len == 0) {
405 dev_dbg(hdmi->dev,
406 "unsupported transfer %d/%d, no data\n",
407 i + 1, num);
408 return -EOPNOTSUPP;
409 }
410 }
411
412 mutex_lock(&i2c->lock);
413
414
415 hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0);
416
417
418 hdmi_writeb(hdmi, addr, HDMI_I2CM_SLAVE);
419
420
421 i2c->is_regaddr = false;
422
423
424 i2c->is_segment = false;
425
426 for (i = 0; i < num; i++) {
427 dev_dbg(hdmi->dev, "xfer: num: %d/%d, len: %d, flags: %#x\n",
428 i + 1, num, msgs[i].len, msgs[i].flags);
429 if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) {
430 i2c->is_segment = true;
431 hdmi_writeb(hdmi, DDC_SEGMENT_ADDR, HDMI_I2CM_SEGADDR);
432 hdmi_writeb(hdmi, *msgs[i].buf, HDMI_I2CM_SEGPTR);
433 } else {
434 if (msgs[i].flags & I2C_M_RD)
435 ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf,
436 msgs[i].len);
437 else
438 ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf,
439 msgs[i].len);
440 }
441 if (ret < 0)
442 break;
443 }
444
445 if (!ret)
446 ret = num;
447
448
449 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0_ERROR | HDMI_IH_I2CM_STAT0_DONE,
450 HDMI_IH_MUTE_I2CM_STAT0);
451
452 mutex_unlock(&i2c->lock);
453
454 return ret;
455}
456
457static u32 dw_hdmi_i2c_func(struct i2c_adapter *adapter)
458{
459 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
460}
461
462static const struct i2c_algorithm dw_hdmi_algorithm = {
463 .master_xfer = dw_hdmi_i2c_xfer,
464 .functionality = dw_hdmi_i2c_func,
465};
466
467static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
468{
469 struct i2c_adapter *adap;
470 struct dw_hdmi_i2c *i2c;
471 int ret;
472
473 i2c = devm_kzalloc(hdmi->dev, sizeof(*i2c), GFP_KERNEL);
474 if (!i2c)
475 return ERR_PTR(-ENOMEM);
476
477 mutex_init(&i2c->lock);
478 init_completion(&i2c->cmp);
479
480 adap = &i2c->adap;
481 adap->class = I2C_CLASS_DDC;
482 adap->owner = THIS_MODULE;
483 adap->dev.parent = hdmi->dev;
484 adap->algo = &dw_hdmi_algorithm;
485 strlcpy(adap->name, "DesignWare HDMI", sizeof(adap->name));
486 i2c_set_adapdata(adap, hdmi);
487
488 ret = i2c_add_adapter(adap);
489 if (ret) {
490 dev_warn(hdmi->dev, "cannot add %s I2C adapter\n", adap->name);
491 devm_kfree(hdmi->dev, i2c);
492 return ERR_PTR(ret);
493 }
494
495 hdmi->i2c = i2c;
496
497 dev_info(hdmi->dev, "registered %s I2C bus driver\n", adap->name);
498
499 return adap;
500}
501
502static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
503 unsigned int n)
504{
505
506 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
507
508
509 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
510
511 hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
512 HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
513 hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
514 hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
515
516 hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3);
517 hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
518 hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
519}
520
521static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
522{
523 unsigned int n = (128 * freq) / 1000;
524 unsigned int mult = 1;
525
526 while (freq > 48000) {
527 mult *= 2;
528 freq /= 2;
529 }
530
531 switch (freq) {
532 case 32000:
533 if (pixel_clk == 25175000)
534 n = 4576;
535 else if (pixel_clk == 27027000)
536 n = 4096;
537 else if (pixel_clk == 74176000 || pixel_clk == 148352000)
538 n = 11648;
539 else
540 n = 4096;
541 n *= mult;
542 break;
543
544 case 44100:
545 if (pixel_clk == 25175000)
546 n = 7007;
547 else if (pixel_clk == 74176000)
548 n = 17836;
549 else if (pixel_clk == 148352000)
550 n = 8918;
551 else
552 n = 6272;
553 n *= mult;
554 break;
555
556 case 48000:
557 if (pixel_clk == 25175000)
558 n = 6864;
559 else if (pixel_clk == 27027000)
560 n = 6144;
561 else if (pixel_clk == 74176000)
562 n = 11648;
563 else if (pixel_clk == 148352000)
564 n = 5824;
565 else
566 n = 6144;
567 n *= mult;
568 break;
569
570 default:
571 break;
572 }
573
574 return n;
575}
576
577static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
578 unsigned long pixel_clk, unsigned int sample_rate)
579{
580 unsigned long ftdms = pixel_clk;
581 unsigned int n, cts;
582 u64 tmp;
583
584 n = hdmi_compute_n(sample_rate, pixel_clk);
585
586
587
588
589
590
591
592
593 tmp = (u64)ftdms * n;
594 do_div(tmp, 128 * sample_rate);
595 cts = tmp;
596
597 dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
598 __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
599 n, cts);
600
601 spin_lock_irq(&hdmi->audio_lock);
602 hdmi->audio_n = n;
603 hdmi->audio_cts = cts;
604 hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0);
605 spin_unlock_irq(&hdmi->audio_lock);
606}
607
608static void hdmi_init_clk_regenerator(struct dw_hdmi *hdmi)
609{
610 mutex_lock(&hdmi->audio_mutex);
611 hdmi_set_clk_regenerator(hdmi, 74250000, hdmi->sample_rate);
612 mutex_unlock(&hdmi->audio_mutex);
613}
614
615static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi)
616{
617 mutex_lock(&hdmi->audio_mutex);
618 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
619 hdmi->sample_rate);
620 mutex_unlock(&hdmi->audio_mutex);
621}
622
623void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
624{
625 mutex_lock(&hdmi->audio_mutex);
626 hdmi->sample_rate = rate;
627 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mtmdsclock,
628 hdmi->sample_rate);
629 mutex_unlock(&hdmi->audio_mutex);
630}
631EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
632
633static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
634{
635 if (enable)
636 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
637 else
638 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_AUDCLK_DISABLE;
639 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
640}
641
642static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi)
643{
644 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
645}
646
647static void dw_hdmi_ahb_audio_disable(struct dw_hdmi *hdmi)
648{
649 hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0);
650}
651
652static void dw_hdmi_i2s_audio_enable(struct dw_hdmi *hdmi)
653{
654 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n);
655 hdmi_enable_audio_clk(hdmi, true);
656}
657
658static void dw_hdmi_i2s_audio_disable(struct dw_hdmi *hdmi)
659{
660 hdmi_enable_audio_clk(hdmi, false);
661}
662
663void dw_hdmi_audio_enable(struct dw_hdmi *hdmi)
664{
665 unsigned long flags;
666
667 spin_lock_irqsave(&hdmi->audio_lock, flags);
668 hdmi->audio_enable = true;
669 if (hdmi->enable_audio)
670 hdmi->enable_audio(hdmi);
671 spin_unlock_irqrestore(&hdmi->audio_lock, flags);
672}
673EXPORT_SYMBOL_GPL(dw_hdmi_audio_enable);
674
675void dw_hdmi_audio_disable(struct dw_hdmi *hdmi)
676{
677 unsigned long flags;
678
679 spin_lock_irqsave(&hdmi->audio_lock, flags);
680 hdmi->audio_enable = false;
681 if (hdmi->disable_audio)
682 hdmi->disable_audio(hdmi);
683 spin_unlock_irqrestore(&hdmi->audio_lock, flags);
684}
685EXPORT_SYMBOL_GPL(dw_hdmi_audio_disable);
686
687static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
688{
689 switch (bus_format) {
690 case MEDIA_BUS_FMT_RGB888_1X24:
691 case MEDIA_BUS_FMT_RGB101010_1X30:
692 case MEDIA_BUS_FMT_RGB121212_1X36:
693 case MEDIA_BUS_FMT_RGB161616_1X48:
694 return true;
695
696 default:
697 return false;
698 }
699}
700
701static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
702{
703 switch (bus_format) {
704 case MEDIA_BUS_FMT_YUV8_1X24:
705 case MEDIA_BUS_FMT_YUV10_1X30:
706 case MEDIA_BUS_FMT_YUV12_1X36:
707 case MEDIA_BUS_FMT_YUV16_1X48:
708 return true;
709
710 default:
711 return false;
712 }
713}
714
715static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
716{
717 switch (bus_format) {
718 case MEDIA_BUS_FMT_UYVY8_1X16:
719 case MEDIA_BUS_FMT_UYVY10_1X20:
720 case MEDIA_BUS_FMT_UYVY12_1X24:
721 return true;
722
723 default:
724 return false;
725 }
726}
727
728static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
729{
730 switch (bus_format) {
731 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
732 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
733 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
734 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
735 return true;
736
737 default:
738 return false;
739 }
740}
741
742static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
743{
744 switch (bus_format) {
745 case MEDIA_BUS_FMT_RGB888_1X24:
746 case MEDIA_BUS_FMT_YUV8_1X24:
747 case MEDIA_BUS_FMT_UYVY8_1X16:
748 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
749 return 8;
750
751 case MEDIA_BUS_FMT_RGB101010_1X30:
752 case MEDIA_BUS_FMT_YUV10_1X30:
753 case MEDIA_BUS_FMT_UYVY10_1X20:
754 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
755 return 10;
756
757 case MEDIA_BUS_FMT_RGB121212_1X36:
758 case MEDIA_BUS_FMT_YUV12_1X36:
759 case MEDIA_BUS_FMT_UYVY12_1X24:
760 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
761 return 12;
762
763 case MEDIA_BUS_FMT_RGB161616_1X48:
764 case MEDIA_BUS_FMT_YUV16_1X48:
765 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
766 return 16;
767
768 default:
769 return 0;
770 }
771}
772
773
774
775
776
777
778
779
780static void hdmi_video_sample(struct dw_hdmi *hdmi)
781{
782 int color_format = 0;
783 u8 val;
784
785 switch (hdmi->hdmi_data.enc_in_bus_format) {
786 case MEDIA_BUS_FMT_RGB888_1X24:
787 color_format = 0x01;
788 break;
789 case MEDIA_BUS_FMT_RGB101010_1X30:
790 color_format = 0x03;
791 break;
792 case MEDIA_BUS_FMT_RGB121212_1X36:
793 color_format = 0x05;
794 break;
795 case MEDIA_BUS_FMT_RGB161616_1X48:
796 color_format = 0x07;
797 break;
798
799 case MEDIA_BUS_FMT_YUV8_1X24:
800 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
801 color_format = 0x09;
802 break;
803 case MEDIA_BUS_FMT_YUV10_1X30:
804 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
805 color_format = 0x0B;
806 break;
807 case MEDIA_BUS_FMT_YUV12_1X36:
808 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
809 color_format = 0x0D;
810 break;
811 case MEDIA_BUS_FMT_YUV16_1X48:
812 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
813 color_format = 0x0F;
814 break;
815
816 case MEDIA_BUS_FMT_UYVY8_1X16:
817 color_format = 0x16;
818 break;
819 case MEDIA_BUS_FMT_UYVY10_1X20:
820 color_format = 0x14;
821 break;
822 case MEDIA_BUS_FMT_UYVY12_1X24:
823 color_format = 0x12;
824 break;
825
826 default:
827 return;
828 }
829
830 val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
831 ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
832 HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
833 hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
834
835
836 val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
837 HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
838 HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
839 hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
840 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
841 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
842 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
843 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
844 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
845 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
846}
847
848static int is_color_space_conversion(struct dw_hdmi *hdmi)
849{
850 return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format;
851}
852
853static int is_color_space_decimation(struct dw_hdmi *hdmi)
854{
855 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
856 return 0;
857
858 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) ||
859 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format))
860 return 1;
861
862 return 0;
863}
864
865static int is_color_space_interpolation(struct dw_hdmi *hdmi)
866{
867 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format))
868 return 0;
869
870 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
871 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
872 return 1;
873
874 return 0;
875}
876
877static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
878{
879 const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
880 unsigned i;
881 u32 csc_scale = 1;
882
883 if (is_color_space_conversion(hdmi)) {
884 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
885 if (hdmi->hdmi_data.enc_out_encoding ==
886 V4L2_YCBCR_ENC_601)
887 csc_coeff = &csc_coeff_rgb_out_eitu601;
888 else
889 csc_coeff = &csc_coeff_rgb_out_eitu709;
890 } else if (hdmi_bus_fmt_is_rgb(
891 hdmi->hdmi_data.enc_in_bus_format)) {
892 if (hdmi->hdmi_data.enc_out_encoding ==
893 V4L2_YCBCR_ENC_601)
894 csc_coeff = &csc_coeff_rgb_in_eitu601;
895 else
896 csc_coeff = &csc_coeff_rgb_in_eitu709;
897 csc_scale = 0;
898 }
899 }
900
901
902 for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
903 u16 coeff_a = (*csc_coeff)[0][i];
904 u16 coeff_b = (*csc_coeff)[1][i];
905 u16 coeff_c = (*csc_coeff)[2][i];
906
907 hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
908 hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
909 hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
910 hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
911 hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
912 hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
913 }
914
915 hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
916 HDMI_CSC_SCALE);
917}
918
919static void hdmi_video_csc(struct dw_hdmi *hdmi)
920{
921 int color_depth = 0;
922 int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
923 int decimation = 0;
924
925
926 if (is_color_space_interpolation(hdmi))
927 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
928 else if (is_color_space_decimation(hdmi))
929 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
930
931 switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) {
932 case 8:
933 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
934 break;
935 case 10:
936 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
937 break;
938 case 12:
939 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
940 break;
941 case 16:
942 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
943 break;
944
945 default:
946 return;
947 }
948
949
950 hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
951 hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
952 HDMI_CSC_SCALE);
953
954 dw_hdmi_update_csc_coeffs(hdmi);
955}
956
957
958
959
960
961
962static void hdmi_video_packetize(struct dw_hdmi *hdmi)
963{
964 unsigned int color_depth = 0;
965 unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
966 unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
967 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
968 u8 val, vp_conf;
969
970 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
971 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) ||
972 hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
973 switch (hdmi_bus_fmt_color_depth(
974 hdmi->hdmi_data.enc_out_bus_format)) {
975 case 8:
976 color_depth = 4;
977 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
978 break;
979 case 10:
980 color_depth = 5;
981 break;
982 case 12:
983 color_depth = 6;
984 break;
985 case 16:
986 color_depth = 7;
987 break;
988 default:
989 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
990 }
991 } else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
992 switch (hdmi_bus_fmt_color_depth(
993 hdmi->hdmi_data.enc_out_bus_format)) {
994 case 0:
995 case 8:
996 remap_size = HDMI_VP_REMAP_YCC422_16bit;
997 break;
998 case 10:
999 remap_size = HDMI_VP_REMAP_YCC422_20bit;
1000 break;
1001 case 12:
1002 remap_size = HDMI_VP_REMAP_YCC422_24bit;
1003 break;
1004
1005 default:
1006 return;
1007 }
1008 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
1009 } else {
1010 return;
1011 }
1012
1013
1014 val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
1015 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
1016 ((hdmi_data->pix_repet_factor <<
1017 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
1018 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
1019 hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
1020
1021 hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE,
1022 HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF);
1023
1024
1025 if (hdmi_data->pix_repet_factor > 1) {
1026 vp_conf = HDMI_VP_CONF_PR_EN_ENABLE |
1027 HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
1028 } else {
1029 vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
1030 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
1031 }
1032
1033 hdmi_modb(hdmi, vp_conf,
1034 HDMI_VP_CONF_PR_EN_MASK |
1035 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
1036
1037 hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
1038 HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
1039
1040 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
1041
1042 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
1043 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
1044 HDMI_VP_CONF_PP_EN_ENABLE |
1045 HDMI_VP_CONF_YCC422_EN_DISABLE;
1046 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
1047 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE |
1048 HDMI_VP_CONF_PP_EN_DISABLE |
1049 HDMI_VP_CONF_YCC422_EN_ENABLE;
1050 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
1051 vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
1052 HDMI_VP_CONF_PP_EN_DISABLE |
1053 HDMI_VP_CONF_YCC422_EN_DISABLE;
1054 } else {
1055 return;
1056 }
1057
1058 hdmi_modb(hdmi, vp_conf,
1059 HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK |
1060 HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF);
1061
1062 hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
1063 HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE,
1064 HDMI_VP_STUFF_PP_STUFFING_MASK |
1065 HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF);
1066
1067 hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
1068 HDMI_VP_CONF);
1069}
1070
1071
1072
1073
1074
1075static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi,
1076 unsigned char bit)
1077{
1078 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET,
1079 HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0);
1080}
1081
1082static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
1083{
1084 u32 val;
1085
1086 while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
1087 if (msec-- == 0)
1088 return false;
1089 udelay(1000);
1090 }
1091 hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
1092
1093 return true;
1094}
1095
1096void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data,
1097 unsigned char addr)
1098{
1099 hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
1100 hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
1101 hdmi_writeb(hdmi, (unsigned char)(data >> 8),
1102 HDMI_PHY_I2CM_DATAO_1_ADDR);
1103 hdmi_writeb(hdmi, (unsigned char)(data >> 0),
1104 HDMI_PHY_I2CM_DATAO_0_ADDR);
1105 hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
1106 HDMI_PHY_I2CM_OPERATION_ADDR);
1107 hdmi_phy_wait_i2c_done(hdmi, 1000);
1108}
1109EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_write);
1110
1111
1112static bool dw_hdmi_support_scdc(struct dw_hdmi *hdmi)
1113{
1114 struct drm_display_info *display = &hdmi->connector.display_info;
1115
1116
1117 if (hdmi->version < 0x200a)
1118 return false;
1119
1120
1121 if (!hdmi->ddc)
1122 return false;
1123
1124
1125 if (!display->hdmi.scdc.supported ||
1126 !display->hdmi.scdc.scrambling.supported)
1127 return false;
1128
1129
1130
1131
1132
1133 if (!display->hdmi.scdc.scrambling.low_rates &&
1134 display->max_tmds_clock <= 340000)
1135 return false;
1136
1137 return true;
1138}
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi)
1154{
1155 unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
1156
1157
1158 if (dw_hdmi_support_scdc(hdmi)) {
1159 if (mtmdsclock > HDMI14_MAX_TMDSCLK)
1160 drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 1);
1161 else
1162 drm_scdc_set_high_tmds_clock_ratio(hdmi->ddc, 0);
1163 }
1164}
1165EXPORT_SYMBOL_GPL(dw_hdmi_set_high_tmds_clock_ratio);
1166
1167static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable)
1168{
1169 hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0,
1170 HDMI_PHY_CONF0_PDZ_OFFSET,
1171 HDMI_PHY_CONF0_PDZ_MASK);
1172}
1173
1174static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable)
1175{
1176 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1177 HDMI_PHY_CONF0_ENTMDS_OFFSET,
1178 HDMI_PHY_CONF0_ENTMDS_MASK);
1179}
1180
1181static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable)
1182{
1183 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1184 HDMI_PHY_CONF0_SVSRET_OFFSET,
1185 HDMI_PHY_CONF0_SVSRET_MASK);
1186}
1187
1188void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable)
1189{
1190 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1191 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
1192 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
1193}
1194EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_pddq);
1195
1196void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable)
1197{
1198 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1199 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
1200 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
1201}
1202EXPORT_SYMBOL_GPL(dw_hdmi_phy_gen2_txpwron);
1203
1204static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable)
1205{
1206 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1207 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
1208 HDMI_PHY_CONF0_SELDATAENPOL_MASK);
1209}
1210
1211static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable)
1212{
1213 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
1214 HDMI_PHY_CONF0_SELDIPIF_OFFSET,
1215 HDMI_PHY_CONF0_SELDIPIF_MASK);
1216}
1217
1218void dw_hdmi_phy_reset(struct dw_hdmi *hdmi)
1219{
1220
1221 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ);
1222 hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ);
1223}
1224EXPORT_SYMBOL_GPL(dw_hdmi_phy_reset);
1225
1226void dw_hdmi_phy_i2c_set_addr(struct dw_hdmi *hdmi, u8 address)
1227{
1228 hdmi_phy_test_clear(hdmi, 1);
1229 hdmi_writeb(hdmi, address, HDMI_PHY_I2CM_SLAVE_ADDR);
1230 hdmi_phy_test_clear(hdmi, 0);
1231}
1232EXPORT_SYMBOL_GPL(dw_hdmi_phy_i2c_set_addr);
1233
1234static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi)
1235{
1236 const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
1237 unsigned int i;
1238 u16 val;
1239
1240 if (phy->gen == 1) {
1241 dw_hdmi_phy_enable_tmds(hdmi, 0);
1242 dw_hdmi_phy_enable_powerdown(hdmi, true);
1243 return;
1244 }
1245
1246 dw_hdmi_phy_gen2_txpwron(hdmi, 0);
1247
1248
1249
1250
1251
1252 for (i = 0; i < 5; ++i) {
1253 val = hdmi_readb(hdmi, HDMI_PHY_STAT0);
1254 if (!(val & HDMI_PHY_TX_PHY_LOCK))
1255 break;
1256
1257 usleep_range(1000, 2000);
1258 }
1259
1260 if (val & HDMI_PHY_TX_PHY_LOCK)
1261 dev_warn(hdmi->dev, "PHY failed to power down\n");
1262 else
1263 dev_dbg(hdmi->dev, "PHY powered down in %u iterations\n", i);
1264
1265 dw_hdmi_phy_gen2_pddq(hdmi, 1);
1266}
1267
1268static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi)
1269{
1270 const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
1271 unsigned int i;
1272 u8 val;
1273
1274 if (phy->gen == 1) {
1275 dw_hdmi_phy_enable_powerdown(hdmi, false);
1276
1277
1278 dw_hdmi_phy_enable_tmds(hdmi, 0);
1279 dw_hdmi_phy_enable_tmds(hdmi, 1);
1280 return 0;
1281 }
1282
1283 dw_hdmi_phy_gen2_txpwron(hdmi, 1);
1284 dw_hdmi_phy_gen2_pddq(hdmi, 0);
1285
1286
1287 for (i = 0; i < 5; ++i) {
1288 val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
1289 if (val)
1290 break;
1291
1292 usleep_range(1000, 2000);
1293 }
1294
1295 if (!val) {
1296 dev_err(hdmi->dev, "PHY PLL failed to lock\n");
1297 return -ETIMEDOUT;
1298 }
1299
1300 dev_dbg(hdmi->dev, "PHY PLL locked %u iterations\n", i);
1301 return 0;
1302}
1303
1304
1305
1306
1307
1308
1309static int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi,
1310 const struct dw_hdmi_plat_data *pdata,
1311 unsigned long mpixelclock)
1312{
1313 const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg;
1314 const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr;
1315 const struct dw_hdmi_phy_config *phy_config = pdata->phy_config;
1316
1317
1318
1319
1320 for (; mpll_config->mpixelclock != ~0UL; mpll_config++)
1321 if (mpixelclock <= mpll_config->mpixelclock)
1322 break;
1323
1324 for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++)
1325 if (mpixelclock <= curr_ctrl->mpixelclock)
1326 break;
1327
1328 for (; phy_config->mpixelclock != ~0UL; phy_config++)
1329 if (mpixelclock <= phy_config->mpixelclock)
1330 break;
1331
1332 if (mpll_config->mpixelclock == ~0UL ||
1333 curr_ctrl->mpixelclock == ~0UL ||
1334 phy_config->mpixelclock == ~0UL)
1335 return -EINVAL;
1336
1337 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce,
1338 HDMI_3D_TX_PHY_CPCE_CTRL);
1339 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp,
1340 HDMI_3D_TX_PHY_GMPCTRL);
1341 dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0],
1342 HDMI_3D_TX_PHY_CURRCTRL);
1343
1344 dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL);
1345 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK,
1346 HDMI_3D_TX_PHY_MSM_CTRL);
1347
1348 dw_hdmi_phy_i2c_write(hdmi, phy_config->term, HDMI_3D_TX_PHY_TXTERM);
1349 dw_hdmi_phy_i2c_write(hdmi, phy_config->sym_ctr,
1350 HDMI_3D_TX_PHY_CKSYMTXCTRL);
1351 dw_hdmi_phy_i2c_write(hdmi, phy_config->vlev_ctr,
1352 HDMI_3D_TX_PHY_VLEVCTRL);
1353
1354
1355 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE,
1356 HDMI_3D_TX_PHY_CKCALCTRL);
1357
1358 return 0;
1359}
1360
1361static int hdmi_phy_configure(struct dw_hdmi *hdmi)
1362{
1363 const struct dw_hdmi_phy_data *phy = hdmi->phy.data;
1364 const struct dw_hdmi_plat_data *pdata = hdmi->plat_data;
1365 unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock;
1366 unsigned long mtmdsclock = hdmi->hdmi_data.video_mode.mtmdsclock;
1367 int ret;
1368
1369 dw_hdmi_phy_power_off(hdmi);
1370
1371 dw_hdmi_set_high_tmds_clock_ratio(hdmi);
1372
1373
1374 if (phy->has_svsret)
1375 dw_hdmi_phy_enable_svsret(hdmi, 1);
1376
1377 dw_hdmi_phy_reset(hdmi);
1378
1379 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
1380
1381 dw_hdmi_phy_i2c_set_addr(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2);
1382
1383
1384 if (pdata->configure_phy)
1385 ret = pdata->configure_phy(hdmi, pdata, mpixelclock);
1386 else
1387 ret = phy->configure(hdmi, pdata, mpixelclock);
1388 if (ret) {
1389 dev_err(hdmi->dev, "PHY configuration failed (clock %lu)\n",
1390 mpixelclock);
1391 return ret;
1392 }
1393
1394
1395 if (mtmdsclock > HDMI14_MAX_TMDSCLK)
1396 msleep(100);
1397
1398 return dw_hdmi_phy_power_on(hdmi);
1399}
1400
1401static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
1402 struct drm_display_mode *mode)
1403{
1404 int i, ret;
1405
1406
1407 for (i = 0; i < 2; i++) {
1408 dw_hdmi_phy_sel_data_en_pol(hdmi, 1);
1409 dw_hdmi_phy_sel_interface_control(hdmi, 0);
1410
1411 ret = hdmi_phy_configure(hdmi);
1412 if (ret)
1413 return ret;
1414 }
1415
1416 return 0;
1417}
1418
1419static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data)
1420{
1421 dw_hdmi_phy_power_off(hdmi);
1422}
1423
1424enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi,
1425 void *data)
1426{
1427 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
1428 connector_status_connected : connector_status_disconnected;
1429}
1430EXPORT_SYMBOL_GPL(dw_hdmi_phy_read_hpd);
1431
1432void dw_hdmi_phy_update_hpd(struct dw_hdmi *hdmi, void *data,
1433 bool force, bool disabled, bool rxsense)
1434{
1435 u8 old_mask = hdmi->phy_mask;
1436
1437 if (force || disabled || !rxsense)
1438 hdmi->phy_mask |= HDMI_PHY_RX_SENSE;
1439 else
1440 hdmi->phy_mask &= ~HDMI_PHY_RX_SENSE;
1441
1442 if (old_mask != hdmi->phy_mask)
1443 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
1444}
1445EXPORT_SYMBOL_GPL(dw_hdmi_phy_update_hpd);
1446
1447void dw_hdmi_phy_setup_hpd(struct dw_hdmi *hdmi, void *data)
1448{
1449
1450
1451
1452
1453 hdmi_writeb(hdmi, HDMI_PHY_HPD | HDMI_PHY_RX_SENSE, HDMI_PHY_POL0);
1454 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
1455 HDMI_IH_PHY_STAT0);
1456
1457
1458 hdmi_writeb(hdmi, hdmi->phy_mask, HDMI_PHY_MASK0);
1459
1460
1461 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE,
1462 HDMI_IH_PHY_STAT0);
1463 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
1464 HDMI_IH_MUTE_PHY_STAT0);
1465}
1466EXPORT_SYMBOL_GPL(dw_hdmi_phy_setup_hpd);
1467
1468static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = {
1469 .init = dw_hdmi_phy_init,
1470 .disable = dw_hdmi_phy_disable,
1471 .read_hpd = dw_hdmi_phy_read_hpd,
1472 .update_hpd = dw_hdmi_phy_update_hpd,
1473 .setup_hpd = dw_hdmi_phy_setup_hpd,
1474};
1475
1476
1477
1478
1479
1480static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi)
1481{
1482 u8 de;
1483
1484 if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
1485 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
1486 else
1487 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
1488
1489
1490 hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE,
1491 HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0);
1492
1493 hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG);
1494
1495 hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE,
1496 HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1);
1497}
1498
1499static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1500{
1501 struct hdmi_avi_infoframe frame;
1502 u8 val;
1503
1504
1505 drm_hdmi_avi_infoframe_from_display_mode(&frame,
1506 &hdmi->connector, mode);
1507
1508 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
1509 frame.colorspace = HDMI_COLORSPACE_YUV444;
1510 else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
1511 frame.colorspace = HDMI_COLORSPACE_YUV422;
1512 else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
1513 frame.colorspace = HDMI_COLORSPACE_YUV420;
1514 else
1515 frame.colorspace = HDMI_COLORSPACE_RGB;
1516
1517
1518 switch (hdmi->hdmi_data.enc_out_encoding) {
1519 case V4L2_YCBCR_ENC_601:
1520 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601)
1521 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
1522 else
1523 frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
1524 frame.extended_colorimetry =
1525 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
1526 break;
1527 case V4L2_YCBCR_ENC_709:
1528 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709)
1529 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
1530 else
1531 frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
1532 frame.extended_colorimetry =
1533 HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
1534 break;
1535 default:
1536 frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
1537 frame.extended_colorimetry =
1538 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
1539 break;
1540 }
1541
1542 frame.scan_mode = HDMI_SCAN_MODE_NONE;
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555 val = (frame.scan_mode & 3) << 4 | (frame.colorspace & 3);
1556 if (frame.active_aspect & 15)
1557 val |= HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT;
1558 if (frame.top_bar || frame.bottom_bar)
1559 val |= HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR;
1560 if (frame.left_bar || frame.right_bar)
1561 val |= HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR;
1562 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
1563
1564
1565 val = ((frame.colorimetry & 0x3) << 6) |
1566 ((frame.picture_aspect & 0x3) << 4) |
1567 (frame.active_aspect & 0xf);
1568 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
1569
1570
1571 val = ((frame.extended_colorimetry & 0x7) << 4) |
1572 ((frame.quantization_range & 0x3) << 2) |
1573 (frame.nups & 0x3);
1574 if (frame.itc)
1575 val |= HDMI_FC_AVICONF2_IT_CONTENT_VALID;
1576 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
1577
1578
1579 val = frame.video_code & 0x7f;
1580 hdmi_writeb(hdmi, val, HDMI_FC_AVIVID);
1581
1582
1583 val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
1584 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
1585 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
1586 ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
1587 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
1588 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
1589 hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
1590
1591
1592
1593
1594
1595 val = ((frame.ycc_quantization_range & 0x3) << 2) |
1596 (frame.content_type & 0x3);
1597 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
1598
1599
1600 hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0);
1601 hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1);
1602 hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0);
1603 hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1);
1604 hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0);
1605 hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1);
1606 hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0);
1607 hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1);
1608}
1609
1610static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
1611 struct drm_display_mode *mode)
1612{
1613 struct hdmi_vendor_infoframe frame;
1614 u8 buffer[10];
1615 ssize_t err;
1616
1617 err = drm_hdmi_vendor_infoframe_from_display_mode(&frame,
1618 &hdmi->connector,
1619 mode);
1620 if (err < 0)
1621
1622
1623
1624
1625
1626
1627 return;
1628
1629 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
1630 if (err < 0) {
1631 dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n",
1632 err);
1633 return;
1634 }
1635 hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
1636 HDMI_FC_DATAUTO0_VSD_MASK);
1637
1638
1639 hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE);
1640
1641
1642 hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0);
1643 hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1);
1644 hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2);
1645
1646
1647 hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0);
1648 hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1);
1649
1650 if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
1651 hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2);
1652
1653
1654 hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1);
1655
1656
1657 hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2);
1658
1659
1660 hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET,
1661 HDMI_FC_DATAUTO0_VSD_MASK);
1662}
1663
1664static void hdmi_av_composer(struct dw_hdmi *hdmi,
1665 const struct drm_display_mode *mode)
1666{
1667 u8 inv_val, bytes;
1668 struct drm_hdmi_info *hdmi_info = &hdmi->connector.display_info.hdmi;
1669 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
1670 int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
1671 unsigned int vdisplay, hdisplay;
1672
1673 vmode->mtmdsclock = vmode->mpixelclock = mode->clock * 1000;
1674
1675 dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
1676
1677 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
1678 vmode->mtmdsclock /= 2;
1679
1680
1681 inv_val = (hdmi->hdmi_data.hdcp_enable ||
1682 (dw_hdmi_support_scdc(hdmi) &&
1683 (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
1684 hdmi_info->scdc.scrambling.low_rates)) ?
1685 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1686 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
1687
1688 inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
1689 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
1690 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW;
1691
1692 inv_val |= mode->flags & DRM_MODE_FLAG_PHSYNC ?
1693 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
1694 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW;
1695
1696 inv_val |= (vmode->mdataenablepolarity ?
1697 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
1698 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
1699
1700 if (hdmi->vic == 39)
1701 inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
1702 else
1703 inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
1704 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
1705 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
1706
1707 inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ?
1708 HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
1709 HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
1710
1711 inv_val |= hdmi->sink_is_hdmi ?
1712 HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
1713 HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE;
1714
1715 hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
1716
1717 hdisplay = mode->hdisplay;
1718 hblank = mode->htotal - mode->hdisplay;
1719 h_de_hs = mode->hsync_start - mode->hdisplay;
1720 hsync_len = mode->hsync_end - mode->hsync_start;
1721
1722
1723
1724
1725
1726 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) {
1727 hdisplay /= 2;
1728 hblank /= 2;
1729 h_de_hs /= 2;
1730 hsync_len /= 2;
1731 }
1732
1733 vdisplay = mode->vdisplay;
1734 vblank = mode->vtotal - mode->vdisplay;
1735 v_de_vs = mode->vsync_start - mode->vdisplay;
1736 vsync_len = mode->vsync_end - mode->vsync_start;
1737
1738
1739
1740
1741
1742 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
1743 vdisplay /= 2;
1744 vblank /= 2;
1745 v_de_vs /= 2;
1746 vsync_len /= 2;
1747 }
1748
1749
1750 if (dw_hdmi_support_scdc(hdmi)) {
1751 if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK ||
1752 hdmi_info->scdc.scrambling.low_rates) {
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762 drm_scdc_readb(hdmi->ddc, SCDC_SINK_VERSION,
1763 &bytes);
1764 drm_scdc_writeb(hdmi->ddc, SCDC_SOURCE_VERSION,
1765 min_t(u8, bytes, SCDC_MIN_SOURCE_VERSION));
1766
1767
1768 drm_scdc_set_scrambling(hdmi->ddc, 1);
1769
1770
1771
1772
1773
1774
1775
1776
1777 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
1778 HDMI_MC_SWRSTZ);
1779 hdmi_writeb(hdmi, 1, HDMI_FC_SCRAMBLER_CTRL);
1780 } else {
1781 hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL);
1782 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
1783 HDMI_MC_SWRSTZ);
1784 drm_scdc_set_scrambling(hdmi->ddc, 0);
1785 }
1786 }
1787
1788
1789 hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);
1790 hdmi_writeb(hdmi, hdisplay, HDMI_FC_INHACTV0);
1791
1792
1793 hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1);
1794 hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0);
1795
1796
1797 hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
1798 hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
1799
1800
1801 hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
1802
1803
1804 hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
1805 hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
1806
1807
1808 hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
1809
1810
1811 hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
1812 hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
1813
1814
1815 hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
1816}
1817
1818
1819static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi)
1820{
1821
1822 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
1823 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
1824 hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
1825
1826
1827 hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
1828 hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
1829 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
1830
1831
1832 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_HDCPCLK_DISABLE |
1833 HDMI_MC_CLKDIS_CSCCLK_DISABLE |
1834 HDMI_MC_CLKDIS_AUDCLK_DISABLE |
1835 HDMI_MC_CLKDIS_PREPCLK_DISABLE |
1836 HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1837 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
1838 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1839
1840 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1841 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1842
1843
1844 if (is_color_space_conversion(hdmi)) {
1845 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
1846 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
1847 }
1848
1849
1850 if (is_color_space_conversion(hdmi))
1851 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
1852 HDMI_MC_FLOWCTRL);
1853 else
1854 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
1855 HDMI_MC_FLOWCTRL);
1856}
1857
1858
1859static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi)
1860{
1861 unsigned int count;
1862 unsigned int i;
1863 u8 val;
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882 switch (hdmi->version) {
1883 case 0x130a:
1884 count = 4;
1885 break;
1886 case 0x131a:
1887 case 0x132a:
1888 case 0x200a:
1889 case 0x201a:
1890 case 0x211a:
1891 case 0x212a:
1892 count = 1;
1893 break;
1894 default:
1895 return;
1896 }
1897
1898
1899 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
1900
1901 val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
1902 for (i = 0; i < count; i++)
1903 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1904}
1905
1906static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi)
1907{
1908 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
1909 HDMI_IH_MUTE_FC_STAT2);
1910}
1911
1912static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
1913{
1914 int ret;
1915
1916 hdmi_disable_overflow_interrupts(hdmi);
1917
1918 hdmi->vic = drm_match_cea_mode(mode);
1919
1920 if (!hdmi->vic) {
1921 dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
1922 } else {
1923 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
1924 }
1925
1926 if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
1927 (hdmi->vic == 21) || (hdmi->vic == 22) ||
1928 (hdmi->vic == 2) || (hdmi->vic == 3) ||
1929 (hdmi->vic == 17) || (hdmi->vic == 18))
1930 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
1931 else
1932 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
1933
1934 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
1935 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
1936
1937
1938 if (hdmi->plat_data->input_bus_format)
1939 hdmi->hdmi_data.enc_in_bus_format =
1940 hdmi->plat_data->input_bus_format;
1941 else
1942 hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
1943
1944
1945 if (hdmi->plat_data->input_bus_encoding)
1946 hdmi->hdmi_data.enc_in_encoding =
1947 hdmi->plat_data->input_bus_encoding;
1948 else
1949 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
1950
1951
1952 hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
1953
1954 hdmi->hdmi_data.pix_repet_factor = 0;
1955 hdmi->hdmi_data.hdcp_enable = 0;
1956 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
1957
1958
1959 hdmi_av_composer(hdmi, mode);
1960
1961
1962 ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode);
1963 if (ret)
1964 return ret;
1965 hdmi->phy.enabled = true;
1966
1967
1968 dw_hdmi_enable_video_path(hdmi);
1969
1970 if (hdmi->sink_has_audio) {
1971 dev_dbg(hdmi->dev, "sink has audio support\n");
1972
1973
1974 hdmi_clk_regenerator_update_pixel_clock(hdmi);
1975 hdmi_enable_audio_clk(hdmi, true);
1976 }
1977
1978
1979 if (hdmi->sink_is_hdmi) {
1980 dev_dbg(hdmi->dev, "%s HDMI mode\n", __func__);
1981
1982
1983 hdmi_config_AVI(hdmi, mode);
1984 hdmi_config_vendor_specific_infoframe(hdmi, mode);
1985 } else {
1986 dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
1987 }
1988
1989 hdmi_video_packetize(hdmi);
1990 hdmi_video_csc(hdmi);
1991 hdmi_video_sample(hdmi);
1992 hdmi_tx_hdcp_config(hdmi);
1993
1994 dw_hdmi_clear_overflow(hdmi);
1995
1996 return 0;
1997}
1998
1999static void initialize_hdmi_ih_mutes(struct dw_hdmi *hdmi)
2000{
2001 u8 ih_mute;
2002
2003
2004
2005
2006
2007
2008
2009
2010 ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
2011 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
2012 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
2013
2014 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
2015
2016
2017 hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
2018 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
2019 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
2020 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
2021 hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
2022 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
2023 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
2024 hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
2025 hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
2026 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
2027 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
2028 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
2029 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
2030 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
2031
2032
2033 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
2034 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
2035 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
2036 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
2037 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
2038 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
2039 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
2040 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
2041 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
2042 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
2043
2044
2045 ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
2046 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
2047 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
2048}
2049
2050static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
2051{
2052 hdmi->bridge_is_on = true;
2053 dw_hdmi_setup(hdmi, &hdmi->previous_mode);
2054}
2055
2056static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
2057{
2058 if (hdmi->phy.enabled) {
2059 hdmi->phy.ops->disable(hdmi, hdmi->phy.data);
2060 hdmi->phy.enabled = false;
2061 }
2062
2063 hdmi->bridge_is_on = false;
2064}
2065
2066static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
2067{
2068 int force = hdmi->force;
2069
2070 if (hdmi->disabled) {
2071 force = DRM_FORCE_OFF;
2072 } else if (force == DRM_FORCE_UNSPECIFIED) {
2073 if (hdmi->rxsense)
2074 force = DRM_FORCE_ON;
2075 else
2076 force = DRM_FORCE_OFF;
2077 }
2078
2079 if (force == DRM_FORCE_OFF) {
2080 if (hdmi->bridge_is_on)
2081 dw_hdmi_poweroff(hdmi);
2082 } else {
2083 if (!hdmi->bridge_is_on)
2084 dw_hdmi_poweron(hdmi);
2085 }
2086}
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100static void dw_hdmi_update_phy_mask(struct dw_hdmi *hdmi)
2101{
2102 if (hdmi->phy.ops->update_hpd)
2103 hdmi->phy.ops->update_hpd(hdmi, hdmi->phy.data,
2104 hdmi->force, hdmi->disabled,
2105 hdmi->rxsense);
2106}
2107
2108static enum drm_connector_status
2109dw_hdmi_connector_detect(struct drm_connector *connector, bool force)
2110{
2111 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
2112 connector);
2113
2114 mutex_lock(&hdmi->mutex);
2115 hdmi->force = DRM_FORCE_UNSPECIFIED;
2116 dw_hdmi_update_power(hdmi);
2117 dw_hdmi_update_phy_mask(hdmi);
2118 mutex_unlock(&hdmi->mutex);
2119
2120 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data);
2121}
2122
2123static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
2124{
2125 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
2126 connector);
2127 struct edid *edid;
2128 int ret = 0;
2129
2130 if (!hdmi->ddc)
2131 return 0;
2132
2133 edid = drm_get_edid(connector, hdmi->ddc);
2134 if (edid) {
2135 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
2136 edid->width_cm, edid->height_cm);
2137
2138 hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid);
2139 hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
2140 drm_connector_update_edid_property(connector, edid);
2141 cec_notifier_set_phys_addr_from_edid(hdmi->cec_notifier, edid);
2142 ret = drm_add_edid_modes(connector, edid);
2143 kfree(edid);
2144 } else {
2145 dev_dbg(hdmi->dev, "failed to get edid\n");
2146 }
2147
2148 return ret;
2149}
2150
2151static void dw_hdmi_connector_force(struct drm_connector *connector)
2152{
2153 struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
2154 connector);
2155
2156 mutex_lock(&hdmi->mutex);
2157 hdmi->force = connector->force;
2158 dw_hdmi_update_power(hdmi);
2159 dw_hdmi_update_phy_mask(hdmi);
2160 mutex_unlock(&hdmi->mutex);
2161}
2162
2163static const struct drm_connector_funcs dw_hdmi_connector_funcs = {
2164 .fill_modes = drm_helper_probe_single_connector_modes,
2165 .detect = dw_hdmi_connector_detect,
2166 .destroy = drm_connector_cleanup,
2167 .force = dw_hdmi_connector_force,
2168 .reset = drm_atomic_helper_connector_reset,
2169 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
2170 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
2171};
2172
2173static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
2174 .get_modes = dw_hdmi_connector_get_modes,
2175};
2176
2177static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
2178{
2179 struct dw_hdmi *hdmi = bridge->driver_private;
2180 struct drm_encoder *encoder = bridge->encoder;
2181 struct drm_connector *connector = &hdmi->connector;
2182
2183 connector->interlace_allowed = 1;
2184 connector->polled = DRM_CONNECTOR_POLL_HPD;
2185
2186 drm_connector_helper_add(connector, &dw_hdmi_connector_helper_funcs);
2187
2188 drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs,
2189 DRM_MODE_CONNECTOR_HDMIA);
2190
2191 drm_connector_attach_encoder(connector, encoder);
2192
2193 return 0;
2194}
2195
2196static enum drm_mode_status
2197dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
2198 const struct drm_display_mode *mode)
2199{
2200 struct dw_hdmi *hdmi = bridge->driver_private;
2201 struct drm_connector *connector = &hdmi->connector;
2202 enum drm_mode_status mode_status = MODE_OK;
2203
2204
2205 if (mode->flags & DRM_MODE_FLAG_DBLCLK)
2206 return MODE_BAD;
2207
2208 if (hdmi->plat_data->mode_valid)
2209 mode_status = hdmi->plat_data->mode_valid(connector, mode);
2210
2211 return mode_status;
2212}
2213
2214static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
2215 const struct drm_display_mode *orig_mode,
2216 const struct drm_display_mode *mode)
2217{
2218 struct dw_hdmi *hdmi = bridge->driver_private;
2219
2220 mutex_lock(&hdmi->mutex);
2221
2222
2223 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
2224
2225 mutex_unlock(&hdmi->mutex);
2226}
2227
2228static void dw_hdmi_bridge_disable(struct drm_bridge *bridge)
2229{
2230 struct dw_hdmi *hdmi = bridge->driver_private;
2231
2232 mutex_lock(&hdmi->mutex);
2233 hdmi->disabled = true;
2234 dw_hdmi_update_power(hdmi);
2235 dw_hdmi_update_phy_mask(hdmi);
2236 mutex_unlock(&hdmi->mutex);
2237}
2238
2239static void dw_hdmi_bridge_enable(struct drm_bridge *bridge)
2240{
2241 struct dw_hdmi *hdmi = bridge->driver_private;
2242
2243 mutex_lock(&hdmi->mutex);
2244 hdmi->disabled = false;
2245 dw_hdmi_update_power(hdmi);
2246 dw_hdmi_update_phy_mask(hdmi);
2247 mutex_unlock(&hdmi->mutex);
2248}
2249
2250static const struct drm_bridge_funcs dw_hdmi_bridge_funcs = {
2251 .attach = dw_hdmi_bridge_attach,
2252 .enable = dw_hdmi_bridge_enable,
2253 .disable = dw_hdmi_bridge_disable,
2254 .mode_set = dw_hdmi_bridge_mode_set,
2255 .mode_valid = dw_hdmi_bridge_mode_valid,
2256};
2257
2258static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi)
2259{
2260 struct dw_hdmi_i2c *i2c = hdmi->i2c;
2261 unsigned int stat;
2262
2263 stat = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0);
2264 if (!stat)
2265 return IRQ_NONE;
2266
2267 hdmi_writeb(hdmi, stat, HDMI_IH_I2CM_STAT0);
2268
2269 i2c->stat = stat;
2270
2271 complete(&i2c->cmp);
2272
2273 return IRQ_HANDLED;
2274}
2275
2276static irqreturn_t dw_hdmi_hardirq(int irq, void *dev_id)
2277{
2278 struct dw_hdmi *hdmi = dev_id;
2279 u8 intr_stat;
2280 irqreturn_t ret = IRQ_NONE;
2281
2282 if (hdmi->i2c)
2283 ret = dw_hdmi_i2c_irq(hdmi);
2284
2285 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
2286 if (intr_stat) {
2287 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
2288 return IRQ_WAKE_THREAD;
2289 }
2290
2291 return ret;
2292}
2293
2294void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense)
2295{
2296 mutex_lock(&hdmi->mutex);
2297
2298 if (!hdmi->force) {
2299
2300
2301
2302
2303 if (!rx_sense)
2304 hdmi->rxsense = false;
2305
2306
2307
2308
2309
2310
2311
2312 if (hpd)
2313 hdmi->rxsense = true;
2314
2315 dw_hdmi_update_power(hdmi);
2316 dw_hdmi_update_phy_mask(hdmi);
2317 }
2318 mutex_unlock(&hdmi->mutex);
2319}
2320EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense);
2321
2322static irqreturn_t dw_hdmi_irq(int irq, void *dev_id)
2323{
2324 struct dw_hdmi *hdmi = dev_id;
2325 u8 intr_stat, phy_int_pol, phy_pol_mask, phy_stat;
2326
2327 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
2328 phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
2329 phy_stat = hdmi_readb(hdmi, HDMI_PHY_STAT0);
2330
2331 phy_pol_mask = 0;
2332 if (intr_stat & HDMI_IH_PHY_STAT0_HPD)
2333 phy_pol_mask |= HDMI_PHY_HPD;
2334 if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE0)
2335 phy_pol_mask |= HDMI_PHY_RX_SENSE0;
2336 if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE1)
2337 phy_pol_mask |= HDMI_PHY_RX_SENSE1;
2338 if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE2)
2339 phy_pol_mask |= HDMI_PHY_RX_SENSE2;
2340 if (intr_stat & HDMI_IH_PHY_STAT0_RX_SENSE3)
2341 phy_pol_mask |= HDMI_PHY_RX_SENSE3;
2342
2343 if (phy_pol_mask)
2344 hdmi_modb(hdmi, ~phy_int_pol, phy_pol_mask, HDMI_PHY_POL0);
2345
2346
2347
2348
2349
2350
2351
2352
2353 if (intr_stat &
2354 (HDMI_IH_PHY_STAT0_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) {
2355 dw_hdmi_setup_rx_sense(hdmi,
2356 phy_stat & HDMI_PHY_HPD,
2357 phy_stat & HDMI_PHY_RX_SENSE);
2358
2359 if ((phy_stat & (HDMI_PHY_RX_SENSE | HDMI_PHY_HPD)) == 0)
2360 cec_notifier_set_phys_addr(hdmi->cec_notifier,
2361 CEC_PHYS_ADDR_INVALID);
2362 }
2363
2364 if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
2365 dev_dbg(hdmi->dev, "EVENT=%s\n",
2366 phy_int_pol & HDMI_PHY_HPD ? "plugin" : "plugout");
2367 if (hdmi->bridge.dev)
2368 drm_helper_hpd_irq_event(hdmi->bridge.dev);
2369 }
2370
2371 hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
2372 hdmi_writeb(hdmi, ~(HDMI_IH_PHY_STAT0_HPD | HDMI_IH_PHY_STAT0_RX_SENSE),
2373 HDMI_IH_MUTE_PHY_STAT0);
2374
2375 return IRQ_HANDLED;
2376}
2377
2378static const struct dw_hdmi_phy_data dw_hdmi_phys[] = {
2379 {
2380 .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY,
2381 .name = "DWC HDMI TX PHY",
2382 .gen = 1,
2383 }, {
2384 .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC,
2385 .name = "DWC MHL PHY + HEAC PHY",
2386 .gen = 2,
2387 .has_svsret = true,
2388 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2389 }, {
2390 .type = DW_HDMI_PHY_DWC_MHL_PHY,
2391 .name = "DWC MHL PHY",
2392 .gen = 2,
2393 .has_svsret = true,
2394 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2395 }, {
2396 .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC,
2397 .name = "DWC HDMI 3D TX PHY + HEAC PHY",
2398 .gen = 2,
2399 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2400 }, {
2401 .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY,
2402 .name = "DWC HDMI 3D TX PHY",
2403 .gen = 2,
2404 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2405 }, {
2406 .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY,
2407 .name = "DWC HDMI 2.0 TX PHY",
2408 .gen = 2,
2409 .has_svsret = true,
2410 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx,
2411 }, {
2412 .type = DW_HDMI_PHY_VENDOR_PHY,
2413 .name = "Vendor PHY",
2414 }
2415};
2416
2417static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi)
2418{
2419 unsigned int i;
2420 u8 phy_type;
2421
2422 phy_type = hdmi->plat_data->phy_force_vendor ?
2423 DW_HDMI_PHY_VENDOR_PHY :
2424 hdmi_readb(hdmi, HDMI_CONFIG2_ID);
2425
2426 if (phy_type == DW_HDMI_PHY_VENDOR_PHY) {
2427
2428 if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) {
2429 dev_err(hdmi->dev,
2430 "Vendor HDMI PHY not supported by glue layer\n");
2431 return -ENODEV;
2432 }
2433
2434 hdmi->phy.ops = hdmi->plat_data->phy_ops;
2435 hdmi->phy.data = hdmi->plat_data->phy_data;
2436 hdmi->phy.name = hdmi->plat_data->phy_name;
2437 return 0;
2438 }
2439
2440
2441 for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) {
2442 if (dw_hdmi_phys[i].type == phy_type) {
2443 hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops;
2444 hdmi->phy.name = dw_hdmi_phys[i].name;
2445 hdmi->phy.data = (void *)&dw_hdmi_phys[i];
2446
2447 if (!dw_hdmi_phys[i].configure &&
2448 !hdmi->plat_data->configure_phy) {
2449 dev_err(hdmi->dev, "%s requires platform support\n",
2450 hdmi->phy.name);
2451 return -ENODEV;
2452 }
2453
2454 return 0;
2455 }
2456 }
2457
2458 dev_err(hdmi->dev, "Unsupported HDMI PHY type (%02x)\n", phy_type);
2459 return -ENODEV;
2460}
2461
2462static void dw_hdmi_cec_enable(struct dw_hdmi *hdmi)
2463{
2464 mutex_lock(&hdmi->mutex);
2465 hdmi->mc_clkdis &= ~HDMI_MC_CLKDIS_CECCLK_DISABLE;
2466 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
2467 mutex_unlock(&hdmi->mutex);
2468}
2469
2470static void dw_hdmi_cec_disable(struct dw_hdmi *hdmi)
2471{
2472 mutex_lock(&hdmi->mutex);
2473 hdmi->mc_clkdis |= HDMI_MC_CLKDIS_CECCLK_DISABLE;
2474 hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS);
2475 mutex_unlock(&hdmi->mutex);
2476}
2477
2478static const struct dw_hdmi_cec_ops dw_hdmi_cec_ops = {
2479 .write = hdmi_writeb,
2480 .read = hdmi_readb,
2481 .enable = dw_hdmi_cec_enable,
2482 .disable = dw_hdmi_cec_disable,
2483};
2484
2485static const struct regmap_config hdmi_regmap_8bit_config = {
2486 .reg_bits = 32,
2487 .val_bits = 8,
2488 .reg_stride = 1,
2489 .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR,
2490};
2491
2492static const struct regmap_config hdmi_regmap_32bit_config = {
2493 .reg_bits = 32,
2494 .val_bits = 32,
2495 .reg_stride = 4,
2496 .max_register = HDMI_I2CM_FS_SCL_LCNT_0_ADDR << 2,
2497};
2498
2499static void dw_hdmi_init_hw(struct dw_hdmi *hdmi)
2500{
2501 initialize_hdmi_ih_mutes(hdmi);
2502
2503
2504
2505
2506
2507
2508 dw_hdmi_i2c_init(hdmi);
2509
2510 if (hdmi->phy.ops->setup_hpd)
2511 hdmi->phy.ops->setup_hpd(hdmi, hdmi->phy.data);
2512}
2513
2514static struct dw_hdmi *
2515__dw_hdmi_probe(struct platform_device *pdev,
2516 const struct dw_hdmi_plat_data *plat_data)
2517{
2518 struct device *dev = &pdev->dev;
2519 struct device_node *np = dev->of_node;
2520 struct platform_device_info pdevinfo;
2521 struct device_node *ddc_node;
2522 struct dw_hdmi_cec_data cec;
2523 struct dw_hdmi *hdmi;
2524 struct resource *iores = NULL;
2525 int irq;
2526 int ret;
2527 u32 val = 1;
2528 u8 prod_id0;
2529 u8 prod_id1;
2530 u8 config0;
2531 u8 config3;
2532
2533 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
2534 if (!hdmi)
2535 return ERR_PTR(-ENOMEM);
2536
2537 hdmi->plat_data = plat_data;
2538 hdmi->dev = dev;
2539 hdmi->sample_rate = 48000;
2540 hdmi->disabled = true;
2541 hdmi->rxsense = true;
2542 hdmi->phy_mask = (u8)~(HDMI_PHY_HPD | HDMI_PHY_RX_SENSE);
2543 hdmi->mc_clkdis = 0x7f;
2544
2545 mutex_init(&hdmi->mutex);
2546 mutex_init(&hdmi->audio_mutex);
2547 spin_lock_init(&hdmi->audio_lock);
2548
2549 ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
2550 if (ddc_node) {
2551 hdmi->ddc = of_get_i2c_adapter_by_node(ddc_node);
2552 of_node_put(ddc_node);
2553 if (!hdmi->ddc) {
2554 dev_dbg(hdmi->dev, "failed to read ddc node\n");
2555 return ERR_PTR(-EPROBE_DEFER);
2556 }
2557
2558 } else {
2559 dev_dbg(hdmi->dev, "no ddc property found\n");
2560 }
2561
2562 if (!plat_data->regm) {
2563 const struct regmap_config *reg_config;
2564
2565 of_property_read_u32(np, "reg-io-width", &val);
2566 switch (val) {
2567 case 4:
2568 reg_config = &hdmi_regmap_32bit_config;
2569 hdmi->reg_shift = 2;
2570 break;
2571 case 1:
2572 reg_config = &hdmi_regmap_8bit_config;
2573 break;
2574 default:
2575 dev_err(dev, "reg-io-width must be 1 or 4\n");
2576 return ERR_PTR(-EINVAL);
2577 }
2578
2579 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2580 hdmi->regs = devm_ioremap_resource(dev, iores);
2581 if (IS_ERR(hdmi->regs)) {
2582 ret = PTR_ERR(hdmi->regs);
2583 goto err_res;
2584 }
2585
2586 hdmi->regm = devm_regmap_init_mmio(dev, hdmi->regs, reg_config);
2587 if (IS_ERR(hdmi->regm)) {
2588 dev_err(dev, "Failed to configure regmap\n");
2589 ret = PTR_ERR(hdmi->regm);
2590 goto err_res;
2591 }
2592 } else {
2593 hdmi->regm = plat_data->regm;
2594 }
2595
2596 hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
2597 if (IS_ERR(hdmi->isfr_clk)) {
2598 ret = PTR_ERR(hdmi->isfr_clk);
2599 dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret);
2600 goto err_res;
2601 }
2602
2603 ret = clk_prepare_enable(hdmi->isfr_clk);
2604 if (ret) {
2605 dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret);
2606 goto err_res;
2607 }
2608
2609 hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
2610 if (IS_ERR(hdmi->iahb_clk)) {
2611 ret = PTR_ERR(hdmi->iahb_clk);
2612 dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret);
2613 goto err_isfr;
2614 }
2615
2616 ret = clk_prepare_enable(hdmi->iahb_clk);
2617 if (ret) {
2618 dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret);
2619 goto err_isfr;
2620 }
2621
2622 hdmi->cec_clk = devm_clk_get(hdmi->dev, "cec");
2623 if (PTR_ERR(hdmi->cec_clk) == -ENOENT) {
2624 hdmi->cec_clk = NULL;
2625 } else if (IS_ERR(hdmi->cec_clk)) {
2626 ret = PTR_ERR(hdmi->cec_clk);
2627 if (ret != -EPROBE_DEFER)
2628 dev_err(hdmi->dev, "Cannot get HDMI cec clock: %d\n",
2629 ret);
2630
2631 hdmi->cec_clk = NULL;
2632 goto err_iahb;
2633 } else {
2634 ret = clk_prepare_enable(hdmi->cec_clk);
2635 if (ret) {
2636 dev_err(hdmi->dev, "Cannot enable HDMI cec clock: %d\n",
2637 ret);
2638 goto err_iahb;
2639 }
2640 }
2641
2642
2643 hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8)
2644 | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0);
2645 prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0);
2646 prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1);
2647
2648 if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX ||
2649 (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) {
2650 dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n",
2651 hdmi->version, prod_id0, prod_id1);
2652 ret = -ENODEV;
2653 goto err_iahb;
2654 }
2655
2656 ret = dw_hdmi_detect_phy(hdmi);
2657 if (ret < 0)
2658 goto err_iahb;
2659
2660 dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP (%s)\n",
2661 hdmi->version >> 12, hdmi->version & 0xfff,
2662 prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without",
2663 hdmi->phy.name);
2664
2665 dw_hdmi_init_hw(hdmi);
2666
2667 irq = platform_get_irq(pdev, 0);
2668 if (irq < 0) {
2669 ret = irq;
2670 goto err_iahb;
2671 }
2672
2673 ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
2674 dw_hdmi_irq, IRQF_SHARED,
2675 dev_name(dev), hdmi);
2676 if (ret)
2677 goto err_iahb;
2678
2679 hdmi->cec_notifier = cec_notifier_get(dev);
2680 if (!hdmi->cec_notifier) {
2681 ret = -ENOMEM;
2682 goto err_iahb;
2683 }
2684
2685
2686
2687
2688
2689 hdmi_init_clk_regenerator(hdmi);
2690
2691
2692 if (!hdmi->ddc) {
2693
2694 hdmi->pinctrl = devm_pinctrl_get(dev);
2695 if (!IS_ERR(hdmi->pinctrl)) {
2696 hdmi->unwedge_state =
2697 pinctrl_lookup_state(hdmi->pinctrl, "unwedge");
2698 hdmi->default_state =
2699 pinctrl_lookup_state(hdmi->pinctrl, "default");
2700
2701 if (IS_ERR(hdmi->default_state) ||
2702 IS_ERR(hdmi->unwedge_state)) {
2703 if (!IS_ERR(hdmi->unwedge_state))
2704 dev_warn(dev,
2705 "Unwedge requires default pinctrl\n");
2706 hdmi->default_state = NULL;
2707 hdmi->unwedge_state = NULL;
2708 }
2709 }
2710
2711 hdmi->ddc = dw_hdmi_i2c_adapter(hdmi);
2712 if (IS_ERR(hdmi->ddc))
2713 hdmi->ddc = NULL;
2714 }
2715
2716 hdmi->bridge.driver_private = hdmi;
2717 hdmi->bridge.funcs = &dw_hdmi_bridge_funcs;
2718#ifdef CONFIG_OF
2719 hdmi->bridge.of_node = pdev->dev.of_node;
2720#endif
2721
2722 memset(&pdevinfo, 0, sizeof(pdevinfo));
2723 pdevinfo.parent = dev;
2724 pdevinfo.id = PLATFORM_DEVID_AUTO;
2725
2726 config0 = hdmi_readb(hdmi, HDMI_CONFIG0_ID);
2727 config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
2728
2729 if (iores && config3 & HDMI_CONFIG3_AHBAUDDMA) {
2730 struct dw_hdmi_audio_data audio;
2731
2732 audio.phys = iores->start;
2733 audio.base = hdmi->regs;
2734 audio.irq = irq;
2735 audio.hdmi = hdmi;
2736 audio.eld = hdmi->connector.eld;
2737 hdmi->enable_audio = dw_hdmi_ahb_audio_enable;
2738 hdmi->disable_audio = dw_hdmi_ahb_audio_disable;
2739
2740 pdevinfo.name = "dw-hdmi-ahb-audio";
2741 pdevinfo.data = &audio;
2742 pdevinfo.size_data = sizeof(audio);
2743 pdevinfo.dma_mask = DMA_BIT_MASK(32);
2744 hdmi->audio = platform_device_register_full(&pdevinfo);
2745 } else if (config0 & HDMI_CONFIG0_I2S) {
2746 struct dw_hdmi_i2s_audio_data audio;
2747
2748 audio.hdmi = hdmi;
2749 audio.write = hdmi_writeb;
2750 audio.read = hdmi_readb;
2751 hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
2752 hdmi->disable_audio = dw_hdmi_i2s_audio_disable;
2753
2754 pdevinfo.name = "dw-hdmi-i2s-audio";
2755 pdevinfo.data = &audio;
2756 pdevinfo.size_data = sizeof(audio);
2757 pdevinfo.dma_mask = DMA_BIT_MASK(32);
2758 hdmi->audio = platform_device_register_full(&pdevinfo);
2759 }
2760
2761 if (config0 & HDMI_CONFIG0_CEC) {
2762 cec.hdmi = hdmi;
2763 cec.ops = &dw_hdmi_cec_ops;
2764 cec.irq = irq;
2765
2766 pdevinfo.name = "dw-hdmi-cec";
2767 pdevinfo.data = &cec;
2768 pdevinfo.size_data = sizeof(cec);
2769 pdevinfo.dma_mask = 0;
2770
2771 hdmi->cec = platform_device_register_full(&pdevinfo);
2772 }
2773
2774 return hdmi;
2775
2776err_iahb:
2777 if (hdmi->i2c) {
2778 i2c_del_adapter(&hdmi->i2c->adap);
2779 hdmi->ddc = NULL;
2780 }
2781
2782 if (hdmi->cec_notifier)
2783 cec_notifier_put(hdmi->cec_notifier);
2784
2785 clk_disable_unprepare(hdmi->iahb_clk);
2786 if (hdmi->cec_clk)
2787 clk_disable_unprepare(hdmi->cec_clk);
2788err_isfr:
2789 clk_disable_unprepare(hdmi->isfr_clk);
2790err_res:
2791 i2c_put_adapter(hdmi->ddc);
2792
2793 return ERR_PTR(ret);
2794}
2795
2796static void __dw_hdmi_remove(struct dw_hdmi *hdmi)
2797{
2798 if (hdmi->audio && !IS_ERR(hdmi->audio))
2799 platform_device_unregister(hdmi->audio);
2800 if (!IS_ERR(hdmi->cec))
2801 platform_device_unregister(hdmi->cec);
2802
2803
2804 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);
2805
2806 if (hdmi->cec_notifier)
2807 cec_notifier_put(hdmi->cec_notifier);
2808
2809 clk_disable_unprepare(hdmi->iahb_clk);
2810 clk_disable_unprepare(hdmi->isfr_clk);
2811 if (hdmi->cec_clk)
2812 clk_disable_unprepare(hdmi->cec_clk);
2813
2814 if (hdmi->i2c)
2815 i2c_del_adapter(&hdmi->i2c->adap);
2816 else
2817 i2c_put_adapter(hdmi->ddc);
2818}
2819
2820
2821
2822
2823struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev,
2824 const struct dw_hdmi_plat_data *plat_data)
2825{
2826 struct dw_hdmi *hdmi;
2827
2828 hdmi = __dw_hdmi_probe(pdev, plat_data);
2829 if (IS_ERR(hdmi))
2830 return hdmi;
2831
2832 drm_bridge_add(&hdmi->bridge);
2833
2834 return hdmi;
2835}
2836EXPORT_SYMBOL_GPL(dw_hdmi_probe);
2837
2838void dw_hdmi_remove(struct dw_hdmi *hdmi)
2839{
2840 drm_bridge_remove(&hdmi->bridge);
2841
2842 __dw_hdmi_remove(hdmi);
2843}
2844EXPORT_SYMBOL_GPL(dw_hdmi_remove);
2845
2846
2847
2848
2849struct dw_hdmi *dw_hdmi_bind(struct platform_device *pdev,
2850 struct drm_encoder *encoder,
2851 const struct dw_hdmi_plat_data *plat_data)
2852{
2853 struct dw_hdmi *hdmi;
2854 int ret;
2855
2856 hdmi = __dw_hdmi_probe(pdev, plat_data);
2857 if (IS_ERR(hdmi))
2858 return hdmi;
2859
2860 ret = drm_bridge_attach(encoder, &hdmi->bridge, NULL);
2861 if (ret) {
2862 dw_hdmi_remove(hdmi);
2863 DRM_ERROR("Failed to initialize bridge with drm\n");
2864 return ERR_PTR(ret);
2865 }
2866
2867 return hdmi;
2868}
2869EXPORT_SYMBOL_GPL(dw_hdmi_bind);
2870
2871void dw_hdmi_unbind(struct dw_hdmi *hdmi)
2872{
2873 __dw_hdmi_remove(hdmi);
2874}
2875EXPORT_SYMBOL_GPL(dw_hdmi_unbind);
2876
2877void dw_hdmi_resume(struct dw_hdmi *hdmi)
2878{
2879 dw_hdmi_init_hw(hdmi);
2880}
2881EXPORT_SYMBOL_GPL(dw_hdmi_resume);
2882
2883MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
2884MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com>");
2885MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>");
2886MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>");
2887MODULE_DESCRIPTION("DW HDMI transmitter driver");
2888MODULE_LICENSE("GPL");
2889MODULE_ALIAS("platform:dw-hdmi");
2890