video: rockchip: hdmiv1: fix no sound/noise problem
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / rockchip-hdmiv1 / rockchip_hdmiv1_hw.c
1 #include <linux/delay.h>
2 #include <linux/io.h>
3 #include <linux/interrupt.h>
4 #include <linux/of_irq.h>
5 #include "rockchip_hdmiv1.h"
6 #include "rockchip_hdmiv1_hw.h"
7 #include "rockchip_hdmiv1_hdcp.h"
8
9 static inline void delay100us(void)
10 {
11         usleep_range(99, 100);
12 }
13
14 static void rockchip_hdmiv1_av_mute(struct hdmi *hdmi_drv, bool enable)
15 {
16         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
17
18         if (enable) {
19                 hdmi_msk_reg(hdmi_dev, AV_MUTE,
20                              m_AVMUTE_CLEAR | m_AVMUTE_ENABLE,
21                              v_AVMUTE_CLEAR(0) | v_AVMUTE_ENABLE(1));
22         } else {
23                 hdmi_msk_reg(hdmi_dev, AV_MUTE,
24                              m_AVMUTE_CLEAR | m_AVMUTE_ENABLE,
25                              v_AVMUTE_CLEAR(1) | v_AVMUTE_ENABLE(0));
26         }
27         hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO,
28                      m_PACKET_GCP_EN, v_PACKET_GCP_EN(1));
29 }
30
31 static void rockchip_hdmiv1_sys_power(struct hdmi *hdmi_drv, bool enable)
32 {
33         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
34
35         if (enable)
36                 hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_ON);
37         else
38                 hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_OFF);
39 }
40
41 static void rockchip_hdmiv1_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
42 {
43         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
44
45         if (hdmi_dev->pwr_mode == mode)
46                 return;
47
48         dev_info(hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __func__,
49                  hdmi_dev->pwr_mode, mode);
50
51         switch (mode) {
52         case NORMAL:
53                 dev_info(hdmi_drv->dev,
54                          "%s change pwr_mode NORMAL\n",
55                          __func__);
56                 rockchip_hdmiv1_sys_power(hdmi_drv, false);
57                 if (hdmi_dev->soctype == HDMI_SOC_RK3036) {
58                         hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x6f);
59                         hdmi_writel(hdmi_dev, PHY_DRIVER, 0xbb);
60                 } else if (hdmi_dev->soctype == HDMI_SOC_RK312X) {
61                         hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x5f);
62                         hdmi_writel(hdmi_dev, PHY_DRIVER, 0xaa);
63                 }
64
65                 hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x15);
66                 hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x14);
67                 hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x10);
68                 hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f);
69                 hdmi_writel(hdmi_dev, 0xce, 0x00);
70                 hdmi_writel(hdmi_dev, 0xce, 0x01);
71                 rockchip_hdmiv1_sys_power(hdmi_drv, true);
72                 break;
73         case LOWER_PWR:
74                 dev_info(hdmi_drv->dev,
75                          "%s change pwr_mode LOWER_PWR\n",
76                          __func__);
77                 rockchip_hdmiv1_sys_power(hdmi_drv, false);
78                 hdmi_writel(hdmi_dev, PHY_DRIVER, 0x00);
79                 hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x00);
80                 hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x00);
81                 hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x17);
82                 break;
83         default:
84                 dev_info(hdmi_drv->dev, "unkown rk3036 hdmi pwr mode %d\n",
85                          mode);
86         }
87
88         hdmi_dev->pwr_mode = mode;
89 }
90
91 int rockchip_hdmiv1_detect_hotplug(struct hdmi *hdmi_drv)
92 {
93         int value = 0;
94         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
95
96         hdmi_readl(hdmi_dev, HDMI_STATUS, &value);
97         value &= m_HOTPLUG;
98         if (value == m_HOTPLUG)
99                 return HDMI_HPD_ACTIVED;
100         else if (value)
101                 return HDMI_HPD_INSERT;
102         else
103                 return HDMI_HPD_REMOVED;
104 }
105
106 int rockchip_hdmiv1_insert(struct hdmi *hdmi_drv)
107 {
108         rockchip_hdmiv1_set_pwr_mode(hdmi_drv, NORMAL);
109         return 0;
110 }
111
112
113 int rockchip_hdmiv1_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf)
114 {
115         u32 c = 0;
116         u8 segment = 0;
117         u8 offset = 0;
118         int ret = -1;
119         int i, j;
120         int ddc_bus_freq;
121         int trytime;
122         int checksum = 0;
123         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
124
125         if (block % 2)
126                 offset = HDMI_EDID_BLOCK_SIZE;
127
128         if (block / 2)
129                 segment = 1;
130         ddc_bus_freq = (hdmi_dev->hclk_rate >> 2) / HDMI_SCL_RATE;
131         hdmi_writel(hdmi_dev, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
132         hdmi_writel(hdmi_dev, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
133
134         dev_info(hdmi_drv->dev,
135                  "EDID DATA (Segment = %d Block = %d Offset = %d):\n",
136                  (int)segment, (int)block, (int)offset);
137         disable_irq(hdmi_dev->irq);
138
139         /* Enable edid interrupt */
140         hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_EDID_READY);
141
142         for (trytime = 0; trytime < 10; trytime++) {
143                 checksum = 0;
144                 hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, 0x04);
145
146                 /* Set edid fifo first addr */
147                 hdmi_writel(hdmi_dev, EDID_FIFO_OFFSET, 0x00);
148
149                 /* Set edid word address 0x00/0x80 */
150                 hdmi_writel(hdmi_dev, EDID_WORD_ADDR, offset);
151
152                 /* Set edid segment pointer */
153                 hdmi_writel(hdmi_dev, EDID_SEGMENT_POINTER, segment);
154
155                 for (i = 0; i < 200; i++) {
156                         /* Wait edid interrupt */
157                         usleep_range(900, 1000);
158                         c = 0x00;
159                         hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &c);
160
161                         if (c & m_INT_EDID_READY)
162                                 break;
163                 }
164
165                 if (c & m_INT_EDID_READY) {
166                         for (j = 0; j < HDMI_EDID_BLOCK_SIZE; j++) {
167                                 c = 0;
168                                 hdmi_readl(hdmi_dev, 0x50, &c);
169                                 buf[j] = c;
170                                 checksum += c;
171 #ifdef HDMI_DEBUG
172                                 if (j % 16 == 0)
173                                         printk("\n>>>0x%02x: ", j);
174                                 printk("0x%02x ", c);
175 #endif
176                         }
177
178                         if ((checksum & 0xff) == 0) {
179                                 ret = 0;
180                                 dev_info(hdmi_drv->dev,
181                                          "[%s] edid read sucess\n", __func__);
182                                 break;
183                         }
184                 }
185         }
186         /*close edid irq*/
187         hdmi_writel(hdmi_dev, INTERRUPT_MASK1, 0);
188         /* clear EDID interrupt reg */
189         hdmi_writel(hdmi_dev, INTERRUPT_STATUS1,
190                     m_INT_EDID_READY);
191
192         enable_irq(hdmi_dev->irq);
193
194         return ret;
195 }
196
197 static const char coeff_csc[][24] = {
198         /*YUV2RGB:601 SD mode(Y[16:235],UV[16:240],RGB[0:255]):
199             R = 1.164*Y +1.596*V - 204
200             G = 1.164*Y - 0.391*U - 0.813*V + 154
201             B = 1.164*Y + 2.018*U - 258*/
202         {
203         0x04, 0xa7, 0x00, 0x00, 0x06, 0x62, 0x02, 0xcc,
204         0x04, 0xa7, 0x11, 0x90, 0x13, 0x40, 0x00, 0x9a,
205         0x04, 0xa7, 0x08, 0x12, 0x00, 0x00, 0x03, 0x02},
206
207         /*YUV2RGB:601 SD mode(YUV[0:255],RGB[0:255]):
208             R = Y + 1.402*V - 248
209             G = Y - 0.344*U - 0.714*V + 135
210             B = Y + 1.772*U - 227*/
211         {
212         0x04, 0x00, 0x00, 0x00, 0x05, 0x9b, 0x02, 0xf8,
213         0x04, 0x00, 0x11, 0x60, 0x12, 0xdb, 0x00, 0x87,
214         0x04, 0x00, 0x07, 0x16, 0x00, 0x00, 0x02, 0xe3},
215         /*YUV2RGB:709 HD mode(Y[16:235],UV[16:240],RGB[0:255]):
216             R = 1.164*Y +1.793*V - 248
217             G = 1.164*Y - 0.213*U - 0.534*V + 77
218             B = 1.164*Y + 2.115*U - 289*/
219         {
220         0x04, 0xa7, 0x00, 0x00, 0x07, 0x2c, 0x02, 0xf8,
221         0x04, 0xa7, 0x10, 0xda, 0x12, 0x22, 0x00, 0x4d,
222         0x04, 0xa7, 0x08, 0x74, 0x00, 0x00, 0x03, 0x21},
223         /*RGB2YUV:601 SD mode:
224             Cb = -0.291G  - 0.148R + 0.439B + 128
225             Y   = 0.504G   + 0.257R + 0.098B + 16
226             Cr  = -0.368G + 0.439R - 0.071B + 128*/
227         {
228         /*0x11, 0x78, 0x01, 0xc1, 0x10, 0x48, 0x00, 0x80,
229         0x02, 0x04, 0x01, 0x07, 0x00, 0x64, 0x00, 0x10,
230         0x11, 0x29, 0x10, 0x97, 0x01, 0xc1, 0x00, 0x80*/
231
232         /*0x11,0x4b,0x01,0x8a,0x10,0x3f,0x00,0x80,
233         0x01,0xbb,0x00,0xe2,0x00,0x56,0x00,0x1d,
234         0x11,0x05,0x10,0x85,0x01,0x8a,0x00,0x80*/
235
236         0x11, 0x5f, 0x01, 0x82, 0x10, 0x23, 0x00, 0x80,
237         0x02, 0x1c, 0x00, 0xa1, 0x00, 0x36, 0x00, 0x1e,
238         0x11, 0x29, 0x10, 0x59, 0x01, 0x82, 0x00, 0x80
239         },
240
241         /*RGB2YUV:709 HD mode:
242             Cb = - 0.338G - 0.101R +  0.439B + 128
243             Y  =    0.614G + 0.183R +  0.062B + 16
244             Cr = - 0.399G + 0.439R  -  0.040B + 128*/
245         {
246         0x11, 0x98, 0x01, 0xc1, 0x10, 0x28, 0x00, 0x80,
247         0x02, 0x74, 0x00, 0xbb, 0x00, 0x3f, 0x00, 0x10,
248         0x11, 0x5a, 0x10, 0x67, 0x01, 0xc1, 0x00, 0x80
249         },
250         /*RGB[0:255]2RGB[16:235]:
251         R' = R x (235-16)/255 + 16;
252         G' = G x (235-16)/255 + 16;
253         B' = B x (235-16)/255 + 16;*/
254         {
255         0x00, 0x00, 0x03, 0x6F, 0x00, 0x00, 0x00, 0x10,
256         0x03, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
257         0x00, 0x00, 0x00, 0x00, 0x03, 0x6F, 0x00, 0x10},
258 };
259
260 static int rockchip_hdmiv1_video_csc(struct hdmi *hdmi_drv,
261                                      struct hdmi_video *vpara)
262 {
263         int value, i, csc_mode, c0_c2_change, auto_csc, csc_enable;
264         const char *coeff = NULL;
265         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
266
267         /* Enable or disalbe color space convert */
268         dev_info(hdmi_drv->dev, "[%s] input_color=%d,output_color=%d\n",
269                  __func__, vpara->color_input, vpara->color_output);
270         if (vpara->color_input == vpara->color_output) {
271                 if ((vpara->color_input >= HDMI_COLOR_YCBCR444) ||
272                     (vpara->color_input == HDMI_COLOR_RGB_0_255)) {
273                         value = v_SOF_DISABLE | v_COLOR_DEPTH_NOT_INDICATED(1);
274                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
275                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
276                                      m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_SWAP,
277                                      v_VIDEO_AUTO_CSC(AUTO_CSC_DISABLE) |
278                                      v_VIDEO_C0_C2_SWAP(C0_C2_CHANGE_DISABLE));
279                         return 0;
280                 } else if (vpara->color_input == HDMI_COLOR_RGB_16_235) {
281                         csc_mode = CSC_RGB_0_255_TO_RGB_16_235_8BIT;
282                         auto_csc = AUTO_CSC_DISABLE;
283                         c0_c2_change = C0_C2_CHANGE_DISABLE;
284                         csc_enable = v_CSC_ENABLE;
285                 }
286         }
287
288         switch (vpara->vic) {
289         case HDMI_720X480I_60HZ_4_3:
290         case HDMI_720X576I_50HZ_4_3:
291         case HDMI_720X480P_60HZ_4_3:
292         case HDMI_720X576P_50HZ_4_3:
293         case HDMI_720X480I_60HZ_16_9:
294         case HDMI_720X576I_50HZ_16_9:
295         case HDMI_720X480P_60HZ_16_9:
296         case HDMI_720X576P_50HZ_16_9:
297                 if (((vpara->color_input == HDMI_COLOR_RGB_0_255) ||
298                      (vpara->color_input == HDMI_COLOR_RGB_16_235)) &&
299                     vpara->color_output >= HDMI_COLOR_YCBCR444) {
300                         csc_mode = CSC_RGB_0_255_TO_ITU601_16_235_8BIT;
301                         auto_csc = AUTO_CSC_DISABLE;
302                         c0_c2_change = C0_C2_CHANGE_DISABLE;
303                         csc_enable = v_CSC_ENABLE;
304                 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
305                            ((vpara->color_output == HDMI_COLOR_RGB_0_255) ||
306                            (vpara->color_output == HDMI_COLOR_RGB_16_235))) {
307 #ifdef AUTO_DEFINE_CSC
308                         csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
309                         auto_csc = AUTO_CSC_ENABLE;
310                         c0_c2_change = C0_C2_CHANGE_DISABLE;
311                         csc_enable = v_CSC_DISABLE;
312 #else
313                         csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
314                         auto_csc = AUTO_CSC_DISABLE;
315                         c0_c2_change = C0_C2_CHANGE_ENABLE;
316                         csc_enable = v_CSC_ENABLE;
317 #endif
318                 }
319                 break;
320         default:
321                 if (((vpara->color_input == HDMI_COLOR_RGB_0_255) ||
322                      (vpara->color_input == HDMI_COLOR_RGB_16_235)) &&
323                     vpara->color_output >= HDMI_COLOR_YCBCR444) {
324                         csc_mode = CSC_RGB_0_255_TO_ITU709_16_235_8BIT;
325                         auto_csc = AUTO_CSC_DISABLE;
326                         c0_c2_change = C0_C2_CHANGE_DISABLE;
327                         csc_enable = v_CSC_ENABLE;
328                 } else if (vpara->color_input >= HDMI_COLOR_YCBCR444 &&
329                            ((vpara->color_output == HDMI_COLOR_RGB_0_255) ||
330                            (vpara->color_output == HDMI_COLOR_RGB_16_235))) {
331 #ifdef AUTO_DEFINE_CSC
332                         csc_mode = CSC_ITU709_16_235_TO_RGB_0_255_8BIT;
333                         auto_csc = AUTO_CSC_ENABLE;
334                         c0_c2_change = C0_C2_CHANGE_DISABLE;
335                         csc_enable = v_CSC_DISABLE;
336 #else
337                         /*CSC_ITU709_16_235_TO_RGB_0_255_8BIT;*/
338                         csc_mode = CSC_ITU601_16_235_TO_RGB_0_255_8BIT;
339                         auto_csc = AUTO_CSC_DISABLE;
340                         c0_c2_change = C0_C2_CHANGE_ENABLE;
341                         csc_enable = v_CSC_ENABLE;
342 #endif
343                 }
344                 break;
345         }
346
347         coeff = coeff_csc[csc_mode];
348         for (i = 0; i < 24; i++)
349                 hdmi_writel(hdmi_dev, VIDEO_CSC_COEF+i, coeff[i]);
350
351         value = v_SOF_DISABLE | csc_enable | v_COLOR_DEPTH_NOT_INDICATED(1);
352         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
353         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
354                      m_VIDEO_AUTO_CSC |
355                      m_VIDEO_C0_C2_SWAP,
356                      v_VIDEO_AUTO_CSC(auto_csc) |
357                      v_VIDEO_C0_C2_SWAP(c0_c2_change));
358
359 #if 0
360         if (vpara->input_color != vpara->output_color) {
361                 if (vpara->input_color == VIDEO_INPUT_COLOR_RGB) {/*rgb2yuv*/
362                         coeff = coeff_csc[3];
363                         for (i = 0; i < 24; i++)
364                                 hdmi_writel(hdmi_dev,
365                                             VIDEO_CSC_COEF+i, coeff[i]);
366
367                         value = v_SOF_DISABLE | v_CSC_ENABLE;
368                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
369                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
370                                      m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE,
371                                      v_VIDEO_AUTO_CSC(0) |
372                                      v_VIDEO_C0_C2_EXCHANGE(1));
373                 } else {/*yuv2rgb*/
374 #ifdef AUTO_DEFINE_CSC
375                         value = v_SOF_DISABLE | v_CSC_DISABLE;
376                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
377                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
378                                      m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE,
379                                      v_VIDEO_AUTO_CSC(1) |
380                                      v_VIDEO_C0_C2_EXCHANGE(1));
381 #else
382                         if (hdmi_drv->lcdc->cur_screen->mode.xres <= 576) {
383                                 /*x <= 576,REC-601*/
384                                 coeff = coeff_csc[0];
385                                 pr_info("xres<=576,xres=%d\n",
386                                         hdmi_drv->lcdc->cur_screen->mode.xres);
387                         } else/*x > 576,REC-709*/{
388                                 coeff = coeff_csc[2];
389                                 pr_info("xres>576,xres=%d\n",
390                                         hdmi_drv->lcdc->cur_screen->mode.xres);
391                         }
392                         for (i = 0; i < 24; i++)
393                                 hdmi_writel(hdmi_dev,
394                                             VIDEO_CSC_COEF+i, coeff[i]);
395
396                         value = v_SOF_DISABLE | v_CSC_ENABLE;
397                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
398                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
399                                      m_VIDEO_AUTO_CSC |
400                                      m_VIDEO_C0_C2_EXCHANGE,
401                                      v_VIDEO_AUTO_CSC(0) |
402                                      v_VIDEO_C0_C2_EXCHANGE(0));
403 #endif
404                 }
405         } else {
406                 if (vpara->input_color == VIDEO_INPUT_COLOR_RGB) {
407                         /*rgb[0:255]->rbg[16:235]*/
408                         coeff = coeff_csc[5];
409                         for (i = 0; i < 24; i++)
410                                 hdmi_writel(hdmi_dev,
411                                             VIDEO_CSC_COEF+i, coeff[i]);
412
413                         value = v_SOF_DISABLE | v_CSC_ENABLE;
414                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
415                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
416                                      m_VIDEO_AUTO_CSC | m_VIDEO_C0_C2_EXCHANGE,
417                                      v_VIDEO_AUTO_CSC(0) |
418                                      v_VIDEO_C0_C2_EXCHANGE(1));
419                 } else {
420                         value = v_SOF_DISABLE;
421                         hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
422                         hdmi_msk_reg(hdmi_dev, VIDEO_CONTRL,
423                                      m_VIDEO_AUTO_CSC |
424                                      m_VIDEO_C0_C2_EXCHANGE,
425                                      v_VIDEO_AUTO_CSC(0) |
426                                      v_VIDEO_C0_C2_EXCHANGE(1));
427                 }
428         }
429 #endif
430         return 0;
431 }
432
433 static int rockchip_hdmiv1_config_vsi(struct hdmi *hdmi,
434                                       unsigned char vic_3d,
435                                       unsigned char format)
436 {
437         struct hdmi_dev *hdmi_dev = hdmi->property->priv;
438         char info[SIZE_VSI_INFOFRAME];
439         int i;
440
441         DBG("[%s] vic_3d %d format %d.\n", __func__, vic_3d, format);
442         memset(info, 0, SIZE_VSI_INFOFRAME);
443         hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO,
444                      m_PACKET_VSI_EN, v_PACKET_VSI_EN(0));
445         hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_VSI);
446         /* Header Bytes */
447         info[0] = 0x81;
448         info[1] = 0x01;
449         /* PB1 - PB3 contain the 24bit IEEE Registration Identifier */
450         info[4] = 0x03;
451         info[5] = 0x0c;
452         info[6] = 0x00;
453         /* PB4 - HDMI_Video_Format into bits 7:5 */
454         info[7] = format << 5;
455         /* PB5 - Depending on the video format, this byte will contain either
456            the HDMI_VIC code in buts 7:0, OR the 3D_Structure in bits 7:4. */
457         switch (format) {
458         case HDMI_VIDEO_FORMAT_4KX2K:
459                 /* This is a 2x4K mode, set the HDMI_VIC in buts 7:0.  Values
460                    are from HDMI 1.4 Spec, 8.2.3.1 (Table 8-13). */
461                 info[2] = 0x06 - 1;
462                 info[8] = vic_3d;
463                 info[9] = 0;
464                 break;
465         case HDMI_VIDEO_FORMAT_3D:
466                 /* This is a 3D mode, set the 3D_Structure in buts 7:4
467                    Bits 3:0 are reseved so set to 0.  Values are from HDMI 1.4
468                    Spec, Appendix H (Table H-2). */
469                 info[8] = vic_3d << 4;
470                 /* Add the Extended data field when the 3D format is
471                    Side-by-Side(Half). See Spec Table H-3 for details. */
472                 if ((info[8] >> 4) == HDMI_3D_SIDE_BY_SIDE_HALF) {
473                         info[2] = 0x06;
474                         info[9] = 0x00;
475                 } else {
476                         info[2] = 0x06 - 1;
477                 }
478                 break;
479         default:
480                 info[2] = 0x06 - 2;
481                 info[8] = 0;
482                 info[9] = 0;
483                 break;
484         }
485         info[3] = info[0] + info[1] + info[2];
486         /* Calculate InfoFrame ChecKsum */
487         for (i = 4; i < SIZE_VSI_INFOFRAME; i++)
488                 info[3] += info[i];
489         info[3] = 0x100 - info[3];
490
491         for (i = 0; i < SIZE_VSI_INFOFRAME; i++)
492                 hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]);
493         hdmi_msk_reg(hdmi_dev, PACKET_SEND_AUTO,
494                      m_PACKET_VSI_EN, v_PACKET_VSI_EN(1));
495         return 0;
496 }
497
498 static void rockchip_hdmiv1_config_avi(struct hdmi *hdmi_drv,
499                                        unsigned char vic,
500                                        unsigned char output_color)
501 {
502         int i;
503         int avi_color_mode;
504         char info[SIZE_AVI_INFOFRAME];
505         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
506
507         memset(info, 0, SIZE_AVI_INFOFRAME);
508         hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
509         info[0] = 0x82;
510         info[1] = 0x02;
511         info[2] = 0x0D;
512         info[3] = info[0] + info[1] + info[2];
513
514         if ((output_color == HDMI_COLOR_RGB_0_255) ||
515             (output_color == HDMI_COLOR_RGB_16_235))
516                 avi_color_mode = AVI_COLOR_MODE_RGB;
517         else if (output_color == HDMI_COLOR_YCBCR444)
518                 avi_color_mode = AVI_COLOR_MODE_YCBCR444;
519         else if (output_color == HDMI_COLOR_YCBCR422)
520                 avi_color_mode = AVI_COLOR_MODE_YCBCR422;
521
522         info[4] = (avi_color_mode << 5);
523         info[5] =
524             (AVI_COLORIMETRY_NO_DATA << 6) |
525             (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) |
526             ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME;
527         info[6] = 0;
528         info[7] = vic;
529         if ((vic == HDMI_720X480I_60HZ_4_3) ||
530             (vic == HDMI_720X576I_50HZ_4_3) ||
531             (vic == HDMI_720X480I_60HZ_16_9) ||
532             (vic == HDMI_720X480I_60HZ_16_9))
533                 info[8] = 1;
534         else
535                 info[8] = 0;
536
537         /* Calculate AVI InfoFrame ChecKsum */
538         for (i = 4; i < SIZE_AVI_INFOFRAME; i++)
539                 info[3] += info[i];
540
541         info[3] = 0x100 - info[3];
542
543         for (i = 0; i < SIZE_AVI_INFOFRAME; i++)
544                 hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]);
545 }
546
547 static int rockchip_hdmiv1_config_video(struct hdmi *hdmi_drv,
548                                         struct hdmi_video *vpara)
549 {
550         struct fb_videomode *mode;
551         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
552         int value;
553
554         dev_dbg(hdmi_drv->dev, "[%s]\n", __func__);
555
556         if (vpara == NULL) {
557                 dev_err(hdmi_drv->dev, "[%s] input parameter error\n",
558                         __func__);
559                 return -1;
560         }
561
562         if (hdmi_dev->soctype == HDMI_SOC_RK3036) {
563                 /*rk3036 vop only can output rgb fmt*/
564                 vpara->color_input = HDMI_COLOR_RGB_0_255;
565         } else if (hdmi_dev->soctype == HDMI_SOC_RK312X) {
566                 /* rk3128 vop can output yuv444 fmt */
567                 /*if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444)
568                         vpara->output_color = VIDEO_OUTPUT_YCBCR444;
569                 else
570                         vpara->output_color = VIDEO_OUTPUT_RGB444;*/
571         }
572
573         mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
574         if (mode == NULL) {
575                 dev_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__,
576                         vpara->vic);
577                 return -ENOENT;
578         }
579         hdmi_dev->tmdsclk = mode->pixclock;
580         if (hdmi_drv->uboot)
581                 return 0;
582         /* Disable video and audio output */
583         hdmi_msk_reg(hdmi_dev, AV_MUTE,
584                      m_AUDIO_MUTE | m_AUDIO_PD | m_VIDEO_BLACK,
585                      v_AUDIO_MUTE(1) | v_AUDIO_PD(1) | v_VIDEO_MUTE(1));
586
587         /* Input video mode is SDR RGB24bit,
588            Data enable signal from external */
589         hdmi_writel(hdmi_dev, VIDEO_CONTRL1,
590                     v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) |
591                     v_DE_EXTERNAL);
592
593         value = v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS);
594         if (vpara->color_output <= HDMI_COLOR_RGB_16_235)
595                 value |= v_VIDEO_OUTPUT_COLOR(0);
596         else
597                 value |= v_VIDEO_OUTPUT_COLOR((vpara->color_output - 2) & 0x3);
598         if (vpara->color_input <= HDMI_COLOR_RGB_16_235)
599                 value |= v_VIDEO_INPUT_CSP(0);
600         else
601                 value |= v_VIDEO_INPUT_CSP((vpara->color_input - 2) & 0x1);
602
603         hdmi_writel(hdmi_dev, VIDEO_CONTRL2, value);
604         /* Set HDMI Mode */
605         hdmi_writel(hdmi_dev, HDCP_CTRL, v_HDMI_DVI(vpara->sink_hdmi));
606
607         /* Enable or disalbe color space convert */
608         rockchip_hdmiv1_video_csc(hdmi_drv, vpara);
609
610         /* Set ext video timing */
611         if ((mode->vmode || mode->pixclock <= 27000000) &&
612             vpara->format_3d != HDMI_3D_FRAME_PACKING) {
613                 hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0);
614         } else {
615                 if (vpara->format_3d == HDMI_3D_FRAME_PACKING)
616                         value = v_EXTERANL_VIDEO(1) |
617                                 v_INETLACE(0);
618                 else
619                         value = v_EXTERANL_VIDEO(1) |
620                                 v_INETLACE(mode->vmode);
621                 if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
622                         value |= v_HSYNC_POLARITY(1);
623                 if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
624                         value |= v_VSYNC_POLARITY(1);
625                 hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, value);
626
627                 value = mode->left_margin +
628                         mode->xres + mode->right_margin +
629                         mode->hsync_len;
630                 hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_L, value & 0xFF);
631                 hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
632
633                 value = mode->left_margin +
634                         mode->right_margin +
635                         mode->hsync_len;
636                 hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_L, value & 0xFF);
637                 hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
638
639                 value = mode->left_margin + mode->hsync_len;
640                 hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_L, value & 0xFF);
641                 hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
642
643                 value = mode->hsync_len;
644                 hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_L,
645                             value & 0xFF);
646                 hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_H,
647                             (value >> 8) & 0xFF);
648
649                 if (vpara->format_3d == HDMI_3D_FRAME_PACKING) {
650                         if (mode->vmode == 0)
651                                 value = mode->upper_margin +
652                                         mode->lower_margin +
653                                         mode->vsync_len +
654                                         2 * mode->yres;
655                         else
656                                 value = 4 * (mode->upper_margin +
657                                              mode->lower_margin +
658                                              mode->vsync_len) +
659                                         2 * mode->yres + 2;
660                 } else {
661                         value = mode->upper_margin +
662                                 mode->lower_margin +
663                                 mode->vsync_len +
664                                 mode->yres;
665                 }
666                 hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_L, value & 0xFF);
667                 hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
668
669                 value = mode->upper_margin +
670                         mode->vsync_len +
671                         mode->lower_margin;
672                 hdmi_writel(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF);
673
674                 if (vpara->vic == HDMI_720X480P_60HZ_4_3 ||
675                     vpara->vic == HDMI_720X480P_60HZ_16_9)
676                         value = 42;
677                 else
678                         value = mode->upper_margin + mode->vsync_len;
679
680                 hdmi_writel(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF);
681
682                 value = mode->vsync_len;
683                 hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF);
684         }
685         if (vpara->sink_hdmi == OUTPUT_HDMI) {
686                 rockchip_hdmiv1_config_avi(hdmi_drv, vpara->vic,
687                                            vpara->color_output);
688                 if (vpara->format_3d != HDMI_3D_NONE) {
689                         rockchip_hdmiv1_config_vsi(hdmi_drv,
690                                                    vpara->format_3d,
691                                                    HDMI_VIDEO_FORMAT_3D);
692                 } else if ((vpara->vic > 92 && vpara->vic < 96) ||
693                          (vpara->vic == 98)) {
694                         vpara->vic = (vpara->vic == 98) ?
695                                      4 : (96 - vpara->vic);
696                         rockchip_hdmiv1_config_vsi(hdmi_drv,
697                                                    vpara->vic,
698                                                    HDMI_VIDEO_FORMAT_4KX2K);
699                 } else {
700                         rockchip_hdmiv1_config_vsi(hdmi_drv,
701                                                    vpara->vic,
702                                                    HDMI_VIDEO_FORMAT_NORMAL);
703                 }
704                 dev_info(hdmi_drv->dev,
705                          "[%s] sucess output HDMI.\n", __func__);
706         } else {
707                 dev_info(hdmi_drv->dev,
708                          "[%s] sucess output DVI.\n", __func__);
709         }
710
711         /* rk3028a */
712         hdmi_writel(hdmi_dev, PHY_PRE_DIV_RATIO, 0x1e);
713         hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
714         hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
715
716         return 0;
717 }
718
719 static void rockchip_hdmiv1_config_aai(struct hdmi *hdmi_drv)
720 {
721         int i;
722         char info[SIZE_AUDIO_INFOFRAME];
723         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
724
725         memset(info, 0, SIZE_AUDIO_INFOFRAME);
726
727         info[0] = 0x84;
728         info[1] = 0x01;
729         info[2] = 0x0A;
730
731         info[3] = info[0] + info[1] + info[2];
732         for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++)
733                 info[3] += info[i];
734
735         info[3] = 0x100 - info[3];
736
737         hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI);
738         for (i = 0; i < SIZE_AUDIO_INFOFRAME; i++)
739                 hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]);
740 }
741
742 static int rockchip_hdmiv1_config_audio(struct hdmi *hdmi_drv,
743                                         struct hdmi_audio *audio)
744 {
745         int rate, N, channel, mclk_fs;
746         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
747
748         if (audio->channel < 3)
749                 channel = I2S_CHANNEL_1_2;
750         else if (audio->channel < 5)
751                 channel = I2S_CHANNEL_3_4;
752         else if (audio->channel < 7)
753                 channel = I2S_CHANNEL_5_6;
754         else
755                 channel = I2S_CHANNEL_7_8;
756
757         switch (audio->rate) {
758         case HDMI_AUDIO_FS_32000:
759                 rate = AUDIO_32K;
760                 N = N_32K;
761                 mclk_fs = MCLK_384FS;
762                 break;
763         case HDMI_AUDIO_FS_44100:
764                 rate = AUDIO_441K;
765                 N = N_441K;
766                 mclk_fs = MCLK_256FS;
767                 break;
768         case HDMI_AUDIO_FS_48000:
769                 rate = AUDIO_48K;
770                 N = N_48K;
771                 mclk_fs = MCLK_256FS;
772                 break;
773         case HDMI_AUDIO_FS_88200:
774                 rate = AUDIO_882K;
775                 N = N_882K;
776                 mclk_fs = MCLK_128FS;
777                 break;
778         case HDMI_AUDIO_FS_96000:
779                 rate = AUDIO_96K;
780                 N = N_96K;
781                 mclk_fs = MCLK_128FS;
782                 break;
783         case HDMI_AUDIO_FS_176400:
784                 rate = AUDIO_1764K;
785                 N = N_1764K;
786                 mclk_fs = MCLK_128FS;
787                 break;
788         case HDMI_AUDIO_FS_192000:
789                 rate = AUDIO_192K;
790                 N = N_192K;
791                 mclk_fs = MCLK_128FS;
792                 break;
793         default:
794                 dev_err(hdmi_drv->dev,
795                         "[%s] not support such sample rate %d\n",
796                         __func__, audio->rate);
797                 return -ENOENT;
798         }
799
800         /* set_audio source I2S */
801         if (hdmi_dev->audiosrc == HDMI_AUDIO_SRC_IIS) {
802                 hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x01);
803                 hdmi_writel(hdmi_dev, AUDIO_SAMPLE_RATE, rate);
804                 hdmi_writel(hdmi_dev, AUDIO_I2S_MODE,
805                             v_I2S_MODE(I2S_STANDARD) |
806                             v_I2S_CHANNEL(channel));
807                 hdmi_writel(hdmi_dev, AUDIO_I2S_MAP, 0x00);
808                 /* no swap */
809                 hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0);
810         } else {
811                 hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x08);
812                 /* no swap */
813                 hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0);
814         }
815
816         /* Set N value */
817         hdmi_writel(hdmi_dev, AUDIO_N_H, (N >> 16) & 0x0F);
818         hdmi_writel(hdmi_dev, AUDIO_N_M, (N >> 8) & 0xFF);
819         hdmi_writel(hdmi_dev, AUDIO_N_L, N & 0xFF);
820
821         /*Set hdmi nlpcm mode to support hdmi bitstream*/
822         if (audio->type == HDMI_AUDIO_NLPCM)
823                 hdmi_writel(hdmi_dev, AUDIO_CHANNEL_STATUS,
824                             v_AUDIO_STATUS_NLPCM(1));
825         else
826                 hdmi_writel(hdmi_dev, AUDIO_CHANNEL_STATUS,
827                             v_AUDIO_STATUS_NLPCM(0));
828
829         rockchip_hdmiv1_config_aai(hdmi_drv);
830
831         return 0;
832 }
833
834 int rockchip_hdmiv1_control_output(struct hdmi *hdmi_drv, int enable)
835 {
836         int mutestatus = 0;
837         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
838
839         if (hdmi_drv->uboot) {
840                 hdmi_drv->uboot = 0;
841                 return 0;
842         }
843
844         if (enable == HDMI_AV_UNMUTE) {
845                 if (hdmi_dev->pwr_mode == LOWER_PWR)
846                         rockchip_hdmiv1_set_pwr_mode(hdmi_drv, NORMAL);
847                 hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus);
848                 if (mutestatus & m_VIDEO_BLACK) {
849                         rockchip_hdmiv1_sys_power(hdmi_drv, true);
850                         rockchip_hdmiv1_sys_power(hdmi_drv, false);
851                         delay100us();
852                         rockchip_hdmiv1_sys_power(hdmi_drv, true);
853                         hdmi_writel(hdmi_dev, 0xce, 0x00);
854                         delay100us();
855                         hdmi_writel(hdmi_dev, 0xce, 0x01);
856                 }
857
858                 if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
859                         hdmi_msk_reg(hdmi_dev, AV_MUTE,
860                                      m_AUDIO_MUTE |
861                                      m_AUDIO_PD |
862                                      m_VIDEO_BLACK,
863                                      v_AUDIO_MUTE(0) |
864                                      v_AUDIO_PD(0) |
865                                      v_VIDEO_MUTE(0));
866                 }
867                 rockchip_hdmiv1_av_mute(hdmi_drv, 0);
868         } else {
869                 mutestatus = 0;
870                 if (enable & HDMI_VIDEO_MUTE)
871                         mutestatus |= v_VIDEO_MUTE(1);
872                 if (enable & HDMI_AUDIO_MUTE)
873                         mutestatus |= (v_AUDIO_MUTE(1) | v_AUDIO_PD(1));
874                 hdmi_msk_reg(hdmi_dev, AV_MUTE,
875                              m_AUDIO_MUTE | m_AUDIO_PD | m_VIDEO_BLACK,
876                              mutestatus);
877
878                 if (enable == (HDMI_VIDEO_MUTE | HDMI_AUDIO_MUTE)) {
879                         rockchip_hdmiv1_av_mute(hdmi_drv, 1);
880                         msleep(100);
881                         rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR);
882                 }
883         }
884         return 0;
885 }
886
887 int rockchip_hdmiv1_removed(struct hdmi *hdmi_drv)
888 {
889         dev_info(hdmi_drv->dev, "Removed.\n");
890         if (hdmi_drv->ops->hdcp_power_off_cb)
891                 hdmi_drv->ops->hdcp_power_off_cb(hdmi_drv);
892
893         rockchip_hdmiv1_control_output(hdmi_drv, -1);
894         rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR);
895
896         return HDMI_ERROR_SUCESS;
897 }
898
899 static int rockchip_hdmiv1_enable(struct hdmi *hdmi_drv)
900 {
901         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
902
903         if (!hdmi_dev->enable) {
904                 hdmi_dev->enable = 1;
905                 hdmi_msk_reg(hdmi_dev, HDMI_STATUS,
906                              m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(1));
907         }
908         hdmi_submit_work(hdmi_drv, HDMI_HPD_CHANGE, 10, 0);
909         return 0;
910 }
911
912 static int rockchip_hdmiv1_disable(struct hdmi *hdmi_drv)
913 {
914         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
915
916         if (hdmi_dev->enable) {
917                 hdmi_dev->enable = 0;
918                 hdmi_msk_reg(hdmi_dev, HDMI_STATUS,
919                              m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(0));
920         }
921         return 0;
922 }
923
924 void rockchip_hdmiv1_irq(struct hdmi *hdmi_drv)
925 {
926         u32 interrupt = 0;
927         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
928
929         hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt);
930         if (interrupt) {
931                 hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
932                 dev_info(hdmi_drv->dev, "Clear edid irq.\n");
933         }
934
935         hdmi_readl(hdmi_dev, HDMI_STATUS, &interrupt);
936         if (interrupt)
937                 hdmi_writel(hdmi_dev, HDMI_STATUS, interrupt);
938         if (interrupt & m_INT_HOTPLUG)
939                 hdmi_submit_work(hdmi_drv, HDMI_HPD_CHANGE, 20, 0);
940
941         if (hdmi_drv->ops->hdcp_irq_cb)
942                 hdmi_drv->ops->hdcp_irq_cb(0);
943         if (hdmi_drv->property->feature & SUPPORT_CEC)
944                 rockchip_hdmiv1_cec_isr(hdmi_dev);
945 }
946
947 static void rockchip_hdmiv1_reset(struct hdmi *hdmi_drv)
948 {
949         u32 val = 0;
950         u32 msk = 0;
951         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
952
953         hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
954         delay100us();
955         hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
956         delay100us();
957         msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
958         val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
959         hdmi_msk_reg(hdmi_dev, SYS_CTRL, msk, val);
960
961         rockchip_hdmiv1_set_pwr_mode(hdmi_drv, LOWER_PWR);
962 }
963
964 void rockchip_hdmiv1_dev_init_ops(struct hdmi_ops *ops)
965 {
966         if (ops) {
967                 ops->disable = rockchip_hdmiv1_disable;
968                 ops->enable = rockchip_hdmiv1_enable;
969                 ops->remove = rockchip_hdmiv1_removed;
970                 ops->setmute = rockchip_hdmiv1_control_output;
971                 ops->setvideo = rockchip_hdmiv1_config_video;
972                 ops->setaudio = rockchip_hdmiv1_config_audio;
973                 ops->getstatus = rockchip_hdmiv1_detect_hotplug;
974                 ops->getedid = rockchip_hdmiv1_read_edid;
975                 ops->insert     = rockchip_hdmiv1_insert;
976                 ops->setvsi = rockchip_hdmiv1_config_vsi;
977         }
978 }
979
980 int rockchip_hdmiv1_initial(struct hdmi *hdmi_drv)
981 {
982         int rc = HDMI_ERROR_SUCESS;
983         struct hdmi_dev *hdmi_dev = hdmi_drv->property->priv;
984
985         hdmi_dev->pwr_mode = NORMAL;
986
987         if (!hdmi_drv->uboot) {
988                 rockchip_hdmiv1_reset_pclk();
989                 rockchip_hdmiv1_reset(hdmi_drv);
990                 hdmi_msk_reg(hdmi_dev, HDMI_STATUS,
991                              m_MASK_INT_HOTPLUG, v_MASK_INT_HOTPLUG(0));
992         } else if (hdmi_drv->ops->getstatus(hdmi_drv) == HDMI_HPD_REMOVED) {
993                 rockchip_hdmiv1_removed(hdmi_drv);
994                 hdmi_drv->lcdc->uboot_logo = 0;
995                 hdmi_drv->uboot = 0;
996         }
997         if (hdmi_drv->property->feature & SUPPORT_CEC)
998                 rockchip_hdmiv1_cec_init(hdmi_drv);
999         if (hdmi_drv->property->feature & SUPPORT_HDCP)
1000                 rockchip_hdmiv1_hdcp_init(hdmi_drv);
1001         return rc;
1002 }