#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" #include "hdmi.h" #include "sysreg.h" #include "hdmi_time.h" #include "../../module_include/drv_gpio.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; 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); 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(10); 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"); VIP_SendInformation(&stKic); /* 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 HDMI_TurnOff_SW_5V_schedule(2000, hdmi_get_cur_port()); //restart HW DDC 5V detection after signal is stable #endif 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; if (HDMI_RegisterRead(HDMIRX_R_HDMI_en)) //HDMI mode { bNotSupport = ((HDMI_RegisterRead(HDMIRX_ref_freq_cnt) * 26672410/1000000) > 0xa00); //246.7MHz } else //DVI mode { bNotSupport = ((HDMI_RegisterRead(HDMIRX_ref_freq_cnt) * 26672410/1000000) > 0x6b0); //165MHz } #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)) { if(WQ_NOSIGNAL_CNT<3) { 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_SetPLL_ByFreq(); 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)) { 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); } #endif hdmi_signal_lock_check_start(); WQ_NOSIGNAL_CNT++; } else if(WQ_NOSIGNAL_CNT<10) { 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_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)) { 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); } #endif hdmi_signal_lock_check_start(); WQ_NOSIGNAL_CNT++; } else { /* mantis 27479, chroma 2402 unsupport timing issue*/ #ifdef HDMI_DDC5V_WORKAROUND 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"); } } #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)) { 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); } #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)) { 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 { WQ_NOSIGNAL_CNT =0; VBUS_TOGGLE_CNT =0; if (hdmi_get_hpd_at_cur_src() && bNotSupport) { //HDMI_NoticeHandler(HDMINOTICE_NOTSUPPORT, "NOSIGNAL_TIMER"); HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); } else { HDMI_NoticeHandler(HDMINOTICE_NOSIGNAL, "NOSIGNAL_TIMER"); } } } } static void WQ_AVI_CHANGE(void *dummy) { if(HDMI_IsAviChanged(&stKic) == true) { HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 1); VIP_MuteScreen(); VIP_SendInformation(&stKic); /* 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; } HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 0); } } static void WQ_TURN_OFF_SW5V(UINT32 data) { if((HDMI_PORT_T)data != DRV_Get_GPIO5V_ARCPort()) //do not turn off SW 5V at ARC GPIO 5V port,workaround for SONY BDP-S360 { sysset_HDMI_SW5V((HDMI_PORT_T)data, FALSE); } } //========================================== // Timer //========================================== /* no signal */ static void NOSIGNAL_TIMER(void *dummy) { if (hdmi_flag_check(HAS_ACTIVE_DATA) == FALSE) { schedule_work(&wq_nosignal); } } static void nosignal_timer_schedule(UINT32 delay_ms) { hdmidbg("%s: check signal after %d ms\n", __FUNCTION__, delay_ms); del_timer(&nosignal_timer); nosignal_timer.expires = jiffies + ((HZ / 1000) * delay_ms) + HZ / 1000; nosignal_timer.data = (UINT32)NULL; nosignal_timer.function = (void (*)(ULONG))NOSIGNAL_TIMER; add_timer(&nosignal_timer); } static void nosignal_timer_remove(void) { del_timer(&nosignal_timer); } void hdmi_signal_check_start(void) { UINT32 delay_ms; UINT8 fInRange = HDMI_RegisterRead(HDMIRX_IN_RANGE); if(fInRange==0) { delay_ms = HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; } else { /* Wait for Long Time if 5V is high, otherwise wait for Short Time */ #ifdef HDMI_DDC5V_WORKAROUND #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if((MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { delay_ms = HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; } else { delay_ms = (CEC_Get_SW5V(hdmi_get_cur_port()) == DRV_5V_LEVEL_HIGH) ? HDMI_INFORM_NOSIGNAL_DELAY_WITH_5V : HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; } #endif #else delay_ms = (CEC_Get_SW5V(hdmi_get_cur_port()) == DRV_5V_LEVEL_HIGH) ? HDMI_INFORM_NOSIGNAL_DELAY_WITH_5V : HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; #endif #else #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if((MHL_CABLE_IN == TRUE)&&(DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { delay_ms = HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; } else { delay_ms = hdmi_get_hpd_at_cur_src() ? HDMI_INFORM_NOSIGNAL_DELAY_WITH_5V : HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; } #endif #else delay_ms = hdmi_get_hpd_at_cur_src() ? HDMI_INFORM_NOSIGNAL_DELAY_WITH_5V : HDMI_INFORM_NOSIGNAL_DELAY_NO_5V; #endif #endif } hdmidbg("%s: check signal after %d ms\n", __FUNCTION__, delay_ms); nosignal_timer_schedule(delay_ms); } void hdmi_signal_lock_check_start(void) { nosignal_timer_schedule(1000); } void hdmi_signal_check_stop(void) { hdmidbg("%s: removed\n", __FUNCTION__); nosignal_timer_remove(); } /* active */ #ifdef CONFIG_QSD #define ACTIVE_DEBOUNCE_DELAY (1) //unit:10ms #else #define ACTIVE_DEBOUNCE_DELAY (20) //unit:10ms #endif #define ACTIVE_DEBOUNCE_TIMES (10) #define MAX_HDCP_WAIT_TIMES (20) UINT32 MAX_BCH_ERROR_CNT = 0x20; #define ACTIVE_SIGNAL_MONITOR_DELAY (20) //unit:10ms static void ACTIVE_TIMER(void* dummy) { BOOL bWait = false; #ifdef CONFIG_QSD //for module test, reduce debounce time if(HDMI_GetInputInformation(&stKic) == 1) { if((stKic.bDviEnable == 0) && (stKic.uiHactive > 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!!! \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(); 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 && active_run < MAX_HDCP_WAIT_TIMES) { bWait = true; } if (active_run < ACTIVE_DEBOUNCE_TIMES) { bWait = true; } if(hdmi_flag_check(WAIT_HDCP) == true ) { if (active_run >= MAX_HDCP_WAIT_TIMES) { bWait = false; } } else { if (active_run >= ACTIVE_DEBOUNCE_TIMES) { bWait = false; } } 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); 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; } extern void HDMI_Toggle_HPD(void); static void SIGNAL_MONITOR_TIMER(void* dummy) { VIP_InterfaceKIC CurKic; bool fResolution_change = false; UINT32 Vactive_o, Vactive_e; if (active_run <= ACTIVE_DEBOUNCE_TIMES*2) { active_run++; } else { if(HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)>0x1000) { printk("%s bch_cnt:0x%x\n", __FUNCTION__,HDMI_RegisterRead(HDMIRX_R_bch_ep_cnt)); HDMI_Toggle_HPD(); } } /* 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); 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; } #endif 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; } if(fResolution_change == true) { printk("Mode Change!!!!!! \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_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); } 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.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); } //========================================== // 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); }