2 * Copyright (c) 2015 Google, Inc
3 * Copyright 2014 Rockchip Inc.
5 * SPDX-License-Identifier: GPL-2.0+
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>
29 struct rk3288_hdmi *regs;
30 struct rk3288_grf *grf;
33 static const struct tmds_n_cts n_cts_table[] = {
35 .tmds = 25175000, .n = 6144, .cts = 25175,
37 .tmds = 25200000, .n = 6144, .cts = 25200,
39 .tmds = 27000000, .n = 6144, .cts = 27000,
41 .tmds = 27027000, .n = 6144, .cts = 27027,
43 .tmds = 40000000, .n = 6144, .cts = 40000,
45 .tmds = 54000000, .n = 6144, .cts = 54000,
47 .tmds = 54054000, .n = 6144, .cts = 54054,
49 .tmds = 65000000, .n = 6144, .cts = 65000,
51 .tmds = 74176000, .n = 11648, .cts = 140625,
53 .tmds = 74250000, .n = 6144, .cts = 74250,
55 .tmds = 83500000, .n = 6144, .cts = 83500,
57 .tmds = 106500000, .n = 6144, .cts = 106500,
59 .tmds = 108000000, .n = 6144, .cts = 108000,
61 .tmds = 148352000, .n = 5824, .cts = 140625,
63 .tmds = 148500000, .n = 6144, .cts = 148500,
65 .tmds = 297000000, .n = 5120, .cts = 247500,
69 struct hdmi_mpll_config {
71 /* Mode of Operation and PLL Dividers Control Register */
73 /* PLL Gmp Control Register */
75 /* PLL Current COntrol Register */
79 struct hdmi_phy_config {
81 u32 sym_ctr; /* clock symbol and transmitter control */
82 u32 term; /* transmission termination value */
83 u32 vlev_ctr; /* voltage level control */
86 static const struct hdmi_phy_config rockchip_phy_config[] = {
88 .mpixelclock = 74250000,
89 .sym_ctr = 0x8009, .term = 0x0004, .vlev_ctr = 0x0272,
91 .mpixelclock = 148500000,
92 .sym_ctr = 0x802b, .term = 0x0004, .vlev_ctr = 0x028d,
94 .mpixelclock = 297000000,
95 .sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
98 .sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
102 static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
104 .mpixelclock = 40000000,
105 .cpce = 0x00b3, .gmp = 0x0000, .curr = 0x0018,
107 .mpixelclock = 65000000,
108 .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
110 .mpixelclock = 66000000,
111 .cpce = 0x013e, .gmp = 0x0003, .curr = 0x0038,
113 .mpixelclock = 83500000,
114 .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
116 .mpixelclock = 146250000,
117 .cpce = 0x0051, .gmp = 0x0002, .curr = 0x0038,
119 .mpixelclock = 148500000,
120 .cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
123 .cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
127 static void hdmi_set_clock_regenerator(struct rk3288_hdmi *regs, u32 n, u32 cts)
132 /* first set ncts_atomic_write (if present) */
133 n3 = HDMI_AUD_N3_NCTS_ATOMIC_WRITE;
134 writel(n3, ®s->aud_n3);
136 /* set cts_manual (if present) */
137 cts3 = HDMI_AUD_CTS3_CTS_MANUAL;
139 cts3 |= HDMI_AUD_CTS3_N_SHIFT_1 << HDMI_AUD_CTS3_N_SHIFT_OFFSET;
140 cts3 |= (cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK;
142 /* write cts values; cts3 must be written first */
143 writel(cts3, ®s->aud_cts3);
144 writel((cts >> 8) & 0xff, ®s->aud_cts2);
145 writel(cts & 0xff, ®s->aud_cts1);
147 /* write n values; n1 must be written last */
148 n3 |= (n >> 16) & HDMI_AUD_N3_AUDN19_16_MASK;
149 writel(n3, ®s->aud_n3);
150 writel((n >> 8) & 0xff, ®s->aud_n2);
151 writel(n & 0xff, ®s->aud_n1);
153 writel(HDMI_AUD_INPUTCLKFS_128, ®s->aud_inputclkfs);
156 static int hdmi_lookup_n_cts(u32 pixel_clk)
160 for (i = 0; i < ARRAY_SIZE(n_cts_table); i++)
161 if (pixel_clk <= n_cts_table[i].tmds)
164 if (i >= ARRAY_SIZE(n_cts_table))
170 static void hdmi_audio_set_samplerate(struct rk3288_hdmi *regs, u32 pixel_clk)
175 index = hdmi_lookup_n_cts(pixel_clk);
177 debug("audio not supported for pixel clk %d\n", pixel_clk);
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);
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]
193 static void hdmi_video_sample(struct rk3288_hdmi *regs)
195 u32 color_format = 0x01;
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);
202 writel(val, ®s->tx_invid0);
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, ®s->tx_instuffing);
209 writel(0x0, ®s->tx_gydata0);
210 writel(0x0, ®s->tx_gydata1);
211 writel(0x0, ®s->tx_rcrdata0);
212 writel(0x0, ®s->tx_rcrdata1);
213 writel(0x0, ®s->tx_bcbdata0);
214 writel(0x0, ®s->tx_bcbdata1);
217 static void hdmi_video_packetize(struct rk3288_hdmi *regs)
219 u32 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
220 u32 remap_size = HDMI_VP_REMAP_YCC422_16BIT;
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, ®s->vp_pr_cd);
231 clrsetbits_le32(®s->vp_stuff, HDMI_VP_STUFF_PR_STUFFING_MASK,
232 HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE);
234 /* data from pixel repeater block */
235 vp_conf = HDMI_VP_CONF_PR_EN_DISABLE |
236 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
238 clrsetbits_le32(®s->vp_conf, HDMI_VP_CONF_PR_EN_MASK |
239 HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf);
241 clrsetbits_le32(®s->vp_stuff, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
242 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET);
244 writel(remap_size, ®s->vp_remap);
246 vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE |
247 HDMI_VP_CONF_PP_EN_DISABLE |
248 HDMI_VP_CONF_YCC422_EN_DISABLE;
250 clrsetbits_le32(®s->vp_conf, HDMI_VP_CONF_BYPASS_EN_MASK |
251 HDMI_VP_CONF_PP_EN_ENMASK | HDMI_VP_CONF_YCC422_EN_MASK,
254 clrsetbits_le32(®s->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);
259 clrsetbits_le32(®s->vp_conf, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK,
263 static inline void hdmi_phy_test_clear(struct rk3288_hdmi *regs, uint bit)
265 clrsetbits_le32(®s->phy_tst0, HDMI_PHY_TST0_TSTCLR_MASK,
266 bit << HDMI_PHY_TST0_TSTCLR_OFFSET);
269 static int hdmi_phy_wait_i2c_done(struct rk3288_hdmi *regs, u32 msec)
274 start = get_timer(0);
276 val = readl(®s->ih_i2cmphy_stat0);
278 writel(val, ®s->ih_i2cmphy_stat0);
283 } while (get_timer(start) < msec);
288 static void hdmi_phy_i2c_write(struct rk3288_hdmi *regs, uint data, uint addr)
290 writel(0xff, ®s->ih_i2cmphy_stat0);
291 writel(addr, ®s->phy_i2cm_address_addr);
292 writel((u8)(data >> 8), ®s->phy_i2cm_datao_1_addr);
293 writel((u8)(data >> 0), ®s->phy_i2cm_datao_0_addr);
294 writel(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
295 ®s->phy_i2cm_operation_addr);
297 hdmi_phy_wait_i2c_done(regs, 1000);
300 static void hdmi_phy_enable_power(struct rk3288_hdmi *regs, uint enable)
302 clrsetbits_le32(®s->phy_conf0, HDMI_PHY_CONF0_PDZ_MASK,
303 enable << HDMI_PHY_CONF0_PDZ_OFFSET);
306 static void hdmi_phy_enable_tmds(struct rk3288_hdmi *regs, uint enable)
308 clrsetbits_le32(®s->phy_conf0, HDMI_PHY_CONF0_ENTMDS_MASK,
309 enable << HDMI_PHY_CONF0_ENTMDS_OFFSET);
312 static void hdmi_phy_enable_spare(struct rk3288_hdmi *regs, uint enable)
314 clrsetbits_le32(®s->phy_conf0, HDMI_PHY_CONF0_SPARECTRL_MASK,
315 enable << HDMI_PHY_CONF0_SPARECTRL_OFFSET);
318 static void hdmi_phy_gen2_pddq(struct rk3288_hdmi *regs, uint enable)
320 clrsetbits_le32(®s->phy_conf0, HDMI_PHY_CONF0_GEN2_PDDQ_MASK,
321 enable << HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET);
324 static void hdmi_phy_gen2_txpwron(struct rk3288_hdmi *regs, uint enable)
326 clrsetbits_le32(®s->phy_conf0,
327 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK,
328 enable << HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET);
331 static void hdmi_phy_sel_data_en_pol(struct rk3288_hdmi *regs, uint enable)
333 clrsetbits_le32(®s->phy_conf0,
334 HDMI_PHY_CONF0_SELDATAENPOL_MASK,
335 enable << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET);
338 static void hdmi_phy_sel_interface_control(struct rk3288_hdmi *regs,
341 clrsetbits_le32(®s->phy_conf0, HDMI_PHY_CONF0_SELDIPIF_MASK,
342 enable << HDMI_PHY_CONF0_SELDIPIF_OFFSET);
345 static int hdmi_phy_configure(struct rk3288_hdmi *regs, u32 mpixelclock)
350 writel(HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS,
353 /* gen2 tx power off */
354 hdmi_phy_gen2_txpwron(regs, 0);
357 hdmi_phy_gen2_pddq(regs, 1);
360 writel(HDMI_MC_PHYRSTZ_DEASSERT, ®s->mc_phyrstz);
361 writel(HDMI_MC_PHYRSTZ_ASSERT, ®s->mc_phyrstz);
362 writel(HDMI_MC_HEACPHY_RST_ASSERT, ®s->mc_heacphy_rst);
364 hdmi_phy_test_clear(regs, 1);
365 writel(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, ®s->phy_i2cm_slave_addr);
366 hdmi_phy_test_clear(regs, 0);
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)
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);
377 hdmi_phy_i2c_write(regs, 0x0000, PHY_PLLPHBYCTRL);
378 hdmi_phy_i2c_write(regs, 0x0006, PHY_PLLCLKBISTPHASE);
380 for (i = 0; rockchip_phy_config[i].mpixelclock != (~0ul); i++)
381 if (mpixelclock <= rockchip_phy_config[i].mpixelclock)
385 * resistance term 133ohm cfg
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,
392 hdmi_phy_i2c_write(regs, rockchip_phy_config[i].vlev_ctr, PHY_VLEVCTRL);
394 /* remove clk term */
395 hdmi_phy_i2c_write(regs, 0x8000, PHY_CKCALCTRL);
397 hdmi_phy_enable_power(regs, 1);
399 /* toggle tmds enable */
400 hdmi_phy_enable_tmds(regs, 0);
401 hdmi_phy_enable_tmds(regs, 1);
403 /* gen2 tx power on */
404 hdmi_phy_gen2_txpwron(regs, 1);
405 hdmi_phy_gen2_pddq(regs, 0);
407 hdmi_phy_enable_spare(regs, 1);
409 /* wait for phy pll lock */
410 start = get_timer(0);
412 val = readl(®s->phy_stat0);
413 if (!(val & HDMI_PHY_TX_PHY_LOCK))
417 } while (get_timer(start) < 5);
422 static int hdmi_phy_init(struct rk3288_hdmi *regs, uint mpixelclock)
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);
433 ret = hdmi_phy_configure(regs, mpixelclock);
435 debug("hdmi phy config failure %d\n", ret);
443 static void hdmi_av_composer(struct rk3288_hdmi *regs,
444 const struct display_timing *edid)
446 bool mdataenablepolarity = true;
451 hbl = edid->hback_porch.typ + edid->hfront_porch.typ +
453 vbl = edid->vback_porch.typ + edid->vfront_porch.typ +
456 /* set up hdmi_fc_invidconf */
457 inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE;
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);
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);
467 inv_val |= (mdataenablepolarity ?
468 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
469 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
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);
477 inv_val |= HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE;
479 inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW;
481 inv_val |= HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE;
483 writel(inv_val, ®s->fc_invidconf);
485 /* set up horizontal active pixel width */
486 writel(edid->hactive.typ >> 8, ®s->fc_inhactv1);
487 writel(edid->hactive.typ, ®s->fc_inhactv0);
489 /* set up vertical active lines */
490 writel(edid->vactive.typ >> 8, ®s->fc_invactv1);
491 writel(edid->vactive.typ, ®s->fc_invactv0);
493 /* set up horizontal blanking pixel region width */
494 writel(hbl >> 8, ®s->fc_inhblank1);
495 writel(hbl, ®s->fc_inhblank0);
497 /* set up vertical blanking pixel region width */
498 writel(vbl, ®s->fc_invblank);
500 /* set up hsync active edge delay width (in pixel clks) */
501 writel(edid->hfront_porch.typ >> 8, ®s->fc_hsyncindelay1);
502 writel(edid->hfront_porch.typ, ®s->fc_hsyncindelay0);
504 /* set up vsync active edge delay (in lines) */
505 writel(edid->vfront_porch.typ, ®s->fc_vsyncindelay);
507 /* set up hsync active pulse width (in pixel clks) */
508 writel(edid->hsync_len.typ >> 8, ®s->fc_hsyncinwidth1);
509 writel(edid->hsync_len.typ, ®s->fc_hsyncinwidth0);
511 /* set up vsync active edge delay (in lines) */
512 writel(edid->vsync_len.typ, ®s->fc_vsyncinwidth);
515 /* hdmi initialization step b.4 */
516 static void hdmi_enable_video_path(struct rk3288_hdmi *regs)
520 /* control period minimum duration */
521 writel(12, ®s->fc_ctrldur);
522 writel(32, ®s->fc_exctrldur);
523 writel(1, ®s->fc_exctrlspac);
525 /* set to fill tmds data channels */
526 writel(0x0b, ®s->fc_ch0pream);
527 writel(0x16, ®s->fc_ch1pream);
528 writel(0x21, ®s->fc_ch2pream);
530 /* enable pixel clock and tmds data path */
532 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
533 writel(clkdis, ®s->mc_clkdis);
535 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
536 writel(clkdis, ®s->mc_clkdis);
538 clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
539 writel(clkdis, ®s->mc_clkdis);
542 /* workaround to clear the overflow condition */
543 static void hdmi_clear_overflow(struct rk3288_hdmi *regs)
547 /* tmds software reset */
548 writel((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, ®s->mc_swrstz);
550 val = readl(®s->fc_invidconf);
552 for (count = 0; count < 4; count++)
553 writel(val, ®s->fc_invidconf);
556 static void hdmi_audio_set_format(struct rk3288_hdmi *regs)
558 writel(HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_IN_EN_0,
562 writel(HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE |
563 HDMI_AUD_CONF1_I2S_WIDTH_16BIT, ®s->aud_conf1);
565 writel(0x00, ®s->aud_conf2);
568 static void hdmi_audio_fifo_reset(struct rk3288_hdmi *regs)
570 writel((u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, ®s->mc_swrstz);
571 writel(HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, ®s->aud_conf0);
573 writel(0x00, ®s->aud_int);
574 writel(0x00, ®s->aud_int1);
577 static void hdmi_init_interrupt(struct rk3288_hdmi *regs)
582 * boot up defaults are:
583 * hdmi_ih_mute = 0x03 (disabled)
584 * hdmi_ih_mute_* = 0x00 (enabled)
586 * disable top level interrupt bits in hdmi block
588 ih_mute = readl(®s->ih_mute) |
589 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
590 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
592 writel(ih_mute, ®s->ih_mute);
594 /* enable i2c master done irq */
595 writel(~0x04, ®s->i2cm_int);
597 /* enable i2c client nack % arbitration error irq */
598 writel(~0x44, ®s->i2cm_ctlint);
600 /* enable phy i2cm done irq */
601 writel(HDMI_PHY_I2CM_INT_ADDR_DONE_POL, ®s->phy_i2cm_int_addr);
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 ®s->phy_i2cm_ctlint_addr);
608 /* enable cable hot plug irq */
609 writel((u8)~HDMI_PHY_HPD, ®s->phy_mask0);
611 /* clear hotplug interrupts */
612 writel(HDMI_IH_PHY_STAT0_HPD, ®s->ih_phy_stat0);
615 static int hdmi_get_plug_in_status(struct rk3288_hdmi *regs)
617 uint val = readl(®s->phy_stat0) & HDMI_PHY_HPD;
622 static int hdmi_wait_for_hpd(struct rk3288_hdmi *regs)
626 start = get_timer(0);
628 if (hdmi_get_plug_in_status(regs))
631 } while (get_timer(start) < 300);
636 static int hdmi_ddc_wait_i2c_done(struct rk3288_hdmi *regs, int msec)
641 start = get_timer(0);
643 val = readl(®s->ih_i2cm_stat0);
645 writel(val, ®s->ih_i2cm_stat0);
650 } while (get_timer(start) < msec);
655 static void hdmi_ddc_reset(struct rk3288_hdmi *regs)
657 clrbits_le32(®s->i2cm_softrstz, HDMI_I2CM_SOFTRSTZ);
660 static int hdmi_read_edid(struct rk3288_hdmi *regs, int block, u8 *buff)
662 int shift = (block % 2) * 0x80;
663 int edid_read_err = 0;
667 /* set ddc i2c clk which devided from ddc_clk to 100khz */
668 writel(0x7a, ®s->i2cm_ss_scl_hcnt_0_addr);
669 writel(0x8d, ®s->i2cm_ss_scl_lcnt_0_addr);
672 * TODO(sjg@chromium.org): The above values don't work - these ones
673 * work better, but generate lots of errors in the data.
675 writel(0x0d, ®s->i2cm_ss_scl_hcnt_0_addr);
676 writel(0x0d, ®s->i2cm_ss_scl_lcnt_0_addr);
677 clrsetbits_le32(®s->i2cm_div, HDMI_I2CM_DIV_FAST_STD_MODE,
678 HDMI_I2CM_DIV_STD_MODE);
680 writel(HDMI_I2CM_SLAVE_DDC_ADDR, ®s->i2cm_slave);
681 writel(HDMI_I2CM_SEGADDR_DDC, ®s->i2cm_segaddr);
682 writel(block >> 1, ®s->i2cm_segptr);
687 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
688 writel(shift + 8 * n, ®s->i2c_address);
691 clrsetbits_le32(®s->i2cm_operation,
695 clrsetbits_le32(®s->i2cm_operation,
696 HDMI_I2CM_OPT_RD8_EXT,
697 HDMI_I2CM_OPT_RD8_EXT);
699 if (hdmi_ddc_wait_i2c_done(regs, 10)) {
700 hdmi_ddc_reset(regs);
705 for (j = 0; j < 8; j++) {
706 val = readl(®s->i2cm_buf0 + j);
707 buff[8 * n + j] = val;
715 return edid_read_err;
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,
753 static int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
755 struct rk_hdmi_priv *priv = dev_get_priv(dev);
756 u32 edid_size = HDMI_EDID_BLOCK_SIZE;
760 edid_size = sizeof(pre_buf);
761 memcpy(buf, pre_buf, edid_size);
763 ret = hdmi_read_edid(priv->regs, 0, buf);
765 debug("failed to read edid.\n");
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;
779 static int rk_hdmi_enable(struct udevice *dev, int panel_bpp,
780 const struct display_timing *edid)
782 struct rk_hdmi_priv *priv = dev_get_priv(dev);
783 struct rk3288_hdmi *regs = priv->regs;
786 debug("hdmi, mode info : clock %d hdis %d vdis %d\n",
787 edid->pixelclock.typ, edid->hactive.typ, edid->vactive.typ);
789 hdmi_av_composer(regs, edid);
791 ret = hdmi_phy_init(regs, edid->pixelclock.typ);
795 hdmi_enable_video_path(regs);
797 hdmi_audio_fifo_reset(regs);
798 hdmi_audio_set_format(regs);
799 hdmi_audio_set_samplerate(regs, edid->pixelclock.typ);
801 hdmi_video_packetize(regs);
802 hdmi_video_sample(regs);
804 hdmi_clear_overflow(regs);
809 static int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
811 struct rk_hdmi_priv *priv = dev_get_priv(dev);
813 priv->regs = (struct rk3288_hdmi *)dev_get_addr(dev);
814 priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
819 static int rk_hdmi_probe(struct udevice *dev)
821 struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
822 struct rk_hdmi_priv *priv = dev_get_priv(dev);
826 int vop_id = uc_plat->source_id;
828 ret = clk_get_by_index(dev, 0, &clk);
830 ret = clk_set_rate(&clk, 0);
834 debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret);
839 * Configure the maximum clock to permit whatever resolution the
842 ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
844 ret = clk_set_rate(&clk, 384000000);
848 debug("%s: Failed to set clock in source device '%s': ret=%d\n",
849 __func__, uc_plat->src_dev->name, ret);
853 ret = regulator_get_by_platname("vcc50_hdmi", ®);
855 ret = regulator_set_enable(reg, true);
857 debug("%s: Cannot set regulator vcc50_hdmi\n", __func__);
859 /* hdmi source select hdmi controller */
860 rk_setreg(&priv->grf->soc_con6, 1 << 15);
862 /* hdmi data from vop id */
863 rk_clrsetreg(&priv->grf->soc_con6, 1 << 4,
864 (vop_id == 1) ? (1 << 4) : 0);
866 ret = hdmi_wait_for_hpd(priv->regs);
868 debug("hdmi can not get hpd signal\n");
872 hdmi_init_interrupt(priv->regs);
877 static const struct dm_display_ops rk_hdmi_ops = {
878 .read_edid = rk_hdmi_read_edid,
879 .enable = rk_hdmi_enable,
882 static const struct udevice_id rk_hdmi_ids[] = {
883 { .compatible = "rockchip,rk3288-dw-hdmi" },
887 U_BOOT_DRIVER(hdmi_rockchip) = {
888 .name = "hdmi_rockchip",
889 .id = UCLASS_DISPLAY,
890 .of_match = rk_hdmi_ids,
892 .ofdata_to_platdata = rk_hdmi_ofdata_to_platdata,
893 .probe = rk_hdmi_probe,
894 .priv_auto_alloc_size = sizeof(struct rk_hdmi_priv),