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, ®s->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, ®s->aud_cts3); 144 writel((cts >> 8) & 0xff, ®s->aud_cts2); 145 writel(cts & 0xff, ®s->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, ®s->aud_n3); 150 writel((n >> 8) & 0xff, ®s->aud_n2); 151 writel(n & 0xff, ®s->aud_n1); 152 153 writel(HDMI_AUD_INPUTCLKFS_128, ®s->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, ®s->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, ®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); 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, ®s->vp_pr_cd); 230 231 clrsetbits_le32(®s->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(®s->vp_conf, HDMI_VP_CONF_PR_EN_MASK | 239 HDMI_VP_CONF_BYPASS_SELECT_MASK, vp_conf); 240 241 clrsetbits_le32(®s->vp_stuff, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, 242 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET); 243 244 writel(remap_size, ®s->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(®s->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(®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); 258 259 clrsetbits_le32(®s->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(®s->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(®s->ih_i2cmphy_stat0); 277 if (val & 0x3) { 278 writel(val, ®s->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, ®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); 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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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(®s->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 ®s->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, ®s->mc_phyrstz); 361 writel(HDMI_MC_PHYRSTZ_ASSERT, ®s->mc_phyrstz); 362 writel(HDMI_MC_HEACPHY_RST_ASSERT, ®s->mc_heacphy_rst); 363 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); 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(®s->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, ®s->fc_invidconf); 484 485 /* set up horizontal active pixel width */ 486 writel(edid->hactive.typ >> 8, ®s->fc_inhactv1); 487 writel(edid->hactive.typ, ®s->fc_inhactv0); 488 489 /* set up vertical active lines */ 490 writel(edid->vactive.typ >> 8, ®s->fc_invactv1); 491 writel(edid->vactive.typ, ®s->fc_invactv0); 492 493 /* set up horizontal blanking pixel region width */ 494 writel(hbl >> 8, ®s->fc_inhblank1); 495 writel(hbl, ®s->fc_inhblank0); 496 497 /* set up vertical blanking pixel region width */ 498 writel(vbl, ®s->fc_invblank); 499 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); 503 504 /* set up vsync active edge delay (in lines) */ 505 writel(edid->vfront_porch.typ, ®s->fc_vsyncindelay); 506 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); 510 511 /* set up vsync active edge delay (in lines) */ 512 writel(edid->vsync_len.typ, ®s->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, ®s->fc_ctrldur); 522 writel(32, ®s->fc_exctrldur); 523 writel(1, ®s->fc_exctrlspac); 524 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); 529 530 /* enable pixel clock and tmds data path */ 531 clkdis = 0x7f; 532 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; 533 writel(clkdis, ®s->mc_clkdis); 534 535 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; 536 writel(clkdis, ®s->mc_clkdis); 537 538 clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE; 539 writel(clkdis, ®s->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, ®s->mc_swrstz); 549 550 val = readl(®s->fc_invidconf); 551 552 for (count = 0; count < 4; count++) 553 writel(val, ®s->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 ®s->aud_conf0); 560 561 562 writel(HDMI_AUD_CONF1_I2S_MODE_STANDARD_MODE | 563 HDMI_AUD_CONF1_I2S_WIDTH_16BIT, ®s->aud_conf1); 564 565 writel(0x00, ®s->aud_conf2); 566 } 567 568 static void hdmi_audio_fifo_reset(struct rk3288_hdmi *regs) 569 { 570 writel((u8)~HDMI_MC_SWRSTZ_II2SSWRST_REQ, ®s->mc_swrstz); 571 writel(HDMI_AUD_CONF0_SW_AUDIO_FIFO_RST, ®s->aud_conf0); 572 573 writel(0x00, ®s->aud_int); 574 writel(0x00, ®s->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(®s->ih_mute) | 589 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | 590 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; 591 592 writel(ih_mute, ®s->ih_mute); 593 594 /* enable i2c master done irq */ 595 writel(~0x04, ®s->i2cm_int); 596 597 /* enable i2c client nack % arbitration error irq */ 598 writel(~0x44, ®s->i2cm_ctlint); 599 600 /* enable phy i2cm done irq */ 601 writel(HDMI_PHY_I2CM_INT_ADDR_DONE_POL, ®s->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 ®s->phy_i2cm_ctlint_addr); 607 608 /* enable cable hot plug irq */ 609 writel((u8)~HDMI_PHY_HPD, ®s->phy_mask0); 610 611 /* clear hotplug interrupts */ 612 writel(HDMI_IH_PHY_STAT0_HPD, ®s->ih_phy_stat0); 613 } 614 615 static int hdmi_get_plug_in_status(struct rk3288_hdmi *regs) 616 { 617 uint val = readl(®s->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(®s->ih_i2cm_stat0); 644 if (val & 0x2) { 645 writel(val, ®s->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(®s->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, ®s->i2cm_ss_scl_hcnt_0_addr); 669 writel(0x8d, ®s->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, ®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); 679 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); 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, ®s->i2c_address); 689 690 if (block == 0) 691 clrsetbits_le32(®s->i2cm_operation, 692 HDMI_I2CM_OPT_RD8, 693 HDMI_I2CM_OPT_RD8); 694 else 695 clrsetbits_le32(®s->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(®s->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", ®); 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 }; 896