1/* 2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * SH-Mobile High-Definition Multimedia Interface (HDMI) driver 10 * for SLISHDMI13T and SLIPHDMIT IP cores 11 * 12 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> 13 */ 14 15#include <linux/component.h> 16#include <linux/irq.h> 17#include <linux/delay.h> 18#include <linux/err.h> 19#include <linux/clk.h> 20#include <linux/hdmi.h> 21#include <linux/regmap.h> 22#include <linux/mfd/syscon.h> 23#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> 24#include <linux/of_device.h> 25 26#include <drm/drmP.h> 27#include <drm/drm_crtc_helper.h> 28#include <drm/drm_edid.h> 29#include <drm/drm_encoder_slave.h> 30#include <video/imx-ipu-v3.h> 31 32#include "imx-hdmi.h" 33#include "imx-drm.h" 34 35#define HDMI_EDID_LEN 512 36 37#define RGB 0 38#define YCBCR444 1 39#define YCBCR422_16BITS 2 40#define YCBCR422_8BITS 3 41#define XVYCC444 4 42 43enum hdmi_datamap { 44 RGB444_8B = 0x01, 45 RGB444_10B = 0x03, 46 RGB444_12B = 0x05, 47 RGB444_16B = 0x07, 48 YCbCr444_8B = 0x09, 49 YCbCr444_10B = 0x0B, 50 YCbCr444_12B = 0x0D, 51 YCbCr444_16B = 0x0F, 52 YCbCr422_8B = 0x16, 53 YCbCr422_10B = 0x14, 54 YCbCr422_12B = 0x12, 55}; 56 57enum imx_hdmi_devtype { 58 IMX6Q_HDMI, 59 IMX6DL_HDMI, 60}; 61 62static const u16 csc_coeff_default[3][4] = { 63 { 0x2000, 0x0000, 0x0000, 0x0000 }, 64 { 0x0000, 0x2000, 0x0000, 0x0000 }, 65 { 0x0000, 0x0000, 0x2000, 0x0000 } 66}; 67 68static const u16 csc_coeff_rgb_out_eitu601[3][4] = { 69 { 0x2000, 0x6926, 0x74fd, 0x010e }, 70 { 0x2000, 0x2cdd, 0x0000, 0x7e9a }, 71 { 0x2000, 0x0000, 0x38b4, 0x7e3b } 72}; 73 74static const u16 csc_coeff_rgb_out_eitu709[3][4] = { 75 { 0x2000, 0x7106, 0x7a02, 0x00a7 }, 76 { 0x2000, 0x3264, 0x0000, 0x7e6d }, 77 { 0x2000, 0x0000, 0x3b61, 0x7e25 } 78}; 79 80static const u16 csc_coeff_rgb_in_eitu601[3][4] = { 81 { 0x2591, 0x1322, 0x074b, 0x0000 }, 82 { 0x6535, 0x2000, 0x7acc, 0x0200 }, 83 { 0x6acd, 0x7534, 0x2000, 0x0200 } 84}; 85 86static const u16 csc_coeff_rgb_in_eitu709[3][4] = { 87 { 0x2dc5, 0x0d9b, 0x049e, 0x0000 }, 88 { 0x62f0, 0x2000, 0x7d11, 0x0200 }, 89 { 0x6756, 0x78ab, 0x2000, 0x0200 } 90}; 91 92struct hdmi_vmode { 93 bool mdvi; 94 bool mhsyncpolarity; 95 bool mvsyncpolarity; 96 bool minterlaced; 97 bool mdataenablepolarity; 98 99 unsigned int mpixelclock; 100 unsigned int mpixelrepetitioninput; 101 unsigned int mpixelrepetitionoutput; 102}; 103 104struct hdmi_data_info { 105 unsigned int enc_in_format; 106 unsigned int enc_out_format; 107 unsigned int enc_color_depth; 108 unsigned int colorimetry; 109 unsigned int pix_repet_factor; 110 unsigned int hdcp_enable; 111 struct hdmi_vmode video_mode; 112}; 113 114struct imx_hdmi { 115 struct drm_connector connector; 116 struct drm_encoder encoder; 117 118 enum imx_hdmi_devtype dev_type; 119 struct device *dev; 120 struct clk *isfr_clk; 121 struct clk *iahb_clk; 122 123 struct hdmi_data_info hdmi_data; 124 int vic; 125 126 u8 edid[HDMI_EDID_LEN]; 127 bool cable_plugin; 128 129 bool phy_enabled; 130 struct drm_display_mode previous_mode; 131 132 struct regmap *regmap; 133 struct i2c_adapter *ddc; 134 void __iomem *regs; 135 136 unsigned int sample_rate; 137 int ratio; 138}; 139 140static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di) 141{ 142 regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, 143 IMX6Q_GPR3_HDMI_MUX_CTL_MASK, 144 ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); 145} 146 147static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset) 148{ 149 writeb(val, hdmi->regs + offset); 150} 151 152static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) 153{ 154 return readb(hdmi->regs + offset); 155} 156 157static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) 158{ 159 u8 val = hdmi_readb(hdmi, reg) & ~mask; 160 161 val |= data & mask; 162 hdmi_writeb(hdmi, val, reg); 163} 164 165static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, 166 u8 shift, u8 mask) 167{ 168 hdmi_modb(hdmi, data << shift, mask, reg); 169} 170 171static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, 172 unsigned int value) 173{ 174 hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); 175 hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2); 176 hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3); 177 178 /* nshift factor = 0 */ 179 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); 180} 181 182static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) 183{ 184 /* Must be set/cleared first */ 185 hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); 186 187 hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); 188 hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); 189 hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | 190 HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); 191} 192 193static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk, 194 unsigned int ratio) 195{ 196 unsigned int n = (128 * freq) / 1000; 197 198 switch (freq) { 199 case 32000: 200 if (pixel_clk == 25170000) 201 n = (ratio == 150) ? 9152 : 4576; 202 else if (pixel_clk == 27020000) 203 n = (ratio == 150) ? 8192 : 4096; 204 else if (pixel_clk == 74170000 || pixel_clk == 148350000) 205 n = 11648; 206 else 207 n = 4096; 208 break; 209 210 case 44100: 211 if (pixel_clk == 25170000) 212 n = 7007; 213 else if (pixel_clk == 74170000) 214 n = 17836; 215 else if (pixel_clk == 148350000) 216 n = (ratio == 150) ? 17836 : 8918; 217 else 218 n = 6272; 219 break; 220 221 case 48000: 222 if (pixel_clk == 25170000) 223 n = (ratio == 150) ? 9152 : 6864; 224 else if (pixel_clk == 27020000) 225 n = (ratio == 150) ? 8192 : 6144; 226 else if (pixel_clk == 74170000) 227 n = 11648; 228 else if (pixel_clk == 148350000) 229 n = (ratio == 150) ? 11648 : 5824; 230 else 231 n = 6144; 232 break; 233 234 case 88200: 235 n = hdmi_compute_n(44100, pixel_clk, ratio) * 2; 236 break; 237 238 case 96000: 239 n = hdmi_compute_n(48000, pixel_clk, ratio) * 2; 240 break; 241 242 case 176400: 243 n = hdmi_compute_n(44100, pixel_clk, ratio) * 4; 244 break; 245 246 case 192000: 247 n = hdmi_compute_n(48000, pixel_clk, ratio) * 4; 248 break; 249 250 default: 251 break; 252 } 253 254 return n; 255} 256 257static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, 258 unsigned int ratio) 259{ 260 unsigned int cts = 0; 261 262 pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq, 263 pixel_clk, ratio); 264 265 switch (freq) { 266 case 32000: 267 if (pixel_clk == 297000000) { 268 cts = 222750; 269 break; 270 } 271 case 48000: 272 case 96000: 273 case 192000: 274 switch (pixel_clk) { 275 case 25200000: 276 case 27000000: 277 case 54000000: 278 case 74250000: 279 case 148500000: 280 cts = pixel_clk / 1000; 281 break; 282 case 297000000: 283 cts = 247500; 284 break; 285 /* 286 * All other TMDS clocks are not supported by 287 * DWC_hdmi_tx. The TMDS clocks divided or 288 * multiplied by 1,001 coefficients are not 289 * supported. 290 */ 291 default: 292 break; 293 } 294 break; 295 case 44100: 296 case 88200: 297 case 176400: 298 switch (pixel_clk) { 299 case 25200000: 300 cts = 28000; 301 break; 302 case 27000000: 303 cts = 30000; 304 break; 305 case 54000000: 306 cts = 60000; 307 break; 308 case 74250000: 309 cts = 82500; 310 break; 311 case 148500000: 312 cts = 165000; 313 break; 314 case 297000000: 315 cts = 247500; 316 break; 317 default: 318 break; 319 } 320 break; 321 default: 322 break; 323 } 324 if (ratio == 100) 325 return cts; 326 return (cts * ratio) / 100; 327} 328 329static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, 330 unsigned long pixel_clk) 331{ 332 unsigned int clk_n, clk_cts; 333 334 clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk, 335 hdmi->ratio); 336 clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk, 337 hdmi->ratio); 338 339 if (!clk_cts) { 340 dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", 341 __func__, pixel_clk); 342 return; 343 } 344 345 dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", 346 __func__, hdmi->sample_rate, hdmi->ratio, 347 pixel_clk, clk_n, clk_cts); 348 349 hdmi_set_clock_regenerator_n(hdmi, clk_n); 350 hdmi_regenerate_cts(hdmi, clk_cts); 351} 352 353static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi) 354{ 355 hdmi_set_clk_regenerator(hdmi, 74250000); 356} 357 358static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi) 359{ 360 hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock); 361} 362 363/* 364 * this submodule is responsible for the video data synchronization. 365 * for example, for RGB 4:4:4 input, the data map is defined as 366 * pin{47~40} <==> R[7:0] 367 * pin{31~24} <==> G[7:0] 368 * pin{15~8} <==> B[7:0] 369 */ 370static void hdmi_video_sample(struct imx_hdmi *hdmi) 371{ 372 int color_format = 0; 373 u8 val; 374 375 if (hdmi->hdmi_data.enc_in_format == RGB) { 376 if (hdmi->hdmi_data.enc_color_depth == 8) 377 color_format = 0x01; 378 else if (hdmi->hdmi_data.enc_color_depth == 10) 379 color_format = 0x03; 380 else if (hdmi->hdmi_data.enc_color_depth == 12) 381 color_format = 0x05; 382 else if (hdmi->hdmi_data.enc_color_depth == 16) 383 color_format = 0x07; 384 else 385 return; 386 } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) { 387 if (hdmi->hdmi_data.enc_color_depth == 8) 388 color_format = 0x09; 389 else if (hdmi->hdmi_data.enc_color_depth == 10) 390 color_format = 0x0B; 391 else if (hdmi->hdmi_data.enc_color_depth == 12) 392 color_format = 0x0D; 393 else if (hdmi->hdmi_data.enc_color_depth == 16) 394 color_format = 0x0F; 395 else 396 return; 397 } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) { 398 if (hdmi->hdmi_data.enc_color_depth == 8) 399 color_format = 0x16; 400 else if (hdmi->hdmi_data.enc_color_depth == 10) 401 color_format = 0x14; 402 else if (hdmi->hdmi_data.enc_color_depth == 12) 403 color_format = 0x12; 404 else 405 return; 406 } 407 408 val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE | 409 ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) & 410 HDMI_TX_INVID0_VIDEO_MAPPING_MASK); 411 hdmi_writeb(hdmi, val, HDMI_TX_INVID0); 412 413 /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */ 414 val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE | 415 HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE | 416 HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE; 417 hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING); 418 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0); 419 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1); 420 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0); 421 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1); 422 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0); 423 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1); 424} 425 426static int is_color_space_conversion(struct imx_hdmi *hdmi) 427{ 428 return hdmi->hdmi_data.enc_in_format != hdmi->hdmi_data.enc_out_format; 429} 430 431static int is_color_space_decimation(struct imx_hdmi *hdmi) 432{ 433 if (hdmi->hdmi_data.enc_out_format != YCBCR422_8BITS) 434 return 0; 435 if (hdmi->hdmi_data.enc_in_format == RGB || 436 hdmi->hdmi_data.enc_in_format == YCBCR444) 437 return 1; 438 return 0; 439} 440 441static int is_color_space_interpolation(struct imx_hdmi *hdmi) 442{ 443 if (hdmi->hdmi_data.enc_in_format != YCBCR422_8BITS) 444 return 0; 445 if (hdmi->hdmi_data.enc_out_format == RGB || 446 hdmi->hdmi_data.enc_out_format == YCBCR444) 447 return 1; 448 return 0; 449} 450 451static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) 452{ 453 const u16 (*csc_coeff)[3][4] = &csc_coeff_default; 454 unsigned i; 455 u32 csc_scale = 1; 456 457 if (is_color_space_conversion(hdmi)) { 458 if (hdmi->hdmi_data.enc_out_format == RGB) { 459 if (hdmi->hdmi_data.colorimetry == 460 HDMI_COLORIMETRY_ITU_601) 461 csc_coeff = &csc_coeff_rgb_out_eitu601; 462 else 463 csc_coeff = &csc_coeff_rgb_out_eitu709; 464 } else if (hdmi->hdmi_data.enc_in_format == RGB) { 465 if (hdmi->hdmi_data.colorimetry == 466 HDMI_COLORIMETRY_ITU_601) 467 csc_coeff = &csc_coeff_rgb_in_eitu601; 468 else 469 csc_coeff = &csc_coeff_rgb_in_eitu709; 470 csc_scale = 0; 471 } 472 } 473 474 /* The CSC registers are sequential, alternating MSB then LSB */ 475 for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) { 476 u16 coeff_a = (*csc_coeff)[0][i]; 477 u16 coeff_b = (*csc_coeff)[1][i]; 478 u16 coeff_c = (*csc_coeff)[2][i]; 479 480 hdmi_writeb(hdmi, coeff_a & 0xff, 481 HDMI_CSC_COEF_A1_LSB + i * 2); 482 hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); 483 hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); 484 hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); 485 hdmi_writeb(hdmi, coeff_c & 0xff, 486 HDMI_CSC_COEF_C1_LSB + i * 2); 487 hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); 488 } 489 490 hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, 491 HDMI_CSC_SCALE); 492} 493 494static void hdmi_video_csc(struct imx_hdmi *hdmi) 495{ 496 int color_depth = 0; 497 int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; 498 int decimation = 0; 499 500 /* YCC422 interpolation to 444 mode */ 501 if (is_color_space_interpolation(hdmi)) 502 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1; 503 else if (is_color_space_decimation(hdmi)) 504 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3; 505 506 if (hdmi->hdmi_data.enc_color_depth == 8) 507 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP; 508 else if (hdmi->hdmi_data.enc_color_depth == 10) 509 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP; 510 else if (hdmi->hdmi_data.enc_color_depth == 12) 511 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP; 512 else if (hdmi->hdmi_data.enc_color_depth == 16) 513 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP; 514 else 515 return; 516 517 /* Configure the CSC registers */ 518 hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); 519 hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, 520 HDMI_CSC_SCALE); 521 522 imx_hdmi_update_csc_coeffs(hdmi); 523} 524 525/* 526 * HDMI video packetizer is used to packetize the data. 527 * for example, if input is YCC422 mode or repeater is used, 528 * data should be repacked this module can be bypassed. 529 */ 530static void hdmi_video_packetize(struct imx_hdmi *hdmi) 531{ 532 unsigned int color_depth = 0; 533 unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; 534 unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; 535 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; 536 u8 val, vp_conf; 537 538 if (hdmi_data->enc_out_format == RGB 539 || hdmi_data->enc_out_format == YCBCR444) { 540 if (!hdmi_data->enc_color_depth) 541 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; 542 else if (hdmi_data->enc_color_depth == 8) { 543 color_depth = 4; 544 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS; 545 } else if (hdmi_data->enc_color_depth == 10) 546 color_depth = 5; 547 else if (hdmi_data->enc_color_depth == 12) 548 color_depth = 6; 549 else if (hdmi_data->enc_color_depth == 16) 550 color_depth = 7; 551 else 552 return; 553 } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) { 554 if (!hdmi_data->enc_color_depth || 555 hdmi_data->enc_color_depth == 8) 556 remap_size = HDMI_VP_REMAP_YCC422_16bit; 557 else if (hdmi_data->enc_color_depth == 10) 558 remap_size = HDMI_VP_REMAP_YCC422_20bit; 559 else if (hdmi_data->enc_color_depth == 12) 560 remap_size = HDMI_VP_REMAP_YCC422_24bit; 561 else 562 return; 563 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422; 564 } else 565 return; 566 567 /* set the packetizer registers */ 568 val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) & 569 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) | 570 ((hdmi_data->pix_repet_factor << 571 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) & 572 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); 573 hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); 574 575 hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, 576 HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF); 577 578 /* Data from pixel repeater block */ 579 if (hdmi_data->pix_repet_factor > 1) { 580 vp_conf = HDMI_VP_CONF_PR_EN_ENABLE | 581 HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; 582 } else { /* data from packetizer block */ 583 vp_conf = HDMI_VP_CONF_PR_EN_DISABLE | 584 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; 585 } 586 587 hdmi_modb(hdmi, vp_conf, 588 HDMI_VP_CONF_PR_EN_MASK | 589 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); 590 591 hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, 592 HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF); 593 594 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); 595 596 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { 597 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | 598 HDMI_VP_CONF_PP_EN_ENABLE | 599 HDMI_VP_CONF_YCC422_EN_DISABLE; 600 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { 601 vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | 602 HDMI_VP_CONF_PP_EN_DISABLE | 603 HDMI_VP_CONF_YCC422_EN_ENABLE; 604 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { 605 vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE | 606 HDMI_VP_CONF_PP_EN_DISABLE | 607 HDMI_VP_CONF_YCC422_EN_DISABLE; 608 } else { 609 return; 610 } 611 612 hdmi_modb(hdmi, vp_conf, 613 HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK | 614 HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); 615 616 hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | 617 HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE, 618 HDMI_VP_STUFF_PP_STUFFING_MASK | 619 HDMI_VP_STUFF_YCC422_STUFFING_MASK, HDMI_VP_STUFF); 620 621 hdmi_modb(hdmi, output_select, HDMI_VP_CONF_OUTPUT_SELECTOR_MASK, 622 HDMI_VP_CONF); 623} 624 625static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi, 626 unsigned char bit) 627{ 628 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLR_OFFSET, 629 HDMI_PHY_TST0_TSTCLR_MASK, HDMI_PHY_TST0); 630} 631 632static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi, 633 unsigned char bit) 634{ 635 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTEN_OFFSET, 636 HDMI_PHY_TST0_TSTEN_MASK, HDMI_PHY_TST0); 637} 638 639static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi, 640 unsigned char bit) 641{ 642 hdmi_modb(hdmi, bit << HDMI_PHY_TST0_TSTCLK_OFFSET, 643 HDMI_PHY_TST0_TSTCLK_MASK, HDMI_PHY_TST0); 644} 645 646static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi, 647 unsigned char bit) 648{ 649 hdmi_writeb(hdmi, bit, HDMI_PHY_TST1); 650} 651 652static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi, 653 unsigned char bit) 654{ 655 hdmi_writeb(hdmi, bit, HDMI_PHY_TST2); 656} 657 658static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec) 659{ 660 while ((hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) { 661 if (msec-- == 0) 662 return false; 663 udelay(1000); 664 } 665 return true; 666} 667 668static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, 669 unsigned char addr) 670{ 671 hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0); 672 hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR); 673 hdmi_writeb(hdmi, (unsigned char)(data >> 8), 674 HDMI_PHY_I2CM_DATAO_1_ADDR); 675 hdmi_writeb(hdmi, (unsigned char)(data >> 0), 676 HDMI_PHY_I2CM_DATAO_0_ADDR); 677 hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE, 678 HDMI_PHY_I2CM_OPERATION_ADDR); 679 hdmi_phy_wait_i2c_done(hdmi, 1000); 680} 681 682static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data, 683 unsigned char addr) 684{ 685 __hdmi_phy_i2c_write(hdmi, data, addr); 686 return 0; 687} 688 689static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable) 690{ 691 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 692 HDMI_PHY_CONF0_PDZ_OFFSET, 693 HDMI_PHY_CONF0_PDZ_MASK); 694} 695 696static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable) 697{ 698 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 699 HDMI_PHY_CONF0_ENTMDS_OFFSET, 700 HDMI_PHY_CONF0_ENTMDS_MASK); 701} 702 703static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable) 704{ 705 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 706 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET, 707 HDMI_PHY_CONF0_GEN2_PDDQ_MASK); 708} 709 710static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable) 711{ 712 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 713 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET, 714 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK); 715} 716 717static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable) 718{ 719 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 720 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET, 721 HDMI_PHY_CONF0_SELDATAENPOL_MASK); 722} 723 724static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable) 725{ 726 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0, 727 HDMI_PHY_CONF0_SELDIPIF_OFFSET, 728 HDMI_PHY_CONF0_SELDIPIF_MASK); 729} 730 731enum { 732 RES_8, 733 RES_10, 734 RES_12, 735 RES_MAX, 736}; 737 738struct mpll_config { 739 unsigned long mpixelclock; 740 struct { 741 u16 cpce; 742 u16 gmp; 743 } res[RES_MAX]; 744}; 745 746static const struct mpll_config mpll_config[] = { 747 { 748 45250000, { 749 { 0x01e0, 0x0000 }, 750 { 0x21e1, 0x0000 }, 751 { 0x41e2, 0x0000 } 752 }, 753 }, { 754 92500000, { 755 { 0x0140, 0x0005 }, 756 { 0x2141, 0x0005 }, 757 { 0x4142, 0x0005 }, 758 }, 759 }, { 760 148500000, { 761 { 0x00a0, 0x000a }, 762 { 0x20a1, 0x000a }, 763 { 0x40a2, 0x000a }, 764 }, 765 }, { 766 ~0UL, { 767 { 0x00a0, 0x000a }, 768 { 0x2001, 0x000f }, 769 { 0x4002, 0x000f }, 770 }, 771 } 772}; 773 774struct curr_ctrl { 775 unsigned long mpixelclock; 776 u16 curr[RES_MAX]; 777}; 778 779static const struct curr_ctrl curr_ctrl[] = { 780 /* pixelclk bpp8 bpp10 bpp12 */ 781 { 782 54000000, { 0x091c, 0x091c, 0x06dc }, 783 }, { 784 58400000, { 0x091c, 0x06dc, 0x06dc }, 785 }, { 786 72000000, { 0x06dc, 0x06dc, 0x091c }, 787 }, { 788 74250000, { 0x06dc, 0x0b5c, 0x091c }, 789 }, { 790 118800000, { 0x091c, 0x091c, 0x06dc }, 791 }, { 792 216000000, { 0x06dc, 0x0b5c, 0x091c }, 793 } 794}; 795 796static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, 797 unsigned char res, int cscon) 798{ 799 unsigned res_idx, i; 800 u8 val, msec; 801 802 if (prep) 803 return -EINVAL; 804 805 switch (res) { 806 case 0: /* color resolution 0 is 8 bit colour depth */ 807 case 8: 808 res_idx = RES_8; 809 break; 810 case 10: 811 res_idx = RES_10; 812 break; 813 case 12: 814 res_idx = RES_12; 815 break; 816 default: 817 return -EINVAL; 818 } 819 820 /* Enable csc path */ 821 if (cscon) 822 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH; 823 else 824 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS; 825 826 hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL); 827 828 /* gen2 tx power off */ 829 imx_hdmi_phy_gen2_txpwron(hdmi, 0); 830 831 /* gen2 pddq */ 832 imx_hdmi_phy_gen2_pddq(hdmi, 1); 833 834 /* PHY reset */ 835 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ); 836 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ); 837 838 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST); 839 840 hdmi_phy_test_clear(hdmi, 1); 841 hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2, 842 HDMI_PHY_I2CM_SLAVE_ADDR); 843 hdmi_phy_test_clear(hdmi, 0); 844 845 /* PLL/MPLL Cfg - always match on final entry */ 846 for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++) 847 if (hdmi->hdmi_data.video_mode.mpixelclock <= 848 mpll_config[i].mpixelclock) 849 break; 850 851 hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06); 852 hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15); 853 854 for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++) 855 if (hdmi->hdmi_data.video_mode.mpixelclock <= 856 curr_ctrl[i].mpixelclock) 857 break; 858 859 if (i >= ARRAY_SIZE(curr_ctrl)) { 860 dev_err(hdmi->dev, 861 "Pixel clock %d - unsupported by HDMI\n", 862 hdmi->hdmi_data.video_mode.mpixelclock); 863 return -EINVAL; 864 } 865 866 /* CURRCTRL */ 867 hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10); 868 869 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */ 870 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17); 871 /* RESISTANCE TERM 133Ohm Cfg */ 872 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */ 873 /* PREEMP Cgf 0.00 */ 874 hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */ 875 /* TX/CK LVL 10 */ 876 hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */ 877 /* REMOVE CLK TERM */ 878 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */ 879 880 imx_hdmi_phy_enable_power(hdmi, 1); 881 882 /* toggle TMDS enable */ 883 imx_hdmi_phy_enable_tmds(hdmi, 0); 884 imx_hdmi_phy_enable_tmds(hdmi, 1); 885 886 /* gen2 tx power on */ 887 imx_hdmi_phy_gen2_txpwron(hdmi, 1); 888 imx_hdmi_phy_gen2_pddq(hdmi, 0); 889 890 /*Wait for PHY PLL lock */ 891 msec = 5; 892 do { 893 val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; 894 if (!val) 895 break; 896 897 if (msec == 0) { 898 dev_err(hdmi->dev, "PHY PLL not locked\n"); 899 return -ETIMEDOUT; 900 } 901 902 udelay(1000); 903 msec--; 904 } while (1); 905 906 return 0; 907} 908 909static int imx_hdmi_phy_init(struct imx_hdmi *hdmi) 910{ 911 int i, ret; 912 bool cscon = false; 913 914 /*check csc whether needed activated in HDMI mode */ 915 cscon = (is_color_space_conversion(hdmi) && 916 !hdmi->hdmi_data.video_mode.mdvi); 917 918 /* HDMI Phy spec says to do the phy initialization sequence twice */ 919 for (i = 0; i < 2; i++) { 920 imx_hdmi_phy_sel_data_en_pol(hdmi, 1); 921 imx_hdmi_phy_sel_interface_control(hdmi, 0); 922 imx_hdmi_phy_enable_tmds(hdmi, 0); 923 imx_hdmi_phy_enable_power(hdmi, 0); 924 925 /* Enable CSC */ 926 ret = hdmi_phy_configure(hdmi, 0, 8, cscon); 927 if (ret) 928 return ret; 929 } 930 931 hdmi->phy_enabled = true; 932 return 0; 933} 934 935static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi) 936{ 937 u8 de; 938 939 if (hdmi->hdmi_data.video_mode.mdataenablepolarity) 940 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH; 941 else 942 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW; 943 944 /* disable rx detect */ 945 hdmi_modb(hdmi, HDMI_A_HDCPCFG0_RXDETECT_DISABLE, 946 HDMI_A_HDCPCFG0_RXDETECT_MASK, HDMI_A_HDCPCFG0); 947 948 hdmi_modb(hdmi, de, HDMI_A_VIDPOLCFG_DATAENPOL_MASK, HDMI_A_VIDPOLCFG); 949 950 hdmi_modb(hdmi, HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE, 951 HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK, HDMI_A_HDCPCFG1); 952} 953 954static void hdmi_config_AVI(struct imx_hdmi *hdmi) 955{ 956 u8 val, pix_fmt, under_scan; 957 u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry; 958 bool aspect_16_9; 959 960 aspect_16_9 = false; /* FIXME */ 961 962 /* AVI Data Byte 1 */ 963 if (hdmi->hdmi_data.enc_out_format == YCBCR444) 964 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444; 965 else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) 966 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422; 967 else 968 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB; 969 970 under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA; 971 972 /* 973 * Active format identification data is present in the AVI InfoFrame. 974 * Under scan info, no bar data 975 */ 976 val = pix_fmt | under_scan | 977 HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT | 978 HDMI_FC_AVICONF0_BAR_DATA_NO_DATA; 979 980 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0); 981 982 /* AVI Data Byte 2 -Set the Aspect Ratio */ 983 if (aspect_16_9) { 984 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9; 985 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9; 986 } else { 987 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3; 988 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3; 989 } 990 991 /* Set up colorimetry */ 992 if (hdmi->hdmi_data.enc_out_format == XVYCC444) { 993 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO; 994 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) 995 ext_colorimetry = 996 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; 997 else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ 998 ext_colorimetry = 999 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709; 1000 } else if (hdmi->hdmi_data.enc_out_format != RGB) { 1001 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601) 1002 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE; 1003 else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/ 1004 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR; 1005 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; 1006 } else { /* Carries no data */ 1007 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA; 1008 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601; 1009 } 1010 1011 val = colorimetry | coded_ratio | act_ratio; 1012 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1); 1013 1014 /* AVI Data Byte 3 */ 1015 val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry | 1016 HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT | 1017 HDMI_FC_AVICONF2_SCALING_NONE; 1018 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2); 1019 1020 /* AVI Data Byte 4 */ 1021 hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID); 1022 1023 /* AVI Data Byte 5- set up input and output pixel repetition */ 1024 val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) << 1025 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) & 1026 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) | 1027 ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput << 1028 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) & 1029 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK); 1030 hdmi_writeb(hdmi, val, HDMI_FC_PRCONF); 1031 1032 /* IT Content and quantization range = don't care */ 1033 val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS | 1034 HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED; 1035 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3); 1036 1037 /* AVI Data Bytes 6-13 */ 1038 hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0); 1039 hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1); 1040 hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0); 1041 hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1); 1042 hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0); 1043 hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1); 1044 hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0); 1045 hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1); 1046} 1047 1048static void hdmi_av_composer(struct imx_hdmi *hdmi, 1049 const struct drm_display_mode *mode) 1050{ 1051 u8 inv_val; 1052 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode; 1053 int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len; 1054 1055 vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC); 1056 vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC); 1057 vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); 1058 vmode->mpixelclock = mode->clock * 1000; 1059 1060 dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); 1061 1062 /* Set up HDMI_FC_INVIDCONF */ 1063 inv_val = (hdmi->hdmi_data.hdcp_enable ? 1064 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE : 1065 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE); 1066 1067 inv_val |= (vmode->mvsyncpolarity ? 1068 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH : 1069 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW); 1070 1071 inv_val |= (vmode->mhsyncpolarity ? 1072 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH : 1073 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW); 1074 1075 inv_val |= (vmode->mdataenablepolarity ? 1076 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH : 1077 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW); 1078 1079 if (hdmi->vic == 39) 1080 inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH; 1081 else 1082 inv_val |= (vmode->minterlaced ? 1083 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH : 1084 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW); 1085 1086 inv_val |= (vmode->minterlaced ? 1087 HDMI_FC_INVIDCONF_IN_I_P_INTERLACED : 1088 HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE); 1089 1090 inv_val |= (vmode->mdvi ? 1091 HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE : 1092 HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE); 1093 1094 hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF); 1095 1096 /* Set up horizontal active pixel width */ 1097 hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1); 1098 hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0); 1099 1100 /* Set up vertical active lines */ 1101 hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1); 1102 hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0); 1103 1104 /* Set up horizontal blanking pixel region width */ 1105 hblank = mode->htotal - mode->hdisplay; 1106 hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1); 1107 hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0); 1108 1109 /* Set up vertical blanking pixel region width */ 1110 vblank = mode->vtotal - mode->vdisplay; 1111 hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK); 1112 1113 /* Set up HSYNC active edge delay width (in pixel clks) */ 1114 h_de_hs = mode->hsync_start - mode->hdisplay; 1115 hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1); 1116 hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0); 1117 1118 /* Set up VSYNC active edge delay (in lines) */ 1119 v_de_vs = mode->vsync_start - mode->vdisplay; 1120 hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY); 1121 1122 /* Set up HSYNC active pulse width (in pixel clks) */ 1123 hsync_len = mode->hsync_end - mode->hsync_start; 1124 hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); 1125 hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); 1126 1127 /* Set up VSYNC active edge delay (in lines) */ 1128 vsync_len = mode->vsync_end - mode->vsync_start; 1129 hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); 1130} 1131 1132static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi) 1133{ 1134 if (!hdmi->phy_enabled) 1135 return; 1136 1137 imx_hdmi_phy_enable_tmds(hdmi, 0); 1138 imx_hdmi_phy_enable_power(hdmi, 0); 1139 1140 hdmi->phy_enabled = false; 1141} 1142 1143/* HDMI Initialization Step B.4 */ 1144static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi) 1145{ 1146 u8 clkdis; 1147 1148 /* control period minimum duration */ 1149 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR); 1150 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR); 1151 hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC); 1152 1153 /* Set to fill TMDS data channels */ 1154 hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM); 1155 hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM); 1156 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM); 1157 1158 /* Enable pixel clock and tmds data path */ 1159 clkdis = 0x7F; 1160 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE; 1161 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1162 1163 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE; 1164 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1165 1166 /* Enable csc path */ 1167 if (is_color_space_conversion(hdmi)) { 1168 clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE; 1169 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS); 1170 } 1171} 1172 1173static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi) 1174{ 1175 hdmi_modb(hdmi, 0, HDMI_MC_CLKDIS_AUDCLK_DISABLE, HDMI_MC_CLKDIS); 1176} 1177 1178/* Workaround to clear the overflow condition */ 1179static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi) 1180{ 1181 int count; 1182 u8 val; 1183 1184 /* TMDS software reset */ 1185 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); 1186 1187 val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); 1188 if (hdmi->dev_type == IMX6DL_HDMI) { 1189 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); 1190 return; 1191 } 1192 1193 for (count = 0; count < 4; count++) 1194 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); 1195} 1196 1197static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi) 1198{ 1199 hdmi_writeb(hdmi, 0, HDMI_FC_MASK2); 1200 hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2); 1201} 1202 1203static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi) 1204{ 1205 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK, 1206 HDMI_IH_MUTE_FC_STAT2); 1207} 1208 1209static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) 1210{ 1211 int ret; 1212 1213 hdmi_disable_overflow_interrupts(hdmi); 1214 1215 hdmi->vic = drm_match_cea_mode(mode); 1216 1217 if (!hdmi->vic) { 1218 dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n"); 1219 hdmi->hdmi_data.video_mode.mdvi = true; 1220 } else { 1221 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic); 1222 hdmi->hdmi_data.video_mode.mdvi = false; 1223 } 1224 1225 if ((hdmi->vic == 6) || (hdmi->vic == 7) || 1226 (hdmi->vic == 21) || (hdmi->vic == 22) || 1227 (hdmi->vic == 2) || (hdmi->vic == 3) || 1228 (hdmi->vic == 17) || (hdmi->vic == 18)) 1229 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601; 1230 else 1231 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709; 1232 1233 if ((hdmi->vic == 10) || (hdmi->vic == 11) || 1234 (hdmi->vic == 12) || (hdmi->vic == 13) || 1235 (hdmi->vic == 14) || (hdmi->vic == 15) || 1236 (hdmi->vic == 25) || (hdmi->vic == 26) || 1237 (hdmi->vic == 27) || (hdmi->vic == 28) || 1238 (hdmi->vic == 29) || (hdmi->vic == 30) || 1239 (hdmi->vic == 35) || (hdmi->vic == 36) || 1240 (hdmi->vic == 37) || (hdmi->vic == 38)) 1241 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1; 1242 else 1243 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; 1244 1245 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; 1246 1247 /* TODO: Get input format from IPU (via FB driver interface) */ 1248 hdmi->hdmi_data.enc_in_format = RGB; 1249 1250 hdmi->hdmi_data.enc_out_format = RGB; 1251 1252 hdmi->hdmi_data.enc_color_depth = 8; 1253 hdmi->hdmi_data.pix_repet_factor = 0; 1254 hdmi->hdmi_data.hdcp_enable = 0; 1255 hdmi->hdmi_data.video_mode.mdataenablepolarity = true; 1256 1257 /* HDMI Initialization Step B.1 */ 1258 hdmi_av_composer(hdmi, mode); 1259 1260 /* HDMI Initializateion Step B.2 */ 1261 ret = imx_hdmi_phy_init(hdmi); 1262 if (ret) 1263 return ret; 1264 1265 /* HDMI Initialization Step B.3 */ 1266 imx_hdmi_enable_video_path(hdmi); 1267 1268 /* not for DVI mode */ 1269 if (hdmi->hdmi_data.video_mode.mdvi) 1270 dev_dbg(hdmi->dev, "%s DVI mode\n", __func__); 1271 else { 1272 dev_dbg(hdmi->dev, "%s CEA mode\n", __func__); 1273 1274 /* HDMI Initialization Step E - Configure audio */ 1275 hdmi_clk_regenerator_update_pixel_clock(hdmi); 1276 hdmi_enable_audio_clk(hdmi); 1277 1278 /* HDMI Initialization Step F - Configure AVI InfoFrame */ 1279 hdmi_config_AVI(hdmi); 1280 } 1281 1282 hdmi_video_packetize(hdmi); 1283 hdmi_video_csc(hdmi); 1284 hdmi_video_sample(hdmi); 1285 hdmi_tx_hdcp_config(hdmi); 1286 1287 imx_hdmi_clear_overflow(hdmi); 1288 if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi) 1289 hdmi_enable_overflow_interrupts(hdmi); 1290 1291 return 0; 1292} 1293 1294/* Wait until we are registered to enable interrupts */ 1295static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) 1296{ 1297 hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, 1298 HDMI_PHY_I2CM_INT_ADDR); 1299 1300 hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL | 1301 HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL, 1302 HDMI_PHY_I2CM_CTLINT_ADDR); 1303 1304 /* enable cable hot plug irq */ 1305 hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0); 1306 1307 /* Clear Hotplug interrupts */ 1308 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); 1309 1310 return 0; 1311} 1312 1313static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi) 1314{ 1315 u8 ih_mute; 1316 1317 /* 1318 * Boot up defaults are: 1319 * HDMI_IH_MUTE = 0x03 (disabled) 1320 * HDMI_IH_MUTE_* = 0x00 (enabled) 1321 * 1322 * Disable top level interrupt bits in HDMI block 1323 */ 1324 ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) | 1325 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | 1326 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT; 1327 1328 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); 1329 1330 /* by default mask all interrupts */ 1331 hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK); 1332 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0); 1333 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1); 1334 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2); 1335 hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0); 1336 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR); 1337 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR); 1338 hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT); 1339 hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT); 1340 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK); 1341 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK); 1342 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK); 1343 hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK); 1344 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT); 1345 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT); 1346 1347 /* Disable interrupts in the IH_MUTE_* registers */ 1348 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0); 1349 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1); 1350 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2); 1351 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0); 1352 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0); 1353 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0); 1354 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0); 1355 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0); 1356 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0); 1357 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0); 1358 1359 /* Enable top level interrupt bits in HDMI block */ 1360 ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT | 1361 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT); 1362 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE); 1363} 1364 1365static void imx_hdmi_poweron(struct imx_hdmi *hdmi) 1366{ 1367 imx_hdmi_setup(hdmi, &hdmi->previous_mode); 1368} 1369 1370static void imx_hdmi_poweroff(struct imx_hdmi *hdmi) 1371{ 1372 imx_hdmi_phy_disable(hdmi); 1373} 1374 1375static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector 1376 *connector, bool force) 1377{ 1378 struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, 1379 connector); 1380 1381 return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ? 1382 connector_status_connected : connector_status_disconnected; 1383} 1384 1385static int imx_hdmi_connector_get_modes(struct drm_connector *connector) 1386{ 1387 struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, 1388 connector); 1389 struct edid *edid; 1390 int ret; 1391 1392 if (!hdmi->ddc) 1393 return 0; 1394 1395 edid = drm_get_edid(connector, hdmi->ddc); 1396 if (edid) { 1397 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n", 1398 edid->width_cm, edid->height_cm); 1399 1400 drm_mode_connector_update_edid_property(connector, edid); 1401 ret = drm_add_edid_modes(connector, edid); 1402 kfree(edid); 1403 } else { 1404 dev_dbg(hdmi->dev, "failed to get edid\n"); 1405 } 1406 1407 return 0; 1408} 1409 1410static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector 1411 *connector) 1412{ 1413 struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, 1414 connector); 1415 1416 return &hdmi->encoder; 1417} 1418 1419static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder, 1420 struct drm_display_mode *mode, 1421 struct drm_display_mode *adjusted_mode) 1422{ 1423 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); 1424 1425 imx_hdmi_setup(hdmi, mode); 1426 1427 /* Store the display mode for plugin/DKMS poweron events */ 1428 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode)); 1429} 1430 1431static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder, 1432 const struct drm_display_mode *mode, 1433 struct drm_display_mode *adjusted_mode) 1434{ 1435 return true; 1436} 1437 1438static void imx_hdmi_encoder_disable(struct drm_encoder *encoder) 1439{ 1440} 1441 1442static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode) 1443{ 1444 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); 1445 1446 if (mode) 1447 imx_hdmi_poweroff(hdmi); 1448 else 1449 imx_hdmi_poweron(hdmi); 1450} 1451 1452static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) 1453{ 1454 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); 1455 1456 imx_hdmi_poweroff(hdmi); 1457 imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24); 1458} 1459 1460static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) 1461{ 1462 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); 1463 int mux = imx_drm_encoder_get_mux_id(hdmi->dev->of_node, encoder); 1464 1465 imx_hdmi_set_ipu_di_mux(hdmi, mux); 1466 1467 imx_hdmi_poweron(hdmi); 1468} 1469 1470static struct drm_encoder_funcs imx_hdmi_encoder_funcs = { 1471 .destroy = imx_drm_encoder_destroy, 1472}; 1473 1474static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = { 1475 .dpms = imx_hdmi_encoder_dpms, 1476 .prepare = imx_hdmi_encoder_prepare, 1477 .commit = imx_hdmi_encoder_commit, 1478 .mode_set = imx_hdmi_encoder_mode_set, 1479 .mode_fixup = imx_hdmi_encoder_mode_fixup, 1480 .disable = imx_hdmi_encoder_disable, 1481}; 1482 1483static struct drm_connector_funcs imx_hdmi_connector_funcs = { 1484 .dpms = drm_helper_connector_dpms, 1485 .fill_modes = drm_helper_probe_single_connector_modes, 1486 .detect = imx_hdmi_connector_detect, 1487 .destroy = imx_drm_connector_destroy, 1488}; 1489 1490static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { 1491 .get_modes = imx_hdmi_connector_get_modes, 1492 .best_encoder = imx_hdmi_connector_best_encoder, 1493}; 1494 1495static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id) 1496{ 1497 struct imx_hdmi *hdmi = dev_id; 1498 u8 intr_stat; 1499 1500 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); 1501 if (intr_stat) 1502 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); 1503 1504 return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE; 1505} 1506 1507static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) 1508{ 1509 struct imx_hdmi *hdmi = dev_id; 1510 u8 intr_stat; 1511 u8 phy_int_pol; 1512 1513 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); 1514 1515 phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0); 1516 1517 if (intr_stat & HDMI_IH_PHY_STAT0_HPD) { 1518 if (phy_int_pol & HDMI_PHY_HPD) { 1519 dev_dbg(hdmi->dev, "EVENT=plugin\n"); 1520 1521 hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0); 1522 1523 imx_hdmi_poweron(hdmi); 1524 } else { 1525 dev_dbg(hdmi->dev, "EVENT=plugout\n"); 1526 1527 hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD, 1528 HDMI_PHY_POL0); 1529 1530 imx_hdmi_poweroff(hdmi); 1531 } 1532 drm_helper_hpd_irq_event(hdmi->connector.dev); 1533 } 1534 1535 hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); 1536 hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); 1537 1538 return IRQ_HANDLED; 1539} 1540 1541static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi) 1542{ 1543 int ret; 1544 1545 ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder, 1546 hdmi->dev->of_node); 1547 if (ret) 1548 return ret; 1549 1550 hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; 1551 1552 drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs); 1553 drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs, 1554 DRM_MODE_ENCODER_TMDS); 1555 1556 drm_connector_helper_add(&hdmi->connector, 1557 &imx_hdmi_connector_helper_funcs); 1558 drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs, 1559 DRM_MODE_CONNECTOR_HDMIA); 1560 1561 hdmi->connector.encoder = &hdmi->encoder; 1562 1563 drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder); 1564 1565 return 0; 1566} 1567 1568static struct platform_device_id imx_hdmi_devtype[] = { 1569 { 1570 .name = "imx6q-hdmi", 1571 .driver_data = IMX6Q_HDMI, 1572 }, { 1573 .name = "imx6dl-hdmi", 1574 .driver_data = IMX6DL_HDMI, 1575 }, { /* sentinel */ } 1576}; 1577MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype); 1578 1579static const struct of_device_id imx_hdmi_dt_ids[] = { 1580{ .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], }, 1581{ .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], }, 1582{ /* sentinel */ } 1583}; 1584MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); 1585 1586static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) 1587{ 1588 struct platform_device *pdev = to_platform_device(dev); 1589 const struct of_device_id *of_id = 1590 of_match_device(imx_hdmi_dt_ids, dev); 1591 struct drm_device *drm = data; 1592 struct device_node *np = dev->of_node; 1593 struct device_node *ddc_node; 1594 struct imx_hdmi *hdmi; 1595 struct resource *iores; 1596 int ret, irq; 1597 1598 hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); 1599 if (!hdmi) 1600 return -ENOMEM; 1601 1602 hdmi->dev = dev; 1603 hdmi->sample_rate = 48000; 1604 hdmi->ratio = 100; 1605 1606 if (of_id) { 1607 const struct platform_device_id *device_id = of_id->data; 1608 1609 hdmi->dev_type = device_id->driver_data; 1610 } 1611 1612 ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); 1613 if (ddc_node) { 1614 hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); 1615 if (!hdmi->ddc) 1616 dev_dbg(hdmi->dev, "failed to read ddc node\n"); 1617 1618 of_node_put(ddc_node); 1619 } else { 1620 dev_dbg(hdmi->dev, "no ddc property found\n"); 1621 } 1622 1623 irq = platform_get_irq(pdev, 0); 1624 if (irq < 0) 1625 return irq; 1626 1627 ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq, 1628 imx_hdmi_irq, IRQF_SHARED, 1629 dev_name(dev), hdmi); 1630 if (ret) 1631 return ret; 1632 1633 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1634 hdmi->regs = devm_ioremap_resource(dev, iores); 1635 if (IS_ERR(hdmi->regs)) 1636 return PTR_ERR(hdmi->regs); 1637 1638 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); 1639 if (IS_ERR(hdmi->regmap)) 1640 return PTR_ERR(hdmi->regmap); 1641 1642 hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr"); 1643 if (IS_ERR(hdmi->isfr_clk)) { 1644 ret = PTR_ERR(hdmi->isfr_clk); 1645 dev_err(hdmi->dev, 1646 "Unable to get HDMI isfr clk: %d\n", ret); 1647 return ret; 1648 } 1649 1650 ret = clk_prepare_enable(hdmi->isfr_clk); 1651 if (ret) { 1652 dev_err(hdmi->dev, 1653 "Cannot enable HDMI isfr clock: %d\n", ret); 1654 return ret; 1655 } 1656 1657 hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb"); 1658 if (IS_ERR(hdmi->iahb_clk)) { 1659 ret = PTR_ERR(hdmi->iahb_clk); 1660 dev_err(hdmi->dev, 1661 "Unable to get HDMI iahb clk: %d\n", ret); 1662 goto err_isfr; 1663 } 1664 1665 ret = clk_prepare_enable(hdmi->iahb_clk); 1666 if (ret) { 1667 dev_err(hdmi->dev, 1668 "Cannot enable HDMI iahb clock: %d\n", ret); 1669 goto err_isfr; 1670 } 1671 1672 /* Product and revision IDs */ 1673 dev_info(dev, 1674 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", 1675 hdmi_readb(hdmi, HDMI_DESIGN_ID), 1676 hdmi_readb(hdmi, HDMI_REVISION_ID), 1677 hdmi_readb(hdmi, HDMI_PRODUCT_ID0), 1678 hdmi_readb(hdmi, HDMI_PRODUCT_ID1)); 1679 1680 initialize_hdmi_ih_mutes(hdmi); 1681 1682 /* 1683 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator 1684 * N and cts values before enabling phy 1685 */ 1686 hdmi_init_clk_regenerator(hdmi); 1687 1688 /* 1689 * Configure registers related to HDMI interrupt 1690 * generation before registering IRQ. 1691 */ 1692 hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0); 1693 1694 /* Clear Hotplug interrupts */ 1695 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); 1696 1697 ret = imx_hdmi_fb_registered(hdmi); 1698 if (ret) 1699 goto err_iahb; 1700 1701 ret = imx_hdmi_register(drm, hdmi); 1702 if (ret) 1703 goto err_iahb; 1704 1705 /* Unmute interrupts */ 1706 hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); 1707 1708 dev_set_drvdata(dev, hdmi); 1709 1710 return 0; 1711 1712err_iahb: 1713 clk_disable_unprepare(hdmi->iahb_clk); 1714err_isfr: 1715 clk_disable_unprepare(hdmi->isfr_clk); 1716 1717 return ret; 1718} 1719 1720static void imx_hdmi_unbind(struct device *dev, struct device *master, 1721 void *data) 1722{ 1723 struct imx_hdmi *hdmi = dev_get_drvdata(dev); 1724 1725 /* Disable all interrupts */ 1726 hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); 1727 1728 hdmi->connector.funcs->destroy(&hdmi->connector); 1729 hdmi->encoder.funcs->destroy(&hdmi->encoder); 1730 1731 clk_disable_unprepare(hdmi->iahb_clk); 1732 clk_disable_unprepare(hdmi->isfr_clk); 1733 i2c_put_adapter(hdmi->ddc); 1734} 1735 1736static const struct component_ops hdmi_ops = { 1737 .bind = imx_hdmi_bind, 1738 .unbind = imx_hdmi_unbind, 1739}; 1740 1741static int imx_hdmi_platform_probe(struct platform_device *pdev) 1742{ 1743 return component_add(&pdev->dev, &hdmi_ops); 1744} 1745 1746static int imx_hdmi_platform_remove(struct platform_device *pdev) 1747{ 1748 component_del(&pdev->dev, &hdmi_ops); 1749 return 0; 1750} 1751 1752static struct platform_driver imx_hdmi_driver = { 1753 .probe = imx_hdmi_platform_probe, 1754 .remove = imx_hdmi_platform_remove, 1755 .driver = { 1756 .name = "imx-hdmi", 1757 .owner = THIS_MODULE, 1758 .of_match_table = imx_hdmi_dt_ids, 1759 }, 1760}; 1761 1762module_platform_driver(imx_hdmi_driver); 1763 1764MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); 1765MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver"); 1766MODULE_LICENSE("GPL"); 1767MODULE_ALIAS("platform:imx-hdmi"); 1768