1 #include <linux/delay.h>
2 #include <linux/interrupt.h>
3 #include "rk3288_hdmi_hw.h"
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},
26 const struct phy_mpll_config_tab *get_phy_mpll_tab(int pixClock, char pixRepet,
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];
43 static void rk3288_hdmi_av_mute(struct hdmi *hdmi_drv, int enable)
45 struct rk3288_hdmi_device *hdmi_dev =
46 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
48 hdmi_msk_reg(hdmi_dev, FC_GCP, m_FC_SET_AVMUTE,
49 v_FC_SET_AVMUTE(enable));
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));
59 static void rk3288_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
61 struct rk3288_hdmi_device *hdmi_dev =
62 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
63 if (hdmi_drv->pwr_mode == mode)
66 dev_printk(KERN_INFO, hdmi_drv->dev, "%s change pwr_mode %d --> %d\n",
67 __func__, hdmi_drv->pwr_mode, mode);
71 hdmi_writel(hdmi_dev, MC_CLKDIS, 0x00);
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));
81 hdmi_dbg(hdmi_drv->dev, "unkown hdmi pwr mode %d\n", mode);
83 hdmi_drv->pwr_mode = mode;
86 /* i2c master reset */
87 void rk3288_hdmi_i2cm_reset(struct rk3288_hdmi_device *hdmi_dev)
89 hdmi_msk_reg(hdmi_dev, I2CM_SOFTRSTZ, m_I2CM_SOFTRST,
94 void rk3288_hdmi_reset(struct hdmi *hdmi_drv)
96 struct rk3288_hdmi_device *hdmi_dev =
97 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
99 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0x00);
101 hdmi_writel(hdmi_dev, MC_SWRSTZREQ, 0xff);
102 hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x00);
104 hdmi_writel(hdmi_dev, MC_SWRSTZREQ_2, 0x01);
106 rk3288_hdmi_i2cm_reset(hdmi_dev);
109 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
111 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
114 rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
117 int rk3288_hdmi_detect_hotplug(struct hdmi *hdmi_drv)
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);
123 hdmi_dbg(hdmi_drv->dev, "[%s] reg%x value %02x\n", __func__,
126 if ((value & m_PHY_HPD) || ((value & 0xf0) == 0xf0))
127 return HDMI_HPD_ACTIVED;
129 return HDMI_HPD_REMOVED;
132 int rk3288_hdmi_read_edid(struct hdmi *hdmi_drv, int block, unsigned char *buff)
134 int i = 0, n = 0, index = 0, ret = -1, trytime = 2;
135 int offset = (block % 2) * 0x80;
137 struct rk3288_hdmi_device *hdmi_dev =
138 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
140 hdmi_dbg(hdmi_drv->dev, "[%s] block %d\n", __func__, block);
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 */
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) |
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));
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);
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 */
164 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
165 m_I2CM_RD8, v_I2CM_RD8(1));
167 hdmi_msk_reg(hdmi_dev, I2CM_OPERATION,
168 m_I2CM_RD8_EXT, v_I2CM_RD8_EXT(1));
173 interrupt = hdmi_readl(hdmi_dev, IH_I2CM_STAT0);
175 hdmi_writel(hdmi_dev, IH_I2CM_STAT0,
179 (m_SCDC_READREQ | m_I2CM_DONE |
185 if (interrupt & m_I2CM_DONE) {
186 for (index = 0; index < 8; index++) {
187 buff[8 * n + index] =
189 I2CM_READ_BUFF0 + index);
192 if (n == HDMI_EDID_BLOCK_SIZE / 8 - 1) {
194 hdmi_dbg(hdmi_drv->dev,
195 "[%s] edid read sucess\n",
199 for (i = 0; i < 128; i++) {
200 printk("%02x ,", buff[i]);
201 if ((i + 1) % 16 == 0)
208 } else if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
209 hdmi_err(hdmi_drv->dev,
210 "[%s] edid read error\n",
212 rk3288_hdmi_i2cm_reset(hdmi_dev);
217 hdmi_err(hdmi_drv->dev, "[%s] edid try times %d\n",
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));
233 static int rk3288_hdmi_video_forceOutput(struct hdmi *hdmi_drv, char enable)
235 struct rk3288_hdmi_device *hdmi_dev =
236 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
238 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEAUDIO,
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,
248 hdmi_msk_reg(hdmi_dev, FC_DBGFORCE, m_FC_FORCEVIDEO,
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*/
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)
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);
273 mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
275 hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__,
280 hdmi_drv->pixclock = mode->pixclock;
281 switch (vpara->color_depth) {
282 case HDMI_COLOR_DEPTH_8BIT:
283 hdmi_drv->tmdsclk = mode->pixclock;
285 case HDMI_COLOR_DEPTH_10BIT:
286 hdmi_drv->tmdsclk = mode->pixclock * 10 / 8;
288 case HDMI_COLOR_DEPTH_12BIT:
289 hdmi_drv->tmdsclk = mode->pixclock * 12 / 8;
291 case HDMI_COLOR_DEPTH_16BIT:
292 hdmi_drv->tmdsclk = mode->pixclock * 2;
295 hdmi_drv->tmdsclk = mode->pixclock;
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->
308 v_FC_INTERLACE_MODE(mode->vmode));
309 hdmi_msk_reg(hdmi_dev, FC_INVIDCONF, m_FC_VBLANK,
310 v_FC_VBLANK(mode->vmode));
313 hdmi_writel(hdmi_dev, FC_INHACTIV1, v_FC_HACTIVE1(h_act >> 8));
314 hdmi_writel(hdmi_dev, FC_INHACTIV0, (h_act & 0xff));
317 hdmi_writel(hdmi_dev, FC_INVACTIV1, v_FC_VACTIVE1(v_act >> 8));
318 hdmi_writel(hdmi_dev, FC_INVACTIV0, (v_act & 0xff));
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));
324 v_blank = mode->vsync_len + mode->upper_margin + mode->lower_margin;
325 hdmi_writel(hdmi_dev, FC_INVBLANK, (v_blank & 0xff));
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));
332 v_syncdelay = mode->lower_margin;
333 hdmi_writel(hdmi_dev, FC_VSYNCINDELAY, (v_syncdelay & 0xff));
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));
339 v_sync = mode->vsync_len;
340 hdmi_writel(hdmi_dev, FC_VSYNCINWIDTH, (v_sync & 0xff));
342 /* Set the control period minimum duration
343 * (min. of 12 pixel clock cycles, refer to HDMI 1.4b specification)
345 hdmi_writel(hdmi_dev, FC_CTRLDUR, 12);
346 hdmi_writel(hdmi_dev, FC_EXCTRLDUR, 32);
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));
356 /* spacing < 256^2 * config / tmdsClock, spacing <= 50ms
357 * worst case: tmdsClock == 25MHz => config <= 19
359 hdmi_writel(hdmi_dev, FC_EXCTRLSPAC, 1);
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);
372 /* Set PixelRepetition:No pixel repetition */
373 hdmi_writel(hdmi_dev, FC_PRCONF,
374 v_FC_PR_FACTOR(vpara->pixel_repet + 1));
379 static int rk3288_hdmi_video_packetizer(struct hdmi *hdmi_drv,
380 struct hdmi_video_para *vpara)
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);
388 if (vpara->output_color == VIDEO_OUTPUT_RGB444
389 || vpara->output_color == VIDEO_OUTPUT_YCBCR444
390 || vpara->output_color == VIDEO_OUTPUT_YCBCR420) {
392 switch (vpara->color_depth) {
393 case HDMI_COLOR_DEPTH_8BIT:
394 color_depth = COLOR_DEPTH_24BIT;
395 output_select = OUT_FROM_8BIT_BYPASS;
397 case HDMI_COLOR_DEPTH_10BIT:
398 color_depth = COLOR_DEPTH_30BIT;
399 output_select = OUT_FROM_PIXEL_PACKING;
401 case HDMI_COLOR_DEPTH_12BIT:
402 color_depth = COLOR_DEPTH_36BIT;
403 output_select = OUT_FROM_PIXEL_PACKING;
405 case HDMI_COLOR_DEPTH_16BIT:
406 color_depth = COLOR_DEPTH_48BIT;
407 output_select = OUT_FROM_PIXEL_PACKING;
410 color_depth = COLOR_DEPTH_24BIT;
411 output_select = OUT_FROM_8BIT_BYPASS;
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) {
420 switch (vpara->color_depth) {
421 case HDMI_COLOR_DEPTH_8BIT:
422 remap_size = YCC422_16BIT;
424 case HDMI_COLOR_DEPTH_10BIT:
425 remap_size = YCC422_20BIT;
427 case HDMI_COLOR_DEPTH_12BIT:
428 remap_size = YCC422_24BIT;
431 remap_size = YCC422_16BIT;
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));
440 hdmi_err(hdmi_drv->dev, "invalid output color type: %d",
441 vpara->output_color);
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));
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));
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 |
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 |
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) {
470 hdmi_msk_reg(hdmi_dev, VP_CONF,
471 m_BYPASS_EN | m_PIXEL_PACK_EN | m_YCC422_EN |
473 v_BYPASS_EN(1) | v_PIXEL_PACK_EN(0) |
474 v_YCC422_EN(0) | v_OUTPUT_SEL(output_select));
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));
485 int rk3288_hdmi_video_sampler(struct hdmi *hdmi_drv,
486 struct hdmi_video_para *vpara)
489 struct rk3288_hdmi_device *hdmi_dev =
490 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
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) {
496 switch (vpara->color_depth) {
497 case HDMI_COLOR_DEPTH_8BIT:
498 map_code = VIDEO_RGB444_8BIT;
500 case HDMI_COLOR_DEPTH_10BIT:
501 map_code = VIDEO_RGB444_10BIT;
503 case HDMI_COLOR_DEPTH_12BIT:
504 map_code = VIDEO_RGB444_12BIT;
506 case HDMI_COLOR_DEPTH_16BIT:
507 map_code = VIDEO_RGB444_16BIT;
510 map_code = VIDEO_RGB444_8BIT;
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;
521 case HDMI_COLOR_DEPTH_10BIT:
522 map_code = VIDEO_YCBCR422_10BIT;
524 case HDMI_COLOR_DEPTH_12BIT:
525 map_code = VIDEO_YCBCR422_12BIT;
528 map_code = VIDEO_YCBCR422_8BIT;
532 hdmi_err(hdmi_drv->dev, "invalid input color type: %d",
537 /* Set Data enable signal from external
538 * and set video sample input mapping
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));
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,
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,
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,
561 static int rk3288_hdmi_read_phy(struct rk3288_hdmi_device *hdmi_dev,
564 int trytime = 2, i = 0, op_status = 0;
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);
576 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
578 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
581 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) {
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",
595 hdmi_err(hdmi_dev->dev,
596 "[%s] operation error,trytime=%d\n",
606 static int rk3288_hdmi_write_phy(struct rk3288_hdmi_device *hdmi_dev,
607 int reg_addr, int val)
609 int trytime = 2, i = 0, op_status = 0;
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);
620 op_status = hdmi_readl(hdmi_dev, IH_I2CMPHY_STAT0);
622 hdmi_writel(hdmi_dev, IH_I2CMPHY_STAT0,
625 if (op_status & (m_I2CMPHY_DONE | m_I2CMPHY_ERR)) {
631 if (op_status & m_I2CMPHY_DONE) {
634 hdmi_err(hdmi_dev->dev,
635 "[%s] operation error,trytime=%d\n",
644 int rk3288_hdmi_config_phy(struct hdmi *hdmi_drv, unsigned char pixel_repet,
645 unsigned char color_depth)
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);
652 hdmi_msk_reg(hdmi_dev, PHY_I2CM_DIV, m_PHY_I2CM_FAST_STD,
653 v_PHY_I2CM_FAST_STD(0));
656 hdmi_writel(hdmi_dev, PHY_CONF0, 0x3a);
658 hdmi_msk_reg(hdmi_dev, PHY_CONF0, m_PDDQ_SIG | m_TXPWRON_SIG,
659 v_PDDQ_SIG(1) | v_TXPWRON_SIG(0));
663 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(1));
665 hdmi_writel(hdmi_dev, MC_PHYRSTZ, v_PHY_RSTZ(0));
667 /* Set slave address as PHY GEN2 address */
668 hdmi_writel(hdmi_dev, PHY_I2CM_SLAVE, PHY_GEN2_ADDR);
670 /* config the required PHY I2C register */
672 get_phy_mpll_tab(hdmi_drv->pixclock, pixel_repet, color_depth);
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));
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));
715 if (hdmi_drv->pixclock < 297000000)
716 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
717 v_SUP_TXLVL(20) | v_SUP_CLKLVL(19));
719 rk3288_hdmi_write_phy(hdmi_dev, PHYTX_VLEVCTRL,
720 v_SUP_TXLVL(17) | v_SUP_CLKLVL(16));
723 hdmi_writel(hdmi_dev, PHY_CONF0, 0x6e);
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));
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) {
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);
751 int rk3288_hdmi_config_vsi(struct hdmi *hdmi_drv, unsigned char vic_3d,
752 unsigned char format, int auto_send)
755 unsigned char data[3] = { 0 };
757 struct rk3288_hdmi_device *hdmi_dev =
758 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
760 hdmi_dbg(hdmi_drv->dev, "[%s] vic %d format %d.\n", __func__,
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);
767 data[0] = format << 5; /* PB4 --HDMI_Video_Format */
769 case HDMI_VIDEO_FORMAT_4Kx2K:
770 data[1] = vic_3d; /* PB5--HDMI_VIC */
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 */
783 for (i = 0; i < 3; i++)
784 hdmi_writel(hdmi_dev, FC_VSDPAYLOAD0 + i, data[i]);
787 hdmi_msk_reg(hdmi_dev, FC_DATAUTO0, m_VSD_AUTO,
788 v_VSD_AUTO(auto_send));
790 hdmi_msk_reg(hdmi_dev, FC_DATMAN, m_VSD_MAN, v_VSD_MAN(1));
796 static void rk3288_hdmi_config_avi(struct hdmi *hdmi_drv, unsigned char vic,
797 struct hdmi_video_para *vpara)
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);
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;
812 y1y0 = AVI_COLOR_MODE_RGB;
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));
817 /* Set AVI infoFrame Data byte2 */
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;
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;
834 aspect_ratio = AVI_CODED_FRAME_ASPECT_16_9;
835 colorimetry = AVI_COLORIMETRY_ITU709;
838 if (vpara->color_depth > HDMI_COLOR_DEPTH_8BIT) {
839 colorimetry = AVI_COLORIMETRY_EXTENDED;
841 } else if (vpara->output_color == VIDEO_OUTPUT_RGB444) {
842 colorimetry = AVI_COLORIMETRY_NO_DATA;
846 hdmi_writel(hdmi_dev, FC_AVICONF1,
847 v_FC_COLORIMETRY(colorimetry) |
848 v_FC_PIC_ASPEC_RATIO(aspect_ratio) |
850 (ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME));
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));
858 /* Set AVI infoFrame Data byte4 */
859 hdmi_writel(hdmi_dev, FC_AVIVID, (vic & 0xff));
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));
867 static const char coeff_csc[][24] = {
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
938 static int rk3288_hdmi_video_csc(struct hdmi *hdmi_drv,
939 struct hdmi_video_para *vpara)
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);
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));
954 if (vpara->input_color == VIDEO_INPUT_COLOR_YCBCR422 &&
955 (vpara->output_color == VIDEO_OUTPUT_RGB444
956 || vpara->output_color == VIDEO_OUTPUT_YCBCR444)) {
958 hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_INTPMODE,
959 v_CSC_INTPMODE(interpolation));
962 if ((vpara->input_color == VIDEO_INPUT_COLOR_RGB
963 || vpara->input_color == VIDEO_INPUT_COLOR_YCBCR444)
964 && vpara->output_color == VIDEO_OUTPUT_YCBCR422) {
966 hdmi_msk_reg(hdmi_dev, CSC_CFG, m_CSC_DECIMODE,
967 v_CSC_DECIMODE(decimation));
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;
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;
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;
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;
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;
1009 switch (vpara->color_depth) {
1010 case HDMI_COLOR_DEPTH_8BIT:
1011 color_depth = COLOR_DEPTH_24BIT;
1013 case HDMI_COLOR_DEPTH_10BIT:
1014 color_depth = COLOR_DEPTH_30BIT;
1017 case HDMI_COLOR_DEPTH_12BIT:
1018 color_depth = COLOR_DEPTH_36BIT;
1021 case HDMI_COLOR_DEPTH_16BIT:
1022 color_depth = COLOR_DEPTH_48BIT;
1026 color_depth = COLOR_DEPTH_24BIT;
1030 coeff = coeff_csc[mode];
1031 for (i = 0; i < 24; i++) {
1032 hdmi_writel(hdmi_dev, CSC_COEF_A1_MSB + i, coeff[i]);
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));
1040 hdmi_msk_reg(hdmi_dev, MC_FLOWCTRL, m_FEED_THROUGH_OFF,
1041 v_FEED_THROUGH_OFF(1));
1045 int rk3288_hdmi_config_video(struct hdmi *hdmi_drv,
1046 struct hdmi_video_para *vpara)
1048 rk3288_hdmi_av_mute(hdmi_drv, 1);
1050 if (rk3288_hdmi_video_forceOutput(hdmi_drv, 1) < 0)
1052 if (rk3288_hdmi_video_frameComposer(hdmi_drv, vpara) < 0)
1054 if (rk3288_hdmi_video_packetizer(hdmi_drv, vpara) < 0)
1056 if (rk3288_hdmi_video_csc(hdmi_drv, vpara) < 0)
1058 if (rk3288_hdmi_video_sampler(hdmi_drv, vpara) < 0)
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",
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);
1078 rk3288_hdmi_config_vsi(hdmi_drv, vpara->vic,
1079 HDMI_VIDEO_FORMAT_NORMAL, 1);
1081 hdmi_dbg(hdmi_drv->dev, "[%s] sucess output DVI.\n",
1085 rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
1086 rk3288_hdmi_config_phy(hdmi_drv, vpara->pixel_repet,
1087 vpara->color_depth);
1091 static void rk3288_hdmi_config_aai(struct hdmi *hdmi_drv,
1092 struct hdmi_audio *audio)
1094 struct rk3288_hdmi_device *hdmi_dev =
1095 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1097 /* Refer to CEA861-E Audio infoFrame */
1098 /* Set both Audio Channel Count and
1099 * Audio Coding Type Refer to Stream Head for HDMI
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));
1104 /* Set both Audio Sample Size and
1105 * Sample Frequency Refer to Stream Head for HDMI
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));
1111 /* Set Channel Allocation */
1112 hdmi_writel(hdmi_dev, FC_AUDICONF2, 0x00);
1114 /* Set LFEPBL¡¢DOWN-MIX INH and LSV */
1115 hdmi_writel(hdmi_dev, FC_AUDICONF3, 0x00);
1118 int rk3288_hdmi_config_audio(struct hdmi *hdmi_drv, struct hdmi_audio *audio)
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);
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;
1133 channel = I2S_CHANNEL_7_8;
1135 switch (audio->rate) {
1136 case HDMI_AUDIO_FS_32000:
1138 if (hdmi_drv->pixclock >= 594000000)
1140 else if (hdmi_drv->pixclock == 297000000)
1145 /* div a num to avoid the value is exceed 2^32(int) */
1146 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 32);
1148 case HDMI_AUDIO_FS_44100:
1150 if (hdmi_drv->pixclock >= 594000000)
1152 else if (hdmi_drv->pixclock == 297000000)
1157 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 441);
1159 case HDMI_AUDIO_FS_48000:
1161 if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */
1163 else if (hdmi_drv->pixclock == 297000000)
1168 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 48);
1170 case HDMI_AUDIO_FS_88200:
1172 if (hdmi_drv->pixclock >= 594000000)
1174 else if (hdmi_drv->pixclock == 297000000)
1179 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 882);
1181 case HDMI_AUDIO_FS_96000:
1183 if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */
1185 else if (hdmi_drv->pixclock == 297000000)
1190 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 96);
1192 case HDMI_AUDIO_FS_176400:
1194 if (hdmi_drv->pixclock >= 594000000)
1195 N = N_1764K_HIGHCLK;
1196 else if (hdmi_drv->pixclock == 297000000)
1201 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 100, 1764);
1203 case HDMI_AUDIO_FS_192000:
1205 if (hdmi_drv->pixclock >= 594000000) /* FS_153.6 */
1207 else if (hdmi_drv->pixclock == 297000000)
1212 CTS = CALC_CTS(N, hdmi_drv->tmdsclk / 1000, 192);
1215 hdmi_err(hdmi_drv->dev,
1216 "[%s] not support such sample rate %d\n", __func__,
1221 switch (audio->word_length) {
1222 case HDMI_AUDIO_WORD_LENGTH_16bit:
1223 word_length = I2S_16BIT_SAMPLE;
1225 case HDMI_AUDIO_WORD_LENGTH_20bit:
1226 word_length = I2S_20BIT_SAMPLE;
1228 case HDMI_AUDIO_WORD_LENGTH_24bit:
1229 word_length = I2S_24BIT_SAMPLE;
1232 word_length = I2S_16BIT_SAMPLE;
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
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));
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));
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));
1270 hdmi_msk_reg(hdmi_dev, AUD_INPUTCLKFS, m_LFS_FACTOR,
1271 v_LFS_FACTOR(mclk_fs));
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 >>
1281 hdmi_writel(hdmi_dev, AUD_CTS2, (CTS >> 8) & 0xff);
1282 hdmi_writel(hdmi_dev, AUD_CTS1, CTS & 0xff);
1284 hdmi_msk_reg(hdmi_dev, MC_CLKDIS, m_AUDCLK_DISABLE,
1285 v_AUDCLK_DISABLE(0));
1286 rk3288_hdmi_config_aai(hdmi_drv, audio);
1291 void rk3288_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
1293 hdmi_dbg(hdmi_drv->dev, "[%s] %d\n", __func__, enable);
1295 rk3288_hdmi_av_mute(hdmi_drv, 1);
1297 if (hdmi_drv->pwr_mode == LOWER_PWR)
1298 rk3288_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
1300 /* disable blue screen transmission
1301 * after turning on all necessary blocks
1303 rk3288_hdmi_video_forceOutput(hdmi_drv, 0);
1304 rk3288_hdmi_av_mute(hdmi_drv, 0);
1308 int rk3288_hdmi_insert(struct hdmi *hdmi_drv)
1310 struct rk3288_hdmi_device *hdmi_dev =
1311 container_of(hdmi_drv, struct rk3288_hdmi_device, driver);
1313 /* report HPD state to HDCP (after configuration) */
1314 hdmi_msk_reg(hdmi_dev, A_HDCPCFG0, m_RX_DETECT, v_RX_DETECT(1));
1319 int rk3288_hdmi_removed(struct hdmi *hdmi_drv)
1321 rk3288_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
1322 dev_printk(KERN_INFO, hdmi_drv->dev, "Removed.\n");
1326 int rk3288_hdmi_initial(struct hdmi *hdmi_drv)
1328 int rc = HDMI_ERROR_SUCESS;
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;
1339 rk3288_hdmi_reset(hdmi_drv);
1341 if (hdmi_drv->hdcp_power_on_cb)
1342 rc = hdmi_drv->hdcp_power_on_cb();
1347 irqreturn_t hdmi_irq(int irq, void *priv)
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;
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);
1362 hdcp_int = hdmi_readl(hdmi_dev, A_APIINTSTAT);
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);
1372 hdmi_writel(hdmi_dev, A_APIINTCLR, hdcp_int);
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));
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); */
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); */
1398 if (hdmi_drv->hdcp_irq_cb)
1399 hdmi_drv->hdcp_irq_cb(i2cm_int);