int ddp_mutex_hw_dcm_off(int mutex_idx,void * handle) { if(gMutexFreeRun==1 && primary_display_is_video_mode()==0 && mutex_idx==0) { DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_HW_DCM,0); } DDPDBG("mutex %d hw_dcm 0x%x \n", mutex_idx, DISP_REG_GET(DISP_REG_CONFIG_MUTEX_HW_DCM)); return 0; }
static int ddp_mutex_set_l(int mutex_id, int* module_list, DDP_MODE ddp_mode, void * handle) { int i=0; kal_uint32 value = 0; int module_num = ddp_get_module_num_l(module_list); MUTEX_SOF mode = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode); if(mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) { DDPERR("exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST); return -1; } for(i = 0 ; i < module_num ; i++) { if(module_mutex_map[module_list[i]].bit != -1) { DDPDBG("module %s added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id); value |= (1 << module_mutex_map[module_list[i]].bit); } else { DDPDBG("module %s not added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id); } } DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),mode); // for primary config thread, save more time for register config if(gEnableMutexRisingEdge==1 && primary_display_is_video_mode()==1 && mutex_id==0) { DISP_REG_SET_FIELD(handle, SOF_FLD_MUTEX0_SOF_TIMING, DISP_REG_CONFIG_MUTEX0_SOF, 1); } if(gEnableSWTrigger==1 && primary_display_is_video_mode()==1 && mutex_id==0) { // set OVL0/OVL1 to separate mutex DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(DISP_OVL_SEPARATE_MUTEX_ID),value&((1 << module_mutex_map[DISP_MODULE_OVL0].bit)|(1 << module_mutex_map[DISP_MODULE_OVL1].bit))); DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(DISP_OVL_SEPARATE_MUTEX_ID), SOF_SINGLE); // move OVL0/OVL1 out from primary path DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value&(~((1 << module_mutex_map[DISP_MODULE_OVL0].bit)|(1 << module_mutex_map[DISP_MODULE_OVL1].bit)))); } DDPDBG("mutex %d value=0x%x, sof=%s\n",mutex_id, value, ddp_get_mutex_sof_name(mode)); return 0; }
int ddp_insert_config_dirty_rec(void *handle) { int ret = 0; if(handle == NULL) { ASSERT(0); } if(primary_display_is_video_mode()) // TODO: modify this { //do nothing } else { ret = cmdqRecSetEventToken(handle, CMDQ_SYNC_TOKEN_CONFIG_DIRTY); } return ret; }
int ddp_insert_config_allow_rec(void *handle) { int ret = 0; if(handle == NULL) { ASSERT(0); } if(primary_display_is_video_mode()) { ret = cmdqRecWaitNoClear(handle, CMDQ_EVENT_MUTEX0_STREAM_EOF); } else { ret = cmdqRecWaitNoClear(handle, CMDQ_SYNC_TOKEN_STREAM_EOF); } return ret; }
void mt_disp_update(UINT32 x, UINT32 y, UINT32 width, UINT32 height) { { unsigned int va = fb_addr; dprintf(0,"fb dump: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", *(unsigned int*)va, *(unsigned int*)(va+4), *(unsigned int*)(va+8), *(unsigned int*)(va+0xC)); } arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize()); primary_display_trigger(TRUE); if(!primary_display_is_video_mode()) { /*video mode no need to wait*/ mdelay(30); } /* // TODO: Fixit!!!!! if(fb_isdirty) { fb_isdirty = 0; MASKREG32(0x1400E000, 0x1, 0x1); //Enable DISP MUTEX0 MASKREG32(0x1400E004, 0x1, 0x0); LCD_CHECK_RET(LCD_LayerSetAddress(FB_LAYER - 1, (UINT32)fb_addr + fb_offset_logo * fb_size)); printk("[wwy] hardware address = %x, fb_offset_logo = %d\n",(UINT32)fb_addr + fb_offset_logo * fb_size,fb_offset_logo); arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize()); DISP_CHECK_RET(DISP_UpdateScreen(x, y, width, height)); //wait reg update to set fb_offset_logo DISP_WaitRegUpdate(); fb_offset_logo = fb_offset_logo ? 0 : 3; } else { arch_clean_cache_range((unsigned int)fb_addr, DISP_GetFBRamSize()); DISP_CHECK_RET(DISP_UpdateScreen(x, y, width, height)); } */ }
irqreturn_t disp_irq_handler(int irq, void *dev_id) { DISP_MODULE_ENUM module = DISP_MODULE_UNKNOWN; unsigned long reg_val = 0; unsigned int index = 0; unsigned int mutexID = 0; unsigned long reg_temp_val = 0; DDPDBG("disp_irq_handler, irq=%d, module=%s \n", irq, disp_irq_module(irq)); MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagStart, irq, 0); //switch(irq) { if(irq==dispsys_irq[DISP_REG_DSI0]) { module = DISP_MODULE_DSI0; reg_val = (DISP_REG_GET(dsi_reg_va + 0xC) & 0xff); if(atomic_read(&ESDCheck_byCPU) == 0) { reg_temp_val=reg_val&0xfffe;//rd_rdy don't clear and wait for ESD & Read LCM will clear the bit. DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_temp_val); } else { DISP_CPU_REG_SET(dsi_reg_va + 0xC, ~reg_val); } MMProfileLogEx(ddp_mmp_get_events()->DSI_IRQ[0], MMProfileFlagPulse, reg_val, 0); } else if(irq==dispsys_irq[DISP_REG_OVL0] || irq==dispsys_irq[DISP_REG_OVL1]) { index = (irq==dispsys_irq[DISP_REG_OVL0]) ? 0 : 1; module= (irq==dispsys_irq[DISP_REG_OVL0]) ? DISP_MODULE_OVL0 : DISP_MODULE_OVL1; reg_val = DISP_REG_GET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET); if(reg_val&(1<<1)) { DDPIRQ("IRQ: OVL%d frame done! \n",index); ovl_complete_irq_cnt[index]++; // update OVL addr { unsigned int i = 0; if(index==0) { for(i=0;i<4;i++) { if(DISP_REG_GET(DISP_REG_OVL_SRC_CON)&(0x1<<i)) MMProfileLogEx(ddp_mmp_get_events()->layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+i*0x20), 0); } } if(index==1) { for(i=0;i<4;i++) { if(DISP_REG_GET(DISP_REG_OVL_SRC_CON+DISP_OVL_INDEX_OFFSET)&(0x1<<i)) MMProfileLogEx(ddp_mmp_get_events()->ovl1_layer[i], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR+DISP_OVL_INDEX_OFFSET+i*0x20), 0); } } } } if(reg_val&(1<<2)) { //DDPERR("IRQ: OVL%d frame underrun! cnt=%d \n",index, cnt_ovl_underflow[index]++); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<3)) { DDPIRQ("IRQ: OVL%d sw reset done\n",index); } if(reg_val&(1<<4)) { DDPIRQ("IRQ: OVL%d hw reset done\n",index); } if(reg_val&(1<<5)) { DDPERR("IRQ: OVL%d-L0 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<6)) { DDPERR("IRQ: OVL%d-L1 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<7)) { DDPERR("IRQ: OVL%d-L2 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<8)) { DDPERR("IRQ: OVL%d-L3 not complete untill EOF!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<9)) { //DDPERR("IRQ: OVL%d-L0 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<10)) { //DDPERR("IRQ: OVL%d-L1 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<11)) { //DDPERR("IRQ: OVL%d-L2 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } if(reg_val&(1<<12)) { //DDPERR("IRQ: OVL%d-L3 fifo underflow!\n",index); //disp_irq_log_module |= 1<<module; } //clear intr if(reg_val&(0xf<<5)) { ddp_dump_analysis(DISP_MODULE_CONFIG); if(index==0) { ddp_dump_analysis(DISP_MODULE_OVL1); ddp_dump_analysis(DISP_MODULE_OVL0); ddp_dump_analysis(DISP_MODULE_COLOR0); ddp_dump_analysis(DISP_MODULE_AAL); ddp_dump_analysis(DISP_MODULE_RDMA0); } else { ddp_dump_analysis(DISP_MODULE_OVL1); ddp_dump_analysis(DISP_MODULE_RDMA1); ddp_dump_reg(DISP_MODULE_CONFIG); } } DISP_CPU_REG_SET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET, ~reg_val); MMProfileLogEx(ddp_mmp_get_events()->OVL_IRQ[index], MMProfileFlagPulse, reg_val, 0); if(reg_val&0x1e0) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, module<<24); } } else if(irq==dispsys_irq[DISP_REG_WDMA0] || irq==dispsys_irq[DISP_REG_WDMA1]) { index = (irq==dispsys_irq[DISP_REG_WDMA0]) ? 0 : 1; module =(irq==dispsys_irq[DISP_REG_WDMA0]) ? DISP_MODULE_WDMA0 : DISP_MODULE_WDMA1; reg_val = DISP_REG_GET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET); if(reg_val&(1<<0)) { DDPIRQ("IRQ: WDMA%d frame done!\n",index); } if(reg_val&(1<<1)) { DDPERR("IRQ: WDMA%d underrun! cnt=%d\n",index,cnt_wdma_underflow[index]++); disp_irq_log_module |= 1<<module; } //clear intr DISP_CPU_REG_SET(DISP_REG_WDMA_INTSTA+index*DISP_WDMA_INDEX_OFFSET,~reg_val); MMProfileLogEx(ddp_mmp_get_events()->WDMA_IRQ[index], MMProfileFlagPulse, reg_val, DISP_REG_GET(DISP_REG_WDMA_CLIP_SIZE)); if(reg_val&0x2) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, cnt_wdma_underflow[index]|(module<<24)); } } else if(irq==dispsys_irq[DISP_REG_RDMA0] || irq==dispsys_irq[DISP_REG_RDMA1]) { if(dispsys_irq[DISP_REG_RDMA0]==irq) { index = 0; module = DISP_MODULE_RDMA0; } else if(dispsys_irq[DISP_REG_RDMA1]==irq) { index = 1; module = DISP_MODULE_RDMA1; } reg_val = DISP_REG_GET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET); if(reg_val&(1<<0)) { DDPIRQ("IRQ: RDMA%d reg update done! \n",index); } if(reg_val&(1<<1)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagStart, reg_val, DISP_REG_GET(DISP_REG_RDMA_MEM_START_ADDR)); rdma_start_time[index]= sched_clock(); DDPIRQ("IRQ: RDMA%d frame start! \n",index); rdma_start_irq_cnt[index]++; // rdma start/end irq should equal, else need reset ovl if(gResetRDMAEnable == 1 && is_hwc_enabled == 1 && index ==0 && primary_display_is_video_mode()==1 && rdma_start_irq_cnt[0] > rdma_done_irq_cnt[0]+3) { ovl_reset(DISP_MODULE_OVL0, NULL); if(ovl_get_status()!=DDP_OVL1_STATUS_SUB) { ovl_reset(DISP_MODULE_OVL1, NULL); } rdma_done_irq_cnt[0] = rdma_start_irq_cnt[0]; DDPERR("warning: reset ovl!\n"); } #ifdef CONFIG_MTK_SEGMENT_TEST if(record_rdma_end_interval == 1) { if(rdma_end_begin_time == 0) { rdma_end_begin_time = sched_clock(); //printk("[display_test]====RDMA frame end time1:%lld\n",rdma_end_begin_time); } else { unsigned long long time_now = sched_clock(); //printk("[display_test]====RDMA frame end time2:%lld\n",time_now); //printk("[display_test]====RDMA frame end time3:this=%lld,max=%lld,min=%lld\n",time_now - rdma_end_begin_time,rdma_end_max_interval,rdma_end_min_interval); if((time_now - rdma_end_begin_time) > rdma_end_max_interval) { rdma_end_max_interval = time_now - rdma_end_begin_time; } if((time_now - rdma_end_begin_time) < rdma_end_min_interval) { rdma_end_min_interval = time_now - rdma_end_begin_time; } rdma_end_begin_time = time_now; } } #endif } if(reg_val&(1<<2)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagEnd, reg_val, 0); rdma_end_time[index]= sched_clock(); DDPIRQ("IRQ: RDMA%d frame done! \n",index); //rdma_done_irq_cnt[index] ++; rdma_done_irq_cnt[index] = rdma_start_irq_cnt[index]; } if(reg_val&(1<<3)) { DDPERR("IRQ: RDMA%d abnormal! cnt=%d \n",index, cnt_rdma_abnormal[index]++); disp_irq_log_module |= 1<<module; } if(reg_val&(1<<4)) { DDPERR("IRQ: RDMA%d underflow! cnt=%d \n",index, cnt_rdma_underflow[index]++); disp_irq_log_module |= 1<<module; rdma_underflow_irq_cnt[index]++; } if(reg_val&(1<<5)) { DDPIRQ("IRQ: RDMA%d target line! \n",index); rdma_targetline_irq_cnt[index]++; } //clear intr DISP_CPU_REG_SET(DISP_REG_RDMA_INT_STATUS+index*DISP_RDMA_INDEX_OFFSET,~reg_val); MMProfileLogEx(ddp_mmp_get_events()->RDMA_IRQ[index], MMProfileFlagPulse, reg_val, 0); if(reg_val&0x18) { MMProfileLogEx(ddp_mmp_get_events()->ddp_abnormal_irq, MMProfileFlagPulse, (index<<16)|reg_val, rdma_underflow_irq_cnt[index]|(cnt_rdma_abnormal[index]<<8)||(module<<24)); } } else if(irq==dispsys_irq[DISP_REG_COLOR]) { } else if(irq==dispsys_irq[DISP_REG_MUTEX]) { // mutex0: perimary disp // mutex1: sub disp // mutex2: aal module = DISP_MODULE_MUTEX; reg_val = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_INTSTA) & 0x7C1F; for(mutexID = 0; mutexID<5; mutexID++) { if(reg_val & (0x1<<mutexID)) { DDPIRQ("IRQ: mutex%d sof!\n",mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 0); } if(reg_val & (0x1<<(mutexID+DISP_MUTEX_TOTAL))) { DDPIRQ("IRQ: mutex%d eof!\n",mutexID); MMProfileLogEx(ddp_mmp_get_events()->MUTEX_IRQ[mutexID], MMProfileFlagPulse, reg_val, 1); } } DISP_CPU_REG_SET(DISP_REG_CONFIG_MUTEX_INTSTA, ~reg_val); } else if(irq==dispsys_irq[DISP_REG_AAL]) { module = DISP_MODULE_AAL; reg_val = DISP_REG_GET(DISP_AAL_INTSTA); disp_aal_on_end_of_frame(); } else if(irq==dispsys_irq[DISP_REG_CONFIG]) // MMSYS error intr { reg_val = DISP_REG_GET(DISP_REG_CONFIG_MMSYS_INTSTA) & 0x7; if(reg_val&(1<<0)) { DDPERR("MMSYS to MFG APB TX Error, MMSYS clock off but MFG clock on! \n"); } if(reg_val&(1<<1)) { DDPERR("MMSYS to MJC APB TX Error, MMSYS clock off but MJC clock on! \n"); } if(reg_val&(1<<2)) { DDPERR("PWM APB TX Error! \n"); } DISP_CPU_REG_SET(DISP_REG_CONFIG_MMSYS_INTSTA, ~reg_val); } else { module = DISP_MODULE_UNKNOWN; reg_val = 0; DDPERR("invalid irq=%d \n ", irq); } } disp_invoke_irq_callbacks(module, reg_val); if(disp_irq_log_module!=0) { wake_up_interruptible(&disp_irq_log_wq); } MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagEnd, irq, reg_val); return IRQ_HANDLED; }