/* set ovl1 status */ void ovl_set_status(DISP_OVL1_STATUS status) { DDPMSG("cascade, set_ovl1 from %s to %s!\n", ovl_get_status_name(ovl1_status), ovl_get_status_name(status)); MMProfileLogEx(ddp_mmp_get_events()->ovl1_status, MMProfileFlagPulse, ovl1_status, status); ovl1_status = status; /* atomic operation */ }
int ext_disp_trigger(int blocking, void *callback, unsigned int userdata) { int ret = 0; EXT_DISP_FUNC(); if((is_hdmi_active() == false)|| pgc->state == EXTD_DEINIT || pgc->state == EXTD_SUSPEND || pgc->need_trigger_overlay < 1) { EXT_DISP_LOG("trigger ext display is already sleeped\n"); MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Trigger, 0); return -1; } _ext_disp_path_lock(); if(_should_trigger_interface()) { _trigger_display_interface(blocking, callback, userdata); } else { _trigger_overlay_engine(); } pgc->state = EXTD_RESUME; _ext_disp_path_unlock(); EXT_DISP_LOG("ext_disp_trigger done \n"); return ret; }
void dprec_reg_op(void* cmdq, unsigned int reg, unsigned int val, unsigned int mask) { int len = 0; if(!cmdq && !in_interrupt()) MMProfileLogEx(ddp_mmp_get_events()->dprec_cpu_write_reg, MMProfileFlagPulse, reg, val); if(cmdq) { if(mask) { DISPPR_HWOP("%s/0x%08x/0x%08x=0x%08x&0x%08x\n", _find_module_by_reg_addr(reg), (unsigned int)cmdq, reg, val ,mask); } else { DISPPR_HWOP("%s/0x%08x/0x%08x=0x%08x\n", _find_module_by_reg_addr(reg), (unsigned int)cmdq, reg, val); } } else { if(!in_interrupt()) { if(mask) { DISPDBG("%s/%08x=%08x&%08x\n", _find_module_by_reg_addr(reg), reg, val ,mask); } else { DISPDBG("%s/%08x=%08x\n", _find_module_by_reg_addr(reg), reg, val); } } } if(_control.overall_switch == 0) { return; } len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "[DPREC]"); len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "[%s]", _find_module_by_reg_addr(reg)); len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "[%s]", cmdq?"CMDQ":"CPU"); if(cmdq) len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "[0x%08x]", cmdq); len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "0x%08x=0x%08x", reg, val); if(mask) len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "&0x%08x", mask); len += scnprintf(dprec_string_buffer+len, dprec_string_max_length - len, "\n"); printk(dprec_string_buffer); if(_control.cmm_dump) { printk("[CMM]D.S SD:0x%08x %\LE %\LONG 0x%08x; write %s\n", (_control.cmm_dump_use_va)?reg:(reg&0x1fffffff), mask?(val|mask):val,_find_module_by_reg_addr(reg)); }
void dprec_logger_event_init(dprec_logger_event *p, char *name, uint32_t level, MMP_Event *mmp_root) { if(p) { scnprintf(p->name, sizeof(p->name)/sizeof(p->name[0]), name); if(mmp_root) p->mmp = MMProfileRegisterEvent(mmp_root, name); else p->mmp = MMProfileRegisterEvent(ddp_mmp_get_events()->DDP, name); MMProfileEnableEventRecursive(p->mmp, 1); p->level = level; memset((void*)&p->logger, 0, sizeof(p->logger)); DISPMSG("dprec logger event init, name=%s, level=0x%08x\n", name, level); } }
static int _trigger_display_interface(int blocking, void *callback, unsigned int userdata) { ///EXT_DISP_FUNC(); int i = 0; bool reg_flush = false; if(_should_wait_path_idle()) { dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2); } if(_should_update_lcm()) { extd_drv_update(pgc->plcm, 0, 0, pgc->plcm->params->width, pgc->plcm->params->height, 0); } if(_should_start_path()) { reg_flush = true; dpmgr_path_start(pgc->dpmgr_handle, ext_disp_cmdq_enabled()); MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagPulse, Trigger, 1); } if(_should_trigger_path()) { // trigger_loop_handle is used only for build trigger loop, which should always be NULL for config thread dpmgr_path_trigger(pgc->dpmgr_handle, NULL, ext_disp_cmdq_enabled()); } if(_should_set_cmdq_dirty()) { _cmdq_set_config_handle_dirty(); } ///if(reg_flush == false) { #if 0 if(reg_flush == false) { if(_should_insert_wait_frame_done_token()) { _cmdq_insert_wait_frame_done_token(); } } if(_should_flush_cmdq_config_handle()) { _cmdq_flush_config_handle(reg_flush); } if(_should_reset_cmdq_config_handle()) { _cmdq_reset_config_handle(); } if(reg_flush == true) { if(_should_insert_wait_frame_done_token()) { _cmdq_insert_wait_frame_done_token(); } } ///cmdqRecDumpCommand(cmdqRecHandle handle) #else if(_should_flush_cmdq_config_handle()) { if(reg_flush) { MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagPulse, Trigger, 2); } if(_should_start_path()) { EXT_DISP_LOG("Wait Main Display Vsync\n"); disp_session_vsync_config vsync_config; primary_display_wait_for_vsync(&vsync_config); } _cmdq_flush_config_handle(blocking, callback, userdata); } if(_should_reset_cmdq_config_handle()) { _cmdq_reset_config_handle(); } if(_should_insert_wait_frame_done_token()) { _cmdq_insert_wait_frame_done_token(); } #endif } return 0; }
int ext_disp_config_input_multiple(ext_disp_input_config* input, int idx) { int ret = 0; int i=0; int layer =0; ///EXT_DISP_FUNC(); disp_ddp_path_config *data_config; if((is_hdmi_active() == false) || (pgc->state != EXTD_INIT && pgc->state != EXTD_RESUME) ) { EXT_DISP_LOG("[Donglei]config ext disp is already sleeped, hdmi_active:%d, state:%d\n", is_hdmi_active(), pgc->state); MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Config, idx ); return -2; } _ext_disp_path_lock(); // all dirty should be cleared in dpmgr_path_get_last_config() data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle); // hope we can use only 1 input struct for input config, just set layer number if(_should_config_ovl_input()) { for(i = 0;i<HW_OVERLAY_COUNT;i++) { if(input[i].dirty) { ret = _convert_disp_input_to_ovl(&(data_config->ovl_config[input[i].layer]), &input[i]); dprec_mmp_dump_ovl_layer(&(data_config->ovl_config[input[i].layer]), input[i].layer, 2); } if (init_roi == 1) { LCM_PARAMS *lcm_param = extd_drv_get_params(pgc->plcm); memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS)); if(lcm_param != NULL) { EXT_DISP_LOG("set dest w:%d, h:%d\n", lcm_param->width, lcm_param->height); data_config->dst_w = lcm_param->width; data_config->dst_h = lcm_param->height; } data_config->dst_dirty = 1; data_config->rdma_config.address = 0; } data_config->ovl_dirty = 1; } } else { OVL_CONFIG_STRUCT ovl_config; _convert_disp_input_to_ovl(&ovl_config, input); dprec_mmp_dump_ovl_layer(&ovl_config, input->layer, 2); ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), input); if (data_config->rdma_config.address) { data_config->rdma_dirty = 1; } } if(_should_wait_path_idle()) { dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2); } memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS)); ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, ext_disp_cmdq_enabled()? pgc->cmdq_handle_config : NULL); // this is used for decouple mode, to indicate whether we need to trigger ovl pgc->need_trigger_overlay = 1; init_roi = 0; _ext_disp_path_unlock(); if (data_config->ovl_dirty) { EXT_DISP_LOG("config_input_multiple idx:%d -w:%d, h:%d, pitch:%d\n", idx ,data_config->ovl_config[0].src_w, data_config->ovl_config[0].src_h, data_config->ovl_config[0].src_pitch); }else{ EXT_DISP_LOG("config_input_multiple idx:%d -w:%d, h:%d, pitch:%d, mva:%p\n", idx ,data_config->rdma_config.width, data_config->rdma_config.height, data_config->rdma_config.pitch, data_config->rdma_config.address); } return ret; }
static MMP_Event dprec_mmp_event_spy(DPREC_LOGGER_ENUM l) { switch(l&0xffffff) { case DPREC_LOGGER_PRIMARY_MUTEX: return ddp_mmp_get_events()->primary_sw_mutex; case DPREC_LOGGER_PRIMARY_TRIGGER: return ddp_mmp_get_events()->primary_trigger; case DPREC_LOGGER_PRIMARY_CONFIG: return ddp_mmp_get_events()->primary_config; case DPREC_LOGGER_PRIMARY_CMDQ_SET_DIRTY: return ddp_mmp_get_events()->primary_set_dirty; case DPREC_LOGGER_PRIMARY_CMDQ_FLUSH: return ddp_mmp_get_events()->primary_cmdq_flush; case DPREC_LOGGER_DISPMGR_PREPARE: return ddp_mmp_get_events()->session_prepare; case DPREC_LOGGER_DISPMGR_SET_INPUT: return ddp_mmp_get_events()->session_set_input; case DPREC_LOGGER_DISPMGR_TRIGGER: return ddp_mmp_get_events()->session_trigger; case DPREC_LOGGER_DISPMGR_RELEASE: return ddp_mmp_get_events()->session_release; case DPREC_LOGGER_DISPMGR_WAIT_VSYNC: return ddp_mmp_get_events()->session_wait_vsync; case DPREC_LOGGER_DISPMGR_CACHE_SYNC: return ddp_mmp_get_events()->primary_cache_sync; } return 0xffff; }
DAL_STATUS DAL_Printf(const char *fmt, ...) { va_list args; uint i; DAL_STATUS ret = DAL_STATUS_OK; printk("%s", __func__); //printk("[MTKFB_DAL] DAL_Printf mfc_handle=0x%08X, fmt=0x%08X\n", mfc_handle, fmt); if (NULL == mfc_handle) return DAL_STATUS_NOT_READY; if (NULL == fmt) return DAL_STATUS_INVALID_ARGUMENT; MMProfileLogEx(ddp_mmp_get_events()->dal_printf, MMProfileFlagStart, 0, 0); DAL_LOCK(); if(isAEEEnabled==0) { printk("[DDP] isAEEEnabled from 0 to 1, ASSERT_LAYER=%d, dal_fb_pa %lx\n", ASSERT_LAYER, dal_fb_pa); isAEEEnabled = 1; DAL_Dynamic_Change_FB_Layer(isAEEEnabled); // default_ui_ layer coniig to changed_ui_layer DAL_CHECK_MFC_RET(MFC_Open(&mfc_handle, dal_fb_addr, DAL_WIDTH, DAL_HEIGHT, DAL_BPP, DAL_FG_COLOR, DAL_BG_COLOR)); //DAL_Clean(); primary_disp_input_config input; memset((void*)&input, 0, sizeof(primary_disp_input_config)); input.addr = (unsigned long)dal_fb_pa; input.layer = primary_display_get_option("ASSERT_LAYER"); input.layer_en = 1; input.src_x = 0; input.src_y = 0; input.src_w = DAL_WIDTH; input.src_h = DAL_HEIGHT; input.dst_x = 0; input.dst_y = 0; input.dst_w = DAL_WIDTH; input.dst_h = DAL_HEIGHT; input.alpha = 0x80; input.aen = 1; input.buff_idx = -1; input.src_pitch = DAL_WIDTH * DAL_BPP; input.isDirty = 1; input.fmt = DAL_FORMAT; ret = primary_display_config_input(&input); } va_start (args, fmt); i = vsprintf(dal_print_buffer, fmt, args); BUG_ON(i>=ARRAY_SIZE(dal_print_buffer)); va_end (args); DAL_CHECK_MFC_RET(MFC_Print(mfc_handle, dal_print_buffer)); flush_cache_all(); /* if (LCD_STATE_POWER_OFF == LCD_GetState()) { ret = DAL_STATUS_LCD_IN_SUSPEND; dal_enable_when_resume = TRUE; goto End; } */ #if 0 if(is_early_suspended){ up(&sem_early_suspend); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DAL", "DAL_Printf in power off\n"); goto End; } #endif if (!dal_shown) { dal_shown = TRUE; } ret = primary_display_trigger(0, NULL, 0); End: DAL_UNLOCK(); MMProfileLogEx(ddp_mmp_get_events()->dal_printf, MMProfileFlagEnd, 0, 0); return ret; }
DAL_STATUS DAL_Clean(void) { const UINT32 BG_COLOR = MAKE_TWO_RGB565_COLOR(DAL_BG_COLOR, DAL_BG_COLOR); DAL_STATUS ret = DAL_STATUS_OK; static int dal_clean_cnt = 0; MFC_CONTEXT *ctxt = (MFC_CONTEXT *)mfc_handle; printk("[MTKFB_DAL] DAL_Clean\n"); if (NULL == mfc_handle) return DAL_STATUS_NOT_READY; // if (LCD_STATE_POWER_OFF == LCD_GetState()) // return DAL_STATUS_LCD_IN_SUSPEND; MMProfileLogEx(ddp_mmp_get_events()->dal_clean, MMProfileFlagStart, 0, 0); DAL_LOCK(); DAL_CHECK_MFC_RET(MFC_ResetCursor(mfc_handle)); ctxt->screen_color=0; DAL_SetScreenColor(DAL_COLOR_RED); /* if (LCD_STATE_POWER_OFF == LCD_GetState()) { DISP_LOG_PRINT(ANDROID_LOG_INFO, "DAL", "dal_clean in power off\n"); dal_disable_when_resume = TRUE; ret = DAL_STATUS_LCD_IN_SUSPEND; goto End; } */ //xuecheng, for debug #if 0 if(is_early_suspended){ up(&sem_early_suspend); DISP_LOG_PRINT(ANDROID_LOG_INFO, "DAL", "dal_clean in power off\n"); goto End; } #endif //TODO: if dal_shown=false, and 3D enabled, mtkfb may disable UI layer, please modify 3D driver if(isAEEEnabled==1) { primary_disp_input_config input; memset((void*)&input, 0, sizeof(primary_disp_input_config)); input.addr = (unsigned long)dal_fb_pa; input.layer = primary_display_get_option("ASSERT_LAYER"); input.layer_en = 0; input.src_x = 0; input.src_y = 0; input.src_w = DAL_WIDTH; input.src_h = DAL_HEIGHT; input.dst_x = 0; input.dst_y = 0; input.dst_w = DAL_WIDTH; input.dst_h = DAL_HEIGHT; input.alpha = 0x80; input.aen = 1; input.buff_idx = -1; input.src_pitch = DAL_WIDTH * DAL_BPP; input.isDirty = 1; input.fmt = DAL_FORMAT; ret = primary_display_config_input(&input); // DAL disable, switch UI layer to default layer 3 printk("[DDP]* isAEEEnabled from 1 to 0, %d \n", dal_clean_cnt++); isAEEEnabled = 0; DAL_Dynamic_Change_FB_Layer(isAEEEnabled); // restore UI layer to DEFAULT_UI_LAYER } dal_shown = FALSE; dal_disable_when_resume = FALSE; primary_display_trigger(0, NULL, 0); End: DAL_UNLOCK(); MMProfileLogEx(ddp_mmp_get_events()->dal_clean, MMProfileFlagEnd, 0, 0); return ret; }
int ext_disp_config_input_multiple(ext_disp_input_config* input, int idx) { int ret = 0; int i=0; int layer =0; ///DISPFUNC(); disp_ddp_path_config *data_config; if((is_hdmi_active() == false) || (pgc->state != EXTD_RESUME) ) { DISPMSG("config ext disp is already sleeped\n"); MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Config, idx ); return 0; } _ext_disp_path_lock(); // all dirty should be cleared in dpmgr_path_get_last_config() data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle); data_config->dst_dirty = 0; data_config->ovl_dirty = 0; data_config->rdma_dirty = 0; data_config->wdma_dirty = 0; // hope we can use only 1 input struct for input config, just set layer number if(_should_config_ovl_input()) { for(i = 0;i<HW_OVERLAY_COUNT;i++) { ///dprec_logger_start(DPREC_LOGGER_PRIMARY_CONFIG, input->layer|(input->layer_en<<16), input->addr); if(input[i].dirty) { dprec_mmp_dump_ovl_layer(&(data_config->ovl_config[input[i].layer]), input[i].layer, 2); ret = _convert_disp_input_to_ovl(&(data_config->ovl_config[input[i].layer]), &input[i]); } /* else { data_config->ovl_config[input[i].layer].layer_en = input[i].layer_en; data_config->ovl_config[input[i].layer].layer = input[i].layer; } */ data_config->ovl_dirty = 1; ///dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, input->src_x, input->src_y); } } else { ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), input); data_config->rdma_dirty= 1; } if(_should_wait_path_idle()) { dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2); } memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS)); ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, ext_disp_cmdq_enabled()? pgc->cmdq_handle_config : NULL); // this is used for decouple mode, to indicate whether we need to trigger ovl pgc->need_trigger_overlay = 1; _ext_disp_path_unlock(); DISPMSG("config_input_multiple idx %x -w %d, h %d\n", idx ,data_config->ovl_config[0].src_w, data_config->ovl_config[0].src_h); return ret; }
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; }
static int dpmgr_module_notify(DISP_MODULE_ENUM module, DISP_PATH_EVENT event) { ddp_path_handle handle = find_handle_by_module(module); MMProfileLogEx(ddp_mmp_get_events()->primary_display_aalod_trigger, MMProfileFlagPulse, module, 0); return dpmgr_signal_event(handle,event); }
///TODO: move each irq to module driver irqreturn_t disp_irq_handler(int irq, void *dev_id) { DISP_MODULE_ENUM module = DISP_MODULE_UNKNOWN; unsigned int reg_val = 0; unsigned int index = 0; unsigned int mutexID = 0; //MMProfileLogEx(ddp_mmp_get_events()->DDP_IRQ, MMProfileFlagStart, irq, 0); if(irq==dispsys_irq[DISP_REG_DSI0] || irq==dispsys_irq[DISP_REG_DSI1]) { index = (irq == dispsys_irq[DISP_REG_DSI0]) ? 0 : 1; module = (irq == dispsys_irq[DISP_REG_DSI0]) ? DISP_MODULE_DSI0 : DISP_MODULE_DSI1; reg_val = DISP_REG_GET(DDP_REG_BASE_DSI0+0xC + index * DISP_DSI_INDEX_OFFSET) & 0xff; DISP_CPU_REG_SET(DDP_REG_BASE_DSI0+0xC + index * DISP_DSI_INDEX_OFFSET, ~reg_val); DDPIRQ("IRQ: DSI%d 0x%x!\n", index, reg_val); //MMProfileLogEx(ddp_mmp_get_events()->DSI_IRQ[index], 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); 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-RDMA0 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 6)) { DDPERR("IRQ: OVL%d-RDMA1 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 7)) { DDPERR("IRQ: OVL%d-RDMA2 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 8)) { DDPERR("IRQ: OVL%d-RDMA3 not complete untill EOF!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 9)) { DDPERR("IRQ: OVL%d-RDMA0 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 10)) { DDPERR("IRQ: OVL%d-RDMA1 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 11)) { DDPERR("IRQ: OVL%d-RDMA2 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } if (reg_val & (1 << 12)) { DDPERR("IRQ: OVL%d-RDMA3 fifo underflow!\n", index); disp_irq_log_module |= 1 << module; } 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, DISP_REG_GET(DISP_REG_OVL_INTSTA+index*DISP_OVL_INDEX_OFFSET)); } 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; } 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)); } else if(irq==dispsys_irq[DISP_REG_RDMA0] || irq==dispsys_irq[DISP_REG_RDMA1] || irq==dispsys_irq[DISP_REG_RDMA2] ) { 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; } else if (dispsys_irq[DISP_REG_RDMA2] == irq) { index = 2; module = DISP_MODULE_RDMA2; } 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); } /* deal with end first */ 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); } if (reg_val & (1 << 1)) { MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagStart, reg_val, 0); MMProfileLogEx(ddp_mmp_get_events()->layer[0], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L0_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x1); MMProfileLogEx(ddp_mmp_get_events()->layer[1], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L1_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x2); MMProfileLogEx(ddp_mmp_get_events()->layer[2], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L2_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x4); MMProfileLogEx(ddp_mmp_get_events()->layer[3], MMProfileFlagPulse, DISP_REG_GET(DISP_REG_OVL_L3_ADDR), DISP_REG_GET(DISP_REG_OVL_SRC_CON) & 0x8); rdma_start_time[index] = sched_clock(); DDPIRQ("IRQ: RDMA%d frame start!\n", 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; MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagPulse, reg_val, 0); } if (reg_val & (1 << 4)) { MMProfileLogEx(ddp_mmp_get_events()->rdma_underflow, MMProfileFlagPulse,cnt_rdma_underflow, 0); MMProfileLogEx(ddp_mmp_get_events()->SCREEN_UPDATE[index], MMProfileFlagPulse, reg_val, 0); DDPERR("IRQ: RDMA%d underflow! cnt=%d dsi0_cur(%d,%d)\n", index, cnt_rdma_underflow[index]++, DISP_REG_GET(DDP_REG_BASE_DSI0+0x168), DISP_REG_GET(DDP_REG_BASE_DSI0+0x16C)); disp_irq_log_module |= module; } if (reg_val & (1 << 5)) { DDPIRQ("IRQ: RDMA%d target line!\n", index); } /* clear intr */ DISP_CPU_REG_SET(DISP_REG_RDMA_INT_STATUS + index * DISP_RDMA_INDEX_OFFSET, ~reg_val); } else if(irq==dispsys_irq[DISP_REG_COLOR0] || irq==dispsys_irq[DISP_REG_COLOR1]) { index = (irq == dispsys_irq[DISP_REG_COLOR0]) ? 0 : 1; module = (irq == dispsys_irq[DISP_REG_COLOR0]) ? DISP_MODULE_COLOR0 : DISP_MODULE_COLOR1; reg_val = 0; } else if(irq==dispsys_irq[DISP_REG_MM_MUTEX]) { 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 { 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; }