diff options
author | Srikant Patnaik | 2015-01-11 20:10:08 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 20:10:08 +0530 |
commit | 6be9593ee4352c19377a47475fdcd8473897ac42 (patch) | |
tree | b85d6e3d961374d41c446318e2c2598272a8e86c /drivers/video/wmt/hdmi.c | |
parent | ddd6804ba90290b66ebff05b99752fcdd75fec45 (diff) | |
download | FOSSEE-netbook-kernel-source-6be9593ee4352c19377a47475fdcd8473897ac42.tar.gz FOSSEE-netbook-kernel-source-6be9593ee4352c19377a47475fdcd8473897ac42.tar.bz2 FOSSEE-netbook-kernel-source-6be9593ee4352c19377a47475fdcd8473897ac42.zip |
Fix white screen issue during bootup
Signed-off-by: Manish Patel <manish.patel@xzadium.com>
Diffstat (limited to 'drivers/video/wmt/hdmi.c')
-rw-r--r--[-rwxr-xr-x] | drivers/video/wmt/hdmi.c | 981 |
1 files changed, 569 insertions, 412 deletions
diff --git a/drivers/video/wmt/hdmi.c b/drivers/video/wmt/hdmi.c index c181d757..47626d77 100755..100644 --- a/drivers/video/wmt/hdmi.c +++ b/drivers/video/wmt/hdmi.c @@ -2,7 +2,7 @@ * linux/drivers/video/wmt/hdmi.c * WonderMedia video post processor (VPP) driver * - * Copyright c 2014 WonderMedia Technologies, Inc. + * Copyright c 2013 WonderMedia Technologies, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,6 +39,8 @@ /* #define CONFIG_HDMI_EDID_DISABLE */ #define HDMI_I2C_FREQ 80000 + +#define MAX_ACR_TV_NUM 128 /*----------------------- PRIVATE TYPE --------------------------------------*/ /* typedef xxxx hdmi_xxx_t; *//*Example*/ enum hdmi_fifo_slot_t { @@ -53,14 +55,39 @@ enum hdmi_fifo_slot_t { /*----------------------- INTERNAL PRIVATE VARIABLES - -----------------------*/ /* int hdmi_xxx; *//*Example*/ -HW_REG struct hdmi_base1_regs *hdmi_regs1 = (void *) (HDMI_BASE_ADDR + 0x100); -HW_REG struct hdmi_base2_regs *hdmi_regs2 = (void *) HDMI_BASE2_ADDR; +/* +Added by howayhuo +Some TV need fix the HDMI ACR ration, otherwise these TV will show "overclock" +Fill in the TV vendor name and TV monitor name to this list if your TV needs fix acr +*/ +static const tv_name_t fix_acr_tv_list[] = { + {"TCL", "RTD2662"}, //another name: TCL L19E09 +}; + +static tv_name_t *p_fix_acr_tv; +static int fixed_acr_ration_val = 2300; /*--------------------- INTERNAL PRIVATE FUNCTIONS ---------------------------*/ /* void hdmi_xxx(void); *//*Example*/ /*----------------------- Function Body --------------------------------------*/ /*---------------------------- HDMI COMMON API -------------------------------*/ +unsigned int hdmi_reg32_write(U32 offset, U32 mask, U32 shift, U32 val) +{ + unsigned int new_val; + + new_val = (vppif_reg32_in(offset) & ~(mask)) + | (((val) << (shift)) & mask); + if (offset == REG_HDMI_GENERAL_CTRL) { + new_val &= ~(BIT24 | BIT25 | BIT26); + new_val |= g_vpp.hdmi_ctrl; + DBG_MSG("[HDMI] reg32_wr 0x%x ctrl 0x%x\n", + new_val, g_vpp.hdmi_ctrl); + } + vppif_reg32_out(offset, new_val); + return new_val; +} + unsigned char hdmi_ecc(unsigned char *buf, int bit_cnt) { #define HDMI_CRC_LEN 9 @@ -118,54 +145,52 @@ void hdmi_set_power_down(int pwrdn) { DBG_DETAIL("(%d)\n", pwrdn); - if ((hdmi_regs2->test.b.pd == 0) && (pwrdn == 0)) + if ((vppif_reg32_read(HDMI_PD) == 0) && (pwrdn == 0)) { return; /* avoid HDMI reset */ + } - hdmi_regs2->status.b.internal_ldo = (pwrdn) ? 0 : 1; - hdmi_regs2->test.b.pd = pwrdn; + vppif_reg32_write(HDMI_INTERNAL_LDO, (pwrdn) ? 0 : 1); + vppif_reg32_write(HDMI_PD, pwrdn); if (!pwrdn) { - hdmi_regs2->dftset2.b.reset_pll = 1; + vppif_reg32_write(HDMI_RESET_PLL, 1); mdelay(1); - hdmi_regs2->dftset2.b.reset_pll = 0; + vppif_reg32_write(HDMI_RESET_PLL, 0); } mdelay(1); - hdmi_regs2->test2.b.pd_l2ha = pwrdn; + vppif_reg32_write(HDMI_PD_L2HA, pwrdn); } int hdmi_get_power_down(void) { - return hdmi_regs2->test.b.pd; + return vppif_reg32_read(HDMI_PD); } void hdmi_set_enable(vpp_flag_t enable) { - hdmi_regs1->general_ctrl.b.enable = enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ - hdmi_regs2->test2.b.mode = (enable) ? 0 : 1; + hdmi_reg32_write(HDMI_ENABLE, enable); + vppif_reg32_write(HDMI_MODE, (enable) ? 0 : 1); } void hdmi_set_avmute(vpp_flag_t mute) { - hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable = mute; + vppif_reg32_write(HDMI_AVMUTE_SET_ENABLE, mute); } void hdmi_set_dvi_enable(vpp_flag_t enable) { - hdmi_regs1->general_ctrl.b.dvi_mode_enable = enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_DVI_MODE_ENABLE, enable); } void hdmi_set_sync_low_active(vpp_flag_t hsync, vpp_flag_t vsync) { - hdmi_regs1->general_ctrl.b.hsync_low_active = hsync; - hdmi_regs1->general_ctrl.b.vsync_low_active = vsync; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_HSYNC_LOW_ACTIVE, hsync); + hdmi_reg32_write(HDMI_VSYNC_LOW_ACTIVE, vsync); } void hdmi_get_sync_polar(int *hsync_hi, int *vsync_hi) { - *hsync_hi = (hdmi_regs1->general_ctrl.b.hsync_low_active) ? 0 : 1; - *vsync_hi = (hdmi_regs1->general_ctrl.b.vsync_low_active) ? 0 : 1; + *hsync_hi = (vppif_reg32_read(HDMI_HSYNC_LOW_ACTIVE)) ? 0 : 1; + *vsync_hi = (vppif_reg32_read(HDMI_VSYNC_LOW_ACTIVE)) ? 0 : 1; } void hdmi_set_output_colfmt(vdo_color_fmt colfmt) @@ -185,16 +210,15 @@ void hdmi_set_output_colfmt(vdo_color_fmt colfmt) val = 2; break; } - hdmi_regs1->general_ctrl.b.convert_yuv422 = (val == 2) ? 1 : 0; - hdmi_regs1->general_ctrl.b.output_format = val; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ + hdmi_reg32_write(HDMI_CONVERT_YUV422, (val == 2) ? 1 : 0); + hdmi_reg32_write(HDMI_OUTPUT_FORMAT, val); } vdo_color_fmt hdmi_get_output_colfmt(void) { unsigned int val; - val = hdmi_regs1->general_ctrl.b.output_format; + val = vppif_reg32_read(HDMI_OUTPUT_FORMAT); switch (val) { default: case 0: @@ -211,15 +235,15 @@ int hdmi_get_plugin(void) { int plugin; - if (hdmi_regs1->hotplug_detect.b.in_enable) { - plugin = hdmi_regs1->hotplug_detect.b.sts; + if (vppif_reg32_read(HDMI_HOTPLUG_IN_INT)) { + plugin = vppif_reg32_read(HDMI_HOTPLUG_IN); } else { - int tre_en; + int tre_en; - tre_en = hdmi_regs2->test.b.tre_en; - hdmi_regs2->test.b.tre_en = 0; - plugin = hdmi_regs2->detect.b.rsen; - hdmi_regs2->test.b.tre_en = tre_en; + tre_en = vppif_reg32_read(HDMI_TRE_EN); + vppif_reg32_write(HDMI_TRE_EN, 0); + plugin = vppif_reg32_read(HDMI_RSEN); + vppif_reg32_write(HDMI_TRE_EN, tre_en); } return plugin; } @@ -228,20 +252,20 @@ int hdmi_get_plug_status(void) { int reg; - reg = hdmi_regs1->hotplug_detect.val; + reg = vppif_reg32_in(REG_HDMI_HOTPLUG_DETECT); return reg & 0x3000000; } void hdmi_clear_plug_status(void) { - hdmi_regs1->hotplug_detect.b.in_sts = 1; - hdmi_regs1->hotplug_detect.b.out_sts = 1; + vppif_reg32_write(HDMI_HOTPLUG_IN_STS, 1); + vppif_reg32_write(HDMI_HOTPLUG_OUT_STS, 1); } void hdmi_enable_plugin(int enable) { - hdmi_regs1->hotplug_detect.b.out_enable = enable; - hdmi_regs1->hotplug_detect.b.in_enable = enable; + vppif_reg32_write(HDMI_HOTPLUG_OUT_INT, enable); + vppif_reg32_write(HDMI_HOTPLUG_IN_INT, enable); } void hdmi_write_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) @@ -264,11 +288,12 @@ void hdmi_write_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) DPRINT("\n[HDMI] AVI info package end\n"); } #endif - hdmi_regs1->fifo_ctrl.val = (no << 8); + + vppif_reg32_out(REG_HDMI_FIFO_CTRL, (no << 8)); cnt = (cnt + 3) / 4; for (i = 0; i < cnt; i++) - hdmi_regs1->wr_fifo_addr[i] = buf[i]; - hdmi_regs1->fifo_ctrl.b.wr_strobe = 1; + vppif_reg32_out(REG_HDMI_WR_FIFO_ADDR + 4 * i, buf[i]); + vppif_reg32_write(HDMI_INFOFRAME_WR_STROBE, 1); } void hdmi_read_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) @@ -279,16 +304,16 @@ void hdmi_read_fifo(enum hdmi_fifo_slot_t no, unsigned int *buf, int cnt) if (no > HDMI_FIFO_SLOT_MAX) return; - rdy = hdmi_regs1->infoframe_ctrl.b.fifo1_rdy; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + rdy = vppif_reg32_read(HDMI_INFOFRAME_FIFO1_RDY); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); no = no - 1; - hdmi_regs1->fifo_ctrl.val = (no << 8); - hdmi_regs1->fifo_ctrl.b.rd_strobe = 1; + vppif_reg32_out(REG_HDMI_FIFO_CTRL, (no << 8)); + vppif_reg32_write(HDMI_INFOFRAME_RD_STROBE, 1); cnt = (cnt + 3) / 4; for (i = 0; i < cnt; i++) - buf[i] = hdmi_regs1->rd_fifo_addr[i]; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = rdy; + buf[i] = vppif_reg32_in(REG_HDMI_RD_FIFO_ADDR + 4 * i); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, rdy); #ifdef DEBUG { char *ptr; @@ -335,14 +360,14 @@ int hdmi_DDC_check_status(unsigned int checkbits, int condition) udelay(HDMI_DDC_DELAY); if (condition) { /* wait 1 --> 0 */ - while ((hdmi_regs1->i2c_ctrl2.val & checkbits) + while ((vppif_reg32_in(REG_HDMI_I2C_CTRL2) & checkbits) && (i < maxloop)) { udelay(HDMI_DDC_CHK_DELAY); if (++i == maxloop) status = 0; } } else { /* wait 0 --> 1 */ - while (!(hdmi_regs1->i2c_ctrl2.val & checkbits) + while (!(vppif_reg32_in(REG_HDMI_I2C_CTRL2) & checkbits) && (i < maxloop)) { udelay(HDMI_DDC_CHK_DELAY); if (++i == maxloop) @@ -353,7 +378,7 @@ int hdmi_DDC_check_status(unsigned int checkbits, int condition) if ((status == 0) && (checkbits != HDMI_STATUS_SW_READ)) { unsigned int reg; - reg = hdmi_regs1->i2c_ctrl2.val; + reg = vppif_reg32_in(REG_HDMI_I2C_CTRL2); DBG_DETAIL("[HDMI] status timeout check 0x%x,wait to %s\n", checkbits, (condition) ? "0" : "1"); DBG_DETAIL("[HDMI] 0x%x,sta %d,stop %d,wr %d,rd %d,cp %d\n", @@ -374,15 +399,15 @@ void hdmi_DDC_set_freq(unsigned int hz) clock = 25000000*15/100; /* RTC clock source */ div = clock / hz; - hdmi_regs1->i2c_ctrl.b.i2c_clk_divider = div; + vppif_reg32_write(HDMI_I2C_CLK_DIVIDER, div); DBG_DETAIL("[HDMI] set freq(%d,clk %d,div %d)\n", hz, clock, div); } void hdmi_DDC_reset(void) { - hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 1; + vppif_reg32_write(HDMI_I2C_SW_RESET, 1); udelay(1); - hdmi_regs1->i2c_ctrl.b.i2c_sw_reset = 0; + vppif_reg32_write(HDMI_I2C_SW_RESET, 0); } int hdmi_DDC_read_func(char addr, int index, char *buf, int length) @@ -392,7 +417,7 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) int err_cnt = 0; DBG_DETAIL("[HDMI] read DDC(index 0x%x,len %d),reg 0x%x\n", - index, length, hdmi_regs1->i2c_ctrl2.val); + index, length, vppif_reg32_in(REG_HDMI_I2C_CTRL2)); #ifdef CONFIG_HDMI_EDID_DISABLE return status; @@ -402,8 +427,7 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* enhanced DDC read */ if (index >= 256) { /* sw start, write data avail */ - vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2, - BIT18 + BIT16, 16, 0x5); + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -415,8 +439,8 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave address */ - hdmi_regs1->i2c_ctrl2.b.wr_data = 0x60; - hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1; + vppif_reg32_write(HDMI_WR_DATA, 0x60); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -427,8 +451,8 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Offset */ - hdmi_regs1->i2c_ctrl2.b.wr_data = 0x1; - hdmi_regs1->i2c_ctrl2.b.wr_data_avail = 1; + vppif_reg32_write(HDMI_WR_DATA, 0x1); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -441,7 +465,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* START */ - hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x50000); +#else +#if 0 + vppif_reg32_write(HDMI_SW_START_REQ, 1); /* sw start */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif + /* sw start, write data avail */ + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -453,7 +486,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave address */ - hdmi_regs1->i2c_ctrl2.val = 0x400A0; /* addr & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x400A0); +#else + vppif_reg32_write(HDMI_WR_DATA, addr); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != addr) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -464,7 +506,23 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Offset */ - hdmi_regs1->i2c_ctrl2.val = (0x40000 + index); /* index & data avail */ +#ifdef HDMI_DDC_OUT +{ + unsigned int reg; + + reg = 0x40000; + reg |= index; + + vppif_reg32_out(REG_HDMI_I2C_CTRL2, reg); +} +#else + vppif_reg32_write(HDMI_WR_DATA, index); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != index) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -474,8 +532,19 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) goto ddc_read_fail; } +/* vppif_reg32_write(HDMI_WR_DATA,addr+1); */ + /* START */ - hdmi_regs1->i2c_ctrl2.val = 0x50000; /* start & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x50000); +#else +#if 0 + vppif_reg32_write(HDMI_SW_START_REQ, 1); /* sw start */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif + /* sw start, write data avail */ + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT16, 16, 0x5); +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_START + @@ -487,7 +556,16 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) } /* Slave Address + 1 */ - hdmi_regs1->i2c_ctrl2.val = 0x400A1; /* addr(rd) & data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x400A1); +#else + vppif_reg32_write(HDMI_WR_DATA, addr + 1); + udelay(HDMI_DDC_DELAY); + while (vppif_reg32_read(HDMI_WR_DATA) != (addr + 1)) + ; + udelay(HDMI_DDC_DELAY); + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -499,7 +577,12 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* Read Data */ for (i = 0; i < length; i++) { - hdmi_regs1->i2c_ctrl2.val = 0x40000; /* data avail */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x40000); +#else + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ + /* hdmi_reg32_write(HDMI_WR_DATA_AVAIL,1); */ +#endif udelay(HDMI_DDC_CTRL_DELAY); /* wait wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_WR_AVAIL, 1); @@ -524,16 +607,23 @@ int hdmi_DDC_read_func(char addr, int index, char *buf, int length) /* break; */ } - *buf++ = hdmi_regs1->i2c_ctrl2.b.rd_data; + *buf++ = vppif_reg32_read(HDMI_RD_DATA); udelay(HDMI_DDC_DELAY); - hdmi_regs1->i2c_ctrl2.val = 0x2000000; /* clr sw read */ +#ifdef HDMI_DDC_OUT + vppif_reg32_out(REG_HDMI_I2C_CTRL2, 0x2000000); +#else + vppif_reg32_write(HDMI_SW_READ, 1); +#endif udelay(HDMI_DDC_DELAY); } /* STOP */ +#if 0 + vppif_reg32_write(HDMI_SW_STOP_REQ, 1); /* sw stop */ + vppif_reg32_write(HDMI_WR_DATA_AVAIL, 1); /* write data avail */ +#endif /* sw stop, write data avail */ - vppif_reg32_write((unsigned int) &hdmi_regs1->i2c_ctrl2.val, - BIT18 + BIT17, 17, 3); + vppif_reg32_write(REG_HDMI_I2C_CTRL2, BIT18 + BIT17, 17, 3); udelay(HDMI_DDC_CTRL_DELAY); /* wait start & wr data avail */ status = hdmi_DDC_check_status(HDMI_STATUS_STOP + @@ -554,39 +644,24 @@ ddc_read_fail: int hdmi_DDC_read(char addr, int index, char *buf, int length) { int retry = 3; - int ret; - - DBG_MSG("(0x%x,0x%x,%d)\n", addr, index, length); - do { - ret = hdmi_DDC_read_func(addr, index, buf, length); - if (ret == 0) + if (hdmi_DDC_read_func(addr, index, buf, length) == 0) break; hdmi_DDC_reset(); - DPRINT("[HDMI] *W* DDC reset %d\n", ret); + DPRINT("[HDMI] *W* DDC reset\n"); retry--; } while (retry); - return (retry == 0) ? 1 : 0; } void hdmi_audio_enable(vpp_flag_t enable) { - if (hdmi_regs1->aud_enable != enable) { - if (!enable) { -#ifdef CONFIG_KERNEL - msleep(5); -#endif - if (g_vpp.hdmi_ch_change) - REG32_VAL(I2S_BASE_ADDR + 0x188) = 0; - } - hdmi_regs1->aud_enable = (enable) ? 1 : 0; - } + vppif_reg32_write(HDMI_AUD_ENABLE, enable); } void hdmi_audio_mute(vpp_flag_t enable) { - hdmi_regs1->aud_ratio.b.mute = enable; + vppif_reg32_write(HDMI_AUD_MUTE, enable); } /*----------------------- HDMI API --------------------------------------*/ @@ -638,7 +713,7 @@ void hdmi_tx_general_control_packet(int mute) hdmi_write_packet(HDMI_PACKET_GENERAL_CTRL, buf, 7); } -int hdmi_get_pic_aspect(enum hdmi_video_code_t vic) +int hdmi_get_pic_aspect(hdmi_video_code_t vic) { switch (vic) { case HDMI_640x480p60_4x3: @@ -663,7 +738,7 @@ int hdmi_get_pic_aspect(enum hdmi_video_code_t vic) int hdmi_get_vic(int resx, int resy, int fps, int interlace) { - struct hdmi_vic_t info; + hdmi_vic_t info; int i; info.resx = resx; @@ -673,15 +748,14 @@ int hdmi_get_vic(int resx, int resy, int fps, int interlace) info.option |= (vout_check_ratio_16_9(resx, resy)) ? HDMI_VIC_16x9 : HDMI_VIC_4x3; for (i = 0; i < HDMI_VIDEO_CODE_MAX; i++) { - if (memcmp(&hdmi_vic_info[i], &info, - sizeof(struct hdmi_vic_t)) == 0) + if (memcmp(&hdmi_vic_info[i], &info, sizeof(hdmi_vic_t)) == 0) return i; } return HDMI_UNKNOW; } void hdmi_tx_avi_infoframe_packet(vdo_color_fmt colfmt, - enum hdmi_video_code_t vic) + hdmi_video_code_t vic) { unsigned int header; unsigned char buf[28]; @@ -732,9 +806,7 @@ void hdmi_tx_audio_infoframe_packet(int channel, int freq) buf[1] = (channel - 1) + (HDMI_AUD_TYPE_REF_STM << 4); buf[2] = 0x0; /* HDMI_AUD_SAMPLE_24 + (freq << 2); */ buf[3] = 0x00; - /* 0x13: RRC RLC RR RL FC LFE FR FL - 0x1F: FRC FLC RR RL FC LFE FR FL */ - buf[4] = (channel == 8) ? 0x13 : 0; + buf[4] = 0x0; buf[5] = 0x0; /* 0 db */ buf[0] = hdmi_checksum((unsigned char *)&header, buf, 28); hdmi_write_packet(header, buf, 28); @@ -769,191 +841,270 @@ void hdmi_tx_vendor_specific_infoframe_packet(void) hdmi_write_packet(header, buf, 28); } -#define HDMI_N_CTS_USE_TABLE -#ifdef HDMI_N_CTS_USE_TABLE -struct hdmi_n_cts_s { - unsigned int n; - unsigned int cts; -}; +/* +--> Added by howayhuo. +Some TV (example: TCL L19E09) will overclock if ACR ratio too large, +So we need decrease the ACR ratio for some special TV +*/ +static void print_acr(void) +{ + int i; -struct hdmi_n_cts_s hdmi_n_cts_table[7][11] = { - /* 32kHz */ - {{ 9152, 84375 }, {4096, 37800}, {4096, 40500}, {8192, 81081}, - { 4096, 81000 }, {4096, 81081}, {11648, 316406}, {4096, 111375}, - { 11648, 632812}, {4096, 222750}, {4096, 0}}, - /* 44.1kHz */ - {{7007, 46875}, {6272, 42000}, {6272, 45000}, {6272, 45045}, - {6272, 90000}, {6272, 90090}, {17836, 351562}, {6272, 123750}, - {17836, 703125}, {6272, 247500}, {6272, 0}}, - /* 88.2kHz */ - {{14014, 46875}, {12544, 42000}, {12544, 45000}, {12544, 45045}, - {12544, 90000}, {12544, 90090}, {35672, 351562}, {12544, 123750}, - {35672, 703125}, {12544, 247500}, {12544, 0}}, - /* 176.4kHz */ - {{28028, 46875}, {25088, 42000}, {25088, 45000}, {25088, 45045}, - {25088, 90000}, {25088, 90090}, {71344, 351562}, {25088, 123750}, - {71344, 703125}, {25088, 247500}, {25088, 0}}, - /* 48kHz */ - {{9152, 56250}, {6144, 37800}, {6144, 40500}, {8192, 54054}, - {6144, 81000}, {6144, 81081}, {11648, 210937}, {6144, 111375}, - {11648, 421875}, {6144, 222750}, {6144, 0}}, - /* 96kHz */ - {{18304, 56250}, {12288, 37800}, {12288, 40500}, {16384, 54054}, - {12288, 81000}, {12288,81081}, {23296, 210937}, {12288, 111375}, - {23296, 421875}, {12288, 222750}, {12288, 0}}, - /* 192kHz */ - {{36608, 56250}, {24576, 37800}, {24576, 40500}, {32768, 54054}, - {24576, 81000}, {24576, 81081}, {46592, 210937}, {24576, 111375}, - {46592, 421875}, {24576, 222750}, {24576, 0}} -}; + if(p_fix_acr_tv != NULL) { + for(i = 0; i < MAX_ACR_TV_NUM; i++) { + if(strlen(p_fix_acr_tv[i].vendor_name) == 0 + || strlen(p_fix_acr_tv[i].monitor_name) == 0) + break; + + if(i == 0) + printk("ACR TV Name:\n"); -struct hdmi_n_cts_s *hdmi_get_n_cts(unsigned int tmds_clk, - unsigned int freq) + printk(" %s,%s\n", p_fix_acr_tv[i].vendor_name, p_fix_acr_tv[i].monitor_name); + } + } +} + +static void acr_init(void) { - int i, j; + char buf[512] = {0}; + int buflen = 512; + unsigned long val; + int i, j, k, tv_num; + int ret, to_save_vendor; + tv_name_t tv_name; + + if(p_fix_acr_tv != NULL) { + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + } - switch (freq) { - case 32000: - i = 0; - break; - case 44100: - i = 1; - break; - case 88200: - i = 2; - break; - case 176400: - i = 3; - break; - case 48000: - i = 4; - break; - case 96000: - i = 5; - break; - case 192000: - i = 6; - break; - default: - return 0; + if(wmt_getsyspara("wmt.acr.ratio", buf, &buflen) == 0) { + ret = strict_strtoul(buf, 10, &val); + if(ret) { + printk("[HDMI] Wrong wmt.acr.ratio value: %s\n", buf); + return; + } + if(val >= 0 && val < 0xFFFFF) // total 20 bits + fixed_acr_ration_val = (int)val; + else + printk("[HDMI] Invalid Fixed ACR Ratio: %lu\n", val); } - switch (tmds_clk) { - case 25174825: - j = 0; - break; - case 25200000: - j = 1; - break; - case 27000000: - j = 2; - break; - case 27027000: - j = 3; - break; - case 54000000: - j = 4; - break; - case 54054000: - j = 5; - break; - case 74175824: - j = 6; - break; - case 74250000: - j = 7; - break; - case 148351648: - j = 8; - break; - case 148500000: - j = 9; - break; - default: - j = 10; - break; + if(fixed_acr_ration_val == 0) + return; + + /* + For example: setenv wmt.acr.tv 'TCH,RTD2662;PHL,Philips 244E' + */ + if(wmt_getsyspara("wmt.acr.tv", buf, &buflen) != 0) { + p_fix_acr_tv = (tv_name_t *)kzalloc(sizeof(fix_acr_tv_list) + sizeof(tv_name_t), GFP_KERNEL); + if(p_fix_acr_tv) { + memcpy(p_fix_acr_tv, fix_acr_tv_list, sizeof(fix_acr_tv_list)); + print_acr(); + } else + printk("[HDMI] malloc for ACR fail. malloc len = %d\n", + sizeof(fix_acr_tv_list) + sizeof(tv_name_t)); + + return; + } + + tv_num = 0; + buflen = strlen(buf); + if(buflen == 0) + return; + + if(buflen == sizeof(buf)) { + printk("[HDMI] wmt.acr.tv too long\n"); + return; + } + + for(i = 0; i < buflen; i++) { + if(buf[i] == ',') + tv_num++; + } + + /* + Limit TV Number + */ + if(tv_num > MAX_ACR_TV_NUM) + tv_num = MAX_ACR_TV_NUM; + + if(tv_num == 0) + return; + + printk("acr_tv_num = %d\n", tv_num); + p_fix_acr_tv = (tv_name_t *)kzalloc((tv_num + 1) * sizeof(tv_name_t), GFP_KERNEL); + if(!p_fix_acr_tv) { + printk("[HDMI] malloc for ACR fail. malloc len = %d\n", + sizeof(fix_acr_tv_list) + sizeof(tv_name_t)); + return; + } + memset(&tv_name, 0, sizeof(tv_name_t)); + + j = 0; + k = 0; + to_save_vendor= 1; + for(i = 0; i < buflen + 1; i++) { + if(buf[i] != ',' && buf[i] != ';' && buf[i] != '\0') { + if(to_save_vendor) { + if(k < VENDOR_NAME_LEN) + tv_name.vendor_name[k] = buf[i]; + } else { + if(k < MONITOR_NAME_LEN) + tv_name.monitor_name[k] = buf[i]; + } + k++; + } else if(buf[i] == ',') { + to_save_vendor = 0; + k = 0; + } else { + if(strlen(tv_name.vendor_name) == 0 || strlen(tv_name.monitor_name) == 0) { + printk("[HDMI] Wrong wmt.acr.tv format\n"); + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + break; + } else { + if(j < tv_num) { + memcpy(p_fix_acr_tv + j, &tv_name, sizeof(tv_name_t)); + memset(&tv_name, 0, sizeof(tv_name_t)); + j++; + } + + if(j == tv_num) + break; + } + + if(buf[i]== ';') { + to_save_vendor = 1; + k = 0; + } else + break; + } } - return &hdmi_n_cts_table[i][j]; + + print_acr(); } -#endif -void hdmi_set_audio_n_cts(unsigned int freq) +void acr_exit(void) { - unsigned int n = 0, cts = 0; + if(p_fix_acr_tv != NULL) { + kfree(p_fix_acr_tv); + p_fix_acr_tv = NULL; + } +} -#ifdef HDMI_N_CTS_USE_TABLE - struct hdmi_n_cts_s *p; +static int use_fix_acr_ratio(void) +{ + int i; + + if(fixed_acr_ration_val == 0 || p_fix_acr_tv == NULL) + return 0; + + for(i = 0; i < MAX_ACR_TV_NUM; i++) { + if(strlen(p_fix_acr_tv[i].vendor_name) == 0 + || strlen(p_fix_acr_tv[i].monitor_name) == 0) + break; - p = hdmi_get_n_cts(g_vpp.hdmi_pixel_clock, freq); - if (p) { - n = p->n; - cts = p->cts; - MSG("[HDMI] use table n %d, cts %d\n", n, cts); + if(!strcmp(edid_parsed.tv_name.vendor_name, p_fix_acr_tv[i].vendor_name) + && !strcmp(edid_parsed.tv_name.monitor_name, p_fix_acr_tv[i].monitor_name)) { + printk("TV is \"%s %s\". Use fixed HDMI ACR Ratio: %d\n", + edid_parsed.tv_name.vendor_name, + edid_parsed.tv_name.monitor_name, + fixed_acr_ration_val); + return 1; + } } -#endif - if (n == 0) - n = 128 * freq / 1000; + return 0; +} +/* +<-- end added by howayhuo +*/ + +void hdmi_set_audio_n_cts(unsigned int freq) +{ + unsigned int n, cts; - if (cts == 0) { + n = 128 * freq / 1000; #ifdef __KERNEL__ - unsigned int tmp; - unsigned int pll_clk; +{ + unsigned int tmp; + unsigned int pll_clk; - pll_clk = auto_pll_divisor(DEV_I2S, GET_FREQ, 0, 0); - tmp = (inl(AUDREGF_BASE_ADDR + 0x70) & 0xF); + pll_clk = auto_pll_divisor(DEV_I2S, GET_FREQ, 0, 0); + tmp = (vppif_reg32_in(AUDREGF_BASE_ADDR+0x70) & 0xF); - switch (tmp) { - case 0 ... 4: - tmp = 0x01 << tmp; - break; - case 9 ... 12: - tmp = 3 * (0x1 << (tmp-9)); - break; - default: - tmp = 1; - break; - } - { - unsigned long long tmp2; - unsigned long long div2; - unsigned long mod; - - tmp2 = g_vpp.hdmi_pixel_clock; - tmp2 = tmp2 * n * tmp; - div2 = pll_clk; - mod = do_div(tmp2, div2); - cts = tmp2; - } - DBGMSG("[HDMI] i2s %d,cts %d,reg 0x%x\n", pll_clk, cts, - vppif_reg32_in(AUDREGF_BASE_ADDR + 0x70)); + switch (tmp) { + case 0 ... 4: + tmp = 0x01 << tmp; + break; + case 9 ... 12: + tmp = 3 * (0x1 << (tmp-9)); + break; + default: + tmp = 1; + break; + } + + { + unsigned long long tmp2; + unsigned long long div2; + unsigned long mod; + + tmp2 = g_vpp.hdmi_pixel_clock; + tmp2 = tmp2 * n * tmp; + div2 = pll_clk; + mod = do_div(tmp2, div2); + cts = tmp2; + } + DBGMSG("[HDMI] i2s %d,cts %d,reg 0x%x\n", pll_clk, cts, + vppif_reg32_in(AUDREGF_BASE_ADDR + 0x70)); +} + + vppif_reg32_write(HDMI_AUD_N_20BITS, n); + if(use_fix_acr_ratio()) + vppif_reg32_write(HDMI_AUD_ACR_RATIO, fixed_acr_ration_val); + else + vppif_reg32_write(HDMI_AUD_ACR_RATIO, cts - 1); +#else +#if 1 + cts = g_vpp.hdmi_pixel_clock / 1000; #else - cts = (g_vpp.hdmi_pixel_clock / 1000) - 1; + cts = vpp_get_base_clock(VPP_MOD_GOVRH) / 1000; #endif - } - hdmi_regs1->aud_sample_rate1.b.n_20bits = n; - hdmi_regs1->aud_ratio.b.acr_ratio = cts - 1; - hdmi_regs1->aud_sample_rate2.b.cts_select = 0; + vppif_reg32_write(HDMI_AUD_N_20BITS, n); + if(use_fix_acr_ratio()) + vppif_reg32_write(HDMI_AUD_ACR_RATIO, fixed_acr_ration_val); + else + vppif_reg32_write(HDMI_AUD_ACR_RATIO, cts - 2); +#endif + +#if 1 /* auto detect CTS */ + vppif_reg32_write(HDMI_AUD_CTS_SELECT, 0); cts = 0; - hdmi_regs1->aud_sample_rate1.b.cts_low_12bits = cts & 0xFFF; - hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits = (cts & 0xFF000) >> 12; +#else + vppif_reg32_write(HDMI_AUD_CTS_SELECT, 1); +#endif + vppif_reg32_write(HDMI_AUD_CTS_LOW_12BITS, cts & 0xFFF); + vppif_reg32_write(HDMI_AUD_CTS_HI_8BITS, (cts & 0xFF000) >> 12); + DBGMSG("[HDMI] set audio freq %d,n %d,cts %d,tmds %d\n", freq, n, cts, g_vpp.hdmi_pixel_clock); } - -void hdmi_config_audio(struct vout_audio_t *info) +void hdmi_config_audio(vout_audio_t *info) { unsigned int freq; - g_vpp.hdmi_audio_channel = info->channel; - g_vpp.hdmi_audio_freq = info->sample_rate; + hdmi_info.channel = info->channel; + hdmi_info.freq = info->sample_rate; /* enable ARF & ARFP clock */ REG32_VAL(PM_CTRL_BASE_ADDR + 0x254) |= (BIT4 | BIT3); - hdmi_tx_audio_infoframe_packet(info->channel, info->sample_rate); + hdmi_tx_audio_infoframe_packet(info->channel - 1, info->sample_rate); hdmi_audio_enable(VPP_FLAG_DISABLE); - hdmi_regs1->aud_mode.b.layout = (info->channel > 2) ? 1 : 0; - hdmi_regs1->aud_mode.b._2ch_eco = (info->channel > 2) ? 0 : 1; + vppif_reg32_write(HDMI_AUD_LAYOUT, (info->channel == 8) ? 1 : 0); + vppif_reg32_write(HDMI_AUD_2CH_ECO, 1); + switch (info->sample_rate) { case 32000: freq = 0x3; @@ -981,20 +1132,22 @@ void hdmi_config_audio(struct vout_audio_t *info) freq = 0x9; break; } - hdmi_regs1->aud_chan_status0 = (freq << 24) + 0x4; - hdmi_regs1->aud_chan_status1 = 0x0; - hdmi_regs1->aud_chan_status2 = 0xb; - hdmi_regs1->aud_chan_status3 = 0x0; - hdmi_regs1->aud_chan_status4 = 0x0; - hdmi_regs1->aud_chan_status5 = 0x0; + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS0, (freq << 24) + 0x4); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS1, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS2, 0xb); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS3, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS4, 0x0); + vppif_reg32_out(REG_HDMI_AUD_CHAN_STATUS5, 0x0); hdmi_set_audio_n_cts(info->sample_rate); - hdmi_regs1->aud_ratio.b.acr_enable = 1; - hdmi_regs1->aud_sample_rate2.b.aipclk_rate = 0; - hdmi_audio_enable(VPP_FLAG_ENABLE); + vppif_reg32_write(HDMI_AUD_ACR_ENABLE, VPP_FLAG_ENABLE); + vppif_reg32_write(HDMI_AUD_AIPCLK_RATE, 0); + hdmi_audio_enable(hdmi_get_plugin() ? + VPP_FLAG_ENABLE : VPP_FLAG_DISABLE); + } -void hdmi_config_video(struct hdmi_info_t *info) +void hdmi_config_video(hdmi_info_t *info) { hdmi_set_output_colfmt(info->outfmt); hdmi_tx_avi_infoframe_packet(info->outfmt, info->vic); @@ -1031,16 +1184,16 @@ void hdmi_set_option(unsigned int option) DBG_MSG("[HDMI] set option(8-HDMI,6-AUDIO) 0x%x\n", option); } -void hdmi_config(struct hdmi_info_t *info) +void hdmi_config(hdmi_info_t *info) { - struct vout_audio_t audio_info; + vout_audio_t audio_info; int h_porch; int delay_cfg; vpp_clock_t clock; - hdmi_regs1->ctrl.b.hden = 0; - hdmi_regs1->infoframe_ctrl.b.select = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + vppif_reg32_write(HDMI_HDEN, 0); + vppif_reg32_write(HDMI_INFOFRAME_SELECT, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); hdmi_config_video(info); govrh_get_tg(p_govrh, &clock); @@ -1054,10 +1207,8 @@ void hdmi_config(struct hdmi_info_t *info) h_porch = 1; if (h_porch >= 8) h_porch = 0; - - hdmi_regs1->general_ctrl.b.cp_delay = delay_cfg; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for write only */ - hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck = h_porch; + hdmi_reg32_write(HDMI_CP_DELAY, delay_cfg); + vppif_reg32_write(HDMI_HORIZ_BLANK_MAX_PCK, h_porch); DBGMSG("[HDMI] H blank max pck %d,delay %d\n", h_porch, delay_cfg); audio_info.fmt = 16; @@ -1065,12 +1216,13 @@ void hdmi_config(struct hdmi_info_t *info) audio_info.sample_rate = info->freq; hdmi_config_audio(&audio_info); - hdmi_regs1->infoframe_ctrl.b.fifo1_addr = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_len = 2; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 1; + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_ADDR, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_LEN, 2); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 1); + hdmi_set_option(info->option); - hdmi_regs2->test.b.tre_en = - (g_vpp.hdmi_pixel_clock < 40000000) ? 3 : 2; + vppif_reg32_write(HDMI_TRE_EN, + (g_vpp.hdmi_pixel_clock < 40000000) ? 3 : 2); } /*----------------------- Module API --------------------------------------*/ @@ -1110,9 +1262,14 @@ void hdmi_get_bksv(unsigned int *bksv) #ifdef __KERNEL__ void hdmi_hotplug_notify(int plug_status) { - if (g_vpp.hdmi_disable) - return; - vpp_netlink_notify_plug(VPP_VOUT_NUM_HDMI, plug_status); + if (g_vpp.hdmi_disable) + return; + if (g_vpp.virtual_display || (g_vpp.dual_display == 0)) { + vpp_netlink_notify_plug(VPP_VOUT_ALL, 0); + vpp_netlink_notify_plug(VPP_VOUT_ALL, 1); + return; + } + vpp_netlink_notify_plug(VPP_VOUT_NUM_HDMI, plug_status); } #else #define hdmi_hotplug_notify @@ -1120,44 +1277,44 @@ void hdmi_hotplug_notify(int plug_status) int hdmi_check_plugin(int hotplug) { - static int last_plugin = -1; - int plugin; - int flag; + static int last_plugin = -1; + int plugin; + int flag; - if (g_vpp.hdmi_disable) - return 0; + if (g_vpp.hdmi_disable) + return 0; - plugin = hdmi_get_plugin(); - hdmi_clear_plug_status(); + plugin = hdmi_get_plugin(); + hdmi_clear_plug_status(); #ifdef __KERNEL__ - /* disable HDMI before change clock */ - if (plugin == 0) { - hdmi_set_enable(0); - hdmi_set_power_down(1); - } - vpp_set_clock_enable(DEV_HDMII2C, plugin, 1); - vpp_set_clock_enable(DEV_HDCE, plugin, 1); - - /* slow down clock for plugout */ - flag = (auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0) - == 8000000) ? 0 : 1; - if ((plugin != flag) && !g_vpp.virtual_display) { - int pixclk; - - pixclk = (plugin) ? g_vpp.hdmi_pixel_clock : 8000000; - auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV, 0, pixclk); - } + /* disable HDMI before change clock */ + if (plugin == 0) { + hdmi_set_enable(0); + hdmi_set_power_down(1); + } + vpp_set_clock_enable(DEV_HDMII2C, plugin, 1); + vpp_set_clock_enable(DEV_HDCE, plugin, 1); + + /* slow down clock for plugout */ + flag = (auto_pll_divisor(DEV_HDMILVDS, GET_FREQ, 0, 0) + == 8000000) ? 0 : 1; + if ((plugin != flag) && !g_vpp.virtual_display) { + int pixclk; + + pixclk = (plugin) ? g_vpp.hdmi_pixel_clock : 8000000; + auto_pll_divisor(DEV_HDMILVDS, SET_PLLDIV, 0, pixclk); + } #endif - if (last_plugin != plugin) { - DPRINT("[HDMI] HDMI plug%s,hotplug %d\n", (plugin) ? - "in" : "out", hotplug); - last_plugin = plugin; - } -#if 0 /* Denzel test */ - if (plugin == 0) - hdmi_set_dvi_enable(VPP_FLAG_ENABLE); + if (last_plugin != plugin) { + DPRINT("[HDMI] HDMI plug%s,hotplug %d\n", (plugin) ? + "in" : "out", hotplug); + last_plugin = plugin; + } +#if 0 /* Denzel test */ + if (plugin == 0) + hdmi_set_dvi_enable(VPP_FLAG_ENABLE); #endif - return plugin; + return plugin; } void hdmi_reg_dump(void) @@ -1168,107 +1325,106 @@ void hdmi_reg_dump(void) DPRINT("---------- HDMI common ----------\n"); DPRINT("enable %d,hden %d,reset %d,dvi %d\n", - hdmi_regs1->general_ctrl.b.enable, - hdmi_regs1->ctrl.b.hden, - hdmi_regs1->general_ctrl.b.reset, - hdmi_regs1->general_ctrl.b.dvi_mode_enable); + vppif_reg32_read(HDMI_ENABLE), vppif_reg32_read(HDMI_HDEN), + vppif_reg32_read(HDMI_RESET), + vppif_reg32_read(HDMI_DVI_MODE_ENABLE)); DPRINT("colfmt %d,conv 422 %d,hsync low %d,vsync low %d\n", - hdmi_regs1->general_ctrl.b.output_format, - hdmi_regs1->general_ctrl.b.convert_yuv422, - hdmi_regs1->general_ctrl.b.hsync_low_active, - hdmi_regs1->general_ctrl.b.vsync_low_active); + vppif_reg32_read(HDMI_OUTPUT_FORMAT), + vppif_reg32_read(HDMI_CONVERT_YUV422), + vppif_reg32_read(HDMI_HSYNC_LOW_ACTIVE), + vppif_reg32_read(HDMI_VSYNC_LOW_ACTIVE)); DPRINT("dbg bus sel %d,state mach %d\n", - hdmi_regs1->general_ctrl.b.dbg_bus_select, - hdmi_regs1->general_ctrl.b.state_machine_status); + vppif_reg32_read(HDMI_DBG_BUS_SELECT), + vppif_reg32_read(HDMI_STATE_MACHINE_STATUS)); DPRINT("eep reset %d,encode %d,eess %d\n", - hdmi_regs1->ctrl.b.eeprom_reset, - hdmi_regs1->ctrl.b.encode_enable, - hdmi_regs1->ctrl.b.eess_enable); + vppif_reg32_read(HDMI_EEPROM_RESET), + vppif_reg32_read(HDMI_ENCODE_ENABLE), + vppif_reg32_read(HDMI_EESS_ENABLE)); DPRINT("verify pj %d,auth test %d,cipher %d\n", - hdmi_regs1->ctrl.b.verify_pj_enable, - hdmi_regs1->ctrl.b.auth_test_key, - hdmi_regs1->ctrl.b.cipher_1_1); - DPRINT("preamble %d\n", hdmi_regs1->ctrl.b.preamble); + vppif_reg32_read(HDMI_VERIFY_PJ_ENABLE), + vppif_reg32_read(HDMI_AUTH_TEST_KEY), + vppif_reg32_read(HDMI_CIPHER_1_1)); + DPRINT("preamble %d\n", vppif_reg32_read(HDMI_PREAMBLE)); DPRINT("---------- HDMI hotplug ----------\n"); - DPRINT("plug %s\n", (hdmi_regs1->hotplug_detect.b.sts) ? "in" : "out"); + DPRINT("plug %s\n", vppif_reg32_read(HDMI_HOTPLUG_IN) ? "in" : "out"); DPRINT("plug in enable %d, status %d\n", - hdmi_regs1->hotplug_detect.b.in_enable, - hdmi_regs1->hotplug_detect.b.in_sts); + vppif_reg32_read(HDMI_HOTPLUG_IN_INT), + vppif_reg32_read(HDMI_HOTPLUG_IN_STS)); DPRINT("plug out enable %d, status %d\n", - hdmi_regs1->hotplug_detect.b.out_enable, - hdmi_regs1->hotplug_detect.b.out_sts); + vppif_reg32_read(HDMI_HOTPLUG_OUT_INT), + vppif_reg32_read(HDMI_HOTPLUG_OUT_STS)); DPRINT("debounce detect %d,sample %d\n", - hdmi_regs1->hotplug_debounce.b.detect, - hdmi_regs1->hotplug_debounce.b.sample); + vppif_reg32_read(HDMI_DEBOUNCE_DETECT), + vppif_reg32_read(HDMI_DEBOUNCE_SAMPLE)); DPRINT("---------- I2C ----------\n"); DPRINT("enable %d,exit FSM %d,key read %d\n", - hdmi_regs1->ctrl.b.i2c_enable, - hdmi_regs1->i2c_ctrl.b.force_exit_fsm, - hdmi_regs1->i2c_ctrl.b.key_read_word); + vppif_reg32_read(HDMI_I2C_ENABLE), + vppif_reg32_read(HDMI_FORCE_EXIT_FSM), + vppif_reg32_read(HDMI_KEY_READ_WORD)); DPRINT("clk divid %d,rd data 0x%x,wr data 0x%x\n", - hdmi_regs1->i2c_ctrl.b.i2c_clk_divider, - hdmi_regs1->i2c_ctrl2.b.rd_data, - hdmi_regs1->i2c_ctrl2.b.wr_data); + vppif_reg32_read(HDMI_I2C_CLK_DIVIDER), + vppif_reg32_read(HDMI_RD_DATA), + vppif_reg32_read(HDMI_WR_DATA)); DPRINT("start %d,stop %d,wr avail %d\n", - hdmi_regs1->i2c_ctrl2.b.sw_start_req, - hdmi_regs1->i2c_ctrl2.b.sw_stop_req, - hdmi_regs1->i2c_ctrl2.b.wr_data_avail); + vppif_reg32_read(HDMI_SW_START_REQ), + vppif_reg32_read(HDMI_SW_STOP_REQ), + vppif_reg32_read(HDMI_WR_DATA_AVAIL)); DPRINT("status %d,sw read %d,sw i2c req %d\n", - hdmi_regs1->i2c_ctrl2.b.i2c_status, - hdmi_regs1->i2c_ctrl2.b.sw_read, - hdmi_regs1->i2c_ctrl2.b.sw_i2c_req); + vppif_reg32_read(HDMI_I2C_STATUS), + vppif_reg32_read(HDMI_SW_READ), + vppif_reg32_read(HDMI_SW_I2C_REQ)); DPRINT("---------- AUDIO ----------\n"); DPRINT("enable %d,sub pck %d,spflat %d\n", - hdmi_regs1->aud_enable, - hdmi_regs1->aud_mode.b.sub_packet, - hdmi_regs1->aud_mode.b.spflat); + vppif_reg32_read(HDMI_AUD_ENABLE), + vppif_reg32_read(HDMI_AUD_SUB_PACKET), + vppif_reg32_read(HDMI_AUD_SPFLAT)); DPRINT("aud pck insert reset %d,enable %d,delay %d\n", - hdmi_regs1->aud_insert_ctrl.b.pck_insert_reset, - hdmi_regs1->aud_insert_ctrl.b.pck_insert_enable, - hdmi_regs1->aud_insert_ctrl.b.insert_delay); + vppif_reg32_read(HDMI_AUD_PCK_INSERT_RESET), + vppif_reg32_read(HDMI_AUD_PCK_INSERT_ENABLE), + vppif_reg32_read(HDMI_AUD_INSERT_DELAY)); DPRINT("avmute set %d,clr %d,pixel repete %d\n", - hdmi_regs1->aud_insert_ctrl.b.avmute_set_enable, - hdmi_regs1->aud_insert_ctrl.b.avmute_clr_enable, - hdmi_regs1->aud_insert_ctrl.b.pixel_repetition); + vppif_reg32_read(HDMI_AVMUTE_SET_ENABLE), + vppif_reg32_read(HDMI_AVMUTE_CLR_ENABLE), + vppif_reg32_read(HDMI_AUD_PIXEL_REPETITION)); DPRINT("acr ratio %d,acr enable %d,mute %d\n", - hdmi_regs1->aud_ratio.b.acr_ratio, - hdmi_regs1->aud_ratio.b.acr_enable, - hdmi_regs1->aud_ratio.b.mute); + vppif_reg32_read(HDMI_AUD_ACR_RATIO), + vppif_reg32_read(HDMI_AUD_ACR_ENABLE), + vppif_reg32_read(HDMI_AUD_MUTE)); DPRINT("layout %d,pwr save %d,n 20bits %d\n", - hdmi_regs1->aud_mode.b.layout, - hdmi_regs1->aud_mode.b.pwr_saving, - hdmi_regs1->aud_sample_rate1.b.n_20bits); + vppif_reg32_read(HDMI_AUD_LAYOUT), + vppif_reg32_read(HDMI_AUD_PWR_SAVING), + vppif_reg32_read(HDMI_AUD_N_20BITS)); DPRINT("cts low 12 %d,hi 8 %d,cts sel %d\n", - hdmi_regs1->aud_sample_rate1.b.cts_low_12bits, - hdmi_regs1->aud_sample_rate2.b.cts_hi_8bits, - hdmi_regs1->aud_sample_rate2.b.cts_select); - DPRINT("aipclk rate %d\n", hdmi_regs1->aud_sample_rate2.b.aipclk_rate); + vppif_reg32_read(HDMI_AUD_CTS_LOW_12BITS), + vppif_reg32_read(HDMI_AUD_CTS_HI_8BITS), + vppif_reg32_read(HDMI_AUD_CTS_SELECT)); + DPRINT("aipclk rate %d\n", vppif_reg32_read(HDMI_AUD_AIPCLK_RATE)); DPRINT("---------- INFOFRAME ----------\n"); DPRINT("sel %d,hor blank pck %d\n", - hdmi_regs1->infoframe_ctrl.b.select, - hdmi_regs1->infoframe_ctrl.b.horiz_blank_max_pck); + vppif_reg32_read(HDMI_INFOFRAME_SELECT), + vppif_reg32_read(HDMI_HORIZ_BLANK_MAX_PCK)); DPRINT("fifo1 ready %d,addr 0x%x,len %d\n", - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy, - hdmi_regs1->infoframe_ctrl.b.fifo1_addr, - hdmi_regs1->infoframe_ctrl.b.fifo1_len); + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_RDY), + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_ADDR), + vppif_reg32_read(HDMI_INFOFRAME_FIFO1_LEN)); DPRINT("fifo2 ready %d,addr 0x%x,len %d\n", - hdmi_regs1->infoframe_ctrl.b.fifo2_rdy, - hdmi_regs1->infoframe_ctrl.b.fifo2_addr, - hdmi_regs1->infoframe_ctrl.b.fifo2_len); + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_RDY), + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_ADDR), + vppif_reg32_read(HDMI_INFOFRAME_FIFO2_LEN)); DPRINT("wr strobe %d,rd strobe %d,fifo addr %d\n", - hdmi_regs1->fifo_ctrl.b.wr_strobe, - hdmi_regs1->fifo_ctrl.b.rd_strobe, - hdmi_regs1->fifo_ctrl.b.addr); + vppif_reg32_read(HDMI_INFOFRAME_WR_STROBE), + vppif_reg32_read(HDMI_INFOFRAME_RD_STROBE), + vppif_reg32_read(HDMI_INFOFRAME_FIFO_ADDR)); { int i; unsigned int buf[32]; - for (i = 0; i <= hdmi_regs1->infoframe_ctrl.b.fifo1_len; i++) { + for (i = 0; i <= vppif_reg32_read(HDMI_INFOFRAME_FIFO1_LEN); i++) { DPRINT("----- infoframe %d -----\n", i); hdmi_read_fifo(i, buf, 32); vpp_reg_dump((unsigned int) buf, 32); @@ -1277,14 +1433,15 @@ void hdmi_reg_dump(void) DPRINT("---------- HDMI test ----------\n"); DPRINT("ch0 enable %d, data 0x%x\n", - hdmi_regs1->channel_test.b.ch0_enable, - hdmi_regs1->channel_test.b.ch0_data); + vppif_reg32_read(HDMI_CH0_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH0_TEST_DATA)); DPRINT("ch1 enable %d, data 0x%x\n", - hdmi_regs1->channel_test.b.ch1_enable, - hdmi_regs1->channel_test.b.ch1_data); + vppif_reg32_read(HDMI_CH1_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH1_TEST_DATA)); DPRINT("ch2 enable %d, data 0x%x\n", - hdmi_regs1->hotplug_detect.b.ch2_enable, - hdmi_regs1->hotplug_detect.b.ch2_data); + vppif_reg32_read(HDMI_CH2_TEST_MODE_ENABLE), + vppif_reg32_read(HDMI_CH2_TEST_DATA)); + if (hdmi_cp) hdmi_cp->dump(); } @@ -1295,12 +1452,13 @@ static unsigned int *hdmi_pm_bk2; static unsigned int hdmi_pm_enable; static unsigned int hdmi_pm_enable2; static int hdmi_plug_enable = 0xFF; +extern struct switch_dev vpp_sdev; static int hdmi_resume_plug_cnt; #define HDMI_RESUME_PLUG_MS 50 #define HDMI_RESUME_PLUG_CNT 20 static void hdmi_do_resume_plug(struct work_struct *ptr) { - struct vout_t *vo; + vout_t *vo; int plugin; struct delayed_work *dwork = to_delayed_work(ptr); @@ -1309,7 +1467,7 @@ static void hdmi_do_resume_plug(struct work_struct *ptr) vout_change_status(vo, VPP_VOUT_STS_PLUGIN, plugin); if (plugin) hdmi_hotplug_notify(1); - hdmi_resume_plug_cnt--; + hdmi_resume_plug_cnt --; if (hdmi_resume_plug_cnt && (vpp_sdev.state == 0)) schedule_delayed_work(dwork, msecs_to_jiffies(HDMI_RESUME_PLUG_MS)); @@ -1323,14 +1481,13 @@ void hdmi_suspend(int sts) switch (sts) { case 0: /* disable module */ cancel_delayed_work_sync(&hdmi_resume_work); - hdmi_pm_enable = hdmi_regs1->general_ctrl.b.enable; - hdmi_regs1->general_ctrl.b.enable = 0; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */ - hdmi_pm_enable2 = hdmi_regs1->ctrl.b.hden; - hdmi_regs1->ctrl.b.hden = 0; + hdmi_pm_enable = vppif_reg32_read(HDMI_ENABLE); + hdmi_reg32_write(HDMI_ENABLE, 0); + hdmi_pm_enable2 = vppif_reg32_read(HDMI_HDEN); + vppif_reg32_write(HDMI_HDEN, 0); if (hdmi_plug_enable == 0xFF) hdmi_plug_enable = - hdmi_regs1->hotplug_detect.b.out_enable; + vppif_reg32_read(HDMI_HOTPLUG_OUT_INT); hdmi_enable_plugin(0); break; case 1: /* disable tg */ @@ -1340,6 +1497,7 @@ void hdmi_suspend(int sts) (REG_HDMI_END - REG_HDMI_BEGIN)); hdmi_pm_bk2 = vpp_backup_reg(REG_HDMI2_BEGIN, (REG_HDMI2_END - REG_HDMI2_BEGIN)); + switch_set_state(&vpp_sdev, 0); hdmi_resume_plug_cnt = 20; break; default: @@ -1353,7 +1511,6 @@ void hdmi_resume(int sts) vo_hdmi_set_clock(1); switch (sts) { case 0: /* restore register */ - switch_set_state(&vpp_sdev, 0); vpp_restore_reg(REG_HDMI_BEGIN, (REG_HDMI_END - REG_HDMI_BEGIN), hdmi_pm_bk); vpp_restore_reg(REG_HDMI2_BEGIN, @@ -1365,9 +1522,8 @@ void hdmi_resume(int sts) hdmi_cp->init(); break; case 1: /* enable module */ - hdmi_regs1->general_ctrl.b.enable = hdmi_pm_enable; - hdmi_regs1->general_ctrl.b.vsync_enable = 1; /* for wr only */ - hdmi_regs1->ctrl.b.hden = hdmi_pm_enable2; + hdmi_reg32_write(HDMI_ENABLE, hdmi_pm_enable); + vppif_reg32_write(HDMI_HDEN, hdmi_pm_enable2); break; case 2: /* enable tg */ hdmi_check_plugin(0); @@ -1409,8 +1565,6 @@ void hdmi_init(void) hdmi_info.freq = 48000; hdmi_info.option = EDID_OPT_AUDIO + EDID_OPT_HDMI; - hdmi_enable_plugin(0); - if (g_vpp.govrh_preinit) { DBGMSG("[HDMI] hdmi_init for uboot logo\n"); } else { @@ -1427,31 +1581,34 @@ void hdmi_init(void) /* Wake3 disable pull ctrl */ vppif_reg32_write(GPIO_BASE_ADDR+0x480, BIT19, 19, 0); #endif - hdmi_regs2->level.b.level = 1; - hdmi_regs2->level.b.update = 1; - hdmi_regs2->igs.b.ldi_shift_left = 1; - hdmi_regs2->status.val = 0x0008c000; - hdmi_regs2->test.val = 0x00450409; - hdmi_regs2->test2.val = 0x00005022; - hdmi_regs2->test3 = (g_vpp.hdmi_sp_mode) ? - 0x00010100 : 0x00000100; + vppif_reg32_write(HDMI_REG_LEVEL, 1); + vppif_reg32_write(HDMI_REG_UPDATE, 1); + vppif_reg32_write(HDMI_LDI_SHIFT_LEFT, 1); + vppif_reg32_out(REG_HDMI_STATUS, 0x0008c000); + vppif_reg32_out(REG_HDMI_TEST, 0x00450409); + vppif_reg32_out(REG_HDMI_TEST2, 0x00005022); + vppif_reg32_out(REG_HDMI_TEST3, + (g_vpp.hdmi_sp_mode) ? 0x00010100 : 0x00000100); hdmi_set_enable(VPP_FLAG_DISABLE); hdmi_set_dvi_enable(VPP_FLAG_DISABLE); - hdmi_regs1->ctrl.b.cipher_1_1 = 0; + vppif_reg32_write(HDMI_CIPHER_1_1, 0); - hdmi_regs1->tmds_ctrl.b.infoframe_sram_enable = 1; - hdmi_regs1->infoframe_ctrl.b.select = 0; - hdmi_regs1->infoframe_ctrl.b.fifo1_rdy = 0; + vppif_reg32_write(HDMI_INFOFRAME_SRAM_ENABLE, 1); + vppif_reg32_write(HDMI_INFOFRAME_SELECT, 0); + vppif_reg32_write(HDMI_INFOFRAME_FIFO1_RDY, 0); - hdmi_regs1->hotplug_detect.val = 0x0; - hdmi_regs1->channel_test.val = 0x1; + vppif_reg32_out(HDMI_BASE_ADDR+0x3ec, 0x0); + vppif_reg32_out(HDMI_BASE_ADDR+0x3e8, 0x1); + /* vppif_reg32_write(HDMI_AUD_LAYOUT, 1); */ hdmi_DDC_reset(); hdmi_DDC_set_freq(g_vpp.hdmi_i2c_freq); - hdmi_regs1->ctrl.b.i2c_enable = 1; + vppif_reg32_write(HDMI_I2C_ENABLE, 1); } g_vpp.hdmi_init = 1; if (hdmi_cp) hdmi_cp->init(); + + acr_init(); } #endif /* WMT_FTBLK_HDMI */ |