1 /* 2 * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <fdtdec.h> 9 #include <fdt_support.h> 10 #include <malloc.h> 11 #include <syscon.h> 12 #include <asm/arch-rockchip/clock.h> 13 #include <edid.h> 14 #include <linux/hdmi.h> 15 #include <linux/media-bus-format.h> 16 #include <linux/dw_hdmi.h> 17 #include <asm/io.h> 18 #include "rockchip_display.h" 19 #include "rockchip_crtc.h" 20 #include "rockchip_connector.h" 21 #include "dw_hdmi.h" 22 23 /* 24 * Unless otherwise noted, entries in this table are 100% optimization. 25 * Values can be obtained from hdmi_compute_n() but that function is 26 * slow so we pre-compute values we expect to see. 27 * 28 * All 32k and 48k values are expected to be the same (due to the way 29 * the math works) for any rate that's an exact kHz. 30 */ 31 static const struct dw_hdmi_audio_tmds_n common_tmds_n_table[] = { 32 { .tmds = 25175000, .n_32k = 4096, .n_44k1 = 12854, .n_48k = 6144, }, 33 { .tmds = 25200000, .n_32k = 4096, .n_44k1 = 5656, .n_48k = 6144, }, 34 { .tmds = 27000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, 35 { .tmds = 28320000, .n_32k = 4096, .n_44k1 = 5586, .n_48k = 6144, }, 36 { .tmds = 30240000, .n_32k = 4096, .n_44k1 = 5642, .n_48k = 6144, }, 37 { .tmds = 31500000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, }, 38 { .tmds = 32000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, }, 39 { .tmds = 33750000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, 40 { .tmds = 36000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, }, 41 { .tmds = 40000000, .n_32k = 4096, .n_44k1 = 5733, .n_48k = 6144, }, 42 { .tmds = 49500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, 43 { .tmds = 50000000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, }, 44 { .tmds = 54000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, }, 45 { .tmds = 65000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, }, 46 { .tmds = 68250000, .n_32k = 4096, .n_44k1 = 5376, .n_48k = 6144, }, 47 { .tmds = 71000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, }, 48 { .tmds = 72000000, .n_32k = 4096, .n_44k1 = 5635, .n_48k = 6144, }, 49 { .tmds = 73250000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, }, 50 { .tmds = 74250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, 51 { .tmds = 75000000, .n_32k = 4096, .n_44k1 = 5880, .n_48k = 6144, }, 52 { .tmds = 78750000, .n_32k = 4096, .n_44k1 = 5600, .n_48k = 6144, }, 53 { .tmds = 78800000, .n_32k = 4096, .n_44k1 = 5292, .n_48k = 6144, }, 54 { .tmds = 79500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, }, 55 { .tmds = 83500000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, }, 56 { .tmds = 85500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, 57 { .tmds = 88750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, }, 58 { .tmds = 97750000, .n_32k = 4096, .n_44k1 = 14112, .n_48k = 6144, }, 59 { .tmds = 101000000, .n_32k = 4096, .n_44k1 = 7056, .n_48k = 6144, }, 60 { .tmds = 106500000, .n_32k = 4096, .n_44k1 = 4704, .n_48k = 6144, }, 61 { .tmds = 108000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, }, 62 { .tmds = 115500000, .n_32k = 4096, .n_44k1 = 5712, .n_48k = 6144, }, 63 { .tmds = 119000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, }, 64 { .tmds = 135000000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, 65 { .tmds = 146250000, .n_32k = 4096, .n_44k1 = 6272, .n_48k = 6144, }, 66 { .tmds = 148500000, .n_32k = 4096, .n_44k1 = 5488, .n_48k = 6144, }, 67 { .tmds = 154000000, .n_32k = 4096, .n_44k1 = 5544, .n_48k = 6144, }, 68 { .tmds = 162000000, .n_32k = 4096, .n_44k1 = 5684, .n_48k = 6144, }, 69 70 /* For 297 MHz+ HDMI spec have some other rule for setting N */ 71 { .tmds = 297000000, .n_32k = 3073, .n_44k1 = 4704, .n_48k = 5120, }, 72 { .tmds = 594000000, .n_32k = 3073, .n_44k1 = 9408, .n_48k = 10240, }, 73 74 /* End of table */ 75 { .tmds = 0, .n_32k = 0, .n_44k1 = 0, .n_48k = 0, }, 76 }; 77 78 static const u16 csc_coeff_default[3][4] = { 79 { 0x2000, 0x0000, 0x0000, 0x0000 }, 80 { 0x0000, 0x2000, 0x0000, 0x0000 }, 81 { 0x0000, 0x0000, 0x2000, 0x0000 } 82 }; 83 84 static const u16 csc_coeff_rgb_out_eitu601[3][4] = { 85 { 0x2000, 0x6926, 0x74fd, 0x010e }, 86 { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, 87 { 0x2000, 0x0000, 0x38b4, 0x7e3b } 88 }; 89 90 static const u16 csc_coeff_rgb_out_eitu709[3][4] = { 91 { 0x2000, 0x7106, 0x7a02, 0x00a7 }, 92 { 0x2000, 0x3264, 0x0000, 0x7e6d }, 93 { 0x2000, 0x0000, 0x3b61, 0x7e25 } 94 }; 95 96 static const u16 csc_coeff_rgb_in_eitu601[3][4] = { 97 { 0x2591, 0x1322, 0x074b, 0x0000 }, 98 { 0x6535, 0x2000, 0x7acc, 0x0200 }, 99 { 0x6acd, 0x7534, 0x2000, 0x0200 } 100 }; 101 102 static const u16 csc_coeff_rgb_in_eitu709[3][4] = { 103 { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, 104 { 0x62f0, 0x2000, 0x7d11, 0x0200 }, 105 { 0x6756, 0x78ab, 0x2000, 0x0200 } 106 }; 107 108 struct hdmi_vmode { 109 bool mdataenablepolarity; 110 111 unsigned int mpixelclock; 112 unsigned int mpixelrepetitioninput; 113 unsigned int mpixelrepetitionoutput; 114 }; 115 116 struct hdmi_data_info { 117 unsigned int enc_in_bus_format; 118 unsigned int enc_out_bus_format; 119 unsigned int enc_in_encoding; 120 unsigned int enc_out_encoding; 121 unsigned int pix_repet_factor; 122 struct hdmi_vmode video_mode; 123 }; 124 125 struct dw_hdmi_phy_data { 126 enum dw_hdmi_phy_type type; 127 const char *name; 128 unsigned int gen; 129 bool has_svsret; 130 int (*configure)(struct dw_hdmi *hdmi, 131 const struct dw_hdmi_plat_data *pdata, 132 unsigned long mpixelclock); 133 }; 134 135 struct dw_hdmi { 136 enum dw_hdmi_devtype dev_type; 137 unsigned int version; 138 struct hdmi_data_info hdmi_data; 139 struct hdmi_edid_data edid_data; 140 const struct dw_hdmi_plat_data *plat_data; 141 142 int vic; 143 int io_width; 144 145 unsigned long bus_format; 146 bool cable_plugin; 147 bool sink_is_hdmi; 148 bool sink_has_audio; 149 void *regs; 150 void *grf; 151 152 struct { 153 const struct dw_hdmi_phy_ops *ops; 154 const char *name; 155 void *data; 156 bool enabled; 157 } phy; 158 159 struct drm_display_mode previous_mode; 160 161 unsigned int sample_rate; 162 unsigned int audio_cts; 163 unsigned int audio_n; 164 bool audio_enable; 165 166 void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); 167 u8 (*read)(struct dw_hdmi *hdmi, int offset); 168 }; 169 170 static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset) 171 { 172 writel(val, hdmi->regs + (offset << 2)); 173 } 174 175 static u8 dw_hdmi_readl(struct dw_hdmi *hdmi, int offset) 176 { 177 return readl(hdmi->regs + (offset << 2)); 178 } 179 180 static void dw_hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) 181 { 182 writeb(val, hdmi->regs + offset); 183 } 184 185 static u8 dw_hdmi_readb(struct dw_hdmi *hdmi, int offset) 186 { 187 return readb(hdmi->regs + offset); 188 } 189 190 static inline void hdmi_writeb(struct dw_hdmi *hdmi, u8 val, int offset) 191 { 192 hdmi->write(hdmi, val, offset); 193 } 194 195 static inline u8 hdmi_readb(struct dw_hdmi *hdmi, int offset) 196 { 197 return hdmi->read(hdmi, offset); 198 } 199 200 static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg) 201 { 202 u8 val = hdmi_readb(hdmi, reg) & ~mask; 203 204 val |= data & mask; 205 hdmi_writeb(hdmi, val, reg); 206 } 207 208 static void hdmi_mask_writeb(struct dw_hdmi *hdmi, u8 data, unsigned int reg, 209 u8 shift, u8 mask) 210 { 211 hdmi_modb(hdmi, data << shift, mask, reg); 212 } 213 214 static bool hdmi_bus_fmt_is_rgb(unsigned int bus_format) 215 { 216 switch (bus_format) { 217 case MEDIA_BUS_FMT_RGB888_1X24: 218 case MEDIA_BUS_FMT_RGB101010_1X30: 219 case MEDIA_BUS_FMT_RGB121212_1X36: 220 case MEDIA_BUS_FMT_RGB161616_1X48: 221 return true; 222 223 default: 224 return false; 225 } 226 } 227 228 static bool hdmi_bus_fmt_is_yuv444(unsigned int bus_format) 229 { 230 switch (bus_format) { 231 case MEDIA_BUS_FMT_YUV8_1X24: 232 case MEDIA_BUS_FMT_YUV10_1X30: 233 case MEDIA_BUS_FMT_YUV12_1X36: 234 case MEDIA_BUS_FMT_YUV16_1X48: 235 return true; 236 237 default: 238 return false; 239 } 240 } 241 242 static bool hdmi_bus_fmt_is_yuv422(unsigned int bus_format) 243 { 244 switch (bus_format) { 245 case MEDIA_BUS_FMT_UYVY8_1X16: 246 case MEDIA_BUS_FMT_UYVY10_1X20: 247 case MEDIA_BUS_FMT_UYVY12_1X24: 248 return true; 249 250 default: 251 return false; 252 } 253 } 254 255 static bool hdmi_bus_fmt_is_yuv420(unsigned int bus_format) 256 { 257 switch (bus_format) { 258 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 259 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 260 case MEDIA_BUS_FMT_UYYVYY12_0_5X36: 261 case MEDIA_BUS_FMT_UYYVYY16_0_5X48: 262 return true; 263 264 default: 265 return false; 266 } 267 } 268 269 static int hdmi_bus_fmt_color_depth(unsigned int bus_format) 270 { 271 switch (bus_format) { 272 case MEDIA_BUS_FMT_RGB888_1X24: 273 case MEDIA_BUS_FMT_YUV8_1X24: 274 case MEDIA_BUS_FMT_UYVY8_1X16: 275 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 276 return 8; 277 278 case MEDIA_BUS_FMT_RGB101010_1X30: 279 case MEDIA_BUS_FMT_YUV10_1X30: 280 case MEDIA_BUS_FMT_UYVY10_1X20: 281 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 282 return 10; 283 284 case MEDIA_BUS_FMT_RGB121212_1X36: 285 case MEDIA_BUS_FMT_YUV12_1X36: 286 case MEDIA_BUS_FMT_UYVY12_1X24: 287 case MEDIA_BUS_FMT_UYYVYY12_0_5X36: 288 return 12; 289 290 case MEDIA_BUS_FMT_RGB161616_1X48: 291 case MEDIA_BUS_FMT_YUV16_1X48: 292 case MEDIA_BUS_FMT_UYYVYY16_0_5X48: 293 return 16; 294 295 default: 296 return 0; 297 } 298 } 299 300 static int is_color_space_conversion(struct dw_hdmi *hdmi) 301 { 302 return hdmi->hdmi_data.enc_in_bus_format != 303 hdmi->hdmi_data.enc_out_bus_format; 304 } 305 306 static int is_color_space_decimation(struct dw_hdmi *hdmi) 307 { 308 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) 309 return 0; 310 311 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) || 312 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_in_bus_format)) 313 return 1; 314 315 return 0; 316 } 317 318 static inline void hdmi_phy_test_clear(struct dw_hdmi *hdmi, 319 unsigned char bit) 320 { 321 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, 322 HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); 323 } 324 325 static inline void hdmi_phy_test_enable(struct dw_hdmi *hdmi, 326 unsigned char bit) 327 { 328 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET, 329 HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0); 330 } 331 332 static inline void hdmi_phy_test_clock(struct dw_hdmi *hdmi, 333 unsigned char bit) 334 { 335 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET, 336 HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0); 337 } 338 339 static inline void hdmi_phy_test_din(struct dw_hdmi *hdmi, 340 unsigned char bit) 341 { 342 hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); 343 } 344 345 static inline void hdmi_phy_test_dout(struct dw_hdmi *hdmi, 346 unsigned char bit) 347 { 348 hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); 349 } 350 351 static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec) 352 { 353 u32 val; 354 355 while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { 356 if (msec-- == 0) 357 return false; 358 udelay(1000); 359 } 360 hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0); 361 362 return true; 363 } 364 365 static void dw_hdmi_phy_i2c_write(struct dw_hdmi *hdmi, unsigned short data, 366 unsigned char addr) 367 { 368 hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); 369 hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); 370 hdmi_writeb(hdmi, (unsigned char)(data >> 8), 371 HDMI_PHY_I2CM_DATAO_1_ADDR); 372 hdmi_writeb(hdmi, (unsigned char)(data >> 0), 373 HDMI_PHY_I2CM_DATAO_0_ADDR); 374 hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, 375 HDMI_PHY_I2CM_OPERATION_ADDR); 376 hdmi_phy_wait_i2c_done(hdmi, 1000); 377 } 378 379 static void dw_hdmi_phy_enable_powerdown(struct dw_hdmi *hdmi, bool enable) 380 { 381 hdmi_mask_writeb(hdmi, !enable, HDMI_PHY_CONF0, 382 HDMI_PHY_CONF0_PDZ_OFFSET, 383 HDMI_PHY_CONF0_PDZ_MASK); 384 } 385 386 static void dw_hdmi_phy_enable_tmds(struct dw_hdmi *hdmi, u8 enable) 387 { 388 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 389 HDMI_PHY_CONF0_ENTMDS_OFFSET, 390 HDMI_PHY_CONF0_ENTMDS_MASK); 391 } 392 393 static void dw_hdmi_phy_enable_svsret(struct dw_hdmi *hdmi, u8 enable) 394 { 395 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 396 HDMI_PHY_CONF0_SVSRET_OFFSET, 397 HDMI_PHY_CONF0_SVSRET_MASK); 398 } 399 400 static void dw_hdmi_phy_gen2_pddq(struct dw_hdmi *hdmi, u8 enable) 401 { 402 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 403 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, 404 HDMI_PHY_CONF0_GEN2_PDDQ_MASK); 405 } 406 407 static void dw_hdmi_phy_gen2_txpwron(struct dw_hdmi *hdmi, u8 enable) 408 { 409 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 410 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, 411 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); 412 } 413 414 static void dw_hdmi_phy_sel_data_en_pol(struct dw_hdmi *hdmi, u8 enable) 415 { 416 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 417 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, 418 HDMI_PHY_CONF0_SELDATAENPOL_MASK); 419 } 420 421 static void dw_hdmi_phy_sel_interface_control(struct dw_hdmi *hdmi, u8 enable) 422 { 423 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 424 HDMI_PHY_CONF0_SELDIPIF_OFFSET, 425 HDMI_PHY_CONF0_SELDIPIF_MASK); 426 } 427 428 static void dw_hdmi_phy_power_off(struct dw_hdmi *hdmi) 429 { 430 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; 431 unsigned int i; 432 u16 val; 433 434 if (phy->gen == 1) { 435 dw_hdmi_phy_enable_tmds(hdmi, 0); 436 dw_hdmi_phy_enable_powerdown(hdmi, true); 437 return; 438 } 439 440 dw_hdmi_phy_gen2_txpwron(hdmi, 0); 441 442 /* 443 * Wait for TX_PHY_LOCK to be deasserted to indicate that the PHY went 444 * to low power mode. 445 */ 446 for (i = 0; i < 5; ++i) { 447 val = hdmi_readb(hdmi, HDMI_PHY_STAT0); 448 if (!(val & HDMI_PHY_TX_PHY_LOCK)) 449 break; 450 451 udelay(2000); 452 } 453 454 if (val & HDMI_PHY_TX_PHY_LOCK) 455 printf("PHY failed to power down\n"); 456 else 457 printf("PHY powered down in %u iterations\n", i); 458 459 dw_hdmi_phy_gen2_pddq(hdmi, 1); 460 } 461 462 static int dw_hdmi_phy_power_on(struct dw_hdmi *hdmi) 463 { 464 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; 465 unsigned int i; 466 u8 val; 467 468 if (phy->gen == 1) { 469 dw_hdmi_phy_enable_powerdown(hdmi, false); 470 471 /* Toggle TMDS enable. */ 472 dw_hdmi_phy_enable_tmds(hdmi, 0); 473 dw_hdmi_phy_enable_tmds(hdmi, 1); 474 return 0; 475 } 476 477 dw_hdmi_phy_gen2_txpwron(hdmi, 1); 478 dw_hdmi_phy_gen2_pddq(hdmi, 0); 479 480 /* Wait for PHY PLL lock */ 481 for (i = 0; i < 5; ++i) { 482 val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; 483 if (val) 484 break; 485 486 udelay(2000); 487 } 488 489 if (!val) { 490 printf("PHY PLL failed to lock\n"); 491 return -ETIMEDOUT; 492 } 493 494 printf("PHY PLL locked %u iterations\n", i); 495 return 0; 496 } 497 498 /* 499 * PHY configuration function for the DWC HDMI 3D TX PHY. Based on the available 500 * information the DWC MHL PHY has the same register layout and is thus also 501 * supported by this function. 502 */ 503 static 504 int hdmi_phy_configure_dwc_hdmi_3d_tx(struct dw_hdmi *hdmi, 505 const struct dw_hdmi_plat_data *pdata, 506 unsigned long mpixelclock) 507 { 508 const struct dw_hdmi_mpll_config *mpll_config = pdata->mpll_cfg; 509 const struct dw_hdmi_curr_ctrl *curr_ctrl = pdata->cur_ctr; 510 const struct dw_hdmi_phy_config *phy_config = pdata->phy_config; 511 512 /* PLL/MPLL Cfg - always match on final entry */ 513 for (; mpll_config->mpixelclock != ~0UL; mpll_config++) 514 if (mpixelclock <= mpll_config->mpixelclock) 515 break; 516 517 for (; curr_ctrl->mpixelclock != ~0UL; curr_ctrl++) 518 if (mpixelclock <= curr_ctrl->mpixelclock) 519 break; 520 521 for (; phy_config->mpixelclock != ~0UL; phy_config++) 522 if (mpixelclock <= phy_config->mpixelclock) 523 break; 524 525 if (mpll_config->mpixelclock == ~0UL || 526 curr_ctrl->mpixelclock == ~0UL || 527 phy_config->mpixelclock == ~0UL) 528 return -EINVAL; 529 530 /* 531 * RK3399 mpll clock source is vpll, also is vop clock source. 532 * vpll rate is twice of mpixelclock in YCBCR420 mode, we need 533 * to enable mpll pre-divider. 534 */ 535 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) && 536 (hdmi->dev_type == RK3399_HDMI || hdmi->dev_type == RK3368_HDMI)) 537 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce | 4, 538 HDMI_3D_TX_PHY_CPCE_CTRL); 539 else 540 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].cpce, 541 HDMI_3D_TX_PHY_CPCE_CTRL); 542 dw_hdmi_phy_i2c_write(hdmi, mpll_config->res[0].gmp, 543 HDMI_3D_TX_PHY_GMPCTRL); 544 dw_hdmi_phy_i2c_write(hdmi, curr_ctrl->curr[0], 545 HDMI_3D_TX_PHY_CURRCTRL); 546 547 dw_hdmi_phy_i2c_write(hdmi, 0, HDMI_3D_TX_PHY_PLLPHBYCTRL); 548 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_MSM_CTRL_CKO_SEL_FB_CLK, 549 HDMI_3D_TX_PHY_MSM_CTRL); 550 551 dw_hdmi_phy_i2c_write(hdmi, 0x0004, HDMI_3D_TX_PHY_TXTERM); 552 dw_hdmi_phy_i2c_write(hdmi, 0x8009, 553 HDMI_3D_TX_PHY_CKSYMTXCTRL); 554 dw_hdmi_phy_i2c_write(hdmi, 0x0272, 555 HDMI_3D_TX_PHY_VLEVCTRL); 556 557 /* Override and disable clock termination. */ 558 dw_hdmi_phy_i2c_write(hdmi, HDMI_3D_TX_PHY_CKCALCTRL_OVERRIDE, 559 HDMI_3D_TX_PHY_CKCALCTRL); 560 return 0; 561 } 562 563 static const struct dw_hdmi_phy_data dw_hdmi_phys[] = { 564 { 565 .type = DW_HDMI_PHY_DWC_HDMI_TX_PHY, 566 .name = "DWC HDMI TX PHY", 567 .gen = 1, 568 }, { 569 .type = DW_HDMI_PHY_DWC_MHL_PHY_HEAC, 570 .name = "DWC MHL PHY + HEAC PHY", 571 .gen = 2, 572 .has_svsret = true, 573 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, 574 }, { 575 .type = DW_HDMI_PHY_DWC_MHL_PHY, 576 .name = "DWC MHL PHY", 577 .gen = 2, 578 .has_svsret = true, 579 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, 580 }, { 581 .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY_HEAC, 582 .name = "DWC HDMI 3D TX PHY + HEAC PHY", 583 .gen = 2, 584 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, 585 }, { 586 .type = DW_HDMI_PHY_DWC_HDMI_3D_TX_PHY, 587 .name = "DWC HDMI 3D TX PHY", 588 .gen = 2, 589 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, 590 }, { 591 .type = DW_HDMI_PHY_DWC_HDMI20_TX_PHY, 592 .name = "DWC HDMI 2.0 TX PHY", 593 .gen = 2, 594 .has_svsret = true, 595 .configure = hdmi_phy_configure_dwc_hdmi_3d_tx, 596 }, { 597 .type = DW_HDMI_PHY_VENDOR_PHY, 598 .name = "Vendor PHY", 599 } 600 }; 601 602 /* ddc i2c master reset */ 603 static void rockchip_dw_hdmi_i2cm_reset(struct dw_hdmi *hdmi) 604 { 605 hdmi_writeb(hdmi, 0x00, HDMI_I2CM_SOFTRSTZ); 606 udelay(100); 607 } 608 609 static void rockchip_dw_hdmi_i2cm_mask_int(struct dw_hdmi *hdmi, int mask) 610 { 611 if (!mask) { 612 hdmi_writeb(hdmi, HDMI_I2CM_INT_DONE_POL, HDMI_I2CM_INT); 613 hdmi_writeb(hdmi, HDMI_I2CM_CTLINT_NAC_POL | 614 HDMI_I2CM_CTLINT_ARB_POL, HDMI_I2CM_CTLINT); 615 hdmi_writeb(hdmi, 0x00, HDMI_IH_MUTE_I2CM_STAT0); 616 } else { 617 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); 618 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); 619 } 620 } 621 622 static u16 i2c_count(u16 sfrclock, u16 sclmintime) 623 { 624 unsigned long tmp_scl_period = 0; 625 626 if (((sfrclock * sclmintime) % I2C_DIV_FACTOR) != 0) 627 tmp_scl_period = (unsigned long)((sfrclock * sclmintime) + 628 (I2C_DIV_FACTOR - ((sfrclock * sclmintime) % 629 I2C_DIV_FACTOR))) / I2C_DIV_FACTOR; 630 else 631 tmp_scl_period = (unsigned long)(sfrclock * sclmintime) / 632 I2C_DIV_FACTOR; 633 634 return (u16)(tmp_scl_period); 635 } 636 637 static void rockchip_dw_hdmi_i2cm_clk_init(struct dw_hdmi *hdmi) 638 { 639 int value; 640 641 /* Set DDC I2C CLK which divided from DDC_CLK. */ 642 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_HIGH_TIME); 643 hdmi_writeb(hdmi, value & 0xff, 644 HDMI_I2CM_SS_SCL_HCNT_0_ADDR); 645 hdmi_writeb(hdmi, (value >> 8) & 0xff, 646 HDMI_I2CM_SS_SCL_HCNT_1_ADDR); 647 value = i2c_count(24000, EDID_I2C_MIN_SS_SCL_LOW_TIME); 648 hdmi_writeb(hdmi, value & 0xff, 649 HDMI_I2CM_SS_SCL_LCNT_0_ADDR); 650 hdmi_writeb(hdmi, (value >> 8) & 0xff, 651 HDMI_I2CM_SS_SCL_LCNT_1_ADDR); 652 hdmi_modb(hdmi, HDMI_I2CM_DIV_STD_MODE, 653 HDMI_I2CM_DIV_FAST_STD_MODE, HDMI_I2CM_DIV); 654 } 655 656 /*set read/write offset,set read/write mode*/ 657 static void rockchip_dw_hdmi_i2cm_write_request(struct dw_hdmi *hdmi, 658 u8 offset, u8 data) 659 { 660 hdmi_writeb(hdmi, offset, HDMI_I2CM_ADDRESS); 661 hdmi_writeb(hdmi, data, HDMI_I2CM_DATAO); 662 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_WRITE, HDMI_I2CM_OPERATION_READ); 663 } 664 665 static void rockchip_dw_hdmi_i2cm_read_request(struct dw_hdmi *hdmi, 666 u8 offset) 667 { 668 hdmi_writeb(hdmi, offset, HDMI_I2CM_ADDRESS); 669 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ, HDMI_I2CM_OPERATION); 670 } 671 672 static void rockchip_dw_hdmi_i2cm_write_data(struct dw_hdmi *hdmi, 673 u8 data, u8 offset) 674 { 675 u8 interrupt = 0; 676 int trytime = 2; 677 int i = 20; 678 679 while (trytime-- > 0) { 680 rockchip_dw_hdmi_i2cm_write_request(hdmi, offset, data); 681 while (i--) { 682 udelay(1000); 683 interrupt = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0); 684 if (interrupt) 685 hdmi_writeb(hdmi, 686 interrupt, HDMI_IH_I2CM_STAT0); 687 688 if (interrupt & (m_SCDC_READREQ | 689 m_I2CM_DONE | m_I2CM_ERROR)) 690 break; 691 } 692 693 if (interrupt & m_I2CM_DONE) { 694 printf("[%s] write offset %02x data %02x success\n", 695 __func__, offset, data); 696 trytime = 0; 697 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { 698 printf("[%s] write data error\n", __func__); 699 rockchip_dw_hdmi_i2cm_reset(hdmi); 700 } 701 } 702 } 703 704 static int rockchip_dw_hdmi_i2cm_read_data(struct dw_hdmi *hdmi, u8 offset) 705 { 706 u8 interrupt = 0, val = 0; 707 int trytime = 2; 708 int i = 20; 709 710 while (trytime-- > 0) { 711 rockchip_dw_hdmi_i2cm_read_request(hdmi, offset); 712 while (i--) { 713 udelay(1000); 714 interrupt = hdmi_readb(hdmi, HDMI_IH_I2CM_STAT0); 715 if (interrupt) 716 hdmi_writeb(hdmi, HDMI_IH_I2CM_STAT0, 717 interrupt); 718 719 if (interrupt & (m_SCDC_READREQ | 720 m_I2CM_DONE | m_I2CM_ERROR)) 721 break; 722 } 723 724 if (interrupt & m_I2CM_DONE) { 725 val = hdmi_readb(hdmi, HDMI_I2CM_DATAI); 726 trytime = 0; 727 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { 728 printf("[%s] read data error\n", __func__); 729 rockchip_dw_hdmi_i2cm_reset(hdmi); 730 } 731 } 732 return val; 733 } 734 735 static int rockchip_dw_hdmi_scdc_get_sink_version(struct dw_hdmi *hdmi) 736 { 737 return rockchip_dw_hdmi_i2cm_read_data(hdmi, SCDC_SINK_VERSION); 738 } 739 740 static void rockchip_dw_hdmi_scdc_set_source_version(struct dw_hdmi *hdmi, 741 u8 version) 742 { 743 rockchip_dw_hdmi_i2cm_write_data(hdmi, version, SCDC_SOURCE_VERSION); 744 } 745 746 static void rockchip_dw_hdmi_scdc_init(struct dw_hdmi *hdmi) 747 { 748 rockchip_dw_hdmi_i2cm_reset(hdmi); 749 rockchip_dw_hdmi_i2cm_mask_int(hdmi, 1); 750 rockchip_dw_hdmi_i2cm_clk_init(hdmi); 751 /* set scdc i2c addr */ 752 hdmi_writeb(hdmi, DDC_I2C_SCDC_ADDR, HDMI_I2CM_SLAVE); 753 rockchip_dw_hdmi_i2cm_mask_int(hdmi, 0);/*enable interrupt*/ 754 } 755 756 static int rockchip_dw_hdmi_scrambling_enable(struct dw_hdmi *hdmi, 757 int enable) 758 { 759 int stat; 760 761 rockchip_dw_hdmi_scdc_init(hdmi); 762 stat = rockchip_dw_hdmi_i2cm_read_data(hdmi, 763 SCDC_TMDS_CONFIG); 764 if (stat < 0) { 765 debug("Failed to read tmds config\n"); 766 return false; 767 } 768 769 if (enable == 1) { 770 /* Write on Rx the bit Scrambling_Enable, register 0x20 */ 771 stat |= SCDC_SCRAMBLING_ENABLE; 772 rockchip_dw_hdmi_i2cm_write_data(hdmi, stat, SCDC_TMDS_CONFIG); 773 /* TMDS software reset request */ 774 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, 775 HDMI_MC_SWRSTZ); 776 /* Enable/Disable Scrambling */ 777 hdmi_writeb(hdmi, 1, HDMI_FC_SCRAMBLER_CTRL); 778 } else { 779 /* Enable/Disable Scrambling */ 780 hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL); 781 /* TMDS software reset request */ 782 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, 783 HDMI_MC_SWRSTZ); 784 /* Write on Rx the bit Scrambling_Enable, register 0x20 */ 785 stat &= ~SCDC_SCRAMBLING_ENABLE; 786 rockchip_dw_hdmi_i2cm_write_data(hdmi, stat, SCDC_TMDS_CONFIG); 787 } 788 789 return 0; 790 } 791 792 static void rockchip_dw_hdmi_scdc_set_tmds_rate(struct dw_hdmi *hdmi) 793 { 794 int stat; 795 796 rockchip_dw_hdmi_scdc_init(hdmi); 797 stat = rockchip_dw_hdmi_i2cm_read_data(hdmi, 798 SCDC_TMDS_CONFIG); 799 if (hdmi->hdmi_data.video_mode.mpixelclock > 340000000) 800 stat |= SCDC_TMDS_BIT_CLOCK_RATIO_BY_40; 801 else 802 stat &= ~SCDC_TMDS_BIT_CLOCK_RATIO_BY_40; 803 rockchip_dw_hdmi_i2cm_write_data(hdmi, stat, 804 SCDC_TMDS_CONFIG); 805 } 806 807 static int hdmi_phy_configure(struct dw_hdmi *hdmi) 808 { 809 const struct dw_hdmi_phy_data *phy = hdmi->phy.data; 810 const struct dw_hdmi_plat_data *pdata = hdmi->plat_data; 811 unsigned long mpixelclock = hdmi->hdmi_data.video_mode.mpixelclock; 812 int ret, sink_version; 813 814 dw_hdmi_phy_power_off(hdmi); 815 816 /* Control for TMDS Bit Period/TMDS Clock-Period Ratio */ 817 if (hdmi->edid_data.display_info.hdmi.scdc.supported) 818 rockchip_dw_hdmi_scdc_set_tmds_rate(hdmi); 819 820 /* Leave low power consumption mode by asserting SVSRET. */ 821 if (phy->has_svsret) 822 dw_hdmi_phy_enable_svsret(hdmi, 1); 823 824 /* PHY reset. The reset signal is active high on Gen2 PHYs. */ 825 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_PHYRSTZ, HDMI_MC_PHYRSTZ); 826 hdmi_writeb(hdmi, 0, HDMI_MC_PHYRSTZ); 827 828 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); 829 830 hdmi_phy_test_clear(hdmi, 1); 831 hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, 832 HDMI_PHY_I2CM_SLAVE_ADDR); 833 hdmi_phy_test_clear(hdmi, 0); 834 835 /* Write to the PHY as configured by the platform */ 836 if (pdata->configure_phy) 837 ret = pdata->configure_phy(hdmi, pdata, mpixelclock); 838 else 839 ret = phy->configure(hdmi, pdata, mpixelclock); 840 if (ret) { 841 printf("PHY configuration failed (clock %lu)\n", 842 mpixelclock); 843 return ret; 844 } 845 846 /* Wait for resuming transmission of TMDS clock and data */ 847 if (mpixelclock > 340000000) 848 mdelay(100); 849 850 return dw_hdmi_phy_power_on(hdmi); 851 } 852 853 static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, 854 struct drm_display_mode *mode) 855 { 856 int i, ret; 857 858 /* HDMI Phy spec says to do the phy initialization sequence twice */ 859 for (i = 0; i < 2; i++) { 860 dw_hdmi_phy_sel_data_en_pol(hdmi, 1); 861 dw_hdmi_phy_sel_interface_control(hdmi, 0); 862 ret = hdmi_phy_configure(hdmi); 863 if (ret) 864 return ret; 865 } 866 867 return 0; 868 } 869 870 static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, void *data) 871 { 872 dw_hdmi_phy_power_off(hdmi); 873 } 874 875 static enum drm_connector_status dw_hdmi_phy_read_hpd(struct dw_hdmi *hdmi, 876 void *data) 877 { 878 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? 879 connector_status_connected : connector_status_disconnected; 880 } 881 882 static const struct dw_hdmi_phy_ops dw_hdmi_synopsys_phy_ops = { 883 .init = dw_hdmi_phy_init, 884 .disable = dw_hdmi_phy_disable, 885 .read_hpd = dw_hdmi_phy_read_hpd, 886 }; 887 888 static int dw_hdmi_detect_phy(struct dw_hdmi *hdmi) 889 { 890 unsigned int i; 891 u8 phy_type; 892 893 phy_type = hdmi_readb(hdmi, HDMI_CONFIG2_ID); 894 895 /* 896 * RK3228 and RK3328 phy_type is DW_HDMI_PHY_DWC_HDMI20_TX_PHY, 897 * but it has a vedor phy. 898 */ 899 if (phy_type == DW_HDMI_PHY_VENDOR_PHY || 900 hdmi->dev_type == RK3328_HDMI || 901 hdmi->dev_type == RK3228_HDMI) { 902 /* Vendor PHYs require support from the glue layer. */ 903 if (!hdmi->plat_data->phy_ops || !hdmi->plat_data->phy_name) { 904 printf( 905 "Vendor HDMI PHY not supported by glue layer\n"); 906 return -ENODEV; 907 } 908 909 hdmi->phy.ops = hdmi->plat_data->phy_ops; 910 hdmi->phy.data = hdmi->plat_data->phy_data; 911 hdmi->phy.name = hdmi->plat_data->phy_name; 912 return 0; 913 } 914 915 /* Synopsys PHYs are handled internally. */ 916 for (i = 0; i < ARRAY_SIZE(dw_hdmi_phys); ++i) { 917 if (dw_hdmi_phys[i].type == phy_type) { 918 hdmi->phy.ops = &dw_hdmi_synopsys_phy_ops; 919 hdmi->phy.name = dw_hdmi_phys[i].name; 920 hdmi->phy.data = (void *)&dw_hdmi_phys[i]; 921 922 if (!dw_hdmi_phys[i].configure && 923 !hdmi->plat_data->configure_phy) { 924 printf("%s requires platform support\n", 925 hdmi->phy.name); 926 return -ENODEV; 927 } 928 929 return 0; 930 } 931 } 932 933 printf("Unsupported HDMI PHY type (%02x)\n", phy_type); 934 return -ENODEV; 935 } 936 937 static void hdmi_av_composer(struct dw_hdmi *hdmi, 938 const struct drm_display_mode *mode) 939 { 940 u8 inv_val = 0; 941 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; 942 struct drm_hdmi_info *hdmi_info = &hdmi->edid_data.display_info.hdmi; 943 int bytes, hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; 944 unsigned int hdisplay, vdisplay; 945 946 vmode->mpixelclock = mode->clock * 1000; 947 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) 948 vmode->mpixelclock /= 2; 949 if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == 950 DRM_MODE_FLAG_3D_FRAME_PACKING) 951 vmode->mpixelclock *= 2; 952 printf("final pixclk = %d\n", vmode->mpixelclock); 953 954 /* Set up HDMI_FC_INVIDCONF 955 * fc_invidconf.HDCP_keepout must be set (1'b1) 956 * when activate the scrambler feature. 957 */ 958 inv_val = (vmode->mpixelclock > 340000000 || 959 hdmi_info->scdc.scrambling.low_rates ? 960 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : 961 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); 962 963 inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ? 964 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : 965 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW; 966 967 inv_val |= mode->flags & DRM_MODE_FLAG_PHSYNC ? 968 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : 969 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW; 970 971 inv_val |= (vmode->mdataenablepolarity ? 972 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : 973 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); 974 975 if (hdmi->vic == 39) 976 inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; 977 else 978 inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? 979 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : 980 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW; 981 982 inv_val |= mode->flags & DRM_MODE_FLAG_INTERLACE ? 983 HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : 984 HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE; 985 986 inv_val |= hdmi->sink_is_hdmi ? 987 HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE : 988 HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE; 989 990 hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); 991 992 hdisplay = mode->hdisplay; 993 hblank = mode->htotal - mode->hdisplay; 994 h_de_hs = mode->hsync_start - mode->hdisplay; 995 hsync_len = mode->hsync_end - mode->hsync_start; 996 997 /* 998 * When we're setting a YCbCr420 mode, we need 999 * to adjust the horizontal timing to suit. 1000 */ 1001 /* 1002 * When we're setting a YCbCr420 mode, we need 1003 * to adjust the horizontal timing to suit. 1004 */ 1005 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) { 1006 hdisplay /= 2; 1007 hblank /= 2; 1008 h_de_hs /= 2; 1009 hsync_len /= 2; 1010 } 1011 1012 vdisplay = mode->vdisplay; 1013 vblank = mode->vtotal - mode->vdisplay; 1014 v_de_vs = mode->vsync_start - mode->vdisplay; 1015 vsync_len = mode->vsync_end - mode->vsync_start; 1016 1017 /* 1018 * When we're setting an interlaced mode, we need 1019 * to adjust the vertical timing to suit. 1020 */ 1021 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1022 vdisplay /= 2; 1023 vblank /= 2; 1024 v_de_vs /= 2; 1025 vsync_len /= 2; 1026 } else if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == 1027 DRM_MODE_FLAG_3D_FRAME_PACKING) { 1028 vdisplay += mode->vtotal; 1029 } 1030 1031 /* Scrambling Control */ 1032 if (hdmi_info->scdc.supported) { 1033 if (vmode->mpixelclock > 340000000 || 1034 hdmi_info->scdc.scrambling.low_rates) { 1035 bytes = rockchip_dw_hdmi_scdc_get_sink_version(hdmi); 1036 rockchip_dw_hdmi_scdc_set_source_version(hdmi, bytes); 1037 rockchip_dw_hdmi_scrambling_enable(hdmi, 1); 1038 } else { 1039 rockchip_dw_hdmi_scrambling_enable(hdmi, 0); 1040 } 1041 } 1042 1043 /* Set up horizontal active pixel width */ 1044 hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1); 1045 hdmi_writeb(hdmi, hdisplay, HDMI_FC_INHACTV0); 1046 1047 /* Set up vertical active lines */ 1048 hdmi_writeb(hdmi, vdisplay >> 8, HDMI_FC_INVACTV1); 1049 hdmi_writeb(hdmi, vdisplay, HDMI_FC_INVACTV0); 1050 1051 /* Set up horizontal blanking pixel region width */ 1052 hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); 1053 hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); 1054 1055 /* Set up vertical blanking pixel region width */ 1056 hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); 1057 1058 /* Set up HSYNC active edge delay width (in pixel clks) */ 1059 hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); 1060 hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); 1061 1062 /* Set up VSYNC active edge delay (in lines) */ 1063 hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); 1064 1065 /* Set up HSYNC active pulse width (in pixel clks) */ 1066 hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); 1067 hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); 1068 1069 /* Set up VSYNC active edge delay (in lines) */ 1070 hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); 1071 } 1072 1073 static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) 1074 { 1075 const u16 (*csc_coeff)[3][4] = &csc_coeff_default; 1076 unsigned i; 1077 u32 csc_scale = 1; 1078 1079 if (is_color_space_conversion(hdmi)) { 1080 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { 1081 if (hdmi->hdmi_data.enc_out_encoding == 1082 V4L2_YCBCR_ENC_601) 1083 csc_coeff = &csc_coeff_rgb_out_eitu601; 1084 else 1085 csc_coeff = &csc_coeff_rgb_out_eitu709; 1086 } else if (hdmi_bus_fmt_is_rgb( 1087 hdmi->hdmi_data.enc_in_bus_format)) { 1088 if (hdmi->hdmi_data.enc_out_encoding == 1089 V4L2_YCBCR_ENC_601) 1090 csc_coeff = &csc_coeff_rgb_in_eitu601; 1091 else 1092 csc_coeff = &csc_coeff_rgb_in_eitu709; 1093 csc_scale = 0; 1094 } 1095 } 1096 1097 /* The CSC registers are sequential, alternating MSB then LSB */ 1098 for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) { 1099 u16 coeff_a = (*csc_coeff)[0][i]; 1100 u16 coeff_b = (*csc_coeff)[1][i]; 1101 u16 coeff_c = (*csc_coeff)[2][i]; 1102 1103 hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); 1104 hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); 1105 hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); 1106 hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); 1107 hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); 1108 hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); 1109 } 1110 1111 hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, 1112 HDMI_CSC_SCALE); 1113 } 1114 1115 static int is_color_space_interpolation(struct dw_hdmi *hdmi) 1116 { 1117 if (!hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_in_bus_format)) 1118 return 0; 1119 1120 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || 1121 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) 1122 return 1; 1123 1124 return 0; 1125 } 1126 1127 static void hdmi_video_csc(struct dw_hdmi *hdmi) 1128 { 1129 int color_depth = 0; 1130 int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; 1131 int decimation = 0; 1132 1133 /* YCC422 interpolation to 444 mode */ 1134 if (is_color_space_interpolation(hdmi)) 1135 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; 1136 else if (is_color_space_decimation(hdmi)) 1137 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; 1138 1139 switch (hdmi_bus_fmt_color_depth(hdmi->hdmi_data.enc_out_bus_format)) { 1140 case 8: 1141 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; 1142 break; 1143 case 10: 1144 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; 1145 break; 1146 case 12: 1147 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; 1148 break; 1149 case 16: 1150 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; 1151 break; 1152 1153 default: 1154 return; 1155 } 1156 1157 /* Configure the CSC registers */ 1158 hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); 1159 hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, 1160 HDMI_CSC_SCALE); 1161 1162 dw_hdmi_update_csc_coeffs(hdmi); 1163 } 1164 1165 static void dw_hdmi_enable_video_path(struct dw_hdmi *hdmi) 1166 { 1167 u8 clkdis; 1168 1169 /* control period minimum duration */ 1170 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); 1171 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); 1172 hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); 1173 1174 /* Set to fill TMDS data channels */ 1175 hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); 1176 hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); 1177 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); 1178 1179 /* Enable pixel clock and tmds data path */ 1180 clkdis = 0x7F; 1181 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; 1182 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1183 1184 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; 1185 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1186 1187 /* Enable csc path */ 1188 if (is_color_space_conversion(hdmi)) { 1189 clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; 1190 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1191 } 1192 1193 /* Enable pixel repetition path */ 1194 if (hdmi->hdmi_data.video_mode.mpixelrepetitioninput) { 1195 clkdis &= ~HDMI_MC_CLKDIS_PREPCLK_DISABLE; 1196 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1197 } 1198 1199 /* Enable color space conversion if needed */ 1200 if (is_color_space_conversion(hdmi)) 1201 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH, 1202 HDMI_MC_FLOWCTRL); 1203 else 1204 hdmi_writeb(hdmi, HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS, 1205 HDMI_MC_FLOWCTRL); 1206 } 1207 1208 static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) 1209 { 1210 unsigned int count; 1211 unsigned int i; 1212 u8 val; 1213 1214 /* 1215 * Under some circumstances the Frame Composer arithmetic unit can miss 1216 * an FC register write due to being busy processing the previous one. 1217 * The issue can be worked around by issuing a TMDS software reset and 1218 * then write one of the FC registers several times. 1219 * 1220 * The number of iterations matters and depends on the HDMI TX revision 1221 * (and possibly on the platform). So far only i.MX6Q (v1.30a) and 1222 * i.MX6DL (v1.31a) have been identified as needing the workaround, with 1223 * 4 and 1 iterations respectively. 1224 */ 1225 1226 switch (hdmi->version) { 1227 case 0x130a: 1228 count = 4; 1229 break; 1230 case 0x131a: 1231 count = 1; 1232 break; 1233 default: 1234 return; 1235 } 1236 1237 /* TMDS software reset */ 1238 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); 1239 1240 val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); 1241 for (i = 0; i < count; i++) 1242 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); 1243 } 1244 1245 static void hdmi_disable_overflow_interrupts(struct dw_hdmi *hdmi) 1246 { 1247 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, 1248 HDMI_IH_MUTE_FC_STAT2); 1249 } 1250 1251 static void hdmi_video_packetize(struct dw_hdmi *hdmi) 1252 { 1253 unsigned int color_depth = 0; 1254 unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; 1255 unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; 1256 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; 1257 u8 val, vp_conf; 1258 1259 if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) || 1260 hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format) || 1261 hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) { 1262 switch (hdmi_bus_fmt_color_depth( 1263 hdmi->hdmi_data.enc_out_bus_format)) { 1264 case 8: 1265 color_depth = 0; 1266 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; 1267 break; 1268 case 10: 1269 color_depth = 5; 1270 break; 1271 case 12: 1272 color_depth = 6; 1273 break; 1274 case 16: 1275 color_depth = 7; 1276 break; 1277 default: 1278 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; 1279 } 1280 } else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) { 1281 switch (hdmi_bus_fmt_color_depth( 1282 hdmi->hdmi_data.enc_out_bus_format)) { 1283 case 0: 1284 case 8: 1285 remap_size = HDMI_VP_REMAP_YCC422_16bit; 1286 break; 1287 case 10: 1288 remap_size = HDMI_VP_REMAP_YCC422_20bit; 1289 break; 1290 case 12: 1291 remap_size = HDMI_VP_REMAP_YCC422_24bit; 1292 break; 1293 1294 default: 1295 return; 1296 } 1297 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; 1298 } else { 1299 return; 1300 } 1301 1302 /* set the packetizer registers */ 1303 val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & 1304 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | 1305 ((hdmi_data->pix_repet_factor << 1306 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & 1307 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); 1308 hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); 1309 1310 hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, 1311 HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF); 1312 1313 /* Data from pixel repeater block */ 1314 if (hdmi_data->pix_repet_factor > 0) { 1315 vp_conf = HDMI_VP_CONF_PR_EN_ENABLE | 1316 HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; 1317 } else { /* data from packetizer block */ 1318 vp_conf = HDMI_VP_CONF_PR_EN_DISABLE | 1319 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; 1320 } 1321 1322 hdmi_modb(hdmi, vp_conf, 1323 HDMI_VP_CONF_PR_EN_MASK | 1324 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); 1325 1326 hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, 1327 HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF); 1328 1329 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); 1330 1331 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { 1332 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | 1333 HDMI_VP_CONF_PP_EN_ENABLE | 1334 HDMI_VP_CONF_YCC422_EN_DISABLE; 1335 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { 1336 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | 1337 HDMI_VP_CONF_PP_EN_DISABLE | 1338 HDMI_VP_CONF_YCC422_EN_ENABLE; 1339 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { 1340 vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE | 1341 HDMI_VP_CONF_PP_EN_DISABLE | 1342 HDMI_VP_CONF_YCC422_EN_DISABLE; 1343 } else { 1344 return; 1345 } 1346 1347 hdmi_modb(hdmi, vp_conf, 1348 HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK | 1349 HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); 1350 1351 hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | 1352 HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE, 1353 HDMI_VP_STUFF_PP_STUFFING_MASK | 1354 HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF); 1355 1356 hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK, 1357 HDMI_VP_CONF); 1358 } 1359 1360 static void hdmi_video_sample(struct dw_hdmi *hdmi) 1361 { 1362 int color_format = 0; 1363 u8 val; 1364 1365 switch (hdmi->hdmi_data.enc_in_bus_format) { 1366 case MEDIA_BUS_FMT_RGB888_1X24: 1367 color_format = 0x01; 1368 break; 1369 case MEDIA_BUS_FMT_RGB101010_1X30: 1370 color_format = 0x03; 1371 break; 1372 case MEDIA_BUS_FMT_RGB121212_1X36: 1373 color_format = 0x05; 1374 break; 1375 case MEDIA_BUS_FMT_RGB161616_1X48: 1376 color_format = 0x07; 1377 break; 1378 1379 case MEDIA_BUS_FMT_YUV8_1X24: 1380 case MEDIA_BUS_FMT_UYYVYY8_0_5X24: 1381 color_format = 0x09; 1382 break; 1383 case MEDIA_BUS_FMT_YUV10_1X30: 1384 case MEDIA_BUS_FMT_UYYVYY10_0_5X30: 1385 color_format = 0x0B; 1386 break; 1387 case MEDIA_BUS_FMT_YUV12_1X36: 1388 case MEDIA_BUS_FMT_UYYVYY12_0_5X36: 1389 color_format = 0x0D; 1390 break; 1391 case MEDIA_BUS_FMT_YUV16_1X48: 1392 case MEDIA_BUS_FMT_UYYVYY16_0_5X48: 1393 color_format = 0x0F; 1394 break; 1395 1396 case MEDIA_BUS_FMT_UYVY8_1X16: 1397 color_format = 0x16; 1398 break; 1399 case MEDIA_BUS_FMT_UYVY10_1X20: 1400 color_format = 0x14; 1401 break; 1402 case MEDIA_BUS_FMT_UYVY12_1X24: 1403 color_format = 0x12; 1404 break; 1405 1406 default: 1407 return; 1408 } 1409 1410 val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | 1411 ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & 1412 HDMI_TX_INVID0_VIDEO_MAPPING_MASK); 1413 hdmi_writeb(hdmi, val, HDMI_TX_INVID0); 1414 1415 /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ 1416 val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | 1417 HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | 1418 HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; 1419 hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); 1420 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); 1421 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); 1422 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); 1423 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); 1424 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); 1425 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); 1426 } 1427 1428 static void hdmi_enable_overflow_interrupts(struct dw_hdmi *hdmi) 1429 { 1430 hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); 1431 hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); 1432 } 1433 1434 static void dw_hdmi_disable(struct dw_hdmi *hdmi) 1435 { 1436 if (hdmi->phy.enabled) { 1437 hdmi->phy.ops->disable(hdmi, hdmi->phy.data); 1438 hdmi->phy.enabled = false; 1439 } 1440 } 1441 1442 static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) 1443 { 1444 struct hdmi_avi_infoframe frame; 1445 u8 val; 1446 bool is_hdmi2 = false; 1447 1448 if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format) || 1449 hdmi->edid_data.display_info.hdmi.scdc.supported) 1450 is_hdmi2 = true; 1451 /* Initialise info frame from DRM mode */ 1452 drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, is_hdmi2); 1453 1454 if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) 1455 frame.colorspace = HDMI_COLORSPACE_YUV444; 1456 else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) 1457 frame.colorspace = HDMI_COLORSPACE_YUV422; 1458 else if (hdmi_bus_fmt_is_yuv420(hdmi->hdmi_data.enc_out_bus_format)) 1459 frame.colorspace = HDMI_COLORSPACE_YUV420; 1460 else 1461 frame.colorspace = HDMI_COLORSPACE_RGB; 1462 1463 /* Set up colorimetry */ 1464 switch (hdmi->hdmi_data.enc_out_encoding) { 1465 case V4L2_YCBCR_ENC_601: 1466 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) 1467 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; 1468 else 1469 frame.colorimetry = HDMI_COLORIMETRY_ITU_601; 1470 frame.extended_colorimetry = 1471 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; 1472 break; 1473 case V4L2_YCBCR_ENC_709: 1474 if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) 1475 frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; 1476 else 1477 frame.colorimetry = HDMI_COLORIMETRY_ITU_709; 1478 frame.extended_colorimetry = 1479 HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; 1480 break; 1481 default: /* Carries no data */ 1482 frame.colorimetry = HDMI_COLORIMETRY_ITU_601; 1483 frame.extended_colorimetry = 1484 HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; 1485 break; 1486 } 1487 1488 frame.scan_mode = HDMI_SCAN_MODE_NONE; 1489 1490 /* 1491 * The Designware IP uses a different byte format from standard 1492 * AVI info frames, though generally the bits are in the correct 1493 * bytes. 1494 */ 1495 1496 /* 1497 * AVI data byte 1 differences: Colorspace in bits 0,1,7 rather than 1498 * 5,6,7, active aspect present in bit 6 rather than 4. 1499 */ 1500 val = (frame.scan_mode & 3) << 4 | (frame.colorspace & 0x3); 1501 if (frame.active_aspect & 15) 1502 val |= HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT; 1503 if (frame.top_bar || frame.bottom_bar) 1504 val |= HDMI_FC_AVICONF0_BAR_DATA_HORIZ_BAR; 1505 if (frame.left_bar || frame.right_bar) 1506 val |= HDMI_FC_AVICONF0_BAR_DATA_VERT_BAR; 1507 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); 1508 1509 /* AVI data byte 2 differences: none */ 1510 val = ((frame.colorimetry & 0x3) << 6) | 1511 ((frame.picture_aspect & 0x3) << 4) | 1512 (frame.active_aspect & 0xf); 1513 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); 1514 1515 /* AVI data byte 3 differences: none */ 1516 val = ((frame.extended_colorimetry & 0x7) << 4) | 1517 ((frame.quantization_range & 0x3) << 2) | 1518 (frame.nups & 0x3); 1519 if (frame.itc) 1520 val |= HDMI_FC_AVICONF2_IT_CONTENT_VALID; 1521 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); 1522 1523 /* AVI data byte 4 differences: none */ 1524 val = frame.video_code & 0x7f; 1525 hdmi_writeb(hdmi, val, HDMI_FC_AVIVID); 1526 1527 /* AVI Data Byte 5- set up input and output pixel repetition */ 1528 val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << 1529 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & 1530 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | 1531 ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << 1532 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & 1533 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); 1534 hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); 1535 1536 /* 1537 * AVI data byte 5 differences: content type in 0,1 rather than 4,5, 1538 * ycc range in bits 2,3 rather than 6,7 1539 */ 1540 val = ((frame.ycc_quantization_range & 0x3) << 2) | 1541 (frame.content_type & 0x3); 1542 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); 1543 1544 /* AVI Data Bytes 6-13 */ 1545 hdmi_writeb(hdmi, frame.top_bar & 0xff, HDMI_FC_AVIETB0); 1546 hdmi_writeb(hdmi, (frame.top_bar >> 8) & 0xff, HDMI_FC_AVIETB1); 1547 hdmi_writeb(hdmi, frame.bottom_bar & 0xff, HDMI_FC_AVISBB0); 1548 hdmi_writeb(hdmi, (frame.bottom_bar >> 8) & 0xff, HDMI_FC_AVISBB1); 1549 hdmi_writeb(hdmi, frame.left_bar & 0xff, HDMI_FC_AVIELB0); 1550 hdmi_writeb(hdmi, (frame.left_bar >> 8) & 0xff, HDMI_FC_AVIELB1); 1551 hdmi_writeb(hdmi, frame.right_bar & 0xff, HDMI_FC_AVISRB0); 1552 hdmi_writeb(hdmi, (frame.right_bar >> 8) & 0xff, HDMI_FC_AVISRB1); 1553 } 1554 1555 static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi, 1556 struct drm_display_mode *mode) 1557 { 1558 struct hdmi_vendor_infoframe frame; 1559 u8 buffer[10]; 1560 ssize_t err; 1561 1562 /* Disable HDMI vendor specific infoframe send */ 1563 hdmi_mask_writeb(hdmi, 0, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, 1564 HDMI_FC_DATAUTO0_VSD_MASK); 1565 1566 err = drm_hdmi_vendor_infoframe_from_display_mode(&frame, mode); 1567 if (err < 0) 1568 /* 1569 * Going into that statement does not means vendor infoframe 1570 * fails. It just informed us that vendor infoframe is not 1571 * needed for the selected mode. Only 4k or stereoscopic 3D 1572 * mode requires vendor infoframe. So just simply return. 1573 */ 1574 return; 1575 1576 err = hdmi_vendor_infoframe_pack(&frame, buffer, sizeof(buffer)); 1577 if (err < 0) { 1578 printf("Failed to pack vendor infoframe: %zd\n", err); 1579 return; 1580 } 1581 1582 /* Set the length of HDMI vendor specific InfoFrame payload */ 1583 hdmi_writeb(hdmi, buffer[2], HDMI_FC_VSDSIZE); 1584 1585 /* Set 24bit IEEE Registration Identifier */ 1586 hdmi_writeb(hdmi, buffer[4], HDMI_FC_VSDIEEEID0); 1587 hdmi_writeb(hdmi, buffer[5], HDMI_FC_VSDIEEEID1); 1588 hdmi_writeb(hdmi, buffer[6], HDMI_FC_VSDIEEEID2); 1589 1590 /* Set HDMI_Video_Format and HDMI_VIC/3D_Structure */ 1591 hdmi_writeb(hdmi, buffer[7], HDMI_FC_VSDPAYLOAD0); 1592 hdmi_writeb(hdmi, buffer[8], HDMI_FC_VSDPAYLOAD1); 1593 1594 if (frame.s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 1595 hdmi_writeb(hdmi, buffer[9], HDMI_FC_VSDPAYLOAD2); 1596 1597 /* Packet frame interpolation */ 1598 hdmi_writeb(hdmi, 1, HDMI_FC_DATAUTO1); 1599 1600 /* Auto packets per frame and line spacing */ 1601 hdmi_writeb(hdmi, 0x11, HDMI_FC_DATAUTO2); 1602 1603 /* Configures the Frame Composer On RDRB mode */ 1604 hdmi_mask_writeb(hdmi, 1, HDMI_FC_DATAUTO0, HDMI_FC_DATAUTO0_VSD_OFFSET, 1605 HDMI_FC_DATAUTO0_VSD_MASK); 1606 } 1607 1608 static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, 1609 unsigned int n) 1610 { 1611 /* Must be set/cleared first */ 1612 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); 1613 1614 /* nshift factor = 0 */ 1615 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); 1616 1617 hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | 1618 HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); 1619 hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); 1620 hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); 1621 1622 hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3); 1623 hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2); 1624 hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1); 1625 } 1626 1627 static int hdmi_match_tmds_n_table(struct dw_hdmi *hdmi, 1628 unsigned long pixel_clk, 1629 unsigned long freq) 1630 { 1631 const struct dw_hdmi_plat_data *plat_data = hdmi->plat_data; 1632 const struct dw_hdmi_audio_tmds_n *tmds_n = NULL; 1633 int i; 1634 1635 if (plat_data->tmds_n_table) { 1636 for (i = 0; plat_data->tmds_n_table[i].tmds != 0; i++) { 1637 if (pixel_clk == plat_data->tmds_n_table[i].tmds) { 1638 tmds_n = &plat_data->tmds_n_table[i]; 1639 break; 1640 } 1641 } 1642 } 1643 1644 if (!tmds_n) { 1645 for (i = 0; common_tmds_n_table[i].tmds != 0; i++) { 1646 if (pixel_clk == common_tmds_n_table[i].tmds) { 1647 tmds_n = &common_tmds_n_table[i]; 1648 break; 1649 } 1650 } 1651 } 1652 1653 if (!tmds_n) 1654 return -ENOENT; 1655 1656 switch (freq) { 1657 case 32000: 1658 return tmds_n->n_32k; 1659 case 44100: 1660 case 88200: 1661 case 176400: 1662 return (freq / 44100) * tmds_n->n_44k1; 1663 case 48000: 1664 case 96000: 1665 case 192000: 1666 return (freq / 48000) * tmds_n->n_48k; 1667 default: 1668 return -ENOENT; 1669 } 1670 } 1671 1672 static u64 hdmi_audio_math_diff(unsigned int freq, unsigned int n, 1673 unsigned int pixel_clk) 1674 { 1675 u64 final, diff; 1676 u64 cts; 1677 1678 final = (u64)pixel_clk * n; 1679 1680 cts = final; 1681 do_div(cts, 128 * freq); 1682 1683 diff = final - (u64)cts * (128 * freq); 1684 1685 return diff; 1686 } 1687 1688 static unsigned int hdmi_compute_n(struct dw_hdmi *hdmi, 1689 unsigned long pixel_clk, 1690 unsigned long freq) 1691 { 1692 unsigned int min_n = DIV_ROUND_UP((128 * freq), 1500); 1693 unsigned int max_n = (128 * freq) / 300; 1694 unsigned int ideal_n = (128 * freq) / 1000; 1695 unsigned int best_n_distance = ideal_n; 1696 unsigned int best_n = 0; 1697 u64 best_diff = U64_MAX; 1698 int n; 1699 1700 /* If the ideal N could satisfy the audio math, then just take it */ 1701 if (hdmi_audio_math_diff(freq, ideal_n, pixel_clk) == 0) 1702 return ideal_n; 1703 1704 for (n = min_n; n <= max_n; n++) { 1705 u64 diff = hdmi_audio_math_diff(freq, n, pixel_clk); 1706 1707 if (diff < best_diff || (diff == best_diff && 1708 abs(n - ideal_n) < best_n_distance)) { 1709 best_n = n; 1710 best_diff = diff; 1711 best_n_distance = abs(best_n - ideal_n); 1712 } 1713 1714 /* 1715 * The best N already satisfy the audio math, and also be 1716 * the closest value to ideal N, so just cut the loop. 1717 */ 1718 if ((best_diff == 0) && (abs(n - ideal_n) > best_n_distance)) 1719 break; 1720 } 1721 1722 return best_n; 1723 } 1724 1725 static unsigned int hdmi_find_n(struct dw_hdmi *hdmi, unsigned long pixel_clk, 1726 unsigned long sample_rate) 1727 { 1728 int n; 1729 1730 n = hdmi_match_tmds_n_table(hdmi, pixel_clk, sample_rate); 1731 if (n > 0) 1732 return n; 1733 1734 printf("Rate %lu missing; compute N dynamically\n", 1735 pixel_clk); 1736 1737 return hdmi_compute_n(hdmi, pixel_clk, sample_rate); 1738 } 1739 1740 static 1741 void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, unsigned long pixel_clk, 1742 unsigned int sample_rate) 1743 { 1744 unsigned long ftdms = pixel_clk; 1745 unsigned int n, cts; 1746 u64 tmp; 1747 1748 n = hdmi_find_n(hdmi, pixel_clk, sample_rate); 1749 1750 /* 1751 * Compute the CTS value from the N value. Note that CTS and N 1752 * can be up to 20 bits in total, so we need 64-bit math. Also 1753 * note that our TDMS clock is not fully accurate; it is accurate 1754 * to kHz. This can introduce an unnecessary remainder in the 1755 * calculation below, so we don't try to warn about that. 1756 */ 1757 tmp = (u64)ftdms * n; 1758 do_div(tmp, 128 * sample_rate); 1759 cts = tmp; 1760 1761 printf("%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", __func__, 1762 sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, n, cts); 1763 1764 hdmi->audio_n = n; 1765 hdmi->audio_cts = cts; 1766 hdmi_set_cts_n(hdmi, cts, hdmi->audio_enable ? n : 0); 1767 } 1768 1769 static void hdmi_clk_regenerator_update_pixel_clock(struct dw_hdmi *hdmi) 1770 { 1771 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, 1772 hdmi->sample_rate); 1773 } 1774 1775 static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) 1776 { 1777 hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); 1778 } 1779 1780 void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate) 1781 { 1782 hdmi->sample_rate = rate; 1783 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock, 1784 hdmi->sample_rate); 1785 } 1786 1787 static int dw_hdmi_setup(struct dw_hdmi *hdmi, 1788 struct drm_display_mode *mode) 1789 { 1790 int ret; 1791 void *data = hdmi->plat_data->phy_data; 1792 1793 hdmi_disable_overflow_interrupts(hdmi); 1794 1795 if (!hdmi->vic) 1796 printf("Non-CEA mode used in HDMI\n"); 1797 else 1798 printf("CEA mode used vic=%d\n", hdmi->vic); 1799 1800 if (hdmi->plat_data->get_enc_out_encoding) 1801 hdmi->hdmi_data.enc_out_encoding = 1802 hdmi->plat_data->get_enc_out_encoding(data); 1803 else if ((hdmi->vic == 6) || (hdmi->vic == 7) || 1804 (hdmi->vic == 21) || (hdmi->vic == 22) || 1805 (hdmi->vic == 2) || (hdmi->vic == 3) || 1806 (hdmi->vic == 17) || (hdmi->vic == 18)) 1807 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601; 1808 else 1809 hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709; 1810 1811 if (mode->flags & DRM_MODE_FLAG_DBLCLK) { 1812 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1; 1813 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 1; 1814 } else { 1815 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; 1816 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; 1817 } 1818 1819 /* TOFIX: Get input format from plat data or fallback to RGB888 */ 1820 if (hdmi->plat_data->get_input_bus_format) 1821 hdmi->hdmi_data.enc_in_bus_format = 1822 hdmi->plat_data->get_input_bus_format(data); 1823 else if (hdmi->plat_data->input_bus_format) 1824 hdmi->hdmi_data.enc_in_bus_format = 1825 hdmi->plat_data->input_bus_format; 1826 else 1827 hdmi->hdmi_data.enc_in_bus_format = 1828 MEDIA_BUS_FMT_RGB888_1X24; 1829 1830 /* TOFIX: Default to RGB888 output format */ 1831 if (hdmi->plat_data->get_output_bus_format) 1832 hdmi->hdmi_data.enc_out_bus_format = 1833 hdmi->plat_data->get_output_bus_format(data); 1834 else 1835 hdmi->hdmi_data.enc_out_bus_format = 1836 MEDIA_BUS_FMT_RGB888_1X24; 1837 1838 /* TOFIX: Get input encoding from plat data or fallback to none */ 1839 if (hdmi->plat_data->get_enc_in_encoding) 1840 hdmi->hdmi_data.enc_in_encoding = 1841 hdmi->plat_data->get_enc_in_encoding(data); 1842 else if (hdmi->plat_data->input_bus_encoding) 1843 hdmi->hdmi_data.enc_in_encoding = 1844 hdmi->plat_data->input_bus_encoding; 1845 else 1846 hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; 1847 /* 1848 * According to the dw-hdmi specification 6.4.2 1849 * vp_pr_cd[3:0]: 1850 * 0000b: No pixel repetition (pixel sent only once) 1851 * 0001b: Pixel sent two times (pixel repeated once) 1852 */ 1853 hdmi->hdmi_data.pix_repet_factor = 1854 (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 1 : 0; 1855 hdmi->hdmi_data.video_mode.mdataenablepolarity = true; 1856 1857 /* HDMI Initialization Step B.1 */ 1858 hdmi_av_composer(hdmi, mode); 1859 1860 /* HDMI Initialization Step B.2 */ 1861 ret = hdmi->phy.ops->init(hdmi, hdmi->phy.data, &hdmi->previous_mode); 1862 if (ret) 1863 return ret; 1864 hdmi->phy.enabled = true; 1865 1866 /* HDMI Initializateion Step B.3 */ 1867 dw_hdmi_enable_video_path(hdmi); 1868 1869 /* HDMI Initialization Step E - Configure audio */ 1870 if (hdmi->sink_has_audio) { 1871 printf("sink has audio support\n"); 1872 hdmi_clk_regenerator_update_pixel_clock(hdmi); 1873 hdmi_enable_audio_clk(hdmi); 1874 } 1875 1876 /* not for DVI mode */ 1877 if (hdmi->sink_is_hdmi) { 1878 printf("%s HDMI mode\n", __func__); 1879 1880 /* HDMI Initialization Step F - Configure AVI InfoFrame */ 1881 hdmi_config_AVI(hdmi, mode); 1882 hdmi_config_vendor_specific_infoframe(hdmi, mode); 1883 } else { 1884 printf("%s DVI mode\n", __func__); 1885 } 1886 1887 hdmi_video_packetize(hdmi); 1888 hdmi_video_csc(hdmi); 1889 hdmi_video_sample(hdmi); 1890 dw_hdmi_clear_overflow(hdmi); 1891 if (hdmi->cable_plugin && hdmi->sink_is_hdmi) 1892 hdmi_enable_overflow_interrupts(hdmi); 1893 1894 return 0; 1895 } 1896 1897 int dw_hdmi_detect_hotplug(struct dw_hdmi *hdmi) 1898 { 1899 return hdmi->phy.ops->read_hpd(hdmi, hdmi->phy.data); 1900 } 1901 1902 static int dw_hdmi_set_reg_wr(struct dw_hdmi *hdmi) 1903 { 1904 switch (hdmi->io_width) { 1905 case 4: 1906 hdmi->write = dw_hdmi_writel; 1907 hdmi->read = dw_hdmi_readl; 1908 break; 1909 case 1: 1910 hdmi->write = dw_hdmi_writeb; 1911 hdmi->read = dw_hdmi_readb; 1912 break; 1913 default: 1914 printf("reg-io-width must be 1 or 4\n"); 1915 return -EINVAL; 1916 } 1917 1918 return 0; 1919 } 1920 1921 static void initialize_hdmi_mutes(struct dw_hdmi *hdmi) 1922 { 1923 /*mute unnecessary interrupt, only enable hpd */ 1924 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); 1925 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); 1926 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); 1927 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); 1928 hdmi_writeb(hdmi, 0xfe, HDMI_IH_MUTE_PHY_STAT0); 1929 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); 1930 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); 1931 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); 1932 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); 1933 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); 1934 hdmi_writeb(hdmi, 0xf1, HDMI_PHY_MASK0); 1935 1936 /*Force output black*/ 1937 dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS2); 1938 dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS1); 1939 dw_hdmi_writel(hdmi, 0x00, HDMI_FC_DBGTMDS0); 1940 } 1941 1942 static void dw_hdmi_dev_init(struct dw_hdmi *hdmi) 1943 { 1944 hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) 1945 | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); 1946 1947 dw_hdmi_phy_power_off(hdmi); 1948 initialize_hdmi_mutes(hdmi); 1949 } 1950 1951 static int dw_hdmi_read_edid(struct dw_hdmi *hdmi, 1952 int block, unsigned char *buff) 1953 { 1954 int i = 0, n = 0, index = 0, ret = -1, trytime = 2; 1955 int offset = (block % 2) * 0x80; 1956 int interrupt = 0; 1957 1958 rockchip_dw_hdmi_i2cm_reset(hdmi); 1959 1960 /* Set DDC I2C CLK which divided from DDC_CLK to 100KHz. */ 1961 rockchip_dw_hdmi_i2cm_clk_init(hdmi); 1962 1963 /* Enable I2C interrupt for reading edid */ 1964 rockchip_dw_hdmi_i2cm_mask_int(hdmi, 0); 1965 1966 hdmi_writeb(hdmi, DDC_I2C_EDID_ADDR, HDMI_I2CM_SLAVE); 1967 hdmi_writeb(hdmi, DDC_I2C_SEG_ADDR, HDMI_I2CM_SEGADDR); 1968 hdmi_writeb(hdmi, block / 2, HDMI_I2CM_SEGPTR); 1969 1970 while (trytime--) { 1971 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) { 1972 hdmi_writeb(hdmi, offset + 8 * n, HDMI_I2CM_ADDRESS); 1973 /*enable extend sequential read operation*/ 1974 if (block == 0) 1975 hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8, 1976 HDMI_I2CM_OPERATION); 1977 else 1978 hdmi_writeb(hdmi, 1979 HDMI_I2CM_OPERATION_READ8_EXT, 1980 HDMI_I2CM_OPERATION); 1981 1982 i = 20; 1983 while (i--) { 1984 mdelay(1); 1985 interrupt = hdmi_readb(hdmi, 1986 HDMI_IH_I2CM_STAT0); 1987 if (interrupt) { 1988 hdmi_writeb(hdmi, 1989 interrupt, 1990 HDMI_IH_I2CM_STAT0); 1991 } 1992 1993 if (interrupt & 1994 (m_SCDC_READREQ | 1995 m_I2CM_DONE | 1996 m_I2CM_ERROR)) 1997 break; 1998 mdelay(4); 1999 } 2000 2001 if (interrupt & m_I2CM_DONE) { 2002 for (index = 0; index < 8; index++) 2003 buff[8 * n + index] = 2004 hdmi_readb(hdmi, HDMI_I2CM_READ_BUFF0 2005 + index); 2006 2007 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) { 2008 ret = 0; 2009 printf("[%s] edid read success\n", 2010 __func__); 2011 goto exit; 2012 } 2013 continue; 2014 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) { 2015 printf("[%s] edid read error\n", __func__); 2016 rockchip_dw_hdmi_i2cm_reset(hdmi); 2017 break; 2018 } 2019 } 2020 2021 printf("[%s] edid try times %d\n", __func__, trytime); 2022 mdelay(100); 2023 } 2024 2025 exit: 2026 /* Disable I2C interrupt */ 2027 rockchip_dw_hdmi_i2cm_mask_int(hdmi, 1); 2028 return ret; 2029 } 2030 2031 static int drm_do_get_edid(struct dw_hdmi *hdmi, u8 *edid) 2032 { 2033 int i, j, block_num, ret; 2034 2035 /* base block fetch */ 2036 for (i = 0; i < 3; i++) { 2037 ret = dw_hdmi_read_edid(hdmi, 0, edid); 2038 if (!ret) 2039 break; 2040 } 2041 2042 if (ret) { 2043 printf("get base block failed\n"); 2044 goto err; 2045 } 2046 2047 /* get the number of extensions */ 2048 block_num = edid[0x7e]; 2049 2050 for (j = 1; j <= block_num; j++) { 2051 for (i = 0; i < 3; i++) { 2052 ret = dw_hdmi_read_edid(hdmi, j, &edid[0x80 * j]); 2053 if (!ret) 2054 break; 2055 } 2056 } 2057 2058 if (ret) { 2059 printf("get extensions failed\n"); 2060 goto err; 2061 } 2062 2063 return 0; 2064 2065 err: 2066 memset(edid, 0, HDMI_EDID_BLOCK_SIZE); 2067 return -EFAULT; 2068 } 2069 2070 void dw_hdmi_audio_enable(struct dw_hdmi *hdmi) 2071 { 2072 hdmi->audio_enable = true; 2073 hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); 2074 } 2075 2076 void dw_hdmi_audio_disable(struct dw_hdmi *hdmi) 2077 { 2078 hdmi->audio_enable = false; 2079 hdmi_set_cts_n(hdmi, hdmi->audio_cts, 0); 2080 } 2081 2082 int rockchip_dw_hdmi_init(struct display_state *state) 2083 { 2084 struct connector_state *conn_state = &state->conn_state; 2085 const struct rockchip_connector *connector = conn_state->connector; 2086 const struct dw_hdmi_plat_data *pdata = connector->data; 2087 struct crtc_state *crtc_state = &state->crtc_state; 2088 struct dw_hdmi *hdmi; 2089 struct drm_display_mode *mode_buf; 2090 int hdmi_node = conn_state->node; 2091 u32 val; 2092 2093 hdmi = malloc(sizeof(struct dw_hdmi)); 2094 if (!hdmi) 2095 return -ENOMEM; 2096 2097 memset(hdmi, 0, sizeof(struct dw_hdmi)); 2098 2099 mode_buf = malloc(MODE_LEN * sizeof(struct drm_display_mode)); 2100 if (!mode_buf) 2101 return -ENOMEM; 2102 memset(mode_buf, 0, MODE_LEN * sizeof(struct drm_display_mode)); 2103 2104 hdmi->regs = (void *)fdtdec_get_addr_size_auto_noparent(state->blob, 2105 hdmi_node, "reg", 0, NULL, false); 2106 hdmi->io_width = fdtdec_get_int(state->blob, hdmi_node, 2107 "reg-io-width", -1); 2108 hdmi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); 2109 if (hdmi->grf <= 0) { 2110 printf("%s: Get syscon grf failed (ret=%p)\n", 2111 __func__, hdmi->grf); 2112 return -ENXIO; 2113 } 2114 2115 dw_hdmi_set_reg_wr(hdmi); 2116 2117 if (crtc_state->crtc_id) 2118 val = ((1 << pdata->vop_sel_bit) | 2119 (1 << (16 + pdata->vop_sel_bit))); 2120 else 2121 val = ((0 << pdata->vop_sel_bit) | 2122 (1 << (16 + pdata->vop_sel_bit))); 2123 writel(val, hdmi->grf + pdata->grf_vop_sel_reg); 2124 2125 conn_state->type = DRM_MODE_CONNECTOR_HDMIA; 2126 conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA; 2127 2128 hdmi->dev_type = pdata->dev_type; 2129 hdmi->plat_data = pdata; 2130 hdmi->edid_data.mode_buf = mode_buf; 2131 hdmi->sample_rate = 48000; 2132 2133 conn_state->private = hdmi; 2134 dw_hdmi_detect_phy(hdmi); 2135 dw_hdmi_dev_init(hdmi); 2136 2137 return 0; 2138 } 2139 2140 void rockchip_dw_hdmi_deinit(struct display_state *state) 2141 { 2142 struct connector_state *conn_state = &state->conn_state; 2143 struct dw_hdmi *hdmi = conn_state->private; 2144 2145 if (hdmi->edid_data.mode_buf) 2146 free(hdmi->edid_data.mode_buf); 2147 if (hdmi) 2148 free(hdmi); 2149 } 2150 2151 int rockchip_dw_hdmi_prepare(struct display_state *state) 2152 { 2153 return 0; 2154 } 2155 2156 int rockchip_dw_hdmi_enable(struct display_state *state) 2157 { 2158 struct connector_state *conn_state = &state->conn_state; 2159 struct drm_display_mode *mode = &conn_state->mode; 2160 struct dw_hdmi *hdmi = conn_state->private; 2161 2162 if (!hdmi) 2163 return -EFAULT; 2164 2165 dw_hdmi_setup(hdmi, mode); 2166 2167 return 0; 2168 } 2169 2170 int rockchip_dw_hdmi_disable(struct display_state *state) 2171 { 2172 struct connector_state *conn_state = &state->conn_state; 2173 struct dw_hdmi *hdmi = conn_state->private; 2174 2175 dw_hdmi_disable(hdmi); 2176 return 0; 2177 } 2178 2179 int rockchip_dw_hdmi_get_timing(struct display_state *state) 2180 { 2181 int ret; 2182 struct connector_state *conn_state = &state->conn_state; 2183 struct drm_display_mode *mode = &conn_state->mode; 2184 struct dw_hdmi *hdmi = conn_state->private; 2185 2186 if (!hdmi) 2187 return -EFAULT; 2188 ret = drm_do_get_edid(hdmi, conn_state->edid); 2189 if (!ret) { 2190 ret = drm_add_edid_modes(&hdmi->edid_data, conn_state->edid); 2191 2192 if (ret > 0) { 2193 hdmi->sink_is_hdmi = 2194 drm_detect_hdmi_monitor(conn_state->edid); 2195 hdmi->sink_has_audio = false; 2196 *mode = *hdmi->edid_data.preferred_mode; 2197 hdmi->vic = drm_match_cea_mode(mode); 2198 2199 return 0; 2200 } 2201 } 2202 2203 /* if can't get edid timing, use default resolution. */ 2204 printf("can't get edid timing\n"); 2205 hdmi->vic = HDMI_VIDEO_DEFAULT_MODE; 2206 hdmi->sink_is_hdmi = true; 2207 hdmi->sink_has_audio = false; 2208 mode->hdisplay = 1280; 2209 mode->hsync_start = 1390; 2210 mode->hsync_end = 1430; 2211 mode->htotal = 1650; 2212 mode->vdisplay = 720; 2213 mode->vsync_start = 725; 2214 mode->vsync_end = 730; 2215 mode->vtotal = 750; 2216 mode->clock = 74250; 2217 mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC; 2218 2219 return 0; 2220 } 2221 2222 int rockchip_dw_hdmi_detect(struct display_state *state) 2223 { 2224 int ret; 2225 struct connector_state *conn_state = &state->conn_state; 2226 struct dw_hdmi *hdmi = conn_state->private; 2227 2228 if (!hdmi) 2229 return -EFAULT; 2230 2231 ret = dw_hdmi_detect_hotplug(hdmi); 2232 2233 return ret; 2234 } 2235 2236 int rockchip_dw_hdmi_get_edid(struct display_state *state) 2237 { 2238 int ret; 2239 struct connector_state *conn_state = &state->conn_state; 2240 struct dw_hdmi *hdmi = conn_state->private; 2241 2242 ret = drm_do_get_edid(hdmi, conn_state->edid); 2243 2244 return ret; 2245 } 2246 2247