#include "drv_types.h" #include "hdmi.h" #include "hdmi_hw.h" #include "hdmi_hdcp.h" #include "hdmi_notice.h" #include "hdmi_audio.h" #include "hdmi_video.h" #include "hdmi_mapping.h" #include "hdmi_hpd.h" #include "hdmi_processing.h" #include "hdmi_switch.h" #include "hdmi_time.h" #include "hdmi_dbg.h" #include "hdmi_cfg.h" #include "cec.h" #include "gpioi2c.h" #include "sysreg.h" #ifdef CONFIG_HDMI_SUPPORT_MHL #include "cbus_drv.h" #include "cbus_app.h" #include "mhl_application.h" static BOOL MHL_CBUS_Init=FALSE; #endif BOOL MHL_CABLE_IN=FALSE; BOOL MHL_CTS=FALSE; static BOOL HDMI_Init=FALSE; static struct work_struct wq_chlock; #ifdef CONFIG_HDMI_HW_PATCH_FOR_HDCP_COLOR_SNOW static struct work_struct wq_ToggleHPD; #endif #ifdef USE_HW_ADAPTIVE_EQ static struct delayed_work wq_Enable_DCK; #endif #define writel(data, address) (*(volatile unsigned long*)(address) = data) #define writeb(data, address) (*(volatile unsigned char*)(address) = data) #define readl(address) (*(volatile unsigned long*)(address)) #define readb(address) (*(volatile unsigned char*)(address)) void HDMI_Toggle_HPD(void) { printk("HDMI_Toggle_HPD\n"); /* All hpd goes low */ /* Disable hdmi hw and all interrupts */ HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 0); //stop phy clock HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); /* Disable hdmi logic */ HDMI_Interrupt_Disable(INTR_ALL); /* Disable all interrupts */ HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_ALL); /* Clear all interrupts if any */ #ifdef HDMI_DDC5V_WORKAROUND if(CEC_Get_SW5V(hdmi_get_cur_port()) == DRV_5V_LEVEL_HIGH) //do not change HPD status after cable out #endif hdmi_apply_hpd((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_LOW); /* Wait 100ms for hot plug pulse width */ HDMI_DelayMs(100); /* Enable related interrupts */ //HDMI_Interrupt_Enable(INTR_HDCP_Key_Request | INTR_AVI_infoframe | INTR_Inactive_to_Active | INTR_phy_IN_RANGE | INTR_phy_PLLLOCK); HDMI_Interrupt_Enable(INTR_HDCP_Key_Request | INTR_AVI_infoframe | INTR_SPD_infoframe | INTR_Inactive_to_Active | INTR_phy_IN_RANGE | INTR_PLLLOCK); //HDMI_RegisterWrite(HDMIRX_R_INTR_en, INTR_GamutBoundaryData); //enable INTR_GamutBoundaryData //HDMI_RegisterWrite(HDMIRX_R_INTR_en, INTR_VSI_packets); //enable INTR_VSI_packets /* Clear interrupts of audio sample commings */ HDMI_RegisterWrite(HDMIRX_AS_exist, 1); // Write 1 Clear HDMI_RegisterWrite(HDMIRX_HBRAS_exist, 1); // Write 1 Clear /* Enable hdmi logic, power on */ HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); /* Enable hdmi logic */ HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 1); //start phy clock for In_Range interrupt /* Set software hdcp handshake */ HDMI_RegisterWrite(HDMIRX_R_CLK_DIV, 0x4); /* Enable hdcp */ HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f04); HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f0c); HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f85); /* Apply HPD according to DDC status */ #ifdef HDMI_DDC5V_WORKAROUND if(CEC_Get_SW5V(hdmi_get_cur_port()) == DRV_5V_LEVEL_HIGH) //do not change HPD status after cable out, or the HPD will be high #endif hdmi_apply_hpd((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_HIGH); hdmi_flag_set(WAIT_HDCP); } static struct work_struct wq_Enable_InRange; void HDMI_Enable_InRange(void) { printk("HDMI_Enable_InRange\n"); HDMI_Interrupt_Enable(INTR_phy_IN_RANGE); } #ifdef USE_HW_ADAPTIVE_EQ void HDMI_Enable_DCK(void) { hdmidbg("HDMI_Enable_DCK\n"); HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 1); } #endif void DRV_HDMI_SW_HDCP_RSTN(void) { hdmidbg("DRV_HDMI_SW_HDCP_RSTN\n"); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 0); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 1); } void hdmi_dbg_Handler(INT8 *buf, size_t size); /* Defined in hdmi_hdcp.c */ UINT32 hdmi_get_hdcp_data(INT32 offset); static BOOL Active_Flag=FALSE; static UINT8 AVI_ISR_CNT=0; static UINT8 Active_to_Inactive_ISR_CNT=0; #ifdef CONFIG_SUPPORT_DOLBY_AUDIO static BOOL ATMOS_MODE=FALSE; static BOOL CurATMOS_MODE=FALSE; static BOOL EDID_SUPPORT_DD_PLUS=TRUE; #endif static irqreturn_t hdmi_isr(INT32 irq, void* dev_id, struct pt_regs *regs) { UINT32 dIntrStatus; #ifdef USE_HW_ADAPTIVE_EQ UINT32 bPhyOvspIntrStatus; #endif static UINT8 bResetInRangeIntrCnt = 0; static UINT32 dLastHDMI_GetSysTime = 0; UINT32 dCurHDMI_GetSysTime = 0; dIntrStatus = HDMI_RegisterRead(HDMIRX_R_INTR_Status); #ifdef USE_HW_ADAPTIVE_EQ bPhyOvspIntrStatus = (*((u32 *)0xbe0e0c40) &INTR_Phy_Ovsp_int) ; #endif if(dIntrStatus & INTR_HDCP_Key_Request) { UINT32 start_count = read_c0_count(); UINT32 diff_count = 0; UINT32 wait_count = __TIMER_FREQ / 10; hdmidbg("ISR:HDCP_Key_Request\n"); do { INT32 keyoffset = HDMI_RegisterRead(HDMIRX_mmio_raddr); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_HDCP_Key_Request); //clear HDMI_RegisterWrite(HDMIRX_mmio_rdata, hdmi_get_hdcp_data(keyoffset)); if (keyoffset == 0x01) { hdmidbg("HDCP KSV\n"); break; } else if (keyoffset == 0x47) { hdmi_flag_set(HAS_HDCP); hdmidbg("HDCP KEY\n"); hdmi_flag_clear(WAIT_HDCP); break; } dIntrStatus = HDMI_RegisterRead(HDMIRX_R_INTR_Status); while ((!(dIntrStatus & INTR_HDCP_Key_Request)) && (diff_count < wait_count)) { diff_count = read_c0_count(); diff_count -= start_count; dIntrStatus = HDMI_RegisterRead(HDMIRX_R_INTR_Status); } } while (diff_count < wait_count); return IRQ_HANDLED; } dIntrStatus = HDMI_RegisterRead(HDMIRX_R_INTR_Status); if(dIntrStatus & INTR_Buffer_Change_Pulse) { //hdmidbg("ISR:Buffer_Change_Pulse\n"); if (hdmi_flag_check(HAS_ACTIVE_DATA)) { HDMI_Audio_BufferUpdated(); } else { HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Buffer_Change_Pulse); //clear } } else if (dIntrStatus & INTR_Channel_Status_Lock_Pulse) { hdmidbg("ISR:Channel_Status_Lock_Pulse\n"); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Channel_Status_Lock_Pulse); //clear /* The ACP Interrupt is enabled after channel lock interrupt is serviced. */ HDMI_Interrupt_Enable(INTR_ACP_packets); /* Only handle channel lock interrupts when video is avaliable */ if (hdmi_flag_check(HAS_ACTIVE_DATA)) { // schedule_work(&wq_chlock); // printk("Channel lock isr\n"); HDMI_Audio_ChannelLocked(); } else { hdmidbg("Channel lock isr is disabled\n"); HDMI_RegisterWrite(HDMIRX_R_dma_w_enable, 0); HDMI_Interrupt_Disable(INTR_Buffer_Change_Pulse | INTR_Channel_Status_Lock_Pulse); HDMI_RegisterWrite(HDMIRX_R_audio_enable, 0); } } else if (dIntrStatus & INTR_audio_sample_coming) { hdmidbg("ISR:audio_sample_coming\n"); HDMI_Interrupt_Disable(INTR_audio_sample_coming); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_audio_sample_coming); //clear HDMI_Interrupt_Enable(INTR_HBR_audio_sample_coming); HDMI_RegisterWrite(HDMIRX_AS_exist, 1); //Write 1 Clear HDMI_RegisterWrite(HDMIRX_HBRAS_exist, 1); //Write 1 Clear /* Restart hdmi audio to receive high bitrate audio samples */ DRV_HDMI_AudioRestart(); } else if (dIntrStatus & INTR_HBR_audio_sample_coming) { hdmidbg("ISR:HBR_audio_sample_coming\n"); HDMI_Interrupt_Disable(INTR_HBR_audio_sample_coming); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_HBR_audio_sample_coming); //clear HDMI_Interrupt_Enable(INTR_audio_sample_coming); HDMI_RegisterWrite(HDMIRX_AS_exist, 1); //Write 1 Clear HDMI_RegisterWrite(HDMIRX_HBRAS_exist, 1); //Write 1 Clear /* Restart hdmi audio to receive normal bitrate audio samples */ DRV_HDMI_AudioRestart(); } else if (dIntrStatus & INTR_ACP_packets) { hdmidbg("ISR:ACP_packets\n"); /* The ACP Interrupt is enabled after channel lock interrupt is serviced. */ /* Clear the interrupt */ HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_ACP_packets); //clear /* Service once and disable the interrupt */ HDMI_Interrupt_Disable(INTR_ACP_packets); /* Notice flow control that the input audio type */ //HDMI_NoticeAudioACP(HDMI_RegisterWrite(HDMIRX_R_ACP_Type); } else if (dIntrStatus & INTR_AVI_infoframe) { /* Related info will be used in active interrupt handler */ hdmidbg("ISR:AVI_infoframe\n"); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_AVI_infoframe); //clear if(hdmi_flag_check(HAS_ACTIVE_DATA)) { avi_change_schedule(); } hdmi_flag_set(HAS_AVIINFO_PKT); if( Active_Flag ==FALSE) { if(AVI_ISR_CNT<3) { AVI_ISR_CNT++; } else { printk("Repeat ISR:AVI_infoframe\n"); HDMI_Reset_HDMI_PLL(); 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); AVI_ISR_CNT = 0; } } } else if (dIntrStatus & INTR_Inactive_to_Active) { #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) { printk("ISR:Inactive_to_Active\n"); } else #endif { #ifdef USE_HW_ADAPTIVE_EQ printk("ISR:Inactive_to_Active EQ:0x%x\n",HDMI_RegisterRead(HDMIRX_1050_DW_1050)); #else printk("ISR:Inactive_to_Active\n"); #endif } HDMI_RegisterWrite(HDMIRX_R_GBD_exist, 1); // reset, pass xvYCC to VIP HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Inactive_to_Active); //clear HDMI_Interrupt_Disable(INTR_Inactive_to_Active); if( Active_Flag ==FALSE) { HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 1); /* Notice audio driver that no video present */ HDMI_NoticeAudioMode(NO_HDMI_AUDIO); /* Remove no signal timer */ hdmi_signal_check_stop(); /* Schedule active timer */ active_timer_remove(); // reset active run to zero signal_monitor_timer_remove(); active_timer_schedule(0); // start active run for stable signal HDMI_Interrupt_Enable(INTR_Active_to_Inactive); Active_Flag=TRUE; AVI_ISR_CNT = 0; } else { printk("Repeat ISR:Inactive_to_Active\n"); } } else if (dIntrStatus & INTR_Active_to_Inactive) { #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT)) HDMI_MHL_RxSense_Term_Debug(FALSE); //auto HDMI or MHL mode for MHL CTS 4.3.23.2 else HDMI_MHL_RxSense_Term_Debug(TRUE); //force HDMI mode for debug(not MHL mode) #endif HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 1); HDMI_DelayMs(1); HDMI_NoticeHandler(HDMINOTICE_INACTIVE, "hdmi_isr"); //mute video for port C hpd always high issue printk("ISR:Active_to_Inactive\n"); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 0); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 1); HDMI_RegisterWrite(HDMIRX_icrst_n, 1); HDMI_RegisterWrite(HDMIRX_external_gated_TMDSCLK, 0); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x0);// HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x0); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 0); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 0); //HDMI_RegisterWrite(CTRLI_47_32__DW_0284,0x0003);//Base on old address setting from 531 HDMI_RegisterWrite(HDMIRX_PLL_EN_FDIV, 0x0); HDMI_RegisterWrite(HDMIRX_PLL_GB_5, 0x1);//For 533 PFD_PWDJ HDMI_RegisterWrite(HDMIRX_PLL_GB_4_0_, 0x0); HDMI_RegisterWrite(HDMIRX_PLL_ICTRL_3_0_, 0x0); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 0x0); HDMI_RegisterWrite(HDMIRX_PLL_PWDN_DEMOD, 0x0); HDMI_RegisterWrite(HDMIRX_LDO_PWDE, 0x0); HDMI_RegisterWrite(HDMIRX_LDO_PWD, 0x0); HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 0);//For CTS Nosiglal issue HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_PDACJ_CK, 1); Active_Flag=FALSE; HDMI_Interrupt_Disable(INTR_Active_to_Inactive); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_Active_to_Inactive); //clear HDMI_Interrupt_Enable(INTR_Inactive_to_Active); //HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 0); HDMI_RegisterWrite(HDMIRX_R_GBD_exist, 1); // reset, pass xvYCC to VIP #ifdef CONFIG_HDMI_HW_PATCH_FOR_HDCP_COLOR_SNOW if ((hdmi_flag_check(HAS_HDCP) == true) && (hdmi_flag_check(HAS_ACTIVE_DATA) == true)) { printk("[H] HDCP SNOW PATCH\n"); /* Disable hdmi hw and all interrupts */ HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); /* Disable hdmi logic */ HDMI_Interrupt_Disable(INTR_ALL); /* Disable all interrupts */ //HDMI_Interrupt_Enable(INTR_phy_IN_RANGE | INTR_phy_PLLLOCK); //These two interrupt shall not be disabled at 531 HDMI_Interrupt_Enable(INTR_phy_IN_RANGE | INTR_PLLLOCK); //These two interrupt shall not be disabled at 531 HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_ALL); /* Clear all interrupts if any */ schedule_work(&wq_ToggleHPD); } hdmi_flag_clear(HAS_ACTIVE_DATA); #endif // Clear Soft Mute interrupt HDMI_RegisterWrite(HDMIRX_Soft_Clear_Mute, 1); HDMI_RegisterWrite(HDMIRX_Soft_Clear_Mute, 0); /* Clear all video related flags */ hdmi_flag_reset(); /* Notice audio driver that no video present */ HDMI_NoticeAudioMode(NO_HDMI_AUDIO); /* Remove active timer if scheduled */ active_timer_remove(); // reset active run to zero signal_monitor_timer_remove(); /* Check signal status */ hdmi_signal_check_start(); 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); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_0_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_1_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_2_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_3_reg_ctl, 0x0); if(Active_to_Inactive_ISR_CNT<5) { Active_to_Inactive_ISR_CNT++; } else { //Reset PLL printk("ISR:Reset PLL\n"); HDMI_Reset_HDMI_PLL(); 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); printk("Repeat ISR:Active_to_Inactive\n"); Active_to_Inactive_ISR_CNT = 0; } HDMI_Interrupt_Disable(INTR_audio_sample_coming | INTR_HBR_audio_sample_coming); HDMI_NoticeHandler(HDMINOTICE_SPD_INFOFRAME_UPDATE, "hdmi_isr"); } else if (dIntrStatus & INTR_phy_IN_RANGE) { if(TRUE == Active_Flag) { Active_Flag = FALSE; HDMI_Interrupt_Disable(INTR_Active_to_Inactive); HDMI_Interrupt_Enable(INTR_Inactive_to_Active); } #ifdef USE_HW_ADAPTIVE_EQ #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet() == CONFIG_HDMI_MHL_PORT)) { HDMI_RegisterWrite(HDMIRX_icrst_n, 1); HDMI_RegisterWrite(HDMIRX_prstn, 1); HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 1); HDMI_RegisterWrite(HDMIRX_EQ_VAL_FIX, 1); writel((readl(0xbe0e0c44)&(~INTR_Phy_Ovsp_int)), 0xbe0e0c44); } else #endif { HDMI_RegisterWrite(HDMIRX_icrst_n, 0); HDMI_RegisterWrite(HDMIRX_prstn, 0); //HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 0); HDMI_RegisterWrite(HDMIRX_EQ_VAL_FIX, 0); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); writel((readl(0xbe0e0c44)|INTR_Phy_Ovsp_int), 0xbe0e0c44); } #endif HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 0); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_RegisterWrite(HDMIRX_R_SP5_PLL_CTP_PWDJ, 0x0); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x0); HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x0); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 0); HDMI_DelayUs(10); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_0_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_1_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_2_reg_ctl, 0x0); HDMI_RegisterWrite(HDMIRX_RTT_CMCTL_3_reg_ctl, 0x1); /* Prevent In_Range continually happens cause system hang, and set a timeout for reset bResetInRangeIntrCnt */ dCurHDMI_GetSysTime = HDMI_GetSysTime(); if((dCurHDMI_GetSysTime - dLastHDMI_GetSysTime) > 2000) { dLastHDMI_GetSysTime = dCurHDMI_GetSysTime; bResetInRangeIntrCnt = 0; } bResetInRangeIntrCnt++; if(bResetInRangeIntrCnt >= HDMI_RESET_IN_RANGE_INTR_TH) { HDMI_Interrupt_Disable(INTR_phy_IN_RANGE); } printk("ISR:IN_RANGE %d\n", bResetInRangeIntrCnt); /* Remove active timer if scheduled */ active_timer_remove(); // reset active run to zero signal_monitor_timer_remove(); #ifdef HDMI_HPD_USE_1K_OHM if( DrvHDMIPortSelectBitsGet()==0x0) { sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_A, FALSE); } else if( DrvHDMIPortSelectBitsGet()==0x1) { sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_B, FALSE); } else if( DrvHDMIPortSelectBitsGet()==0x2) { sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_C, FALSE); } #endif #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN == TRUE)&&( DrvHDMIPortSelectBitsGet() == CONFIG_HDMI_MHL_PORT)) { printk("MHL Mode\n"); //HDMI_RegisterWrite(CTRLI_47_32__DW_0284, 0x9068);//Base on old address setting from 531 //HDMI_RegisterWrite(HDMIRX_R_RTT_INI_5_0_, 0x35); HDMI_RegisterWrite(HDMIRX_R_RTT_INI_5_0_, 0x2f); HDMI_RegisterWrite(HDMIRX_lowlmt, 0x0); HDMI_RegisterWrite(HDMIRX_taps_0, 0x0); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); //HDMI_RegisterWrite(HDMIRX_icrst_n, 0); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_phy_IN_RANGE); //clear HDMI_DelayMs(10); HDMI_RegisterWrite(HDMIRX_PLL_ICTRL_3_0_, 0x1); HDMI_RegisterWrite(HDMIRX_PLL_GB_5, 1);//For 533 PFD_PWDJ HDMI_RegisterWrite(HDMIRX_PLL_GB_4_0_, 0xf);// 3 HDMI_DelayUs(10); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_R_SP5_PLL_CTP_PWDJ, 0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x1); HDMI_DelayUs(8); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 1); HDMI_DelayUs(1); HDMI_MHL_SetPLL_ByFreq(); //HDMI_DelayMs(2); //HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); #ifdef CONFIG_HDMI_MHL_PORT if(CONFIG_HDMI_MHL_PORT==0) { HDMI_RegisterWrite(HDMIRX_HDMIP0_Rx_Sense_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Rx_Sense_mux, 1); } else if(CONFIG_HDMI_MHL_PORT==1) { HDMI_RegisterWrite(HDMIRX_HDMIP1_Rx_Sense_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP1_Rx_Sense_mux, 1); } #endif HDMI_DelayMs(1); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x1); HDMI_DelayMs(1); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 1); HDMI_DelayMs(1); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 1); } else { printk("HDMI Mode\n"); HDMI_RegisterWrite(HDMIRX_R_RTT_INI_5_0_, 0x2d); HDMI_RegisterWrite(HDMIRX_lowlmt, 0x0); HDMI_RegisterWrite(HDMIRX_taps_0, 0x0); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_RegisterWrite(HDMIRX_icrst_n, 0); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_phy_IN_RANGE); //clear HDMI_DelayMs(50); #if 0 HDMI_RegisterWrite(CTRLI_631_600__DW_0430,0x77722077); HDMI_RegisterWrite(CTRLI_663_632__DW_0434,0x20777220); HDMI_RegisterWrite(CTRLI_695_664__DW_0438,0x00000072); #endif HDMI_RegisterWrite(HDMIRX_PLL_ICTRL_3_0_, 0x1); HDMI_RegisterWrite(HDMIRX_PLL_GB_5, 1);//For 533 PFD_PWDJ HDMI_RegisterWrite(HDMIRX_PLL_GB_4_0_, 0xf);// 3 HDMI_DelayUs(10); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_R_SP5_PLL_CTP_PWDJ, 0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x1); HDMI_DelayUs(8); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 1); HDMI_DelayUs(1); HDMI_SetPLL_ByFreq(); } #else HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); HDMI_RegisterWrite(HDMIRX_icrst_n, 0); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_phy_IN_RANGE); //clear HDMI_DelayMs(50); HDMI_RegisterWrite(HDMIRX_PLL_ICTRL_3_0_, 0x1); HDMI_RegisterWrite(HDMIRX_PLL_GB_5, 1);//For 533A2 PFD_PWDJ HDMI_RegisterWrite(HDMIRX_PLL_GB_4_0_, 0xf);// 3 HDMI_DelayUs(10); HDMI_RegisterWrite(HDMIRX_PLL_RSTN, 1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_R_SP5_PLL_CTP_PWDJ, 0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWD,0x1); HDMI_RegisterWrite(HDMIRX_LDO_PWDE,0x1); HDMI_DelayUs(8); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0020); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x0028); HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_PLL_RESETJ, 1); HDMI_DelayUs(1); HDMI_SetPLL_ByFreq(); #endif if(HDMI_RegisterRead(HDMIRX_ref_freq_cnt)<=5) { HDMI_RegisterWrite(HDMIRX_icrst_n, 1); HDMI_RegisterWrite(HDMIRX_external_gated_TMDSCLK, 1); HDMI_RegisterWrite(HDMIRX_CTL_R_MORECTRLI_15_0_, 0x40e8); HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 1); } if(bResetInRangeIntrCnt >= HDMI_RESET_IN_RANGE_INTR_TH) schedule_work(&wq_Enable_InRange); } else if (dIntrStatus & INTR_PLLLOCK) { printk("ISR:PLLLOCK\n"); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_PLLLOCK); //clear //Bryan@20131217 add toggle HDMIRX_PHY_DIV_RESETJ to fix sometime no signal issue HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_RegisterWrite(HDMIRX_HDMIRX_CDRRSTJ_CTL, 0); HDMI_RegisterWrite(HDMIRX_icrst_n, 0); HDMI_DelayMs(10); /* Power On PHY */ HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 1); //HDMI_DelayMs(10); HDMI_RegisterWrite(HDMIRX_HDMIRX_CDRRSTJ_CTL, 1); HDMI_RegisterWrite(HDMIRX_icrst_n, 1); #ifdef USE_HW_ADAPTIVE_EQ #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN != TRUE)||( DrvHDMIPortSelectBitsGet() != CONFIG_HDMI_MHL_PORT)) #endif { HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_prstn, 1); //HDMI_DelayMs(300); //HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 1); schedule_delayed_work(&wq_Enable_DCK, (300*HZ)/1000); //HZ = 1000; 1 jiffies = 1ms } #endif //HDMI_DelayMs(10); //HDMI_RegisterWrite(HDMIRX_bp_fix, 1); HDMI_DelayMs(2); HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); hdmi_signal_check_stop(); hdmi_signal_lock_check_start(); Active_to_Inactive_ISR_CNT = 0; //bBP_LOCK = TRUE; bResetInRangeIntrCnt = 0; } else if (dIntrStatus & INTR_SPD_infoframe) { printk("ISR:INTR_SPD_infoframe\n"); HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_SPD_infoframe); //clear HDMI_NoticeHandler(HDMINOTICE_SPD_INFOFRAME_UPDATE, "hdmi_isr"); } #ifdef USE_HW_ADAPTIVE_EQ #ifdef CONFIG_HDMI_SUPPORT_MHL if((MHL_CABLE_IN != TRUE)||( DrvHDMIPortSelectBitsGet() != CONFIG_HDMI_MHL_PORT)) #endif { if(bPhyOvspIntrStatus & INTR_Phy_Ovsp_int) { printk("INTR_Phy_Ovsp_int EQ:0x%x\n",HDMI_RegisterRead(HDMIRX_1050_DW_1050)); (*((u32 *)0xbe0e0c40) )= (*((u32 *)0xbe0e0c40) )|INTR_Phy_Ovsp_int;//write 1 to Clear HDMI_DelayUs(1); HDMI_RegisterWrite(HDMIRX_RST_1XCLK, 1); } } #endif return IRQ_HANDLED; } static void hdmi_dispatch(struct pt_regs *regs) { do_IRQ(IRQ_HDMI); } static struct irqaction hdmi_irqaction = { .handler = (void *)&hdmi_isr, .flags = 0, .name = "hdmi", }; #ifdef CONFIG_DEBUG_DRV_HDMI_WRITE_EN INT32 hdmi_write(struct file *file, const INT8 __user * buf, size_t size, loff_t * ppos) { size_t in_sz = 0x100; INT8 inbuf[0x100]; in_sz = (size < in_sz) ? size :in_sz; memset(inbuf, 0, sizeof(inbuf)); if (copy_from_user(inbuf, buf, in_sz) == 0) { hdmi_dbg_Handler(inbuf, in_sz); } return size; } #endif static struct file_operations hdmi_fops = { #ifdef CONFIG_DEBUG_DRV_HDMI_WRITE_EN .write = hdmi_write, #endif .owner = THIS_MODULE, }; void DRV_HDMI_Disable(void) { hdmidbg("%s\n", __FUNCTION__); #ifdef CONFIG_CHANGE_HOT_PLUG_ACTION #ifndef CONFIG_SUPPORT_CEC_TV hdmi_apply_hpd(DRV_HDMI_PORT_ALL , DRV_HPD_LEVEL_LOW); #endif #endif /* Indicate flow control that no video is present now */ HDMI_NoticeAudioMode(NO_HDMI_AUDIO); HDMI_Interrupt_Disable(INTR_ALL); /* Disable all interrupts */ HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_ALL); /* Clear all interrupts if any */ /* Remove timers */ active_timer_remove(); signal_monitor_timer_remove(); hdmi_signal_check_stop(); /* Clear all video related flags */ hdmi_flag_reset(); /* Disable hdmi logic, power off */ HDMI_RegisterWrite(HDMIRX_R_VIDEO_MUTE, 0); /* Mute Video */ HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); /* Disable hdmi logic */ /* Indicate hpd handler we leave hdmi source */ hdmi_hpd_handler(HDMI_SRC_NULL); /*Set Termination Off for power saving*/ // Must set_termination before turn off bandgap power #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if(CONFIG_HDMI_MHL_PORT==0) { if(MHL_CABLE_IN == FALSE)//For XIAOMI charging function can not set termination off. { hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW); } hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW); hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_LOW); } else if(CONFIG_HDMI_MHL_PORT==1) { if(MHL_CABLE_IN == FALSE) { hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW); } hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW); hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_LOW); } #endif #else hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW); hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW); hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_LOW); #endif /* Disable HDMI PHY */ HDMI_PHY_Enable(FALSE); /* Disable hdmi switch if any */ hdmi_switch_disable(); #ifdef CONFIG_HDMI_SUPPORT_MHL /* Pause MHL CBUS Work */ //MHL_CBUS_Work_Enable(FALSE); HDMI_RegisterWrite(HDMIRX_R_hdmi_port_sel, 3);//Set HDMIRX_R_hdmi_port_sel to null port #endif } INT32 DRV_HDMI_Enable(INT32 src) { HDMI_PORT_T port = hdmi_hw_port(src); hdmidbg("%s src:%d port:%d\n", __FUNCTION__, src, port); if (port == HDMI_PORT_NULL) { hdmidbg("%s Incorrect hdmi port\n", __FUNCTION__); return 1; } //After plug in S+8203r HDMI Tester Source,Box IBT 1073 NG HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 0); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 1); /* Indicate hpd handler that we select hdmi source */ if(HDMI_Init==TRUE) hdmi_hpd_handler(src); #ifdef CONFIG_SUPPORT_CEC_TV /*Set Toggle HPD*/ if(HDMI_Init==TRUE) { if(hdmi_get_hpd_at_cur_src()) { #ifdef CONFIG_SUPPORT_DOLBY_AUDIO if (CurATMOS_MODE !=ATMOS_MODE) { hdmi_apply_hpd(DRV_HDMI_PORT_ALL , DRV_HPD_LEVEL_LOW); HDMI_Change_EDID_DD_Plus_Data(ATMOS_MODE); HDMI_DelayMs(HDMI_HPD_L2H_DELAY); hdmi_apply_hpd_by5V(DRV_HDMI_PORT_ALL); } else #endif { hdmi_apply_hpd_Toggle((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_LOW,TRUE); HDMI_DelayMs(HDMI_HPD_L2H_DELAY); hdmi_apply_hpd_Toggle((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_HIGH,FALSE); } } } #else #ifdef CONFIG_CHANGE_HOT_PLUG_ACTION if(HDMI_Init==TRUE) { hdmi_apply_hpd_by5V((1 << hdmi_get_cur_port())); hdmi_hpd_update(); } #endif #endif #ifdef CONFIG_ENTER_PORT_HPD_HIGH if(HDMI_Init==TRUE) { if(hdmi_get_hpd_at_cur_src()==FALSE) { hdmi_apply_hpd((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_HIGH); } } #endif /* Disable hdmi hw and all interrupts */ HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); /* Disable hdmi logic */ HDMI_Interrupt_Disable(INTR_ALL); /* Disable all interrupts */ HDMI_RegisterWrite(HDMIRX_R_INTR_Status, INTR_ALL); /* Clear all interrupts if any */ /* Clear all video related flags */ hdmi_flag_reset(); Active_Flag=FALSE; AVI_ISR_CNT = 0; /* Disable HDMI PHY */ HDMI_PHY_Enable(FALSE); HDMI_DelayMs(10); /* Enable HDMI PHY */ HDMI_PHY_Enable(TRUE); #ifdef HDMI_HPD_USE_1K_OHM if(MHL_CABLE_IN == FALSE) { sysset_HDMI_HPD_1K_OnOff(port, TRUE); } #else sysset_HDMI_HPD_1K_OnOff(port, FALSE); #endif #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT) { if(CONFIG_HDMI_MHL_PORT==0) { if(MHL_CABLE_IN == TRUE)//For HTC Butterfly S need toggle HDMI termination. { hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_LOW); HDMI_DelayMs(150); } } else if(CONFIG_HDMI_MHL_PORT==1) { if(MHL_CABLE_IN == TRUE) { hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_LOW); HDMI_DelayMs(150); } } } #endif #endif /*Set Termination On*/ #ifdef CONFIG_HDMI_ALL_PORT_TERMINATION_ON hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH); hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH); hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_HIGH); #else hdmi_set_termination((1 << hdmi_get_cur_port()), DRV_HPD_LEVEL_HIGH); #endif /* Set hdmi hw for each port */ switch (port) { case HDMI_PORT_A: //hdmi_set_termination(DRV_HDMI_PORT_A, DRV_HPD_LEVEL_HIGH); HDMI_RegisterWrite(HDMIRX_R_HDMI_LinkS, 0); HDMI_RegisterWrite(HDMIRX_R_hdmi_port_sel, 0); //HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 0);//Support MHL in Port:A HDMI_RegisterWrite(HDMIRX_PORT_EN_P2_0,0x1); //sysset_cbus_port_sel(HDMI_PORT_A); //HDMI_RegisterWrite(HDMIRX_VBG_VREF_SEL_3_0_,1); break; case HDMI_PORT_B: //hdmi_set_termination(DRV_HDMI_PORT_B, DRV_HPD_LEVEL_HIGH); HDMI_RegisterWrite(HDMIRX_R_HDMI_LinkS, 1); HDMI_RegisterWrite(HDMIRX_R_hdmi_port_sel, 1); HDMI_RegisterWrite(HDMIRX_PORT_EN_P2_0,0x2); break; case HDMI_PORT_C: //hdmi_set_termination(DRV_HDMI_PORT_C, DRV_HPD_LEVEL_HIGH); HDMI_RegisterWrite(HDMIRX_R_HDMI_LinkS, 2); HDMI_RegisterWrite(HDMIRX_R_hdmi_port_sel, 2); HDMI_RegisterWrite(HDMIRX_PORT_EN_P2_0,0x4); break; default: break; } #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT) { #if 0 //reset cbus HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 1); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_buf_reset, 1); //HDMI_DelayMs(100); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_cbus_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_r_reset_reg, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_debounce_reset, 0); HDMI_RegisterWrite(HDMIRX_CBUS_cfg_buf_reset, 0); #endif if(MHL_CABLE_IN == TRUE) { HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 0xF);//For MIK-706 } } #endif #endif HDMI_RegisterWrite(HDMIRX_R_PHY_SEL, 0); /* Enable related interrupts */ //HDMI_Interrupt_Enable(INTR_HDCP_Key_Request | INTR_AVI_infoframe | INTR_Inactive_to_Active | INTR_phy_IN_RANGE | INTR_phy_PLLLOCK); HDMI_Interrupt_Enable(INTR_HDCP_Key_Request | INTR_AVI_infoframe | INTR_SPD_infoframe | INTR_Inactive_to_Active | INTR_phy_IN_RANGE | INTR_PLLLOCK); HDMI_Interrupt_Disable(INTR_audio_sample_coming | INTR_HBR_audio_sample_coming); HDMI_RegisterWrite(HDMIRX_R_GBD_update_once, 1); #ifdef USE_HW_ADAPTIVE_EQ //0xbe0e0c46[7]Phy_Ovsp_int Enable 1: Enable *((u32 *)0xbe0e0c44) = (*((u32 *)0xbe0e0c44) |INTR_Phy_Ovsp_int) ;//write 1 to Enable #endif /* Clear interrupts of audio sample commings */ HDMI_RegisterWrite(HDMIRX_AS_exist, 1); // Write 1 Clear HDMI_RegisterWrite(HDMIRX_HBRAS_exist, 1); // Write 1 Clear /* Enable hdmi logic, power on */ HDMI_RegisterWrite(HDMIRX_R_rst_n, 1); /* Enable hdmi logic */ HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rst_en, 1); /* set hdcp reset independent from HDMIRX_R_rst_n , do not reset by hdmi resst */ /* Set software hdcp handshake */ HDMI_RegisterWrite(HDMIRX_R_CLK_DIV, 0x4); /* Enable hdcp */ HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f04); HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f0c); HDMI_RegisterWrite(HDMIRX_R_HDCP_CTL, 0x9f85); /* Check signal status */ //HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 0); hdmi_signal_check_start(); /* Select hdmi switch port if any */ hdmi_switch_enable(hdmi_sw_port(src)); *((u8 *)0xbe000214) = (*((u8 *)0xbe000214) &0x0F) | 0x80 ; /* Initial MHL CBUS Work */ #ifdef CONFIG_HDMI_SUPPORT_MHL if(CONFIG_HDMI_MHL_PORT==0) { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 0);//Support MHL in Port:A sysset_cbus_port_sel(HDMI_PORT_A); } else if(CONFIG_HDMI_MHL_PORT==1) { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 1);//Support MHL in Port:B sysset_cbus_port_sel(HDMI_PORT_B); } else //Error Case: Not config MHL in correct port(0 or 1) , Set to 3(Null port) and let A and B keep in HDMI Mode { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 3);//Let A and B keep in HDMI Mode } if(MHL_CBUS_Init==FALSE) { MHL_CBUS_Initial(); MHL_CBUS_Init=TRUE; } if( DrvHDMIPortSelectBitsGet()==CONFIG_HDMI_MHL_PORT) { if(CbusMidGetDevCapReadyBit()==FALSE) { /* Start MHL CBUS Work */ if(TRUE == HDMI_Init) { MHL_CBUS_Work_Enable(TRUE); } } else { if((HDMI_RegisterRead(HDMIRX_cbus_mode_pathen_muted)&0x3) ==0x2) {//CLK_MODE=10 =>PP Mode hdmidbg("MHL PP Mode\n"); HDMI_RegisterWrite(HDMIRX_TMDSCLK_PP_SEL, 1); //*((u8 *)0xbe0e001c) = 0xff; HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_PLL_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_PLL_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_PLL_Sel_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_PLL_mux, 1); } else {//CLK_MODE=11 =>24 Bit Mode hdmidbg("MHL 24 Bit Mode\n"); HDMI_RegisterWrite(HDMIRX_TMDSCLK_PP_SEL, 0); //*((u8 *)0xbe0e001c) = 0xbb; HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_external, 0); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_PLL_external, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_Mode_Sel_PLL_mux, 1); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_PLL_Sel_external, 0); HDMI_RegisterWrite(HDMIRX_HDMIP0_MHL_Mode_Sel_PLL_mux, 1); } } } #endif return 0; } #ifdef CONFIG_SUPPORT_DOLBY_AUDIO void HDMI_Set_EDID_ATMOS_Mode(BOOL eATMOS) { hdmidbg("%s\n", __FUNCTION__); hdmidbg("ATMOS_Mode %d\n",eATMOS); ATMOS_MODE=eATMOS; if (CurATMOS_MODE !=ATMOS_MODE) { //if(EDID_SUPPORT_DD_PLUS==TRUE) { HDMI_Change_EDID_DD_Plus_Data(ATMOS_MODE); } } } void HDMI_Change_EDID_DD_Plus_Data(BOOL Atmos_Mode) { u32 edid_data_addr,edid_data_size,i; UINT32 *data_ptr1; UINT8 *data_ptr = NULL; UINT8 bEdidWriteBack=0; if(Atmos_Mode !=CurATMOS_MODE) { edid_data_addr = lookup_flashtable_addr("EDID"); edid_data_size = lookup_flashtable_size("EDID"); data_ptr = kmalloc(edid_data_size, GFP_KERNEL); //memcpy(data_ptr, edid_data_addr|0xb0000000, edid_data_size); memcpy( (void *)data_ptr, (void* )(edid_data_addr|0xb0000000), edid_data_size); //hdmidbg("data_ptr[0] : %x data_ptr[1] : %x data_ptr[2] : %x data_ptr[3] : %x data_ptr[4] : %x \n", data_ptr[128+0], data_ptr[128+1], data_ptr[128+2], data_ptr[128+3], data_ptr[128+4]); if(Atmos_Mode==TRUE) { UINT8 bDataBlkType1 = (data_ptr[128+4]&0xe0)>>5; UINT8 bLength1 = data_ptr[128+4]&0x1f; UINT8 bDataBlkType2 = (data_ptr[128+4+bLength1+1]&0xe0)>>5; UINT8 bLength2 = data_ptr[128+4+bLength1+1]&0x1f; UINT8 bShortAudDataCount = 0, bShortAudDataShift = 0, bDD_Plus_Byte3_Index = 0; if(bDataBlkType1==1) { bShortAudDataCount =bLength1/3 ; for (i = 0; i < bShortAudDataCount; i++) { bShortAudDataShift = i*3; if (( ((data_ptr[128+4+1+bShortAudDataShift])&0x78)>>3) ==10) //DD_Plus { bDD_Plus_Byte3_Index=(128+4+bShortAudDataShift+3); break; } } } else if (bDataBlkType2==1) { bShortAudDataCount =bLength2/3 ; for (i = 0; i < bShortAudDataCount; i++) { bShortAudDataShift = i*3; if (( ((data_ptr[128+4+bLength1+1+bShortAudDataShift+1])&0x78)>>3) ==10) //DD_Plus { bDD_Plus_Byte3_Index=(128+4+bLength1+1+bShortAudDataShift+3); break; } } } if (bDD_Plus_Byte3_Index !=0) { hdmidbg("bDD_Plus_Byte3 is %x \n", data_ptr[bDD_Plus_Byte3_Index]); EDID_SUPPORT_DD_PLUS=TRUE; bEdidWriteBack = TRUE; if((data_ptr[bDD_Plus_Byte3_Index]&0x01)==0) { data_ptr[bDD_Plus_Byte3_Index]+=1;//EDIDA Set ATMOS Mode data_ptr[255]-=1;//Update Check Sum Data } if((data_ptr[bDD_Plus_Byte3_Index+256]&0x01)==0) { data_ptr[bDD_Plus_Byte3_Index+256]+=1;//EDIDB Set ATMOS Mode data_ptr[255+256]-=1;//Update Check Sum Data } if((data_ptr[bDD_Plus_Byte3_Index+256+256+128]&0x01)==0) { data_ptr[bDD_Plus_Byte3_Index+256+256+128]+=1;//EDIDC Set ATMOS Mode data_ptr[255+256+128+256]-=1;//Update Check Sum Data } } else { EDID_SUPPORT_DD_PLUS=FALSE; bEdidWriteBack = FALSE; hdmidbg("Don't find DD+ Audio Format Code in Short Audio Descriptor!!!\n"); } } else { hdmidbg("edid write back !!!\n"); bEdidWriteBack = TRUE; } } if(bEdidWriteBack == TRUE) { hdmi_apply_hpd(DRV_HDMI_PORT_ALL , DRV_HPD_LEVEL_LOW); data_ptr1 = (UINT32 *) data_ptr; //Update SRAM EDID /* Write HDMI A & B EDID 512 (0x280) byte */ for (i = 0; i < 0x80; i++) { writel(0x100+i,0xbe060034); writel(data_ptr1[i], 0xbe060038); writeb(0x1, 0xbe06002c); } data_ptr1 +=0xA0; /* Write HDMI C EDIDF 256 (0x100) byte */ for (i = 0; i < 0x40; i++) { writel(0x100+i,0xbe060134); writel(data_ptr1[i], 0xbe060138); writeb(0x1, 0xbe06012c); } /* Enable EDID after initial done */ writel( 0x000603a1,0xbe060024); //HDMI A writel( 0x000603a1,0xbe060030); //HDMI B writel( 0x000603a1,0xbe060124); //HDMI C HDMI_DelayMs(HDMI_HPD_L2H_DELAY); hdmi_apply_hpd_by5V(DRV_HDMI_PORT_ALL); } if(Atmos_Mode !=CurATMOS_MODE) { CurATMOS_MODE = Atmos_Mode; if(data_ptr != NULL) kfree(data_ptr); } } #endif static struct cdev hdmirx_cdev; static INT32 hdmirx_devno; INT32 DRV_HDMI_Init(void) { hdmidbg("%s\n", __FUNCTION__); hdmidbg("*** HDMI Mapping Information ***\n"); hdmidbg("\tProject:HDMISwitchMap 0x%02x HDMIPortMap 0x%08x\n", CONFIG_HDMI_SWITCH, CONFIG_HDMI_PORT_MAP); /* Decrypt hdcp key */ DRV_HDMI_UpdateHDCPKey((UINT8*)SPI_HDCPKEY_FLASHADDR); /* Init each blocks */ hdmi_mapping_init(); /* hdmi source and hw port mapping */ hdmi_hpd_init(); /* hot plug detect and related patch */ hdmi_processing_init(); /* signal processing block */ /* Init working queues */ INIT_WORK(&wq_chlock, (work_func_t) HDMI_Audio_ChannelLocked); #ifdef CONFIG_HDMI_HW_PATCH_FOR_HDCP_COLOR_SNOW INIT_WORK(&wq_ToggleHPD, (work_func_t) HDMI_Toggle_HPD); #endif INIT_WORK(&wq_Enable_InRange, (work_func_t) HDMI_Enable_InRange); #ifdef USE_HW_ADAPTIVE_EQ INIT_DELAYED_WORK(&wq_Enable_DCK, (work_func_t) HDMI_Enable_DCK); #endif /* Register interrupts handler */ set_vi_handler(IRQ_HDMI, (vi_handler_t) hdmi_dispatch); setup_irq(IRQ_HDMI, &hdmi_irqaction); /* Driver device node */ hdmirx_devno = MKDEV(HDMI_DEV_MAJOR, 0); if (register_chrdev_region(hdmirx_devno, 0, HDMIRXDRV_DEVNAME)) { return -EIO; } cdev_init(&hdmirx_cdev, &hdmi_fops); hdmirx_cdev.owner = THIS_MODULE; hdmirx_cdev.ops = &hdmi_fops; if (cdev_add(&hdmirx_cdev, hdmirx_devno, 1)) { return -EIO; } /* Set up related global system registers */ sysset_hdmi_stcInitValue(0x0); /* Initialize STC value */ sysset_hdmi_stcclk(); /* Enable HDMI STC clock */ sysset_hdmi_tmdsclk(true); /* Disable HDMI PD */ sysset_HDMI_HPD_1K_Init(); sysset_HDMI_EN_AVI_V3(true); HDMI_RegisterWrite(HDMIRX_R_ref_length, 0x180); HDMI_RegisterWrite(HDMIRX_R_DDC5V_reset, 0); HDMI_RegisterWrite(HDMIRX_R_inactive_level, 0x19); HDMI_RegisterWrite(HDMIRX_R_half_quarter_HT, 0); HDMI_RegisterWrite(HDMIRX_R_phy_freq_det, 0x0); HDMI_RegisterWrite(HDMIRX_R_inter_alignment_once, 0x0); HDMI_RegisterWrite(HDMIRX_R_stable_time, 0x120000);//Can not set too long for MHL Samsung Note3 HDMI_RegisterWrite(HDMIRX_R_Clear_mute_timer, 1); // CLEAR_MUTE_TIMER; HDMI_RegisterWrite(HDMIRX_R_clear_ACP_timer, 0xff); // CLEAR_ACP_TIMER; HDMI_RegisterWrite(HDMIRX_R_system_clk_cnt, 0xff); HDMI_RegisterWrite(HDMIRX_Soft_Clear_Mute, 0); HDMI_RegisterWrite(HDMIRX_R_subpacket_identical_en, 1); HDMI_RegisterWrite(HDMIRX_R_subpacket_identical_en2, 1); HDMI_RegisterWrite(HDMIRX_R_REALIGN_EN, 3); HDMI_RegisterWrite(HDMIRX_R_frame_cnt30, 1); //HDMI_RegisterWrite(HDMIRX_R_AUTO_CSC, 0); //not available in 531 HDMI_RegisterWrite(HDMIRX_R_FIELD_POL, 0); //HDMI_RegisterWrite(HDMIRX_R_out_sel, 1); //not available in 531 HDMI_RegisterWrite(HDMIRX_R_PR_EN, 1); HDMI_RegisterWrite(HDMIRX_R_InterCA_TH, 0x2); HDMI_RegisterWrite(HDMIRX_R_ALIGN_CNT, 0x4); //HDMI_RegisterWrite(HDMIRX_R_ALIGN_CNT, 0xF); HDMI_RegisterWrite(HDMIRX_R_freq_stable_th, 0x06); HDMI_RegisterWrite(HDMIRX_R_freq_unstable_th, 0x06); HDMI_RegisterWrite(HDMIRX_R_freq_stable_th, 0x08); HDMI_RegisterWrite(HDMIRX_R_auto_phypd, 0); // Don't automatically disable phy when hdmi logic is disabled HDMI_RegisterWrite(HDMIRX_R_REALIGN_TIMER1, 0x1e); // retry condition without symbol lock. HDMI_RegisterWrite(HDMIRX_R_REALIGN_TIMER2, 0x06); // inactive condition with symbol lock. HDMI_RegisterWrite(HDMIRX_R_HDMI_level, 0x14); HDMI_RegisterWrite(HDMIRX_EQ_VAL_FIX, 0x1); HDMI_RegisterWrite(CTRLI_631_600__DW_0430,0x77722077); HDMI_RegisterWrite(CTRLI_663_632__DW_0434,0x20777220); HDMI_RegisterWrite(CTRLI_695_664__DW_0438,0x00000072); #ifdef USE_HW_ADAPTIVE_EQ HDMI_Adaptive_EQ_Init(); #endif /* [0] ht, [1] vt, [2] disp, [3] de, [4] interlace */ HDMI_RegisterWrite(HDMIRX_R_LEVEL, 8); /* Settings for pixel color conversion */ HDMI_RegisterWrite(HDMIRX_R_DnSAMPLING_EN, 0); /* Black screen color setting */ HDMI_RegisterWrite(HDMIRX_R_AVMUTE_blk_screen, 1); HDMI_RegisterWrite(HDMIRX_R_auto_blk_msb, 1); HDMI_RegisterWrite(HDMIRX_R_rst_n, 0); /* Disable hdmi logic */ //HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 4); //HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 8); HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT2, 0xF);//For Silicon Image MHL Starter KIT-9244 //HDMI_RegisterWrite(HDMIRX_r_disable_unlock_mhl, 1); HDMI_RegisterWrite(HDMIRX_R_BYTE_ALIGN_CNT1, 4); HDMI_RegisterWrite(HDMIRX_R_strict_symlock_a, 1); HDMI_RegisterWrite(HDMIRX_R_pre_align_chk_a, 1); //// HDMI_RegisterWrite(HDMIRX_PHY_DIV_RESETJ, 0); HDMI_RegisterWrite(HDMIRX_HDMIRX_CDRRSTJ_CTL, 0); HDMI_RegisterWrite(HDMIRX_icrst_n, 0); //// //*((u8 *)0xbe000214) = (*((u8 *)0xbe000214) &0x0F) | 0x80 ; sysset_HDMI_Downscale(1); /* Init external hdmi switch */ hdmi_switch_init(); #ifndef INIT_BY_KMF DRV_HDMI_Power(1); DRV_HDMI_Enable(0); #else DRV_HDMI_Power(0); #endif DRV_CEC_Init(); #ifdef CONFIG_HDMI_SUPPORT_MHL #ifdef CONFIG_HDMI_MHL_PORT if(CONFIG_HDMI_MHL_PORT==0) { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 0);//Support MHL in Port:A sysset_cbus_port_sel(HDMI_PORT_A); DRV_HDMI_Enable(0); } else if(CONFIG_HDMI_MHL_PORT==1) { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 1);//Support MHL in Port:B sysset_cbus_port_sel(HDMI_PORT_B); DRV_HDMI_Enable(1); } else //Error Case: Not config MHL in correct port(0 or 1) , Set to 3(Null port) and let A and B keep in HDMI Mode { HDMI_RegisterWrite(HDMIRX_R_mhl_port_sel, 3);//Let A and B keep in HDMI Mode } #endif if(MHL_CBUS_Init==FALSE) { MHL_CBUS_Initial(); MHL_CBUS_Init=TRUE; } /* Start MHL CBUS Work */ MHL_CBUS_Work_Enable(TRUE); DRV_HDMI_Disable(); #else sysset_VbusEnable(0); #endif HDMI_Init=TRUE; return 0; } void DRV_HDMI_Exit(void) { hdmidbg("%s\n", __FUNCTION__); /* Disable hdmi */ DRV_HDMI_Disable(); /* Exit cec driver */ DRV_CEC_Exit(); /* Remove device node */ cdev_del(&hdmirx_cdev); unregister_chrdev_region(hdmirx_devno, 0); return; } UINT32 hdmi_clk_flag=0; void DRV_HDMI_Power(BOOL bPwr) { hdmidbg("%s(%s)\n", __FUNCTION__, bPwr ? "on" :"off"); if (bPwr) { /* Enable HDMI Clock PD */ sysset_hdmi_tmdsclk(false); if ( hdmi_clk_flag == 0 ) { drv_gated_clk_ctrl(GATED_F24MCLK_HDMI, GATED_PASS_CLK); drv_gated_clk_ctrl(GATED_MCLK_HDMI, GATED_PASS_CLK); hdmi_clk_flag = 1; } } else { /* Disable hdmi */ DRV_HDMI_Disable(); /* Disable HDMI Clock PD */ sysset_hdmi_tmdsclk(true); #ifndef CONFIG_HDMI_SUPPORT_MHL //do not turn off HDMI power for MHL application if ( hdmi_clk_flag == 1 ) { drv_gated_clk_ctrl(GATED_F24MCLK_HDMI, GATED_STOP_CLK); drv_gated_clk_ctrl(GATED_MCLK_HDMI, GATED_STOP_CLK); hdmi_clk_flag = 0; } #endif } /* Power up/down hdmi switch */ hdmi_switch_power(bPwr); } void DRV_HDMI_IR_PowerOff(void) { /* Disable hdmi */ DRV_HDMI_Disable(); HDMI_Set_PLL_Mode(HDMI_PLL_MODE_OFF); /* Disable HDMI Clock PD */ sysset_hdmi_tmdsclk(true); #ifndef CONFIG_HDMI_SUPPORT_MHL drv_gated_clk_ctrl(GATED_F24MCLK_HDMI, GATED_STOP_CLK); drv_gated_clk_ctrl(GATED_MCLK_HDMI, GATED_STOP_CLK); #endif /* Power up/down hdmi switch */ hdmi_switch_power(FALSE); } #ifndef INIT_BY_KMF module_init(DRV_HDMI_Init); module_exit(DRV_HDMI_Exit); #endif MODULE_LICENSE("Dual BSD/GPL");