PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / staging / imx-drm / imx-hdmi.c
blob62ce0e86f14b50cfe7392bc5b47dd8871616af2b
1 /*
2 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
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.
9 * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
10 * for SLISHDMI13T and SLIPHDMIT IP cores
12 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
15 #include <linux/irq.h>
16 #include <linux/delay.h>
17 #include <linux/err.h>
18 #include <linux/clk.h>
19 #include <linux/hdmi.h>
20 #include <linux/regmap.h>
21 #include <linux/mfd/syscon.h>
22 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
23 #include <linux/of_device.h>
25 #include <drm/drmP.h>
26 #include <drm/drm_crtc_helper.h>
27 #include <drm/drm_edid.h>
28 #include <drm/drm_encoder_slave.h>
30 #include "ipu-v3/imx-ipu-v3.h"
31 #include "imx-hdmi.h"
32 #include "imx-drm.h"
34 #define HDMI_EDID_LEN 512
36 #define RGB 0
37 #define YCBCR444 1
38 #define YCBCR422_16BITS 2
39 #define YCBCR422_8BITS 3
40 #define XVYCC444 4
42 enum hdmi_datamap {
43 RGB444_8B = 0x01,
44 RGB444_10B = 0x03,
45 RGB444_12B = 0x05,
46 RGB444_16B = 0x07,
47 YCbCr444_8B = 0x09,
48 YCbCr444_10B = 0x0B,
49 YCbCr444_12B = 0x0D,
50 YCbCr444_16B = 0x0F,
51 YCbCr422_8B = 0x16,
52 YCbCr422_10B = 0x14,
53 YCbCr422_12B = 0x12,
56 enum imx_hdmi_devtype {
57 IMX6Q_HDMI,
58 IMX6DL_HDMI,
61 static const u16 csc_coeff_default[3][4] = {
62 { 0x2000, 0x0000, 0x0000, 0x0000 },
63 { 0x0000, 0x2000, 0x0000, 0x0000 },
64 { 0x0000, 0x0000, 0x2000, 0x0000 }
67 static const u16 csc_coeff_rgb_out_eitu601[3][4] = {
68 { 0x2000, 0x6926, 0x74fd, 0x010e },
69 { 0x2000, 0x2cdd, 0x0000, 0x7e9a },
70 { 0x2000, 0x0000, 0x38b4, 0x7e3b }
73 static const u16 csc_coeff_rgb_out_eitu709[3][4] = {
74 { 0x2000, 0x7106, 0x7a02, 0x00a7 },
75 { 0x2000, 0x3264, 0x0000, 0x7e6d },
76 { 0x2000, 0x0000, 0x3b61, 0x7e25 }
79 static const u16 csc_coeff_rgb_in_eitu601[3][4] = {
80 { 0x2591, 0x1322, 0x074b, 0x0000 },
81 { 0x6535, 0x2000, 0x7acc, 0x0200 },
82 { 0x6acd, 0x7534, 0x2000, 0x0200 }
85 static const u16 csc_coeff_rgb_in_eitu709[3][4] = {
86 { 0x2dc5, 0x0d9b, 0x049e, 0x0000 },
87 { 0x62f0, 0x2000, 0x7d11, 0x0200 },
88 { 0x6756, 0x78ab, 0x2000, 0x0200 }
91 struct hdmi_vmode {
92 bool mdvi;
93 bool mhsyncpolarity;
94 bool mvsyncpolarity;
95 bool minterlaced;
96 bool mdataenablepolarity;
98 unsigned int mpixelclock;
99 unsigned int mpixelrepetitioninput;
100 unsigned int mpixelrepetitionoutput;
103 struct hdmi_data_info {
104 unsigned int enc_in_format;
105 unsigned int enc_out_format;
106 unsigned int enc_color_depth;
107 unsigned int colorimetry;
108 unsigned int pix_repet_factor;
109 unsigned int hdcp_enable;
110 struct hdmi_vmode video_mode;
113 struct imx_hdmi {
114 struct drm_connector connector;
115 struct imx_drm_connector *imx_drm_connector;
116 struct drm_encoder encoder;
117 struct imx_drm_encoder *imx_drm_encoder;
119 enum imx_hdmi_devtype dev_type;
120 struct device *dev;
121 struct clk *isfr_clk;
122 struct clk *iahb_clk;
124 struct hdmi_data_info hdmi_data;
125 int vic;
127 u8 edid[HDMI_EDID_LEN];
128 bool cable_plugin;
130 bool phy_enabled;
131 struct drm_display_mode previous_mode;
133 struct regmap *regmap;
134 struct i2c_adapter *ddc;
135 void __iomem *regs;
137 unsigned long pixel_clk_rate;
138 unsigned int sample_rate;
139 int ratio;
142 static void imx_hdmi_set_ipu_di_mux(struct imx_hdmi *hdmi, int ipu_di)
144 regmap_update_bits(hdmi->regmap, IOMUXC_GPR3,
145 IMX6Q_GPR3_HDMI_MUX_CTL_MASK,
146 ipu_di << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT);
149 static inline void hdmi_writeb(struct imx_hdmi *hdmi, u8 val, int offset)
151 writeb(val, hdmi->regs + offset);
154 static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset)
156 return readb(hdmi->regs + offset);
159 static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg,
160 u8 shift, u8 mask)
162 u8 value = hdmi_readb(hdmi, reg) & ~mask;
163 value |= (data << shift) & mask;
164 hdmi_writeb(hdmi, value, reg);
167 static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
168 unsigned int value)
170 u8 val;
172 hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
173 hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
174 hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);
176 /* nshift factor = 0 */
177 val = hdmi_readb(hdmi, HDMI_AUD_CTS3);
178 val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
179 hdmi_writeb(hdmi, val, HDMI_AUD_CTS3);
182 static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
184 u8 val;
186 /* Must be set/cleared first */
187 val = hdmi_readb(hdmi, HDMI_AUD_CTS3);
188 val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
189 hdmi_writeb(hdmi, val, HDMI_AUD_CTS3);
191 hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
192 hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
193 hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
194 HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
197 static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk,
198 unsigned int ratio)
200 unsigned int n = (128 * freq) / 1000;
202 switch (freq) {
203 case 32000:
204 if (pixel_clk == 25170000)
205 n = (ratio == 150) ? 9152 : 4576;
206 else if (pixel_clk == 27020000)
207 n = (ratio == 150) ? 8192 : 4096;
208 else if (pixel_clk == 74170000 || pixel_clk == 148350000)
209 n = 11648;
210 else
211 n = 4096;
212 break;
214 case 44100:
215 if (pixel_clk == 25170000)
216 n = 7007;
217 else if (pixel_clk == 74170000)
218 n = 17836;
219 else if (pixel_clk == 148350000)
220 n = (ratio == 150) ? 17836 : 8918;
221 else
222 n = 6272;
223 break;
225 case 48000:
226 if (pixel_clk == 25170000)
227 n = (ratio == 150) ? 9152 : 6864;
228 else if (pixel_clk == 27020000)
229 n = (ratio == 150) ? 8192 : 6144;
230 else if (pixel_clk == 74170000)
231 n = 11648;
232 else if (pixel_clk == 148350000)
233 n = (ratio == 150) ? 11648 : 5824;
234 else
235 n = 6144;
236 break;
238 case 88200:
239 n = hdmi_compute_n(44100, pixel_clk, ratio) * 2;
240 break;
242 case 96000:
243 n = hdmi_compute_n(48000, pixel_clk, ratio) * 2;
244 break;
246 case 176400:
247 n = hdmi_compute_n(44100, pixel_clk, ratio) * 4;
248 break;
250 case 192000:
251 n = hdmi_compute_n(48000, pixel_clk, ratio) * 4;
252 break;
254 default:
255 break;
258 return n;
261 static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk,
262 unsigned int ratio)
264 unsigned int cts = 0;
266 pr_debug("%s: freq: %d pixel_clk: %ld ratio: %d\n", __func__, freq,
267 pixel_clk, ratio);
269 switch (freq) {
270 case 32000:
271 if (pixel_clk == 297000000) {
272 cts = 222750;
273 break;
275 case 48000:
276 case 96000:
277 case 192000:
278 switch (pixel_clk) {
279 case 25200000:
280 case 27000000:
281 case 54000000:
282 case 74250000:
283 case 148500000:
284 cts = pixel_clk / 1000;
285 break;
286 case 297000000:
287 cts = 247500;
288 break;
290 * All other TMDS clocks are not supported by
291 * DWC_hdmi_tx. The TMDS clocks divided or
292 * multiplied by 1,001 coefficients are not
293 * supported.
295 default:
296 break;
298 break;
299 case 44100:
300 case 88200:
301 case 176400:
302 switch (pixel_clk) {
303 case 25200000:
304 cts = 28000;
305 break;
306 case 27000000:
307 cts = 30000;
308 break;
309 case 54000000:
310 cts = 60000;
311 break;
312 case 74250000:
313 cts = 82500;
314 break;
315 case 148500000:
316 cts = 165000;
317 break;
318 case 297000000:
319 cts = 247500;
320 break;
321 default:
322 break;
324 break;
325 default:
326 break;
328 if (ratio == 100)
329 return cts;
330 else
331 return (cts * ratio) / 100;
334 static void hdmi_get_pixel_clk(struct imx_hdmi *hdmi)
336 unsigned long rate;
338 rate = 65000000; /* FIXME */
340 if (rate)
341 hdmi->pixel_clk_rate = rate;
344 static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi)
346 unsigned int clk_n, clk_cts;
348 clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate,
349 hdmi->ratio);
350 clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate,
351 hdmi->ratio);
353 if (!clk_cts) {
354 dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
355 __func__, hdmi->pixel_clk_rate);
356 return;
359 dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n",
360 __func__, hdmi->sample_rate, hdmi->ratio,
361 hdmi->pixel_clk_rate, clk_n, clk_cts);
363 hdmi_set_clock_regenerator_n(hdmi, clk_n);
364 hdmi_regenerate_cts(hdmi, clk_cts);
367 static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi)
369 unsigned int clk_n, clk_cts;
371 clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate,
372 hdmi->ratio);
373 clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate,
374 hdmi->ratio);
376 if (!clk_cts) {
377 dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n",
378 __func__, hdmi->pixel_clk_rate);
379 return;
382 dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n",
383 __func__, hdmi->sample_rate, hdmi->ratio,
384 hdmi->pixel_clk_rate, clk_n, clk_cts);
386 hdmi_set_clock_regenerator_n(hdmi, clk_n);
387 hdmi_regenerate_cts(hdmi, clk_cts);
390 static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi)
392 /* Get pixel clock from ipu */
393 hdmi_get_pixel_clk(hdmi);
394 hdmi_set_clk_regenerator(hdmi);
398 * this submodule is responsible for the video data synchronization.
399 * for example, for RGB 4:4:4 input, the data map is defined as
400 * pin{47~40} <==> R[7:0]
401 * pin{31~24} <==> G[7:0]
402 * pin{15~8} <==> B[7:0]
404 static void hdmi_video_sample(struct imx_hdmi *hdmi)
406 int color_format = 0;
407 u8 val;
409 if (hdmi->hdmi_data.enc_in_format == RGB) {
410 if (hdmi->hdmi_data.enc_color_depth == 8)
411 color_format = 0x01;
412 else if (hdmi->hdmi_data.enc_color_depth == 10)
413 color_format = 0x03;
414 else if (hdmi->hdmi_data.enc_color_depth == 12)
415 color_format = 0x05;
416 else if (hdmi->hdmi_data.enc_color_depth == 16)
417 color_format = 0x07;
418 else
419 return;
420 } else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
421 if (hdmi->hdmi_data.enc_color_depth == 8)
422 color_format = 0x09;
423 else if (hdmi->hdmi_data.enc_color_depth == 10)
424 color_format = 0x0B;
425 else if (hdmi->hdmi_data.enc_color_depth == 12)
426 color_format = 0x0D;
427 else if (hdmi->hdmi_data.enc_color_depth == 16)
428 color_format = 0x0F;
429 else
430 return;
431 } else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
432 if (hdmi->hdmi_data.enc_color_depth == 8)
433 color_format = 0x16;
434 else if (hdmi->hdmi_data.enc_color_depth == 10)
435 color_format = 0x14;
436 else if (hdmi->hdmi_data.enc_color_depth == 12)
437 color_format = 0x12;
438 else
439 return;
442 val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
443 ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
444 HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
445 hdmi_writeb(hdmi, val, HDMI_TX_INVID0);
447 /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
448 val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
449 HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
450 HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
451 hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
452 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
453 hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
454 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
455 hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
456 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
457 hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
460 static int is_color_space_conversion(struct imx_hdmi *hdmi)
462 return (hdmi->hdmi_data.enc_in_format !=
463 hdmi->hdmi_data.enc_out_format);
466 static int is_color_space_decimation(struct imx_hdmi *hdmi)
468 return ((hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS) &&
469 (hdmi->hdmi_data.enc_in_format == RGB ||
470 hdmi->hdmi_data.enc_in_format == YCBCR444));
473 static int is_color_space_interpolation(struct imx_hdmi *hdmi)
475 return ((hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) &&
476 (hdmi->hdmi_data.enc_out_format == RGB ||
477 hdmi->hdmi_data.enc_out_format == YCBCR444));
480 static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
482 const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
483 u32 csc_scale = 1;
484 u8 val;
486 if (is_color_space_conversion(hdmi)) {
487 if (hdmi->hdmi_data.enc_out_format == RGB) {
488 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
489 csc_coeff = &csc_coeff_rgb_out_eitu601;
490 else
491 csc_coeff = &csc_coeff_rgb_out_eitu709;
492 } else if (hdmi->hdmi_data.enc_in_format == RGB) {
493 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
494 csc_coeff = &csc_coeff_rgb_in_eitu601;
495 else
496 csc_coeff = &csc_coeff_rgb_in_eitu709;
497 csc_scale = 0;
501 hdmi_writeb(hdmi, ((*csc_coeff)[0][0] & 0xff), HDMI_CSC_COEF_A1_LSB);
502 hdmi_writeb(hdmi, ((*csc_coeff)[0][0] >> 8), HDMI_CSC_COEF_A1_MSB);
503 hdmi_writeb(hdmi, ((*csc_coeff)[0][1] & 0xff), HDMI_CSC_COEF_A2_LSB);
504 hdmi_writeb(hdmi, ((*csc_coeff)[0][1] >> 8), HDMI_CSC_COEF_A2_MSB);
505 hdmi_writeb(hdmi, ((*csc_coeff)[0][2] & 0xff), HDMI_CSC_COEF_A3_LSB);
506 hdmi_writeb(hdmi, ((*csc_coeff)[0][2] >> 8), HDMI_CSC_COEF_A3_MSB);
507 hdmi_writeb(hdmi, ((*csc_coeff)[0][3] & 0xff), HDMI_CSC_COEF_A4_LSB);
508 hdmi_writeb(hdmi, ((*csc_coeff)[0][3] >> 8), HDMI_CSC_COEF_A4_MSB);
510 hdmi_writeb(hdmi, ((*csc_coeff)[1][0] & 0xff), HDMI_CSC_COEF_B1_LSB);
511 hdmi_writeb(hdmi, ((*csc_coeff)[1][0] >> 8), HDMI_CSC_COEF_B1_MSB);
512 hdmi_writeb(hdmi, ((*csc_coeff)[1][1] & 0xff), HDMI_CSC_COEF_B2_LSB);
513 hdmi_writeb(hdmi, ((*csc_coeff)[1][1] >> 8), HDMI_CSC_COEF_B2_MSB);
514 hdmi_writeb(hdmi, ((*csc_coeff)[1][2] & 0xff), HDMI_CSC_COEF_B3_LSB);
515 hdmi_writeb(hdmi, ((*csc_coeff)[1][2] >> 8), HDMI_CSC_COEF_B3_MSB);
516 hdmi_writeb(hdmi, ((*csc_coeff)[1][3] & 0xff), HDMI_CSC_COEF_B4_LSB);
517 hdmi_writeb(hdmi, ((*csc_coeff)[1][3] >> 8), HDMI_CSC_COEF_B4_MSB);
519 hdmi_writeb(hdmi, ((*csc_coeff)[2][0] & 0xff), HDMI_CSC_COEF_C1_LSB);
520 hdmi_writeb(hdmi, ((*csc_coeff)[2][0] >> 8), HDMI_CSC_COEF_C1_MSB);
521 hdmi_writeb(hdmi, ((*csc_coeff)[2][1] & 0xff), HDMI_CSC_COEF_C2_LSB);
522 hdmi_writeb(hdmi, ((*csc_coeff)[2][1] >> 8), HDMI_CSC_COEF_C2_MSB);
523 hdmi_writeb(hdmi, ((*csc_coeff)[2][2] & 0xff), HDMI_CSC_COEF_C3_LSB);
524 hdmi_writeb(hdmi, ((*csc_coeff)[2][2] >> 8), HDMI_CSC_COEF_C3_MSB);
525 hdmi_writeb(hdmi, ((*csc_coeff)[2][3] & 0xff), HDMI_CSC_COEF_C4_LSB);
526 hdmi_writeb(hdmi, ((*csc_coeff)[2][3] >> 8), HDMI_CSC_COEF_C4_MSB);
528 val = hdmi_readb(hdmi, HDMI_CSC_SCALE);
529 val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
530 val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
531 hdmi_writeb(hdmi, val, HDMI_CSC_SCALE);
534 static void hdmi_video_csc(struct imx_hdmi *hdmi)
536 int color_depth = 0;
537 int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
538 int decimation = 0;
539 u8 val;
541 /* YCC422 interpolation to 444 mode */
542 if (is_color_space_interpolation(hdmi))
543 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
544 else if (is_color_space_decimation(hdmi))
545 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;
547 if (hdmi->hdmi_data.enc_color_depth == 8)
548 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
549 else if (hdmi->hdmi_data.enc_color_depth == 10)
550 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
551 else if (hdmi->hdmi_data.enc_color_depth == 12)
552 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
553 else if (hdmi->hdmi_data.enc_color_depth == 16)
554 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
555 else
556 return;
558 /* Configure the CSC registers */
559 hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
560 val = hdmi_readb(hdmi, HDMI_CSC_SCALE);
561 val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
562 val |= color_depth;
563 hdmi_writeb(hdmi, val, HDMI_CSC_SCALE);
565 imx_hdmi_update_csc_coeffs(hdmi);
569 * HDMI video packetizer is used to packetize the data.
570 * for example, if input is YCC422 mode or repeater is used,
571 * data should be repacked this module can be bypassed.
573 static void hdmi_video_packetize(struct imx_hdmi *hdmi)
575 unsigned int color_depth = 0;
576 unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
577 unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
578 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
579 u8 val;
581 if (hdmi_data->enc_out_format == RGB
582 || hdmi_data->enc_out_format == YCBCR444) {
583 if (!hdmi_data->enc_color_depth)
584 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
585 else if (hdmi_data->enc_color_depth == 8) {
586 color_depth = 4;
587 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
588 } else if (hdmi_data->enc_color_depth == 10)
589 color_depth = 5;
590 else if (hdmi_data->enc_color_depth == 12)
591 color_depth = 6;
592 else if (hdmi_data->enc_color_depth == 16)
593 color_depth = 7;
594 else
595 return;
596 } else if (hdmi_data->enc_out_format == YCBCR422_8BITS) {
597 if (!hdmi_data->enc_color_depth ||
598 hdmi_data->enc_color_depth == 8)
599 remap_size = HDMI_VP_REMAP_YCC422_16bit;
600 else if (hdmi_data->enc_color_depth == 10)
601 remap_size = HDMI_VP_REMAP_YCC422_20bit;
602 else if (hdmi_data->enc_color_depth == 12)
603 remap_size = HDMI_VP_REMAP_YCC422_24bit;
604 else
605 return;
606 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
607 } else
608 return;
610 /* set the packetizer registers */
611 val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
612 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
613 ((hdmi_data->pix_repet_factor <<
614 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
615 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
616 hdmi_writeb(hdmi, val, HDMI_VP_PR_CD);
618 val = hdmi_readb(hdmi, HDMI_VP_STUFF);
619 val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
620 val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
621 hdmi_writeb(hdmi, val, HDMI_VP_STUFF);
623 /* Data from pixel repeater block */
624 if (hdmi_data->pix_repet_factor > 1) {
625 val = hdmi_readb(hdmi, HDMI_VP_CONF);
626 val &= ~(HDMI_VP_CONF_PR_EN_MASK |
627 HDMI_VP_CONF_BYPASS_SELECT_MASK);
628 val |= HDMI_VP_CONF_PR_EN_ENABLE |
629 HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
630 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
631 } else { /* data from packetizer block */
632 val = hdmi_readb(hdmi, HDMI_VP_CONF);
633 val &= ~(HDMI_VP_CONF_PR_EN_MASK |
634 HDMI_VP_CONF_BYPASS_SELECT_MASK);
635 val |= HDMI_VP_CONF_PR_EN_DISABLE |
636 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
637 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
640 val = hdmi_readb(hdmi, HDMI_VP_STUFF);
641 val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
642 val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
643 hdmi_writeb(hdmi, val, HDMI_VP_STUFF);
645 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
647 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
648 val = hdmi_readb(hdmi, HDMI_VP_CONF);
649 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
650 HDMI_VP_CONF_PP_EN_ENMASK |
651 HDMI_VP_CONF_YCC422_EN_MASK);
652 val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
653 HDMI_VP_CONF_PP_EN_ENABLE |
654 HDMI_VP_CONF_YCC422_EN_DISABLE;
655 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
656 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
657 val = hdmi_readb(hdmi, HDMI_VP_CONF);
658 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
659 HDMI_VP_CONF_PP_EN_ENMASK |
660 HDMI_VP_CONF_YCC422_EN_MASK);
661 val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
662 HDMI_VP_CONF_PP_EN_DISABLE |
663 HDMI_VP_CONF_YCC422_EN_ENABLE;
664 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
665 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
666 val = hdmi_readb(hdmi, HDMI_VP_CONF);
667 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
668 HDMI_VP_CONF_PP_EN_ENMASK |
669 HDMI_VP_CONF_YCC422_EN_MASK);
670 val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
671 HDMI_VP_CONF_PP_EN_DISABLE |
672 HDMI_VP_CONF_YCC422_EN_DISABLE;
673 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
674 } else {
675 return;
678 val = hdmi_readb(hdmi, HDMI_VP_STUFF);
679 val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
680 HDMI_VP_STUFF_YCC422_STUFFING_MASK);
681 val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
682 HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
683 hdmi_writeb(hdmi, val, HDMI_VP_STUFF);
685 val = hdmi_readb(hdmi, HDMI_VP_CONF);
686 val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
687 val |= output_select;
688 hdmi_writeb(hdmi, val, HDMI_VP_CONF);
691 static inline void hdmi_phy_test_clear(struct imx_hdmi *hdmi,
692 unsigned char bit)
694 u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0);
695 val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
696 val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
697 HDMI_PHY_TST0_TSTCLR_MASK;
698 hdmi_writeb(hdmi, val, HDMI_PHY_TST0);
701 static inline void hdmi_phy_test_enable(struct imx_hdmi *hdmi,
702 unsigned char bit)
704 u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0);
705 val &= ~HDMI_PHY_TST0_TSTEN_MASK;
706 val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
707 HDMI_PHY_TST0_TSTEN_MASK;
708 hdmi_writeb(hdmi, val, HDMI_PHY_TST0);
711 static inline void hdmi_phy_test_clock(struct imx_hdmi *hdmi,
712 unsigned char bit)
714 u8 val = hdmi_readb(hdmi, HDMI_PHY_TST0);
715 val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
716 val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
717 HDMI_PHY_TST0_TSTCLK_MASK;
718 hdmi_writeb(hdmi, val, HDMI_PHY_TST0);
721 static inline void hdmi_phy_test_din(struct imx_hdmi *hdmi,
722 unsigned char bit)
724 hdmi_writeb(hdmi, bit, HDMI_PHY_TST1);
727 static inline void hdmi_phy_test_dout(struct imx_hdmi *hdmi,
728 unsigned char bit)
730 hdmi_writeb(hdmi, bit, HDMI_PHY_TST2);
733 static bool hdmi_phy_wait_i2c_done(struct imx_hdmi *hdmi, int msec)
735 unsigned char val = 0;
736 val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
737 while (!val) {
738 udelay(1000);
739 if (msec-- == 0)
740 return false;
741 val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3;
743 return true;
746 static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
747 unsigned char addr)
749 hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
750 hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
751 hdmi_writeb(hdmi, (unsigned char)(data >> 8),
752 HDMI_PHY_I2CM_DATAO_1_ADDR);
753 hdmi_writeb(hdmi, (unsigned char)(data >> 0),
754 HDMI_PHY_I2CM_DATAO_0_ADDR);
755 hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
756 HDMI_PHY_I2CM_OPERATION_ADDR);
757 hdmi_phy_wait_i2c_done(hdmi, 1000);
760 static int hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
761 unsigned char addr)
763 __hdmi_phy_i2c_write(hdmi, data, addr);
764 return 0;
767 static void imx_hdmi_phy_enable_power(struct imx_hdmi *hdmi, u8 enable)
769 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
770 HDMI_PHY_CONF0_PDZ_OFFSET,
771 HDMI_PHY_CONF0_PDZ_MASK);
774 static void imx_hdmi_phy_enable_tmds(struct imx_hdmi *hdmi, u8 enable)
776 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
777 HDMI_PHY_CONF0_ENTMDS_OFFSET,
778 HDMI_PHY_CONF0_ENTMDS_MASK);
781 static void imx_hdmi_phy_gen2_pddq(struct imx_hdmi *hdmi, u8 enable)
783 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
784 HDMI_PHY_CONF0_GEN2_PDDQ_OFFSET,
785 HDMI_PHY_CONF0_GEN2_PDDQ_MASK);
788 static void imx_hdmi_phy_gen2_txpwron(struct imx_hdmi *hdmi, u8 enable)
790 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
791 HDMI_PHY_CONF0_GEN2_TXPWRON_OFFSET,
792 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
795 static void imx_hdmi_phy_sel_data_en_pol(struct imx_hdmi *hdmi, u8 enable)
797 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
798 HDMI_PHY_CONF0_SELDATAENPOL_OFFSET,
799 HDMI_PHY_CONF0_SELDATAENPOL_MASK);
802 static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable)
804 hdmi_mask_writeb(hdmi, enable, HDMI_PHY_CONF0,
805 HDMI_PHY_CONF0_SELDIPIF_OFFSET,
806 HDMI_PHY_CONF0_SELDIPIF_MASK);
809 static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
810 unsigned char res, int cscon)
812 u8 val, msec;
814 /* color resolution 0 is 8 bit colour depth */
815 if (!res)
816 res = 8;
818 if (prep)
819 return -EINVAL;
820 else if (res != 8 && res != 12)
821 return -EINVAL;
823 /* Enable csc path */
824 if (cscon)
825 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
826 else
827 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
829 hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);
831 /* gen2 tx power off */
832 imx_hdmi_phy_gen2_txpwron(hdmi, 0);
834 /* gen2 pddq */
835 imx_hdmi_phy_gen2_pddq(hdmi, 1);
837 /* PHY reset */
838 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
839 hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
841 hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);
843 hdmi_phy_test_clear(hdmi, 1);
844 hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
845 HDMI_PHY_I2CM_SLAVE_ADDR);
846 hdmi_phy_test_clear(hdmi, 0);
848 if (hdmi->hdmi_data.video_mode.mpixelclock <= 45250000) {
849 switch (res) {
850 case 8:
851 /* PLL/MPLL Cfg */
852 hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
853 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
854 break;
855 case 10:
856 hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
857 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
858 break;
859 case 12:
860 hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
861 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
862 break;
863 default:
864 return -EINVAL;
866 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 92500000) {
867 switch (res) {
868 case 8:
869 hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
870 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
871 break;
872 case 10:
873 hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
874 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
875 break;
876 case 12:
877 hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
878 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
879 default:
880 return -EINVAL;
882 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 148500000) {
883 switch (res) {
884 case 8:
885 hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
886 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
887 break;
888 case 10:
889 hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
890 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
891 break;
892 case 12:
893 hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
894 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
895 default:
896 return -EINVAL;
898 } else {
899 switch (res) {
900 case 8:
901 hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
902 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
903 break;
904 case 10:
905 hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
906 hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
907 break;
908 case 12:
909 hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
910 hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
911 default:
912 return -EINVAL;
916 if (hdmi->hdmi_data.video_mode.mpixelclock <= 54000000) {
917 switch (res) {
918 case 8:
919 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
920 break;
921 case 10:
922 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
923 break;
924 case 12:
925 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
926 break;
927 default:
928 return -EINVAL;
930 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 58400000) {
931 switch (res) {
932 case 8:
933 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
934 break;
935 case 10:
936 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
937 break;
938 case 12:
939 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
940 break;
941 default:
942 return -EINVAL;
944 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 72000000) {
945 switch (res) {
946 case 8:
947 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
948 break;
949 case 10:
950 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
951 break;
952 case 12:
953 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
954 break;
955 default:
956 return -EINVAL;
958 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 74250000) {
959 switch (res) {
960 case 8:
961 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
962 break;
963 case 10:
964 hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
965 break;
966 case 12:
967 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
968 break;
969 default:
970 return -EINVAL;
972 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 118800000) {
973 switch (res) {
974 case 8:
975 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
976 break;
977 case 10:
978 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
979 break;
980 case 12:
981 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
982 break;
983 default:
984 return -EINVAL;
986 } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 216000000) {
987 switch (res) {
988 case 8:
989 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
990 break;
991 case 10:
992 hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
993 break;
994 case 12:
995 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
996 break;
997 default:
998 return -EINVAL;
1000 } else {
1001 dev_err(hdmi->dev,
1002 "Pixel clock %d - unsupported by HDMI\n",
1003 hdmi->hdmi_data.video_mode.mpixelclock);
1004 return -EINVAL;
1007 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
1008 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
1009 /* RESISTANCE TERM 133Ohm Cfg */
1010 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
1011 /* PREEMP Cgf 0.00 */
1012 hdmi_phy_i2c_write(hdmi, 0x800d, 0x09); /* CKSYMTXCTRL */
1013 /* TX/CK LVL 10 */
1014 hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E); /* VLEVCTRL */
1015 /* REMOVE CLK TERM */
1016 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
1018 imx_hdmi_phy_enable_power(hdmi, 1);
1020 /* toggle TMDS enable */
1021 imx_hdmi_phy_enable_tmds(hdmi, 0);
1022 imx_hdmi_phy_enable_tmds(hdmi, 1);
1024 /* gen2 tx power on */
1025 imx_hdmi_phy_gen2_txpwron(hdmi, 1);
1026 imx_hdmi_phy_gen2_pddq(hdmi, 0);
1028 /*Wait for PHY PLL lock */
1029 msec = 5;
1030 do {
1031 val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
1032 if (!val)
1033 break;
1035 if (msec == 0) {
1036 dev_err(hdmi->dev, "PHY PLL not locked\n");
1037 return -ETIMEDOUT;
1040 udelay(1000);
1041 msec--;
1042 } while (1);
1044 return 0;
1047 static int imx_hdmi_phy_init(struct imx_hdmi *hdmi)
1049 int i, ret;
1050 bool cscon = false;
1052 /*check csc whether needed activated in HDMI mode */
1053 cscon = (is_color_space_conversion(hdmi) &&
1054 !hdmi->hdmi_data.video_mode.mdvi);
1056 /* HDMI Phy spec says to do the phy initialization sequence twice */
1057 for (i = 0; i < 2; i++) {
1058 imx_hdmi_phy_sel_data_en_pol(hdmi, 1);
1059 imx_hdmi_phy_sel_interface_control(hdmi, 0);
1060 imx_hdmi_phy_enable_tmds(hdmi, 0);
1061 imx_hdmi_phy_enable_power(hdmi, 0);
1063 /* Enable CSC */
1064 ret = hdmi_phy_configure(hdmi, 0, 8, cscon);
1065 if (ret)
1066 return ret;
1069 hdmi->phy_enabled = true;
1070 return 0;
1073 static void hdmi_tx_hdcp_config(struct imx_hdmi *hdmi)
1075 u8 de, val;
1077 if (hdmi->hdmi_data.video_mode.mdataenablepolarity)
1078 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
1079 else
1080 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
1082 /* disable rx detect */
1083 val = hdmi_readb(hdmi, HDMI_A_HDCPCFG0);
1084 val &= HDMI_A_HDCPCFG0_RXDETECT_MASK;
1085 val |= HDMI_A_HDCPCFG0_RXDETECT_DISABLE;
1086 hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG0);
1088 val = hdmi_readb(hdmi, HDMI_A_VIDPOLCFG);
1089 val &= HDMI_A_VIDPOLCFG_DATAENPOL_MASK;
1090 val |= de;
1091 hdmi_writeb(hdmi, val, HDMI_A_VIDPOLCFG);
1093 val = hdmi_readb(hdmi, HDMI_A_HDCPCFG1);
1094 val &= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK;
1095 val |= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE;
1096 hdmi_writeb(hdmi, val, HDMI_A_HDCPCFG1);
1099 static void hdmi_config_AVI(struct imx_hdmi *hdmi)
1101 u8 val, pix_fmt, under_scan;
1102 u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
1103 bool aspect_16_9;
1105 aspect_16_9 = false; /* FIXME */
1107 /* AVI Data Byte 1 */
1108 if (hdmi->hdmi_data.enc_out_format == YCBCR444)
1109 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
1110 else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
1111 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
1112 else
1113 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
1115 under_scan = HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
1118 * Active format identification data is present in the AVI InfoFrame.
1119 * Under scan info, no bar data
1121 val = pix_fmt | under_scan |
1122 HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
1123 HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;
1125 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);
1127 /* AVI Data Byte 2 -Set the Aspect Ratio */
1128 if (aspect_16_9) {
1129 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
1130 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
1131 } else {
1132 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
1133 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
1136 /* Set up colorimetry */
1137 if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
1138 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
1139 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
1140 ext_colorimetry =
1141 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1142 else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
1143 ext_colorimetry =
1144 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
1145 } else if (hdmi->hdmi_data.enc_out_format != RGB) {
1146 if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
1147 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
1148 else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
1149 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
1150 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1151 } else { /* Carries no data */
1152 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
1153 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1156 val = colorimetry | coded_ratio | act_ratio;
1157 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);
1159 /* AVI Data Byte 3 */
1160 val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
1161 HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
1162 HDMI_FC_AVICONF2_SCALING_NONE;
1163 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);
1165 /* AVI Data Byte 4 */
1166 hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);
1168 /* AVI Data Byte 5- set up input and output pixel repetition */
1169 val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
1170 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
1171 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
1172 ((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
1173 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
1174 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
1175 hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);
1177 /* IT Content and quantization range = don't care */
1178 val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
1179 HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
1180 hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);
1182 /* AVI Data Bytes 6-13 */
1183 hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
1184 hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
1185 hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
1186 hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
1187 hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
1188 hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
1189 hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
1190 hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
1193 static void hdmi_av_composer(struct imx_hdmi *hdmi,
1194 const struct drm_display_mode *mode)
1196 u8 inv_val;
1197 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
1198 int hblank, vblank, h_de_hs, v_de_vs, hsync_len, vsync_len;
1200 vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC);
1201 vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC);
1202 vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE);
1203 vmode->mpixelclock = mode->clock * 1000;
1205 dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock);
1207 /* Set up HDMI_FC_INVIDCONF */
1208 inv_val = (hdmi->hdmi_data.hdcp_enable ?
1209 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1210 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
1212 inv_val |= (vmode->mvsyncpolarity ?
1213 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
1214 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
1216 inv_val |= (vmode->mhsyncpolarity ?
1217 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
1218 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
1220 inv_val |= (vmode->mdataenablepolarity ?
1221 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
1222 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
1224 if (hdmi->vic == 39)
1225 inv_val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
1226 else
1227 inv_val |= (vmode->minterlaced ?
1228 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
1229 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
1231 inv_val |= (vmode->minterlaced ?
1232 HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
1233 HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
1235 inv_val |= (vmode->mdvi ?
1236 HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE :
1237 HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE);
1239 hdmi_writeb(hdmi, inv_val, HDMI_FC_INVIDCONF);
1241 /* Set up horizontal active pixel width */
1242 hdmi_writeb(hdmi, mode->hdisplay >> 8, HDMI_FC_INHACTV1);
1243 hdmi_writeb(hdmi, mode->hdisplay, HDMI_FC_INHACTV0);
1245 /* Set up vertical active lines */
1246 hdmi_writeb(hdmi, mode->vdisplay >> 8, HDMI_FC_INVACTV1);
1247 hdmi_writeb(hdmi, mode->vdisplay, HDMI_FC_INVACTV0);
1249 /* Set up horizontal blanking pixel region width */
1250 hblank = mode->htotal - mode->hdisplay;
1251 hdmi_writeb(hdmi, hblank >> 8, HDMI_FC_INHBLANK1);
1252 hdmi_writeb(hdmi, hblank, HDMI_FC_INHBLANK0);
1254 /* Set up vertical blanking pixel region width */
1255 vblank = mode->vtotal - mode->vdisplay;
1256 hdmi_writeb(hdmi, vblank, HDMI_FC_INVBLANK);
1258 /* Set up HSYNC active edge delay width (in pixel clks) */
1259 h_de_hs = mode->hsync_start - mode->hdisplay;
1260 hdmi_writeb(hdmi, h_de_hs >> 8, HDMI_FC_HSYNCINDELAY1);
1261 hdmi_writeb(hdmi, h_de_hs, HDMI_FC_HSYNCINDELAY0);
1263 /* Set up VSYNC active edge delay (in lines) */
1264 v_de_vs = mode->vsync_start - mode->vdisplay;
1265 hdmi_writeb(hdmi, v_de_vs, HDMI_FC_VSYNCINDELAY);
1267 /* Set up HSYNC active pulse width (in pixel clks) */
1268 hsync_len = mode->hsync_end - mode->hsync_start;
1269 hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
1270 hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0);
1272 /* Set up VSYNC active edge delay (in lines) */
1273 vsync_len = mode->vsync_end - mode->vsync_start;
1274 hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH);
1277 static void imx_hdmi_phy_disable(struct imx_hdmi *hdmi)
1279 if (!hdmi->phy_enabled)
1280 return;
1282 imx_hdmi_phy_enable_tmds(hdmi, 0);
1283 imx_hdmi_phy_enable_power(hdmi, 0);
1285 hdmi->phy_enabled = false;
1288 /* HDMI Initialization Step B.4 */
1289 static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
1291 u8 clkdis;
1293 /* control period minimum duration */
1294 hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
1295 hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
1296 hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);
1298 /* Set to fill TMDS data channels */
1299 hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
1300 hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
1301 hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);
1303 /* Enable pixel clock and tmds data path */
1304 clkdis = 0x7F;
1305 clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
1306 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1308 clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
1309 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1311 /* Enable csc path */
1312 if (is_color_space_conversion(hdmi)) {
1313 clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
1314 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1318 static void hdmi_enable_audio_clk(struct imx_hdmi *hdmi)
1320 u8 clkdis;
1322 clkdis = hdmi_readb(hdmi, HDMI_MC_CLKDIS);
1323 clkdis &= ~HDMI_MC_CLKDIS_AUDCLK_DISABLE;
1324 hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
1327 /* Workaround to clear the overflow condition */
1328 static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
1330 int count;
1331 u8 val;
1333 /* TMDS software reset */
1334 hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);
1336 val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
1337 if (hdmi->dev_type == IMX6DL_HDMI) {
1338 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1339 return;
1342 for (count = 0; count < 4; count++)
1343 hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
1346 static void hdmi_enable_overflow_interrupts(struct imx_hdmi *hdmi)
1348 hdmi_writeb(hdmi, 0, HDMI_FC_MASK2);
1349 hdmi_writeb(hdmi, 0, HDMI_IH_MUTE_FC_STAT2);
1352 static void hdmi_disable_overflow_interrupts(struct imx_hdmi *hdmi)
1354 hdmi_writeb(hdmi, HDMI_IH_MUTE_FC_STAT2_OVERFLOW_MASK,
1355 HDMI_IH_MUTE_FC_STAT2);
1358 static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode)
1360 int ret;
1362 hdmi_disable_overflow_interrupts(hdmi);
1364 hdmi->vic = drm_match_cea_mode(mode);
1366 if (!hdmi->vic) {
1367 dev_dbg(hdmi->dev, "Non-CEA mode used in HDMI\n");
1368 hdmi->hdmi_data.video_mode.mdvi = true;
1369 } else {
1370 dev_dbg(hdmi->dev, "CEA mode used vic=%d\n", hdmi->vic);
1371 hdmi->hdmi_data.video_mode.mdvi = false;
1374 if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
1375 (hdmi->vic == 21) || (hdmi->vic == 22) ||
1376 (hdmi->vic == 2) || (hdmi->vic == 3) ||
1377 (hdmi->vic == 17) || (hdmi->vic == 18))
1378 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_601;
1379 else
1380 hdmi->hdmi_data.colorimetry = HDMI_COLORIMETRY_ITU_709;
1382 if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
1383 (hdmi->vic == 12) || (hdmi->vic == 13) ||
1384 (hdmi->vic == 14) || (hdmi->vic == 15) ||
1385 (hdmi->vic == 25) || (hdmi->vic == 26) ||
1386 (hdmi->vic == 27) || (hdmi->vic == 28) ||
1387 (hdmi->vic == 29) || (hdmi->vic == 30) ||
1388 (hdmi->vic == 35) || (hdmi->vic == 36) ||
1389 (hdmi->vic == 37) || (hdmi->vic == 38))
1390 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 1;
1391 else
1392 hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0;
1394 hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0;
1396 /* TODO: Get input format from IPU (via FB driver interface) */
1397 hdmi->hdmi_data.enc_in_format = RGB;
1399 hdmi->hdmi_data.enc_out_format = RGB;
1401 hdmi->hdmi_data.enc_color_depth = 8;
1402 hdmi->hdmi_data.pix_repet_factor = 0;
1403 hdmi->hdmi_data.hdcp_enable = 0;
1404 hdmi->hdmi_data.video_mode.mdataenablepolarity = true;
1406 /* HDMI Initialization Step B.1 */
1407 hdmi_av_composer(hdmi, mode);
1409 /* HDMI Initializateion Step B.2 */
1410 ret = imx_hdmi_phy_init(hdmi);
1411 if (ret)
1412 return ret;
1414 /* HDMI Initialization Step B.3 */
1415 imx_hdmi_enable_video_path(hdmi);
1417 /* not for DVI mode */
1418 if (hdmi->hdmi_data.video_mode.mdvi)
1419 dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
1420 else {
1421 dev_dbg(hdmi->dev, "%s CEA mode\n", __func__);
1423 /* HDMI Initialization Step E - Configure audio */
1424 hdmi_clk_regenerator_update_pixel_clock(hdmi);
1425 hdmi_enable_audio_clk(hdmi);
1427 /* HDMI Initialization Step F - Configure AVI InfoFrame */
1428 hdmi_config_AVI(hdmi);
1431 hdmi_video_packetize(hdmi);
1432 hdmi_video_csc(hdmi);
1433 hdmi_video_sample(hdmi);
1434 hdmi_tx_hdcp_config(hdmi);
1436 imx_hdmi_clear_overflow(hdmi);
1437 if (hdmi->cable_plugin && !hdmi->hdmi_data.video_mode.mdvi)
1438 hdmi_enable_overflow_interrupts(hdmi);
1440 return 0;
1443 /* Wait until we are registered to enable interrupts */
1444 static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
1446 hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
1447 HDMI_PHY_I2CM_INT_ADDR);
1449 hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
1450 HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
1451 HDMI_PHY_I2CM_CTLINT_ADDR);
1453 /* enable cable hot plug irq */
1454 hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);
1456 /* Clear Hotplug interrupts */
1457 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
1459 /* Unmute interrupts */
1460 hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);
1462 return 0;
1465 static void initialize_hdmi_ih_mutes(struct imx_hdmi *hdmi)
1467 u8 ih_mute;
1470 * Boot up defaults are:
1471 * HDMI_IH_MUTE = 0x03 (disabled)
1472 * HDMI_IH_MUTE_* = 0x00 (enabled)
1474 * Disable top level interrupt bits in HDMI block
1476 ih_mute = hdmi_readb(hdmi, HDMI_IH_MUTE) |
1477 HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
1478 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;
1480 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
1482 /* by default mask all interrupts */
1483 hdmi_writeb(hdmi, 0xff, HDMI_VP_MASK);
1484 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK0);
1485 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK1);
1486 hdmi_writeb(hdmi, 0xff, HDMI_FC_MASK2);
1487 hdmi_writeb(hdmi, 0xff, HDMI_PHY_MASK0);
1488 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_INT_ADDR);
1489 hdmi_writeb(hdmi, 0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
1490 hdmi_writeb(hdmi, 0xff, HDMI_AUD_INT);
1491 hdmi_writeb(hdmi, 0xff, HDMI_AUD_SPDIFINT);
1492 hdmi_writeb(hdmi, 0xff, HDMI_AUD_HBR_MASK);
1493 hdmi_writeb(hdmi, 0xff, HDMI_GP_MASK);
1494 hdmi_writeb(hdmi, 0xff, HDMI_A_APIINTMSK);
1495 hdmi_writeb(hdmi, 0xff, HDMI_CEC_MASK);
1496 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_INT);
1497 hdmi_writeb(hdmi, 0xff, HDMI_I2CM_CTLINT);
1499 /* Disable interrupts in the IH_MUTE_* registers */
1500 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT0);
1501 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT1);
1502 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_FC_STAT2);
1503 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AS_STAT0);
1504 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_PHY_STAT0);
1505 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CM_STAT0);
1506 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_CEC_STAT0);
1507 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_VP_STAT0);
1508 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
1509 hdmi_writeb(hdmi, 0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
1511 /* Enable top level interrupt bits in HDMI block */
1512 ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
1513 HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
1514 hdmi_writeb(hdmi, ih_mute, HDMI_IH_MUTE);
1517 static void imx_hdmi_poweron(struct imx_hdmi *hdmi)
1519 imx_hdmi_setup(hdmi, &hdmi->previous_mode);
1522 static void imx_hdmi_poweroff(struct imx_hdmi *hdmi)
1524 imx_hdmi_phy_disable(hdmi);
1527 static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector
1528 *connector, bool force)
1530 /* FIXME */
1531 return connector_status_connected;
1534 static void imx_hdmi_connector_destroy(struct drm_connector *connector)
1538 static int imx_hdmi_connector_get_modes(struct drm_connector *connector)
1540 struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
1541 connector);
1542 struct edid *edid;
1543 int ret;
1545 if (!hdmi->ddc)
1546 return 0;
1548 edid = drm_get_edid(connector, hdmi->ddc);
1549 if (edid) {
1550 dev_dbg(hdmi->dev, "got edid: width[%d] x height[%d]\n",
1551 edid->width_cm, edid->height_cm);
1553 drm_mode_connector_update_edid_property(connector, edid);
1554 ret = drm_add_edid_modes(connector, edid);
1555 kfree(edid);
1556 } else {
1557 dev_dbg(hdmi->dev, "failed to get edid\n");
1560 return 0;
1563 static int imx_hdmi_connector_mode_valid(struct drm_connector *connector,
1564 struct drm_display_mode *mode)
1567 return MODE_OK;
1570 static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector
1571 *connector)
1573 struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi,
1574 connector);
1576 return &hdmi->encoder;
1579 static void imx_hdmi_encoder_mode_set(struct drm_encoder *encoder,
1580 struct drm_display_mode *mode,
1581 struct drm_display_mode *adjusted_mode)
1583 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1585 imx_hdmi_setup(hdmi, mode);
1587 /* Store the display mode for plugin/DKMS poweron events */
1588 memcpy(&hdmi->previous_mode, mode, sizeof(hdmi->previous_mode));
1591 static bool imx_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
1592 const struct drm_display_mode *mode,
1593 struct drm_display_mode *adjusted_mode)
1595 return true;
1598 static void imx_hdmi_encoder_disable(struct drm_encoder *encoder)
1602 static void imx_hdmi_encoder_dpms(struct drm_encoder *encoder, int mode)
1604 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1606 if (mode)
1607 imx_hdmi_poweroff(hdmi);
1608 else
1609 imx_hdmi_poweron(hdmi);
1612 static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder)
1614 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1616 imx_hdmi_poweroff(hdmi);
1617 imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE,
1618 V4L2_PIX_FMT_RGB24);
1621 static void imx_hdmi_encoder_commit(struct drm_encoder *encoder)
1623 struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder);
1624 int mux = imx_drm_encoder_get_mux_id(hdmi->imx_drm_encoder,
1625 encoder->crtc);
1627 imx_hdmi_set_ipu_di_mux(hdmi, mux);
1629 imx_hdmi_poweron(hdmi);
1632 static void imx_hdmi_encoder_destroy(struct drm_encoder *encoder)
1634 return;
1637 static struct drm_encoder_funcs imx_hdmi_encoder_funcs = {
1638 .destroy = imx_hdmi_encoder_destroy,
1641 static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = {
1642 .dpms = imx_hdmi_encoder_dpms,
1643 .prepare = imx_hdmi_encoder_prepare,
1644 .commit = imx_hdmi_encoder_commit,
1645 .mode_set = imx_hdmi_encoder_mode_set,
1646 .mode_fixup = imx_hdmi_encoder_mode_fixup,
1647 .disable = imx_hdmi_encoder_disable,
1650 static struct drm_connector_funcs imx_hdmi_connector_funcs = {
1651 .dpms = drm_helper_connector_dpms,
1652 .fill_modes = drm_helper_probe_single_connector_modes,
1653 .detect = imx_hdmi_connector_detect,
1654 .destroy = imx_hdmi_connector_destroy,
1657 static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = {
1658 .get_modes = imx_hdmi_connector_get_modes,
1659 .mode_valid = imx_hdmi_connector_mode_valid,
1660 .best_encoder = imx_hdmi_connector_best_encoder,
1663 static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
1665 struct imx_hdmi *hdmi = dev_id;
1666 u8 intr_stat;
1667 u8 phy_int_pol;
1668 u8 val;
1670 intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
1672 phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);
1674 if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
1675 if (phy_int_pol & HDMI_PHY_HPD) {
1676 dev_dbg(hdmi->dev, "EVENT=plugin\n");
1678 val = hdmi_readb(hdmi, HDMI_PHY_POL0);
1679 val &= ~HDMI_PHY_HPD;
1680 hdmi_writeb(hdmi, val, HDMI_PHY_POL0);
1682 imx_hdmi_poweron(hdmi);
1683 } else {
1684 dev_dbg(hdmi->dev, "EVENT=plugout\n");
1686 val = hdmi_readb(hdmi, HDMI_PHY_POL0);
1687 val |= HDMI_PHY_HPD;
1688 hdmi_writeb(hdmi, val, HDMI_PHY_POL0);
1690 imx_hdmi_poweroff(hdmi);
1694 hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
1696 return IRQ_HANDLED;
1699 static int imx_hdmi_register(struct imx_hdmi *hdmi)
1701 int ret;
1703 hdmi->connector.funcs = &imx_hdmi_connector_funcs;
1704 hdmi->encoder.funcs = &imx_hdmi_encoder_funcs;
1706 hdmi->encoder.encoder_type = DRM_MODE_ENCODER_TMDS;
1707 hdmi->connector.connector_type = DRM_MODE_CONNECTOR_HDMIA;
1709 drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs);
1710 ret = imx_drm_add_encoder(&hdmi->encoder, &hdmi->imx_drm_encoder,
1711 THIS_MODULE);
1712 if (ret) {
1713 dev_err(hdmi->dev, "adding encoder failed: %d\n", ret);
1714 return ret;
1717 drm_connector_helper_add(&hdmi->connector,
1718 &imx_hdmi_connector_helper_funcs);
1720 ret = imx_drm_add_connector(&hdmi->connector,
1721 &hdmi->imx_drm_connector, THIS_MODULE);
1722 if (ret) {
1723 imx_drm_remove_encoder(hdmi->imx_drm_encoder);
1724 dev_err(hdmi->dev, "adding connector failed: %d\n", ret);
1725 return ret;
1728 hdmi->connector.encoder = &hdmi->encoder;
1730 drm_mode_connector_attach_encoder(&hdmi->connector, &hdmi->encoder);
1732 return 0;
1735 static struct platform_device_id imx_hdmi_devtype[] = {
1737 .name = "imx6q-hdmi",
1738 .driver_data = IMX6Q_HDMI,
1739 }, {
1740 .name = "imx6dl-hdmi",
1741 .driver_data = IMX6DL_HDMI,
1742 }, { /* sentinel */ }
1744 MODULE_DEVICE_TABLE(platform, imx_hdmi_devtype);
1746 static const struct of_device_id imx_hdmi_dt_ids[] = {
1747 { .compatible = "fsl,imx6q-hdmi", .data = &imx_hdmi_devtype[IMX6Q_HDMI], },
1748 { .compatible = "fsl,imx6dl-hdmi", .data = &imx_hdmi_devtype[IMX6DL_HDMI], },
1749 { /* sentinel */ }
1751 MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
1753 static int imx_hdmi_platform_probe(struct platform_device *pdev)
1755 const struct of_device_id *of_id =
1756 of_match_device(imx_hdmi_dt_ids, &pdev->dev);
1757 struct device_node *np = pdev->dev.of_node;
1758 struct device_node *ddc_node;
1759 struct imx_hdmi *hdmi;
1760 struct resource *iores;
1761 int ret, irq;
1763 hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
1764 if (!hdmi)
1765 return -ENOMEM;
1767 hdmi->dev = &pdev->dev;
1769 if (of_id) {
1770 const struct platform_device_id *device_id = of_id->data;
1771 hdmi->dev_type = device_id->driver_data;
1774 ddc_node = of_parse_phandle(np, "ddc", 0);
1775 if (ddc_node) {
1776 hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
1777 if (!hdmi->ddc)
1778 dev_dbg(hdmi->dev, "failed to read ddc node\n");
1780 of_node_put(ddc_node);
1781 } else {
1782 dev_dbg(hdmi->dev, "no ddc property found\n");
1785 irq = platform_get_irq(pdev, 0);
1786 if (irq < 0)
1787 return -EINVAL;
1789 ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0,
1790 dev_name(&pdev->dev), hdmi);
1791 if (ret)
1792 return ret;
1794 iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1795 hdmi->regs = devm_ioremap_resource(&pdev->dev, iores);
1796 if (IS_ERR(hdmi->regs))
1797 return PTR_ERR(hdmi->regs);
1799 hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
1800 if (IS_ERR(hdmi->regmap))
1801 return PTR_ERR(hdmi->regmap);
1803 hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
1804 if (IS_ERR(hdmi->isfr_clk)) {
1805 ret = PTR_ERR(hdmi->isfr_clk);
1806 dev_err(hdmi->dev,
1807 "Unable to get HDMI isfr clk: %d\n", ret);
1808 return ret;
1811 ret = clk_prepare_enable(hdmi->isfr_clk);
1812 if (ret) {
1813 dev_err(hdmi->dev,
1814 "Cannot enable HDMI isfr clock: %d\n", ret);
1815 return ret;
1818 hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
1819 if (IS_ERR(hdmi->iahb_clk)) {
1820 ret = PTR_ERR(hdmi->iahb_clk);
1821 dev_err(hdmi->dev,
1822 "Unable to get HDMI iahb clk: %d\n", ret);
1823 goto err_isfr;
1826 ret = clk_prepare_enable(hdmi->iahb_clk);
1827 if (ret) {
1828 dev_err(hdmi->dev,
1829 "Cannot enable HDMI iahb clock: %d\n", ret);
1830 goto err_isfr;
1833 /* Product and revision IDs */
1834 dev_info(&pdev->dev,
1835 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
1836 hdmi_readb(hdmi, HDMI_DESIGN_ID),
1837 hdmi_readb(hdmi, HDMI_REVISION_ID),
1838 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
1839 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));
1841 initialize_hdmi_ih_mutes(hdmi);
1844 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
1845 * N and cts values before enabling phy
1847 hdmi_init_clk_regenerator(hdmi);
1850 * Configure registers related to HDMI interrupt
1851 * generation before registering IRQ.
1853 hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);
1855 /* Clear Hotplug interrupts */
1856 hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);
1858 ret = imx_hdmi_fb_registered(hdmi);
1859 if (ret)
1860 goto err_iahb;
1862 ret = imx_hdmi_register(hdmi);
1863 if (ret)
1864 goto err_iahb;
1866 imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np);
1868 platform_set_drvdata(pdev, hdmi);
1870 return 0;
1872 err_iahb:
1873 clk_disable_unprepare(hdmi->iahb_clk);
1874 err_isfr:
1875 clk_disable_unprepare(hdmi->isfr_clk);
1877 return ret;
1880 static int imx_hdmi_platform_remove(struct platform_device *pdev)
1882 struct imx_hdmi *hdmi = platform_get_drvdata(pdev);
1883 struct drm_connector *connector = &hdmi->connector;
1884 struct drm_encoder *encoder = &hdmi->encoder;
1886 drm_mode_connector_detach_encoder(connector, encoder);
1887 imx_drm_remove_connector(hdmi->imx_drm_connector);
1888 imx_drm_remove_encoder(hdmi->imx_drm_encoder);
1890 clk_disable_unprepare(hdmi->iahb_clk);
1891 clk_disable_unprepare(hdmi->isfr_clk);
1892 i2c_put_adapter(hdmi->ddc);
1894 return 0;
1897 static struct platform_driver imx_hdmi_driver = {
1898 .probe = imx_hdmi_platform_probe,
1899 .remove = imx_hdmi_platform_remove,
1900 .driver = {
1901 .name = "imx-hdmi",
1902 .owner = THIS_MODULE,
1903 .of_match_table = imx_hdmi_dt_ids,
1907 module_platform_driver(imx_hdmi_driver);
1909 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1910 MODULE_DESCRIPTION("i.MX6 HDMI transmitter driver");
1911 MODULE_LICENSE("GPL");
1912 MODULE_ALIAS("platform:imx-hdmi");