int disp_helper_set_option(DISP_HELPER_OPTION option, int value) { if (option < DISP_HELPER_OPTION_NUM) { DISPCHECK("Set Option %d(%s) from (%d) to (%d)\n", option, disp_helper_option_spy(option), disp_helper_get_option(option), value); _disp_helper_option_value[option] = value; DISPCHECK("After set (%s) is (%d)\n", disp_helper_option_spy(option), disp_helper_get_option(option)); } else { DISPERR("Wrong option: %d\n", option); } }
static int _build_path_debug_rdma_dpi(void) { int ret = 0; DISP_MODULE_ENUM dst_module = 0; pgc->mode = EXTD_DEBUG_RDMA_DPI_MODE; pgc->dpmgr_handle = dpmgr_create_path(DDP_SCENARIO_SUB_RDMA2_DISP, pgc->cmdq_handle_config); if(pgc->dpmgr_handle) { DISPCHECK("dpmgr create path SUCCESS(%p)\n", pgc->dpmgr_handle); } else { DISPCHECK("dpmgr create path FAIL\n"); return -1; } dst_module = _get_dst_module_by_lcm(pgc->plcm); dpmgr_path_set_dst_module(pgc->dpmgr_handle, dst_module); DISPCHECK("dpmgr set dst module FINISHED(%s)\n", ddp_get_module_name(dst_module)); { M4U_PORT_STRUCT sPort; sPort.ePortID = M4U_PORT_DISP_RDMA2; sPort.Virtuality = ext_disp_use_m4u; sPort.Security = 0; sPort.Distance = 1; sPort.Direction = 0; ret = m4u_config_port(&sPort); if(ret == 0) { DISPCHECK("config M4U Port %s to %s SUCCESS\n",ddp_get_module_name(DISP_MODULE_RDMA2), ext_disp_use_m4u?"virtual":"physical"); } else { DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",ddp_get_module_name(DISP_MODULE_RDMA2), ext_disp_use_m4u?"virtual":"physical", ret); return -1; } } dpmgr_set_lcm_utils(pgc->dpmgr_handle, pgc->plcm->drv); dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC); dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE); return ret; }
static void _cmdq_stop_trigger_loop(void) { int ret = 0; // this should be called only once because trigger loop will nevet stop ret = cmdqRecStopLoop(pgc->cmdq_handle_trigger); DISPCHECK("ext display STOP cmdq trigger loop finished\n"); }
int ext_disp_switch_cmdq_cpu(CMDQ_SWITCH use_cmdq) { _ext_disp_path_lock(); ext_disp_use_cmdq = use_cmdq; DISPCHECK("display driver use %s to config register now\n", (use_cmdq==CMDQ_ENABLE)?"CMDQ":"CPU"); _ext_disp_path_unlock(); return ext_disp_use_cmdq; }
int ext_disp_diagnose(void) { int ret = 0; if(is_context_inited > 0) { DISPCHECK("ext_disp_diagnose, is_context_inited --%d\n", is_context_inited); dpmgr_check_status(pgc->dpmgr_handle); ///ddp_dpi_dump(DISP_MODULE_DPI , 0); } else ddp_dpi_dump(DISP_MODULE_DPI , 0); return ret; }
static void _cmdq_start_trigger_loop(void) { int ret = 0; // this should be called only once because trigger loop will nevet stop ret = cmdqRecStartLoop(pgc->cmdq_handle_trigger); if(!ext_disp_is_video_mode()) { // need to set STREAM_EOF for the first time, otherwise we will stuck in dead loop cmdqCoreSetEvent(CMDQ_SYNC_TOKEN_STREAM_EOF); ///dprec_event_op(DPREC_EVENT_CMDQ_SET_EVENT_ALLOW); } DISPCHECK("START cmdq trigger loop finished\n"); }
int ext_disp_wait_for_vsync(void *config) { disp_session_vsync_config *c = (disp_session_vsync_config *)config; int ret = 0; ret = dpmgr_wait_event(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC); ///dprec_logger_trigger(DPREC_LOGGER_VSYNC); if(ret == -2) { DISPCHECK("vsync for ext display path not enabled yet\n"); return -1; } //DISPMSG("vsync signaled\n"); c->vsync_ts = get_current_time_us(); c->vsync_cnt ++; return ret; }
int ext_disp_resume(void) { EXT_DISP_STATUS ret = EXT_DISP_STATUS_OK; _ext_disp_path_lock(); if(pgc->state < EXTD_INIT) { DISPERR("EXTD_DEINIT \n"); goto done; } dpmgr_path_power_on(pgc->dpmgr_handle, CMDQ_DISABLE); extd_drv_resume(pgc->plcm); ///dpmgr_path_start(pgc->dpmgr_handle, CMDQ_DISABLE); if(ext_disp_use_cmdq == CMDQ_ENABLE) _cmdq_start_trigger_loop(); if(dpmgr_path_is_busy(pgc->dpmgr_handle)) { DISPCHECK("stop display path failed, still busy\n"); ret = -1; goto done; } pgc->state = EXTD_RESUME; done: _ext_disp_path_unlock(); DISPMSG("ext_disp_resume done \n"); return ret; }
void _dump_extd_drv_info(extd_drv_handle *plcm) { int i = 0; LCM_DRIVER *l = NULL; LCM_PARAMS *p = NULL; if(plcm == NULL) { DISPERR("plcm is null\n"); return; } l = plcm->drv; p = plcm->params; if(l && p) { DISPCHECK("[LCM] resolution: %d x %d\n", p->width, p->height); DISPCHECK("[LCM] physical size: %d x %d\n", p->physical_width, p->physical_height); DISPCHECK("[LCM] physical size: %d x %d\n", p->physical_width, p->physical_height); switch(p->lcm_if) { case LCM_INTERFACE_DSI0: DISPCHECK("[LCM] interface: DSI0\n"); break; case LCM_INTERFACE_DSI1: DISPCHECK("[LCM] interface: DSI1\n"); break; case LCM_INTERFACE_DPI0: DISPCHECK("[LCM] interface: DPI0\n"); break; case LCM_INTERFACE_DPI1: DISPCHECK("[LCM] interface: DPI1\n"); break; case LCM_INTERFACE_DBI0: DISPCHECK("[LCM] interface: DBI0\n"); break; default: DISPCHECK("[LCM] interface: unknown\n"); break; } switch(p->type) { case LCM_TYPE_DBI: DISPCHECK("[LCM] Type: DBI\n"); break; case LCM_TYPE_DSI: DISPCHECK("[LCM] Type: DSI\n"); break; case LCM_TYPE_DPI: DISPCHECK("[LCM] Type: DPI\n"); break; default: DISPCHECK("[LCM] TYPE: unknown\n"); break; } if(p->type == LCM_TYPE_DSI) { switch(p->dsi.mode) { case CMD_MODE: DISPCHECK("[LCM] DSI Mode: CMD_MODE\n"); break; case SYNC_PULSE_VDO_MODE: DISPCHECK("[LCM] DSI Mode: SYNC_PULSE_VDO_MODE\n"); break; case SYNC_EVENT_VDO_MODE: DISPCHECK("[LCM] DSI Mode: SYNC_EVENT_VDO_MODE\n"); break; case BURST_VDO_MODE: DISPCHECK("[LCM] DSI Mode: BURST_VDO_MODE\n"); break; default: DISPCHECK("[LCM] DSI Mode: Unknown\n"); break; } } if(p->type == LCM_TYPE_DSI) { DISPCHECK("[LCM] LANE_NUM: %d,data_format: %d,vertical_sync_active: %d\n",p->dsi.LANE_NUM,p->dsi.data_format); #ifdef ROME_TODO #error #endif DISPCHECK("[LCM] vact: %d, vbp: %d, vfp: %d, vact_line: %d, hact: %d, hbp: %d, hfp: %d, hblank: %d, hblank: %d\n",p->dsi.vertical_sync_active, p->dsi.vertical_backporch,p->dsi.vertical_frontporch,p->dsi.vertical_active_line,p->dsi.horizontal_sync_active,p->dsi.horizontal_backporch,p->dsi.horizontal_frontporch,p->dsi.horizontal_blanking_pixel); DISPCHECK("[LCM] pll_select: %d, pll_div1: %d, pll_div2: %d, fbk_div: %d,fbk_sel: %d, rg_bir: %d\n",p->dsi.pll_select,p->dsi.pll_div1,p->dsi.pll_div2,p->dsi.fbk_div,p->dsi.fbk_sel,p->dsi.rg_bir); DISPCHECK("[LCM] rg_bic: %d, rg_bp: %d, PLL_CLOCK: %d, dsi_clock: %d, ssc_range: %d, ssc_disable: %d, compatibility_for_nvk: %d, cont_clock: %d\n", p->dsi.rg_bic, p->dsi.rg_bp,p->dsi.PLL_CLOCK,p->dsi.dsi_clock,p->dsi.ssc_range,p->dsi.ssc_disable,p->dsi.compatibility_for_nvk,p->dsi.cont_clock); DISPCHECK("[LCM] lcm_ext_te_enable: %d, noncont_clock: %d, noncont_clock_period: %d\n", p->dsi.lcm_ext_te_enable,p->dsi.noncont_clock,p->dsi.noncont_clock_period); } } return; }
int ovl2mem_init(unsigned int session) { int ret = -1; DISPFUNC(); dpmgr_init(); mutex_init(&(pgc->lock)); _ovl2mem_path_lock(__func__); if(pgc->state > 0) goto Exit; #if 0 ret = cmdqCoreRegisterCB(CMDQ_GROUP_DISP, cmdqDdpClockOn,cmdqDdpDumpInfo,cmdqDdpResetEng,cmdqDdpClockOff); if(ret) { DISPERR("cmdqCoreRegisterCB failed, ret=%d \n", ret); goto done; } #endif ret = cmdqRecCreate(CMDQ_SCENARIO_SUB_DISP,&(pgc->cmdq_handle_config)); if(ret) { DISPCHECK("cmdqRecCreate FAIL, ret=%d \n", ret); goto Exit; } else { DISPCHECK("cmdqRecCreate SUCCESS, cmdq_handle=%p\n", pgc->cmdq_handle_config); } pgc->dpmgr_handle = dpmgr_create_path(DDP_SCENARIO_SUB_OVL_MEMOUT, pgc->cmdq_handle_config); if(pgc->dpmgr_handle) { DISPCHECK("dpmgr create path SUCCESS(%p)\n", pgc->dpmgr_handle); } else { DISPCHECK("dpmgr create path FAIL\n"); goto Exit; } M4U_PORT_STRUCT sPort; sPort.ePortID = M4U_PORT_DISP_OVL1; sPort.Virtuality = ovl2mem_use_m4u; sPort.Security = 0; sPort.Distance = 1; sPort.Direction = 0; ret = m4u_config_port(&sPort); sPort.ePortID = M4U_PORT_DISP_WDMA1; sPort.Virtuality = ovl2mem_use_m4u; sPort.Security = 0; sPort.Distance = 1; sPort.Direction = 0; ret = m4u_config_port(&sPort); if(ret == 0) { DISPCHECK("config M4U Port %s to %s SUCCESS\n",ddp_get_module_name(DISP_MODULE_OVL1), ovl2mem_use_m4u?"virtual":"physical"); } else { DISPCHECK("config M4U Port %s to %s FAIL(ret=%d)\n",ddp_get_module_name(DISP_MODULE_OVL1), ovl2mem_use_m4u?"virtual":"physical", ret); goto Exit; } dpmgr_path_set_video_mode(pgc->dpmgr_handle, ovl2mem_cmdq_enabled()); dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE); dpmgr_path_reset(pgc->dpmgr_handle, CMDQ_DISABLE); //dpmgr_path_set_dst_module(pgc->dpmgr_handle,DISP_MODULE_ENUM dst_module) dpmgr_enable_event(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_COMPLETE); pgc->max_layer = 4; pgc->state = 1; pgc->session = session; atomic_set(&g_trigger_ticket, 1); atomic_set(&g_release_ticket, 1); Exit: _ovl2mem_path_unlock(__func__); DISPMSG("ovl2mem_init done\n"); return ret; }
disp_lcm_handle* disp_lcm_probe(char* plcm_name, LCM_INTERFACE_ID lcm_id) { DISPFUNC(); int ret = 0; int lcmindex = 0; bool isLCMFound = false; bool isLCMInited = false; LCM_DRIVER *lcm_drv = NULL; LCM_PARAMS *lcm_param = NULL; disp_lcm_handle *plcm = NULL; DISPCHECK("plcm_name=%s\n", plcm_name); if(_lcm_count() == 0) { DISPERR("no lcm driver defined in linux kernel driver\n"); return NULL; } else if(_lcm_count() == 1) { if(plcm_name == NULL) { lcm_drv = lcm_driver_list[0]; isLCMFound = true; isLCMInited = false; } else { lcm_drv = lcm_driver_list[0]; if(strcmp(lcm_drv->name, plcm_name)) { DISPERR("FATAL ERROR!!!LCM Driver defined in kernel(%s) is different with LK(%s)\n", lcm_drv->name, plcm_name); return NULL; } isLCMInited = true; isLCMFound = true; } lcmindex = 0; } else { if(plcm_name == NULL) { // TODO: we need to detect all the lcm driver } else { int i = 0; for(i=0;i<_lcm_count();i++) { lcm_drv = lcm_driver_list[i]; if(!strcmp(lcm_drv->name, plcm_name)) { isLCMFound = true; isLCMInited = true; lcmindex = i; break; } } DISPERR("FATAL ERROR: can't found lcm driver:%s in linux kernel driver\n", plcm_name); } // TODO: } if(isLCMFound == false) { DISPERR("FATAL ERROR!!!No LCM Driver defined\n"); return NULL; } plcm = kzalloc(sizeof(uint8_t*) *sizeof(disp_lcm_handle), GFP_KERNEL); lcm_param = kzalloc(sizeof(uint8_t*) *sizeof(LCM_PARAMS), GFP_KERNEL); if(plcm && lcm_param) { plcm->params = lcm_param; plcm->drv = lcm_drv; plcm->is_inited = isLCMInited; plcm->index = lcmindex; } else { DISPERR("FATAL ERROR!!!kzalloc plcm and plcm->params failed\n"); goto FAIL; } { plcm->drv->get_params(plcm->params); plcm->lcm_if_id = plcm->params->lcm_if; // below code is for lcm driver forward compatible if(plcm->params->type == LCM_TYPE_DSI && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED) plcm->lcm_if_id = LCM_INTERFACE_DSI0; if(plcm->params->type == LCM_TYPE_DPI && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED) plcm->lcm_if_id = LCM_INTERFACE_DPI0; if(plcm->params->type == LCM_TYPE_DBI && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED) plcm->lcm_if_id = LCM_INTERFACE_DBI0; if((lcm_id == LCM_INTERFACE_NOTDEFINED) || lcm_id == plcm->lcm_if_id) { plcm->lcm_original_width = plcm->params->width; plcm->lcm_original_height = plcm->params->height; _dump_lcm_info(plcm); return plcm; } else { DISPERR("the specific LCM Interface [%d] didn't define any lcm driver\n", lcm_id); goto FAIL; } } FAIL: if(plcm) kfree(plcm); if(lcm_param) kfree(lcm_param); return NULL; }
void _dump_lcm_info(disp_lcm_handle *plcm) { LCM_DRIVER *l = NULL; LCM_PARAMS *p = NULL; char str_buf[128]; int buf_len = 128; int buf_pos = 0; if (plcm == NULL) { DISPERR("plcm is null\n"); return; } l = plcm->drv; p = plcm->params; if (l && p) { buf_pos += scnprintf(str_buf + buf_pos, 128 - buf_pos, "resolution: %d x %d", p->width, p->height); switch (p->lcm_if) { case LCM_INTERFACE_DSI0: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DSI0"); break; case LCM_INTERFACE_DSI1: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DSI1"); break; case LCM_INTERFACE_DPI0: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DPI0"); break; case LCM_INTERFACE_DPI1: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DPI1"); break; case LCM_INTERFACE_DBI0: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DBI0"); break; default: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: unknown"); break; } switch (p->type) { case LCM_TYPE_DBI: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DBI"); break; case LCM_TYPE_DSI: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DSI"); break; case LCM_TYPE_DPI: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DPI"); break; default: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : unknown"); break; } if (p->type == LCM_TYPE_DSI) { switch (p->dsi.mode) { case CMD_MODE: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", DSI Mode: CMD_MODE"); break; case SYNC_PULSE_VDO_MODE: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", DSI Mode: SYNC_PULSE_VDO_MODE"); break; case SYNC_EVENT_VDO_MODE: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", DSI Mode: SYNC_EVENT_VDO_MODE"); break; case BURST_VDO_MODE: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", DSI Mode: BURST_VDO_MODE"); break; default: buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", DSI Mode: Unknown"); break; } } #if 0 if (p->type == LCM_TYPE_DSI) { DISPCHECK("[LCM] LANE_NUM: %d,data_format\n", (int)p->dsi.LANE_NUM); #ifdef MT_TODO #error #endif DISPCHECK("[LCM] vact: %u, vbp: %u, vfp: %u,\n", p->dsi.vertical_sync_active, p->dsi.vertical_backporch, p->dsi.vertical_frontporch); DISPCHECK("vact_line: %u, hact: %u, hbp: %u, hfp: %u, hblank: %u\n", p->dsi.vertical_active_line, p->dsi.horizontal_sync_active, p->dsi.horizontal_backporch, p->dsi.horizontal_frontporch, p->dsi.horizontal_blanking_pixel); DISPCHECK("[LCM] pll_select: %d, pll_div1: %d, pll_div2: %d, fbk_div: %d,\n", p->dsi.pll_select, p->dsi.pll_div1, p->dsi.pll_div2, p->dsi.fbk_div); DISPCHECK("fbk_sel: %d, rg_bir: %d\n", p->dsi.fbk_sel, p->dsi.rg_bir); DISPCHECK("[LCM] rg_bic: %d, rg_bp: %d, PLL_CLOCK: %d, dsi_clock: %d,\n", p->dsi.rg_bic, p->dsi.rg_bp, p->dsi.PLL_CLOCK, p->dsi.dsi_clock); DISPCHECK("ssc_range: %d, ssc_disable: %d, compatibility_for_nvk: %d, cont_clock: %d\n", p->dsi.ssc_range, p->dsi.ssc_disable, p->dsi.compatibility_for_nvk, p->dsi.cont_clock); DISPCHECK("[LCM] lcm_ext_te_enable: %d, noncont_clock: %d, noncont_clock_period: %d\n", p->dsi.lcm_ext_te_enable, p->dsi.noncont_clock, p->dsi.noncont_clock_period); } #endif DISPPRINT("[LCM] %s\n", str_buf); } }
int ext_disp_init(char *lcm_name, unsigned int session) { DISPFUNC(); EXT_DISP_STATUS ret = EXT_DISP_STATUS_OK; DISP_MODULE_ENUM dst_module = 0; LCM_PARAMS *lcm_param = NULL; LCM_INTERFACE_ID lcm_id = LCM_INTERFACE_NOTDEFINED; dpmgr_init(); extd_mutex_init(&(pgc->lock)); _ext_disp_path_lock(); pgc->plcm = extd_drv_probe( lcm_name, LCM_INTERFACE_NOTDEFINED); if(pgc->plcm == NULL) { DISPCHECK("disp_lcm_probe returns null\n"); ret = EXT_DISP_STATUS_ERROR; goto done; } else { DISPCHECK("disp_lcm_probe SUCCESS\n"); } lcm_param = extd_drv_get_params(pgc->plcm); if(lcm_param == NULL) { DISPERR("get lcm params FAILED\n"); ret = EXT_DISP_STATUS_ERROR; goto done; } #if 0 ret = cmdqCoreRegisterCB(CMDQ_GROUP_DISP, cmdqDdpClockOn,cmdqDdpDumpInfo,cmdqDdpResetEng,cmdqDdpClockOff); if(ret) { DISPERR("cmdqCoreRegisterCB failed, ret=%d \n", ret); ret = EXT_DISP_STATUS_ERROR; goto done; } #endif ret = cmdqRecCreate(CMDQ_SCENARIO_MHL_DISP, &(pgc->cmdq_handle_config)); if(ret) { DISPCHECK("cmdqRecCreate FAIL, ret=%d \n", ret); ret = EXT_DISP_STATUS_ERROR; goto done; } else { DISPCHECK("cmdqRecCreate SUCCESS, g_cmdq_handle=%p \n", pgc->cmdq_handle_config); } if(ext_disp_mode == EXTD_DIRECT_LINK_MODE) { _build_path_direct_link(); DISPCHECK("ext_disp display is DIRECT LINK MODE\n"); } else if(ext_disp_mode == EXTD_DECOUPLE_MODE) { _build_path_decouple(); DISPCHECK("ext_disp display is DECOUPLE MODE\n"); } else if(ext_disp_mode == EXTD_SINGLE_LAYER_MODE) { _build_path_single_layer(); DISPCHECK("ext_disp display is SINGLE LAYER MODE\n"); } else if(ext_disp_mode == EXTD_DEBUG_RDMA_DPI_MODE) { _build_path_debug_rdma_dpi(); DISPCHECK("ext_disp display is DEBUG RDMA to dpi MODE\n"); } else { DISPCHECK("ext_disp display mode is WRONG\n"); } if(ext_disp_use_cmdq == CMDQ_ENABLE) { _cmdq_build_trigger_loop(); DISPCHECK("ext_disp display BUILD cmdq trigger loop finished\n"); _cmdq_start_trigger_loop(); } pgc->session = session; DISPCHECK("ext_disp display START cmdq trigger loop finished\n"); dpmgr_path_set_video_mode(pgc->dpmgr_handle, ext_disp_is_video_mode()); dpmgr_path_init(pgc->dpmgr_handle, CMDQ_DISABLE); /* disp_ddp_path_config data_config; memset((void*)&data_config, 0, sizeof(disp_ddp_path_config)); memcpy(&(data_config.dispif_config), &(lcm_param), sizeof(LCM_PARAMS)); data_config.dst_w = lcm_param->width; data_config.dst_h = lcm_param->height; data_config.dst_dirty = 1; ret = dpmgr_path_config(pgc->dpmgr_handle, &data_config, CMDQ_DISABLE); */ disp_ddp_path_config *data_config = (disp_ddp_path_config *)vmalloc(sizeof(disp_ddp_path_config)); if(data_config) { memset((void*)data_config, 0, sizeof(disp_ddp_path_config)); memcpy(&(data_config->dispif_config), &(lcm_param), sizeof(LCM_PARAMS)); data_config->dst_w = lcm_param->width; data_config->dst_h = lcm_param->height; data_config->dst_dirty = 1; ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, CMDQ_DISABLE); vfree(data_config); } else { DISPCHECK("allocate buffer data_config failed!!!\n"); ret = EXT_DISP_STATUS_ERROR; goto done; } if(!extd_drv_is_inited(pgc->plcm)) { ret = extd_drv_init(pgc->plcm); } // this will be set to always enable cmdq later if(ext_disp_is_video_mode()) { ///ext_disp_use_cmdq = CMDQ_ENABLE; if(ext_disp_mode == EXTD_DEBUG_RDMA_DPI_MODE) dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, DDP_IRQ_RDMA2_DONE); else dpmgr_map_event_to_irq(pgc->dpmgr_handle, DISP_PATH_EVENT_IF_VSYNC, DDP_IRQ_RDMA1_DONE); } if(ext_disp_use_cmdq == CMDQ_ENABLE) { _cmdq_reset_config_handle(); _cmdq_insert_wait_frame_done_token(); } pgc->state = EXTD_INIT; done: ///dpmgr_check_status(pgc->dpmgr_handle); _ext_disp_path_unlock(); ext_disp_resume(); dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE); DISPMSG("ext_disp_init done \n"); return ret; }
static void _cmdq_build_trigger_loop(void) { int ret = 0; cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &(pgc->cmdq_handle_trigger)); DISPMSG("ext_disp path trigger thread cmd handle=%p\n", pgc->cmdq_handle_trigger); cmdqRecReset(pgc->cmdq_handle_trigger); if(ext_disp_is_video_mode()) { // wait and clear stream_done, HW will assert mutex enable automatically in frame done reset. // todo: should let dpmanager to decide wait which mutex's eof. ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_MUTEX1_STREAM_EOF); ///dpmgr_path_get_mutex(pgc->dpmgr_handle) // for some module(like COLOR) to read hw register to GPR after frame done dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_AFTER_STREAM_EOF, 0); } else { // DSI command mode doesn't have mutex_stream_eof, need use CMDQ token instead ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_CONFIG_DIRTY); //ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_MDP_DSI0_TE_SOF); // for operations before frame transfer, such as waiting for DSI TE dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_BEFORE_STREAM_SOF, 0); // cleat frame done token, now the config thread will not allowed to config registers. // remember that config thread's priority is higher than trigger thread, so all the config queued before will be applied then STREAM_EOF token be cleared // this is what CMDQ did as "Merge" ret = cmdqRecClearEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF); // enable mutex, only cmd mode need this // this is what CMDQ did as "Trigger" dpmgr_path_trigger(pgc->dpmgr_handle, pgc->cmdq_handle_trigger, CMDQ_ENABLE); //ret = cmdqRecWrite(pgc->cmdq_handle_trigger, (unsigned int)(DISP_REG_CONFIG_MUTEX_EN(0))&0x1fffffff, 1, ~0); // waiting for frame done, because we can't use mutex stream eof here, so need to let dpmanager help to decide which event to wait // most time we wait rdmax frame done event. ret = cmdqRecWait(pgc->cmdq_handle_trigger, CMDQ_EVENT_DISP_RDMA1_EOF); dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_WAIT_STREAM_EOF_EVENT, 0); // dsi is not idle rightly after rdma frame done, so we need to polling about 1us for dsi returns to idle // do not polling dsi idle directly which will decrease CMDQ performance dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_CHECK_IDLE_AFTER_STREAM_EOF, 0); // for some module(like COLOR) to read hw register to GPR after frame done dpmgr_path_build_cmdq(pgc->dpmgr_handle, pgc->cmdq_handle_trigger,CMDQ_AFTER_STREAM_EOF, 0); // polling DSI idle //ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x1401b00c, 0, 0x80000000); // polling wdma frame done //ret = cmdqRecPoll(pgc->cmdq_handle_trigger, 0x140060A0, 1, 0x1); // now frame done, config thread is allowed to config register now ret = cmdqRecSetEventToken(pgc->cmdq_handle_trigger, CMDQ_SYNC_TOKEN_STREAM_EOF); // RUN forever!!!! BUG_ON(ret < 0); } // dump trigger loop instructions to check whether dpmgr_path_build_cmdq works correctly cmdqRecDumpCommand(pgc->cmdq_handle_trigger); DISPCHECK("ext display BUILD cmdq trigger loop finished\n"); return; }