Merge branch 'master' of git://git.denx.de/u-boot-mmc
[platform/kernel/u-boot.git] / drivers / video / dw_hdmi.c
1 /*
2  * Copyright (c) 2015 Google, Inc
3  * Copyright 2014 Rockchip Inc.
4  * Copyright 2017 Jernej Skrabec <jernej.skrabec@siol.net>
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <common.h>
10 #include <fdtdec.h>
11 #include <asm/io.h>
12 #include "dw_hdmi.h"
13
14 struct tmds_n_cts {
15         u32 tmds;
16         u32 cts;
17         u32 n;
18 };
19
20 static const struct tmds_n_cts n_cts_table[] = {
21         {
22                 .tmds = 25175000, .n = 6144, .cts = 25175,
23         }, {
24                 .tmds = 25200000, .n = 6144, .cts = 25200,
25         }, {
26                 .tmds = 27000000, .n = 6144, .cts = 27000,
27         }, {
28                 .tmds = 27027000, .n = 6144, .cts = 27027,
29         }, {
30                 .tmds = 40000000, .n = 6144, .cts = 40000,
31         }, {
32                 .tmds = 54000000, .n = 6144, .cts = 54000,
33         }, {
34                 .tmds = 54054000, .n = 6144, .cts = 54054,
35         }, {
36                 .tmds = 65000000, .n = 6144, .cts = 65000,
37         }, {
38                 .tmds = 74176000, .n = 11648, .cts = 140625,
39         }, {
40                 .tmds = 74250000, .n = 6144, .cts = 74250,
41         }, {
42                 .tmds = 83500000, .n = 6144, .cts = 83500,
43         }, {
44                 .tmds = 106500000, .n = 6144, .cts = 106500,
45         }, {
46                 .tmds = 108000000, .n = 6144, .cts = 108000,
47         }, {
48                 .tmds = 148352000, .n = 5824, .cts = 140625,
49         }, {
50                 .tmds = 148500000, .n = 6144, .cts = 148500,
51         }, {
52                 .tmds = 297000000, .n = 5120, .cts = 247500,
53         }
54 };
55
56 static void hdmi_write(struct dw_hdmi *hdmi, u8 val, int offset)
57 {
58         switch (hdmi->reg_io_width) {
59         case 1:
60                 writeb(val, hdmi->ioaddr + offset);
61                 break;
62         case 4:
63                 writel(val, hdmi->ioaddr + (offset << 2));
64                 break;
65         default:
66                 debug("reg_io_width has unsupported width!\n");
67                 break;
68         }
69 }
70
71 static u8 hdmi_read(struct dw_hdmi *hdmi, int offset)
72 {
73         switch (hdmi->reg_io_width) {
74         case 1:
75                 return readb(hdmi->ioaddr + offset);
76         case 4:
77                 return readl(hdmi->ioaddr + (offset << 2));
78         default:
79                 debug("reg_io_width has unsupported width!\n");
80                 break;
81         }
82
83         return 0;
84 }
85
86 static void hdmi_mod(struct dw_hdmi *hdmi, unsigned reg, u8 mask, u8 data)
87 {
88         u8 val = hdmi_read(hdmi, reg) & ~mask;
89
90         val |= data & mask;
91         hdmi_write(hdmi, val, reg);
92 }
93
94 static void hdmi_set_clock_regenerator(struct dw_hdmi *hdmi, u32 n, u32 cts)
95 {
96         uint cts3;
97         uint n3;
98
99         /* first set ncts_atomic_write (if present) */
100         n3 = HDMI_AUD_N3_NCTS_ATOMIC_WRITE;
101         hdmi_write(hdmi, n3, HDMI_AUD_N3);
102
103         /* set cts_manual (if present) */
104         cts3 = HDMI_AUD_CTS3_CTS_MANUAL;
105
106         cts3 |= HDMI_AUD_CTS3_N_SHIFT_1 << HDMI_AUD_CTS3_N_SHIFT_OFFSET;
107         cts3 |= (cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK;
108
109         /* write cts values; cts3 must be written first */
110         hdmi_write(hdmi, cts3, HDMI_AUD_CTS3);
111         hdmi_write(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
112         hdmi_write(hdmi, cts & 0xff, HDMI_AUD_CTS1);
113
114         /* write n values; n1 must be written last */
115         n3 |= (n >> 16) & HDMI_AUD_N3_AUDN19_16_MASK;
116         hdmi_write(hdmi, n3, HDMI_AUD_N3);
117         hdmi_write(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
118         hdmi_write(hdmi, n & 0xff, HDMI_AUD_N3);
119
120         hdmi_write(hdmi, HDMI_AUD_INPUTCLKFS_128, HDMI_AUD_INPUTCLKFS);
121 }
122
123 static int hdmi_lookup_n_cts(u32 pixel_clk)
124 {
125         int i;
126
127         for (i = 0; i < ARRAY_SIZE(n_cts_table); i++)
128                 if (pixel_clk <= n_cts_table[i].tmds)
129                         break;
130
131         if (i >= ARRAY_SIZE(n_cts_table))
132                 return -1;
133
134         return i;
135 }
136
137 static void hdmi_audio_set_samplerate(struct dw_hdmi *hdmi, u32 pixel_clk)
138 {
139         u32 clk_n, clk_cts;
140         int index;
141
142         index = hdmi_lookup_n_cts(pixel_clk);
143         if (index == -1) {
144                 debug("audio not supported for pixel clk %d\n", pixel_clk);
145                 return;
146         }
147
148         clk_n = n_cts_table[index].n;
149         clk_cts = n_cts_table[index].cts;
150         hdmi_set_clock_regenerator(hdmi, clk_n, clk_cts);
151 }
152
153 /*
154  * this submodule is responsible for the video data synchronization.
155  * for example, for rgb 4:4:4 input, the data map is defined as
156  *                      pin{47~40} <==> r[7:0]
157  *                      pin{31~24} <==> g[7:0]
158  *                      pin{15~8}  <==> b[7:0]
159  */
160 static void hdmi_video_sample(struct dw_hdmi *hdmi)
161 {
162         u32 color_format = 0x01;
163         uint val;
164
165         val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
166               ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
167               HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
168
169         hdmi_write(hdmi, val, HDMI_TX_INVID0);
170
171         /* enable tx stuffing: when de is inactive, fix the output data to 0 */
172         val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
173               HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
174               HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
175         hdmi_write(hdmi, val, HDMI_TX_INSTUFFING);
176         hdmi_write(hdmi, 0x0, HDMI_TX_GYDATA0);
177         hdmi_write(hdmi, 0x0, HDMI_TX_GYDATA1);
178         hdmi_write(hdmi, 0x0, HDMI_TX_RCRDATA0);
179         hdmi_write(hdmi, 0x0, HDMI_TX_RCRDATA1);
180         hdmi_write(hdmi, 0x0, HDMI_TX_BCBDATA0);
181         hdmi_write(hdmi, 0x0, HDMI_TX_BCBDATA1);
182 }
183
184 static void hdmi_video_packetize(struct dw_hdmi *hdmi)
185 {
186         u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
187         u32 remap_size = HDMI_VP_REMAP_YCC422_16BIT;
188         u32 color_depth = 0;
189         uint val, vp_conf;
190
191         /* set the packetizer registers */
192         val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
193                 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
194                 ((0 << HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
195                 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
196         hdmi_write(hdmi, val, HDMI_VP_PR_CD);
197
198         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_PR_STUFFING_MASK,
199                  HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE);
200
201         /* data from pixel repeater block */
202         vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
203                   HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
204
205         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_PR_EN_MASK |
206                  HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf);
207
208         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
209                  1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET);
210
211         hdmi_write(hdmi, remap_size, HDMI_VP_REMAP);
212
213         vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
214                   HDMI_VP_CONF_PP_EN_DISABLE |
215                   HDMI_VP_CONF_YCC422_EN_DISABLE;
216
217         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_BYPASS_EN_MASK |
218                  HDMI_VP_CONF_PP_EN_ENMASK | HDMI_VP_CONF_YCC422_EN_MASK,
219                  vp_conf);
220
221         hdmi_mod(hdmi, HDMI_VP_STUFF, HDMI_VP_STUFF_PP_STUFFING_MASK |
222                  HDMI_VP_STUFF_YCC422_STUFFING_MASK,
223                  HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
224                  HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE);
225
226         hdmi_mod(hdmi, HDMI_VP_CONF, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
227                  output_select);
228 }
229
230 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, uint bit)
231 {
232         hdmi_mod(hdmi, HDMI_PHY_TST0, HDMI_PHY_TST0_TSTCLR_MASK,
233                  bit << HDMI_PHY_TST0_TSTCLR_OFFSET);
234 }
235
236 static int hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, u32 msec)
237 {
238         ulong start;
239         u32 val;
240
241         start = get_timer(0);
242         do {
243                 val = hdmi_read(hdmi, HDMI_IH_I2CMPHY_STAT0);
244                 if (val & 0x3) {
245                         hdmi_write(hdmi, val, HDMI_IH_I2CMPHY_STAT0);
246                         return 0;
247                 }
248
249                 udelay(100);
250         } while (get_timer(start) < msec);
251
252         return 1;
253 }
254
255 static void hdmi_phy_i2c_write(struct dw_hdmi *hdmi, uint data, uint addr)
256 {
257         hdmi_write(hdmi, 0xff, HDMI_IH_I2CMPHY_STAT0);
258         hdmi_write(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
259         hdmi_write(hdmi, (u8)(data >> 8), HDMI_PHY_I2CM_DATAO_1_ADDR);
260         hdmi_write(hdmi, (u8)(data >> 0), HDMI_PHY_I2CM_DATAO_0_ADDR);
261         hdmi_write(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
262                    HDMI_PHY_I2CM_OPERATION_ADDR);
263
264         hdmi_phy_wait_i2c_done(hdmi, 1000);
265 }
266
267 static void hdmi_phy_enable_power(struct dw_hdmi *hdmi, uint enable)
268 {
269         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_PDZ_MASK,
270                  enable << HDMI_PHY_CONF0_PDZ_OFFSET);
271 }
272
273 static void hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, uint enable)
274 {
275         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_ENTMDS_MASK,
276                  enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
277 }
278
279 static void hdmi_phy_enable_spare(struct dw_hdmi *hdmi, uint enable)
280 {
281         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_SPARECTRL_MASK,
282                  enable << HDMI_PHY_CONF0_SPARECTRL_OFFSET);
283 }
284
285 static void hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, uint enable)
286 {
287         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_GEN2_PDDQ_MASK,
288                  enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
289 }
290
291 static void hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, uint enable)
292 {
293         hdmi_mod(hdmi, HDMI_PHY_CONF0,
294                  HDMI_PHY_CONF0_GEN2_TXPWRON_MASK,
295                  enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
296 }
297
298 static void hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, uint enable)
299 {
300         hdmi_mod(hdmi, HDMI_PHY_CONF0,
301                  HDMI_PHY_CONF0_SELDATAENPOL_MASK,
302                  enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
303 }
304
305 static void hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi,
306                                            uint enable)
307 {
308         hdmi_mod(hdmi, HDMI_PHY_CONF0, HDMI_PHY_CONF0_SELDIPIF_MASK,
309                  enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
310 }
311
312 static int hdmi_phy_configure(struct dw_hdmi *hdmi, u32 mpixelclock)
313 {
314         ulong start;
315         uint i, val;
316
317         if (!hdmi->mpll_cfg || !hdmi->phy_cfg)
318                 return -1;
319
320         /* gen2 tx power off */
321         hdmi_phy_gen2_txpwron(hdmi, 0);
322
323         /* gen2 pddq */
324         hdmi_phy_gen2_pddq(hdmi, 1);
325
326         /* phy reset */
327         hdmi_write(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
328         hdmi_write(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
329         hdmi_write(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
330
331         hdmi_phy_test_clear(hdmi, 1);
332         hdmi_write(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
333                    HDMI_PHY_I2CM_SLAVE_ADDR);
334         hdmi_phy_test_clear(hdmi, 0);
335
336         /* pll/mpll cfg - always match on final entry */
337         for (i = 0; hdmi->mpll_cfg[i].mpixelclock != (~0ul); i++)
338                 if (mpixelclock <= hdmi->mpll_cfg[i].mpixelclock)
339                         break;
340
341         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].cpce, PHY_OPMODE_PLLCFG);
342         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].gmp, PHY_PLLGMPCTRL);
343         hdmi_phy_i2c_write(hdmi, hdmi->mpll_cfg[i].curr, PHY_PLLCURRCTRL);
344
345         hdmi_phy_i2c_write(hdmi, 0x0000, PHY_PLLPHBYCTRL);
346         hdmi_phy_i2c_write(hdmi, 0x0006, PHY_PLLCLKBISTPHASE);
347
348         for (i = 0; hdmi->phy_cfg[i].mpixelclock != (~0ul); i++)
349                 if (mpixelclock <= hdmi->phy_cfg[i].mpixelclock)
350                         break;
351
352         /*
353          * resistance term 133ohm cfg
354          * preemp cgf 0.00
355          * tx/ck lvl 10
356          */
357         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].term, PHY_TXTERM);
358         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].sym_ctr, PHY_CKSYMTXCTRL);
359         hdmi_phy_i2c_write(hdmi, hdmi->phy_cfg[i].vlev_ctr, PHY_VLEVCTRL);
360
361         /* remove clk term */
362         hdmi_phy_i2c_write(hdmi, 0x8000, PHY_CKCALCTRL);
363
364         hdmi_phy_enable_power(hdmi, 1);
365
366         /* toggle tmds enable */
367         hdmi_phy_enable_tmds(hdmi, 0);
368         hdmi_phy_enable_tmds(hdmi, 1);
369
370         /* gen2 tx power on */
371         hdmi_phy_gen2_txpwron(hdmi, 1);
372         hdmi_phy_gen2_pddq(hdmi, 0);
373
374         hdmi_phy_enable_spare(hdmi, 1);
375
376         /* wait for phy pll lock */
377         start = get_timer(0);
378         do {
379                 val = hdmi_read(hdmi, HDMI_PHY_STAT0);
380                 if (!(val & HDMI_PHY_TX_PHY_LOCK))
381                         return 0;
382
383                 udelay(100);
384         } while (get_timer(start) < 5);
385
386         return -1;
387 }
388
389 static void hdmi_av_composer(struct dw_hdmi *hdmi,
390                              const struct display_timing *edid)
391 {
392         bool mdataenablepolarity = true;
393         uint inv_val;
394         uint hbl;
395         uint vbl;
396
397         hbl = edid->hback_porch.typ + edid->hfront_porch.typ +
398                         edid->hsync_len.typ;
399         vbl = edid->vback_porch.typ + edid->vfront_porch.typ +
400                         edid->vsync_len.typ;
401
402         /* set up hdmi_fc_invidconf */
403         inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE;
404
405         inv_val |= (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
406                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
407                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
408
409         inv_val |= (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
410                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
411                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
412
413         inv_val |= (mdataenablepolarity ?
414                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
415                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
416
417         inv_val |= (edid->hdmi_monitor ?
418                    HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
419                    HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE);
420
421         inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
422
423         inv_val |= HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
424
425         hdmi_write(hdmi, inv_val, HDMI_FC_INVIDCONF);
426
427         /* set up horizontal active pixel width */
428         hdmi_write(hdmi, edid->hactive.typ >> 8, HDMI_FC_INHACTV1);
429         hdmi_write(hdmi, edid->hactive.typ, HDMI_FC_INHACTV0);
430
431         /* set up vertical active lines */
432         hdmi_write(hdmi, edid->vactive.typ >> 8, HDMI_FC_INVACTV1);
433         hdmi_write(hdmi, edid->vactive.typ, HDMI_FC_INVACTV0);
434
435         /* set up horizontal blanking pixel region width */
436         hdmi_write(hdmi, hbl >> 8, HDMI_FC_INHBLANK1);
437         hdmi_write(hdmi, hbl, HDMI_FC_INHBLANK0);
438
439         /* set up vertical blanking pixel region width */
440         hdmi_write(hdmi, vbl, HDMI_FC_INVBLANK);
441
442         /* set up hsync active edge delay width (in pixel clks) */
443         hdmi_write(hdmi, edid->hfront_porch.typ >> 8, HDMI_FC_HSYNCINDELAY1);
444         hdmi_write(hdmi, edid->hfront_porch.typ, HDMI_FC_HSYNCINDELAY0);
445
446         /* set up vsync active edge delay (in lines) */
447         hdmi_write(hdmi, edid->vfront_porch.typ, HDMI_FC_VSYNCINDELAY);
448
449         /* set up hsync active pulse width (in pixel clks) */
450         hdmi_write(hdmi, edid->hsync_len.typ >> 8, HDMI_FC_HSYNCINWIDTH1);
451         hdmi_write(hdmi, edid->hsync_len.typ, HDMI_FC_HSYNCINWIDTH0);
452
453         /* set up vsync active edge delay (in lines) */
454         hdmi_write(hdmi, edid->vsync_len.typ, HDMI_FC_VSYNCINWIDTH);
455 }
456
457 /* hdmi initialization step b.4 */
458 static void hdmi_enable_video_path(struct dw_hdmi *hdmi, bool audio)
459 {
460         uint clkdis;
461
462         /* control period minimum duration */
463         hdmi_write(hdmi, 12, HDMI_FC_CTRLDUR);
464         hdmi_write(hdmi, 32, HDMI_FC_EXCTRLDUR);
465         hdmi_write(hdmi, 1, HDMI_FC_EXCTRLSPAC);
466
467         /* set to fill tmds data channels */
468         hdmi_write(hdmi, 0x0b, HDMI_FC_CH0PREAM);
469         hdmi_write(hdmi, 0x16, HDMI_FC_CH1PREAM);
470         hdmi_write(hdmi, 0x21, HDMI_FC_CH2PREAM);
471
472         hdmi_write(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
473                    HDMI_MC_FLOWCTRL);
474
475         /* enable pixel clock and tmds data path */
476         clkdis = 0x7f;
477         clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
478         hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
479
480         clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
481         hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
482
483         if (audio) {
484                 clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
485                 hdmi_write(hdmi, clkdis, HDMI_MC_CLKDIS);
486         }
487 }
488
489 /* workaround to clear the overflow condition */
490 static void hdmi_clear_overflow(struct dw_hdmi *hdmi)
491 {
492         uint val, count;
493
494         /* tmds software reset */
495         hdmi_write(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
496
497         val = hdmi_read(hdmi, HDMI_FC_INVIDCONF);
498
499         for (count = 0; count < 4; count++)
500                 hdmi_write(hdmi, val, HDMI_FC_INVIDCONF);
501 }
502
503 static void hdmi_audio_set_format(struct dw_hdmi *hdmi)
504 {
505         hdmi_write(hdmi, HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_IN_EN_0,
506                    HDMI_AUD_CONF0);
507
508
509         hdmi_write(hdmi, HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE |
510                    HDMI_AUD_CONF1_I2S_WIDTH_16BIT, HDMI_AUD_CONF1);
511
512         hdmi_write(hdmi, 0x00, HDMI_AUD_CONF2);
513 }
514
515 static void hdmi_audio_fifo_reset(struct dw_hdmi *hdmi)
516 {
517         hdmi_write(hdmi, (u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, HDMI_MC_SWRSTZ);
518         hdmi_write(hdmi, HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, HDMI_AUD_CONF0);
519
520         hdmi_write(hdmi, 0x00, HDMI_AUD_INT);
521         hdmi_write(hdmi, 0x00, HDMI_AUD_INT1);
522 }
523
524 static int hdmi_get_plug_in_status(struct dw_hdmi *hdmi)
525 {
526         uint val = hdmi_read(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD;
527
528         return !!val;
529 }
530
531 static int hdmi_ddc_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
532 {
533         u32 val;
534         ulong start;
535
536         start = get_timer(0);
537         do {
538                 val = hdmi_read(hdmi, HDMI_IH_I2CM_STAT0);
539                 if (val & 0x2) {
540                         hdmi_write(hdmi, val, HDMI_IH_I2CM_STAT0);
541                         return 0;
542                 }
543
544                 udelay(100);
545         } while (get_timer(start) < msec);
546
547         return 1;
548 }
549
550 static void hdmi_ddc_reset(struct dw_hdmi *hdmi)
551 {
552         hdmi_mod(hdmi, HDMI_I2CM_SOFTRSTZ, HDMI_I2CM_SOFTRSTZ_MASK, 0);
553 }
554
555 static int hdmi_read_edid(struct dw_hdmi *hdmi, int block, u8 *buff)
556 {
557         int shift = (block % 2) * 0x80;
558         int edid_read_err = 0;
559         u32 trytime = 5;
560         u32 n;
561
562         /* set ddc i2c clk which devided from ddc_clk to 100khz */
563         hdmi_write(hdmi, hdmi->i2c_clk_high, HDMI_I2CM_SS_SCL_HCNT_0_ADDR);
564         hdmi_write(hdmi, hdmi->i2c_clk_low, HDMI_I2CM_SS_SCL_LCNT_0_ADDR);
565         hdmi_mod(hdmi, HDMI_I2CM_DIV, HDMI_I2CM_DIV_FAST_STD_MODE,
566                  HDMI_I2CM_DIV_STD_MODE);
567
568         hdmi_write(hdmi, HDMI_I2CM_SLAVE_DDC_ADDR, HDMI_I2CM_SLAVE);
569         hdmi_write(hdmi, HDMI_I2CM_SEGADDR_DDC, HDMI_I2CM_SEGADDR);
570         hdmi_write(hdmi, block >> 1, HDMI_I2CM_SEGPTR);
571
572         while (trytime--) {
573                 edid_read_err = 0;
574
575                 for (n = 0; n < HDMI_EDID_BLOCK_SIZE; n++) {
576                         hdmi_write(hdmi, shift + n, HDMI_I2CM_ADDRESS);
577
578                         if (block == 0)
579                                 hdmi_write(hdmi, HDMI_I2CM_OP_RD8,
580                                            HDMI_I2CM_OPERATION);
581                         else
582                                 hdmi_write(hdmi, HDMI_I2CM_OP_RD8_EXT,
583                                            HDMI_I2CM_OPERATION);
584
585                         if (hdmi_ddc_wait_i2c_done(hdmi, 10)) {
586                                 hdmi_ddc_reset(hdmi);
587                                 edid_read_err = 1;
588                                 break;
589                         }
590
591                         buff[n] = hdmi_read(hdmi, HDMI_I2CM_DATAI);
592                 }
593
594                 if (!edid_read_err)
595                         break;
596         }
597
598         return edid_read_err;
599 }
600
601 static const u8 pre_buf[] = {
602         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
603         0x04, 0x69, 0xfa, 0x23, 0xc8, 0x28, 0x01, 0x00,
604         0x10, 0x17, 0x01, 0x03, 0x80, 0x33, 0x1d, 0x78,
605         0x2a, 0xd9, 0x45, 0xa2, 0x55, 0x4d, 0xa0, 0x27,
606         0x12, 0x50, 0x54, 0xb7, 0xef, 0x00, 0x71, 0x4f,
607         0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0xb3, 0x00,
608         0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x00, 0x02, 0x3a,
609         0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
610         0x45, 0x00, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
611         0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x34, 0x4c,
612         0x4d, 0x54, 0x46, 0x30, 0x37, 0x35, 0x39, 0x37,
613         0x36, 0x0a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
614         0x4b, 0x18, 0x53, 0x11, 0x00, 0x0a, 0x20, 0x20,
615         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
616         0x00, 0x41, 0x53, 0x55, 0x53, 0x20, 0x56, 0x53,
617         0x32, 0x33, 0x38, 0x0a, 0x20, 0x20, 0x01, 0xb0,
618         0x02, 0x03, 0x22, 0x71, 0x4f, 0x01, 0x02, 0x03,
619         0x11, 0x12, 0x13, 0x04, 0x14, 0x05, 0x0e, 0x0f,
620         0x1d, 0x1e, 0x1f, 0x10, 0x23, 0x09, 0x17, 0x07,
621         0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0c, 0x00,
622         0x10, 0x00, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0,
623         0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xfd, 0x1e,
624         0x11, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0x72,
625         0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
626         0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d,
627         0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28,
628         0x55, 0x40, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
629         0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20,
630         0x0c, 0x40, 0x55, 0x00, 0xfd, 0x1e, 0x11, 0x00,
631         0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9,
634 };
635
636 int dw_hdmi_phy_cfg(struct dw_hdmi *hdmi, uint mpixelclock)
637 {
638         int i, ret;
639
640         /* hdmi phy spec says to do the phy initialization sequence twice */
641         for (i = 0; i < 2; i++) {
642                 hdmi_phy_sel_data_en_pol(hdmi, 1);
643                 hdmi_phy_sel_interface_control(hdmi, 0);
644                 hdmi_phy_enable_tmds(hdmi, 0);
645                 hdmi_phy_enable_power(hdmi, 0);
646
647                 ret = hdmi_phy_configure(hdmi, mpixelclock);
648                 if (ret) {
649                         debug("hdmi phy config failure %d\n", ret);
650                         return ret;
651                 }
652         }
653
654         return 0;
655 }
656
657 int dw_hdmi_phy_wait_for_hpd(struct dw_hdmi *hdmi)
658 {
659         ulong start;
660
661         start = get_timer(0);
662         do {
663                 if (hdmi_get_plug_in_status(hdmi))
664                         return 0;
665                 udelay(100);
666         } while (get_timer(start) < 300);
667
668         return -1;
669 }
670
671 void dw_hdmi_phy_init(struct dw_hdmi *hdmi)
672 {
673         /* enable phy i2cm done irq */
674         hdmi_write(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
675                    HDMI_PHY_I2CM_INT_ADDR);
676
677         /* enable phy i2cm nack & arbitration error irq */
678         hdmi_write(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
679                    HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
680                    HDMI_PHY_I2CM_CTLINT_ADDR);
681
682         /* enable cable hot plug irq */
683         hdmi_write(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
684
685         /* clear hotplug interrupts */
686         hdmi_write(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
687 }
688
689 int dw_hdmi_read_edid(struct dw_hdmi *hdmi, u8 *buf, int buf_size)
690 {
691         u32 edid_size = HDMI_EDID_BLOCK_SIZE;
692         int ret;
693
694         if (0) {
695                 edid_size = sizeof(pre_buf);
696                 memcpy(buf, pre_buf, edid_size);
697         } else {
698                 ret = hdmi_read_edid(hdmi, 0, buf);
699                 if (ret) {
700                         debug("failed to read edid.\n");
701                         return -1;
702                 }
703
704                 if (buf[0x7e] != 0) {
705                         hdmi_read_edid(hdmi, 1, buf + HDMI_EDID_BLOCK_SIZE);
706                         edid_size += HDMI_EDID_BLOCK_SIZE;
707                 }
708         }
709
710         return edid_size;
711 }
712
713 int dw_hdmi_enable(struct dw_hdmi *hdmi, const struct display_timing *edid)
714 {
715         int ret;
716
717         debug("%s, mode info : clock %d hdis %d vdis %d\n",
718               edid->hdmi_monitor ? "hdmi" : "dvi",
719               edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ);
720
721         hdmi_av_composer(hdmi, edid);
722
723         ret = hdmi->phy_set(hdmi, edid->pixelclock.typ);
724         if (ret)
725                 return ret;
726
727         hdmi_enable_video_path(hdmi, edid->hdmi_monitor);
728
729         if (edid->hdmi_monitor) {
730                 hdmi_audio_fifo_reset(hdmi);
731                 hdmi_audio_set_format(hdmi);
732                 hdmi_audio_set_samplerate(hdmi, edid->pixelclock.typ);
733         }
734
735         hdmi_video_packetize(hdmi);
736         hdmi_video_sample(hdmi);
737
738         hdmi_clear_overflow(hdmi);
739
740         return 0;
741 }
742
743 void dw_hdmi_init(struct dw_hdmi *hdmi)
744 {
745         uint ih_mute;
746
747         /*
748          * boot up defaults are:
749          * hdmi_ih_mute   = 0x03 (disabled)
750          * hdmi_ih_mute_* = 0x00 (enabled)
751          *
752          * disable top level interrupt bits in hdmi block
753          */
754         ih_mute = /*hdmi_read(hdmi, HDMI_IH_MUTE) |*/
755                   HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
756                   HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
757
758         hdmi_write(hdmi, ih_mute, HDMI_IH_MUTE);
759
760         /* enable i2c master done irq */
761         hdmi_write(hdmi, ~0x04, HDMI_I2CM_INT);
762
763         /* enable i2c client nack % arbitration error irq */
764         hdmi_write(hdmi, ~0x44, HDMI_I2CM_CTLINT);
765 }