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