1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd
4 * Author: Algea Cao <algea.cao@rock-chips.com>
5 */
6
7 #include <common.h>
8 #include <malloc.h>
9 #include <syscon.h>
10 #include <asm/arch-rockchip/clock.h>
11 #include <asm/arch/vendor.h>
12 #include <edid.h>
13 #include <dm/device.h>
14 #include <dm/of_access.h>
15 #include <dm/ofnode.h>
16 #include <dm/read.h>
17 #include <linux/hdmi.h>
18 #include <linux/media-bus-format.h>
19 #include <linux/dw_hdmi.h>
20 #include <asm/io.h>
21 #include "rockchip_display.h"
22 #include "rockchip_crtc.h"
23 #include "rockchip_connector.h"
24 #include "dw_hdmi_qp.h"
25 #include "rockchip_phy.h"
26
27 enum frl_mask {
28 FRL_3GBPS_3LANE = 1,
29 FRL_6GBPS_3LANE,
30 FRL_6GBPS_4LANE,
31 FRL_8GBPS_4LANE,
32 FRL_10GBPS_4LANE,
33 FRL_12GBPS_4LANE,
34 };
35
36 #define DDC_CI_ADDR 0x37
37 #define DDC_SEGMENT_ADDR 0x30
38
39 #define HDMI_EDID_LEN 512
40
41 /* DW-HDMI Controller >= 0x200a are at least compliant with SCDC version 1 */
42 #define SCDC_MIN_SOURCE_VERSION 0x1
43
44 #define HDMI14_MAX_TMDSCLK 340000000
45
46 struct hdmi_vmode {
47 bool mdataenablepolarity;
48
49 unsigned int mpixelclock;
50 unsigned int mpixelrepetitioninput;
51 unsigned int mpixelrepetitionoutput;
52 unsigned int mtmdsclock;
53 };
54
55 struct hdmi_data_info {
56 unsigned int enc_in_bus_format;
57 unsigned int enc_out_bus_format;
58 unsigned int enc_in_encoding;
59 unsigned int enc_out_encoding;
60 unsigned int quant_range;
61 unsigned int pix_repet_factor;
62 struct hdmi_vmode video_mode;
63 };
64
65 struct dw_hdmi_phy_data {
66 enum dw_hdmi_phy_type type;
67 const char *name;
68 unsigned int gen;
69 bool has_svsret;
70 int (*configure)(struct dw_hdmi *hdmi,
71 const struct dw_hdmi_plat_data *pdata,
72 unsigned long mpixelclock);
73 };
74
75 struct dw_hdmi_i2c {
76 u8 slave_reg;
77 bool is_regaddr;
78 bool is_segment;
79
80 unsigned int scl_high_ns;
81 unsigned int scl_low_ns;
82 };
83
84 struct dw_hdmi_qp {
85 enum dw_hdmi_devtype dev_type;
86 unsigned int version;
87 struct hdmi_data_info hdmi_data;
88 struct hdmi_edid_data edid_data;
89 const struct dw_hdmi_plat_data *plat_data;
90 struct ddc_adapter adap;
91
92 int vic;
93 int id;
94
95 unsigned long bus_format;
96 bool cable_plugin;
97 bool sink_is_hdmi;
98 bool sink_has_audio;
99 void *regs;
100 void *rk_hdmi;
101 struct dw_hdmi_i2c *i2c;
102
103 struct {
104 const struct dw_hdmi_qp_phy_ops *ops;
105 const char *name;
106 void *data;
107 bool enabled;
108 } phy;
109
110 struct drm_display_mode previous_mode;
111
112 unsigned int sample_rate;
113 unsigned int audio_cts;
114 unsigned int audio_n;
115 bool audio_enable;
116 bool scramble_low_rates;
117
118 void (*write)(struct dw_hdmi_qp *hdmi, u32 val, int offset);
119 u8 (*read)(struct dw_hdmi_qp *hdmi, int offset);
120
121 bool hdcp1x_enable;
122 bool output_bus_format_rgb;
123 };
124
hdmi_writel(struct dw_hdmi_qp * hdmi,u32 val,int offset)125 static inline void hdmi_writel(struct dw_hdmi_qp *hdmi, u32 val, int offset)
126 {
127 writel(val, hdmi->regs + offset);
128 }
129
hdmi_readl(struct dw_hdmi_qp * hdmi,int offset)130 static inline u32 hdmi_readl(struct dw_hdmi_qp *hdmi, int offset)
131 {
132 return readl(hdmi->regs + offset);
133 }
134
135 static void
hdmi_modb(struct dw_hdmi_qp * hdmi,u32 data,u32 mask,unsigned int reg)136 hdmi_modb(struct dw_hdmi_qp *hdmi, u32 data, u32 mask, unsigned int reg)
137 {
138 u32 val = hdmi_readl(hdmi, reg) & ~mask;
139
140 val |= data & mask;
141 hdmi_writel(hdmi, val, reg);
142 }
143
hdmi_bus_fmt_is_rgb(unsigned int bus_format)144 static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
145 {
146 switch (bus_format) {
147 case MEDIA_BUS_FMT_RGB888_1X24:
148 case MEDIA_BUS_FMT_RGB101010_1X30:
149 case MEDIA_BUS_FMT_RGB121212_1X36:
150 case MEDIA_BUS_FMT_RGB161616_1X48:
151 return true;
152
153 default:
154 return false;
155 }
156 }
157
hdmi_bus_fmt_is_yuv444(unsigned int bus_format)158 static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
159 {
160 switch (bus_format) {
161 case MEDIA_BUS_FMT_YUV8_1X24:
162 case MEDIA_BUS_FMT_YUV10_1X30:
163 case MEDIA_BUS_FMT_YUV12_1X36:
164 case MEDIA_BUS_FMT_YUV16_1X48:
165 return true;
166
167 default:
168 return false;
169 }
170 }
171
hdmi_bus_fmt_is_yuv422(unsigned int bus_format)172 static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
173 {
174 switch (bus_format) {
175 case MEDIA_BUS_FMT_UYVY8_1X16:
176 case MEDIA_BUS_FMT_UYVY10_1X20:
177 case MEDIA_BUS_FMT_UYVY12_1X24:
178 case MEDIA_BUS_FMT_YUYV8_1X16:
179 case MEDIA_BUS_FMT_YUYV10_1X20:
180 case MEDIA_BUS_FMT_YUYV12_1X24:
181 return true;
182
183 default:
184 return false;
185 }
186 }
187
hdmi_bus_fmt_is_yuv420(unsigned int bus_format)188 static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format)
189 {
190 switch (bus_format) {
191 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
192 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
193 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
194 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
195 return true;
196
197 default:
198 return false;
199 }
200 }
201
hdmi_bus_fmt_color_depth(unsigned int bus_format)202 static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
203 {
204 switch (bus_format) {
205 case MEDIA_BUS_FMT_RGB888_1X24:
206 case MEDIA_BUS_FMT_YUV8_1X24:
207 case MEDIA_BUS_FMT_UYVY8_1X16:
208 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
209 return 8;
210
211 case MEDIA_BUS_FMT_RGB101010_1X30:
212 case MEDIA_BUS_FMT_YUV10_1X30:
213 case MEDIA_BUS_FMT_UYVY10_1X20:
214 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
215 return 10;
216
217 case MEDIA_BUS_FMT_RGB121212_1X36:
218 case MEDIA_BUS_FMT_YUV12_1X36:
219 case MEDIA_BUS_FMT_UYVY12_1X24:
220 case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
221 return 12;
222
223 case MEDIA_BUS_FMT_RGB161616_1X48:
224 case MEDIA_BUS_FMT_YUV16_1X48:
225 case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
226 return 16;
227
228 default:
229 return 0;
230 }
231 }
232
drm_scdc_set_scrambling(struct ddc_adapter * adapter,bool enable)233 static bool drm_scdc_set_scrambling(struct ddc_adapter *adapter, bool enable)
234 {
235 u8 config;
236 int ret;
237
238 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
239 if (ret < 0) {
240 debug("Failed to read TMDS config: %d\n", ret);
241 return false;
242 }
243
244 if (enable)
245 config |= SCDC_SCRAMBLING_ENABLE;
246 else
247 config &= ~SCDC_SCRAMBLING_ENABLE;
248
249 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
250 if (ret < 0) {
251 debug("Failed to enable scrambling: %d\n", ret);
252 return false;
253 }
254
255 return true;
256 }
257
258 static bool
drm_scdc_set_high_tmds_clock_ratio(struct ddc_adapter * adapter,bool set)259 drm_scdc_set_high_tmds_clock_ratio(struct ddc_adapter *adapter, bool set)
260 {
261 u8 config;
262 int ret;
263
264 ret = drm_scdc_readb(adapter, SCDC_TMDS_CONFIG, &config);
265 if (ret < 0) {
266 debug("Failed to read TMDS config: %d\n", ret);
267 return false;
268 }
269
270 if (set)
271 config |= SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
272 else
273 config &= ~SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
274
275 ret = drm_scdc_writeb(adapter, SCDC_TMDS_CONFIG, config);
276 if (ret < 0) {
277 debug("Failed to set TMDS clock ratio: %d\n", ret);
278 return false;
279 }
280
281 /*
282 * The spec says that a source should wait minimum 1ms and maximum
283 * 100ms after writing the TMDS config for clock ratio. Lets allow a
284 * wait of up to 2ms here.
285 */
286 udelay(2000);
287 return true;
288 }
289
dw_hdmi_i2c_init(struct dw_hdmi_qp * hdmi)290 static void dw_hdmi_i2c_init(struct dw_hdmi_qp *hdmi)
291 {
292 /* Software reset */
293 hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
294
295 hdmi_writel(hdmi, 0x085c085c, I2CM_FM_SCL_CONFIG0);
296
297 hdmi_modb(hdmi, 0, I2CM_FM_EN, I2CM_INTERFACE_CONTROL0);
298
299 /* Clear DONE and ERROR interrupts */
300 hdmi_writel(hdmi, I2CM_OP_DONE_CLEAR | I2CM_NACK_RCVD_CLEAR,
301 MAINUNIT_1_INT_CLEAR);
302 }
303
dw_hdmi_i2c_read(struct dw_hdmi_qp * hdmi,unsigned char * buf,unsigned int length)304 static int dw_hdmi_i2c_read(struct dw_hdmi_qp *hdmi,
305 unsigned char *buf, unsigned int length)
306 {
307 struct dw_hdmi_i2c *i2c = hdmi->i2c;
308 int i = 20;
309 u32 intr = 0;
310
311 if (!i2c->is_regaddr) {
312 printf("set read register address to 0\n");
313 i2c->slave_reg = 0x00;
314 i2c->is_regaddr = true;
315 }
316
317 while (length--) {
318 hdmi_modb(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
319 I2CM_INTERFACE_CONTROL0);
320
321 hdmi_modb(hdmi, I2CM_FM_READ, I2CM_WR_MASK,
322 I2CM_INTERFACE_CONTROL0);
323
324 while (i--) {
325 udelay(1000);
326 intr = hdmi_readl(hdmi, MAINUNIT_1_INT_STATUS) &
327 (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ |
328 I2CM_NACK_RCVD_IRQ);
329 if (intr) {
330 hdmi_writel(hdmi, intr, MAINUNIT_1_INT_CLEAR);
331 break;
332 }
333 }
334
335 if (!i) {
336 printf("i2c read time out!\n");
337 hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
338 return -EAGAIN;
339 }
340
341 /* Check for error condition on the bus */
342 if (intr & I2CM_NACK_RCVD_IRQ) {
343 printf("i2c read err!\n");
344 hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
345 return -EIO;
346 }
347
348 *buf++ = hdmi_readl(hdmi, I2CM_INTERFACE_RDDATA_0_3) & 0xff;
349 hdmi_modb(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
350 i = 20;
351 }
352 i2c->is_segment = false;
353
354 return 0;
355 }
356
dw_hdmi_i2c_write(struct dw_hdmi_qp * hdmi,unsigned char * buf,unsigned int length)357 static int dw_hdmi_i2c_write(struct dw_hdmi_qp *hdmi,
358 unsigned char *buf, unsigned int length)
359 {
360 struct dw_hdmi_i2c *i2c = hdmi->i2c;
361 int i = 20;
362 u32 intr = 0;
363
364 if (!i2c->is_regaddr) {
365 /* Use the first write byte as register address */
366 i2c->slave_reg = buf[0];
367 length--;
368 buf++;
369 i2c->is_regaddr = true;
370 }
371
372 while (length--) {
373 hdmi_writel(hdmi, *buf++, I2CM_INTERFACE_WRDATA_0_3);
374 hdmi_modb(hdmi, i2c->slave_reg++ << 12, I2CM_ADDR,
375 I2CM_INTERFACE_CONTROL0);
376 hdmi_modb(hdmi, I2CM_FM_WRITE, I2CM_WR_MASK,
377 I2CM_INTERFACE_CONTROL0);
378
379 while (i--) {
380 udelay(1000);
381 intr = hdmi_readl(hdmi, MAINUNIT_1_INT_STATUS) &
382 (I2CM_OP_DONE_IRQ | I2CM_READ_REQUEST_IRQ |
383 I2CM_NACK_RCVD_IRQ);
384 if (intr) {
385 hdmi_writel(hdmi, intr, MAINUNIT_1_INT_CLEAR);
386 break;
387 }
388 }
389
390 if (!i) {
391 printf("i2c write time out!\n");
392 hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
393 return -EAGAIN;
394 }
395
396 /* Check for error condition on the bus */
397 if (intr & I2CM_NACK_RCVD_IRQ) {
398 printf("i2c write nack!\n");
399 hdmi_writel(hdmi, 0x01, I2CM_CONTROL0);
400 return -EIO;
401 }
402 hdmi_modb(hdmi, 0, I2CM_WR_MASK, I2CM_INTERFACE_CONTROL0);
403 i = 20;
404 }
405
406 return 0;
407 }
408
dw_hdmi_i2c_xfer(struct ddc_adapter * adap,struct i2c_msg * msgs,int num)409 static int dw_hdmi_i2c_xfer(struct ddc_adapter *adap,
410 struct i2c_msg *msgs, int num)
411 {
412 struct dw_hdmi_qp *hdmi = container_of(adap, struct dw_hdmi_qp, adap);
413 struct dw_hdmi_i2c *i2c = hdmi->i2c;
414 u8 addr = msgs[0].addr;
415 int i, ret = 0;
416
417 debug("i2c xfer: num: %d, addr: %#x\n", num, addr);
418
419 for (i = 0; i < num; i++) {
420 if (msgs[i].len == 0) {
421 printf("unsupported transfer %d/%d, no data\n",
422 i + 1, num);
423 return -EOPNOTSUPP;
424 }
425 }
426
427 /* Unmute DONE and ERROR interrupts */
428 hdmi_modb(hdmi, I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
429 I2CM_NACK_RCVD_MASK_N | I2CM_OP_DONE_MASK_N,
430 MAINUNIT_1_INT_MASK_N);
431
432 /* Set slave device address taken from the first I2C message */
433 if (addr == DDC_SEGMENT_ADDR && msgs[0].len == 1)
434 addr = DDC_ADDR;
435
436 hdmi_modb(hdmi, addr << 5, I2CM_SLVADDR, I2CM_INTERFACE_CONTROL0);
437
438 /* Set slave device register address on transfer */
439 i2c->is_regaddr = false;
440
441 /* Set segment pointer for I2C extended read mode operation */
442 i2c->is_segment = false;
443
444 for (i = 0; i < num; i++) {
445 debug("xfer: num: %d/%d, len: %d, flags: %#x\n",
446 i + 1, num, msgs[i].len, msgs[i].flags);
447
448 if (msgs[i].addr == DDC_SEGMENT_ADDR && msgs[i].len == 1) {
449 i2c->is_segment = true;
450 hdmi_modb(hdmi, DDC_SEGMENT_ADDR, I2CM_SEG_ADDR,
451 I2CM_INTERFACE_CONTROL1);
452 hdmi_modb(hdmi, *msgs[i].buf, I2CM_SEG_PTR,
453 I2CM_INTERFACE_CONTROL1);
454 } else {
455 if (msgs[i].flags & I2C_M_RD)
456 ret = dw_hdmi_i2c_read(hdmi, msgs[i].buf,
457 msgs[i].len);
458 else
459 ret = dw_hdmi_i2c_write(hdmi, msgs[i].buf,
460 msgs[i].len);
461 }
462 if (ret < 0)
463 break;
464 }
465
466 if (!ret)
467 ret = num;
468
469 /* Mute DONE and ERROR interrupts */
470 hdmi_modb(hdmi, 0, I2CM_OP_DONE_MASK_N | I2CM_NACK_RCVD_MASK_N,
471 MAINUNIT_1_INT_MASK_N);
472
473 return ret;
474 }
475
dw_hdmi_detect_phy(struct dw_hdmi_qp * hdmi)476 static int dw_hdmi_detect_phy(struct dw_hdmi_qp *hdmi)
477 {
478 /* Vendor PHYs require support from the glue layer. */
479 if (!hdmi->plat_data->qp_phy_ops || !hdmi->plat_data->phy_name) {
480 dev_err(hdmi->dev,
481 "Vendor HDMI PHY not supported by glue layer\n");
482 return -ENODEV;
483 }
484
485 hdmi->phy.ops = hdmi->plat_data->qp_phy_ops;
486 hdmi->phy.data = hdmi->plat_data->phy_data;
487 hdmi->phy.name = hdmi->plat_data->phy_name;
488
489 return 0;
490 }
491
492 static unsigned int
hdmi_get_tmdsclock(struct dw_hdmi_qp * hdmi,unsigned long mpixelclock)493 hdmi_get_tmdsclock(struct dw_hdmi_qp *hdmi, unsigned long mpixelclock)
494 {
495 unsigned int tmdsclock = mpixelclock;
496 unsigned int depth =
497 hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format);
498
499 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) {
500 switch (depth) {
501 case 16:
502 tmdsclock = mpixelclock * 2;
503 break;
504 case 12:
505 tmdsclock = mpixelclock * 3 / 2;
506 break;
507 case 10:
508 tmdsclock = mpixelclock * 5 / 4;
509 break;
510 default:
511 break;
512 }
513 }
514
515 return tmdsclock;
516 }
517
hdmi_infoframe_set_checksum(u8 * ptr,int size)518 static void hdmi_infoframe_set_checksum(u8 *ptr, int size)
519 {
520 u8 csum = 0;
521 int i;
522
523 ptr[3] = 0;
524 /* compute checksum */
525 for (i = 0; i < size; i++)
526 csum += ptr[i];
527
528 ptr[3] = 256 - csum;
529 }
530
is_hdmi2_sink(struct dw_hdmi_qp * hdmi)531 static bool is_hdmi2_sink(struct dw_hdmi_qp *hdmi)
532 {
533 return hdmi->edid_data.display_info.hdmi.scdc.supported ||
534 hdmi->edid_data.display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
535 }
536
hdmi_config_AVI(struct dw_hdmi_qp * hdmi,struct drm_display_mode * mode)537 static void hdmi_config_AVI(struct dw_hdmi_qp *hdmi, struct drm_display_mode *mode)
538 {
539 struct hdmi_avi_infoframe frame;
540 u32 val, i, j;
541 u8 buff[17];
542 bool is_hdmi2 = false;
543 enum hdmi_quantization_range rgb_quant_range =
544 hdmi->hdmi_data.quant_range;
545
546 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) ||
547 hdmi->edid_data.display_info.hdmi.scdc.supported)
548 is_hdmi2 = true;
549 /* Initialise info frame from DRM mode */
550 drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2);
551
552 /*
553 * Ignore monitor selectable quantization, use quantization set
554 * by the user
555 */
556 drm_hdmi_avi_infoframe_quant_range(&frame, mode, rgb_quant_range,
557 true);
558 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
559 frame.colorspace = HDMI_COLORSPACE_YUV444;
560 else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
561 frame.colorspace = HDMI_COLORSPACE_YUV422;
562 else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
563 frame.colorspace = HDMI_COLORSPACE_YUV420;
564 else
565 frame.colorspace = HDMI_COLORSPACE_RGB;
566
567 /* Set up colorimetry and quant range */
568 if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
569 switch (hdmi->hdmi_data.enc_out_encoding) {
570 case V4L2_YCBCR_ENC_601:
571 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601)
572 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
573 else
574 frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
575 frame.extended_colorimetry =
576 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
577 break;
578 case V4L2_YCBCR_ENC_709:
579 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709)
580 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
581 else
582 frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
583 frame.extended_colorimetry =
584 HDMI_EXTENDED_COLORIMETRY_XV_YCC_709;
585 break;
586 case V4L2_YCBCR_ENC_BT2020:
587 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_BT2020)
588 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
589 else
590 frame.colorimetry = HDMI_COLORIMETRY_ITU_709;
591 frame.extended_colorimetry =
592 HDMI_EXTENDED_COLORIMETRY_BT2020;
593 break;
594 default: /* Carries no data */
595 frame.colorimetry = HDMI_COLORIMETRY_ITU_601;
596 frame.extended_colorimetry =
597 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
598 break;
599 }
600
601 frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
602 } else {
603 if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_BT2020) {
604 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED;
605 frame.extended_colorimetry =
606 HDMI_EXTENDED_COLORIMETRY_BT2020;
607 } else {
608 frame.colorimetry = HDMI_COLORIMETRY_NONE;
609 frame.extended_colorimetry =
610 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601;
611 }
612
613 if (is_hdmi2_sink(hdmi) &&
614 frame.quantization_range == HDMI_QUANTIZATION_RANGE_FULL)
615 frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_FULL;
616 else
617 frame.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
618 }
619
620 frame.scan_mode = HDMI_SCAN_MODE_NONE;
621
622 hdmi_avi_infoframe_pack_only(&frame, buff, 17);
623
624 /* mode which vic >= 128 must use avi version 3 */
625 if (hdmi->vic >= 128) {
626 frame.version = 3;
627 buff[1] = frame.version;
628 buff[4] &= 0x1f;
629 buff[4] |= ((frame.colorspace & 0x7) << 5);
630 buff[7] = hdmi->vic;
631 hdmi_infoframe_set_checksum(buff, 17);
632 }
633
634 /*
635 * The Designware IP uses a different byte format from standard
636 * AVI info frames, though generally the bits are in the correct
637 * bytes.
638 */
639
640 val = (frame.version << 8) | (frame.length << 16);
641 hdmi_writel(hdmi, val, PKT_AVI_CONTENTS0);
642
643 for (i = 0; i < 4; i++) {
644 for (j = 0; j < 4; j++) {
645 if (i * 4 + j >= 14)
646 break;
647 if (!j)
648 val = buff[i * 4 + j + 3];
649 val |= buff[i * 4 + j + 3] << (8 * j);
650 }
651
652 hdmi_writel(hdmi, val, PKT_AVI_CONTENTS1 + i * 4);
653 }
654
655 hdmi_modb(hdmi, 0, PKTSCHED_AVI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
656
657 hdmi_modb(hdmi, PKTSCHED_AVI_TX_EN, PKTSCHED_AVI_TX_EN,
658 PKTSCHED_PKT_EN);
659 }
660
661 #define VSI_PKT_TYPE 0x81
662 #define VSI_PKT_VERSION 1
663 #define HDMI_FORUM_OUI 0xc45dd8
664 #define ALLM_MODE BIT(1)
665 #define HDMI_FORUM_LEN 9
666
hdmi_config_vendor_specific_infoframe(struct dw_hdmi_qp * hdmi,struct drm_display_mode * mode)667 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi_qp *hdmi,
668 struct drm_display_mode *mode)
669 {
670 struct hdmi_vendor_infoframe frame;
671 struct dw_hdmi_link_config *link_cfg = NULL;
672 u8 buffer[10];
673 u32 val;
674 ssize_t err;
675 int i, reg;
676
677 link_cfg = dw_hdmi_rockchip_get_link_cfg(hdmi->rk_hdmi);
678
679 hdmi_modb(hdmi, 0, PKTSCHED_VSI_TX_EN, PKTSCHED_PKT_EN);
680
681 for (i = 0; i <= 7; i++)
682 hdmi_writel(hdmi, 0, PKT_VSI_CONTENTS0 + i * 4);
683
684 if (link_cfg->allm_en) {
685 buffer[0] = VSI_PKT_TYPE;
686 buffer[1] = VSI_PKT_VERSION;
687 buffer[2] = 5;
688 buffer[4] = HDMI_FORUM_OUI & 0xff;
689 buffer[5] = (HDMI_FORUM_OUI >> 8) & 0xff;
690 buffer[6] = (HDMI_FORUM_OUI >> 16) & 0xff;
691 buffer[7] = VSI_PKT_VERSION;
692 buffer[8] = ALLM_MODE;
693
694 hdmi_infoframe_set_checksum(buffer, HDMI_FORUM_LEN);
695
696 err = 9;
697 } else {
698 err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode);
699 if (err < 0)
700 /*
701 * Going into that statement does not means vendor infoframe
702 * fails. It just informed us that vendor infoframe is not
703 * needed for the selected mode. Only 4k or stereoscopic 3D
704 * mode requires vendor infoframe. So just simply return.
705 */
706 return;
707
708 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer));
709 if (err < 0) {
710 dev_err(hdmi->dev, "Failed to pack vendor infoframe: %zd\n",
711 err);
712 return;
713 }
714 }
715
716 /* vsi header */
717 val = (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
718 hdmi_writel(hdmi, val, PKT_VSI_CONTENTS0);
719
720 reg = PKT_VSI_CONTENTS1;
721 for (i = 3; i < err; i++) {
722 if (i % 4 == 3)
723 val = buffer[i];
724 if (i % 4 == 0)
725 val |= buffer[i] << 8;
726 if (i % 4 == 1)
727 val |= buffer[i] << 16;
728 if (i % 4 == 2)
729 val |= buffer[i] << 24;
730
731 if ((i % 4 == 2) || (i == (err - 1))) {
732 hdmi_writel(hdmi, val, reg);
733 reg += 4;
734 }
735 }
736
737 hdmi_writel(hdmi, 0, PKT_VSI_CONTENTS7);
738
739 hdmi_modb(hdmi, 0, PKTSCHED_VSI_FIELDRATE, PKTSCHED_PKT_CONFIG1);
740 hdmi_modb(hdmi, PKTSCHED_VSI_TX_EN, PKTSCHED_VSI_TX_EN,
741 PKTSCHED_PKT_EN);
742 }
743
hdmi_config_CVTEM(struct dw_hdmi_qp * hdmi,struct dw_hdmi_link_config * link_cfg)744 static void hdmi_config_CVTEM(struct dw_hdmi_qp *hdmi,
745 struct dw_hdmi_link_config *link_cfg)
746 {
747 u8 ds_type = 0;
748 u8 sync = 1;
749 u8 vfr = 1;
750 u8 afr = 0;
751 u8 new = 1;
752 u8 end = 0;
753 u8 data_set_length = 136;
754 u8 hb1[6] = { 0x80, 0, 0, 0, 0, 0x40 };
755 u8 *pps_body;
756 u32 val, i, reg;
757 struct drm_display_mode *mode = &hdmi->previous_mode;
758 int hsync, hfront, hback;
759
760 hdmi_modb(hdmi, 0, PKTSCHED_EMP_CVTEM_TX_EN, PKTSCHED_PKT_EN);
761
762 if (!link_cfg->dsc_mode) {
763 printf("don't use dsc mode\n");
764 return;
765 }
766
767 pps_body = link_cfg->pps_payload;
768
769 hsync = mode->hsync_end - mode->hsync_start;
770 hback = mode->htotal - mode->hsync_end;
771 hfront = mode->hsync_start - mode->hdisplay;
772
773 for (i = 0; i < 6; i++) {
774 val = i << 16 | hb1[i] << 8;
775 hdmi_writel(hdmi, val, PKT0_EMP_CVTEM_CONTENTS0 + i * 0x20);
776 }
777
778 val = new << 7 | end << 6 | ds_type << 4 | afr << 3 |
779 vfr << 2 | sync << 1;
780 hdmi_writel(hdmi, val, PKT0_EMP_CVTEM_CONTENTS1);
781
782 val = data_set_length << 16 | pps_body[0] << 24;
783 hdmi_writel(hdmi, val, PKT0_EMP_CVTEM_CONTENTS2);
784
785 reg = PKT0_EMP_CVTEM_CONTENTS3;
786 for (i = 1; i < 125; i++) {
787 if (reg == PKT1_EMP_CVTEM_CONTENTS0 ||
788 reg == PKT2_EMP_CVTEM_CONTENTS0 ||
789 reg == PKT3_EMP_CVTEM_CONTENTS0 ||
790 reg == PKT4_EMP_CVTEM_CONTENTS0 ||
791 reg == PKT5_EMP_CVTEM_CONTENTS0) {
792 reg += 4;
793 i--;
794 continue;
795 }
796 if (i % 4 == 1)
797 val = pps_body[i];
798 if (i % 4 == 2)
799 val |= pps_body[i] << 8;
800 if (i % 4 == 3)
801 val |= pps_body[i] << 16;
802 if (!(i % 4)) {
803 val |= pps_body[i] << 24;
804 hdmi_writel(hdmi, val, reg);
805 reg += 4;
806 }
807 }
808
809 val = (hfront & 0xff) << 24 | pps_body[127] << 16 |
810 pps_body[126] << 8 | pps_body[125];
811 hdmi_writel(hdmi, val, PKT4_EMP_CVTEM_CONTENTS6);
812
813 val = (hback & 0xff) << 24 | ((hsync >> 8) & 0xff) << 16 |
814 (hsync & 0xff) << 8 | ((hfront >> 8) & 0xff);
815 hdmi_writel(hdmi, val, PKT4_EMP_CVTEM_CONTENTS7);
816
817 val = link_cfg->hcactive << 8 | ((hback >> 8) & 0xff);
818 hdmi_writel(hdmi, val, PKT5_EMP_CVTEM_CONTENTS1);
819
820 for (i = PKT5_EMP_CVTEM_CONTENTS2; i <= PKT5_EMP_CVTEM_CONTENTS7; i += 4)
821 hdmi_writel(hdmi, 0, i);
822
823 hdmi_modb(hdmi, PKTSCHED_EMP_CVTEM_TX_EN, PKTSCHED_EMP_CVTEM_TX_EN,
824 PKTSCHED_PKT_EN);
825 }
826
hdmi_set_frl_mask(int frl_rate)827 static int hdmi_set_frl_mask(int frl_rate)
828 {
829 switch (frl_rate) {
830 case 48:
831 return FRL_12GBPS_4LANE;
832 case 40:
833 return FRL_10GBPS_4LANE;
834 case 32:
835 return FRL_8GBPS_4LANE;
836 case 24:
837 return FRL_6GBPS_4LANE;
838 case 18:
839 return FRL_6GBPS_3LANE;
840 case 9:
841 return FRL_3GBPS_3LANE;
842 }
843
844 return 0;
845 }
846
hdmi_start_flt(struct dw_hdmi_qp * hdmi,u8 rate)847 static int hdmi_start_flt(struct dw_hdmi_qp *hdmi, u8 rate)
848 {
849 u8 val;
850 u32 value;
851 u8 ffe_lv = 0;
852 int i = 0;
853 bool ltsp = false;
854
855 hdmi_modb(hdmi, AVP_DATAPATH_VIDEO_SWDISABLE,
856 AVP_DATAPATH_VIDEO_SWDISABLE, GLOBAL_SWDISABLE);
857
858 hdmi_writel(hdmi, AVP_DATAPATH_SWINIT_P, GLOBAL_SWRESET_REQUEST);
859
860 /* clear flt flags */
861 drm_scdc_writeb(&hdmi->adap, 0x10, 0xff);
862
863 /* FLT_READY & FFE_LEVELS read */
864 for (i = 0; i < 20; i++) {
865 drm_scdc_readb(&hdmi->adap, SCDC_STATUS_FLAGS_0, &val);
866 if (val & BIT(6))
867 break;
868 mdelay(20);
869 }
870
871 if (i == 20) {
872 printf("sink flt isn't ready\n");
873 return -EINVAL;
874 }
875
876 /* max ffe level 3 */
877 val = 0 << 4 | hdmi_set_frl_mask(rate);
878 drm_scdc_writeb(&hdmi->adap, 0x31, val);
879 /* select FRL_RATE & FFE_LEVELS */
880 hdmi_writel(hdmi, ffe_lv, FLT_CONFIG0);
881
882 i = 500;
883 while (i--) {
884 mdelay(4);
885 drm_scdc_readb(&hdmi->adap, 0x10, &val);
886
887 if (!(val & 0x30))
888 continue;
889
890 if (val & BIT(5)) {
891 u8 reg_val, ln0, ln1, ln2, ln3;
892
893 drm_scdc_readb(&hdmi->adap, 0x41, ®_val);
894 ln0 = reg_val & 0xf;
895 ln1 = (reg_val >> 4) & 0xf;
896
897 drm_scdc_readb(&hdmi->adap, 0x42, ®_val);
898 ln2 = reg_val & 0xf;
899 ln3 = (reg_val >> 4) & 0xf;
900
901 if (!ln0 && !ln1 && !ln2 && !ln3) {
902 printf("goto ltsp\n");
903 ltsp = true;
904 hdmi_writel(hdmi, 0, FLT_CONFIG1);
905 } else if ((ln0 == 0xf) | (ln1 == 0xf) | (ln2 == 0xf) | (ln3 == 0xf)) {
906 printf("goto lts4\n");
907 break;
908 } else if ((ln0 == 0xe) | (ln1 == 0xe) | (ln2 == 0xe) | (ln3 == 0xe)) {
909 printf("goto ffe\n");
910 break;
911 } else {
912 value = (ln3 << 16) | (ln2 << 12) | (ln1 << 8) | (ln0 << 4) | 0xf;
913 hdmi_writel(hdmi, value, FLT_CONFIG1);
914 }
915 }
916
917 drm_scdc_writeb(&hdmi->adap, 0x10, val);
918
919 if ((val & BIT(4)) && ltsp) {
920 hdmi_modb(hdmi, 0, AVP_DATAPATH_VIDEO_SWDISABLE, GLOBAL_SWDISABLE);
921 printf("flt success\n");
922 break;
923 }
924 }
925
926 if (i < 0) {
927 printf("flt time out\n");
928 return -ETIMEDOUT;
929 }
930
931 return 0;
932 }
933
934 #define HDMI_MODE_FRL_MASK BIT(30)
935
hdmi_set_op_mode(struct dw_hdmi_qp * hdmi,struct dw_hdmi_link_config * link_cfg,struct display_state * state,struct rockchip_connector * conn)936 static void hdmi_set_op_mode(struct dw_hdmi_qp *hdmi,
937 struct dw_hdmi_link_config *link_cfg,
938 struct display_state *state,
939 struct rockchip_connector *conn)
940 {
941 int frl_rate;
942 int i, ret;
943
944 if (!link_cfg->frl_mode) {
945 printf("dw hdmi qp use tmds mode\n");
946 hdmi_modb(hdmi, 0, OPMODE_FRL, LINK_CONFIG0);
947 hdmi_modb(hdmi, 0, OPMODE_FRL_4LANES, LINK_CONFIG0);
948 hdmi->phy.ops->init(conn, hdmi->rk_hdmi, state);
949 hdmi->phy.enabled = true;
950 return;
951 }
952
953 if (link_cfg->frl_lanes == 4)
954 hdmi_modb(hdmi, OPMODE_FRL_4LANES, OPMODE_FRL_4LANES,
955 LINK_CONFIG0);
956 else
957 hdmi_modb(hdmi, 0, OPMODE_FRL_4LANES, LINK_CONFIG0);
958
959 hdmi_modb(hdmi, 1, OPMODE_FRL, LINK_CONFIG0);
960
961 frl_rate = link_cfg->frl_lanes * link_cfg->rate_per_lane;
962 hdmi->phy.ops->init(conn, hdmi->rk_hdmi, state);
963 hdmi->phy.enabled = true;
964
965 mdelay(200);
966 ret = hdmi_start_flt(hdmi, frl_rate);
967 if (ret) {
968 hdmi_writel(hdmi, 0, FLT_CONFIG0);
969 drm_scdc_writeb(&hdmi->adap, 0x31, 0);
970 hdmi_modb(hdmi, 0, AVP_DATAPATH_VIDEO_SWDISABLE, GLOBAL_SWDISABLE);
971 return;
972 }
973
974 for (i = 0; i < 200; i++) {
975 hdmi_modb(hdmi, PKTSCHED_NULL_TX_EN, PKTSCHED_NULL_TX_EN, PKTSCHED_PKT_EN);
976 udelay(50);
977 hdmi_modb(hdmi, 0, PKTSCHED_NULL_TX_EN, PKTSCHED_PKT_EN);
978 udelay(50);
979 }
980 }
981
dw_hdmi_setup(struct dw_hdmi_qp * hdmi,struct rockchip_connector * conn,struct drm_display_mode * mode,struct display_state * state)982 static int dw_hdmi_setup(struct dw_hdmi_qp *hdmi,
983 struct rockchip_connector *conn,
984 struct drm_display_mode *mode,
985 struct display_state *state)
986 {
987 int ret;
988 void *data = hdmi->plat_data->phy_data;
989 struct dw_hdmi_link_config *link_cfg;
990 struct drm_hdmi_info *hdmi_info = &hdmi->edid_data.display_info.hdmi;
991 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
992 u8 bytes = 0;
993
994 if (!hdmi->vic)
995 printf("Non-CEA mode used in HDMI\n");
996 else
997 printf("CEA mode used vic=%d\n", hdmi->vic);
998
999 vmode->mpixelclock = mode->clock * 1000;
1000 vmode->mtmdsclock = hdmi_get_tmdsclock(hdmi, vmode->mpixelclock);
1001 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format))
1002 vmode->mtmdsclock /= 2;
1003 printf("mtmdsclock:%d\n", vmode->mtmdsclock);
1004
1005 if (hdmi->plat_data->get_enc_out_encoding)
1006 hdmi->hdmi_data.enc_out_encoding =
1007 hdmi->plat_data->get_enc_out_encoding(data);
1008 else if (hdmi->vic == 6 || hdmi->vic == 7 ||
1009 hdmi->vic == 21 || hdmi->vic == 22 ||
1010 hdmi->vic == 2 || hdmi->vic == 3 ||
1011 hdmi->vic == 17 || hdmi->vic == 18)
1012 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601;
1013 else
1014 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709;
1015
1016 if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
1017 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
1018 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 1;
1019 } else {
1020 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
1021 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
1022 }
1023
1024 /* TOFIX: Get input encoding from plat data or fallback to none */
1025 if (hdmi->plat_data->get_enc_in_encoding)
1026 hdmi->hdmi_data.enc_in_encoding =
1027 hdmi->plat_data->get_enc_in_encoding(data);
1028 else if (hdmi->plat_data->input_bus_encoding)
1029 hdmi->hdmi_data.enc_in_encoding =
1030 hdmi->plat_data->input_bus_encoding;
1031 else
1032 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT;
1033
1034 if (hdmi->plat_data->get_quant_range)
1035 hdmi->hdmi_data.quant_range =
1036 hdmi->plat_data->get_quant_range(data);
1037 else
1038 hdmi->hdmi_data.quant_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
1039
1040 /*
1041 * According to the dw-hdmi specification 6.4.2
1042 * vp_pr_cd[3:0]:
1043 * 0000b: No pixel repetition (pixel sent only once)
1044 * 0001b: Pixel sent two times (pixel repeated once)
1045 */
1046 hdmi->hdmi_data.pix_repet_factor =
1047 (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0;
1048 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
1049
1050 /* HDMI Initialization Step B.2 */
1051 hdmi->phy.ops->set_pll(conn, hdmi->rk_hdmi, state);
1052
1053 /* Mark yuv422 10bit */
1054 if (hdmi->hdmi_data.enc_out_bus_format == MEDIA_BUS_FMT_YUYV10_1X20)
1055 hdmi_writel(hdmi, BIT(20), VIDEO_INTERFACE_CONFIG0);
1056 rk3588_set_grf_cfg(hdmi->rk_hdmi);
1057 link_cfg = dw_hdmi_rockchip_get_link_cfg(hdmi->rk_hdmi);
1058
1059 /* not for DVI mode */
1060 if (hdmi->sink_is_hdmi) {
1061 printf("%s HDMI mode\n", __func__);
1062 hdmi_modb(hdmi, 0, OPMODE_DVI, LINK_CONFIG0);
1063 hdmi_modb(hdmi, HDCP2_BYPASS, HDCP2_BYPASS, HDCP2LOGIC_CONFIG0);
1064 hdmi_modb(hdmi, KEEPOUT_REKEY_ALWAYS, KEEPOUT_REKEY_CFG, FRAME_COMPOSER_CONFIG9);
1065 hdmi_writel(hdmi, 0, FLT_CONFIG0);
1066 if (hdmi_info->scdc.supported)
1067 drm_scdc_writeb(&hdmi->adap, 0x31, 0);
1068 if (!link_cfg->frl_mode) {
1069 if (vmode->mtmdsclock > HDMI14_MAX_TMDSCLK) {
1070 drm_scdc_readb(&hdmi->adap, SCDC_SINK_VERSION, &bytes);
1071 drm_scdc_writeb(&hdmi->adap, SCDC_SOURCE_VERSION,
1072 min_t(u8, bytes, SCDC_MIN_SOURCE_VERSION));
1073 drm_scdc_set_high_tmds_clock_ratio(&hdmi->adap, 1);
1074 drm_scdc_set_scrambling(&hdmi->adap, 1);
1075 hdmi_writel(hdmi, 1, SCRAMB_CONFIG0);
1076 mdelay(100);
1077 } else {
1078 if (hdmi_info->scdc.supported) {
1079 drm_scdc_set_high_tmds_clock_ratio(&hdmi->adap, 0);
1080 drm_scdc_set_scrambling(&hdmi->adap, 0);
1081 }
1082 hdmi_writel(hdmi, 0, SCRAMB_CONFIG0);
1083 }
1084 }
1085 /* HDMI Initialization Step F - Configure AVI InfoFrame */
1086 hdmi_config_AVI(hdmi, mode);
1087 hdmi_config_vendor_specific_infoframe(hdmi, mode);
1088 hdmi_config_CVTEM(hdmi, link_cfg);
1089 hdmi_set_op_mode(hdmi, link_cfg, state, conn);
1090 /* clear avmute */
1091 mdelay(50);
1092 hdmi_writel(hdmi, 2, PKTSCHED_PKT_CONTROL0);
1093 hdmi_modb(hdmi, PKTSCHED_GCP_TX_EN, PKTSCHED_GCP_TX_EN,
1094 PKTSCHED_PKT_EN);
1095 } else {
1096 hdmi_modb(hdmi, OPMODE_DVI, OPMODE_DVI, LINK_CONFIG0);
1097 ret = hdmi->phy.ops->init(conn, hdmi->rk_hdmi, state);
1098 if (ret)
1099 return ret;
1100 hdmi->phy.enabled = true;
1101 printf("%s DVI mode\n", __func__);
1102 }
1103
1104 /* Mark uboot hdmi is enabled */
1105 hdmi_writel(hdmi, BIT(21), VIDEO_INTERFACE_CONFIG0);
1106
1107 return 0;
1108 }
1109
dw_hdmi_detect_hotplug(struct dw_hdmi_qp * hdmi,struct display_state * state)1110 int dw_hdmi_detect_hotplug(struct dw_hdmi_qp *hdmi,
1111 struct display_state *state)
1112 {
1113 struct connector_state *conn_state = &state->conn_state;
1114 int ret;
1115
1116 ret = hdmi->phy.ops->read_hpd(hdmi->rk_hdmi);
1117 if (ret || state->force_output) {
1118 if (!hdmi->id)
1119 conn_state->output_if |= VOP_OUTPUT_IF_HDMI0;
1120 else
1121 conn_state->output_if |= VOP_OUTPUT_IF_HDMI1;
1122 }
1123
1124 return ret;
1125 }
1126
rockchip_dw_hdmi_qp_init(struct rockchip_connector * conn,struct display_state * state)1127 int rockchip_dw_hdmi_qp_init(struct rockchip_connector *conn, struct display_state *state)
1128 {
1129 struct connector_state *conn_state = &state->conn_state;
1130 const struct dw_hdmi_plat_data *pdata =
1131 (const struct dw_hdmi_plat_data *)dev_get_driver_data(conn->dev);
1132 void *rk_hdmi = dev_get_priv(conn->dev);
1133 struct dw_hdmi_qp *hdmi;
1134 struct drm_display_mode *mode_buf;
1135 ofnode hdmi_node = conn->dev->node;
1136 struct device_node *ddc_node;
1137
1138 hdmi = malloc(sizeof(struct dw_hdmi_qp));
1139 if (!hdmi)
1140 return -ENOMEM;
1141
1142 memset(hdmi, 0, sizeof(struct dw_hdmi_qp));
1143 mode_buf = malloc(MODE_LEN * sizeof(struct drm_display_mode));
1144 if (!mode_buf)
1145 return -ENOMEM;
1146
1147 hdmi->rk_hdmi = rk_hdmi;
1148 hdmi->id = of_alias_get_id(ofnode_to_np(hdmi_node), "hdmi");
1149 if (hdmi->id < 0)
1150 hdmi->id = 0;
1151 conn_state->disp_info = rockchip_get_disp_info(conn_state->type, hdmi->id);
1152
1153 memset(mode_buf, 0, MODE_LEN * sizeof(struct drm_display_mode));
1154
1155 hdmi->regs = dev_read_addr_ptr(conn->dev);
1156
1157 ddc_node = of_parse_phandle(ofnode_to_np(hdmi_node), "ddc-i2c-bus", 0);
1158 if (ddc_node) {
1159 uclass_get_device_by_ofnode(UCLASS_I2C, np_to_ofnode(ddc_node),
1160 &hdmi->adap.i2c_bus);
1161 if (hdmi->adap.i2c_bus)
1162 hdmi->adap.ops = i2c_get_ops(hdmi->adap.i2c_bus);
1163 }
1164
1165 hdmi->i2c = malloc(sizeof(struct dw_hdmi_i2c));
1166 if (!hdmi->i2c)
1167 return -ENOMEM;
1168 hdmi->adap.ddc_xfer = dw_hdmi_i2c_xfer;
1169
1170 /*
1171 * Read high and low time from device tree. If not available use
1172 * the default timing scl clock rate is about 99.6KHz.
1173 */
1174 hdmi->i2c->scl_high_ns =
1175 ofnode_read_s32_default(hdmi_node,
1176 "ddc-i2c-scl-high-time-ns", 4708);
1177 hdmi->i2c->scl_low_ns =
1178 ofnode_read_s32_default(hdmi_node,
1179 "ddc-i2c-scl-low-time-ns", 4916);
1180
1181 dw_hdmi_i2c_init(hdmi);
1182 conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA;
1183
1184 hdmi->dev_type = pdata->dev_type;
1185 hdmi->plat_data = pdata;
1186 hdmi->edid_data.mode_buf = mode_buf;
1187
1188 conn->data = hdmi;
1189
1190 dw_hdmi_detect_phy(hdmi);
1191 hdmi_writel(hdmi, 0, MAINUNIT_0_INT_MASK_N);
1192 hdmi_writel(hdmi, 0, MAINUNIT_1_INT_MASK_N);
1193 hdmi_writel(hdmi, 428571429, TIMER_BASE_CONFIG0);
1194
1195 dw_hdmi_qp_set_iomux(hdmi->rk_hdmi);
1196
1197 return 0;
1198 }
1199
rockchip_dw_hdmi_qp_deinit(struct rockchip_connector * conn,struct display_state * state)1200 void rockchip_dw_hdmi_qp_deinit(struct rockchip_connector *conn, struct display_state *state)
1201 {
1202 struct dw_hdmi_qp *hdmi = conn->data;
1203
1204 if (hdmi->i2c)
1205 free(hdmi->i2c);
1206 if (hdmi->edid_data.mode_buf)
1207 free(hdmi->edid_data.mode_buf);
1208 if (hdmi)
1209 free(hdmi);
1210 }
1211
rockchip_dw_hdmi_qp_prepare(struct rockchip_connector * conn,struct display_state * state)1212 int rockchip_dw_hdmi_qp_prepare(struct rockchip_connector *conn, struct display_state *state)
1213 {
1214 return 0;
1215 }
1216
dw_hdmi_disable(struct rockchip_connector * conn,struct dw_hdmi_qp * hdmi,struct display_state * state)1217 static void dw_hdmi_disable(struct rockchip_connector *conn, struct dw_hdmi_qp *hdmi,
1218 struct display_state *state)
1219 {
1220 if (hdmi->phy.enabled) {
1221 hdmi->phy.ops->disable(conn, hdmi->rk_hdmi, state);
1222 hdmi->phy.enabled = false;
1223 }
1224 }
1225
rockchip_dw_hdmi_qp_enable(struct rockchip_connector * conn,struct display_state * state)1226 int rockchip_dw_hdmi_qp_enable(struct rockchip_connector *conn, struct display_state *state)
1227 {
1228 struct connector_state *conn_state = &state->conn_state;
1229 struct drm_display_mode *mode = &conn_state->mode;
1230 struct dw_hdmi_qp *hdmi = conn->data;
1231
1232 if (!hdmi)
1233 return -EFAULT;
1234
1235 /* Store the display mode for plugin/DKMS poweron events */
1236 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
1237
1238 dw_hdmi_setup(hdmi, conn, mode, state);
1239
1240 return 0;
1241 }
1242
rockchip_dw_hdmi_qp_disable(struct rockchip_connector * conn,struct display_state * state)1243 int rockchip_dw_hdmi_qp_disable(struct rockchip_connector *conn, struct display_state *state)
1244 {
1245 struct dw_hdmi_qp *hdmi = conn->data;
1246
1247 dw_hdmi_disable(conn, hdmi, state);
1248 return 0;
1249 }
1250
rockchip_dw_hdmi_qp_mode_valid(struct dw_hdmi_qp * hdmi)1251 static void rockchip_dw_hdmi_qp_mode_valid(struct dw_hdmi_qp *hdmi)
1252 {
1253 struct hdmi_edid_data *edid_data = &hdmi->edid_data;
1254 int i;
1255
1256 for (i = 0; i < edid_data->modes; i++) {
1257 if (edid_data->mode_buf[i].invalid)
1258 continue;
1259 if (edid_data->mode_buf[i].clock <= 25000)
1260 edid_data->mode_buf[i].invalid = true;
1261 }
1262 }
1263
_rockchip_dw_hdmi_qp_get_timing(struct rockchip_connector * conn,struct display_state * state,int edid_status)1264 static int _rockchip_dw_hdmi_qp_get_timing(struct rockchip_connector *conn,
1265 struct display_state *state, int edid_status)
1266 {
1267 int i;
1268 struct connector_state *conn_state = &state->conn_state;
1269 struct drm_display_mode *mode = &conn_state->mode;
1270 struct dw_hdmi_qp *hdmi = conn->data;
1271 struct edid *edid = (struct edid *)conn_state->edid;
1272 unsigned int bus_format;
1273 unsigned long enc_out_encoding;
1274 struct overscan *overscan = &conn_state->overscan;
1275 const u8 def_modes_vic[6] = {4, 16, 2, 17, 31, 19};
1276
1277 if (!hdmi)
1278 return -EFAULT;
1279
1280 if (!edid_status) {
1281 hdmi->sink_is_hdmi =
1282 drm_detect_hdmi_monitor(edid);
1283 hdmi->sink_has_audio = drm_detect_monitor_audio(edid);
1284 edid_status = drm_add_edid_modes(&hdmi->edid_data, conn_state->edid);
1285 }
1286 if (edid_status < 0) {
1287 hdmi->sink_is_hdmi = true;
1288 hdmi->sink_has_audio = true;
1289 do_cea_modes(&hdmi->edid_data, def_modes_vic,
1290 sizeof(def_modes_vic));
1291 hdmi->edid_data.preferred_mode = &hdmi->edid_data.mode_buf[0];
1292 printf("failed to get edid\n");
1293 }
1294 drm_rk_filter_whitelist(&hdmi->edid_data);
1295 rockchip_dw_hdmi_qp_mode_valid(hdmi);
1296 drm_mode_max_resolution_filter(&hdmi->edid_data,
1297 &state->crtc_state.max_output);
1298 if (!drm_mode_prune_invalid(&hdmi->edid_data)) {
1299 printf("can't find valid hdmi mode\n");
1300 return -EINVAL;
1301 }
1302
1303 for (i = 0; i < hdmi->edid_data.modes; i++)
1304 hdmi->edid_data.mode_buf[i].vrefresh =
1305 drm_mode_vrefresh(&hdmi->edid_data.mode_buf[i]);
1306
1307 drm_mode_sort(&hdmi->edid_data);
1308 dw_hdmi_qp_selete_output(&hdmi->edid_data, conn, &bus_format,
1309 overscan, hdmi->dev_type,
1310 hdmi->output_bus_format_rgb, hdmi->rk_hdmi,
1311 state);
1312
1313 *mode = *hdmi->edid_data.preferred_mode;
1314 hdmi->vic = drm_match_cea_mode(mode);
1315
1316 printf("mode:%dx%d bus_format:0x%x\n", mode->hdisplay, mode->vdisplay, bus_format);
1317 conn_state->bus_format = bus_format;
1318 hdmi->hdmi_data.enc_in_bus_format = bus_format;
1319 hdmi->hdmi_data.enc_out_bus_format = bus_format;
1320
1321 switch (bus_format) {
1322 case MEDIA_BUS_FMT_YUYV10_1X20:
1323 conn_state->bus_format = MEDIA_BUS_FMT_YUYV10_1X20;
1324 hdmi->hdmi_data.enc_in_bus_format =
1325 MEDIA_BUS_FMT_YUYV10_1X20;
1326 conn_state->output_mode = ROCKCHIP_OUT_MODE_YUV422;
1327 break;
1328 case MEDIA_BUS_FMT_YUYV8_1X16:
1329 conn_state->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
1330 hdmi->hdmi_data.enc_in_bus_format =
1331 MEDIA_BUS_FMT_YUYV8_1X16;
1332 conn_state->output_mode = ROCKCHIP_OUT_MODE_YUV422;
1333 break;
1334 case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
1335 case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
1336 conn_state->output_mode = ROCKCHIP_OUT_MODE_YUV420;
1337 break;
1338 }
1339
1340 if (hdmi->vic == 6 || hdmi->vic == 7 || hdmi->vic == 21 ||
1341 hdmi->vic == 22 || hdmi->vic == 2 || hdmi->vic == 3 ||
1342 hdmi->vic == 17 || hdmi->vic == 18)
1343 enc_out_encoding = V4L2_YCBCR_ENC_601;
1344 else
1345 enc_out_encoding = V4L2_YCBCR_ENC_709;
1346
1347 if (enc_out_encoding == V4L2_YCBCR_ENC_BT2020)
1348 conn_state->color_space = V4L2_COLORSPACE_BT2020;
1349 else if (bus_format == MEDIA_BUS_FMT_RGB888_1X24 ||
1350 bus_format == MEDIA_BUS_FMT_RGB101010_1X30)
1351 conn_state->color_space = V4L2_COLORSPACE_DEFAULT;
1352 else if (enc_out_encoding == V4L2_YCBCR_ENC_709)
1353 conn_state->color_space = V4L2_COLORSPACE_REC709;
1354 else
1355 conn_state->color_space = V4L2_COLORSPACE_SMPTE170M;
1356
1357 return 0;
1358 }
1359
rockchip_dw_hdmi_qp_get_timing(struct rockchip_connector * conn,struct display_state * state)1360 int rockchip_dw_hdmi_qp_get_timing(struct rockchip_connector *conn, struct display_state *state)
1361 {
1362 struct connector_state *conn_state = &state->conn_state;
1363 struct dw_hdmi_qp *hdmi = conn->data;
1364 int ret;
1365
1366 ret = drm_do_get_edid(&hdmi->adap, conn_state->edid);
1367
1368 if (conn_state->secondary)
1369 _rockchip_dw_hdmi_qp_get_timing(conn_state->secondary, state, ret);
1370
1371 return _rockchip_dw_hdmi_qp_get_timing(conn, state, ret);
1372 }
1373
1374
rockchip_dw_hdmi_qp_detect(struct rockchip_connector * conn,struct display_state * state)1375 int rockchip_dw_hdmi_qp_detect(struct rockchip_connector *conn, struct display_state *state)
1376 {
1377 int ret;
1378 struct dw_hdmi_qp *hdmi = conn->data;
1379
1380 if (!hdmi)
1381 return -EFAULT;
1382
1383 ret = dw_hdmi_detect_hotplug(hdmi, state);
1384
1385 return ret;
1386 }
1387
rockchip_dw_hdmi_qp_get_edid(struct rockchip_connector * conn,struct display_state * state)1388 int rockchip_dw_hdmi_qp_get_edid(struct rockchip_connector *conn, struct display_state *state)
1389 {
1390 int ret;
1391 struct connector_state *conn_state = &state->conn_state;
1392 struct dw_hdmi_qp *hdmi = conn->data;
1393
1394 ret = drm_do_get_edid(&hdmi->adap, conn_state->edid);
1395
1396 return ret;
1397 }
1398