#include "drv_types.h" #include #include "hdmi_dbg.h" #include "hdmi_cfg.h" #include "hdmi_hw.h" #include "hdmi_notice.h" #include "hdmi_processing.h" #include "hdmi_video.h" #include "hdmi_hpd.h" #include "cec.h" #include "drv_hdmi_internal.h" #ifdef CONFIG_SUPPORT_MONITOR_POWERSAVE #include "drv_kmf_interface.h" #include "tv_base.h" #endif #include "hdmi.h" #include "sysreg.h" #include "hdmi_time.h" #include "../../module_include/drv_gpio.h" #include "../vip/6710/reg_vip_def.h" #include "../vip/6710/drv_reg_access.h" #ifdef CONFIG_HDMI_SUPPORT_MHL #include "cbus_drv.h" #include "cbus_mid.h" #endif static UINT32 local_signal_status; static BOOL bHdmiMode = false; static VIP_InterfaceKIC stKic; static INT32 active_run = 0; static struct timer_list active_timer; static struct timer_list nosignal_timer; static struct timer_list turn_off_sw_5V_timer; static struct timer_list signal_monitor_timer; static struct work_struct wq_active; static struct work_struct wq_nosignal; static struct work_struct wq_avi_change; static struct work_struct wq_turn_off_sw_5V; extern GPIOPin_t geGpio5V_Pin; extern UINT8 gbSupportMaxHz; extern BOOL OpenScreen_Flag; extern BOOL MHL_CABLE_IN; #ifdef CONFIG_SUPPORT_MONITOR_POWERSAVE extern UINT8 WEAKUP_EVENT; #endif static void WQ_ACTIVE(void *dummy); static UINT8 WQ_NOSIGNAL_CNT=0; static UINT8 VBUS_TOGGLE_CNT=0; static void WQ_NOSIGNAL(void *dummy); static void WQ_AVI_CHANGE(void *dummy); static void NOSIGNAL_TIMER(void *dummy); static void nosignal_timer_schedule(UINT32 delay_ms); static void nosignal_timer_remove(void); static void ACTIVE_TIMER(void* dummy); extern void HDMI_Toggle_HPD(void); #ifdef CONFIG_SUPPORT_MONITOR_POWERSAVE extern BOOL vip_SourceSelect(input_type_t inputType); #endif BOOL DRV_HDMI_IsHDMIMode(void) { return bHdmiMode; } void hdmi_flag_set(SIGNAL_T s) { local_signal_status |= (1 << s); } void hdmi_flag_clear(SIGNAL_T s) { local_signal_status = local_signal_status & (~(1 << s)); } BOOL hdmi_flag_check(SIGNAL_T s) { return (local_signal_status & (1 << s)) == 0?FALSE:TRUE; } void hdmi_flag_reset(void) { local_signal_status = 0; } //========================================== // Work Queue Function //========================================== static void WQ_ACTIVE(void *dummy) { UINT8 bSignalStatus; WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT=0; HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 0); bSignalStatus = HDMI_GetInputInformation(&stKic); signal_monitor_timer_schedule(50); switch (bSignalStatus) { default: case 0: /* Not Support */ HDMI_NoticeHandler(HDMINOTICE_NOTSUPPORT, "WQ_ACTIVE"); break; case 1: /* Support */ #ifdef SUPPORT_XVYCC if(HDMI_RegisterRead(HDMIRX_R_GBD_exist) == 1) //if Gamut Boundary Description exist, handle xvycc { hdmi_handler_xvycc(); } #endif HDMI_NoticeHandler(HDMINOTICE_HAVESIGNAL, "WQ_ACTIVE"); #ifdef CONFIG_SUPPORT_MONITOR_POWERSAVE if(WEAKUP_EVENT&INPUT_TYPE_HDMI) { drv_gated_clk_ctrl(GATED_ICLK_VIP, 0); *((volatile u8*)(0xbe00010c )) = 0x5; clear_bit(26, (volatile void __iomem *) 0xbe0001ac); // [26]R_LVDSPLL_PWDN clear_bit(15, (volatile void __iomem *) 0xbe00000c); // [15]R_AUDIO_RST vip_init_forwakeup(); vip_SourceSelect(INPUT_TYPE_HDMI); } #endif VIP_SendInformation(&stKic); HDMI_RegisterWrite(HDMIRX_R_force_blk_screen, 0); /* Indicate flow control that hdmi/dvi mode */ if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) == 1) { HDMI_NoticeAudioMode(HDMI_MODE); bHdmiMode = true; } else { HDMI_NoticeAudioMode(DVI_MODE); bHdmiMode = false; } #ifdef HDMI_DDC5V_WORKAROUND if(!((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet() == CONFIG_HDMI_MHL_PORT))) { #ifdef CONFIG_HDMI_GPIO_DETECT if( #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A (hdmi_get_cur_port() != HDMI_PORT_A) && #endif #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B (hdmi_get_cur_port() != HDMI_PORT_B) && #endif #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C (hdmi_get_cur_port() != HDMI_PORT_C) && #endif (TRUE)) #endif HDMI_TurnOff_SW_5V_schedule(2000, hdmi_get_cur_port()); //restart HW DDC 5V detection after signal is stable } #endif OpenScreen_Flag = TRUE; break; case 2: /* No Signal */ HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "WQ_ACTIVE"); break; } } extern BOOL MHL_CABLE_IN; static void WQ_NOSIGNAL(void *dummy) { BOOL bNotSupport; UINT32 pixel_clk_freq,uiHactive; pixel_clk_freq = get_pixel_clock(); uiHactive = HDMI_RegisterRead(HDMIRX_de_h_width_lock) / (HDMI_RegisterRead(HDMIRX_R_AVI_PR) + 1); if((pixel_clk_freq >= 165000000) && (uiHactive < 2560)) { bNotSupport = TRUE; // Not Support } #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if((HDMI_RegisterRead(HDMIRX_IN_RANGE)==0)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { if(( MHL_ADOPTER_ID_Check()== FALSE)&&(VBUS_TOGGLE_CNT==0)&&(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)) { #if 0 printk("MHL TOGGLE Vbus1!!!!!! \n"); sysset_VbusEnable(0); HDMI_DelayMs(100); sysset_VbusEnable(1); VBUS_TOGGLE_CNT ++; #endif } } #endif #endif #if 1 if(HDMI_RegisterRead(HDMIRX_PHYPLLLOCK)) { hdmidbg("p timeout = %d, rd_cnt = %d WQ_NOSIGNAL_CNT = %d\n",sysget_DDC_non_idle_timeout(hdmi_get_cur_port()),sysget_DDC_rd_block_cnt(hdmi_get_cur_port()), WQ_NOSIGNAL_CNT); if(WQ_NOSIGNAL_CNT<2) { printk("HDMIRX_PHYPLLLOCK!!!!!! \n"); //HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); //HDMI_DelayMs(2); /* Power On PHY */ //HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_SetPLL_ByFreq(); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); #ifdef CONFIG_HDMI_MHL_PORT if((MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { if(CbusMidGetWhiteListToResetCubs()) { printk("MHL reset cbus!!!!!! \n"); //reset cbus HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 1); HDMI_DelayMs(150); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 0); } else { printk("ignore MHL reset cbus!!!!!! \n"); } } #endif hdmi_signal_lock_check_start(); WQ_NOSIGNAL_CNT++; } else if(WQ_NOSIGNAL_CNT<4) { printk("HDMIRX_PHYPLLLOCK!!!!!! \n"); printk("Reset PLL!!!!!! \n"); //Reset PLL HDMI_Reset_HDMI_PLL(); //HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); //HDMI_DelayMs(2); /* Power On PHY */ //HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); #ifdef CONFIG_HDMI_MHL_PORT if((MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { if(CbusMidGetWhiteListToResetCubs()) { printk("MHL reset cbus!!!!!! \n"); //reset cbus HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 1); HDMI_DelayMs(150); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 0); } else { printk("ignore MHL reset cbus!!!!!! \n"); } } #endif hdmi_signal_lock_check_start(); WQ_NOSIGNAL_CNT++; } /* else if(WQ_NOSIGNAL_CNT<5) { HDMI_Toggle_HPD(); WQ_NOSIGNAL_CNT++; } */ else { /* mantis 27479, chroma 2402 unsupport timing issue*/ #ifdef HDMI_DDC5V_WORKAROUND #ifdef CONFIG_HDMI_GPIO_DETECT if( #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A (hdmi_get_cur_port() != HDMI_PORT_A) && #endif #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B (hdmi_get_cur_port() != HDMI_PORT_B) && #endif #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C (hdmi_get_cur_port() != HDMI_PORT_C) && #endif (TRUE)) #endif HDMI_TurnOff_SW_5V_schedule(0, hdmi_get_cur_port()); //restart HW DDC 5V detection after signal is stable #endif WQ_NOSIGNAL_CNT =0; //HDMI_NoticeHandler(HDMINOTICE_NOTSUPPORT, "NOSIGNAL_TIMER"); HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); HDMI_Toggle_HPD(); } } #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT else if((CbusMidGetDevCapReadyBit()==FALSE)&&(MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { if(WQ_NOSIGNAL_CNT<26) { if((WQ_NOSIGNAL_CNT==5)||(WQ_NOSIGNAL_CNT==10)||(WQ_NOSIGNAL_CNT==15)||(WQ_NOSIGNAL_CNT==20)||(WQ_NOSIGNAL_CNT==25)) { HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); if(CbusMidGetWhiteListToResetCubs()) { printk("MHL reset cbus!!!!!! \n"); //reset cbus HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 1); HDMI_DelayMs(150); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 0); } else { printk("ignore MHL reset cbus!!!!!! \n"); } } #if 0 if(( MHL_ADOPTER_ID_Check()== FALSE)&&((WQ_NOSIGNAL_CNT==10)||(WQ_NOSIGNAL_CNT==20))&&(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)) { printk("MHL TOGGLE Vbus2!!!!!! \n"); sysset_VbusEnable(0); HDMI_DelayMs(100); sysset_VbusEnable(1); VBUS_TOGGLE_CNT ++; } #endif hdmi_signal_check_start(); WQ_NOSIGNAL_CNT++; } else { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; #if 0 if((HDMI_RegisterRead(HDMIRX_IN_RANGE)==0)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { if(( MHL_ADOPTER_ID_Check()== FALSE)&&(VBUS_TOGGLE_CNT==0)&&(GPIOGetValueByPinFunc(GPIO_PIN_MHL_CD_SENSE_DETECT)==1)) { printk("MHL TOGGLE Vbus3!!!!!! \n"); sysset_VbusEnable(0); HDMI_DelayMs(100); sysset_VbusEnable(1); } } #endif HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); } } #endif #endif else #endif { if(HDMI_RegisterRead(HDMIRX_IN_RANGE)) { hdmidbg("i timeout = %d, rd_cnt = %d WQ_NOSIGNAL_CNT = %d\n",sysget_DDC_non_idle_timeout(hdmi_get_cur_port()),sysget_DDC_rd_block_cnt(hdmi_get_cur_port()), WQ_NOSIGNAL_CNT); if(WQ_NOSIGNAL_CNT<3) { HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 0);//For No siglal issue HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 1); hdmi_signal_lock_check_start(); WQ_NOSIGNAL_CNT++; } else { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; //HDMI_NoticeHandler(HDMINOTICE_NOTSUPPORT, "NOSIGNAL_TIMER"); HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); } } else { #ifdef CONFIG_HDMI_DELAY_START_5V_DETECTION if(CEC_Get_SW5V(hdmi_get_cur_port()) == DRV_5V_LEVEL_HIGH) { if(NormalScreen == HDMI_GetNoticedScreenMode()) { //power off hdmidbg("1 timeout = %d, rd_cnt = %d WQ_NOSIGNAL_CNT = %d\n",sysget_DDC_non_idle_timeout(hdmi_get_cur_port()),sysget_DDC_rd_block_cnt(hdmi_get_cur_port()), WQ_NOSIGNAL_CNT); if(1)//if(sysget_DDC_non_idle_timeout(hdmi_get_cur_port()) == 0) { if((WQ_NOSIGNAL_CNT<2)) { WQ_NOSIGNAL_CNT++; hdmi_signal_lock_check_start(); } else { //power off WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER_D5V01"); } } else { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER_D5V03"); } } else { //gtx 730 750 power on, //dvd play plug-in cable in standby mode(5v is exsit not read edid) hdmidbg("2 timeout = %d, rd_cnt = %d WQ_NOSIGNAL_CNT = %d\n",sysget_DDC_non_idle_timeout(hdmi_get_cur_port()),sysget_DDC_rd_block_cnt(hdmi_get_cur_port()), WQ_NOSIGNAL_CNT); if((WQ_NOSIGNAL_CNT<2)) { WQ_NOSIGNAL_CNT++; hdmi_signal_lock_check_start(); } else { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER_D5V02"); } } } else #endif { hdmidbg("3 timeout = %d, rd_cnt = %d\n",sysget_DDC_non_idle_timeout(hdmi_get_cur_port()),sysget_DDC_rd_block_cnt(hdmi_get_cur_port())); if((MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { #if 0 if((WQ_NOSIGNAL_CNT<5)) { WQ_NOSIGNAL_CNT++; hdmi_signal_lock_check_start(); } else { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); } #else WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); #endif } else { if((WQ_NOSIGNAL_CNT 600) && (stKic.uiVactive > 200) &&(stKic.uiVfreq > 20)) { hdmidbg("%s: Status verified after %d run\n", __FUNCTION__, active_run); hdmidbg("\t%s Mode\n", HDMI_RegisterRead(HDMIRX_R_HDMI_en) ? "HDMI" : "DVI"); hdmidbg("\t%s AVI InfoFrame\n", hdmi_flag_check(HAS_AVIINFO_PKT) ? "Have" : "No"); hdmidbg("\t%s HDCP HandShake\n", hdmi_flag_check(HAS_HDCP) ? "Have" : "No"); /* Remove nosignal timer */ hdmi_signal_check_stop(); /* Set flag */ hdmi_flag_set(HAS_ACTIVE_DATA); schedule_work(&wq_active); signal_monitor_timer_schedule(ACTIVE_SIGNAL_MONITOR_DELAY); /* Enable audio sample coming isrs */ HDMI_Interrupt_Enable(INTR_audio_sample_coming | INTR_HBR_audio_sample_coming); return; } } hdmidbg("%s MT_code active round:%d\n", __FUNCTION__, active_run); active_run++; active_timer_schedule(ACTIVE_DEBOUNCE_DELAY); return; #endif if (active_run == 0) { //HDMI_NoticeHandler(HDMINOTICE_PROCESSING_IN, "ACTIVE_TIMER"); } hdmidbg("%s[%d] bch_cnt:0x%x\n", __FUNCTION__, active_run, HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)); if(HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)>MAX_BCH_ERROR_CNT) { HDMI_RegisterWrite(HDMIRX_Clr_bch_epcnt, 1); if (active_run >= 3) { printk("[H] BCH error, Reset HDMI and toggle HPD!!! \n"); //Reset PLL //HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); //HDMI_DelayMs(2); //HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); /* Check signal status */ //hdmi_signal_check_start(); HDMI_Toggle_HPD(); active_run = 0; return; } } #ifdef USE_HW_ADAPTIVE_EQ #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN != TRUE)||( DrvHDMIPortSelectBitsGet() != CONFIG_HDMI_MHL_PORT)) #endif { if (active_run == 0) { printk("(HDMIRX_unstable_align_cnt) Clear \n"); HDMI_RegisterWrite(HDMIRX_unstable_align_cnt, 1);//Write 1 clear } #if 0 if(HDMI_RegisterRead(HDMIRX_unstable_align_cnt)>0x20) { printk("(HDMIRX_unstable_align_cnt)=%d\n",HDMI_RegisterRead(HDMIRX_unstable_align_cnt)); printk("(HDMIRX_unstable_align_cnt)>0x0 Reset PLL!!!!!! \n"); //Reset PLL HDMI_Reset_HDMI_PLL(); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_DelayMs(2); /* Power On PHY */ HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); /* Check signal status */ //hdmi_signal_check_start(); active_run = 0; return; } #else printk("(HDMIRX_unstable_align_cnt)=%d\n",HDMI_RegisterRead(HDMIRX_unstable_align_cnt)); #endif } #endif if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) && hdmi_flag_check(HAS_HDCP) == false && hdmi_flag_check(HAS_AVIINFO_PKT) == false && active_run < MAX_HDCP_WAIT_TIMES) { bWait = true; } if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) && hdmi_flag_check(HAS_AVIINFO_PKT) == false && active_run < MAX_AVI_INFO_WAIT_TIMES) { bWait = true; } #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet() == CONFIG_HDMI_MHL_PORT)) { if(hdmi_flag_check(HAS_AVIINFO_PKT) == false && hdmi_get_cur_port() == CONFIG_HDMI_MHL_PORT) bWait = true; if (hdmi_flag_check(HAS_HDCP_REQUEST_EARLY_THEN_PLL_LOCK) == true && hdmi_flag_check(HAS_HDCP) == false && active_run < MAX_HDCP_WAIT_TIMES) { bWait = true; } if (hdmi_flag_check(HAS_HDCP) == false && active_run < MAX_HDCP_WAIT_TIMES) { bWait = true; } } #endif if ((hdmi_flag_check(HAS_AVIINFO_PKT) == true) && (0x00 == (HDMI_RegisterRead(HDMIRX_0134_DW_0134))) && (active_run < MAX_AVI_INFO_WAIT_TIMES)) { bWait = true; } if (active_run < ACTIVE_DEBOUNCE_TIMES) { bWait = true; } if (bWait) { active_run++; active_timer_schedule(ACTIVE_DEBOUNCE_DELAY); return; } //HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 4); hdmidbg("%s: Status verified after %d run\n", __FUNCTION__, active_run); hdmidbg("\t%s Mode\n", HDMI_RegisterRead(HDMIRX_R_HDMI_en) ? "HDMI" : "DVI"); hdmidbg("\t%s AVI InfoFrame\n", hdmi_flag_check(HAS_AVIINFO_PKT) ? "Have" : "No"); hdmidbg("\t%s HDCP HandShake\n", hdmi_flag_check(HAS_HDCP) ? "Have" : "No"); /* Remove nosignal timer */ hdmi_signal_check_stop(); /* Set flag */ hdmi_flag_set(HAS_ACTIVE_DATA); if(false == Hdmi_Check_H_V_Ready()) { hdmidbg("Top field active lines and H active width are not ready!!\n"); } schedule_work(&wq_active); // signal_monitor_timer_schedule(ACTIVE_SIGNAL_MONITOR_DELAY); /* Enable audio sample coming isrs */ HDMI_Interrupt_Enable(INTR_audio_sample_coming | INTR_HBR_audio_sample_coming); } void active_timer_schedule(UINT32 ten_ms) { hdmidbg("Active Run #%d, wait for %d ms\n", active_run, ten_ms * 10); del_timer(&active_timer); active_timer.expires = jiffies + ((HZ / 100) * ten_ms) + HZ / 100; active_timer.data = (UINT32)NULL; active_timer.function = (void (*)(ULONG))ACTIVE_TIMER; add_timer(&active_timer); } void active_timer_remove(void) { del_timer(&active_timer); active_run = 0; } static void SIGNAL_MONITOR_TIMER(void* dummy) { VIP_InterfaceKIC CurKic; bool fResolution_change = false; UINT32 Vactive_o, Vactive_e; UINT32 BCH_ERR_CNT_THRE; UINT8 Vfreq_Tolerance; /* Horizontal */ CurKic.uiHactive = HDMI_RegisterRead(HDMIRX_de_h_width_lock) / (HDMI_RegisterRead(HDMIRX_R_AVI_PR) + 1); if (active_run <= ACTIVE_DEBOUNCE_TIMES*2) { active_run++; } else { if(CurKic.uiHactive >= 2560) { BCH_ERR_CNT_THRE = 0x4000; } else { BCH_ERR_CNT_THRE = 0x1000; } if(HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)>BCH_ERR_CNT_THRE) { printk("%s bch_cnt:0x%x\n", __FUNCTION__,HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)); HDMI_Toggle_HPD(); return; } } /* Interlace */ CurKic.bInterlace = HDMI_RegisterRead(HDMIRX_R_Interlace); /* Vertical */ Vactive_o = HDMI_RegisterRead(HDMIRX_top_de_v_width_lock); Vactive_e = HDMI_RegisterRead(HDMIRX_btn_de_v_width_lock); /* Vfreq */ CurKic.uiVfreq = (6000 / (VIP_RegisterRead(VIP_sta_hdmi_frmcnt)+1)); if(((INT32)(HDMI_RegisterRead(HDMIRX_R_TOP_VDEE) - HDMI_RegisterRead(HDMIRX_R_TOP_VDES))) < 0) { Vactive_o = Vactive_o + 1; } if(((INT32)(HDMI_RegisterRead(HDMIRX_R_BTM_VDEE) - HDMI_RegisterRead(HDMIRX_R_BTM_VDES))) < 0) { Vactive_e = Vactive_e + 1; } if (Vactive_o != 0) { CurKic.uiVactive = Vactive_o; CurKic.uiVtotal = HDMI_RegisterRead(HDMIRX_R_TOP_VT); CurKic.uiVstart = HDMI_RegisterRead(HDMIRX_R_TOP_VDES); } else { CurKic.uiVactive = Vactive_e; CurKic.uiVtotal = HDMI_RegisterRead(HDMIRX_R_BTM_VT); CurKic.uiVstart = HDMI_RegisterRead(HDMIRX_R_BTM_VDES); } if(CurKic.bInterlace == 1) { if(Vactive_o == (Vactive_e + 1)) CurKic.uiVactive = Vactive_e; else CurKic.uiVactive = Vactive_o; } CurKic.uiVend = CurKic.uiVstart + CurKic.uiVactive ; /* Horizontal */ //CurKic.uiHactive = HDMI_RegisterRead(HDMIRX_de_h_width_lock) / (HDMI_RegisterRead(HDMIRX_R_AVI_PR) + 1); /* Patch: hactive should be a even number in DVI mode */ if (HDMI_RegisterRead(HDMIRX_R_HDMI_en) == 0) { CurKic.uiHactive &= 0xfffffffe; } CurKic.uiHtotal = HDMI_RegisterRead(HDMIRX_R_HT) + 1; CurKic.uiHstart = HDMI_RegisterRead(HDMIRX_R_HDES) + 1; CurKic.uiHend = CurKic.uiHstart + CurKic.uiHactive; #ifdef CONFIG_SUPPORT_4K_2K_30 if (CurKic.uiHactive == 3840) { //hdmidbg("......4K x 2K.....\n"); CurKic.uiHactive = (CurKic.uiHactive)/2; CurKic.uiHtotal = (CurKic.uiHtotal)/2; CurKic.uiHstart = (CurKic.uiHstart)/2 ; CurKic.uiHend = (CurKic.uiHend)/2; } if (CurKic.uiHactive >= 2560) { CurKic.uiHactive = (CurKic.uiHactive)/2; CurKic.uiHtotal = (CurKic.uiHtotal)/2; CurKic.uiHstart = (CurKic.uiHstart)/2 ; CurKic.uiHend = (CurKic.uiHend)/2; } #endif if(abs(stKic.uiVfreq* HDMI_VFREQ_TOLERANCE_PERMILE / 100) < 1) { Vfreq_Tolerance = 1; } else { Vfreq_Tolerance = abs(stKic.uiVfreq* HDMI_VFREQ_TOLERANCE_PERMILE / 100); } if(abs(CurKic.uiHactive - stKic.uiHactive ) > abs(stKic.uiHactive * HDMI_HVAILD_TOLERANCE_PERMILE / 1000)) { printk("#UNSTBL_H:HVld=%d(%d)\n", CurKic.uiHactive, stKic.uiHactive); fResolution_change = true; } else if (abs(CurKic.uiVactive - stKic.uiVactive ) > abs(stKic.uiVactive * HDMI_VVAILD_TOLERANCE_PERMILE / 1000)) { printk("#UNSTBL_H:VVld=%d(%d)\n", CurKic.uiVactive, stKic.uiVactive); fResolution_change = true; } else if (abs(CurKic.uiHtotal - stKic.uiHtotal ) > abs(stKic.uiHtotal * HDMI_HTOTAL_TOLERANCE_PERMILE / 1000)) { printk("#UNSTBL:HTotal=%d\n", CurKic.uiHtotal); fResolution_change = true; } else if (abs(CurKic.uiVtotal - stKic.uiVtotal) > abs(stKic.uiVtotal* HDMI_VTOTAL_TOLERANCE_PERMILE / 1000)) { printk("#UNSTBL:VTotal=%d\n", CurKic.uiVtotal); fResolution_change = true; } else if (abs (CurKic.uiVfreq - stKic.uiVfreq) > Vfreq_Tolerance) { printk("#UNSTBL:Vfreq=%d\n", CurKic.uiVfreq); fResolution_change = true; } if(fResolution_change == true) { printk("Mode Change!!!!!! \n"); VIP_MuteScreenDirectly(); // VIP_MuteScreen_ISR(); might be pending until the next V sync ISR HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_DelayMs(2); /* Power On PHY */ HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); } else { signal_monitor_timer_schedule(ACTIVE_SIGNAL_MONITOR_DELAY); } HDMI_RegisterWrite(HDMIRX_Clr_bch_epcnt, 1); } UINT8 Hdmi_Check_H_V_Ready(void) { UINT8 i,Status; Status = false; for(i=0;i<40;i++) { if((0 == HDMI_RegisterRead(HDMIRX_top_de_v_ready)) || (0 == HDMI_RegisterRead(HDMIRX_de_h_ready)) || (0 == HDMI_RegisterRead(HDMIRX_R_TOP_VDEE_ready))) { HDMI_DelayMs(25); } else { Status = TRUE; break; } } return Status; } void signal_monitor_timer_schedule(UINT32 ten_ms) { //hdmidbg("bch_check, wait for %d ms\n",ten_ms * 10); del_timer(&signal_monitor_timer); //signal_monitor_timer.expires = jiffies + ((HZ / 100) * ten_ms) + HZ / 100; signal_monitor_timer.expires = jiffies + ((HZ / 100) * ten_ms); signal_monitor_timer.data = (UINT32)NULL; signal_monitor_timer.function = (void (*)(ULONG))SIGNAL_MONITOR_TIMER; add_timer(&signal_monitor_timer); } void signal_monitor_timer_remove(void) { del_timer(&signal_monitor_timer); } /* avi */ void avi_change_schedule(void) { schedule_work(&wq_avi_change); } /* turn off software 5V */ void HDMI_TurnOff_SW_5V_schedule(UINT32 delay_ms, HDMI_PORT_T ePort) { hdmidbg("%s: Turn off Software 5V after %d ms\n", __FUNCTION__, delay_ms); del_timer(&turn_off_sw_5V_timer); turn_off_sw_5V_timer.expires = jiffies + ((HZ / 1000) * delay_ms) + HZ / 1000; turn_off_sw_5V_timer.data = (UINT32)ePort; turn_off_sw_5V_timer.function = (void (*)(ULONG))WQ_TURN_OFF_SW5V; add_timer(&turn_off_sw_5V_timer); } void HDMI_TurnOff_SW_5V_schedule_cancel(HDMI_PORT_T ePort) { //hdmidbg("%s: Turn off Software 5V cancel\n", __FUNCTION__); del_timer(&turn_off_sw_5V_timer); } //========================================== // Initial //========================================== void hdmi_processing_init(void) { init_timer(&nosignal_timer); init_timer(&active_timer); init_timer(&signal_monitor_timer); init_timer(&turn_off_sw_5V_timer); INIT_WORK(&wq_active, (work_func_t) WQ_ACTIVE); INIT_WORK(&wq_nosignal, (work_func_t) WQ_NOSIGNAL); INIT_WORK(&wq_avi_change, (work_func_t) WQ_AVI_CHANGE); INIT_WORK(&wq_turn_off_sw_5V, (work_func_t) WQ_TURN_OFF_SW5V); }