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