video: omap: fix pixel-per-line bitfield setting
[oweals/u-boot.git] / drivers / video / dw_hdmi.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2015 Google, Inc
4  * Copyright 2014 Rockchip Inc.
5  * Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
6  */
7
8 #include <common.h>
9 #include <fdtdec.h>
10 #include <asm/io.h>
11 #include <i2c.h>
12 #include <media_bus_format.h>
13 #include "dw_hdmi.h"
14
15 struct tmds_n_cts {
16         u32 tmds;
17         u32 cts;
18         u32 n;
19 };
20
21 static const struct tmds_n_cts n_cts_table[] = {
22         {
23                 .tmds = 25175000, .n = 6144, .cts = 25175,
24         }, {
25                 .tmds = 25200000, .n = 6144, .cts = 25200,
26         }, {
27                 .tmds = 27000000, .n = 6144, .cts = 27000,
28         }, {
29                 .tmds = 27027000, .n = 6144, .cts = 27027,
30         }, {
31                 .tmds = 40000000, .n = 6144, .cts = 40000,
32         }, {
33                 .tmds = 54000000, .n = 6144, .cts = 54000,
34         }, {
35                 .tmds = 54054000, .n = 6144, .cts = 54054,
36         }, {
37                 .tmds = 65000000, .n = 6144, .cts = 65000,
38         }, {
39                 .tmds = 74176000, .n = 11648, .cts = 140625,
40         }, {
41                 .tmds = 74250000, .n = 6144, .cts = 74250,
42         }, {
43                 .tmds = 83500000, .n = 6144, .cts = 83500,
44         }, {
45                 .tmds = 106500000, .n = 6144, .cts = 106500,
46         }, {
47                 .tmds = 108000000, .n = 6144, .cts = 108000,
48         }, {
49                 .tmds = 148352000, .n = 5824, .cts = 140625,
50         }, {
51                 .tmds = 148500000, .n = 6144, .cts = 148500,
52         }, {
53                 .tmds = 297000000, .n = 5120, .cts = 247500,
54         }
55 };
56
57 static const u16 csc_coeff_default[3][4] = {
58         { 0x2000, 0x0000, 0x0000, 0x0000 },
59         { 0x0000, 0x2000, 0x0000, 0x0000 },
60         { 0x0000, 0x0000, 0x2000, 0x0000 }
61 };
62
63 static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
64         { 0x2591, 0x1322, 0x074b, 0x0000 },
65         { 0x6535, 0x2000, 0x7acc, 0x0200 },
66         { 0x6acd, 0x7534, 0x2000, 0x0200 }
67 };
68
69 static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
70         { 0x2000, 0x6926, 0x74fd, 0x010e },
71         { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
72         { 0x2000, 0x0000, 0x38b4, 0x7e3b }
73 };
74
75 static void dw_hdmi_write(struct dw_hdmi *hdmi, u8 val, int offset)
76 {
77         switch (hdmi->reg_io_width) {
78         case 1:
79                 writeb(val, hdmi->ioaddr + offset);
80                 break;
81         case 4:
82                 writel(val, hdmi->ioaddr + (offset << 2));
83                 break;
84         default:
85                 debug("reg_io_width has unsupported width!\n");
86                 break;
87         }
88 }
89
90 static u8 dw_hdmi_read(struct dw_hdmi *hdmi, int offset)
91 {
92         switch (hdmi->reg_io_width) {
93         case 1:
94                 return readb(hdmi->ioaddr + offset);
95         case 4:
96                 return readl(hdmi->ioaddr + (offset << 2));
97         default:
98                 debug("reg_io_width has unsupported width!\n");
99                 break;
100         }
101
102         return 0;
103 }
104
105 static u8 (*hdmi_read)(struct dw_hdmi *hdmi, int offset) = dw_hdmi_read;
106 static void (*hdmi_write)(struct dw_hdmi *hdmi, u8 val, int offset) =
107                                                                  dw_hdmi_write;
108
109 static void hdmi_mod(struct dw_hdmi *hdmi, unsigned reg, u8 mask, u8 data)
110 {
111         u8 val = hdmi_read(hdmi, reg) & ~mask;
112
113         val |= data & mask;
114         hdmi_write(hdmi, val, reg);
115 }
116
117 static void hdmi_set_clock_regenerator(struct dw_hdmi *hdmi, u32 n, u32 cts)
118 {
119         uint cts3;
120         uint n3;
121
122         /* first set ncts_atomic_write (if present) */
123         n3 = HDMI_AUD_N3_NCTS_ATOMIC_WRITE;
124         hdmi_write(hdmi, n3, HDMI_AUD_N3);
125
126         /* set cts_manual (if present) */
127         cts3 = HDMI_AUD_CTS3_CTS_MANUAL;
128
129         cts3 |= HDMI_AUD_CTS3_N_SHIFT_1 << HDMI_AUD_CTS3_N_SHIFT_OFFSET;
130         cts3 |= (cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK;
131
132         /* write cts values; cts3 must be written first */
133         hdmi_write(hdmi, cts3, HDMI_AUD_CTS3);
134         hdmi_write(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
135         hdmi_write(hdmi, cts & 0xff, HDMI_AUD_CTS1);
136
137         /* write n values; n1 must be written last */
138         n3 |= (n >> 16) & HDMI_AUD_N3_AUDN19_16_MASK;
139         hdmi_write(hdmi, n3, HDMI_AUD_N3);
140         hdmi_write(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
141         hdmi_write(hdmi, n & 0xff, HDMI_AUD_N3);
142
143         hdmi_write(hdmi, HDMI_AUD_INPUTCLKFS_128, HDMI_AUD_INPUTCLKFS);
144 }
145
146 static int hdmi_lookup_n_cts(u32 pixel_clk)
147 {
148         int i;
149
150         for (i = 0; i < ARRAY_SIZE(n_cts_table); i++)
151                 if (pixel_clk <= n_cts_table[i].tmds)
152                         break;
153
154         if (i >= ARRAY_SIZE(n_cts_table))
155                 return -1;
156
157         return i;
158 }
159
160 static void hdmi_audio_set_samplerate(struct dw_hdmi *hdmi, u32 pixel_clk)
161 {
162         u32 clk_n, clk_cts;
163         int index;
164
165         index = hdmi_lookup_n_cts(pixel_clk);
166         if (index == -1) {
167                 debug("audio not supported for pixel clk %d\n", pixel_clk);
168                 return;
169         }
170
171         clk_n = n_cts_table[index].n;
172         clk_cts = n_cts_table[index].cts;
173         hdmi_set_clock_regenerator(hdmi, clk_n, clk_cts);
174 }
175
176 /*
177  * this submodule is responsible for the video data synchronization.
178  * for example, for rgb 4:4:4 input, the data map is defined as
179  *                      pin{47~40} <==> r[7:0]
180  *                      pin{31~24} <==> g[7:0]
181  *                      pin{15~8}  <==> b[7:0]
182  */
183 static void hdmi_video_sample(struct dw_hdmi *hdmi)
184 {
185         u32 color_format;
186         uint val;
187
188         switch (hdmi->hdmi_data.enc_in_bus_format) {
189         case MEDIA_BUS_FMT_RGB888_1X24:
190                 color_format = 0x01;
191                 break;
192         case MEDIA_BUS_FMT_RGB101010_1X30:
193                 color_format = 0x03;
194                 break;
195         case MEDIA_BUS_FMT_RGB121212_1X36:
196                 color_format = 0x05;
197                 break;
198         case MEDIA_BUS_FMT_RGB161616_1X48:
199                 color_format = 0x07;
200                 break;
201         case MEDIA_BUS_FMT_YUV8_1X24:
202         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
203                 color_format = 0x09;
204                 break;
205         case MEDIA_BUS_FMT_YUV10_1X30:
206         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
207                 color_format = 0x0B;
208                 break;
209         case MEDIA_BUS_FMT_YUV12_1X36:
210         case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
211                 color_format = 0x0D;
212                 break;
213         case MEDIA_BUS_FMT_YUV16_1X48:
214         case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
215                 color_format = 0x0F;
216                 break;
217         case MEDIA_BUS_FMT_UYVY8_1X16:
218                 color_format = 0x16;
219                 break;
220         case MEDIA_BUS_FMT_UYVY10_1X20:
221                 color_format = 0x14;
222                 break;
223         case MEDIA_BUS_FMT_UYVY12_1X24:
224                 color_format = 0x12;
225                 break;
226         default:
227                 color_format = 0x01;
228                 break;
229         }
230
231         val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
232               ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
233               HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
234
235         hdmi_write(hdmi, val, HDMI_TX_INVID0);
236
237         /* enable tx stuffing: when de is inactive, fix the output data to 0 */
238         val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
239               HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
240               HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
241         hdmi_write(hdmi, val, HDMI_TX_INSTUFFING);
242         hdmi_write(hdmi, 0x0, HDMI_TX_GYDATA0);
243         hdmi_write(hdmi, 0x0, HDMI_TX_GYDATA1);
244         hdmi_write(hdmi, 0x0, HDMI_TX_RCRDATA0);
245         hdmi_write(hdmi, 0x0, HDMI_TX_RCRDATA1);
246         hdmi_write(hdmi, 0x0, HDMI_TX_BCBDATA0);
247         hdmi_write(hdmi, 0x0, HDMI_TX_BCBDATA1);
248 }
249
250 static void hdmi_video_packetize(struct dw_hdmi *hdmi)
251 {
252         u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
253         u32 remap_size = HDMI_VP_REMAP_YCC422_16BIT;
254         u32 color_depth = 0;
255         uint val, vp_conf;
256
257         /* set the packetizer registers */
258         val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
259                 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
260                 ((0 << HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
261                 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
262         hdmi_write(hdmi, val, HDMI_VP_PR_CD);
263
264         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_PR_STUFFING_MASK,
265                  HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE);
266
267         /* data from pixel repeater block */
268         vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
269                   HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
270
271         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_PR_EN_MASK |
272                  HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf);
273
274         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
275                  1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET);
276
277         hdmi_write(hdmi, remap_size, HDMI_VP_REMAP);
278
279         vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
280                   HDMI_VP_CONF_PP_EN_DISABLE |
281                   HDMI_VP_CONF_YCC422_EN_DISABLE;
282
283         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_BYPASS_EN_MASK |
284                  HDMI_VP_CONF_PP_EN_ENMASK | HDMI_VP_CONF_YCC422_EN_MASK,
285                  vp_conf);
286
287         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_PP_STUFFING_MASK |
288                  HDMI_VP_STUFF_YCC422_STUFFING_MASK,
289                  HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
290                  HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE);
291
292         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
293                  output_select);
294 }
295
296 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, uint bit)
297 {
298         hdmi_mod(hdmi, HDMI_PHY_TST0, HDMI_PHY_TST0_TSTCLR_MASK,
299                  bit << HDMI_PHY_TST0_TSTCLR_OFFSET);
300 }
301
302 static int hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, u32 msec)
303 {
304         ulong start;
305         u32 val;
306
307         start = get_timer(0);
308         do {
309                 val = hdmi_read(hdmi, HDMI_IH_I2CMPHY_STAT0);
310                 if (val & 0x3) {
311                         hdmi_write(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
312                         return 0;
313                 }
314
315                 udelay(100);
316         } while (get_timer(start) < msec);
317
318         return 1;
319 }
320
321 static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, uint data, uint addr)
322 {
323         hdmi_write(hdmi, 0xff, HDMI_IH_I2CMPHY_STAT0);
324         hdmi_write(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
325         hdmi_write(hdmi, (u8)(data >> 8), HDMI_PHY_I2CM_DATAO_1_ADDR);
326         hdmi_write(hdmi, (u8)(data >> 0), HDMI_PHY_I2CM_DATAO_0_ADDR);
327         hdmi_write(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
328                    HDMI_PHY_I2CM_OPERATION_ADDR);
329
330         hdmi_phy_wait_i2c_done(hdmi, 1000);
331 }
332
333 static void hdmi_phy_enable_power(struct dw_hdmi *hdmi, uint enable)
334 {
335         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_PDZ_MASK,
336                  enable << HDMI_PHY_CONF0_PDZ_OFFSET);
337 }
338
339 static void hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, uint enable)
340 {
341         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_ENTMDS_MASK,
342                  enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
343 }
344
345 static void hdmi_phy_enable_spare(struct dw_hdmi *hdmi, uint enable)
346 {
347         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_SPARECTRL_MASK,
348                  enable << HDMI_PHY_CONF0_SPARECTRL_OFFSET);
349 }
350
351 static void hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, uint enable)
352 {
353         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_GEN2_PDDQ_MASK,
354                  enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
355 }
356
357 static void hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, uint enable)
358 {
359         hdmi_mod(hdmi, HDMI_PHY_CONF0,
360                  HDMI_PHY_CONF0_GEN2_TXPWRON_MASK,
361                  enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
362 }
363
364 static void hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, uint enable)
365 {
366         hdmi_mod(hdmi, HDMI_PHY_CONF0,
367                  HDMI_PHY_CONF0_SELDATAENPOL_MASK,
368                  enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
369 }
370
371 static void hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi,
372                                            uint enable)
373 {
374         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_SELDIPIF_MASK,
375                  enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
376 }
377
378 static int hdmi_phy_configure(struct dw_hdmi *hdmi, u32 mpixelclock)
379 {
380         ulong start;
381         uint i, val;
382
383         if (!hdmi->mpll_cfg || !hdmi->phy_cfg)
384                 return -1;
385
386         /* gen2 tx power off */
387         hdmi_phy_gen2_txpwron(hdmi, 0);
388
389         /* gen2 pddq */
390         hdmi_phy_gen2_pddq(hdmi, 1);
391
392         /* phy reset */
393         hdmi_write(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
394         hdmi_write(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
395         hdmi_write(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
396
397         hdmi_phy_test_clear(hdmi, 1);
398         hdmi_write(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
399                    HDMI_PHY_I2CM_SLAVE_ADDR);
400         hdmi_phy_test_clear(hdmi, 0);
401
402         /* pll/mpll cfg - always match on final entry */
403         for (i = 0; hdmi->mpll_cfg[i].mpixelclock != (~0ul); i++)
404                 if (mpixelclock <= hdmi->mpll_cfg[i].mpixelclock)
405                         break;
406
407         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].cpce, PHY_OPMODE_PLLCFG);
408         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].gmp, PHY_PLLGMPCTRL);
409         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].curr, PHY_PLLCURRCTRL);
410
411         hdmi_phy_i2c_write(hdmi, 0x0000, PHY_PLLPHBYCTRL);
412         hdmi_phy_i2c_write(hdmi, 0x0006, PHY_PLLCLKBISTPHASE);
413
414         for (i = 0; hdmi->phy_cfg[i].mpixelclock != (~0ul); i++)
415                 if (mpixelclock <= hdmi->phy_cfg[i].mpixelclock)
416                         break;
417
418         /*
419          * resistance term 133ohm cfg
420          * preemp cgf 0.00
421          * tx/ck lvl 10
422          */
423         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].term, PHY_TXTERM);
424         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].sym_ctr, PHY_CKSYMTXCTRL);
425         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].vlev_ctr, PHY_VLEVCTRL);
426
427         /* remove clk term */
428         hdmi_phy_i2c_write(hdmi, 0x8000, PHY_CKCALCTRL);
429
430         hdmi_phy_enable_power(hdmi, 1);
431
432         /* toggle tmds enable */
433         hdmi_phy_enable_tmds(hdmi, 0);
434         hdmi_phy_enable_tmds(hdmi, 1);
435
436         /* gen2 tx power on */
437         hdmi_phy_gen2_txpwron(hdmi, 1);
438         hdmi_phy_gen2_pddq(hdmi, 0);
439
440         hdmi_phy_enable_spare(hdmi, 1);
441
442         /* wait for phy pll lock */
443         start = get_timer(0);
444         do {
445                 val = hdmi_read(hdmi, HDMI_PHY_STAT0);
446                 if (!(val & HDMI_PHY_TX_PHY_LOCK))
447                         return 0;
448
449                 udelay(100);
450         } while (get_timer(start) < 5);
451
452         return -1;
453 }
454
455 static void hdmi_av_composer(struct dw_hdmi *hdmi,
456                              const struct display_timing *edid)
457 {
458         bool mdataenablepolarity = true;
459         uint inv_val;
460         uint hbl;
461         uint vbl;
462
463         hbl = edid->hback_porch.typ + edid->hfront_porch.typ +
464                         edid->hsync_len.typ;
465         vbl = edid->vback_porch.typ + edid->vfront_porch.typ +
466                         edid->vsync_len.typ;
467
468         /* set up hdmi_fc_invidconf */
469         inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE;
470
471         inv_val |= (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
472                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
473                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
474
475         inv_val |= (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
476                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
477                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
478
479         inv_val |= (mdataenablepolarity ?
480                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
481                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
482
483         inv_val |= (edid->hdmi_monitor ?
484                    HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
485                    HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE);
486
487         inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
488
489         inv_val |= HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
490
491         hdmi_write(hdmi, inv_val, HDMI_FC_INVIDCONF);
492
493         /* set up horizontal active pixel width */
494         hdmi_write(hdmi, edid->hactive.typ >> 8, HDMI_FC_INHACTV1);
495         hdmi_write(hdmi, edid->hactive.typ, HDMI_FC_INHACTV0);
496
497         /* set up vertical active lines */
498         hdmi_write(hdmi, edid->vactive.typ >> 8, HDMI_FC_INVACTV1);
499         hdmi_write(hdmi, edid->vactive.typ, HDMI_FC_INVACTV0);
500
501         /* set up horizontal blanking pixel region width */
502         hdmi_write(hdmi, hbl >> 8, HDMI_FC_INHBLANK1);
503         hdmi_write(hdmi, hbl, HDMI_FC_INHBLANK0);
504
505         /* set up vertical blanking pixel region width */
506         hdmi_write(hdmi, vbl, HDMI_FC_INVBLANK);
507
508         /* set up hsync active edge delay width (in pixel clks) */
509         hdmi_write(hdmi, edid->hfront_porch.typ >> 8, HDMI_FC_HSYNCINDELAY1);
510         hdmi_write(hdmi, edid->hfront_porch.typ, HDMI_FC_HSYNCINDELAY0);
511
512         /* set up vsync active edge delay (in lines) */
513         hdmi_write(hdmi, edid->vfront_porch.typ, HDMI_FC_VSYNCINDELAY);
514
515         /* set up hsync active pulse width (in pixel clks) */
516         hdmi_write(hdmi, edid->hsync_len.typ >> 8, HDMI_FC_HSYNCINWIDTH1);
517         hdmi_write(hdmi, edid->hsync_len.typ, HDMI_FC_HSYNCINWIDTH0);
518
519         /* set up vsync active edge delay (in lines) */
520         hdmi_write(hdmi, edid->vsync_len.typ, HDMI_FC_VSYNCINWIDTH);
521 }
522
523 static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format)
524 {
525         switch (bus_format) {
526         case MEDIA_BUS_FMT_RGB888_1X24:
527         case MEDIA_BUS_FMT_RGB101010_1X30:
528         case MEDIA_BUS_FMT_RGB121212_1X36:
529         case MEDIA_BUS_FMT_RGB161616_1X48:
530                 return true;
531
532         default:
533                 return false;
534         }
535 }
536
537 static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format)
538 {
539         switch (bus_format) {
540         case MEDIA_BUS_FMT_YUV8_1X24:
541         case MEDIA_BUS_FMT_YUV10_1X30:
542         case MEDIA_BUS_FMT_YUV12_1X36:
543         case MEDIA_BUS_FMT_YUV16_1X48:
544                 return true;
545
546         default:
547                 return false;
548         }
549 }
550
551 static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format)
552 {
553         switch (bus_format) {
554         case MEDIA_BUS_FMT_UYVY8_1X16:
555         case MEDIA_BUS_FMT_UYVY10_1X20:
556         case MEDIA_BUS_FMT_UYVY12_1X24:
557                 return true;
558
559         default:
560                 return false;
561         }
562 }
563
564 static int is_color_space_interpolation(struct dw_hdmi *hdmi)
565 {
566         if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format))
567                 return 0;
568
569         if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) ||
570             hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format))
571                 return 1;
572
573         return 0;
574 }
575
576 static int is_color_space_decimation(struct dw_hdmi *hdmi)
577 {
578         if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format))
579                 return 0;
580
581         if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) ||
582             hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format))
583                 return 1;
584
585         return 0;
586 }
587
588 static int hdmi_bus_fmt_color_depth(unsigned int bus_format)
589 {
590         switch (bus_format) {
591         case MEDIA_BUS_FMT_RGB888_1X24:
592         case MEDIA_BUS_FMT_YUV8_1X24:
593         case MEDIA_BUS_FMT_UYVY8_1X16:
594         case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
595                 return 8;
596
597         case MEDIA_BUS_FMT_RGB101010_1X30:
598         case MEDIA_BUS_FMT_YUV10_1X30:
599         case MEDIA_BUS_FMT_UYVY10_1X20:
600         case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
601                 return 10;
602
603         case MEDIA_BUS_FMT_RGB121212_1X36:
604         case MEDIA_BUS_FMT_YUV12_1X36:
605         case MEDIA_BUS_FMT_UYVY12_1X24:
606         case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
607                 return 12;
608
609         case MEDIA_BUS_FMT_RGB161616_1X48:
610         case MEDIA_BUS_FMT_YUV16_1X48:
611         case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
612                 return 16;
613
614         default:
615                 return 0;
616         }
617 }
618
619 static int is_color_space_conversion(struct dw_hdmi *hdmi)
620 {
621         return hdmi->hdmi_data.enc_in_bus_format !=
622                hdmi->hdmi_data.enc_out_bus_format;
623 }
624
625 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi)
626 {
627         const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
628         unsigned int i;
629         u32 csc_scale = 1;
630
631         if (is_color_space_conversion(hdmi)) {
632                 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) {
633                         csc_coeff = &csc_coeff_rgb_out_eitu601;
634                 } else if (hdmi_bus_fmt_is_rgb(
635                                         hdmi->hdmi_data.enc_in_bus_format)) {
636                         csc_coeff = &csc_coeff_rgb_in_eitu601;
637                         csc_scale = 0;
638                 }
639         }
640
641         /* The CSC registers are sequential, alternating MSB then LSB */
642         for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
643                 u16 coeff_a = (*csc_coeff)[0][i];
644                 u16 coeff_b = (*csc_coeff)[1][i];
645                 u16 coeff_c = (*csc_coeff)[2][i];
646
647                 hdmi_write(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2);
648                 hdmi_write(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
649                 hdmi_write(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
650                 hdmi_write(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
651                 hdmi_write(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2);
652                 hdmi_write(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
653         }
654
655         hdmi_mod(hdmi, HDMI_CSC_SCALE, HDMI_CSC_SCALE_CSCSCALE_MASK, csc_scale);
656 }
657
658 static void hdmi_video_csc(struct dw_hdmi *hdmi)
659 {
660         int color_depth = 0;
661         int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
662         int decimation = 0;
663
664         /* YCC422 interpolation to 444 mode */
665         if (is_color_space_interpolation(hdmi))
666                 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
667         else if (is_color_space_decimation(hdmi))
668                 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
669
670         switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) {
671         case 8:
672                 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
673                 break;
674         case 10:
675                 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
676                 break;
677         case 12:
678                 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
679                 break;
680         case 16:
681                 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
682                 break;
683
684         default:
685                 return;
686         }
687
688         /* Configure the CSC registers */
689         hdmi_write(hdmi, interpolation | decimation, HDMI_CSC_CFG);
690
691         hdmi_mod(hdmi, HDMI_CSC_SCALE, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
692                  color_depth);
693
694         dw_hdmi_update_csc_coeffs(hdmi);
695 }
696
697 /* hdmi initialization step b.4 */
698 static void hdmi_enable_video_path(struct dw_hdmi *hdmi, bool audio)
699 {
700         uint clkdis;
701
702         /* control period minimum duration */
703         hdmi_write(hdmi, 12, HDMI_FC_CTRLDUR);
704         hdmi_write(hdmi, 32, HDMI_FC_EXCTRLDUR);
705         hdmi_write(hdmi, 1, HDMI_FC_EXCTRLSPAC);
706
707         /* set to fill tmds data channels */
708         hdmi_write(hdmi, 0x0b, HDMI_FC_CH0PREAM);
709         hdmi_write(hdmi, 0x16, HDMI_FC_CH1PREAM);
710         hdmi_write(hdmi, 0x21, HDMI_FC_CH2PREAM);
711
712         hdmi_write(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
713                    HDMI_MC_FLOWCTRL);
714
715         /* enable pixel clock and tmds data path */
716         clkdis = 0x7f;
717         clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
718         hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
719
720         clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
721         hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
722
723         /* Enable csc path */
724         if (is_color_space_conversion(hdmi)) {
725                 clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
726                 hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
727         }
728
729         /* Enable color space conversion if needed */
730         if (is_color_space_conversion(hdmi))
731                 hdmi_write(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH,
732                            HDMI_MC_FLOWCTRL);
733         else
734                 hdmi_write(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
735                            HDMI_MC_FLOWCTRL);
736
737         if (audio) {
738                 clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
739                 hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
740         }
741 }
742
743 /* workaround to clear the overflow condition */
744 static void hdmi_clear_overflow(struct dw_hdmi *hdmi)
745 {
746         uint val, count;
747
748         /* tmds software reset */
749         hdmi_write(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
750
751         val = hdmi_read(hdmi, HDMI_FC_INVIDCONF);
752
753         for (count = 0; count < 4; count++)
754                 hdmi_write(hdmi, val, HDMI_FC_INVIDCONF);
755 }
756
757 static void hdmi_audio_set_format(struct dw_hdmi *hdmi)
758 {
759         hdmi_write(hdmi, HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_IN_EN_0,
760                    HDMI_AUD_CONF0);
761
762
763         hdmi_write(hdmi, HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE |
764                    HDMI_AUD_CONF1_I2S_WIDTH_16BIT, HDMI_AUD_CONF1);
765
766         hdmi_write(hdmi, 0x00, HDMI_AUD_CONF2);
767 }
768
769 static void hdmi_audio_fifo_reset(struct dw_hdmi *hdmi)
770 {
771         hdmi_write(hdmi, (u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, HDMI_MC_SWRSTZ);
772         hdmi_write(hdmi, HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, HDMI_AUD_CONF0);
773
774         hdmi_write(hdmi, 0x00, HDMI_AUD_INT);
775         hdmi_write(hdmi, 0x00, HDMI_AUD_INT1);
776 }
777
778 static int hdmi_get_plug_in_status(struct dw_hdmi *hdmi)
779 {
780         uint val = hdmi_read(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD;
781
782         return !!val;
783 }
784
785 static int hdmi_ddc_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
786 {
787         u32 val;
788         ulong start;
789
790         start = get_timer(0);
791         do {
792                 val = hdmi_read(hdmi, HDMI_IH_I2CM_STAT0);
793                 if (val & 0x2) {
794                         hdmi_write(hdmi, val, HDMI_IH_I2CM_STAT0);
795                         return 0;
796                 }
797
798                 udelay(100);
799         } while (get_timer(start) < msec);
800
801         return 1;
802 }
803
804 static void hdmi_ddc_reset(struct dw_hdmi *hdmi)
805 {
806         hdmi_mod(hdmi, HDMI_I2CM_SOFTRSTZ, HDMI_I2CM_SOFTRSTZ_MASK, 0);
807 }
808
809 static int hdmi_read_edid(struct dw_hdmi *hdmi, int block, u8 *buff)
810 {
811         int shift = (block % 2) * 0x80;
812         int edid_read_err = 0;
813         u32 trytime = 5;
814         u32 n;
815
816         if (CONFIG_IS_ENABLED(DM_I2C) && hdmi->ddc_bus) {
817                 struct udevice *chip;
818
819                 edid_read_err = i2c_get_chip(hdmi->ddc_bus,
820                                              HDMI_I2CM_SLAVE_DDC_ADDR,
821                                              1, &chip);
822                 if (edid_read_err)
823                         return edid_read_err;
824
825                 return dm_i2c_read(chip, shift, buff, HDMI_EDID_BLOCK_SIZE);
826         }
827
828         /* set ddc i2c clk which devided from ddc_clk to 100khz */
829         hdmi_write(hdmi, hdmi->i2c_clk_high, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
830         hdmi_write(hdmi, hdmi->i2c_clk_low, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
831         hdmi_mod(hdmi, HDMI_I2CM_DIV, HDMI_I2CM_DIV_FAST_STD_MODE,
832                  HDMI_I2CM_DIV_STD_MODE);
833
834         hdmi_write(hdmi, HDMI_I2CM_SLAVE_DDC_ADDR, HDMI_I2CM_SLAVE);
835         hdmi_write(hdmi, HDMI_I2CM_SEGADDR_DDC, HDMI_I2CM_SEGADDR);
836         hdmi_write(hdmi, block >> 1, HDMI_I2CM_SEGPTR);
837
838         while (trytime--) {
839                 edid_read_err = 0;
840
841                 for (n = 0; n < HDMI_EDID_BLOCK_SIZE; n++) {
842                         hdmi_write(hdmi, shift + n, HDMI_I2CM_ADDRESS);
843
844                         if (block == 0)
845                                 hdmi_write(hdmi, HDMI_I2CM_OP_RD8,
846                                            HDMI_I2CM_OPERATION);
847                         else
848                                 hdmi_write(hdmi, HDMI_I2CM_OP_RD8_EXT,
849                                            HDMI_I2CM_OPERATION);
850
851                         if (hdmi_ddc_wait_i2c_done(hdmi, 10)) {
852                                 hdmi_ddc_reset(hdmi);
853                                 edid_read_err = 1;
854                                 break;
855                         }
856
857                         buff[n] = hdmi_read(hdmi, HDMI_I2CM_DATAI);
858                 }
859
860                 if (!edid_read_err)
861                         break;
862         }
863
864         return edid_read_err;
865 }
866
867 static const u8 pre_buf[] = {
868         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
869         0x04, 0x69, 0xfa, 0x23, 0xc8, 0x28, 0x01, 0x00,
870         0x10, 0x17, 0x01, 0x03, 0x80, 0x33, 0x1d, 0x78,
871         0x2a, 0xd9, 0x45, 0xa2, 0x55, 0x4d, 0xa0, 0x27,
872         0x12, 0x50, 0x54, 0xb7, 0xef, 0x00, 0x71, 0x4f,
873         0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0xb3, 0x00,
874         0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x00, 0x02, 0x3a,
875         0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
876         0x45, 0x00, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
877         0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x34, 0x4c,
878         0x4d, 0x54, 0x46, 0x30, 0x37, 0x35, 0x39, 0x37,
879         0x36, 0x0a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
880         0x4b, 0x18, 0x53, 0x11, 0x00, 0x0a, 0x20, 0x20,
881         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
882         0x00, 0x41, 0x53, 0x55, 0x53, 0x20, 0x56, 0x53,
883         0x32, 0x33, 0x38, 0x0a, 0x20, 0x20, 0x01, 0xb0,
884         0x02, 0x03, 0x22, 0x71, 0x4f, 0x01, 0x02, 0x03,
885         0x11, 0x12, 0x13, 0x04, 0x14, 0x05, 0x0e, 0x0f,
886         0x1d, 0x1e, 0x1f, 0x10, 0x23, 0x09, 0x17, 0x07,
887         0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0c, 0x00,
888         0x10, 0x00, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0,
889         0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xfd, 0x1e,
890         0x11, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0x72,
891         0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
892         0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d,
893         0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28,
894         0x55, 0x40, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
895         0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20,
896         0x0c, 0x40, 0x55, 0x00, 0xfd, 0x1e, 0x11, 0x00,
897         0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
898         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
899         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9,
900 };
901
902 int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock)
903 {
904         int i, ret;
905
906         /* hdmi phy spec says to do the phy initialization sequence twice */
907         for (i = 0; i < 2; i++) {
908                 hdmi_phy_sel_data_en_pol(hdmi, 1);
909                 hdmi_phy_sel_interface_control(hdmi, 0);
910                 hdmi_phy_enable_tmds(hdmi, 0);
911                 hdmi_phy_enable_power(hdmi, 0);
912
913                 ret = hdmi_phy_configure(hdmi, mpixelclock);
914                 if (ret) {
915                         debug("hdmi phy config failure %d\n", ret);
916                         return ret;
917                 }
918         }
919
920         return 0;
921 }
922
923 int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi)
924 {
925         ulong start;
926
927         start = get_timer(0);
928         do {
929                 if (hdmi_get_plug_in_status(hdmi))
930                         return 0;
931                 udelay(100);
932         } while (get_timer(start) < 300);
933
934         return -1;
935 }
936
937 void dw_hdmi_phy_init(struct dw_hdmi *hdmi)
938 {
939         /* enable phy i2cm done irq */
940         hdmi_write(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
941                    HDMI_PHY_I2CM_INT_ADDR);
942
943         /* enable phy i2cm nack & arbitration error irq */
944         hdmi_write(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
945                    HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
946                    HDMI_PHY_I2CM_CTLINT_ADDR);
947
948         /* enable cable hot plug irq */
949         hdmi_write(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
950
951         /* clear hotplug interrupts */
952         hdmi_write(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
953 }
954
955 int dw_hdmi_read_edid(struct dw_hdmi *hdmi, u8 *buf, int buf_size)
956 {
957         u32 edid_size = HDMI_EDID_BLOCK_SIZE;
958         int ret;
959
960         if (0) {
961                 edid_size = sizeof(pre_buf);
962                 memcpy(buf, pre_buf, edid_size);
963         } else {
964                 ret = hdmi_read_edid(hdmi, 0, buf);
965                 if (ret) {
966                         debug("failed to read edid.\n");
967                         return -1;
968                 }
969
970                 if (buf[0x7e] != 0) {
971                         hdmi_read_edid(hdmi, 1, buf + HDMI_EDID_BLOCK_SIZE);
972                         edid_size += HDMI_EDID_BLOCK_SIZE;
973                 }
974         }
975
976         return edid_size;
977 }
978
979 int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid)
980 {
981         int ret;
982
983         debug("%s, mode info : clock %d hdis %d vdis %d\n",
984               edid->hdmi_monitor ? "hdmi" : "dvi",
985               edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ);
986
987         hdmi_av_composer(hdmi, edid);
988
989         ret = hdmi->phy_set(hdmi, edid->pixelclock.typ);
990         if (ret)
991                 return ret;
992
993         hdmi_enable_video_path(hdmi, edid->hdmi_monitor);
994
995         if (edid->hdmi_monitor) {
996                 hdmi_audio_fifo_reset(hdmi);
997                 hdmi_audio_set_format(hdmi);
998                 hdmi_audio_set_samplerate(hdmi, edid->pixelclock.typ);
999         }
1000
1001         hdmi_video_packetize(hdmi);
1002         hdmi_video_csc(hdmi);
1003         hdmi_video_sample(hdmi);
1004
1005         hdmi_clear_overflow(hdmi);
1006
1007         return 0;
1008 }
1009
1010 void dw_hdmi_init(struct dw_hdmi *hdmi)
1011 {
1012         uint ih_mute;
1013
1014         /*
1015          * boot up defaults are:
1016          * hdmi_ih_mute   = 0x03 (disabled)
1017          * hdmi_ih_mute_* = 0x00 (enabled)
1018          *
1019          * disable top level interrupt bits in hdmi block
1020          */
1021         ih_mute = /*hdmi_read(hdmi, HDMI_IH_MUTE) |*/
1022                   HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
1023                   HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
1024
1025         if (hdmi->write_reg)
1026                 hdmi_write = hdmi->write_reg;
1027
1028         if (hdmi->read_reg)
1029                 hdmi_read = hdmi->read_reg;
1030
1031         hdmi_write(hdmi, ih_mute, HDMI_IH_MUTE);
1032
1033         /* enable i2c master done irq */
1034         hdmi_write(hdmi, ~0x04, HDMI_I2CM_INT);
1035
1036         /* enable i2c client nack % arbitration error irq */
1037         hdmi_write(hdmi, ~0x44, HDMI_I2CM_CTLINT);
1038 }