static void destroy_external_display_path(unsigned int session, int mode) { int device_id = 0; MULTI_COTRL_LOG("destroy_external_display_path session:%08x\n", session); if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY) { /*virtual device id*/ device_id = DISP_SESSION_DEV(session); } else { /*external device id*/ device_id = DISP_SESSION_DEV(session) - 1; } if ((path_info.old_session[device_id] == DISP_SESSION_PRIMARY) || (path_info.old_session[device_id] == DISP_SESSION_MEMORY && path_info.old_mode[device_id] >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE)) { /*discard for memory session in mirror mode*/ MULTI_COTRL_LOG("no need destroy path for session:0x%08x, mode:%d\n", path_info.old_session[device_id], path_info.old_mode[device_id]); return; } if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) { ext_disp_deinit(session); extd_set_layer_num(0, session); ext_disp_path_change(EXTD_OVL_IDLE_REQ, session); } else if (path_info.old_session[device_id] == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT > 0) { ovl2mem_deinit(); ovl2mem_setlayernum(0); ext_disp_path_change(EXTD_OVL_IDLE_REQ, session); } }
int external_display_trigger(EXTD_TRIGGER_MODE trigger, unsigned int session) { int ret = 0; enum EXTD_OVL_REQ_STATUS ovl_status = EXTD_OVL_NO_REQ; if (trigger == TRIGGER_RESUME) { ext_disp_resume(session); if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL && DISP_SESSION_DEV(session) == DEV_EINK+1) { if (extd_driver[DEV_EINK]->power_enable) { /*1 for power on, 0 for power off*/ extd_driver[DEV_EINK]->power_enable(1); } } } ret = ext_disp_trigger(0, NULL, 0, session); if (trigger == TRIGGER_SUSPEND) { ext_disp_suspend_trigger(NULL, 0, session); if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL && DISP_SESSION_DEV(session) == DEV_EINK+1) { if (extd_driver[DEV_EINK]->power_enable) { /*1 for power on, 0 for power off*/ extd_driver[DEV_EINK]->power_enable(0); } } } ovl_status = ext_disp_get_ovl_req_status(session); if (ovl_status == EXTD_OVL_REMOVING) { /*the new buffer configured, ovl can be removed*/ ext_disp_path_change(EXTD_OVL_REMOVED, session); } else if (ovl_status == EXTD_OVL_INSERT_REQ) { /*the new buffer configured, ovl already is inserted in the path*/ ext_disp_path_change(EXTD_OVL_INSERTED, session); } return ret; }
static int create_external_display_path(unsigned int session, int mode) { int ret = 0; int extd_type = DISP_IF_MHL; MULTI_COTRL_LOG("create_external_display_path session:%08x, mode:%d\n", session, mode); if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT > 0) { if (mode < DISP_SESSION_DIRECT_LINK_MIRROR_MODE && (path_info.old_mode[DEV_WFD] >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE || path_info.old_session[DEV_WFD] != DISP_SESSION_MEMORY)) { if (ext_disp_wait_ovl_available(0) > 0) { ovl2mem_init(session); ovl2mem_setlayernum(4); } else { MULTI_COTRL_ERR("mhl path: OVL1 can not be split out!\n"); ret = -1; } } else if (mode >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE && path_info.old_session[DEV_WFD] == DISP_SESSION_MEMORY && path_info.old_mode[DEV_WFD] < DISP_SESSION_DIRECT_LINK_MIRROR_MODE) { ovl2mem_deinit(); ovl2mem_setlayernum(0); ext_disp_path_change(EXTD_OVL_IDLE_REQ, session); } } else if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL) { int device_id = DISP_SESSION_DEV(session) - 1; extd_type = extd_get_device_type(session); if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) { if (EXTD_OVERLAY_CNT < 1) { /*external display has no OVL to use, so no actions for mode switch */ return ret; } } if (extd_type != DISP_IF_EPD && (mode < DISP_SESSION_DIRECT_LINK_MIRROR_MODE || extd_type == DISP_IF_HDMI_SMARTBOOK)) { if (ext_disp_wait_ovl_available(0) > 0) { if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL && extd_type != DISP_IF_HDMI_SMARTBOOK) { /*insert OVL to external dispaly path*/ ext_disp_path_change(EXTD_OVL_INSERT_REQ, session); } else { /*create external display path with OVL*/ extd_create_path(EXTD_DIRECT_LINK_MODE, session); } extd_set_layer_num(4, session); } else { MULTI_COTRL_ERR("mhl path: OVL1 can not be split out!\n"); extd_create_path(EXTD_RDMA_DPI_MODE, session); extd_set_layer_num(1, session); } } else { if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) { ext_disp_path_change(EXTD_OVL_REMOVE_REQ, session); extd_set_layer_num(1, session); } else { extd_create_path(EXTD_RDMA_DPI_MODE, session); extd_set_layer_num(1, session); } } } else if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT == 0) { MULTI_COTRL_ERR("memory session and ovl time sharing!\n"); ovl2mem_setlayernum(4); } return ret; }
static int disp_switch_mode_kthread(void *data) { int ret = 0; struct sched_param param = { .sched_priority = 94 }; /*RTPM_PRIO_SCRN_UPDATE*/ sched_setscheduler(current, SCHED_RR, ¶m); MULTI_COTRL_LOG("disp_switch_mode_kthread in!\n"); for (;;) { wait_event_interruptible(switch_mode_wq, atomic_read(&switch_mode_event)); atomic_set(&switch_mode_event, 0); MULTI_COTRL_LOG("switch mode, create or change path, mode:%d, session:0x%x\n", path_info.cur_mode, path_info.ext_sid); ret = create_external_display_path(path_info.ext_sid, path_info.cur_mode); if (ret == 0) { path_info.old_session[path_info.switching] = DISP_SESSION_TYPE(path_info.ext_sid); path_info.old_mode[path_info.switching] = path_info.cur_mode; } path_info.switching = DEV_MAX_NUM; path_info.ext_sid = 0; if (kthread_should_stop()) { /*thread exit*/ break; } } return 0; } #ifndef OVL_CASCADE_SUPPORT static int path_change_without_cascade(DISP_MODE mode, unsigned int session_id, unsigned int device_id) { int ret = -1; unsigned int session = 0; /*MULTI_COTRL_FUNC();*/ /*destroy external display path*/ if (session_id == 0 && path_info.old_session[device_id] != DISP_SESSION_PRIMARY) { if (device_id == DEV_WFD) { /*make memory session for WFD*/ session = MAKE_DISP_SESSION(DISP_SESSION_MEMORY, device_id); } else { /*make external session*/ session = MAKE_DISP_SESSION(DISP_SESSION_EXTERNAL, device_id + 1); } destroy_external_display_path(session, DISP_SESSION_DIRECT_LINK_MODE); path_info.old_session[device_id] = DISP_SESSION_PRIMARY; path_info.old_mode[device_id] = DISP_SESSION_DIRECT_LINK_MODE; path_info.switching = DEV_MAX_NUM; return 1; } /*create path or change path*/ if ((session_id > 0 && path_info.old_session[device_id] == DISP_SESSION_PRIMARY) || (mode != path_info.old_mode[device_id] && path_info.old_session[device_id] != DISP_SESSION_PRIMARY)) { ret = create_external_display_path(session_id, mode); if (ret == 0) { path_info.old_session[device_id] = DISP_SESSION_TYPE(session_id); path_info.old_mode[device_id] = mode; } path_info.switching = DEV_MAX_NUM; return 1; } return 0; }
void update_frm_seq_info(unsigned int session_id, unsigned int addr, unsigned int addr_offset,unsigned int seq, DISP_FRM_SEQ_STATE state) { int i= 0; unsigned device_type = DISP_SESSION_TYPE(session_id); //printk("update_frm_seq_info, 0x%x/0x%x/0x%x/%d/%s/%d\n", session_id, addr, addr_offset, seq, get_frame_seq_state_string(state), frm_update_cnt); if(seq < 0 || session_id < 0 || state > FRM_RDMA0_EOF) return ; if(device_type > DISP_SESSION_MEMORY) { printk("seq_end session_id(0x%x) , seq(%d) \n",session_id, seq); return; } if(device_type == DISP_SESSION_PRIMARY || device_type == DISP_SESSION_PRIMARY - 1) { if(FRM_CONFIG == state) { frm_update_sequence[frm_update_cnt].state = state; frm_update_sequence[frm_update_cnt].session_type = device_type; frm_update_sequence[frm_update_cnt].mva= addr; frm_update_sequence[frm_update_cnt].max_offset= addr_offset; if(seq > 0) frm_update_sequence[frm_update_cnt].seq= seq; MMProfileLogEx(MTKFB_MMP_Events.primary_seq_config, MMProfileFlagPulse, addr, seq); } else if(FRM_TRIGGER == state) { frm_update_sequence[frm_update_cnt].state = FRM_TRIGGER; MMProfileLogEx(MTKFB_MMP_Events.primary_seq_trigger, MMProfileFlagPulse, addr, seq); dprec_logger_frame_seq_begin(device_type, frm_update_sequence[frm_update_cnt].seq); frm_update_cnt++; frm_update_cnt%=FRM_UPDATE_SEQ_CACHE_NUM; } else if(FRM_WDMA0_EOF == state) { for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++) { // if((absabs(addr -frm_update_sequence[i].mva) <= frm_update_sequence[i].max_offset) && (frm_update_sequence[i].state == FRM_TRIGGER)) if(frm_update_sequence[i].state == FRM_TRIGGER) { frm_update_sequence[i].state = FRM_WDMA0_EOF; frm_update_sequence[i].mva = addr; MMProfileLogEx(MTKFB_MMP_Events.primary_seq_wdma0_efo, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq); ///break; } } } else if(FRM_RDMA0_SOF == state) { for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++) { if(FRM_WDMA0_EOF == frm_update_sequence[i].state && device_type == DISP_SESSION_PRIMARY && frm_update_sequence[i].mva == addr) { frm_update_sequence[i].state = FRM_RDMA0_SOF; dprec_logger_frame_seq_end(device_type, frm_update_sequence[i].seq); dprec_logger_frame_seq_begin(DISP_SESSION_PRIMARY-1, frm_update_sequence[i].seq); MMProfileLogEx(MTKFB_MMP_Events.primary_seq_rdma0_sof, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq); } } } else if(FRM_RDMA0_EOF == state) { for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++) { if(FRM_RDMA0_SOF == frm_update_sequence[i].state && device_type == DISP_SESSION_PRIMARY && frm_update_sequence[i].mva == addr) { frm_update_sequence[i].state = FRM_RDMA0_EOF; dprec_logger_frame_seq_end(DISP_SESSION_PRIMARY-1, frm_update_sequence[i].seq ); MMProfileLogEx(MTKFB_MMP_Events.primary_seq_rdma0_eof, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq); } } } } else if(device_type == DISP_SESSION_MEMORY) { if(FRM_CONFIG == state) { frm_update_sequence_mem[frm_update_cnt_mem].state = state; frm_update_sequence_mem[frm_update_cnt_mem].session_type = device_type; frm_update_sequence_mem[frm_update_cnt_mem].mva= addr; frm_update_sequence_mem[frm_update_cnt_mem].max_offset= addr_offset; if(seq > 0) frm_update_sequence_mem[frm_update_cnt_mem].seq= seq; MMProfileLogEx(MTKFB_MMP_Events.external_seq_config, MMProfileFlagPulse, addr, seq); } else if(FRM_TRIGGER == state) { frm_update_sequence_mem[frm_update_cnt_mem].state = FRM_TRIGGER; MMProfileLogEx(MTKFB_MMP_Events.external_seq_trigger, MMProfileFlagPulse, addr, seq); dprec_logger_frame_seq_begin(device_type, frm_update_sequence_mem[frm_update_cnt_mem].seq); frm_update_cnt_mem++; frm_update_cnt_mem%=FRM_UPDATE_SEQ_CACHE_NUM; } else if(FRM_WDMA0_EOF == state) { for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++) { // if((absabs(addr -frm_update_sequence_mem[i].mva) <= frm_update_sequence_mem[i].max_offset) && (frm_update_sequence_mem[i].state == FRM_TRIGGER)) if(frm_update_sequence_mem[i].state == FRM_TRIGGER) { MMProfileLogEx(MTKFB_MMP_Events.external_seq_wdma0_efo, MMProfileFlagPulse, frm_update_sequence_mem[i].mva, frm_update_sequence_mem[i].seq); frm_update_sequence_mem[i].state = FRM_WDMA0_EOF; frm_update_sequence_mem[i].mva = addr; dprec_logger_frame_seq_end(device_type, frm_update_sequence_mem[i].seq); ///break; } } } } }