2 * Copyright (C) 2011 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 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
21 * for SLISHDMI13T and SLIPHDMIT IP cores
23 * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License version 2 as
27 * published by the Free Software Foundation.
30 #include <linux/module.h>
31 #include <linux/kernel.h>
32 #include <linux/device.h>
33 #include <linux/platform_device.h>
34 #include <linux/input.h>
35 #include <linux/interrupt.h>
36 #include <linux/irq.h>
38 #include <linux/init.h>
39 #include <linux/list.h>
40 #include <linux/delay.h>
41 #include <linux/dma-mapping.h>
42 #include <linux/err.h>
43 #include <linux/clk.h>
44 #include <linux/uaccess.h>
45 #include <linux/cpufreq.h>
46 #include <linux/firmware.h>
47 #include <linux/kthread.h>
48 #include <linux/regulator/driver.h>
49 #include <linux/fsl_devices.h>
50 #include <linux/ipu.h>
52 #include <linux/console.h>
53 #include <linux/types.h>
55 #include <mach/mxc_edid.h>
56 #include "mxc/mxc_dispdrv.h"
58 #include <linux/mfd/mxc-hdmi-core.h>
59 #include <mach/mxc_hdmi.h>
61 #define DISPDRV_HDMI "hdmi"
62 #define HDMI_EDID_LEN 512
67 #define NUM_CEA_VIDEO_MODES 64
68 #define DEFAULT_VIDEO_MODE 16 /* 1080P */
70 #define HDMI_IH_PHY_RX_SENSE (HDMI_IH_PHY_STAT0_RX_SENSE0 |\
71 HDMI_IH_PHY_STAT0_RX_SENSE1 |\
72 HDMI_IH_PHY_STAT0_RX_SENSE2 |\
73 HDMI_IH_PHY_STAT0_RX_SENSE3)
74 #define HDMI_PHY_RX_SENSE (HDMI_PHY_RX_SENSE0 | HDMI_PHY_RX_SENSE1 |\
75 HDMI_PHY_RX_SENSE2 | HDMI_PHY_RX_SENSE3)
79 #define YCBCR422_16BITS 2
80 #define YCBCR422_8BITS 3
97 enum hdmi_csc_enc_format {
104 enum hdmi_colorimetry {
110 unsigned int mHdmiDviSel;
111 unsigned int mHSyncPolarity;
112 unsigned int mVSyncPolarity;
113 unsigned int mInterlaced;
114 unsigned int mDataEnablePolarity;
115 unsigned int mPixelClock;
116 unsigned int mPixelRepetitionInput;
117 unsigned int mPixelRepetitionOutput;
120 struct hdmi_data_info {
121 unsigned int enc_in_format;
122 unsigned int enc_out_format;
123 unsigned int enc_color_depth;
124 unsigned int colorimetry;
125 unsigned int pix_repet_factor;
126 unsigned int hdcp_enable;
127 struct hdmi_vmode video_mode;
131 struct platform_device *pdev;
132 struct platform_device *core_pdev;
133 struct mxc_dispdrv_entry *disp_mxc_hdmi;
135 struct clk *hdmi_clk;
136 struct delayed_work det_work;
137 struct notifier_block nb;
139 struct hdmi_data_info hdmi_data;
141 struct mxc_edid_cfg edid_cfg;
142 u8 edid[HDMI_EDID_LEN];
144 bool need_mode_change;
149 struct i2c_client *hdmi_i2c;
152 * this submodule is responsible for the video data synchronization.
153 * for example, for RGB 4:4:4 input, the data map is defined as
154 * pin{47~40} <==> R[7:0]
155 * pin{31~24} <==> G[7:0]
156 * pin{15~8} <==> B[7:0]
158 void hdmi_video_sample(struct mxc_hdmi *hdmi)
160 int color_format = 0;
163 if (hdmi->hdmi_data.enc_in_format == eRGB) {
164 if (hdmi->hdmi_data.enc_color_depth == 8)
166 else if (hdmi->hdmi_data.enc_color_depth == 10)
168 else if (hdmi->hdmi_data.enc_color_depth == 12)
170 else if (hdmi->hdmi_data.enc_color_depth == 16)
174 } else if (hdmi->hdmi_data.enc_in_format == eYCC444) {
175 if (hdmi->hdmi_data.enc_color_depth == 8)
177 else if (hdmi->hdmi_data.enc_color_depth == 10)
179 else if (hdmi->hdmi_data.enc_color_depth == 12)
181 else if (hdmi->hdmi_data.enc_color_depth == 16)
185 } else if (hdmi->hdmi_data.enc_in_format == eYCC422) {
186 if (hdmi->hdmi_data.enc_color_depth == 8)
188 else if (hdmi->hdmi_data.enc_color_depth == 10)
190 else if (hdmi->hdmi_data.enc_color_depth == 12)
196 val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
197 ((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
198 HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
199 hdmi_writeb(val, HDMI_TX_INVID0);
201 /* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
202 val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
203 HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
204 HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
205 hdmi_writeb(val, HDMI_TX_INSTUFFING);
206 hdmi_writeb(0x0, HDMI_TX_GYDATA0);
207 hdmi_writeb(0x0, HDMI_TX_GYDATA1);
208 hdmi_writeb(0x0, HDMI_TX_RCRDATA0);
209 hdmi_writeb(0x0, HDMI_TX_RCRDATA1);
210 hdmi_writeb(0x0, HDMI_TX_BCBDATA0);
211 hdmi_writeb(0x0, HDMI_TX_BCBDATA1);
214 static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
216 return (hdmi->hdmi_data.enc_in_format !=
217 hdmi->hdmi_data.enc_out_format) ? TRUE : FALSE;
220 static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
222 return (hdmi->hdmi_data.enc_in_format !=
223 hdmi->hdmi_data.enc_out_format) ? TRUE : FALSE;
226 static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
228 return ((hdmi->hdmi_data.enc_in_format == eYCC422) &&
229 (hdmi->hdmi_data.enc_out_format == eRGB
230 || hdmi->hdmi_data.enc_out_format == eYCC444)) ?
235 * update the color space conversion coefficients.
237 void update_csc_coeffs(struct mxc_hdmi *hdmi)
239 unsigned short csc_coeff[3][4];
240 unsigned int csc_scale = 1;
242 bool coeff_selected = false;
244 if (isColorSpaceConversion(hdmi) == TRUE) { /* csc needed */
245 if (hdmi->hdmi_data.enc_out_format == eRGB) {
246 if (hdmi->hdmi_data.colorimetry == eITU601) {
247 csc_coeff[0][0] = 0x2000;
248 csc_coeff[0][1] = 0x6926;
249 csc_coeff[0][2] = 0x74fd;
250 csc_coeff[0][3] = 0x010e;
252 csc_coeff[1][0] = 0x2000;
253 csc_coeff[1][1] = 0x2cdd;
254 csc_coeff[1][2] = 0x0000;
255 csc_coeff[1][3] = 0x7e9a;
257 csc_coeff[2][0] = 0x2000;
258 csc_coeff[2][1] = 0x0000;
259 csc_coeff[2][2] = 0x38b4;
260 csc_coeff[2][3] = 0x7e3b;
263 coeff_selected = true;
264 } else if (hdmi->hdmi_data.colorimetry == eITU709) {
265 csc_coeff[0][0] = 0x2000;
266 csc_coeff[0][1] = 0x7106;
267 csc_coeff[0][2] = 0x7a02;
268 csc_coeff[0][3] = 0x00a7;
270 csc_coeff[1][0] = 0x2000;
271 csc_coeff[1][1] = 0x3264;
272 csc_coeff[1][2] = 0x0000;
273 csc_coeff[1][3] = 0x7e6d;
275 csc_coeff[2][0] = 0x2000;
276 csc_coeff[2][1] = 0x0000;
277 csc_coeff[2][2] = 0x3b61;
278 csc_coeff[2][3] = 0x7e25;
281 coeff_selected = true;
283 } else if (hdmi->hdmi_data.enc_in_format == eRGB) {
284 if (hdmi->hdmi_data.colorimetry == eITU601) {
285 csc_coeff[0][0] = 0x2591;
286 csc_coeff[0][1] = 0x1322;
287 csc_coeff[0][2] = 0x074b;
288 csc_coeff[0][3] = 0x0000;
290 csc_coeff[1][0] = 0x6535;
291 csc_coeff[1][1] = 0x2000;
292 csc_coeff[1][2] = 0x7acc;
293 csc_coeff[1][3] = 0x0200;
295 csc_coeff[2][0] = 0x6acd;
296 csc_coeff[2][1] = 0x7534;
297 csc_coeff[2][2] = 0x2000;
298 csc_coeff[2][3] = 0x0200;
301 coeff_selected = true;
302 } else if (hdmi->hdmi_data.colorimetry == eITU709) {
303 csc_coeff[0][0] = 0x2dc5;
304 csc_coeff[0][1] = 0x0d9b;
305 csc_coeff[0][2] = 0x049e;
306 csc_coeff[0][3] = 0x0000;
308 csc_coeff[1][0] = 0x63f0;
309 csc_coeff[1][1] = 0x2000;
310 csc_coeff[1][2] = 0x7d11;
311 csc_coeff[1][3] = 0x0200;
313 csc_coeff[2][0] = 0x6756;
314 csc_coeff[2][1] = 0x78ab;
315 csc_coeff[2][2] = 0x2000;
316 csc_coeff[2][3] = 0x0200;
319 coeff_selected = true;
324 if (!coeff_selected) {
325 csc_coeff[0][0] = 0x2000;
326 csc_coeff[0][1] = 0x0000;
327 csc_coeff[0][2] = 0x0000;
328 csc_coeff[0][3] = 0x0000;
330 csc_coeff[1][0] = 0x0000;
331 csc_coeff[1][1] = 0x2000;
332 csc_coeff[1][2] = 0x0000;
333 csc_coeff[1][3] = 0x0000;
335 csc_coeff[2][0] = 0x0000;
336 csc_coeff[2][1] = 0x0000;
337 csc_coeff[2][2] = 0x2000;
338 csc_coeff[2][3] = 0x0000;
343 /* Update CSC parameters in HDMI CSC registers */
344 hdmi_writeb((unsigned char)(csc_coeff[0][0] & 0xFF),
345 HDMI_CSC_COEF_A1_LSB);
346 hdmi_writeb((unsigned char)(csc_coeff[0][0] >> 8),
347 HDMI_CSC_COEF_A1_MSB);
348 hdmi_writeb((unsigned char)(csc_coeff[0][1] & 0xFF),
349 HDMI_CSC_COEF_A2_LSB);
350 hdmi_writeb((unsigned char)(csc_coeff[0][1] >> 8),
351 HDMI_CSC_COEF_A2_MSB);
352 hdmi_writeb((unsigned char)(csc_coeff[0][2] & 0xFF),
353 HDMI_CSC_COEF_A3_LSB);
354 hdmi_writeb((unsigned char)(csc_coeff[0][2] >> 8),
355 HDMI_CSC_COEF_A3_MSB);
356 hdmi_writeb((unsigned char)(csc_coeff[0][3] & 0xFF),
357 HDMI_CSC_COEF_A4_LSB);
358 hdmi_writeb((unsigned char)(csc_coeff[0][3] >> 8),
359 HDMI_CSC_COEF_A4_MSB);
361 hdmi_writeb((unsigned char)(csc_coeff[1][0] & 0xFF),
362 HDMI_CSC_COEF_B1_LSB);
363 hdmi_writeb((unsigned char)(csc_coeff[1][0] >> 8),
364 HDMI_CSC_COEF_B1_MSB);
365 hdmi_writeb((unsigned char)(csc_coeff[1][1] & 0xFF),
366 HDMI_CSC_COEF_B2_LSB);
367 hdmi_writeb((unsigned char)(csc_coeff[1][1] >> 8),
368 HDMI_CSC_COEF_B2_MSB);
369 hdmi_writeb((unsigned char)(csc_coeff[1][2] & 0xFF),
370 HDMI_CSC_COEF_B3_LSB);
371 hdmi_writeb((unsigned char)(csc_coeff[1][2] >> 8),
372 HDMI_CSC_COEF_B3_MSB);
373 hdmi_writeb((unsigned char)(csc_coeff[1][3] & 0xFF),
374 HDMI_CSC_COEF_B4_LSB);
375 hdmi_writeb((unsigned char)(csc_coeff[1][3] >> 8),
376 HDMI_CSC_COEF_B4_MSB);
378 hdmi_writeb((unsigned char)(csc_coeff[2][0] & 0xFF),
379 HDMI_CSC_COEF_C1_LSB);
380 hdmi_writeb((unsigned char)(csc_coeff[2][0] >> 8),
381 HDMI_CSC_COEF_C1_MSB);
382 hdmi_writeb((unsigned char)(csc_coeff[2][1] & 0xFF),
383 HDMI_CSC_COEF_C2_LSB);
384 hdmi_writeb((unsigned char)(csc_coeff[2][1] >> 8),
385 HDMI_CSC_COEF_C2_MSB);
386 hdmi_writeb((unsigned char)(csc_coeff[2][2] & 0xFF),
387 HDMI_CSC_COEF_C3_LSB);
388 hdmi_writeb((unsigned char)(csc_coeff[2][2] >> 8),
389 HDMI_CSC_COEF_C3_MSB);
390 hdmi_writeb((unsigned char)(csc_coeff[2][3] & 0xFF),
391 HDMI_CSC_COEF_C4_LSB);
392 hdmi_writeb((unsigned char)(csc_coeff[2][3] >> 8),
393 HDMI_CSC_COEF_C4_MSB);
395 val = hdmi_readb(HDMI_CSC_SCALE);
396 val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK;
397 val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK;
398 hdmi_writeb(val, HDMI_CSC_SCALE);
401 void hdmi_video_csc(struct mxc_hdmi *hdmi)
404 int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
408 /* YCC422 interpolation to 444 mode */
409 if (isColorSpaceInterpolation(hdmi))
410 interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
411 else if (isColorSpaceDecimation(hdmi))
412 decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA1;
414 if (hdmi->hdmi_data.enc_color_depth == 8)
415 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
416 else if (hdmi->hdmi_data.enc_color_depth == 10)
417 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
418 else if (hdmi->hdmi_data.enc_color_depth == 12)
419 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
420 else if (hdmi->hdmi_data.enc_color_depth == 16)
421 color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
425 /*configure the CSC registers */
426 hdmi_writeb(interpolation | decimation, HDMI_CSC_CFG);
427 val = hdmi_readb(HDMI_CSC_SCALE);
428 val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK;
430 hdmi_writeb(val, HDMI_CSC_SCALE);
432 update_csc_coeffs(hdmi);
436 * HDMI video packetizer is used to packetize the data.
437 * for example, if input is YCC422 mode or repeater is used,
438 * data should be repacked this module can be bypassed.
440 void hdmi_video_packetize(struct mxc_hdmi *hdmi)
442 unsigned int color_depth = 0;
443 unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit;
444 unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP;
445 struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data;
448 if (hdmi_data->enc_out_format == eRGB
449 || hdmi_data->enc_out_format == eYCC444) {
450 if (hdmi_data->enc_color_depth == 0)
451 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
452 else if (hdmi_data->enc_color_depth == 8) {
454 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
455 } else if (hdmi_data->enc_color_depth == 10)
457 else if (hdmi_data->enc_color_depth == 12)
459 else if (hdmi_data->enc_color_depth == 16)
463 } else if (hdmi_data->enc_out_format == eYCC422) {
464 if (hdmi_data->enc_color_depth == 0 ||
465 hdmi_data->enc_color_depth == 8)
466 remap_size = HDMI_VP_REMAP_YCC422_16bit;
467 else if (hdmi_data->enc_color_depth == 10)
468 remap_size = HDMI_VP_REMAP_YCC422_20bit;
469 else if (hdmi_data->enc_color_depth == 12)
470 remap_size = HDMI_VP_REMAP_YCC422_24bit;
473 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
477 /* set the packetizer registers */
478 val = ((color_depth << HDMI_VP_PR_CD_COLOR_DEPTH_OFFSET) &
479 HDMI_VP_PR_CD_COLOR_DEPTH_MASK) |
480 ((hdmi_data->pix_repet_factor <<
481 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_OFFSET) &
482 HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK);
483 hdmi_writeb(val, HDMI_VP_PR_CD);
485 val = hdmi_readb(HDMI_VP_STUFF);
486 val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK;
487 val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE;
488 hdmi_writeb(val, HDMI_VP_STUFF);
490 /* Data from pixel repeater block */
491 if (hdmi_data->pix_repet_factor > 1) {
492 val = hdmi_readb(HDMI_VP_CONF);
493 val &= ~(HDMI_VP_CONF_PR_EN_MASK |
494 HDMI_VP_CONF_BYPASS_SELECT_MASK);
495 val |= HDMI_VP_CONF_PR_EN_ENABLE |
496 HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER;
497 hdmi_writeb(val, HDMI_VP_CONF);
498 } else { /* data from packetizer block */
499 val = hdmi_readb(HDMI_VP_CONF);
500 val &= ~(HDMI_VP_CONF_PR_EN_MASK |
501 HDMI_VP_CONF_BYPASS_SELECT_MASK);
502 val |= HDMI_VP_CONF_PR_EN_DISABLE |
503 HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER;
504 hdmi_writeb(val, HDMI_VP_CONF);
507 val = hdmi_readb(HDMI_VP_STUFF);
508 val &= ~HDMI_VP_STUFF_IDEFAULT_PHASE_MASK;
509 val |= 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET;
510 hdmi_writeb(val, HDMI_VP_STUFF);
512 hdmi_writeb(remap_size, HDMI_VP_REMAP);
514 if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) {
515 val = hdmi_readb(HDMI_VP_CONF);
516 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
517 HDMI_VP_CONF_PP_EN_ENMASK |
518 HDMI_VP_CONF_YCC422_EN_MASK);
519 val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
520 HDMI_VP_CONF_PP_EN_ENABLE |
521 HDMI_VP_CONF_YCC422_EN_DISABLE;
522 hdmi_writeb(val, HDMI_VP_CONF);
523 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) {
524 val = hdmi_readb(HDMI_VP_CONF);
525 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
526 HDMI_VP_CONF_PP_EN_ENMASK |
527 HDMI_VP_CONF_YCC422_EN_MASK);
528 val |= HDMI_VP_CONF_BYPASS_EN_DISABLE |
529 HDMI_VP_CONF_PP_EN_DISABLE |
530 HDMI_VP_CONF_YCC422_EN_ENABLE;
531 hdmi_writeb(val, HDMI_VP_CONF);
532 } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) {
533 val = hdmi_readb(HDMI_VP_CONF);
534 val &= ~(HDMI_VP_CONF_BYPASS_EN_MASK |
535 HDMI_VP_CONF_PP_EN_ENMASK |
536 HDMI_VP_CONF_YCC422_EN_MASK);
537 val |= HDMI_VP_CONF_BYPASS_EN_ENABLE |
538 HDMI_VP_CONF_PP_EN_DISABLE |
539 HDMI_VP_CONF_YCC422_EN_DISABLE;
540 hdmi_writeb(val, HDMI_VP_CONF);
545 val = hdmi_readb(HDMI_VP_STUFF);
546 val &= ~(HDMI_VP_STUFF_PP_STUFFING_MASK |
547 HDMI_VP_STUFF_YCC422_STUFFING_MASK);
548 val |= HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE |
549 HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE;
550 hdmi_writeb(val, HDMI_VP_STUFF);
552 val = hdmi_readb(HDMI_VP_CONF);
553 val &= ~HDMI_VP_CONF_OUTPUT_SELECTOR_MASK;
554 val |= output_select;
555 hdmi_writeb(val, HDMI_VP_CONF);
558 void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
563 hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
564 hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
565 hdmi_writeb(0xFF, HDMI_FC_DBGTMDS0); /* B */
566 val = hdmi_readb(HDMI_FC_DBGFORCE);
567 val |= HDMI_FC_DBGFORCE_FORCEVIDEO;
568 hdmi_writeb(val, HDMI_FC_DBGFORCE);
570 val = hdmi_readb(HDMI_FC_DBGFORCE);
571 val &= ~HDMI_FC_DBGFORCE_FORCEVIDEO;
572 hdmi_writeb(val, HDMI_FC_DBGFORCE);
573 hdmi_writeb(0x00, HDMI_FC_DBGTMDS2); /* R */
574 hdmi_writeb(0x00, HDMI_FC_DBGTMDS1); /* G */
575 hdmi_writeb(0x00, HDMI_FC_DBGTMDS0); /* B */
579 static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
582 u8 val = hdmi_readb(HDMI_PHY_TST0);
583 val &= ~HDMI_PHY_TST0_TSTCLR_MASK;
584 val |= (bit << HDMI_PHY_TST0_TSTCLR_OFFSET) &
585 HDMI_PHY_TST0_TSTCLR_MASK;
586 hdmi_writeb(val, HDMI_PHY_TST0);
589 static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
592 u8 val = hdmi_readb(HDMI_PHY_TST0);
593 val &= ~HDMI_PHY_TST0_TSTEN_MASK;
594 val |= (bit << HDMI_PHY_TST0_TSTEN_OFFSET) &
595 HDMI_PHY_TST0_TSTEN_MASK;
596 hdmi_writeb(val, HDMI_PHY_TST0);
599 static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
602 u8 val = hdmi_readb(HDMI_PHY_TST0);
603 val &= ~HDMI_PHY_TST0_TSTCLK_MASK;
604 val |= (bit << HDMI_PHY_TST0_TSTCLK_OFFSET) &
605 HDMI_PHY_TST0_TSTCLK_MASK;
606 hdmi_writeb(val, HDMI_PHY_TST0);
609 static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
612 hdmi_writeb(bit, HDMI_PHY_TST1);
615 static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
618 hdmi_writeb(bit, HDMI_PHY_TST2);
621 int hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
623 unsigned char val = 0;
624 val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
629 val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
634 int hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
637 hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
638 hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
639 hdmi_writeb((unsigned char)(data >> 8),
640 HDMI_PHY_I2CM_DATAO_1_ADDR);
641 hdmi_writeb((unsigned char)(data >> 0),
642 HDMI_PHY_I2CM_DATAO_0_ADDR);
643 hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
644 HDMI_PHY_I2CM_OPERATION_ADDR);
645 hdmi_phy_wait_i2c_done(hdmi, 1000);
649 unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi, unsigned char addr)
652 unsigned char msb = 0, lsb = 0;
653 hdmi_writeb(0xFF, HDMI_IH_I2CMPHY_STAT0);
654 hdmi_writeb(addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
655 hdmi_writeb(HDMI_PHY_I2CM_OPERATION_ADDR_READ,
656 HDMI_PHY_I2CM_OPERATION_ADDR);
657 hdmi_phy_wait_i2c_done(hdmi, 1000);
658 msb = hdmi_readb(HDMI_PHY_I2CM_DATAI_1_ADDR);
659 lsb = hdmi_readb(HDMI_PHY_I2CM_DATAI_0_ADDR);
660 data = (msb << 8) | lsb;
664 int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
667 unsigned short val = 0;
668 hdmi_phy_i2c_write(hdmi, data, addr);
669 val = hdmi_phy_i2c_read(hdmi, addr);
675 int hdmi_phy_configure(struct mxc_hdmi *hdmi, unsigned char pRep,
676 unsigned char cRes, int cscOn, int audioOn,
677 int cecOn, int hdcpOn)
681 /* color resolution 0 is 8 bit colour depth */
687 else if (cRes != 8 && cRes != 12)
691 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
693 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
694 hdmi_writeb(val, HDMI_MC_FLOWCTRL);
697 /* clock gate == 0 => turn on modules */
698 val = hdcpOn ? HDMI_MC_CLKDIS_PIXELCLK_DISABLE_ENABLE :
699 HDMI_MC_CLKDIS_PIXELCLK_DISABLE_DISABLE;
700 val |= HDMI_MC_CLKDIS_PIXELCLK_DISABLE_ENABLE;
701 val |= HDMI_MC_CLKDIS_TMDSCLK_DISABLE_ENABLE;
702 val |= (pRep > 0) ? HDMI_MC_CLKDIS_PREPCLK_DISABLE_ENABLE :
703 HDMI_MC_CLKDIS_PREPCLK_DISABLE_DISABLE;
704 val |= cecOn ? HDMI_MC_CLKDIS_CECCLK_DISABLE_ENABLE :
705 HDMI_MC_CLKDIS_CECCLK_DISABLE_DISABLE;
706 val |= cscOn ? HDMI_MC_CLKDIS_CSCCLK_DISABLE_ENABLE :
707 HDMI_MC_CLKDIS_CSCCLK_DISABLE_DISABLE;
708 val |= audioOn ? HDMI_MC_CLKDIS_AUDCLK_DISABLE_ENABLE :
709 HDMI_MC_CLKDIS_AUDCLK_DISABLE_DISABLE;
711 /* clock gate == 0 => turn on modules */
712 val = hdcpOn ? HDMI_MC_CLKDIS_PIXELCLK_DISABLE_DISABLE :
713 HDMI_MC_CLKDIS_PIXELCLK_DISABLE_ENABLE;
714 val |= HDMI_MC_CLKDIS_PIXELCLK_DISABLE_ENABLE;
715 val |= HDMI_MC_CLKDIS_TMDSCLK_DISABLE_ENABLE;
716 val |= (pRep > 0) ? HDMI_MC_CLKDIS_PREPCLK_DISABLE_DISABLE :
717 HDMI_MC_CLKDIS_PREPCLK_DISABLE_ENABLE;
718 val |= cecOn ? HDMI_MC_CLKDIS_CECCLK_DISABLE_DISABLE :
719 HDMI_MC_CLKDIS_CECCLK_DISABLE_ENABLE;
720 val |= cscOn ? HDMI_MC_CLKDIS_CSCCLK_DISABLE_DISABLE :
721 HDMI_MC_CLKDIS_CSCCLK_DISABLE_ENABLE;
722 val |= audioOn ? HDMI_MC_CLKDIS_AUDCLK_DISABLE_DISABLE :
723 HDMI_MC_CLKDIS_AUDCLK_DISABLE_ENABLE;
725 hdmi_writeb(val, HDMI_MC_CLKDIS);
727 /* gen2 tx power off */
728 val = hdmi_readb(HDMI_PHY_CONF0);
729 val &= ~HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
730 val |= HDMI_PHY_CONF0_GEN2_TXPWRON_POWER_OFF;
731 hdmi_writeb(val, HDMI_PHY_CONF0);
734 val = hdmi_readb(HDMI_PHY_CONF0);
735 val &= ~HDMI_PHY_CONF0_GEN2_PDDQ_MASK;
736 val |= HDMI_PHY_CONF0_GEN2_PDDQ_ENABLE;
737 hdmi_writeb(val, HDMI_PHY_CONF0);
740 hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
741 hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
743 hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT,
744 HDMI_MC_HEACPHY_RST);
746 hdmi_phy_test_clear(hdmi, 1);
747 hdmi_writeb(HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
748 HDMI_PHY_I2CM_SLAVE_ADDR);
749 hdmi_phy_test_clear(hdmi, 0);
751 switch (hdmi->hdmi_data.video_mode.mPixelClock) {
752 case 25200000: /* 60 Hz */
753 case 24780000: /* 59 Hz (rounded down from 59.94) */
757 hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
758 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10); /* CURRCTRL */
759 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15); /* GMPCTRL */
760 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13); /* PLLPHBYCTRL */
761 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
762 /* RESISTANCE TERM 133Ohm Cfg */
763 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19); /* TXTERM */
764 /* PREEMP Cgf 0.00 */
765 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09); /* CKSYMTXCTRL */
767 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E); /* VLEVCTRL */
768 /* REMOVE CLK TERM */
769 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05); /* CKCALCTRL */
772 hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
773 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
774 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
775 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
776 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
777 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
778 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
779 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
780 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
783 hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
784 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
785 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
786 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
787 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
788 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
789 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
790 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
791 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
800 hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06);
801 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
802 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
803 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
804 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
805 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
806 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
807 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
808 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
811 hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06);
812 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
813 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
814 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
815 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
816 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
817 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
818 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
819 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
822 hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06);
823 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
824 hdmi_phy_i2c_write(hdmi, 0x0000, 0x15);
825 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
826 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
827 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
828 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
829 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
830 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
839 hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
840 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
841 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
842 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
843 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
844 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
845 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
846 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
847 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
850 hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
851 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
852 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
853 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
854 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
855 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
856 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
857 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
858 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
861 hdmi_phy_i2c_write(hdmi, 0x4142, 0x06);
862 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
863 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
864 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
865 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
866 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
867 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
868 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
869 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
878 hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
879 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
880 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
881 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
882 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
883 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
884 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
885 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
886 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
889 hdmi_phy_i2c_write(hdmi, 0x2141, 0x06);
890 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
891 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
892 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
893 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
894 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
895 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
896 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
897 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
900 hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
901 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
902 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
903 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
904 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
905 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
906 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
907 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
908 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
917 hdmi_phy_i2c_write(hdmi, 0x0140, 0x06);
918 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
919 hdmi_phy_i2c_write(hdmi, 0x0005, 0x15);
920 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
921 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
922 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
923 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
924 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
925 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
928 hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
929 hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
930 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
931 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
932 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
933 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
934 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
935 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
936 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
939 hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
940 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
941 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
942 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
943 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
944 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
945 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
946 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
947 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
956 hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
957 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
958 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
959 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
960 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
961 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
962 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
963 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
964 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
967 hdmi_phy_i2c_write(hdmi, 0x20a1, 0x06);
968 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
969 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
970 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
971 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
972 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
973 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
974 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
975 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
978 hdmi_phy_i2c_write(hdmi, 0x40a2, 0x06);
979 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
980 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
981 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
982 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
983 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
984 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
985 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
986 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
995 hdmi_phy_i2c_write(hdmi, 0x00a0, 0x06);
996 hdmi_phy_i2c_write(hdmi, 0x06dc, 0x10);
997 hdmi_phy_i2c_write(hdmi, 0x000a, 0x15);
998 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
999 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
1000 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
1001 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
1002 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
1003 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
1006 hdmi_phy_i2c_write(hdmi, 0x2001, 0x06);
1007 hdmi_phy_i2c_write(hdmi, 0x0b5c, 0x10);
1008 hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
1009 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
1010 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
1011 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
1012 hdmi_phy_i2c_write(hdmi, 0x8009, 0x09);
1013 hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);
1014 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
1017 hdmi_phy_i2c_write(hdmi, 0x4002, 0x06);
1018 hdmi_phy_i2c_write(hdmi, 0x091c, 0x10);
1019 hdmi_phy_i2c_write(hdmi, 0x000f, 0x15);
1020 hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);
1021 hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
1022 hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);
1023 hdmi_phy_i2c_write(hdmi, 0x800b, 0x09);
1024 hdmi_phy_i2c_write(hdmi, 0x0129, 0x0E);
1025 hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);
1032 dev_err(&hdmi->pdev->dev,
1033 "Pixel clock %d - unsupported by HDMI\n",
1034 hdmi->hdmi_data.video_mode.mPixelClock);
1038 /* gen2 tx power on */
1039 val = hdmi_readb(HDMI_PHY_CONF0);
1040 val &= ~HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
1041 val |= HDMI_PHY_CONF0_GEN2_TXPWRON_POWER_ON;
1042 hdmi_writeb(val, HDMI_PHY_CONF0);
1044 val = hdmi_readb(HDMI_PHY_CONF0);
1045 val &= ~HDMI_PHY_CONF0_GEN2_PDDQ_MASK;
1046 val |= HDMI_PHY_CONF0_GEN2_PDDQ_DISABLE;
1047 hdmi_writeb(val, HDMI_PHY_CONF0);
1051 if ((hdmi_readb(HDMI_PHY_STAT0) & 0x01) == 0)
1057 void hdmi_phy_init(struct mxc_hdmi *hdmi, unsigned char de)
1061 val = hdmi_readb(HDMI_PHY_CONF0);
1062 /* set the DE polarity */
1063 val |= (de << HDMI_PHY_CONF0_SELDATAENPOL_OFFSET) &
1064 HDMI_PHY_CONF0_SELDATAENPOL_MASK;
1065 /* set the interface control to 0 */
1066 val |= (0 << HDMI_PHY_CONF0_SELDIPIF_OFFSET) &
1067 HDMI_PHY_CONF0_SELDIPIF_MASK;
1068 /* enable TMDS output */
1069 val |= (1 << HDMI_PHY_CONF0_ENTMDS_OFFSET) &
1070 HDMI_PHY_CONF0_ENTMDS_MASK;
1071 hdmi_writeb(val, HDMI_PHY_CONF0);
1073 /* PHY power enable */
1074 val = hdmi_readb(HDMI_PHY_CONF0);
1075 val |= (1 << HDMI_PHY_CONF0_PDZ_OFFSET) &
1076 HDMI_PHY_CONF0_PDZ_MASK;
1077 hdmi_writeb(val, HDMI_PHY_CONF0);
1079 hdmi_phy_configure(hdmi, 0, 8, FALSE, FALSE, FALSE, FALSE);
1082 void hdmi_tx_hdcp_config(struct mxc_hdmi *hdmi)
1086 if (hdmi->hdmi_data.video_mode.mDataEnablePolarity)
1087 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
1089 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
1091 /* disable rx detect */
1092 val = hdmi_readb(HDMI_A_HDCPCFG0);
1093 val &= HDMI_A_HDCPCFG0_RXDETECT_MASK;
1094 val |= HDMI_A_HDCPCFG0_RXDETECT_DISABLE;
1095 hdmi_writeb(val, HDMI_A_HDCPCFG0);
1097 val = hdmi_readb(HDMI_A_VIDPOLCFG);
1098 val &= HDMI_A_VIDPOLCFG_DATAENPOL_MASK;
1100 hdmi_writeb(val, HDMI_A_VIDPOLCFG);
1102 val = hdmi_readb(HDMI_A_HDCPCFG1);
1103 val &= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_MASK;
1104 val |= HDMI_A_HDCPCFG1_ENCRYPTIONDISABLE_DISABLE;
1105 hdmi_writeb(val, HDMI_A_HDCPCFG1);
1108 void preamble_filter_set(struct mxc_hdmi *hdmi, unsigned char value,
1109 unsigned char channel)
1112 hdmi_writeb(value, HDMI_FC_CH0PREAM);
1113 else if (channel == 1)
1114 hdmi_writeb(value, HDMI_FC_CH1PREAM);
1115 else if (channel == 2)
1116 hdmi_writeb(value, HDMI_FC_CH2PREAM);
1122 static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
1126 u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
1127 struct fb_videomode mode;
1128 const struct fb_videomode *edid_mode;
1131 dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
1133 fb_var_to_videomode(&mode, &hdmi->fbi->var);
1134 /* Use mode from list extracted from EDID to get aspect ratio */
1135 if (!list_empty(&hdmi->fbi->modelist)) {
1136 edid_mode = fb_find_nearest_mode(&mode, &hdmi->fbi->modelist);
1137 if (edid_mode->vmode & FB_VMODE_ASPECT_16_9)
1140 aspect_16_9 = false;
1142 aspect_16_9 = false;
1144 /********************************************
1146 ********************************************/
1147 if (hdmi->edid_cfg.cea_ycbcr444)
1148 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
1149 else if (hdmi->edid_cfg.cea_ycbcr422)
1150 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
1152 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
1155 * Active format identification data is present in the AVI InfoFrame.
1156 * No scan info, no bar data
1159 HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
1160 HDMI_FC_AVICONF0_BAR_DATA_NO_DATA |
1161 HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
1163 hdmi_writeb(val, HDMI_FC_AVICONF0);
1165 /********************************************
1167 ********************************************/
1169 /* Set the Aspect Ratio */
1171 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
1172 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
1174 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
1175 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
1178 /* Set up colorimetry */
1179 if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
1180 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
1181 if (hdmi->hdmi_data.colorimetry == eITU601)
1183 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1184 else /* hdmi->hdmi_data.colorimetry == eITU709 */
1186 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
1187 } else if (hdmi->hdmi_data.enc_out_format != RGB) {
1188 if (hdmi->hdmi_data.colorimetry == eITU601)
1189 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
1190 else /* hdmi->hdmi_data.colorimetry == eITU709 */
1191 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
1192 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1193 } else { /* Carries no data */
1194 colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
1195 ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1198 val = colorimetry | coded_ratio | act_ratio;
1199 hdmi_writeb(val, HDMI_FC_AVICONF1);
1201 /********************************************
1203 ********************************************/
1205 val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
1206 HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
1207 HDMI_FC_AVICONF2_SCALING_NONE;
1208 hdmi_writeb(val, HDMI_FC_AVICONF2);
1210 /********************************************
1212 ********************************************/
1213 hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
1215 /********************************************
1217 ********************************************/
1219 /* Set up input and output pixel repetition */
1220 val = (((hdmi->hdmi_data.video_mode.mPixelRepetitionInput + 1) <<
1221 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
1222 HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
1223 ((hdmi->hdmi_data.video_mode.mPixelRepetitionOutput <<
1224 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
1225 HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
1226 hdmi_writeb(val, HDMI_FC_PRCONF);
1228 /* IT Content and quantization range = don't care */
1229 val = HDMI_FC_AVICONF2_IT_CONTENT_TYPE_GRAPHICS |
1230 HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
1231 hdmi_writeb(val, HDMI_FC_AVICONF3);
1233 /********************************************
1234 * AVI Data Bytes 6-13
1235 ********************************************/
1236 hdmi_writeb(0, HDMI_FC_AVIETB0);
1237 hdmi_writeb(0, HDMI_FC_AVIETB1);
1238 hdmi_writeb(0, HDMI_FC_AVISBB0);
1239 hdmi_writeb(0, HDMI_FC_AVISBB1);
1240 hdmi_writeb(0, HDMI_FC_AVIELB0);
1241 hdmi_writeb(0, HDMI_FC_AVIELB1);
1242 hdmi_writeb(0, HDMI_FC_AVISRB0);
1243 hdmi_writeb(0, HDMI_FC_AVISRB1);
1247 * this submodule is responsible for the video/audio data composition.
1249 void hdmi_av_composer(struct mxc_hdmi *hdmi)
1251 unsigned char i = 0;
1253 struct fb_info *fbi = hdmi->fbi;
1254 struct fb_videomode fb_mode;
1255 struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
1258 fb_var_to_videomode(&fb_mode, &fbi->var);
1260 vmode->mHSyncPolarity =
1261 (fb_mode.sync & FB_SYNC_HOR_HIGH_ACT) ? TRUE : FALSE;
1262 vmode->mVSyncPolarity =
1263 (fb_mode.sync & FB_SYNC_VERT_HIGH_ACT) ? TRUE : FALSE;
1264 vmode->mInterlaced =
1265 (fb_mode.vmode & FB_VMODE_INTERLACED) ? TRUE : FALSE;
1266 vmode->mPixelClock = (fb_mode.xres + fb_mode.left_margin +
1267 fb_mode.right_margin + fb_mode.hsync_len) * (fb_mode.yres +
1268 fb_mode.upper_margin + fb_mode.lower_margin +
1269 fb_mode.vsync_len) * fb_mode.refresh;
1271 /* Expose pixel clock for audio driver */
1272 mxc_hdmi_pixel_clk = vmode->mPixelClock;
1274 dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
1276 /* Set up HDMI_FC_INVIDCONF */
1277 val = ((hdmi->hdmi_data.hdcp_enable == TRUE) ?
1278 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1279 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
1280 val |= ((vmode->mVSyncPolarity == TRUE) ?
1281 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
1282 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_LOW);
1283 val |= ((vmode->mHSyncPolarity == TRUE) ?
1284 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_HIGH :
1285 HDMI_FC_INVIDCONF_HSYNC_IN_POLARITY_ACTIVE_LOW);
1286 val |= ((vmode->mDataEnablePolarity == TRUE) ?
1287 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_HIGH :
1288 HDMI_FC_INVIDCONF_DE_IN_POLARITY_ACTIVE_LOW);
1289 val |= ((vmode->mHdmiDviSel == TRUE) ?
1290 HDMI_FC_INVIDCONF_DVI_MODEZ_HDMI_MODE :
1291 HDMI_FC_INVIDCONF_DVI_MODEZ_DVI_MODE);
1292 if (hdmi->vic == 39)
1293 val |= HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH;
1295 val |= ((vmode->mInterlaced == TRUE) ?
1296 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_HIGH :
1297 HDMI_FC_INVIDCONF_R_V_BLANK_IN_OSC_ACTIVE_LOW);
1298 val |= ((vmode->mInterlaced == TRUE) ?
1299 HDMI_FC_INVIDCONF_IN_I_P_INTERLACED :
1300 HDMI_FC_INVIDCONF_IN_I_P_PROGRESSIVE);
1301 hdmi_writeb(val, HDMI_FC_INVIDCONF);
1303 /* Set up horizontal active pixel region width */
1304 hdmi_writeb(fb_mode.xres,
1306 hdmi_writeb(fb_mode.xres >> 8,
1309 /* Set up horizontal blanking pixel region width */
1310 hblank = fb_mode.left_margin + fb_mode.right_margin +
1312 hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
1313 hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
1315 /* Set up vertical blanking pixel region width */
1316 hdmi_writeb(fb_mode.yres, HDMI_FC_INVACTV0);
1317 hdmi_writeb(fb_mode.yres >> 8, HDMI_FC_INVACTV1);
1319 /* Set up vertical blanking pixel region width */
1320 vblank = fb_mode.upper_margin + fb_mode.lower_margin +
1322 hdmi_writeb(vblank, HDMI_FC_INVBLANK);
1324 /* Set up HSYNC active edge delay width (in pixel clks) */
1325 hdmi_writeb(fb_mode.right_margin, HDMI_FC_HSYNCINDELAY0);
1326 hdmi_writeb(fb_mode.right_margin >> 8, HDMI_FC_HSYNCINDELAY1);
1328 /* Set up HSYNC active pulse width (in pixel clks) */
1329 hdmi_writeb(fb_mode.hsync_len, HDMI_FC_HSYNCINWIDTH0);
1330 hdmi_writeb(fb_mode.hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1);
1332 /* Set up VSYNC active edge delay (in pixel clks) */
1333 hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
1335 /* Set up VSYNC active edge delay (in pixel clks) */
1336 hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
1338 /* control period minimum duration */
1339 hdmi_writeb(12, HDMI_FC_CTRLDUR);
1340 hdmi_writeb(32, HDMI_FC_EXCTRLDUR);
1341 hdmi_writeb(1, HDMI_FC_EXCTRLSPAC);
1343 for (i = 0; i < 3; i++)
1344 preamble_filter_set(hdmi, (i + 1) * 11, i);
1346 /* configure AVI InfoFrame */
1347 hdmi_config_AVI(hdmi);
1350 static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi,
1351 struct fb_info *fbi)
1354 u8 edid_old[HDMI_EDID_LEN];
1357 memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
1360 ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
1361 hdmi->edid, &hdmi->edid_cfg, fbi);
1363 if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN))
1368 static void mxc_hdmi_poweron(struct mxc_hdmi *hdmi)
1370 struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1372 dev_dbg(&hdmi->pdev->dev, "power on\n");
1374 /* Enable pins to HDMI */
1375 if (plat->enable_pins)
1376 plat->enable_pins();
1379 static void mxc_hdmi_poweroff(struct mxc_hdmi *hdmi)
1381 struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1383 dev_dbg(&hdmi->pdev->dev, "power off\n");
1385 /* Disable pins to HDMI */
1386 if (plat->disable_pins)
1387 plat->disable_pins();
1390 static void mxc_hdmi_rx_powerup(struct mxc_hdmi *hdmi)
1394 dev_dbg(&hdmi->pdev->dev, "rx power up\n");
1396 /* Enable HDMI PHY - Set PDDQ=0 and TXPWRON=1 */
1397 val = hdmi_readb(HDMI_PHY_CONF0);
1398 val &= ~(HDMI_PHY_CONF0_GEN2_PDDQ_MASK |
1399 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
1400 val |= HDMI_PHY_CONF0_GEN2_PDDQ_DISABLE |
1401 HDMI_PHY_CONF0_GEN2_TXPWRON_POWER_ON;
1402 hdmi_writeb(val, HDMI_PHY_CONF0);
1404 if (hdmi->need_mode_change && hdmi->fb_reg) {
1405 dev_dbg(&hdmi->pdev->dev, "HDMI changing FB mode\n");
1406 hdmi->fbi->var.activate |= FB_ACTIVATE_FORCE;
1408 hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
1409 fb_set_var(hdmi->fbi, &hdmi->fbi->var);
1410 hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
1412 hdmi->need_mode_change = false;
1416 static void mxc_hdmi_rx_powerdown(struct mxc_hdmi *hdmi)
1420 dev_dbg(&hdmi->pdev->dev, "rx power down\n");
1422 /* Disable HDMI PHY - Set PDDQ=1 and TXPWRON=0 */
1423 val = hdmi_readb(HDMI_PHY_CONF0);
1424 val &= ~(HDMI_PHY_CONF0_GEN2_PDDQ_MASK |
1425 HDMI_PHY_CONF0_GEN2_TXPWRON_MASK);
1426 val |= HDMI_PHY_CONF0_GEN2_PDDQ_ENABLE |
1427 HDMI_PHY_CONF0_GEN2_TXPWRON_POWER_OFF;
1428 hdmi_writeb(val, HDMI_PHY_CONF0);
1431 static int mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
1435 dev_dbg(&hdmi->pdev->dev, "cable connected\n");
1437 hdmi->cable_plugin = true;
1440 ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
1442 dev_err(&hdmi->pdev->dev,
1443 "read edid fail\n");
1445 dev_info(&hdmi->pdev->dev,
1448 if (hdmi->fbi->monspecs.modedb_len > 0) {
1450 const struct fb_videomode *mode;
1451 struct fb_videomode m;
1453 fb_destroy_modelist(&hdmi->fbi->modelist);
1455 for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
1457 * Check whether mode is supported by HDMI.
1458 * We do not currently support interlaced modes
1460 if (mxc_edid_mode_to_vic(&hdmi->fbi->monspecs.modedb[i]) &&
1461 !(hdmi->fbi->monspecs.modedb[i].vmode
1462 & FB_VMODE_INTERLACED))
1463 fb_add_videomode(&hdmi->fbi->monspecs.modedb[i],
1464 &hdmi->fbi->modelist);
1467 fb_var_to_videomode(&m, &hdmi->fbi->var);
1468 mode = fb_find_nearest_mode(&m,
1469 &hdmi->fbi->modelist);
1471 fb_videomode_to_var(&hdmi->fbi->var, mode);
1472 hdmi->need_mode_change = true;
1478 static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
1480 hdmi->cable_plugin = false;
1483 static void det_worker(struct work_struct *work)
1485 struct delayed_work *delay_work = to_delayed_work(work);
1486 struct mxc_hdmi *hdmi =
1487 container_of(delay_work, struct mxc_hdmi, det_work);
1488 u32 phy_int_stat, phy_int_pol, phy_int_mask;
1491 /* Use saved interrupt status, since it was cleared in IST */
1492 phy_int_stat = hdmi->latest_intr_stat;
1493 phy_int_pol = hdmi_readb(HDMI_PHY_POL0);
1495 /* check cable status */
1496 if (phy_int_stat & HDMI_IH_PHY_STAT0_HPD) {
1497 /* cable connection changes */
1498 if (phy_int_pol & HDMI_PHY_HPD) {
1499 dev_dbg(&hdmi->pdev->dev, "EVENT=plugin");
1500 mxc_hdmi_cable_connected(hdmi);
1502 /* Make HPD intr active low to capture unplug event */
1503 val = hdmi_readb(HDMI_PHY_POL0);
1504 val &= ~HDMI_PHY_HPD;
1505 hdmi_writeb(val, HDMI_PHY_POL0);
1506 } else if (!(phy_int_pol & HDMI_PHY_HPD)) {
1507 dev_dbg(&hdmi->pdev->dev, "EVENT=plugout");
1508 mxc_hdmi_cable_disconnected(hdmi);
1510 /* Make HPD intr active high to capture plugin event */
1511 val = hdmi_readb(HDMI_PHY_POL0);
1512 val |= HDMI_PHY_HPD;
1513 hdmi_writeb(val, HDMI_PHY_POL0);
1515 dev_dbg(&hdmi->pdev->dev, "EVENT=none?");
1518 /* check rx power */
1519 if (phy_int_stat & HDMI_IH_PHY_RX_SENSE) {
1520 if ((phy_int_pol & HDMI_PHY_RX_SENSE)) {
1521 mxc_hdmi_rx_powerup(hdmi);
1523 /* Change RX Sense pol to capture RX disable */
1524 val = hdmi_readb(HDMI_PHY_POL0);
1525 val &= ~HDMI_PHY_RX_SENSE;
1526 hdmi_writeb(val, HDMI_PHY_POL0);
1527 } else if (!(phy_int_pol & HDMI_PHY_RX_SENSE)) {
1528 mxc_hdmi_rx_powerdown(hdmi);
1530 /* Change RX Sense pol to capture RX enable */
1531 val = hdmi_readb(HDMI_PHY_POL0);
1532 val |= HDMI_PHY_RX_SENSE;
1533 hdmi_writeb(val, HDMI_PHY_POL0);
1535 dev_err(&hdmi->pdev->dev,
1536 "Received RX sense event but no change\n");
1539 /* Re-enable RX Sense and HPD interrupts */
1540 phy_int_mask = hdmi_readb(HDMI_PHY_MASK0);
1541 phy_int_mask &= ~(HDMI_PHY_RX_SENSE | HDMI_PHY_HPD);
1542 hdmi_writeb(phy_int_mask, HDMI_PHY_MASK0);
1545 static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
1547 struct mxc_hdmi *hdmi = data;
1550 /* Capture status - used in det_worker ISR */
1551 intr_stat = hdmi_readb(HDMI_IH_PHY_STAT0);
1552 if ((intr_stat & (HDMI_IH_PHY_RX_SENSE | HDMI_IH_PHY_STAT0_HPD)) == 0)
1555 dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
1556 hdmi->latest_intr_stat = intr_stat;
1558 /* Unmask interrupts until handled */
1559 val = hdmi_readb(HDMI_PHY_MASK0);
1560 val |= HDMI_PHY_RX_SENSE | HDMI_PHY_HPD;
1561 hdmi_writeb(val, HDMI_PHY_MASK0);
1563 /* Clear Hotplug/RX Sense interrupts */
1564 hdmi_writeb(HDMI_IH_PHY_STAT0_HPD |
1565 HDMI_IH_PHY_STAT0_TX_PHY_LOCK |
1566 HDMI_IH_PHY_STAT0_RX_SENSE0 |
1567 HDMI_IH_PHY_STAT0_RX_SENSE1 |
1568 HDMI_IH_PHY_STAT0_RX_SENSE2 |
1569 HDMI_IH_PHY_STAT0_RX_SENSE3,
1572 schedule_delayed_work(&(hdmi->det_work), msecs_to_jiffies(20));
1577 static int mxc_hdmi_setup(struct mxc_hdmi *hdmi)
1579 struct fb_videomode m;
1580 const struct fb_videomode *edid_mode;
1582 fb_var_to_videomode(&m, &hdmi->fbi->var);
1583 if (!list_empty(&hdmi->fbi->modelist)) {
1584 edid_mode = fb_find_nearest_mode(&m, &hdmi->fbi->modelist);
1586 hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
1590 if (hdmi->vic == 0) {
1591 dev_dbg(&hdmi->pdev->dev, "Non-CEA mode used in HDMI\n");
1592 hdmi->vic = DEFAULT_VIDEO_MODE;
1593 hdmi->hdmi_data.video_mode.mHdmiDviSel = FALSE;
1595 hdmi->hdmi_data.video_mode.mHdmiDviSel = TRUE;
1597 if ((hdmi->vic == 6) || (hdmi->vic == 7) ||
1598 (hdmi->vic == 21) || (hdmi->vic == 22) ||
1599 (hdmi->vic == 2) || (hdmi->vic == 3) ||
1600 (hdmi->vic == 17) || (hdmi->vic == 18))
1601 hdmi->hdmi_data.colorimetry = eITU601;
1603 hdmi->hdmi_data.colorimetry = eITU709;
1605 if ((hdmi->vic == 10) || (hdmi->vic == 11) ||
1606 (hdmi->vic == 12) || (hdmi->vic == 13) ||
1607 (hdmi->vic == 14) || (hdmi->vic == 15) ||
1608 (hdmi->vic == 25) || (hdmi->vic == 26) ||
1609 (hdmi->vic == 27) || (hdmi->vic == 28) ||
1610 (hdmi->vic == 29) || (hdmi->vic == 30) ||
1611 (hdmi->vic == 35) || (hdmi->vic == 36) ||
1612 (hdmi->vic == 37) || (hdmi->vic == 38))
1613 hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 1;
1615 hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
1617 hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
1619 /* TODO: Get input format from IPU (via FB driver iface) */
1620 hdmi->hdmi_data.enc_in_format = eRGB;
1622 hdmi->hdmi_data.enc_out_format = RGB;
1623 if (hdmi->edid_cfg.hdmi_cap) {
1624 if (hdmi->edid_cfg.cea_ycbcr444)
1625 hdmi->hdmi_data.enc_out_format = YCBCR444;
1626 else if (hdmi->edid_cfg.cea_ycbcr422)
1627 hdmi->hdmi_data.enc_out_format = YCBCR422_8BITS;
1630 hdmi->hdmi_data.enc_color_depth = 8;
1631 hdmi->hdmi_data.pix_repet_factor = 0;
1632 hdmi->hdmi_data.hdcp_enable = 0;
1633 hdmi->hdmi_data.video_mode.mDataEnablePolarity = TRUE;
1635 hdmi_video_force_output(hdmi, TRUE);
1636 hdmi_av_composer(hdmi);
1637 hdmi_video_packetize(hdmi);
1638 hdmi_video_csc(hdmi);
1639 hdmi_video_sample(hdmi);
1640 hdmi_tx_hdcp_config(hdmi);
1641 hdmi_phy_init(hdmi, TRUE);
1642 hdmi_video_force_output(hdmi, FALSE);
1647 static int mxc_hdmi_fb_event(struct notifier_block *nb,
1648 unsigned long val, void *v)
1650 struct fb_event *event = v;
1651 struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
1653 if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
1657 case FB_EVENT_FB_REGISTERED:
1658 hdmi->fb_reg = true;
1660 case FB_EVENT_FB_UNREGISTERED:
1661 hdmi->fb_reg = false;
1663 case FB_EVENT_MODE_CHANGE:
1664 mxc_hdmi_setup(hdmi);
1666 case FB_EVENT_BLANK:
1667 if (*((int *)event->data) == FB_BLANK_UNBLANK)
1668 mxc_hdmi_poweron(hdmi);
1670 mxc_hdmi_poweroff(hdmi);
1676 static int mxc_hdmi_disp_init(struct mxc_dispdrv_entry *disp)
1679 struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
1680 struct mxc_dispdrv_setting *setting = mxc_dispdrv_getsetting(disp);
1681 struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1682 int irq = platform_get_irq(hdmi->pdev, 0);
1686 if (!plat || irq < 0)
1689 setting->dev_id = plat->ipu_id;
1690 setting->disp_id = plat->disp_id;
1691 setting->if_fmt = IPU_PIX_FMT_RGB24;
1693 hdmi->fbi = setting->fbi;
1695 /* Claim HDMI pins */
1697 if (!plat->get_pins()) {
1702 /* Initialize HDMI */
1704 plat->init(plat->ipu_id, plat->disp_id);
1706 hdmi->hdmi_clk = clk_get(&hdmi->pdev->dev, "hdmi_isfr_clk");
1707 if (IS_ERR(hdmi->hdmi_clk)) {
1708 ret = PTR_ERR(hdmi->hdmi_clk);
1709 dev_err(&hdmi->pdev->dev,
1710 "Unable to get HDMI clk: %d\n", ret);
1714 ret = clk_enable(hdmi->hdmi_clk);
1716 dev_err(&hdmi->pdev->dev,
1717 "Cannot enable HDMI clock: %d\n", ret);
1720 dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
1722 /* Product and revision IDs */
1723 dev_info(&hdmi->pdev->dev,
1724 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
1725 hdmi_readb(HDMI_DESIGN_ID),
1726 hdmi_readb(HDMI_REVISION_ID),
1727 hdmi_readb(HDMI_PRODUCT_ID0),
1728 hdmi_readb(HDMI_PRODUCT_ID1));
1730 INIT_LIST_HEAD(&hdmi->fbi->modelist);
1732 /* try to read edid */
1733 ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
1735 dev_warn(&hdmi->pdev->dev, "Can not read edid\n");
1736 else if (hdmi->fbi->monspecs.modedb_len > 0) {
1738 const struct fb_videomode *mode;
1739 struct fb_videomode m;
1740 struct fb_var_screeninfo var;
1742 for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
1744 * Check whether mode is supported by HDMI.
1745 * Also, we do not currently support interlaced modes
1747 fb_videomode_to_var(&var, &hdmi->fbi->monspecs.modedb[i]);
1748 if (mxc_edid_mode_to_vic(&hdmi->fbi->monspecs.modedb[i]) &&
1749 !(hdmi->fbi->monspecs.modedb[i].vmode
1750 & FB_VMODE_INTERLACED)) {
1751 dev_dbg(&hdmi->pdev->dev, "Adding mode %d:", i);
1752 dev_dbg(&hdmi->pdev->dev,
1753 "xres = %d, yres = %d, freq = %d\n",
1754 hdmi->fbi->monspecs.modedb[i].xres,
1755 hdmi->fbi->monspecs.modedb[i].yres,
1756 hdmi->fbi->monspecs.modedb[i].refresh);
1758 &hdmi->fbi->monspecs.modedb[i],
1759 &hdmi->fbi->modelist);
1763 fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
1764 setting->dft_mode_str, NULL, 0, NULL,
1765 setting->default_bpp);
1767 fb_var_to_videomode(&m, &hdmi->fbi->var);
1768 mode = fb_find_nearest_mode(&m,
1769 &hdmi->fbi->modelist);
1770 fb_videomode_to_var(&hdmi->fbi->var, mode);
1773 hdmi->need_mode_change = true;
1777 ret = fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
1778 setting->dft_mode_str, NULL, 0, NULL,
1779 setting->default_bpp);
1786 ret = request_irq(irq, mxc_hdmi_hotplug, IRQF_SHARED,
1787 dev_name(&hdmi->pdev->dev), hdmi);
1789 dev_err(&hdmi->pdev->dev,
1790 "Unable to request irq: %d\n", ret);
1794 INIT_DELAYED_WORK(&(hdmi->det_work), det_worker);
1796 /* Configure registers related to HDMI interrupt
1797 * generation before registering IRQ. */
1798 hdmi_writeb(HDMI_PHY_RX_SENSE | HDMI_PHY_HPD,
1801 /* enable cable hot plug irq */
1802 val = HDMI_PHY_RX_SENSE | HDMI_PHY_HPD;
1804 hdmi_writeb(val, HDMI_PHY_MASK0);
1806 /* Clear Hotplug/RX Sense interrupts */
1807 hdmi_writeb(HDMI_IH_PHY_STAT0_HPD |
1808 HDMI_IH_PHY_STAT0_TX_PHY_LOCK |
1809 HDMI_IH_PHY_STAT0_RX_SENSE0 |
1810 HDMI_IH_PHY_STAT0_RX_SENSE1 |
1811 HDMI_IH_PHY_STAT0_RX_SENSE2 |
1812 HDMI_IH_PHY_STAT0_RX_SENSE3,
1815 hdmi_writeb(~(HDMI_IH_PHY_STAT0_HPD |
1816 HDMI_IH_PHY_STAT0_RX_SENSE0 |
1817 HDMI_IH_PHY_STAT0_RX_SENSE1 |
1818 HDMI_IH_PHY_STAT0_RX_SENSE2 |
1819 HDMI_IH_PHY_STAT0_RX_SENSE3),
1820 HDMI_IH_MUTE_PHY_STAT0);
1822 hdmi->nb.notifier_call = mxc_hdmi_fb_event;
1823 ret = fb_register_client(&hdmi->nb);
1827 memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
1829 mxc_hdmi_setup(hdmi);
1834 free_irq(irq, hdmi);
1837 clk_disable(hdmi->hdmi_clk);
1839 clk_put(hdmi->hdmi_clk);
1845 static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_entry *disp)
1847 struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
1848 struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1850 fb_unregister_client(&hdmi->nb);
1852 mxc_hdmi_poweroff(hdmi);
1854 /* Release HDMI pins */
1858 platform_device_unregister(hdmi->pdev);
1863 static struct mxc_dispdrv_driver mxc_hdmi_drv = {
1864 .name = DISPDRV_HDMI,
1865 .init = mxc_hdmi_disp_init,
1866 .deinit = mxc_hdmi_disp_deinit,
1869 static int __devinit mxc_hdmi_probe(struct platform_device *pdev)
1871 struct mxc_hdmi *hdmi;
1874 /* Check that I2C driver is loaded and available */
1878 hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
1880 dev_err(&pdev->dev, "Cannot allocate device data\n");
1887 hdmi->core_pdev = platform_device_alloc("mxc_hdmi_core", -1);
1888 if (!hdmi->core_pdev) {
1889 pr_err("%s failed platform_device_alloc for hdmi core\n",
1895 hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
1896 if (IS_ERR(hdmi->disp_mxc_hdmi)) {
1897 dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
1898 (int)hdmi->disp_mxc_hdmi);
1899 ret = (int)hdmi->disp_mxc_hdmi;
1902 mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
1904 platform_set_drvdata(pdev, hdmi);
1908 platform_device_put(hdmi->core_pdev);
1915 static int mxc_hdmi_remove(struct platform_device *pdev)
1917 struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
1918 int irq = platform_get_irq(pdev, 0);
1920 fb_unregister_client(&hdmi->nb);
1922 /* No new work will be scheduled, wait for running ISR */
1923 free_irq(irq, hdmi);
1924 clk_disable(hdmi->hdmi_clk);
1925 clk_put(hdmi->hdmi_clk);
1931 static struct platform_driver mxc_hdmi_driver = {
1932 .probe = mxc_hdmi_probe,
1933 .remove = mxc_hdmi_remove,
1936 .owner = THIS_MODULE,
1940 static int __init mxc_hdmi_init(void)
1942 return platform_driver_register(&mxc_hdmi_driver);
1944 module_init(mxc_hdmi_init);
1946 static void __exit mxc_hdmi_exit(void)
1948 platform_driver_unregister(&mxc_hdmi_driver);
1950 module_exit(mxc_hdmi_exit);
1953 static int __devinit mxc_hdmi_i2c_probe(struct i2c_client *client,
1954 const struct i2c_device_id *id)
1956 if (!i2c_check_functionality(client->adapter,
1957 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
1965 static int __devexit mxc_hdmi_i2c_remove(struct i2c_client *client)
1971 static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
1972 { "mxc_hdmi_i2c", 0 },
1975 MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
1977 static struct i2c_driver mxc_hdmi_i2c_driver = {
1979 .name = "mxc_hdmi_i2c",
1981 .probe = mxc_hdmi_i2c_probe,
1982 .remove = mxc_hdmi_i2c_remove,
1983 .id_table = mxc_hdmi_i2c_id,
1986 static int __init mxc_hdmi_i2c_init(void)
1988 return i2c_add_driver(&mxc_hdmi_i2c_driver);
1991 static void __exit mxc_hdmi_i2c_exit(void)
1993 i2c_del_driver(&mxc_hdmi_i2c_driver);
1996 module_init(mxc_hdmi_i2c_init);
1997 module_exit(mxc_hdmi_i2c_exit);
1999 MODULE_AUTHOR("Freescale Semiconductor, Inc.");