6a1e0da8cd52de9eb5d3faabb9045c898c663325
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / chips / rk3288 / rk3288_hdmi_hw.c
1 #include <linux/delay.h>
2 #include <linux/interrupt.h>
3 #include "rk3288_hdmi_hw.h"
4
5 static const struct phy_mpll_config_tab PHY_MPLL_TABLE[] = {    /* opmode: 0:HDMI1.4     1:HDMI2.0 */
6 /*      pixclock    pixrepet        colordepth      prepdiv  tmdsmhl opmode  fbdiv2  fbdiv1  ref_cntrl nctrl propctrl intctrl gmpctrl */
7         {27000000,      0,      HDMI_COLOR_DEPTH_8BIT,  0,      0,      0,      2,      3,      0,      3,      7,      0,      3},
8         {27000000,      0,      HDMI_COLOR_DEPTH_10BIT, 1,      0,      0,      5,      1,      0,      3,      3,      0,      0},
9         {27000000,      0,      HDMI_COLOR_DEPTH_12BIT, 2,      0,      0,      3,      3,      0,      3,      3,      0,      0},
10         {27000000,      0,      HDMI_COLOR_DEPTH_16BIT, 3,      0,      0,      2,      3,      0,      2,      5,      0,      1},
11         {74250000,      0,      HDMI_COLOR_DEPTH_8BIT,  0,      0,      0,      4,      3,      3,      2,      7,      0,      3},
12         {74250000,      0,      HDMI_COLOR_DEPTH_10BIT, 1,      0,      0,      5,      3,      3,      2,      7,      0,      2},
13         {74250000,      0,      HDMI_COLOR_DEPTH_12BIT, 2,      0,      0,      1,      2,      0,      1,      7,      0,      2},
14         {74250000,      0,      HDMI_COLOR_DEPTH_16BIT, 3,      0,      0,      1,      3,      0,      1,      7,      0,      2},
15         {148500000,     0,      HDMI_COLOR_DEPTH_8BIT,  0,      0,      0,      1,      1,      0,      1,      0,      0,      3},
16         {148500000,     0,      HDMI_COLOR_DEPTH_10BIT, 1,      0,      0,      5,      1,      3,      1,      7,      0,      3},
17         {148500000,     0,      HDMI_COLOR_DEPTH_12BIT, 2,      0,      0,      1,      2,      1,      0,      7,      0,      3},
18         {148500000,     0,      HDMI_COLOR_DEPTH_16BIT, 3,      0,      0,      1,      1,      0,      0,      7,      0,      3},
19         {297000000,     0,      HDMI_COLOR_DEPTH_8BIT,  0,      0,      0,      1,      0,      0,      0,      0,      0,      3},
20         {297000000,     0,      HDMI_COLOR_DEPTH_10BIT, 1,      3,      1,      5,      0,      3,      0,      7,      0,      3},
21         {297000000,     0,      HDMI_COLOR_DEPTH_12BIT, 2,      3,      1,      1,      2,      2,      0,      7,      0,      3},
22         {297000000,     0,      HDMI_COLOR_DEPTH_16BIT, 3,      3,      1,      1,      1,      0,      0,      5,      0,      3},
23         {594000000,     0,      HDMI_COLOR_DEPTH_8BIT,  0,      3,      1,      1,      0,      0,      0,      3,      0,      3},
24 };
25
26 const struct phy_mpll_config_tab *get_phy_mpll_tab(int pixClock, char pixRepet,
27                                                    char colorDepth)
28 {
29         int i;
30
31         if (pixClock == 0)
32                 return NULL;
33
34         for (i = 0; i < ARRAY_SIZE(PHY_MPLL_TABLE); i++) {
35                 if ((PHY_MPLL_TABLE[i].pix_clock == pixClock)
36                     && (PHY_MPLL_TABLE[i].pix_repet == pixRepet)
37                     && (PHY_MPLL_TABLE[i].color_depth == colorDepth))
38                         return &PHY_MPLL_TABLE[i];
39         }
40         return NULL;
41 }
42
43 static void rk3288_hdmi_av_mute(struct hdmi *hdmi_drv, int enable)
44 {
45         struct rk3288_hdmi_device *hdmi_dev =
46             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
47
48         hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE,
49                      v_FC_SET_AVMUTE(enable));
50 #if 0
51         /* audio mute priority: AVMUTE, sample flat, validity */
52         /* AVMUTE also mutes video */
53         value = enable ? 0xF : 0;
54         hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_SAMPFIT,
55                      v_AUD_PACK_SAMPFIT(value));
56 #endif
57 }
58
59 static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
60 {
61         struct rk3288_hdmi_device *hdmi_dev =
62             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
63         if (hdmi_drv->pwr_mode == mode)
64                 return;
65
66         dev_printk(KERN_INFO, hdmi_drv->dev, "%s change pwr_mode %d --> %d\n",
67                    __func__, hdmi_drv->pwr_mode, mode);
68
69         switch (mode) {
70         case NORMAL:
71                 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x00);
72                 break;
73         case LOWER_PWR:
74                 hdmi_writel(hdmi_dev, MC_CLKDIS, 0xff);
75                 hdmi_msk_reg(hdmi_dev, PHY_CONF0,
76                              m_TMDS_EN | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
77                              v_TMDS_EN(0) | v_TXPWRON_SIG(0) |
78                              v_ENHPD_RXSENSE_SIG(1));
79                 break;
80         default:
81                 hdmi_dbg(hdmi_drv->dev, "unkown hdmi pwr mode %d\n", mode);
82         }
83         hdmi_drv->pwr_mode = mode;
84 }
85
86 /* i2c master reset */
87 void rk3288_hdmi_i2cm_reset(struct rk3288_hdmi_device *hdmi_dev)
88 {
89         hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ, m_I2CM_SOFTRST,
90                      v_I2CM_SOFTRST(0));
91         udelay(100);
92 }
93
94 void rk3288_hdmi_reset(struct hdmi *hdmi_drv)
95 {
96         struct rk3288_hdmi_device *hdmi_dev =
97             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
98
99         hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0x00);
100         udelay(100);
101         hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xff);
102         hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x00);
103         udelay(100);
104         hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x01);
105
106         rk3288_hdmi_i2cm_reset(hdmi_dev);
107 #if 1
108         /* reset PHY */
109         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
110         udelay(100);
111         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
112 #endif
113
114         rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
115 }
116
117 int rk3288_hdmi_detect_hotplug(struct hdmi *hdmi_drv)
118 {
119         struct rk3288_hdmi_device *hdmi_dev =
120             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
121         u32 value = hdmi_readl(hdmi_dev, PHY_STAT0);
122
123         hdmi_dbg(hdmi_drv->dev, "[%s] reg%x value %02x\n", __func__,
124                  PHY_STAT0, value);
125
126         if ((value & m_PHY_HPD) || ((value & 0xf0) == 0xf0))
127                 return HDMI_HPD_ACTIVED;
128         else
129                 return HDMI_HPD_REMOVED;
130 }
131
132 int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff)
133 {
134         int i = 0, n = 0, index = 0, ret = -1, trytime = 2;
135         int offset = (block % 2) * 0x80;
136         int interrupt = 0;
137         struct rk3288_hdmi_device *hdmi_dev =
138             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
139
140         hdmi_dbg(hdmi_drv->dev, "[%s] block %d\n", __func__, block);
141
142         /* Set DDC I2C CLK which devided from DDC_CLK to 100KHz */
143         hdmi_writel(hdmi_dev, I2CM_SS_SCL_HCNT_0_ADDR, 0x7a);
144         hdmi_writel(hdmi_dev, I2CM_SS_SCL_LCNT_0_ADDR, 0x8d);
145         hdmi_msk_reg(hdmi_dev, I2CM_DIV, m_I2CM_FAST_STD_MODE,
146                 v_I2CM_FAST_STD_MODE(STANDARD_MODE));   /* Set Standard Mode */
147
148         /* Enable I2C interrupt for reading edid */
149         hdmi_writel(hdmi_dev, IH_MUTE_I2CM_STAT0,
150                     v_SCDC_READREQ_MUTE(0) | v_I2CM_DONE_MUTE(0) |
151                     v_I2CM_ERR_MUTE(0));
152         hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(0));
153         hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
154                      v_I2CM_NACK_MASK(0) | v_I2CM_ARB_MASK(0));
155
156         hdmi_writel(hdmi_dev, I2CM_SLAVE, DDC_I2C_EDID_ADDR);
157         hdmi_writel(hdmi_dev, I2CM_SEGADDR, DDC_I2C_SEG_ADDR);
158         hdmi_writel(hdmi_dev, I2CM_SEGPTR, block / 2);
159         while (trytime--) {
160                 for (n = 0; n < HDMI_EDID_BLOCK_SIZE / 8; n++) {
161                         hdmi_writel(hdmi_dev, I2CM_ADDRESS, offset + 8 * n);
162                         /* enable extend sequential read operation */
163                         if (block == 0)
164                                 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
165                                              m_I2CM_RD8, v_I2CM_RD8(1));
166                         else
167                                 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
168                                              m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1));
169
170                         i = 20;
171                         while (i--) {
172                                 msleep(1);
173                                 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
174                                 if (interrupt)
175                                         hdmi_writel(hdmi_dev, IH_I2CM_STAT0,
176                                                     interrupt);
177
178                                 if (interrupt &
179                                     (m_SCDC_READREQ | m_I2CM_DONE |
180                                      m_I2CM_ERROR))
181                                         break;
182                                 msleep(4);
183                         }
184
185                         if (interrupt & m_I2CM_DONE) {
186                                 for (index = 0; index < 8; index++) {
187                                         buff[8 * n + index] =
188                                             hdmi_readl(hdmi_dev,
189                                                        I2CM_READ_BUFF0 + index);
190                                 }
191
192                                 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
193                                         ret = 0;
194                                         hdmi_dbg(hdmi_drv->dev,
195                                                  "[%s] edid read sucess\n",
196                                                  __func__);
197
198 #ifdef HDMI_DEBUG
199                                         for (i = 0; i < 128; i++) {
200                                                 printk("%02x ,", buff[i]);
201                                                 if ((i + 1) % 16 == 0)
202                                                         printk("\n");
203                                         }
204 #endif
205                                         goto exit;
206                                 }
207                                 continue;
208                         } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
209                                 hdmi_err(hdmi_drv->dev,
210                                          "[%s] edid read error\n",
211                                          __func__);
212                                 rk3288_hdmi_i2cm_reset(hdmi_dev);
213                                 break;
214                         }
215                 }
216
217                 hdmi_err(hdmi_drv->dev, "[%s] edid try times %d\n",
218                          __func__, trytime);
219                 msleep(100);
220         }
221
222 exit:
223         /* Disable I2C interrupt */
224         hdmi_msk_reg(hdmi_dev, IH_MUTE_I2CM_STAT0,
225                      m_I2CM_DONE_MUTE | m_I2CM_ERR_MUTE,
226                      v_I2CM_DONE_MUTE(1) | v_I2CM_ERR_MUTE(1));
227         hdmi_msk_reg(hdmi_dev, I2CM_INT, m_I2CM_DONE_MASK, v_I2CM_DONE_MASK(1));
228         hdmi_msk_reg(hdmi_dev, I2CM_CTLINT, m_I2CM_NACK_MASK | m_I2CM_ARB_MASK,
229                      v_I2CM_NACK_MASK(1) | v_I2CM_ARB_MASK(1));
230         return ret;
231 }
232
233 static int rk3288_hdmi_video_forceOutput(struct hdmi *hdmi_drv, char enable)
234 {
235         struct rk3288_hdmi_device *hdmi_dev =
236             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
237
238         hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEAUDIO,
239                      v_FC_FORCEAUDIO(0));
240
241         if (enable) {           /* Force output Blue */
242                 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/
243                 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/
244                 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0xff); /*B*/
245                 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO,
246                                  v_FC_FORCEVIDEO(1));
247         } else {
248                 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO,
249                              v_FC_FORCEVIDEO(0));
250                 hdmi_writel(hdmi_dev, FC_DBGTMDS2, 0x00); /*R*/
251                 hdmi_writel(hdmi_dev, FC_DBGTMDS1, 0x00); /*G*/
252                 hdmi_writel(hdmi_dev, FC_DBGTMDS0, 0x00); /*B*/
253         }
254
255         return 0;
256 }
257
258 /* TODO Daisen wait to add support 3D */
259 static int rk3288_hdmi_video_frameComposer(struct hdmi *hdmi_drv,
260                                            struct hdmi_video_para *vpara)
261 {
262         int h_act = 0, v_act = 0;
263         int h_syncdelay = 0, v_syncdelay = 0;
264         int h_sync = 0, v_sync = 0;
265         int h_blank = 0, v_blank = 0;
266         int vsync_pol = hdmi_drv->lcdc->cur_screen->pin_vsync;
267         int hsync_pol = hdmi_drv->lcdc->cur_screen->pin_hsync;
268         int de_pol = (hdmi_drv->lcdc->cur_screen->pin_den == 0) ? 1 : 0;
269         struct fb_videomode *mode = NULL;
270         struct rk3288_hdmi_device *hdmi_dev =
271             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
272
273         mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
274         if (mode == NULL) {
275                 hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__,
276                          vpara->vic);
277                 return -ENOENT;
278         }
279
280         hdmi_drv->pixclock = mode->pixclock;
281         switch (vpara->color_depth) {
282         case HDMI_COLOR_DEPTH_8BIT:
283                 hdmi_drv->tmdsclk = mode->pixclock;
284                 break;
285         case HDMI_COLOR_DEPTH_10BIT:
286                 hdmi_drv->tmdsclk = mode->pixclock * 10 / 8;
287                 break;
288         case HDMI_COLOR_DEPTH_12BIT:
289                 hdmi_drv->tmdsclk = mode->pixclock * 12 / 8;
290                 break;
291         case HDMI_COLOR_DEPTH_16BIT:
292                 hdmi_drv->tmdsclk = mode->pixclock * 2;
293                 break;
294         default:
295                 hdmi_drv->tmdsclk = mode->pixclock;
296                 break;
297         }
298
299         /* cfg to bypass hdcp data encrypt */
300         hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_ENCRYPT_BYPASS | m_HDMI_DVI,
301                      v_ENCRYPT_BYPASS(1) | v_HDMI_DVI(vpara->output_mode));
302         hdmi_msk_reg(hdmi_dev, FC_INVIDCONF,
303                      m_FC_VSYNC_POL | m_FC_HSYNC_POL | m_FC_DE_POL |
304                      m_FC_HDMI_DVI | m_FC_INTERLACE_MODE,
305                      v_FC_VSYNC_POL(vsync_pol) | v_FC_HSYNC_POL(hsync_pol) |
306                      v_FC_DE_POL(de_pol) | v_FC_HDMI_DVI(vpara->
307                                                          output_mode) |
308                      v_FC_INTERLACE_MODE(mode->vmode));
309         hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK,
310                      v_FC_VBLANK(mode->vmode));
311
312         h_act = mode->xres;
313         hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8));
314         hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff));
315
316         v_act = mode->yres;
317         hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8));
318         hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff));
319
320         h_blank = mode->hsync_len + mode->left_margin + mode->right_margin;
321         hdmi_writel(hdmi_dev, FC_INHBLANK1, v_FC_HBLANK1(h_blank >> 8));
322         hdmi_writel(hdmi_dev, FC_INHBLANK0, (h_blank & 0xff));
323
324         v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin;
325         hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff));
326
327         h_syncdelay = mode->right_margin;
328         hdmi_writel(hdmi_dev, FC_HSYNCINDELAY1,
329                     v_FC_HSYNCINDEAY1(h_syncdelay >> 8));
330         hdmi_writel(hdmi_dev, FC_HSYNCINDELAY0, (h_syncdelay & 0xff));
331
332         v_syncdelay = mode->lower_margin;
333         hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff));
334
335         h_sync = mode->hsync_len;
336         hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH1, v_FC_HSYNCWIDTH1(h_sync >> 8));
337         hdmi_writel(hdmi_dev, FC_HSYNCINWIDTH0, (h_sync & 0xff));
338
339         v_sync = mode->vsync_len;
340         hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff));
341
342         /* Set the control period minimum duration
343         * (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)
344         */
345         hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
346         hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
347 #if 0
348         /* used for HDMI 2.0 TX TODO Daisen wait to modify HDCP KEEPOUT */
349         if (hdmi_drv->tmdsclk > 340000000) {
350                 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_HDCP_KEEPOUT,
351                              v_FC_HDCP_KEEPOUT(1));
352                 hdmi_msk_reg(hdmi_dev, FC_SCRAMBLER_CTRL, m_FC_SCRAMBLE_EN,
353                              v_FC_SCRAMBLE_EN(1));
354         }
355
356         /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
357          * worst case: tmdsClock == 25MHz => config <= 19
358         */
359         hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1);
360
361         /* Set PreambleFilter */
362         for (i = 0; i < 3; i++) {
363                 value = (i + 1) * 11;
364                 if (i == 0)             /* channel 0 */
365                         hdmi_writel(hdmi_dev, FC_CH0PREAM, value);
366                 else if (i == 1)        /* channel 1 */
367                         hdmi_writel(hdmi_dev, FC_CH1PREAM, value & 0x3f);
368                 else if (i == 2)        /* channel 2 */
369                         hdmi_writel(hdmi_dev, FC_CH2PREAM, value & 0x3f);
370         }
371 #endif
372         /* Set PixelRepetition:No pixel repetition */
373         hdmi_writel(hdmi_dev, FC_PRCONF,
374                     v_FC_PR_FACTOR(vpara->pixel_repet + 1));
375
376         return 0;
377 }
378
379 static int rk3288_hdmi_video_packetizer(struct hdmi *hdmi_drv,
380                                         struct hdmi_video_para *vpara)
381 {
382         unsigned char color_depth = 0;
383         unsigned char output_select = 0;
384         unsigned char remap_size = 0;
385         struct rk3288_hdmi_device *hdmi_dev =
386             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
387
388         if (vpara->output_color == VIDEO_OUTPUT_RGB444
389             || vpara->output_color == VIDEO_OUTPUT_YCBCR444
390             || vpara->output_color == VIDEO_OUTPUT_YCBCR420) {
391
392                 switch (vpara->color_depth) {
393                 case HDMI_COLOR_DEPTH_8BIT:
394                         color_depth = COLOR_DEPTH_24BIT;
395                         output_select = OUT_FROM_8BIT_BYPASS;
396                         break;
397                 case HDMI_COLOR_DEPTH_10BIT:
398                         color_depth = COLOR_DEPTH_30BIT;
399                         output_select = OUT_FROM_PIXEL_PACKING;
400                         break;
401                 case HDMI_COLOR_DEPTH_12BIT:
402                         color_depth = COLOR_DEPTH_36BIT;
403                         output_select = OUT_FROM_PIXEL_PACKING;
404                         break;
405                 case HDMI_COLOR_DEPTH_16BIT:
406                         color_depth = COLOR_DEPTH_48BIT;
407                         output_select = OUT_FROM_PIXEL_PACKING;
408                         break;
409                 default:
410                         color_depth = COLOR_DEPTH_24BIT;
411                         output_select = OUT_FROM_8BIT_BYPASS;
412                         break;
413                 }
414
415                 /* Config Color Depth */
416                 hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_COLOR_DEPTH,
417                              v_COLOR_DEPTH(color_depth));
418         } else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422) {
419
420                 switch (vpara->color_depth) {
421                 case HDMI_COLOR_DEPTH_8BIT:
422                         remap_size = YCC422_16BIT;
423                         break;
424                 case HDMI_COLOR_DEPTH_10BIT:
425                         remap_size = YCC422_20BIT;
426                         break;
427                 case HDMI_COLOR_DEPTH_12BIT:
428                         remap_size = YCC422_24BIT;
429                         break;
430                 default:
431                         remap_size = YCC422_16BIT;
432                         break;
433                 }
434
435                 output_select = OUT_FROM_YCC422_REMAP;
436                 /* Config remap size for the different color Depth */
437                 hdmi_msk_reg(hdmi_dev, VP_REMAP, m_YCC422_SIZE,
438                              v_YCC422_SIZE(remap_size));
439         } else {
440                 hdmi_err(hdmi_drv->dev, "invalid output color type: %d",
441                          vpara->output_color);
442                 return -1;
443         }
444
445         /* Config pixel repettion */
446         hdmi_msk_reg(hdmi_dev, VP_PR_CD, m_DESIRED_PR_FACTOR,
447                      v_DESIRED_PR_FACTOR(vpara->pixel_repet));
448         if (vpara->pixel_repet > 0)
449                 hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL,
450                              v_PIXEL_REPET_EN(1) | v_BYPASS_SEL(0));
451         else
452                 hdmi_msk_reg(hdmi_dev, VP_CONF, m_PIXEL_REPET_EN | m_BYPASS_SEL,
453                              v_PIXEL_REPET_EN(0) | v_BYPASS_SEL(1));
454
455         /* config output select */
456         if (output_select == OUT_FROM_PIXEL_PACKING) {  /* pixel packing */
457                 hdmi_msk_reg(hdmi_dev, VP_CONF,
458                              m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN |
459                              m_OUTPUT_SEL,
460                              v_BYPASS_EN(0) | v_PIXEL_PACK_EN(1) |
461                              v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
462         } else if (output_select == OUT_FROM_YCC422_REMAP) {    /* YCC422 */
463                 hdmi_msk_reg(hdmi_dev, VP_CONF,
464                              m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN |
465                              m_OUTPUT_SEL,
466                              v_BYPASS_EN(0) | v_PIXEL_PACK_EN(0) |
467                              v_YCC422_EN(1) | v_OUTPUT_SEL(output_select));
468         } else if (output_select == OUT_FROM_8BIT_BYPASS || output_select == 3) {
469                 /* bypass */
470                 hdmi_msk_reg(hdmi_dev, VP_CONF,
471                              m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN |
472                              m_OUTPUT_SEL,
473                              v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
474                              v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
475         }
476 #if defined(HDMI_VIDEO_STUFFING)
477         /* YCC422 and pixel packing stuffing */
478         hdmi_msk_reg(hdmi_dev, VP_STUFF, m_PR_STUFFING, v_PR_STUFFING(1));
479         hdmi_msk_reg(hdmi_dev, VP_STUFF, m_YCC422_STUFFING | m_PP_STUFFING,
480                      v_YCC422_STUFFING(1) | v_PP_STUFFING(1));
481 #endif
482         return 0;
483 }
484
485 int rk3288_hdmi_video_sampler(struct hdmi *hdmi_drv,
486                               struct hdmi_video_para *vpara)
487 {
488         int map_code = 0;
489         struct rk3288_hdmi_device *hdmi_dev =
490             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
491
492         if (vpara->input_color == VIDEO_INPUT_COLOR_RGB
493             || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444
494             || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR420) {
495
496                 switch (vpara->color_depth) {
497                 case HDMI_COLOR_DEPTH_8BIT:
498                         map_code = VIDEO_RGB444_8BIT;
499                         break;
500                 case HDMI_COLOR_DEPTH_10BIT:
501                         map_code = VIDEO_RGB444_10BIT;
502                         break;
503                 case HDMI_COLOR_DEPTH_12BIT:
504                         map_code = VIDEO_RGB444_12BIT;
505                         break;
506                 case HDMI_COLOR_DEPTH_16BIT:
507                         map_code = VIDEO_RGB444_16BIT;
508                         break;
509                 default:
510                         map_code = VIDEO_RGB444_8BIT;
511                         break;
512                 }
513                 map_code +=
514                     (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444) ? 8 : 0;
515         } else if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422) {
516                 /* YCC422 mapping is discontinued - only map 1 is supported */
517                 switch (vpara->color_depth) {
518                 case HDMI_COLOR_DEPTH_8BIT:
519                         map_code = VIDEO_YCBCR422_8BIT;
520                         break;
521                 case HDMI_COLOR_DEPTH_10BIT:
522                         map_code = VIDEO_YCBCR422_10BIT;
523                         break;
524                 case HDMI_COLOR_DEPTH_12BIT:
525                         map_code = VIDEO_YCBCR422_12BIT;
526                         break;
527                 default:
528                         map_code = VIDEO_YCBCR422_8BIT;
529                         break;
530                 }
531         } else {
532                 hdmi_err(hdmi_drv->dev, "invalid input color type: %d",
533                          vpara->input_color);
534                 return -1;
535         }
536
537         /* Set Data enable signal from external
538         * and set video sample input mapping
539         */
540         hdmi_msk_reg(hdmi_dev, TX_INVID0, m_INTERNAL_DE_GEN | m_VIDEO_MAPPING,
541                      v_INTERNAL_DE_GEN(0) | v_VIDEO_MAPPING(map_code));
542
543 #if defined(HDMI_VIDEO_STUFFING)
544         hdmi_writel(hdmi_dev, TX_GYDATA0, 0x00);
545         hdmi_writel(hdmi_dev, TX_GYDATA1, 0x00);
546         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_GYDATA_STUFF,
547                      v_GYDATA_STUFF(1));
548         hdmi_writel(hdmi_dev, TX_RCRDATA0, 0x00);
549         hdmi_writel(hdmi_dev, TX_RCRDATA1, 0x00);
550         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_RCRDATA_STUFF,
551                      v_RCRDATA_STUFF(1));
552         hdmi_writel(hdmi_dev, TX_BCBDATA0, 0x00);
553         hdmi_writel(hdmi_dev, TX_BCBDATA1, 0x00);
554         hdmi_msk_reg(hdmi_dev, TX_INSTUFFING, m_BCBDATA_STUFF,
555                      v_BCBDATA_STUFF(1));
556 #endif
557         return 0;
558 }
559
560 #ifdef HDMI_DEBUG
561 static int rk3288_hdmi_read_phy(struct rk3288_hdmi_device *hdmi_dev,
562                                 int reg_addr)
563 {
564         int trytime = 2, i = 0, op_status = 0;
565         int val = 0;
566
567         while (trytime--) {
568                 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
569                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_1, 0x00);
570                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAI_0, 0x00);
571                 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_READ);
572
573                 i = 20;
574                 while (i--) {
575                         msleep(1);
576                         op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
577                         if (op_status)
578                                 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
579                                             op_status);
580
581                         if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) {
582                                 break;
583                         }
584                         msleep(4);
585                 }
586
587                 if (op_status & m_I2CMPHY_DONE) {
588                         val = hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_1);
589                         val = (val & 0xff) << 8;
590                         val += (hdmi_readl(hdmi_dev, PHY_I2CM_DATAI_0) & 0xff);
591                         hdmi_dbg(hdmi_dev->dev, "phy_reg0x%02x: 0x%04x",
592                                  reg_addr, val);
593                         return val;
594                 } else {
595                         hdmi_err(hdmi_dev->dev,
596                                  "[%s] operation error,trytime=%d\n",
597                                  __func__, trytime);
598                 }
599                 msleep(100);
600         }
601
602         return -1;
603 }
604 #endif
605
606 static int rk3288_hdmi_write_phy(struct rk3288_hdmi_device *hdmi_dev,
607                                  int reg_addr, int val)
608 {
609         int trytime = 2, i = 0, op_status = 0;
610
611         while (trytime--) {
612                 hdmi_writel(hdmi_dev, PHY_I2CM_ADDRESS, reg_addr);
613                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_1, (val >> 8) & 0xff);
614                 hdmi_writel(hdmi_dev, PHY_I2CM_DATAO_0, val & 0xff);
615                 hdmi_writel(hdmi_dev, PHY_I2CM_OPERATION, m_PHY_I2CM_WRITE);
616
617                 i = 20;
618                 while (i--) {
619                         msleep(1);
620                         op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
621                         if (op_status)
622                                 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
623                                             op_status);
624
625                         if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) {
626                                 break;
627                         }
628                         msleep(4);
629                 }
630
631                 if (op_status & m_I2CMPHY_DONE) {
632                         return 0;
633                 } else {
634                         hdmi_err(hdmi_dev->dev,
635                                  "[%s] operation error,trytime=%d\n",
636                                  __func__, trytime);
637                 }
638                 msleep(100);
639         }
640
641         return -1;
642 }
643
644 int rk3288_hdmi_config_phy(struct hdmi *hdmi_drv, unsigned char pixel_repet,
645                            unsigned char color_depth)
646 {
647         int stat = 0, i = 0;
648         const struct phy_mpll_config_tab *phy_mpll = NULL;
649         struct rk3288_hdmi_device *hdmi_dev =
650             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
651
652         hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV, m_PHY_I2CM_FAST_STD,
653                      v_PHY_I2CM_FAST_STD(0));
654
655         /* power on PHY */
656         hdmi_writel(hdmi_dev, PHY_CONF0, 0x3a);
657         /*
658         hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_PDDQ_SIG | m_TXPWRON_SIG,
659                      v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
660         */
661
662         /* reset PHY */
663         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
664         msleep(5);
665         hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
666
667         /* Set slave address as PHY GEN2 address */
668         hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
669
670         /* config the required PHY I2C register */
671         phy_mpll =
672             get_phy_mpll_tab(hdmi_drv->pixclock, pixel_repet, color_depth);
673         if (phy_mpll) {
674                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_OPMODE_PLLCFG,
675                                       v_PREP_DIV(phy_mpll->prep_div) |
676                                       v_TMDS_CNTRL(phy_mpll->tmdsmhl_cntrl) |
677                                       v_OPMODE(phy_mpll->opmode) |
678                                       v_FBDIV2_CNTRL(phy_mpll->fbdiv2_cntrl) |
679                                       v_FBDIV1_CNTRL(phy_mpll->fbdiv1_cntrl) |
680                                       v_REF_CNTRL(phy_mpll->ref_cntrl) |
681                                       v_MPLL_N_CNTRL(phy_mpll->n_cntrl));
682                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_PLLCURRCTRL,
683                                       v_MPLL_PROP_CNTRL(phy_mpll->prop_cntrl) |
684                                       v_MPLL_INT_CNTRL(phy_mpll->int_cntrl));
685                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_PLLGMPCTRL,
686                                       v_MPLL_GMP_CNTRL(phy_mpll->gmp_cntrl));
687         }
688         if (hdmi_drv->pixclock <= 74250000) {
689                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
690                                       v_OVERRIDE(1) | v_SLOPEBOOST(0)
691                                       | v_TX_SYMON(1) | v_TX_TRAON(0) |
692                                       v_TX_TRBON(0) | v_CLK_SYMON(1));
693                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
694                                       v_TX_TERM(R100_Ohms));
695         } else if (hdmi_drv->pixclock == 148500000) {
696                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
697                                       v_OVERRIDE(1) | v_SLOPEBOOST(3)
698                                       | v_TX_SYMON(1) | v_TX_TRAON(0) |
699                                       v_TX_TRBON(0) | v_CLK_SYMON(1));
700                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
701                                       v_TX_TERM(R100_Ohms));
702         } else if (hdmi_drv->pixclock == 297000000) {
703                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_CLKSYMCTRL,
704                                       v_OVERRIDE(1) | v_SLOPEBOOST(2)
705                                       | v_TX_SYMON(1) | v_TX_TRAON(0) |
706                                       v_TX_TRBON(0) | v_CLK_SYMON(1));
707                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
708                                       v_TX_TERM(R100_Ohms));
709         } else if (hdmi_drv->pixclock > 297000000) {
710                 /* TODO Daisen wait to add and modify */
711                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_TERM_RESIS,
712                                       v_TX_TERM(R13333_Ohms));
713         }
714
715         if (hdmi_drv->pixclock < 297000000)
716                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
717                                       v_SUP_TXLVL(20) | v_SUP_CLKLVL(19));
718         else
719                 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
720                                       v_SUP_TXLVL(17) | v_SUP_CLKLVL(16));
721
722         /* power on PHY */
723         hdmi_writel(hdmi_dev, PHY_CONF0, 0x6e);
724         /*
725         hdmi_msk_reg(hdmi_dev, PHY_CONF0,
726                      m_PDDQ_SIG | m_TXPWRON_SIG | m_ENHPD_RXSENSE_SIG,
727                      v_PDDQ_SIG(0) | v_TXPWRON_SIG(1) | v_ENHPD_RXSENSE_SIG(1));
728         */
729
730         /* check if the PHY PLL is locked */
731 #define PHY_TIMEOUT     10000
732         while (i++ < PHY_TIMEOUT) {
733                 if ((i % 100) == 0) {
734                         stat = hdmi_readl(hdmi_dev, PHY_STAT0);
735                         if (stat & m_PHY_LOCK) {
736                                 break;
737                         }
738                 }
739         }
740         if ((stat & m_PHY_LOCK) == 0) {
741                 stat = hdmi_readl(hdmi_dev, MC_LOCKONCLOCK);
742                 hdmi_err(hdmi_dev->dev,
743                          "PHY PLL not locked: PCLK_ON=%d,TMDSCLK_ON=%d\n",
744                          (stat & m_PCLK_ON) >> 6, (stat & m_TMDSCLK_ON) >> 5);
745                 return -1;
746         }
747
748         return 0;
749 }
750
751 int rk3288_hdmi_config_vsi(struct hdmi *hdmi_drv, unsigned char vic_3d,
752                            unsigned char format, int auto_send)
753 {
754         int i = 0;
755         unsigned char data[3] = { 0 };
756         int id = 0x000c03;
757         struct rk3288_hdmi_device *hdmi_dev =
758             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
759
760         hdmi_dbg(hdmi_drv->dev, "[%s] vic %d format %d.\n", __func__,
761                  vic_3d, format);
762         hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO, v_VSD_AUTO(0));
763         hdmi_writel(hdmi_dev, FC_VSDIEEEID0, id & 0xff);
764         hdmi_writel(hdmi_dev, FC_VSDIEEEID1, (id >> 8) & 0xff);
765         hdmi_writel(hdmi_dev, FC_VSDIEEEID2, (id >> 16) & 0xff);
766
767         data[0] = format << 5;          /* PB4 --HDMI_Video_Format */
768         switch (format) {
769         case HDMI_VIDEO_FORMAT_4Kx2K:
770                 data[1] = vic_3d;       /* PB5--HDMI_VIC */
771                 data[2] = 0;
772                 break;
773         case HDMI_VIDEO_FORMAT_3D:
774                 data[1] = vic_3d << 4;  /* PB5--3D_Structure field */
775                 data[2] = 0;            /* PB6--3D_Ext_Data field */
776                 break;
777         default:
778                 data[1] = 0;
779                 data[2] = 0;
780                 break;
781         }
782
783         for (i = 0; i < 3; i++)
784                 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
785
786         if (auto_send) {
787                 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO,
788                              v_VSD_AUTO(auto_send));
789         } else {
790                 hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1));
791         }
792
793         return 0;
794 }
795
796 static void rk3288_hdmi_config_avi(struct hdmi *hdmi_drv, unsigned char vic,
797                                    struct hdmi_video_para *vpara)
798 {
799         unsigned char colorimetry, ext_colorimetry, aspect_ratio, y1y0;
800         unsigned char rgb_quan_range = AVI_QUANTIZATION_RANGE_DEFAULT;
801         struct rk3288_hdmi_device *hdmi_dev =
802             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
803
804         /* Set AVI infoFrame Data byte1 */
805         if (vpara->output_color == VIDEO_OUTPUT_YCBCR444)
806                 y1y0 = AVI_COLOR_MODE_YCBCR444;
807         else if (vpara->output_color == VIDEO_OUTPUT_YCBCR422)
808                 y1y0 = AVI_COLOR_MODE_YCBCR422;
809         else if (vpara->output_color == VIDEO_OUTPUT_YCBCR420)
810                 y1y0 = AVI_COLOR_MODE_YCBCR420;
811         else
812                 y1y0 = AVI_COLOR_MODE_RGB;
813
814         hdmi_msk_reg(hdmi_dev, FC_AVICONF0, m_FC_ACTIV_FORMAT | m_FC_RGC_YCC,
815                      v_FC_RGC_YCC(y1y0) | v_FC_ACTIV_FORMAT(1));
816
817         /* Set AVI infoFrame Data byte2 */
818         switch (vic) {
819         case HDMI_720x480i_60Hz_4_3:
820         case HDMI_720x576i_50Hz_4_3:
821         case HDMI_720x480p_60Hz_4_3:
822         case HDMI_720x576p_50Hz_4_3:
823                 aspect_ratio = AVI_CODED_FRAME_ASPECT_4_3;
824                 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
825                 break;
826         case HDMI_720x480i_60Hz_16_9:
827         case HDMI_720x576i_50Hz_16_9:
828         case HDMI_720x480p_60Hz_16_9:
829         case HDMI_720x576p_50Hz_16_9:
830                 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
831                 colorimetry = AVI_COLORIMETRY_SMPTE_170M;
832                 break;
833         default:
834                 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
835                 colorimetry = AVI_COLORIMETRY_ITU709;
836         }
837
838         if (vpara->color_depth > HDMI_COLOR_DEPTH_8BIT) {
839                 colorimetry = AVI_COLORIMETRY_EXTENDED;
840                 ext_colorimetry = 6;
841         } else if (vpara->output_color == VIDEO_OUTPUT_RGB444) {
842                 colorimetry = AVI_COLORIMETRY_NO_DATA;
843                 ext_colorimetry = 0;
844         }
845
846         hdmi_writel(hdmi_dev, FC_AVICONF1,
847                     v_FC_COLORIMETRY(colorimetry) |
848                     v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
849                     v_FC_ACT_ASPEC_RATIO
850                     (ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME));
851
852         /* Set AVI infoFrame Data byte3 */
853         hdmi_msk_reg(hdmi_dev, FC_AVICONF2,
854                      m_FC_EXT_COLORIMETRY | m_FC_QUAN_RANGE,
855                      v_FC_EXT_COLORIMETRY(ext_colorimetry) |
856                      v_FC_QUAN_RANGE(rgb_quan_range));
857
858         /* Set AVI infoFrame Data byte4 */
859         hdmi_writel(hdmi_dev, FC_AVIVID, (vic & 0xff));
860
861         /* Set AVI infoFrame Data byte5 */
862         hdmi_msk_reg(hdmi_dev, FC_AVICONF3, m_FC_YQ | m_FC_CN,
863                      v_FC_YQ(YQ_LIMITED_RANGE) | v_FC_CN(CN_GRAPHICS));
864
865 }
866
867 static const char coeff_csc[][24] = {
868         /*   G          R           B           Bias    */
869         /*   A1    |    A2     |    A3     |    A4    | */
870         /*   B1    |    B2     |    B3     |    B4    | */
871         /*   C1    |    C2     |    C3     |    C4    | */
872         {       /* CSC_RGB_0_255_TO_RGB_16_235_8BIT */
873          0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,        /* G */
874          0x00, 0x00, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x20,        /* R */
875          0x00, 0x00, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x20,        /* B */
876         },
877         {       /* CSC_RGB_0_255_TO_RGB_16_235_10BIT */
878          0x1b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,        /* G */
879          0x00, 0x00, 0x1b, 0x80, 0x00, 0x00, 0x00, 0x80,        /* R */
880          0x00, 0x00, 0x00, 0x00, 0x1b, 0x80, 0x00, 0x80,        /* B */
881         },
882 #if 0
883         {       /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
884          0x25, 0x91, 0x13, 0x23, 0x07, 0x4c, 0x00, 0x00,        /* Y */
885          0xe5, 0x34, 0x20, 0x00, 0xfa, 0xcc, 0x02, 0x00,        /* Cr */
886          0xea, 0xcd, 0xf5, 0x33, 0x20, 0x00, 0x02, 0x00,        /* Cb */
887         },
888         {       /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
889          0x25, 0x91, 0x13, 0x23, 0x07, 0x4c, 0x00, 0x00,        /* Y */
890          0xe5, 0x34, 0x20, 0x00, 0xfa, 0xcc, 0x08, 0x00,        /* Cr */
891          0xea, 0xcd, 0xf5, 0x33, 0x20, 0x00, 0x08, 0x00,        /* Cb */
892         },
893         {       /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
894          0x2d, 0xc6, 0x0d, 0x9b, 0x04, 0x9f, 0x00, 0x00,        /* Y */
895          0xe2, 0xef, 0x20, 0x00, 0xfd, 0x11, 0x02, 0x00,        /* Cr */
896          0xe7, 0x55, 0xf8, 0xab, 0x20, 0x00, 0x02, 0x00,        /* Cb */
897         },
898         {       /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
899          0x2d, 0xc6, 0x0d, 0x9b, 0x04, 0x9f, 0x00, 0x00,        /* Y */
900          0xe2, 0xef, 0x20, 0x00, 0xfd, 0x11, 0x08, 0x00,        /* Cr */
901          0xe7, 0x55, 0xf8, 0xab, 0x20, 0x00, 0x08, 0x00,        /* Cb */
902         },
903 #else
904         {       /* CSC_RGB_0_255_TO_ITU601_16_235_8BIT */
905          0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x00, 0x40,        /* Y */
906          0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x02, 0x00,        /* Cr */
907          0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x02, 0x00,        /* Cb */
908         },
909         {       /* CSC_RGB_0_255_TO_ITU601_16_235_10BIT */
910          0x20, 0x40, 0x10, 0x80, 0x06, 0x40, 0x01, 0x00,        /* Y */
911          0xe8, 0x80, 0x1c, 0x00, 0xfb, 0x80, 0x08, 0x00,        /* Cr */
912          0xed, 0x80, 0xf6, 0x80, 0x1c, 0x00, 0x08, 0x00,        /* Cb */
913         },
914         {       /* CSC_RGB_0_255_TO_ITU709_16_235_8BIT */
915          0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x00, 0x40,        /* Y */
916          0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x02, 0x00,        /* Cr */
917          0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x02, 0x00,        /* Cb */
918         },
919         {       /* CSC_RGB_0_255_TO_ITU709_16_235_10BIT */
920          0x27, 0x40, 0x0b, 0xc0, 0x04, 0x00, 0x01, 0x00,        /* Y */
921          0xe6, 0x80, 0x1c, 0x00, 0xfd, 0x80, 0x08, 0x00,        /* Cr */
922          0xea, 0x40, 0xf9, 0x80, 0x1c, 0x00, 0x08, 0x00,        /* Cb */
923         },
924 #endif
925         /* Y             Cr          Cb          Bias */
926         {       /* CSC_ITU601_16_235_TO_RGB_0_255_8BIT */
927          0x20, 0x00, 0x69, 0x26, 0x74, 0xfd, 0x01, 0x0e,        /* G */
928          0x20, 0x00, 0x2c, 0xdd, 0x00, 0x00, 0x7e, 0x9a,        /* R */
929          0x20, 0x00, 0x00, 0x00, 0x38, 0xb4, 0x7e, 0x3b,        /* B */
930         },
931         {       /* CSC_ITU709_16_235_TO_RGB_0_255_8BIT */
932          0x20, 0x00, 0x71, 0x06, 0x7a, 0x02, 0x00, 0xa7,        /* G */
933          0x20, 0x00, 0x32, 0x64, 0x00, 0x00, 0x7e, 0x6d,        /* R */
934          0x20, 0x00, 0x00, 0x00, 0x3b, 0x61, 0x7e, 0x25,        /* B */
935         },
936 };
937
938 static int rk3288_hdmi_video_csc(struct hdmi *hdmi_drv,
939                                  struct hdmi_video_para *vpara)
940 {
941         int i, mode, interpolation, decimation, csc_scale;
942         const char *coeff = NULL;
943         unsigned char color_depth = 0;
944         struct rk3288_hdmi_device *hdmi_dev =
945             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
946
947         if ((vpara->input_color == vpara->output_color)
948             && (vpara->color_limit_range == 0)) {
949                 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF,
950                              v_FEED_THROUGH_OFF(0));
951                 return 0;
952         }
953
954         if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422 &&
955             (vpara->output_color == VIDEO_OUTPUT_RGB444
956              || vpara->output_color == VIDEO_OUTPUT_YCBCR444)) {
957                 interpolation = 1;
958                 hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_INTPMODE,
959                              v_CSC_INTPMODE(interpolation));
960         }
961
962         if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB
963              || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444)
964             && vpara->output_color == VIDEO_OUTPUT_YCBCR422) {
965                 decimation = 1;
966                 hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_DECIMODE,
967                              v_CSC_DECIMODE(decimation));
968         }
969
970         switch (vpara->vic) {
971         case HDMI_720x480i_60Hz_4_3:
972         case HDMI_720x576i_50Hz_4_3:
973         case HDMI_720x480p_60Hz_4_3:
974         case HDMI_720x576p_50Hz_4_3:
975         case HDMI_720x480i_60Hz_16_9:
976         case HDMI_720x576i_50Hz_16_9:
977         case HDMI_720x480p_60Hz_16_9:
978         case HDMI_720x576p_50Hz_16_9:
979                 if (vpara->input_color == VIDEO_INPUT_COLOR_RGB
980                     && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) {
981                         mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
982                         csc_scale = 0;
983                 } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444
984                            && vpara->output_color == VIDEO_OUTPUT_RGB444) {
985                         mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
986                         csc_scale = 1;
987                 }
988                 break;
989         default:
990                 if (vpara->input_color == VIDEO_INPUT_COLOR_RGB
991                     && vpara->output_color >= VIDEO_OUTPUT_YCBCR444) {
992                         mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
993                         csc_scale = 0;
994                 } else if (vpara->input_color >= VIDEO_OUTPUT_YCBCR444
995                            && vpara->output_color == VIDEO_OUTPUT_RGB444) {
996                         mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
997                         csc_scale = 1;
998                 }
999                 break;
1000         }
1001
1002         if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB)
1003             && (vpara->output_color == VIDEO_OUTPUT_RGB444)
1004             && (vpara->color_limit_range == 1)) {
1005                 mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
1006                 csc_scale = 1;
1007         }
1008
1009         switch (vpara->color_depth) {
1010         case HDMI_COLOR_DEPTH_8BIT:
1011                 color_depth = COLOR_DEPTH_24BIT;
1012                 break;
1013         case HDMI_COLOR_DEPTH_10BIT:
1014                 color_depth = COLOR_DEPTH_30BIT;
1015                 mode += 1;
1016                 break;
1017         case HDMI_COLOR_DEPTH_12BIT:
1018                 color_depth = COLOR_DEPTH_36BIT;
1019                 mode += 2;
1020                 break;
1021         case HDMI_COLOR_DEPTH_16BIT:
1022                 color_depth = COLOR_DEPTH_48BIT;
1023                 mode += 3;
1024                 break;
1025         default:
1026                 color_depth = COLOR_DEPTH_24BIT;
1027                 break;
1028         }
1029
1030         coeff = coeff_csc[mode];
1031         for (i = 0; i < 24; i++) {
1032                 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
1033         }
1034         hdmi_msk_reg(hdmi_dev, CSC_SCALE, m_CSC_SCALE, v_CSC_SCALE(csc_scale));
1035         /* config CSC_COLOR_DEPTH */
1036         hdmi_msk_reg(hdmi_dev, CSC_SCALE, m_CSC_COLOR_DEPTH,
1037                      v_CSC_COLOR_DEPTH(color_depth));
1038
1039         /* enable CSC */
1040         hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF,
1041                      v_FEED_THROUGH_OFF(1));
1042         return 0;
1043 }
1044
1045 int rk3288_hdmi_config_video(struct hdmi *hdmi_drv,
1046                              struct hdmi_video_para *vpara)
1047 {
1048         rk3288_hdmi_av_mute(hdmi_drv, 1);
1049
1050         if (rk3288_hdmi_video_forceOutput(hdmi_drv, 1) < 0)
1051                 return -1;
1052         if (rk3288_hdmi_video_frameComposer(hdmi_drv, vpara) < 0)
1053                 return -1;
1054         if (rk3288_hdmi_video_packetizer(hdmi_drv, vpara) < 0)
1055                 return -1;
1056         if (rk3288_hdmi_video_csc(hdmi_drv, vpara) < 0)
1057                 return -1;
1058         if (rk3288_hdmi_video_sampler(hdmi_drv, vpara) < 0)
1059                 return -1;
1060
1061         if (vpara->output_mode == OUTPUT_HDMI) {
1062                 rk3288_hdmi_config_avi(hdmi_drv, vpara->vic, vpara);
1063                 hdmi_dbg(hdmi_drv->dev, "[%s] sucess output HDMI.\n",
1064                          __func__);
1065
1066                 if (vpara->format_3d != 0)
1067                         rk3288_hdmi_config_vsi(hdmi_drv, vpara->format_3d,
1068                                                HDMI_VIDEO_FORMAT_3D, 1);
1069 #ifndef HDMI_VERSION_2
1070                 else if ((vpara->vic > 92 && vpara->vic < 96)
1071                          || (vpara->vic == 98)) {
1072                         vpara->vic = (vpara->vic == 98) ? 4 : (96 - vpara->vic);
1073                         rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic,
1074                                                HDMI_VIDEO_FORMAT_4Kx2K, 1);
1075                 }
1076 #endif
1077                 else
1078                         rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic,
1079                                                HDMI_VIDEO_FORMAT_NORMAL, 1);
1080         } else {
1081                 hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n",
1082                          __func__);
1083         }
1084
1085         rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
1086         rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet,
1087                                vpara->color_depth);
1088         return 0;
1089 }
1090
1091 static void rk3288_hdmi_config_aai(struct hdmi *hdmi_drv,
1092                                    struct hdmi_audio *audio)
1093 {
1094         struct rk3288_hdmi_device *hdmi_dev =
1095             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1096
1097         /* Refer to CEA861-E Audio infoFrame */
1098         /* Set both Audio Channel Count and
1099         * Audio Coding Type Refer to Stream Head for HDMI
1100         */
1101         hdmi_msk_reg(hdmi_dev, FC_AUDICONF0, m_FC_CHN_CNT | m_FC_CODING_TYEP,
1102                      v_FC_CHN_CNT(0) | v_FC_CODING_TYEP(0));
1103
1104         /* Set both Audio Sample Size and
1105         * Sample Frequency Refer to Stream Head for HDMI
1106         */
1107         hdmi_msk_reg(hdmi_dev, FC_AUDICONF1,
1108                      m_FC_SAMPLE_SIZE | m_FC_SAMPLE_FREQ,
1109                      v_FC_SAMPLE_SIZE(0) | v_FC_SAMPLE_FREQ(0));
1110
1111         /* Set Channel Allocation */
1112         hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1113
1114         /* Set LFEPBL¡¢DOWN-MIX INH and LSV */
1115         hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1116 }
1117
1118 int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
1119 {
1120         int word_length = 0, channel = 0, mclk_fs;
1121         unsigned int N = 0, CTS = 0;
1122         unsigned char layout_value = 0;
1123         struct rk3288_hdmi_device *hdmi_dev =
1124             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1125
1126         if (audio->channel < 3)
1127                 channel = I2S_CHANNEL_1_2;
1128         else if (audio->channel < 5)
1129                 channel = I2S_CHANNEL_3_4;
1130         else if (audio->channel < 7)
1131                 channel = I2S_CHANNEL_5_6;
1132         else
1133                 channel = I2S_CHANNEL_7_8;
1134
1135         switch (audio->rate) {
1136         case HDMI_AUDIO_FS_32000:
1137                 mclk_fs = FS_256;
1138                 if (hdmi_drv->pixclock >= 594000000)
1139                         N = N_32K_HIGHCLK;
1140                 else if (hdmi_drv->pixclock == 297000000)
1141                         N = N_32K_MIDCLK;
1142                 else
1143                         N = N_32K_LOWCLK;
1144
1145                 /* div a num to avoid the value is exceed 2^32(int) */
1146                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 32);
1147                 break;
1148         case HDMI_AUDIO_FS_44100:
1149                 mclk_fs = FS_256;
1150                 if (hdmi_drv->pixclock >= 594000000)
1151                         N = N_441K_HIGHCLK;
1152                 else if (hdmi_drv->pixclock == 297000000)
1153                         N = N_441K_MIDCLK;
1154                 else
1155                         N = N_441K_LOWCLK;
1156
1157                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 441);
1158                 break;
1159         case HDMI_AUDIO_FS_48000:
1160                 mclk_fs = FS_256;
1161                 if (hdmi_drv->pixclock >= 594000000)    /* FS_153.6 */
1162                         N = N_48K_HIGHCLK;
1163                 else if (hdmi_drv->pixclock == 297000000)
1164                         N = N_48K_MIDCLK;
1165                 else
1166                         N = N_48K_LOWCLK;
1167
1168                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 48);
1169                 break;
1170         case HDMI_AUDIO_FS_88200:
1171                 mclk_fs = FS_256;
1172                 if (hdmi_drv->pixclock >= 594000000)
1173                         N = N_882K_HIGHCLK;
1174                 else if (hdmi_drv->pixclock == 297000000)
1175                         N = N_882K_MIDCLK;
1176                 else
1177                         N = N_882K_LOWCLK;
1178
1179                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 882);
1180                 break;
1181         case HDMI_AUDIO_FS_96000:
1182                 mclk_fs = FS_256;
1183                 if (hdmi_drv->pixclock >= 594000000)    /* FS_153.6 */
1184                         N = N_96K_HIGHCLK;
1185                 else if (hdmi_drv->pixclock == 297000000)
1186                         N = N_96K_MIDCLK;
1187                 else
1188                         N = N_96K_LOWCLK;
1189
1190                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 96);
1191                 break;
1192         case HDMI_AUDIO_FS_176400:
1193                 mclk_fs = FS_256;
1194                 if (hdmi_drv->pixclock >= 594000000)
1195                         N = N_1764K_HIGHCLK;
1196                 else if (hdmi_drv->pixclock == 297000000)
1197                         N = N_1764K_MIDCLK;
1198                 else
1199                         N = N_1764K_LOWCLK;
1200
1201                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 1764);
1202                 break;
1203         case HDMI_AUDIO_FS_192000:
1204                 mclk_fs = FS_256;
1205                 if (hdmi_drv->pixclock >= 594000000)    /* FS_153.6 */
1206                         N = N_192K_HIGHCLK;
1207                 else if (hdmi_drv->pixclock == 297000000)
1208                         N = N_192K_MIDCLK;
1209                 else
1210                         N = N_192K_LOWCLK;
1211
1212                 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 192);
1213                 break;
1214         default:
1215                 hdmi_err(hdmi_drv->dev,
1216                          "[%s] not support such sample rate %d\n", __func__,
1217                          audio->rate);
1218                 return -ENOENT;
1219         }
1220
1221         switch (audio->word_length) {
1222         case HDMI_AUDIO_WORD_LENGTH_16bit:
1223                 word_length = I2S_16BIT_SAMPLE;
1224                 break;
1225         case HDMI_AUDIO_WORD_LENGTH_20bit:
1226                 word_length = I2S_20BIT_SAMPLE;
1227                 break;
1228         case HDMI_AUDIO_WORD_LENGTH_24bit:
1229                 word_length = I2S_24BIT_SAMPLE;
1230                 break;
1231         default:
1232                 word_length = I2S_16BIT_SAMPLE;
1233         }
1234
1235         hdmi_dbg(hdmi_drv->dev, "rate = %d, tmdsclk = %d, N = %d, CTS = %d\n",
1236                  audio->rate, hdmi_drv->tmdsclk, N, CTS);
1237         /* more than 2 channels => layout 1 else layout 0
1238         * TODO Daisen wait to modify
1239         */
1240         layout_value = (audio->channel > 2) ? 1 : 0;
1241         hdmi_msk_reg(hdmi_dev, FC_AUDSCONF, m_AUD_PACK_LAYOUT,
1242                      v_AUD_PACK_LAYOUT(layout_value));
1243
1244         if (hdmi_drv->audio.type == INPUT_SPDIF) {
1245                 hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL,
1246                              v_I2S_SEL(AUDIO_SPDIF_GPA));
1247                 hdmi_msk_reg(hdmi_dev, AUD_SPDIF1, m_SET_NLPCM | m_SPDIF_WIDTH,
1248                              v_SET_NLPCM(PCM_LINEAR) |
1249                              v_SPDIF_WIDTH(word_length));
1250                 /* Mask fifo empty and full int and reset fifo */
1251                 hdmi_msk_reg(hdmi_dev, AUD_SPDIFINT,
1252                              m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1253                              v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1254                 hdmi_msk_reg(hdmi_dev, AUD_SPDIF0, m_SW_SAUD_FIFO_RST,
1255                              v_SW_SAUD_FIFO_RST(1));
1256         } else {
1257                 hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_I2S_SEL | m_I2S_IN_EN,
1258                              v_I2S_SEL(AUDIO_I2S) | v_I2S_IN_EN(channel));
1259                 hdmi_writel(hdmi_dev, AUD_CONF1,
1260                             v_I2S_MODE(I2S_STANDARD_MODE) |
1261                             v_I2S_WIDTH(word_length));
1262                 /* Mask fifo empty and full int and reset fifo */
1263                 hdmi_msk_reg(hdmi_dev, AUD_INT,
1264                              m_FIFO_EMPTY_MASK | m_FIFO_FULL_MASK,
1265                              v_FIFO_EMPTY_MASK(1) | v_FIFO_FULL_MASK(1));
1266                 hdmi_msk_reg(hdmi_dev, AUD_CONF0, m_SW_AUD_FIFO_RST,
1267                              v_SW_AUD_FIFO_RST(1));
1268         }
1269
1270         hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, m_LFS_FACTOR,
1271                      v_LFS_FACTOR(mclk_fs));
1272
1273         /* Set N value */
1274         hdmi_msk_reg(hdmi_dev, AUD_N3, m_AUD_N3, v_AUD_N3(N >> 16));
1275         hdmi_writel(hdmi_dev, AUD_N2, (N >> 8) & 0xff);
1276         hdmi_writel(hdmi_dev, AUD_N1, N & 0xff);
1277         /* Set CTS by manual */
1278         hdmi_msk_reg(hdmi_dev, AUD_CTS3, m_N_SHIFT | m_CTS_MANUAL | m_AUD_CTS3,
1279                      v_N_SHIFT(N_SHIFT_1) | v_CTS_MANUAL(1) | v_AUD_CTS3(CTS >>
1280                                                                          16));
1281         hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
1282         hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
1283
1284         hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE,
1285                      v_AUDCLK_DISABLE(0));
1286         rk3288_hdmi_config_aai(hdmi_drv, audio);
1287
1288         return 0;
1289 }
1290
1291 void rk3288_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
1292 {
1293         hdmi_dbg(hdmi_drv->dev, "[%s] %d\n", __func__, enable);
1294         if (enable == 0) {
1295                 rk3288_hdmi_av_mute(hdmi_drv, 1);
1296         } else {
1297                 if (hdmi_drv->pwr_mode == LOWER_PWR)
1298                         rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
1299
1300                 /* disable blue screen transmission
1301                 * after turning on all necessary blocks
1302                 */
1303                 rk3288_hdmi_video_forceOutput(hdmi_drv, 0);
1304                 rk3288_hdmi_av_mute(hdmi_drv, 0);
1305         }
1306 }
1307
1308 int rk3288_hdmi_insert(struct hdmi *hdmi_drv)
1309 {
1310         struct rk3288_hdmi_device *hdmi_dev =
1311             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1312
1313         /* report HPD state to HDCP (after configuration) */
1314         hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_RX_DETECT, v_RX_DETECT(1));
1315
1316         return 0;
1317 }
1318
1319 int rk3288_hdmi_removed(struct hdmi *hdmi_drv)
1320 {
1321         rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
1322         dev_printk(KERN_INFO, hdmi_drv->dev, "Removed.\n");
1323         return 0;
1324 }
1325
1326 int rk3288_hdmi_initial(struct hdmi *hdmi_drv)
1327 {
1328         int rc = HDMI_ERROR_SUCESS;
1329
1330         hdmi_drv->pwr_mode = NORMAL;
1331         hdmi_drv->insert = rk3288_hdmi_insert;
1332         hdmi_drv->remove = rk3288_hdmi_removed;
1333         hdmi_drv->control_output = rk3288_hdmi_control_output;
1334         hdmi_drv->config_video = rk3288_hdmi_config_video;
1335         hdmi_drv->config_audio = rk3288_hdmi_config_audio;
1336         hdmi_drv->detect_hotplug = rk3288_hdmi_detect_hotplug;
1337         hdmi_drv->read_edid = rk3288_hdmi_read_edid;
1338
1339         rk3288_hdmi_reset(hdmi_drv);
1340
1341         if (hdmi_drv->hdcp_power_on_cb)
1342                 rc = hdmi_drv->hdcp_power_on_cb();
1343
1344         return rc;
1345 }
1346
1347 irqreturn_t hdmi_irq(int irq, void *priv)
1348 {
1349         struct hdmi *hdmi_drv = (struct hdmi *)priv;
1350         struct rk3288_hdmi_device *hdmi_dev =
1351             container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1352         int phy_int = 0, i2cm_int = 0, phy_i2cm_int = 0, cec_int = 0;
1353         int aud_dma_int = 0;
1354
1355         /* read interrupt */
1356         phy_int = hdmi_readl(hdmi_dev, IH_PHY_STAT0);
1357         i2cm_int = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
1358         phy_i2cm_int = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
1359         cec_int = hdmi_readl(hdmi_dev, IH_CEC_STAT0);
1360         aud_dma_int = hdmi_readl(hdmi_dev, IH_AHBDMAAUD_STAT0);
1361         /*
1362         hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
1363         */
1364
1365         /* clear interrupt */
1366         hdmi_writel(hdmi_dev, IH_PHY_STAT0, phy_int);
1367         hdmi_writel(hdmi_dev, IH_I2CM_STAT0, i2cm_int);
1368         hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0, phy_i2cm_int);
1369         hdmi_writel(hdmi_dev, IH_CEC_STAT0, cec_int);
1370         hdmi_writel(hdmi_dev, IH_AHBDMAAUD_STAT0, aud_dma_int);
1371         /*
1372         hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
1373         */
1374
1375         /* HPD or RX_SENSE */
1376         if ((phy_int & m_HPD) || ((phy_int & 0x3c) == 0x3c)) {
1377                 if (hdmi_drv->state == HDMI_SLEEP)
1378                         hdmi_drv->state = WAIT_HOTPLUG;
1379                 queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work,
1380                                    msecs_to_jiffies(5));
1381         }
1382         /* I2CM write or read result */
1383         if (i2cm_int & (m_SCDC_READREQ | m_I2CM_DONE | m_I2CM_ERROR)) {
1384                 /* spin_lock(&hdmi_drv->irq_lock); */
1385                 hdmi_dev->i2cm_int = i2cm_int;
1386                 /* spin_unlock(&hdmi_drv->irq_lock); */
1387         }
1388         /* PHY I2CM write or read result */
1389         if (phy_i2cm_int & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) {
1390                 /* mutex_lock(&hdmi_dev->int_mutex); */
1391                 hdmi_dev->phy_i2cm_int = phy_i2cm_int;
1392                 /* mutex_unlock(&hdmi_dev->int_mutex); */
1393         }
1394         /* CEC */
1395         if (cec_int) {
1396         }
1397         /* HDCP */
1398         if (hdmi_drv->hdcp_irq_cb)
1399                 hdmi_drv->hdcp_irq_cb(i2cm_int);
1400
1401         return IRQ_HANDLED;
1402 }