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