]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/video/mxc_hdmi.c
ENGR00156319-2 mxc edid: use vmode as aspect rate flag
[karo-tx-linux.git] / drivers / video / mxc_hdmi.c
1 /*
2  * Copyright (C) 2011 Freescale Semiconductor, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 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.
13  *
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
17  *
18  */
19 /*
20  * SH-Mobile High-Definition Multimedia Interface (HDMI) driver
21  * for SLISHDMI13T and SLIPHDMIT IP cores
22  *
23  * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
24  *
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.
28  */
29
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>
37 #include <linux/fb.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>
51
52 #include <linux/console.h>
53 #include <linux/types.h>
54
55 #include <mach/mxc_edid.h>
56 #include "mxc/mxc_dispdrv.h"
57
58 #include <linux/mfd/mxc-hdmi-core.h>
59 #include <mach/mxc_hdmi.h>
60
61 #define DISPDRV_HDMI    "hdmi"
62 #define HDMI_EDID_LEN           512
63
64 #define TRUE 1
65 #define FALSE 0
66
67 #define NUM_CEA_VIDEO_MODES     64
68 #define DEFAULT_VIDEO_MODE      16 /* 1080P */
69
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)
76
77 #define RGB                     0
78 #define YCBCR444                1
79 #define YCBCR422_16BITS         2
80 #define YCBCR422_8BITS          3
81 #define XVYCC444                4
82
83 enum hdmi_datamap {
84         RGB444_8B = 0x01,
85         RGB444_10B = 0x03,
86         RGB444_12B = 0x05,
87         RGB444_16B = 0x07,
88         YCbCr444_8B = 0x09,
89         YCbCr444_10B = 0x0B,
90         YCbCr444_12B = 0x0D,
91         YCbCr444_16B = 0x0F,
92         YCbCr422_8B = 0x16,
93         YCbCr422_10B = 0x14,
94         YCbCr422_12B = 0x12,
95 };
96
97 enum hdmi_csc_enc_format {
98         eRGB = 0x0,
99         eYCC444 = 0x01,
100         eYCC422 = 0x2,
101         eExtended = 0x3,
102 };
103
104 enum hdmi_colorimetry {
105         eITU601,
106         eITU709,
107 };
108
109 struct hdmi_vmode {
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;
118 };
119
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;
128 };
129
130 struct mxc_hdmi {
131         struct platform_device *pdev;
132         struct platform_device *core_pdev;
133         struct mxc_dispdrv_entry *disp_mxc_hdmi;
134         struct fb_info *fbi;
135         struct clk *hdmi_clk;
136         struct delayed_work det_work;
137         struct notifier_block nb;
138
139         struct hdmi_data_info hdmi_data;
140         int vic;
141         struct mxc_edid_cfg edid_cfg;
142         u8 edid[HDMI_EDID_LEN];
143         bool fb_reg;
144         bool need_mode_change;
145         bool cable_plugin;
146         u8 latest_intr_stat;
147 };
148
149 struct i2c_client *hdmi_i2c;
150
151 /*!
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]
157  */
158 void hdmi_video_sample(struct mxc_hdmi *hdmi)
159 {
160         int color_format = 0;
161         u8 val;
162
163         if (hdmi->hdmi_data.enc_in_format == eRGB) {
164                 if (hdmi->hdmi_data.enc_color_depth == 8)
165                         color_format = 0x01;
166                 else if (hdmi->hdmi_data.enc_color_depth == 10)
167                         color_format = 0x03;
168                 else if (hdmi->hdmi_data.enc_color_depth == 12)
169                         color_format = 0x05;
170                 else if (hdmi->hdmi_data.enc_color_depth == 16)
171                         color_format = 0x07;
172                 else
173                         return;
174         } else if (hdmi->hdmi_data.enc_in_format == eYCC444) {
175                 if (hdmi->hdmi_data.enc_color_depth == 8)
176                         color_format = 0x09;
177                 else if (hdmi->hdmi_data.enc_color_depth == 10)
178                         color_format = 0x0B;
179                 else if (hdmi->hdmi_data.enc_color_depth == 12)
180                         color_format = 0x0D;
181                 else if (hdmi->hdmi_data.enc_color_depth == 16)
182                         color_format = 0x0F;
183                 else
184                         return;
185         } else if (hdmi->hdmi_data.enc_in_format == eYCC422) {
186                 if (hdmi->hdmi_data.enc_color_depth == 8)
187                         color_format = 0x16;
188                 else if (hdmi->hdmi_data.enc_color_depth == 10)
189                         color_format = 0x14;
190                 else if (hdmi->hdmi_data.enc_color_depth == 12)
191                         color_format = 0x12;
192                 else
193                         return;
194         }
195
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);
200
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);
212 }
213
214 static int isColorSpaceConversion(struct mxc_hdmi *hdmi)
215 {
216         return (hdmi->hdmi_data.enc_in_format !=
217                         hdmi->hdmi_data.enc_out_format) ? TRUE : FALSE;
218 }
219
220 static int isColorSpaceDecimation(struct mxc_hdmi *hdmi)
221 {
222         return (hdmi->hdmi_data.enc_in_format !=
223                         hdmi->hdmi_data.enc_out_format) ? TRUE : FALSE;
224 }
225
226 static int isColorSpaceInterpolation(struct mxc_hdmi *hdmi)
227 {
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)) ?
231                          TRUE : FALSE;
232 }
233
234 /*!
235  * update the color space conversion coefficients.
236  */
237 void update_csc_coeffs(struct mxc_hdmi *hdmi)
238 {
239         unsigned short csc_coeff[3][4];
240         unsigned int csc_scale = 1;
241         u8 val;
242         bool coeff_selected = false;
243
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;
251
252                                 csc_coeff[1][0] = 0x2000;
253                                 csc_coeff[1][1] = 0x2cdd;
254                                 csc_coeff[1][2] = 0x0000;
255                                 csc_coeff[1][3] = 0x7e9a;
256
257                                 csc_coeff[2][0] = 0x2000;
258                                 csc_coeff[2][1] = 0x0000;
259                                 csc_coeff[2][2] = 0x38b4;
260                                 csc_coeff[2][3] = 0x7e3b;
261
262                                 csc_scale = 1;
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;
269
270                                 csc_coeff[1][0] = 0x2000;
271                                 csc_coeff[1][1] = 0x3264;
272                                 csc_coeff[1][2] = 0x0000;
273                                 csc_coeff[1][3] = 0x7e6d;
274
275                                 csc_coeff[2][0] = 0x2000;
276                                 csc_coeff[2][1] = 0x0000;
277                                 csc_coeff[2][2] = 0x3b61;
278                                 csc_coeff[2][3] = 0x7e25;
279
280                                 csc_scale = 1;
281                                 coeff_selected = true;
282                         }
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;
289
290                                 csc_coeff[1][0] = 0x6535;
291                                 csc_coeff[1][1] = 0x2000;
292                                 csc_coeff[1][2] = 0x7acc;
293                                 csc_coeff[1][3] = 0x0200;
294
295                                 csc_coeff[2][0] = 0x6acd;
296                                 csc_coeff[2][1] = 0x7534;
297                                 csc_coeff[2][2] = 0x2000;
298                                 csc_coeff[2][3] = 0x0200;
299
300                                 csc_scale = 1;
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;
307
308                                 csc_coeff[1][0] = 0x63f0;
309                                 csc_coeff[1][1] = 0x2000;
310                                 csc_coeff[1][2] = 0x7d11;
311                                 csc_coeff[1][3] = 0x0200;
312
313                                 csc_coeff[2][0] = 0x6756;
314                                 csc_coeff[2][1] = 0x78ab;
315                                 csc_coeff[2][2] = 0x2000;
316                                 csc_coeff[2][3] = 0x0200;
317
318                                 csc_scale = 1;
319                                 coeff_selected = true;
320                         }
321                 }
322         }
323
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;
329
330                 csc_coeff[1][0] = 0x0000;
331                 csc_coeff[1][1] = 0x2000;
332                 csc_coeff[1][2] = 0x0000;
333                 csc_coeff[1][3] = 0x0000;
334
335                 csc_coeff[2][0] = 0x0000;
336                 csc_coeff[2][1] = 0x0000;
337                 csc_coeff[2][2] = 0x2000;
338                 csc_coeff[2][3] = 0x0000;
339
340                 csc_scale = 1;
341         }
342
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);
360
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);
377
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);
394
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);
399 }
400
401 void hdmi_video_csc(struct mxc_hdmi *hdmi)
402 {
403         int color_depth = 0;
404         int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
405         int decimation = 0;
406         u8 val;
407
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;
413
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;
422         else
423                 return;
424
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;
429         val |= color_depth;
430         hdmi_writeb(val, HDMI_CSC_SCALE);
431
432         update_csc_coeffs(hdmi);
433 }
434
435 /*!
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.
439  */
440 void hdmi_video_packetize(struct mxc_hdmi *hdmi)
441 {
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;
446         u8 val;
447
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) {
453                         color_depth = 4;
454                         output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS;
455                 } else if (hdmi_data->enc_color_depth == 10)
456                         color_depth = 5;
457                 else if (hdmi_data->enc_color_depth == 12)
458                         color_depth = 6;
459                 else if (hdmi_data->enc_color_depth == 16)
460                         color_depth = 7;
461                 else
462                         return;
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;
471                 else
472                         return;
473                 output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422;
474         } else
475                 return;
476
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);
484
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);
489
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);
505         }
506
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);
511
512         hdmi_writeb(remap_size, HDMI_VP_REMAP);
513
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);
541         } else {
542                 return;
543         }
544
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);
551
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);
556 }
557
558 void hdmi_video_force_output(struct mxc_hdmi *hdmi, unsigned char force)
559 {
560         u8 val;
561
562         if (force == TRUE) {
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);
569         } else {
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 */
576         }
577 }
578
579 static inline void hdmi_phy_test_clear(struct mxc_hdmi *hdmi,
580                                                 unsigned char bit)
581 {
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);
587 }
588
589 static inline void hdmi_phy_test_enable(struct mxc_hdmi *hdmi,
590                                                 unsigned char bit)
591 {
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);
597 }
598
599 static inline void hdmi_phy_test_clock(struct mxc_hdmi *hdmi,
600                                                 unsigned char bit)
601 {
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);
607 }
608
609 static inline void hdmi_phy_test_din(struct mxc_hdmi *hdmi,
610                                                 unsigned char bit)
611 {
612         hdmi_writeb(bit, HDMI_PHY_TST1);
613 }
614
615 static inline void hdmi_phy_test_dout(struct mxc_hdmi *hdmi,
616                                                 unsigned char bit)
617 {
618         hdmi_writeb(bit, HDMI_PHY_TST2);
619 }
620
621 int hdmi_phy_wait_i2c_done(struct mxc_hdmi *hdmi, int msec)
622 {
623         unsigned char val = 0;
624         val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
625         while (val == 0) {
626                 udelay(1000);
627                 if (msec-- == 0)
628                         return FALSE;
629                 val = hdmi_readb(HDMI_IH_I2CMPHY_STAT0) & 0x3;
630         }
631         return TRUE;
632 }
633
634 int hdmi_phy_i2c_write(struct mxc_hdmi *hdmi, unsigned short data,
635                                 unsigned char addr)
636 {
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);
646         return TRUE;
647 }
648
649 unsigned short hdmi_phy_i2c_read(struct mxc_hdmi *hdmi, unsigned char addr)
650 {
651         unsigned short data;
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;
661         return data;
662 }
663
664 int hdmi_phy_i2c_write_verify(struct mxc_hdmi *hdmi, unsigned short data,
665                                 unsigned char addr)
666 {
667         unsigned short val = 0;
668         hdmi_phy_i2c_write(hdmi, data, addr);
669         val = hdmi_phy_i2c_read(hdmi, addr);
670         if (val != data)
671                 return FALSE;
672         return TRUE;
673 }
674
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)
678 {
679         u8 val;
680
681         /* color resolution 0 is 8 bit colour depth */
682         if (cRes == 0)
683                 cRes = 8;
684
685         if (pRep != 0)
686                 return FALSE;
687         else if (cRes != 8 && cRes != 12)
688                 return FALSE;
689
690         if (cscOn)
691                 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
692         else
693                 val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;
694         hdmi_writeb(val, HDMI_MC_FLOWCTRL);
695
696 #if 0
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;
710 #else
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;
724 #endif
725         hdmi_writeb(val, HDMI_MC_CLKDIS);
726
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);
732
733         /* gen2 pddq */
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);
738
739         /* PHY reset */
740         hdmi_writeb(HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
741         hdmi_writeb(HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);
742
743         hdmi_writeb(HDMI_MC_HEACPHY_RST_ASSERT,
744                 HDMI_MC_HEACPHY_RST);
745
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);
750
751         switch (hdmi->hdmi_data.video_mode.mPixelClock) {
752         case 25200000: /* 60 Hz */
753         case 24780000: /* 59 Hz (rounded down from 59.94) */
754                 switch (cRes) {
755                 case 8:
756                         /* PLL/MPLL Cfg */
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 */
766                         /* TX/CK LVL 10 */
767                         hdmi_phy_i2c_write(hdmi, 0x0210, 0x0E);  /* VLEVCTRL */
768                         /* REMOVE CLK TERM */
769                         hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */
770                         break;
771                 case 10:
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);
781                         break;
782                 case 12:
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);
792                         break;
793                 default:
794                         return FALSE;
795                 }
796                 break;
797         case 27000000:
798                 switch (cRes) {
799                 case 8:
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);
809                         break;
810                 case 10:
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);
820                         break;
821                 case 12:
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);
831                         break;
832                 default:
833                         return FALSE;
834                 }
835                 break;
836         case 54000000:
837                 switch (cRes) {
838                 case 8:
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);
848                         break;
849                 case 10:
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);
859                         break;
860                 case 12:
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);
870                         break;
871                 default:
872                         return FALSE;
873                 }
874                 break;
875         case 72000000:
876                 switch (cRes) {
877                 case 8:
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);
887                         break;
888                 case 10:
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);
898                         break;
899                 case 12:
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);
909                         break;
910                 default:
911                         return FALSE;
912                 }
913                 break;
914         case 74250000:
915                 switch (cRes) {
916                 case 8:
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);
926                         break;
927                 case 10:
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);
937                         break;
938                 case 12:
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);
948                         break;
949                 default:
950                         return FALSE;
951                 }
952                 break;
953         case 108000000:
954                 switch (cRes) {
955                 case 8:
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);
965                         break;
966                 case 10:
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);
976                         break;
977                 case 12:
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);
987                         break;
988                 default:
989                         return FALSE;
990                 }
991                 break;
992         case 148500000:
993                 switch (cRes) {
994                 case 8:
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);
1004                         break;
1005                 case 10:
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);
1015                         break;
1016                 case 12:
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);
1026                         break;
1027                 default:
1028                         return FALSE;
1029                 }
1030                 break;
1031         default:
1032                 dev_err(&hdmi->pdev->dev,
1033                                 "Pixel clock %d - unsupported by HDMI\n",
1034                                 hdmi->hdmi_data.video_mode.mPixelClock);
1035                 return FALSE;
1036         }
1037
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);
1043
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);
1048
1049         udelay(1000);
1050
1051         if ((hdmi_readb(HDMI_PHY_STAT0) & 0x01) == 0)
1052                 return FALSE;
1053
1054         return TRUE;
1055 }
1056
1057 void hdmi_phy_init(struct mxc_hdmi *hdmi, unsigned char de)
1058 {
1059         u8 val;
1060
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);
1072
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);
1078
1079         hdmi_phy_configure(hdmi, 0, 8, FALSE, FALSE, FALSE, FALSE);
1080 }
1081
1082 void hdmi_tx_hdcp_config(struct mxc_hdmi *hdmi)
1083 {
1084         u8 de, val;
1085
1086         if (hdmi->hdmi_data.video_mode.mDataEnablePolarity)
1087                 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_HIGH;
1088         else
1089                 de = HDMI_A_VIDPOLCFG_DATAENPOL_ACTIVE_LOW;
1090
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);
1096
1097         val = hdmi_readb(HDMI_A_VIDPOLCFG);
1098         val &= HDMI_A_VIDPOLCFG_DATAENPOL_MASK;
1099         val |= de;
1100         hdmi_writeb(val, HDMI_A_VIDPOLCFG);
1101
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);
1106 }
1107
1108 void preamble_filter_set(struct mxc_hdmi *hdmi, unsigned char value,
1109                                 unsigned char channel)
1110 {
1111         if (channel == 0)
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);
1117         else
1118
1119         return;
1120 }
1121
1122 static void hdmi_config_AVI(struct mxc_hdmi *hdmi)
1123 {
1124         u8 val;
1125         u8 pix_fmt;
1126         u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
1127         struct fb_videomode mode;
1128         const struct fb_videomode *edid_mode;
1129         bool aspect_16_9;
1130
1131         dev_dbg(&hdmi->pdev->dev, "set up AVI frame\n");
1132
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)
1138                         aspect_16_9 = true;
1139                 else
1140                         aspect_16_9 = false;
1141         } else
1142                 aspect_16_9 = false;
1143
1144         /********************************************
1145          * AVI Data Byte 1
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;
1151         else
1152                 pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;
1153
1154         /*
1155          * Active format identification data is present in the AVI InfoFrame.
1156          * No scan info, no bar data
1157          */
1158         val = pix_fmt |
1159                 HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
1160                 HDMI_FC_AVICONF0_BAR_DATA_NO_DATA |
1161                 HDMI_FC_AVICONF0_SCAN_INFO_NODATA;
1162
1163         hdmi_writeb(val, HDMI_FC_AVICONF0);
1164
1165         /********************************************
1166          * AVI Data Byte 2
1167          ********************************************/
1168
1169         /*  Set the Aspect Ratio */
1170         if (aspect_16_9) {
1171                 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
1172                 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
1173         } else {
1174                 act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
1175                 coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
1176         }
1177
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)
1182                         ext_colorimetry =
1183                                 HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
1184                 else /* hdmi->hdmi_data.colorimetry == eITU709 */
1185                         ext_colorimetry =
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;
1196         }
1197
1198         val = colorimetry | coded_ratio | act_ratio;
1199         hdmi_writeb(val, HDMI_FC_AVICONF1);
1200
1201         /********************************************
1202          * AVI Data Byte 3
1203          ********************************************/
1204
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);
1209
1210         /********************************************
1211          * AVI Data Byte 4
1212          ********************************************/
1213         hdmi_writeb(hdmi->vic, HDMI_FC_AVIVID);
1214
1215         /********************************************
1216          * AVI Data Byte 5
1217          ********************************************/
1218
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);
1227
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);
1232
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);
1244 }
1245
1246 /*!
1247  * this submodule is responsible for the video/audio data composition.
1248  */
1249 void hdmi_av_composer(struct mxc_hdmi *hdmi)
1250 {
1251         unsigned char i = 0;
1252         u8 val;
1253         struct fb_info *fbi = hdmi->fbi;
1254         struct fb_videomode fb_mode;
1255         struct hdmi_vmode *vmode = &hdmi->hdmi_data.video_mode;
1256         int hblank, vblank;
1257
1258         fb_var_to_videomode(&fb_mode, &fbi->var);
1259
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;
1270
1271         /* Expose pixel clock for audio driver */
1272         mxc_hdmi_pixel_clk = vmode->mPixelClock;
1273
1274         dev_dbg(&hdmi->pdev->dev, "final pixclk = %d\n", vmode->mPixelClock);
1275
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;
1294         else
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);
1302
1303         /* Set up horizontal active pixel region width */
1304         hdmi_writeb(fb_mode.xres,
1305                         HDMI_FC_INHACTV0);
1306         hdmi_writeb(fb_mode.xres >> 8,
1307                         HDMI_FC_INHACTV1);
1308
1309         /* Set up horizontal blanking pixel region width */
1310         hblank = fb_mode.left_margin + fb_mode.right_margin +
1311                 fb_mode.hsync_len;
1312         hdmi_writeb(hblank, HDMI_FC_INHBLANK0);
1313         hdmi_writeb(hblank >> 8, HDMI_FC_INHBLANK1);
1314
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);
1318
1319         /* Set up vertical blanking pixel region width */
1320         vblank = fb_mode.upper_margin + fb_mode.lower_margin +
1321                 fb_mode.vsync_len;
1322         hdmi_writeb(vblank, HDMI_FC_INVBLANK);
1323
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);
1327
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);
1331
1332         /* Set up VSYNC active edge delay (in pixel clks) */
1333         hdmi_writeb(fb_mode.lower_margin, HDMI_FC_VSYNCINDELAY);
1334
1335         /* Set up VSYNC active edge delay (in pixel clks) */
1336         hdmi_writeb(fb_mode.vsync_len, HDMI_FC_VSYNCINWIDTH);
1337
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);
1342
1343         for (i = 0; i < 3; i++)
1344                 preamble_filter_set(hdmi, (i + 1) * 11, i);
1345
1346         /* configure AVI InfoFrame */
1347         hdmi_config_AVI(hdmi);
1348 }
1349
1350 static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi,
1351                         struct fb_info *fbi)
1352 {
1353         int ret;
1354         u8 edid_old[HDMI_EDID_LEN];
1355
1356         /* save old edid */
1357         memcpy(edid_old, hdmi->edid, HDMI_EDID_LEN);
1358
1359         /* edid reading */
1360         ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
1361                                 hdmi->edid, &hdmi->edid_cfg, fbi);
1362
1363         if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN))
1364                 ret = -2;
1365         return ret;
1366 }
1367
1368 static void mxc_hdmi_poweron(struct mxc_hdmi *hdmi)
1369 {
1370         struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1371
1372         dev_dbg(&hdmi->pdev->dev, "power on\n");
1373
1374         /* Enable pins to HDMI */
1375         if (plat->enable_pins)
1376                 plat->enable_pins();
1377 }
1378
1379 static void mxc_hdmi_poweroff(struct mxc_hdmi *hdmi)
1380 {
1381         struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1382
1383         dev_dbg(&hdmi->pdev->dev, "power off\n");
1384
1385         /* Disable pins to HDMI */
1386         if (plat->disable_pins)
1387                 plat->disable_pins();
1388 }
1389
1390 static void mxc_hdmi_rx_powerup(struct mxc_hdmi *hdmi)
1391 {
1392         u8 val;
1393
1394         dev_dbg(&hdmi->pdev->dev, "rx power up\n");
1395
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);
1403
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;
1407                 console_lock();
1408                 hdmi->fbi->flags |= FBINFO_MISC_USEREVENT;
1409                 fb_set_var(hdmi->fbi, &hdmi->fbi->var);
1410                 hdmi->fbi->flags &= ~FBINFO_MISC_USEREVENT;
1411                 console_unlock();
1412                 hdmi->need_mode_change = false;
1413         }
1414 }
1415
1416 static void mxc_hdmi_rx_powerdown(struct mxc_hdmi *hdmi)
1417 {
1418         u8 val;
1419
1420         dev_dbg(&hdmi->pdev->dev, "rx power down\n");
1421
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);
1429 }
1430
1431 static int mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
1432 {
1433         int ret;
1434
1435         dev_dbg(&hdmi->pdev->dev, "cable connected\n");
1436
1437         hdmi->cable_plugin = true;
1438
1439         /* edid read */
1440         ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
1441         if (ret == -1)
1442                 dev_err(&hdmi->pdev->dev,
1443                                 "read edid fail\n");
1444         else if (ret == -2)
1445                 dev_info(&hdmi->pdev->dev,
1446                                 "same edid\n");
1447         else {
1448                 if (hdmi->fbi->monspecs.modedb_len > 0) {
1449                         int i;
1450                         const struct fb_videomode *mode;
1451                         struct fb_videomode m;
1452
1453                         fb_destroy_modelist(&hdmi->fbi->modelist);
1454
1455                         for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
1456                                 /*
1457                                  * Check whether mode is supported by HDMI.
1458                                  * We do not currently support interlaced modes
1459                                  */
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);
1465                         }
1466
1467                         fb_var_to_videomode(&m, &hdmi->fbi->var);
1468                         mode = fb_find_nearest_mode(&m,
1469                                         &hdmi->fbi->modelist);
1470
1471                         fb_videomode_to_var(&hdmi->fbi->var, mode);
1472                         hdmi->need_mode_change = true;
1473                 }
1474         }
1475         return 0;
1476 }
1477
1478 static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
1479 {
1480         hdmi->cable_plugin = false;
1481 }
1482
1483 static void det_worker(struct work_struct *work)
1484 {
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;
1489         u8 val;
1490
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);
1494
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);
1501
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);
1509
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);
1514                 } else
1515                         dev_dbg(&hdmi->pdev->dev, "EVENT=none?");
1516         }
1517
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);
1522
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);
1529
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);
1534                 } else
1535                         dev_err(&hdmi->pdev->dev,
1536                                 "Received RX sense event but no change\n");
1537         }
1538
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);
1543 }
1544
1545 static irqreturn_t mxc_hdmi_hotplug(int irq, void *data)
1546 {
1547         struct mxc_hdmi *hdmi = data;
1548         u8 val, intr_stat;
1549
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)
1553                 return IRQ_HANDLED;
1554
1555         dev_dbg(&hdmi->pdev->dev, "Hotplug interrupt received\n");
1556         hdmi->latest_intr_stat = intr_stat;
1557
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);
1562
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,
1570                 HDMI_IH_PHY_STAT0);
1571
1572         schedule_delayed_work(&(hdmi->det_work), msecs_to_jiffies(20));
1573
1574         return IRQ_HANDLED;
1575 }
1576
1577 static int mxc_hdmi_setup(struct mxc_hdmi *hdmi)
1578 {
1579         struct fb_videomode m;
1580         const struct fb_videomode *edid_mode;
1581
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);
1585
1586                 hdmi->vic = mxc_edid_mode_to_vic(edid_mode);
1587         } else
1588                 hdmi->vic = 0;
1589
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;
1594         } else
1595                 hdmi->hdmi_data.video_mode.mHdmiDviSel = TRUE;
1596
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;
1602         else
1603                 hdmi->hdmi_data.colorimetry = eITU709;
1604
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;
1614         else
1615                 hdmi->hdmi_data.video_mode.mPixelRepetitionOutput = 0;
1616
1617         hdmi->hdmi_data.video_mode.mPixelRepetitionInput = 0;
1618
1619         /* TODO: Get input format from IPU (via FB driver iface) */
1620         hdmi->hdmi_data.enc_in_format = eRGB;
1621
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;
1628         }
1629
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;
1634
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);
1643
1644         return 0;
1645 }
1646
1647 static int mxc_hdmi_fb_event(struct notifier_block *nb,
1648                                         unsigned long val, void *v)
1649 {
1650         struct fb_event *event = v;
1651         struct mxc_hdmi *hdmi = container_of(nb, struct mxc_hdmi, nb);
1652
1653         if (strcmp(event->info->fix.id, hdmi->fbi->fix.id))
1654                 return 0;
1655
1656         switch (val) {
1657         case FB_EVENT_FB_REGISTERED:
1658                 hdmi->fb_reg = true;
1659                 break;
1660         case FB_EVENT_FB_UNREGISTERED:
1661                 hdmi->fb_reg = false;
1662                 break;
1663         case FB_EVENT_MODE_CHANGE:
1664                 mxc_hdmi_setup(hdmi);
1665                 break;
1666         case FB_EVENT_BLANK:
1667                 if (*((int *)event->data) == FB_BLANK_UNBLANK)
1668                         mxc_hdmi_poweron(hdmi);
1669                 else
1670                         mxc_hdmi_poweroff(hdmi);
1671                 break;
1672         }
1673         return 0;
1674 }
1675
1676 static int mxc_hdmi_disp_init(struct mxc_dispdrv_entry *disp)
1677 {
1678         int ret = 0;
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);
1683         bool found = false;
1684         u8 val;
1685
1686         if (!plat || irq < 0)
1687                 return -ENODEV;
1688
1689         setting->dev_id = plat->ipu_id;
1690         setting->disp_id = plat->disp_id;
1691         setting->if_fmt = IPU_PIX_FMT_RGB24;
1692
1693         hdmi->fbi = setting->fbi;
1694
1695         /* Claim HDMI pins */
1696         if (plat->get_pins)
1697                 if (!plat->get_pins()) {
1698                         ret = -EACCES;
1699                         goto egetpins;
1700                 }
1701
1702         /* Initialize HDMI */
1703         if (plat->init)
1704                 plat->init(plat->ipu_id, plat->disp_id);
1705
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);
1711                 goto egetclk;
1712         }
1713
1714         ret = clk_enable(hdmi->hdmi_clk);
1715         if (ret < 0) {
1716                 dev_err(&hdmi->pdev->dev,
1717                         "Cannot enable HDMI clock: %d\n", ret);
1718                 goto erate;
1719         }
1720         dev_dbg(&hdmi->pdev->dev, "Enabled HDMI clocks\n");
1721
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));
1729
1730         INIT_LIST_HEAD(&hdmi->fbi->modelist);
1731
1732         /* try to read edid */
1733         ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
1734         if (ret < 0)
1735                 dev_warn(&hdmi->pdev->dev, "Can not read edid\n");
1736         else if (hdmi->fbi->monspecs.modedb_len > 0) {
1737                 int i;
1738                 const struct fb_videomode *mode;
1739                 struct fb_videomode m;
1740                 struct fb_var_screeninfo var;
1741
1742                 for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
1743                         /*
1744                          * Check whether mode is supported by HDMI.
1745                          * Also, we do not currently support interlaced modes
1746                          */
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);
1757                                 fb_add_videomode(
1758                                         &hdmi->fbi->monspecs.modedb[i],
1759                                         &hdmi->fbi->modelist);
1760                         }
1761                 }
1762
1763                 fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
1764                         setting->dft_mode_str, NULL, 0, NULL,
1765                         setting->default_bpp);
1766
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);
1771                 found = 1;
1772
1773                 hdmi->need_mode_change = true;
1774         }
1775
1776         if (!found) {
1777                 ret = fb_find_mode(&hdmi->fbi->var, hdmi->fbi,
1778                                         setting->dft_mode_str, NULL, 0, NULL,
1779                                         setting->default_bpp);
1780                 if (!ret) {
1781                         ret = -EINVAL;
1782                         goto efindmode;
1783                 }
1784         }
1785
1786         ret = request_irq(irq, mxc_hdmi_hotplug, IRQF_SHARED,
1787                           dev_name(&hdmi->pdev->dev), hdmi);
1788         if (ret < 0) {
1789                 dev_err(&hdmi->pdev->dev,
1790                         "Unable to request irq: %d\n", ret);
1791                 goto ereqirq;
1792         }
1793
1794         INIT_DELAYED_WORK(&(hdmi->det_work), det_worker);
1795
1796         /* Configure registers related to HDMI interrupt
1797          * generation before registering IRQ. */
1798         hdmi_writeb(HDMI_PHY_RX_SENSE | HDMI_PHY_HPD,
1799                 HDMI_PHY_POL0);
1800
1801         /* enable cable hot plug irq */
1802         val = HDMI_PHY_RX_SENSE | HDMI_PHY_HPD;
1803         val = ~val;
1804         hdmi_writeb(val, HDMI_PHY_MASK0);
1805
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,
1813                 HDMI_IH_PHY_STAT0);
1814
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);
1821
1822         hdmi->nb.notifier_call = mxc_hdmi_fb_event;
1823         ret = fb_register_client(&hdmi->nb);
1824         if (ret < 0)
1825                 goto efbclient;
1826
1827         memset(&hdmi->hdmi_data, 0, sizeof(struct hdmi_data_info));
1828
1829         mxc_hdmi_setup(hdmi);
1830
1831         return ret;
1832
1833 efbclient:
1834         free_irq(irq, hdmi);
1835 efindmode:
1836 ereqirq:
1837         clk_disable(hdmi->hdmi_clk);
1838 erate:
1839         clk_put(hdmi->hdmi_clk);
1840 egetclk:
1841 egetpins:
1842         return ret;
1843 }
1844
1845 static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_entry *disp)
1846 {
1847         struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
1848         struct fsl_mxc_hdmi_platform_data *plat = hdmi->pdev->dev.platform_data;
1849
1850         fb_unregister_client(&hdmi->nb);
1851
1852         mxc_hdmi_poweroff(hdmi);
1853
1854         /* Release HDMI pins */
1855         if (plat->put_pins)
1856                 plat->put_pins();
1857
1858         platform_device_unregister(hdmi->pdev);
1859
1860         kfree(hdmi);
1861 }
1862
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,
1867 };
1868
1869 static int __devinit mxc_hdmi_probe(struct platform_device *pdev)
1870 {
1871         struct mxc_hdmi *hdmi;
1872         int ret = 0;
1873
1874         /* Check that I2C driver is loaded and available */
1875         if (!hdmi_i2c)
1876                 return -ENODEV;
1877
1878         hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL);
1879         if (!hdmi) {
1880                 dev_err(&pdev->dev, "Cannot allocate device data\n");
1881                 ret = -ENOMEM;
1882                 goto ealloc;
1883         }
1884
1885         hdmi->pdev = pdev;
1886
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",
1890                         __func__);
1891                 ret = -ENOMEM;
1892                 goto ecore;
1893         }
1894
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;
1900                 goto edispdrv;
1901         }
1902         mxc_dispdrv_setdata(hdmi->disp_mxc_hdmi, hdmi);
1903
1904         platform_set_drvdata(pdev, hdmi);
1905
1906         return 0;
1907 edispdrv:
1908         platform_device_put(hdmi->core_pdev);
1909 ecore:
1910         kfree(hdmi);
1911 ealloc:
1912         return ret;
1913 }
1914
1915 static int mxc_hdmi_remove(struct platform_device *pdev)
1916 {
1917         struct mxc_hdmi *hdmi = platform_get_drvdata(pdev);
1918         int irq = platform_get_irq(pdev, 0);
1919
1920         fb_unregister_client(&hdmi->nb);
1921
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);
1926         kfree(hdmi);
1927
1928         return 0;
1929 }
1930
1931 static struct platform_driver mxc_hdmi_driver = {
1932         .probe = mxc_hdmi_probe,
1933         .remove = mxc_hdmi_remove,
1934         .driver = {
1935                    .name = "mxc_hdmi",
1936                    .owner = THIS_MODULE,
1937         },
1938 };
1939
1940 static int __init mxc_hdmi_init(void)
1941 {
1942         return platform_driver_register(&mxc_hdmi_driver);
1943 }
1944 module_init(mxc_hdmi_init);
1945
1946 static void __exit mxc_hdmi_exit(void)
1947 {
1948         platform_driver_unregister(&mxc_hdmi_driver);
1949 }
1950 module_exit(mxc_hdmi_exit);
1951
1952
1953 static int __devinit mxc_hdmi_i2c_probe(struct i2c_client *client,
1954                 const struct i2c_device_id *id)
1955 {
1956         if (!i2c_check_functionality(client->adapter,
1957                                 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
1958                 return -ENODEV;
1959
1960         hdmi_i2c = client;
1961
1962         return 0;
1963 }
1964
1965 static int __devexit mxc_hdmi_i2c_remove(struct i2c_client *client)
1966 {
1967         hdmi_i2c = NULL;
1968         return 0;
1969 }
1970
1971 static const struct i2c_device_id mxc_hdmi_i2c_id[] = {
1972         { "mxc_hdmi_i2c", 0 },
1973         {},
1974 };
1975 MODULE_DEVICE_TABLE(i2c, mxc_hdmi_i2c_id);
1976
1977 static struct i2c_driver mxc_hdmi_i2c_driver = {
1978         .driver = {
1979                    .name = "mxc_hdmi_i2c",
1980                    },
1981         .probe = mxc_hdmi_i2c_probe,
1982         .remove = mxc_hdmi_i2c_remove,
1983         .id_table = mxc_hdmi_i2c_id,
1984 };
1985
1986 static int __init mxc_hdmi_i2c_init(void)
1987 {
1988         return i2c_add_driver(&mxc_hdmi_i2c_driver);
1989 }
1990
1991 static void __exit mxc_hdmi_i2c_exit(void)
1992 {
1993         i2c_del_driver(&mxc_hdmi_i2c_driver);
1994 }
1995
1996 module_init(mxc_hdmi_i2c_init);
1997 module_exit(mxc_hdmi_i2c_exit);
1998
1999 MODULE_AUTHOR("Freescale Semiconductor, Inc.");