Merge git://git.denx.de/u-boot-rockchip
[oweals/u-boot.git] / drivers / video / rockchip / rk_hdmi.c
1 /*
2  * Copyright (c) 2015 Google, Inc
3  * Copyright 2014 Rockchip Inc.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <clk.h>
10 #include <display.h>
11 #include <dm.h>
12 #include <edid.h>
13 #include <regmap.h>
14 #include <syscon.h>
15 #include <asm/gpio.h>
16 #include <asm/io.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/grf_rk3288.h>
19 #include <asm/arch/hdmi_rk3288.h>
20 #include <power/regulator.h>
21
22 struct tmds_n_cts {
23         u32 tmds;
24         u32 cts;
25         u32 n;
26 };
27
28 struct rk_hdmi_priv {
29         struct rk3288_hdmi *regs;
30         struct rk3288_grf *grf;
31 };
32
33 static const struct tmds_n_cts n_cts_table[] = {
34         {
35                 .tmds = 25175000, .n = 6144, .cts = 25175,
36         }, {
37                 .tmds = 25200000, .n = 6144, .cts = 25200,
38         }, {
39                 .tmds = 27000000, .n = 6144, .cts = 27000,
40         }, {
41                 .tmds = 27027000, .n = 6144, .cts = 27027,
42         }, {
43                 .tmds = 40000000, .n = 6144, .cts = 40000,
44         }, {
45                 .tmds = 54000000, .n = 6144, .cts = 54000,
46         }, {
47                 .tmds = 54054000, .n = 6144, .cts = 54054,
48         }, {
49                 .tmds = 65000000, .n = 6144, .cts = 65000,
50         }, {
51                 .tmds = 74176000, .n = 11648, .cts = 140625,
52         }, {
53                 .tmds = 74250000, .n = 6144, .cts = 74250,
54         }, {
55                 .tmds = 83500000, .n = 6144, .cts = 83500,
56         }, {
57                 .tmds = 106500000, .n = 6144, .cts = 106500,
58         }, {
59                 .tmds = 108000000, .n = 6144, .cts = 108000,
60         }, {
61                 .tmds = 148352000, .n = 5824, .cts = 140625,
62         }, {
63                 .tmds = 148500000, .n = 6144, .cts = 148500,
64         }, {
65                 .tmds = 297000000, .n = 5120, .cts = 247500,
66         }
67 };
68
69 struct hdmi_mpll_config {
70         u64 mpixelclock;
71         /* Mode of Operation and PLL Dividers Control Register */
72         u32 cpce;
73         /* PLL Gmp Control Register */
74         u32 gmp;
75         /* PLL Current COntrol Register */
76         u32 curr;
77 };
78
79 struct hdmi_phy_config {
80         u64 mpixelclock;
81         u32 sym_ctr;    /* clock symbol and transmitter control */
82         u32 term;       /* transmission termination value */
83         u32 vlev_ctr;   /* voltage level control */
84 };
85
86 static const struct hdmi_phy_config rockchip_phy_config[] = {
87         {
88                 .mpixelclock = 74250000,
89                 .sym_ctr = 0x8009, .term = 0x0004, .vlev_ctr = 0x0272,
90         }, {
91                 .mpixelclock = 148500000,
92                 .sym_ctr = 0x802b, .term = 0x0004, .vlev_ctr = 0x028d,
93         }, {
94                 .mpixelclock = 297000000,
95                 .sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
96         }, {
97                 .mpixelclock = ~0ul,
98                 .sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
99         }
100 };
101
102 static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
103         {
104                 .mpixelclock = 40000000,
105                 .cpce = 0x00b3, .gmp = 0x0000, .curr = 0x0018,
106         }, {
107                 .mpixelclock = 65000000,
108                 .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
109         }, {
110                 .mpixelclock = 66000000,
111                 .cpce = 0x013e, .gmp = 0x0003, .curr = 0x0038,
112         }, {
113                 .mpixelclock = 83500000,
114                 .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
115         }, {
116                 .mpixelclock = 146250000,
117                 .cpce = 0x0051, .gmp = 0x0002, .curr = 0x0038,
118         }, {
119                 .mpixelclock = 148500000,
120                 .cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
121         }, {
122                 .mpixelclock = ~0ul,
123                 .cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
124         }
125 };
126
127 static void hdmi_set_clock_regenerator(struct rk3288_hdmi *regs, u32 n, u32 cts)
128 {
129         uint cts3;
130         uint n3;
131
132         /* first set ncts_atomic_write (if present) */
133         n3 = HDMI_AUD_N3_NCTS_ATOMIC_WRITE;
134         writel(n3, &regs->aud_n3);
135
136         /* set cts_manual (if present) */
137         cts3 = HDMI_AUD_CTS3_CTS_MANUAL;
138
139         cts3 |= HDMI_AUD_CTS3_N_SHIFT_1 << HDMI_AUD_CTS3_N_SHIFT_OFFSET;
140         cts3 |= (cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK;
141
142         /* write cts values; cts3 must be written first */
143         writel(cts3, &regs->aud_cts3);
144         writel((cts >> 8) & 0xff, &regs->aud_cts2);
145         writel(cts & 0xff, &regs->aud_cts1);
146
147         /* write n values; n1 must be written last */
148         n3 |= (n >> 16) & HDMI_AUD_N3_AUDN19_16_MASK;
149         writel(n3, &regs->aud_n3);
150         writel((n >> 8) & 0xff, &regs->aud_n2);
151         writel(n & 0xff, &regs->aud_n1);
152
153         writel(HDMI_AUD_INPUTCLKFS_128, &regs->aud_inputclkfs);
154 }
155
156 static int hdmi_lookup_n_cts(u32 pixel_clk)
157 {
158         int i;
159
160         for (i = 0; i < ARRAY_SIZE(n_cts_table); i++)
161                 if (pixel_clk <= n_cts_table[i].tmds)
162                         break;
163
164         if (i >= ARRAY_SIZE(n_cts_table))
165                 return -1;
166
167         return i;
168 }
169
170 static void hdmi_audio_set_samplerate(struct rk3288_hdmi *regs, u32 pixel_clk)
171 {
172         u32 clk_n, clk_cts;
173         int index;
174
175         index = hdmi_lookup_n_cts(pixel_clk);
176         if (index == -1) {
177                 debug("audio not supported for pixel clk %d\n", pixel_clk);
178                 return;
179         }
180
181         clk_n = n_cts_table[index].n;
182         clk_cts = n_cts_table[index].cts;
183         hdmi_set_clock_regenerator(regs, clk_n, clk_cts);
184 }
185
186 /*
187  * this submodule is responsible for the video data synchronization.
188  * for example, for rgb 4:4:4 input, the data map is defined as
189  *                      pin{47~40} <==> r[7:0]
190  *                      pin{31~24} <==> g[7:0]
191  *                      pin{15~8}  <==> b[7:0]
192  */
193 static void hdmi_video_sample(struct rk3288_hdmi *regs)
194 {
195         u32 color_format = 0x01;
196         uint val;
197
198         val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
199               ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
200               HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
201
202         writel(val, &regs->tx_invid0);
203
204         /* enable tx stuffing: when de is inactive, fix the output data to 0 */
205         val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
206               HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
207               HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
208         writel(val, &regs->tx_instuffing);
209         writel(0x0, &regs->tx_gydata0);
210         writel(0x0, &regs->tx_gydata1);
211         writel(0x0, &regs->tx_rcrdata0);
212         writel(0x0, &regs->tx_rcrdata1);
213         writel(0x0, &regs->tx_bcbdata0);
214         writel(0x0, &regs->tx_bcbdata1);
215 }
216
217 static void hdmi_video_packetize(struct rk3288_hdmi *regs)
218 {
219         u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
220         u32 remap_size = HDMI_VP_REMAP_YCC422_16BIT;
221         u32 color_depth = 0;
222         uint val, vp_conf;
223
224         /* set the packetizer registers */
225         val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
226                 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
227                 ((0 << HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
228                 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
229         writel(val, &regs->vp_pr_cd);
230
231         clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_PR_STUFFING_MASK,
232                         HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE);
233
234         /* data from pixel repeater block */
235         vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
236                   HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
237
238         clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_PR_EN_MASK |
239                         HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf);
240
241         clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
242                         1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET);
243
244         writel(remap_size, &regs->vp_remap);
245
246         vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
247                   HDMI_VP_CONF_PP_EN_DISABLE |
248                   HDMI_VP_CONF_YCC422_EN_DISABLE;
249
250         clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_BYPASS_EN_MASK |
251                         HDMI_VP_CONF_PP_EN_ENMASK | HDMI_VP_CONF_YCC422_EN_MASK,
252                         vp_conf);
253
254         clrsetbits_le32(&regs->vp_stuff, HDMI_VP_STUFF_PP_STUFFING_MASK |
255                         HDMI_VP_STUFF_YCC422_STUFFING_MASK,
256                         HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
257                         HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE);
258
259         clrsetbits_le32(&regs->vp_conf, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
260                         output_select);
261 }
262
263 static inline void hdmi_phy_test_clear(struct rk3288_hdmi *regs, uint bit)
264 {
265         clrsetbits_le32(&regs->phy_tst0, HDMI_PHY_TST0_TSTCLR_MASK,
266                         bit << HDMI_PHY_TST0_TSTCLR_OFFSET);
267 }
268
269 static int hdmi_phy_wait_i2c_done(struct rk3288_hdmi *regs, u32 msec)
270 {
271         ulong start;
272         u32 val;
273
274         start = get_timer(0);
275         do {
276                 val = readl(&regs->ih_i2cmphy_stat0);
277                 if (val & 0x3) {
278                         writel(val, &regs->ih_i2cmphy_stat0);
279                         return 0;
280                 }
281
282                 udelay(100);
283         } while (get_timer(start) < msec);
284
285         return 1;
286 }
287
288 static void hdmi_phy_i2c_write(struct rk3288_hdmi *regs, uint data, uint addr)
289 {
290         writel(0xff, &regs->ih_i2cmphy_stat0);
291         writel(addr, &regs->phy_i2cm_address_addr);
292         writel((u8)(data >> 8), &regs->phy_i2cm_datao_1_addr);
293         writel((u8)(data >> 0), &regs->phy_i2cm_datao_0_addr);
294         writel(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
295                &regs->phy_i2cm_operation_addr);
296
297         hdmi_phy_wait_i2c_done(regs, 1000);
298 }
299
300 static void hdmi_phy_enable_power(struct rk3288_hdmi *regs, uint enable)
301 {
302         clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_PDZ_MASK,
303                         enable << HDMI_PHY_CONF0_PDZ_OFFSET);
304 }
305
306 static void hdmi_phy_enable_tmds(struct rk3288_hdmi *regs, uint enable)
307 {
308         clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_ENTMDS_MASK,
309                         enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
310 }
311
312 static void hdmi_phy_enable_spare(struct rk3288_hdmi *regs, uint enable)
313 {
314         clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_SPARECTRL_MASK,
315                         enable << HDMI_PHY_CONF0_SPARECTRL_OFFSET);
316 }
317
318 static void hdmi_phy_gen2_pddq(struct rk3288_hdmi *regs, uint enable)
319 {
320         clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_GEN2_PDDQ_MASK,
321                         enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
322 }
323
324 static void hdmi_phy_gen2_txpwron(struct rk3288_hdmi *regs, uint enable)
325 {
326         clrsetbits_le32(&regs->phy_conf0,
327                         HDMI_PHY_CONF0_GEN2_TXPWRON_MASK,
328                         enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
329 }
330
331 static void hdmi_phy_sel_data_en_pol(struct rk3288_hdmi *regs, uint enable)
332 {
333         clrsetbits_le32(&regs->phy_conf0,
334                         HDMI_PHY_CONF0_SELDATAENPOL_MASK,
335                         enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
336 }
337
338 static void hdmi_phy_sel_interface_control(struct rk3288_hdmi *regs,
339                                            uint enable)
340 {
341         clrsetbits_le32(&regs->phy_conf0, HDMI_PHY_CONF0_SELDIPIF_MASK,
342                         enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
343 }
344
345 static int hdmi_phy_configure(struct rk3288_hdmi *regs, u32 mpixelclock)
346 {
347         ulong start;
348         uint i, val;
349
350         writel(HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
351                &regs->mc_flowctrl);
352
353         /* gen2 tx power off */
354         hdmi_phy_gen2_txpwron(regs, 0);
355
356         /* gen2 pddq */
357         hdmi_phy_gen2_pddq(regs, 1);
358
359         /* phy reset */
360         writel(HDMI_MC_PHYRSTZ_DEASSERT, &regs->mc_phyrstz);
361         writel(HDMI_MC_PHYRSTZ_ASSERT, &regs->mc_phyrstz);
362         writel(HDMI_MC_HEACPHY_RST_ASSERT, &regs->mc_heacphy_rst);
363
364         hdmi_phy_test_clear(regs, 1);
365         writel(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, &regs->phy_i2cm_slave_addr);
366         hdmi_phy_test_clear(regs, 0);
367
368         /* pll/mpll cfg - always match on final entry */
369         for (i = 0; rockchip_mpll_cfg[i].mpixelclock != (~0ul); i++)
370                 if (mpixelclock <= rockchip_mpll_cfg[i].mpixelclock)
371                         break;
372
373         hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].cpce, PHY_OPMODE_PLLCFG);
374         hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].gmp, PHY_PLLGMPCTRL);
375         hdmi_phy_i2c_write(regs, rockchip_mpll_cfg[i].curr, PHY_PLLCURRCTRL);
376
377         hdmi_phy_i2c_write(regs, 0x0000, PHY_PLLPHBYCTRL);
378         hdmi_phy_i2c_write(regs, 0x0006, PHY_PLLCLKBISTPHASE);
379
380         for (i = 0; rockchip_phy_config[i].mpixelclock != (~0ul); i++)
381                 if (mpixelclock <= rockchip_phy_config[i].mpixelclock)
382                         break;
383
384         /*
385          * resistance term 133ohm cfg
386          * preemp cgf 0.00
387          * tx/ck lvl 10
388          */
389         hdmi_phy_i2c_write(regs, rockchip_phy_config[i].term, PHY_TXTERM);
390         hdmi_phy_i2c_write(regs, rockchip_phy_config[i].sym_ctr,
391                            PHY_CKSYMTXCTRL);
392         hdmi_phy_i2c_write(regs, rockchip_phy_config[i].vlev_ctr, PHY_VLEVCTRL);
393
394         /* remove clk term */
395         hdmi_phy_i2c_write(regs, 0x8000, PHY_CKCALCTRL);
396
397         hdmi_phy_enable_power(regs, 1);
398
399         /* toggle tmds enable */
400         hdmi_phy_enable_tmds(regs, 0);
401         hdmi_phy_enable_tmds(regs, 1);
402
403         /* gen2 tx power on */
404         hdmi_phy_gen2_txpwron(regs, 1);
405         hdmi_phy_gen2_pddq(regs, 0);
406
407         hdmi_phy_enable_spare(regs, 1);
408
409         /* wait for phy pll lock */
410         start = get_timer(0);
411         do {
412                 val = readl(&regs->phy_stat0);
413                 if (!(val & HDMI_PHY_TX_PHY_LOCK))
414                         return 0;
415
416                 udelay(100);
417         } while (get_timer(start) < 5);
418
419         return -1;
420 }
421
422 static int hdmi_phy_init(struct rk3288_hdmi *regs, uint mpixelclock)
423 {
424         int i, ret;
425
426         /* hdmi phy spec says to do the phy initialization sequence twice */
427         for (i = 0; i < 2; i++) {
428                 hdmi_phy_sel_data_en_pol(regs, 1);
429                 hdmi_phy_sel_interface_control(regs, 0);
430                 hdmi_phy_enable_tmds(regs, 0);
431                 hdmi_phy_enable_power(regs, 0);
432
433                 ret = hdmi_phy_configure(regs, mpixelclock);
434                 if (ret) {
435                         debug("hdmi phy config failure %d\n", ret);
436                         return ret;
437                 }
438         }
439
440         return 0;
441 }
442
443 static void hdmi_av_composer(struct rk3288_hdmi *regs,
444                              const struct display_timing *edid)
445 {
446         bool mdataenablepolarity = true;
447         uint inv_val;
448         uint hbl;
449         uint vbl;
450
451         hbl = edid->hback_porch.typ + edid->hfront_porch.typ +
452                         edid->hsync_len.typ;
453         vbl = edid->vback_porch.typ + edid->vfront_porch.typ +
454                         edid->vsync_len.typ;
455
456         /* set up hdmi_fc_invidconf */
457         inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE;
458
459         inv_val |= (edid->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
460                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
461                    HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
462
463         inv_val |= (edid->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
464                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
465                    HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
466
467         inv_val |= (mdataenablepolarity ?
468                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
469                    HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
470
471         /*
472          * TODO(sjg@chromium.org>: Need to check for HDMI / DVI
473          * inv_val |= (edid->hdmi_monitor_detected ?
474          *         HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
475          *         HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE);
476          */
477         inv_val |= HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE;
478
479         inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
480
481         inv_val |= HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
482
483         writel(inv_val, &regs->fc_invidconf);
484
485         /* set up horizontal active pixel width */
486         writel(edid->hactive.typ >> 8, &regs->fc_inhactv1);
487         writel(edid->hactive.typ, &regs->fc_inhactv0);
488
489         /* set up vertical active lines */
490         writel(edid->vactive.typ >> 8, &regs->fc_invactv1);
491         writel(edid->vactive.typ, &regs->fc_invactv0);
492
493         /* set up horizontal blanking pixel region width */
494         writel(hbl >> 8, &regs->fc_inhblank1);
495         writel(hbl, &regs->fc_inhblank0);
496
497         /* set up vertical blanking pixel region width */
498         writel(vbl, &regs->fc_invblank);
499
500         /* set up hsync active edge delay width (in pixel clks) */
501         writel(edid->hfront_porch.typ >> 8, &regs->fc_hsyncindelay1);
502         writel(edid->hfront_porch.typ, &regs->fc_hsyncindelay0);
503
504         /* set up vsync active edge delay (in lines) */
505         writel(edid->vfront_porch.typ, &regs->fc_vsyncindelay);
506
507         /* set up hsync active pulse width (in pixel clks) */
508         writel(edid->hsync_len.typ >> 8, &regs->fc_hsyncinwidth1);
509         writel(edid->hsync_len.typ, &regs->fc_hsyncinwidth0);
510
511         /* set up vsync active edge delay (in lines) */
512         writel(edid->vsync_len.typ, &regs->fc_vsyncinwidth);
513 }
514
515 /* hdmi initialization step b.4 */
516 static void hdmi_enable_video_path(struct rk3288_hdmi *regs)
517 {
518         uint clkdis;
519
520         /* control period minimum duration */
521         writel(12, &regs->fc_ctrldur);
522         writel(32, &regs->fc_exctrldur);
523         writel(1, &regs->fc_exctrlspac);
524
525         /* set to fill tmds data channels */
526         writel(0x0b, &regs->fc_ch0pream);
527         writel(0x16, &regs->fc_ch1pream);
528         writel(0x21, &regs->fc_ch2pream);
529
530         /* enable pixel clock and tmds data path */
531         clkdis = 0x7f;
532         clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
533         writel(clkdis, &regs->mc_clkdis);
534
535         clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
536         writel(clkdis, &regs->mc_clkdis);
537
538         clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
539         writel(clkdis, &regs->mc_clkdis);
540 }
541
542 /* workaround to clear the overflow condition */
543 static void hdmi_clear_overflow(struct rk3288_hdmi *regs)
544 {
545         uint val, count;
546
547         /* tmds software reset */
548         writel((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &regs->mc_swrstz);
549
550         val = readl(&regs->fc_invidconf);
551
552         for (count = 0; count < 4; count++)
553                 writel(val, &regs->fc_invidconf);
554 }
555
556 static void hdmi_audio_set_format(struct rk3288_hdmi *regs)
557 {
558         writel(HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_IN_EN_0,
559                &regs->aud_conf0);
560
561
562         writel(HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE |
563                HDMI_AUD_CONF1_I2S_WIDTH_16BIT, &regs->aud_conf1);
564
565         writel(0x00, &regs->aud_conf2);
566 }
567
568 static void hdmi_audio_fifo_reset(struct rk3288_hdmi *regs)
569 {
570         writel((u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, &regs->mc_swrstz);
571         writel(HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, &regs->aud_conf0);
572
573         writel(0x00, &regs->aud_int);
574         writel(0x00, &regs->aud_int1);
575 }
576
577 static void hdmi_init_interrupt(struct rk3288_hdmi *regs)
578 {
579         uint ih_mute;
580
581         /*
582          * boot up defaults are:
583          * hdmi_ih_mute   = 0x03 (disabled)
584          * hdmi_ih_mute_* = 0x00 (enabled)
585          *
586          * disable top level interrupt bits in hdmi block
587          */
588         ih_mute = readl(&regs->ih_mute) |
589                   HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
590                   HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
591
592         writel(ih_mute, &regs->ih_mute);
593
594         /* enable i2c master done irq */
595         writel(~0x04, &regs->i2cm_int);
596
597         /* enable i2c client nack % arbitration error irq */
598         writel(~0x44, &regs->i2cm_ctlint);
599
600         /* enable phy i2cm done irq */
601         writel(HDMI_PHY_I2CM_INT_ADDR_DONE_POL, &regs->phy_i2cm_int_addr);
602
603         /* enable phy i2cm nack & arbitration error irq */
604         writel(HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
605                 HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
606                 &regs->phy_i2cm_ctlint_addr);
607
608         /* enable cable hot plug irq */
609         writel((u8)~HDMI_PHY_HPD, &regs->phy_mask0);
610
611         /* clear hotplug interrupts */
612         writel(HDMI_IH_PHY_STAT0_HPD, &regs->ih_phy_stat0);
613 }
614
615 static int hdmi_get_plug_in_status(struct rk3288_hdmi *regs)
616 {
617         uint val = readl(&regs->phy_stat0) & HDMI_PHY_HPD;
618
619         return !!val;
620 }
621
622 static int hdmi_wait_for_hpd(struct rk3288_hdmi *regs)
623 {
624         ulong start;
625
626         start = get_timer(0);
627         do {
628                 if (hdmi_get_plug_in_status(regs))
629                         return 0;
630                 udelay(100);
631         } while (get_timer(start) < 300);
632
633         return -1;
634 }
635
636 static int hdmi_ddc_wait_i2c_done(struct rk3288_hdmi *regs, int msec)
637 {
638         u32 val;
639         ulong start;
640
641         start = get_timer(0);
642         do {
643                 val = readl(&regs->ih_i2cm_stat0);
644                 if (val & 0x2) {
645                         writel(val, &regs->ih_i2cm_stat0);
646                         return 0;
647                 }
648
649                 udelay(100);
650         } while (get_timer(start) < msec);
651
652         return 1;
653 }
654
655 static void hdmi_ddc_reset(struct rk3288_hdmi *regs)
656 {
657         clrbits_le32(&regs->i2cm_softrstz, HDMI_I2CM_SOFTRSTZ);
658 }
659
660 static int hdmi_read_edid(struct rk3288_hdmi *regs, int block, u8 *buff)
661 {
662         int shift = (block % 2) * 0x80;
663         int edid_read_err = 0;
664         u32 trytime = 5;
665         u32 n, j, val;
666
667         /* set ddc i2c clk which devided from ddc_clk to 100khz */
668         writel(0x7a, &regs->i2cm_ss_scl_hcnt_0_addr);
669         writel(0x8d, &regs->i2cm_ss_scl_lcnt_0_addr);
670
671         /*
672          * TODO(sjg@chromium.org): The above values don't work - these ones
673          * work better, but generate lots of errors in the data.
674          */
675         writel(0x0d, &regs->i2cm_ss_scl_hcnt_0_addr);
676         writel(0x0d, &regs->i2cm_ss_scl_lcnt_0_addr);
677         clrsetbits_le32(&regs->i2cm_div, HDMI_I2CM_DIV_FAST_STD_MODE,
678                         HDMI_I2CM_DIV_STD_MODE);
679
680         writel(HDMI_I2CM_SLAVE_DDC_ADDR, &regs->i2cm_slave);
681         writel(HDMI_I2CM_SEGADDR_DDC, &regs->i2cm_segaddr);
682         writel(block >> 1, &regs->i2cm_segptr);
683
684         while (trytime--) {
685                 edid_read_err = 0;
686
687                 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
688                         writel(shift + 8 * n, &regs->i2c_address);
689
690                         if (block == 0)
691                                 clrsetbits_le32(&regs->i2cm_operation,
692                                                 HDMI_I2CM_OPT_RD8,
693                                                 HDMI_I2CM_OPT_RD8);
694                         else
695                                 clrsetbits_le32(&regs->i2cm_operation,
696                                                 HDMI_I2CM_OPT_RD8_EXT,
697                                                 HDMI_I2CM_OPT_RD8_EXT);
698
699                         if (hdmi_ddc_wait_i2c_done(regs, 10)) {
700                                 hdmi_ddc_reset(regs);
701                                 edid_read_err = 1;
702                                 break;
703                         }
704
705                         for (j = 0; j < 8; j++) {
706                                 val = readl(&regs->i2cm_buf0 + j);
707                                 buff[8 * n + j] = val;
708                         }
709                 }
710
711                 if (!edid_read_err)
712                         break;
713         }
714
715         return edid_read_err;
716 }
717
718 static const u8 pre_buf[] = {
719         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
720         0x04, 0x69, 0xfa, 0x23, 0xc8, 0x28, 0x01, 0x00,
721         0x10, 0x17, 0x01, 0x03, 0x80, 0x33, 0x1d, 0x78,
722         0x2a, 0xd9, 0x45, 0xa2, 0x55, 0x4d, 0xa0, 0x27,
723         0x12, 0x50, 0x54, 0xb7, 0xef, 0x00, 0x71, 0x4f,
724         0x81, 0x40, 0x81, 0x80, 0x95, 0x00, 0xb3, 0x00,
725         0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x00, 0x02, 0x3a,
726         0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
727         0x45, 0x00, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
728         0x00, 0x00, 0x00, 0xff, 0x00, 0x44, 0x34, 0x4c,
729         0x4d, 0x54, 0x46, 0x30, 0x37, 0x35, 0x39, 0x37,
730         0x36, 0x0a, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32,
731         0x4b, 0x18, 0x53, 0x11, 0x00, 0x0a, 0x20, 0x20,
732         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
733         0x00, 0x41, 0x53, 0x55, 0x53, 0x20, 0x56, 0x53,
734         0x32, 0x33, 0x38, 0x0a, 0x20, 0x20, 0x01, 0xb0,
735         0x02, 0x03, 0x22, 0x71, 0x4f, 0x01, 0x02, 0x03,
736         0x11, 0x12, 0x13, 0x04, 0x14, 0x05, 0x0e, 0x0f,
737         0x1d, 0x1e, 0x1f, 0x10, 0x23, 0x09, 0x17, 0x07,
738         0x83, 0x01, 0x00, 0x00, 0x65, 0x03, 0x0c, 0x00,
739         0x10, 0x00, 0x8c, 0x0a, 0xd0, 0x8a, 0x20, 0xe0,
740         0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xfd, 0x1e,
741         0x11, 0x00, 0x00, 0x18, 0x01, 0x1d, 0x00, 0x72,
742         0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
743         0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e, 0x01, 0x1d,
744         0x00, 0xbc, 0x52, 0xd0, 0x1e, 0x20, 0xb8, 0x28,
745         0x55, 0x40, 0xfd, 0x1e, 0x11, 0x00, 0x00, 0x1e,
746         0x8c, 0x0a, 0xd0, 0x90, 0x20, 0x40, 0x31, 0x20,
747         0x0c, 0x40, 0x55, 0x00, 0xfd, 0x1e, 0x11, 0x00,
748         0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9,
751 };
752
753 static int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
754 {
755         struct rk_hdmi_priv *priv = dev_get_priv(dev);
756         u32 edid_size = HDMI_EDID_BLOCK_SIZE;
757         int ret;
758
759         if (0) {
760                 edid_size = sizeof(pre_buf);
761                 memcpy(buf, pre_buf, edid_size);
762         } else {
763                 ret = hdmi_read_edid(priv->regs, 0, buf);
764                 if (ret) {
765                         debug("failed to read edid.\n");
766                         return -1;
767                 }
768
769                 if (buf[0x7e] != 0) {
770                         hdmi_read_edid(priv->regs, 1,
771                                        buf + HDMI_EDID_BLOCK_SIZE);
772                         edid_size += HDMI_EDID_BLOCK_SIZE;
773                 }
774         }
775
776         return edid_size;
777 }
778
779 static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
780                           const struct display_timing *edid)
781 {
782         struct rk_hdmi_priv *priv = dev_get_priv(dev);
783         struct rk3288_hdmi *regs = priv->regs;
784         int ret;
785
786         debug("hdmi, mode info : clock %d hdis %d vdis %d\n",
787               edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ);
788
789         hdmi_av_composer(regs, edid);
790
791         ret = hdmi_phy_init(regs, edid->pixelclock.typ);
792         if (ret)
793                 return ret;
794
795         hdmi_enable_video_path(regs);
796
797         hdmi_audio_fifo_reset(regs);
798         hdmi_audio_set_format(regs);
799         hdmi_audio_set_samplerate(regs, edid->pixelclock.typ);
800
801         hdmi_video_packetize(regs);
802         hdmi_video_sample(regs);
803
804         hdmi_clear_overflow(regs);
805
806         return 0;
807 }
808
809 static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
810 {
811         struct rk_hdmi_priv *priv = dev_get_priv(dev);
812
813         priv->regs = (struct rk3288_hdmi *)dev_get_addr(dev);
814         priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
815
816         return 0;
817 }
818
819 static int rk_hdmi_probe(struct udevice *dev)
820 {
821         struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
822         struct rk_hdmi_priv *priv = dev_get_priv(dev);
823         struct udevice *reg;
824         struct clk clk;
825         int ret;
826         int vop_id = uc_plat->source_id;
827
828         ret = clk_get_by_index(dev, 0, &clk);
829         if (ret >= 0) {
830                 ret = clk_set_rate(&clk, 0);
831                 clk_free(&clk);
832         }
833         if (ret) {
834                 debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret);
835                 return ret;
836         }
837
838         /*
839          * Configure the maximum clock to permit whatever resolution the
840          * monitor wants
841          */
842         ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
843         if (ret >= 0) {
844                 ret = clk_set_rate(&clk, 384000000);
845                 clk_free(&clk);
846         }
847         if (ret < 0) {
848                 debug("%s: Failed to set clock in source device '%s': ret=%d\n",
849                       __func__, uc_plat->src_dev->name, ret);
850                 return ret;
851         }
852
853         ret = regulator_get_by_platname("vcc50_hdmi", &reg);
854         if (!ret)
855                 ret = regulator_set_enable(reg, true);
856         if (ret)
857                 debug("%s: Cannot set regulator vcc50_hdmi\n", __func__);
858
859         /* hdmi source select hdmi controller */
860         rk_setreg(&priv->grf->soc_con6, 1 << 15);
861
862         /* hdmi data from vop id */
863         rk_clrsetreg(&priv->grf->soc_con6, 1 << 4,
864                      (vop_id == 1) ? (1 << 4) : 0);
865
866         ret = hdmi_wait_for_hpd(priv->regs);
867         if (ret < 0) {
868                 debug("hdmi can not get hpd signal\n");
869                 return -1;
870         }
871
872         hdmi_init_interrupt(priv->regs);
873
874         return 0;
875 }
876
877 static const struct dm_display_ops rk_hdmi_ops = {
878         .read_edid = rk_hdmi_read_edid,
879         .enable = rk_hdmi_enable,
880 };
881
882 static const struct udevice_id rk_hdmi_ids[] = {
883         { .compatible = "rockchip,rk3288-dw-hdmi" },
884         { }
885 };
886
887 U_BOOT_DRIVER(hdmi_rockchip) = {
888         .name   = "hdmi_rockchip",
889         .id     = UCLASS_DISPLAY,
890         .of_match = rk_hdmi_ids,
891         .ops    = &rk_hdmi_ops,
892         .ofdata_to_platdata     = rk_hdmi_ofdata_to_platdata,
893         .probe  = rk_hdmi_probe,
894         .priv_auto_alloc_size    = sizeof(struct rk_hdmi_priv),
895 };