#define LOG_TAG "ddp_manager" #include #include #include #include #include "disp_drv_platform.h" #include "lcm_drv.h" #include "ddp_reg.h" #include "ddp_path.h" #include "ddp_irq.h" #include "ddp_drv.h" #include "ddp_debug.h" #include "ddp_manager.h" #include "ddp_rdma.h" #include "ddp_ovl.h" #include "ddp_log.h" #include "mtkfb_fence.h" #include "primary_display.h" #include //#pragma GCC optimize("O0") extern DDP_MODULE_DRIVER * ddp_modules_driver[DISP_MODULE_NUM]; #ifdef MTKFB_FB_BYPASS_PQ unsigned int gDDPError = 1; #else unsigned int gDDPError = 0; #endif static int ddp_manager_init = 0; #define DDP_MAX_MANAGER_HANDLE (DISP_MUTEX_DDP_COUNT+DISP_MUTEX_DDP_FIRST) extern int disp_get_session_number(); extern unsigned int WDMA0_FRAME_START_FLAG; extern unsigned int ALL_LAYER_DISABLE_STEP; unsigned int allLayerDisabled = 0; typedef struct { volatile unsigned int init; DISP_PATH_EVENT event; wait_queue_head_t wq; volatile unsigned long long data; }DPMGR_WQ_HANDLE; typedef struct { DDP_IRQ_BIT irq_bit; }DDP_IRQ_EVENT_MAPPING; typedef struct { cmdqRecHandle cmdqhandle; int hwmutexid; int power_sate; DDP_MODE mode; struct mutex mutex_lock; DDP_IRQ_EVENT_MAPPING irq_event_map[DISP_PATH_EVENT_NUM]; DPMGR_WQ_HANDLE wq_list[DISP_PATH_EVENT_NUM]; DDP_SCENARIO_ENUM scenario; DISP_MODULE_ENUM mem_module; disp_ddp_path_config last_config; }ddp_path_handle_t, *ddp_path_handle; typedef struct { int handle_cnt; int mutex_idx; int power_sate; struct mutex mutex_lock; int module_usage_table[DISP_MODULE_NUM]; ddp_path_handle module_path_table[DISP_MODULE_NUM]; ddp_path_handle handle_pool[DDP_MAX_MANAGER_HANDLE]; }DDP_MANAGER_CONTEXT; #define DEFAULT_IRQ_EVENT_SCENARIO (4) static DDP_IRQ_EVENT_MAPPING ddp_irq_event_list[DEFAULT_IRQ_EVENT_SCENARIO][DISP_PATH_EVENT_NUM] = { {//ovl0 path {DDP_IRQ_RDMA0_DONE }, /*FRAME_DONE*/ {DDP_IRQ_RDMA0_START }, /*FRAME_START*/ {DDP_IRQ_RDMA0_REG_UPDATE }, /*FRAME_REG_UPDATE*/ {DDP_IRQ_RDMA0_TARGET_LINE }, /*FRAME_TARGET_LINE*/ {DDP_IRQ_WDMA0_FRAME_COMPLETE}, /*FRAME_COMPLETE*/ {DDP_IRQ_RDMA0_TARGET_LINE }, /*FRAME_STOP*/ {DDP_IRQ_RDMA0_REG_UPDATE }, /*IF_CMD_DONE*/ {DDP_IRQ_DSI0_EXT_TE }, /*IF_VSYNC*/ {DDP_IRQ_UNKNOW }, /*TRIGER*/ {DDP_IRQ_AAL_OUT_END_FRAME }, /*AAL_OUT_END_EVENT*/ }, {//ovl1 path {DDP_IRQ_RDMA1_DONE }, /*FRAME_DONE*/ {DDP_IRQ_RDMA1_START }, /*FRAME_START*/ {DDP_IRQ_RDMA1_REG_UPDATE }, /*FRAME_REG_UPDATE*/ {DDP_IRQ_RDMA1_TARGET_LINE }, /*FRAME_TARGET_LINE*/ {DDP_IRQ_WDMA1_FRAME_COMPLETE}, /*FRAME_COMPLETE*/ {DDP_IRQ_RDMA1_TARGET_LINE }, /*FRAME_STOP*/ {DDP_IRQ_RDMA1_REG_UPDATE }, /*IF_CMD_DONE*/ {DDP_IRQ_RDMA1_TARGET_LINE }, /*IF_VSYNC*/ {DDP_IRQ_UNKNOW }, /*TRIGER*/ {DDP_IRQ_UNKNOW }, /*AAL_OUT_END_EVENT*/ }, { // rdma path {DDP_IRQ_RDMA2_DONE }, /*FRAME_DONE*/ {DDP_IRQ_RDMA2_START }, /*FRAME_START*/ {DDP_IRQ_RDMA2_REG_UPDATE }, /*FRAME_REG_UPDATE*/ {DDP_IRQ_RDMA2_TARGET_LINE }, /*FRAME_TARGET_LINE*/ {DDP_IRQ_UNKNOW }, /*FRAME_COMPLETE*/ {DDP_IRQ_RDMA2_TARGET_LINE }, /*FRAME_STOP*/ {DDP_IRQ_RDMA2_REG_UPDATE }, /*IF_CMD_DONE*/ {DDP_IRQ_RDMA2_TARGET_LINE }, /*IF_VSYNC*/ {DDP_IRQ_UNKNOW }, /*TRIGER*/ {DDP_IRQ_UNKNOW }, /*AAL_OUT_END_EVENT*/ }, {//ovl0 path {DDP_IRQ_RDMA0_DONE }, /*FRAME_DONE*/ {DDP_IRQ_MUTEX1_SOF}, /*FRAME_START*/ {DDP_IRQ_RDMA0_REG_UPDATE }, /*FRAME_REG_UPDATE*/ {DDP_IRQ_RDMA0_TARGET_LINE }, /*FRAME_TARGET_LINE*/ {DDP_IRQ_WDMA0_FRAME_COMPLETE}, /*FRAME_COMPLETE*/ {DDP_IRQ_RDMA0_TARGET_LINE }, /*FRAME_STOP*/ {DDP_IRQ_RDMA0_REG_UPDATE }, /*IF_CMD_DONE*/ {DDP_IRQ_DSI0_EXT_TE }, /*IF_VSYNC*/ {DDP_IRQ_UNKNOW }, /*TRIGER*/ {DDP_IRQ_AAL_OUT_END_FRAME }, /*AAL_OUT_END_EVENT*/ } }; static char * path_event_name(DISP_PATH_EVENT event) { switch(event) { case DISP_PATH_EVENT_FRAME_START: return "FRAME_START"; case DISP_PATH_EVENT_FRAME_DONE: return "FRAME_DONE"; case DISP_PATH_EVENT_FRAME_REG_UPDATE: return "REG_UPDATE"; case DISP_PATH_EVENT_FRAME_TARGET_LINE: return "TARGET_LINE"; case DISP_PATH_EVENT_FRAME_COMPLETE: return "FRAME COMPLETE"; case DISP_PATH_EVENT_FRAME_STOP: return "FRAME_STOP"; case DISP_PATH_EVENT_IF_CMD_DONE: return "FRAME_STOP"; case DISP_PATH_EVENT_IF_VSYNC: return "VSYNC"; case DISP_PATH_EVENT_TRIGGER: return "TRIGGER"; default: return "unknow event"; } return "unknow event"; } static DDP_MANAGER_CONTEXT* _get_context(void) { static int is_context_inited = 0; static DDP_MANAGER_CONTEXT context; if(!is_context_inited) { memset((void*)&context, 0, sizeof(DDP_MANAGER_CONTEXT)); context.mutex_idx = (1<power_sate) { for(i=0; i< DDP_MAX_MANAGER_HANDLE; i++) { if(context->handle_pool[i] != NULL && context->handle_pool[i]->power_sate !=0) { return 0; } } context->power_sate = 0; ddp_path_top_clock_off(); } return 0; } static int path_top_clock_on(void) { DDP_MANAGER_CONTEXT * context = _get_context(); if(!context->power_sate) { context->power_sate = 1; ddp_path_top_clock_on(); } return 0; } static int module_power_off(DISP_MODULE_ENUM module) { if(module == DISP_MODULE_DSI0) { return 0; } if(ddp_modules_driver[module] != 0) { if(ddp_modules_driver[module]->power_off!= 0) { DISP_LOG_V("%s power off\n",ddp_get_module_name(module)); ddp_modules_driver[module]->power_off(module, NULL); // now just 0; } } return 0; } static int module_power_on(DISP_MODULE_ENUM module) { if(module == DISP_MODULE_DSI0) { /*bypass dsi*/ return 0; } if(ddp_modules_driver[module] != 0) { if(ddp_modules_driver[module]->power_on!= 0) { DISP_LOG_V("%s power on\n",ddp_get_module_name(module)); ddp_modules_driver[module]->power_on(module, NULL); // now just 0; } } return 0; } static ddp_path_handle find_handle_by_module(DISP_MODULE_ENUM module) { return _get_context()->module_path_table[module]; } 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); return 0; } static int assign_default_irqs_table(DDP_SCENARIO_ENUM scenario,DDP_IRQ_EVENT_MAPPING * irq_events) { int idx = 0; switch(scenario) { case DDP_SCENARIO_PRIMARY_DISP: case DDP_SCENARIO_PRIMARY_RDMA0_COLOR0_DISP: case DDP_SCENARIO_PRIMARY_RDMA0_DISP: case DDP_SCENARIO_PRIMARY_BYPASS_RDMA: case DDP_SCENARIO_PRIMARY_DITHER_MEMOUT: case DDP_SCENARIO_PRIMARY_UFOE_MEMOUT: case DDP_SCENARIO_PRIMARY_ALL: case DDP_SCENARIO_MULTIPLE_OVL: idx = 0; break; case DDP_SCENARIO_SUB_DISP: case DDP_SCENARIO_SUB_RDMA1_DISP: case DDP_SCENARIO_SUB_OVL_MEMOUT: case DDP_SCENARIO_SUB_ALL: #ifdef CONFIG_SINGLE_PANEL_OUTPUT idx = 0; #else idx = 1; #endif break; case DDP_SCENARIO_PRIMARY_OVL_MEMOUT: idx = 3; break; default: DISP_LOG_E("unknow scenario %d\n",scenario); } DISP_LOG_I("assign default irqs table index %d\n",idx); memcpy(irq_events,ddp_irq_event_list[idx],sizeof(ddp_irq_event_list[idx])); return 0; } static int acquire_free_bit(unsigned int total) { int free_id =0 ; while(total) { if(total & 0x1) { return free_id; } total>>=1; ++free_id; } return -1; } static int acquire_mutex(DDP_SCENARIO_ENUM scenario) { ///: primay use mutex 0 int mutex_id =0 ; DDP_MANAGER_CONTEXT * content = _get_context(); int mutex_idx_free = content->mutex_idx; ASSERT(scenario >= 0 && scenario < DDP_SCENARIO_MAX); while(mutex_idx_free) { if(mutex_idx_free & 0x1) { content->mutex_idx &= (~(0x1<>=1; ++mutex_id; } ASSERT(mutex_id < (DISP_MUTEX_DDP_FIRST+DISP_MUTEX_DDP_COUNT)); DISP_LOG_I("scenario %s acquire mutex %d , left mutex 0x%x!\n", ddp_get_scenario_name(scenario), mutex_id, content->mutex_idx); return mutex_id; } static int release_mutex(int mutex_idx) { DDP_MANAGER_CONTEXT * content = _get_context(); ASSERT(mutex_idx < (DISP_MUTEX_DDP_FIRST+DISP_MUTEX_DDP_COUNT)); content->mutex_idx |= 1<< (mutex_idx-DISP_MUTEX_DDP_FIRST); DISP_LOG_I("release mutex %d , left mutex 0x%x!\n", mutex_idx, content->mutex_idx); return 0; } int dpmgr_path_set_video_mode(disp_path_handle dp_handle, int is_vdo_mode) { ddp_path_handle handle = NULL; ASSERT(dp_handle != NULL); handle = (ddp_path_handle)dp_handle; handle->mode = is_vdo_mode ? DDP_VIDEO_MODE : DDP_CMD_MODE; DISP_LOG_I("set scenario %s mode: %s\n",ddp_get_scenario_name(handle->scenario), is_vdo_mode ? "Video_Mode":"Cmd_Mode"); return 0; } unsigned long hw_mutex_id_to_handle_map[128]; disp_path_handle dpmgr_create_path(DDP_SCENARIO_ENUM scenario, cmdqRecHandle cmdq_handle) { int i =0; int module_name ; ddp_path_handle path_handle = NULL; int * modules = ddp_get_scenario_list(scenario); int module_num = ddp_get_module_num(scenario); DDP_MANAGER_CONTEXT * content = _get_context(); path_handle = kzalloc(sizeof(uint8_t*) * sizeof(ddp_path_handle_t), GFP_KERNEL); if (NULL != path_handle) { path_handle->cmdqhandle = cmdq_handle; path_handle->scenario = scenario; path_handle->hwmutexid = acquire_mutex(scenario); assign_default_irqs_table(scenario,path_handle->irq_event_map); DISP_LOG_I("create handle %p on scenario %s\n",path_handle,ddp_get_scenario_name(scenario)); for( i=0; i< module_num;i++) { module_name = modules[i]; DISP_LOG_I(" scenario %s include module %s\n",ddp_get_scenario_name(scenario),ddp_get_module_name(module_name)); content->module_usage_table[module_name]++; content->module_path_table[module_name] = path_handle; } hw_mutex_id_to_handle_map[path_handle->hwmutexid] = path_handle; content->handle_cnt ++; content->handle_pool[path_handle->hwmutexid] = path_handle; } else { DISP_LOG_E("Fail to create handle on scenario %s\n",ddp_get_scenario_name(scenario)); } return path_handle; } // please ensure thread/irq safe by caller int dpmgr_modify_path(disp_path_handle dp_handle, DDP_SCENARIO_ENUM new_scenario, cmdqRecHandle cmdq_handle, DDP_MODE isvdomode) { int i =0; int module_name = 0; DISP_MODULE_ENUM module[DISP_MODULE_NUM]={0}; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DDP_MANAGER_CONTEXT * content = _get_context(); DDP_SCENARIO_ENUM old_scenario = handle->scenario; int *new_modules = ddp_get_scenario_list(new_scenario); int new_module_num = ddp_get_module_num(new_scenario); int *old_modules = ddp_get_scenario_list(old_scenario); int old_module_num = ddp_get_module_num(old_scenario); handle->cmdqhandle = cmdq_handle; handle->scenario = new_scenario; DISP_LOG_I("modify handle %p from %s to %s\n", handle, ddp_get_scenario_name(old_scenario), ddp_get_scenario_name(new_scenario)); for(i=0; i< new_module_num;i++) { module_name = new_modules[i]; module[module_name] ++; if(content->module_usage_table[module_name] == 0) { content->module_usage_table[module_name]++; DISP_LOG_D("add module %s\n", ddp_get_module_name(module_name)); content->module_path_table[module_name] = handle; module_power_on(module_name); } } for(i=0; i< old_module_num;i++) { module_name = old_modules[i]; if(module[module_name] == 0) { content->module_usage_table[module_name]--; DISP_LOG_D("remove module %s\n", ddp_get_module_name(module_name)); content->module_path_table[module_name] = NULL; module_power_off(module_name); } } // mutex set will clear old settings ddp_mutex_set(handle->hwmutexid, new_scenario, isvdomode, cmdq_handle); ddp_mutex_Interrupt_enable(handle->hwmutexid, cmdq_handle); // disconnect old path first ddp_disconnect_path(old_scenario,cmdq_handle); // connect new path ddp_connect_path(new_scenario,cmdq_handle); return 0; } int dpmgr_destroy_path(disp_path_handle dp_handle, cmdqRecHandle cmdq_handle) { int i =0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DDP_MANAGER_CONTEXT * content = _get_context(); DISP_LOG_I("destroy path handle %p on scenario %s\n",handle,ddp_get_scenario_name(handle->scenario)); if(handle != NULL) { release_mutex(handle->hwmutexid); ddp_disconnect_path(handle->scenario,cmdq_handle); for( i=0; i< module_num;i++) { module_name = modules[i]; content->module_usage_table[module_name]--; content->module_path_table[module_name] = NULL; } content->handle_cnt --; ASSERT(content->handle_cnt >=0); content->handle_pool[handle->hwmutexid] = NULL; kfree(handle); } return 0; } int dpmgr_path_memout_clock(disp_path_handle dp_handle, int clock_switch) { #if 0 ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; handle->mem_module = ddp_is_scenario_on_primary(handle->scenario) ? DISP_MODULE_WDMA0: DISP_MODULE_WDMA1; if(handle->mem_module == DISP_MODULE_WDMA0 || handle->mem_module ==DISP_MODULE_WDMA1) { if(ddp_modules_driver[handle->mem_module] != 0) { if(clock_switch) { if(ddp_modules_driver[handle->mem_module]->power_on!= 0) { ddp_modules_driver[handle->mem_module]->power_on(handle->mem_module, NULL); } } else { if(ddp_modules_driver[handle->mem_module]->power_off!= 0) { ddp_modules_driver[handle->mem_module]->power_off(handle->mem_module, NULL); } handle->mem_module = DISP_MODULE_UNKNOWN; } } return 0; } return -1; #endif return 0; } int dpmgr_path_add_memout(disp_path_handle dp_handle, ENGINE_DUMP engine,void * cmdq_handle ) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; ASSERT(handle->scenario ==DDP_SCENARIO_PRIMARY_DISP || handle->scenario ==DDP_SCENARIO_SUB_DISP || handle->scenario ==DDP_SCENARIO_PRIMARY_OVL_MEMOUT || handle->scenario ==DDP_SCENARIO_PRIMARY_ALL); DISP_MODULE_ENUM wdma = ddp_is_scenario_on_primary(handle->scenario) ? DISP_MODULE_WDMA0: DISP_MODULE_WDMA1; if(ddp_is_module_in_scenario(handle->scenario, wdma)==1) { DDPERR("dpmgr_path_add_memout error, wdma is already in scenario=%s \n", ddp_get_scenario_name(handle->scenario)); // ASSERT(0); return -1; } // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[wdma]++; context->module_path_table[wdma] = handle; handle->scenario = DDP_SCENARIO_PRIMARY_ALL; // update connected ddp_connect_path(handle->scenario,cmdq_handle); ddp_mutex_set(handle->hwmutexid, handle->scenario, handle->mode, cmdq_handle); //wdma just need start. if(ddp_modules_driver[wdma] != 0) { if(ddp_modules_driver[wdma]->power_on!= 0) { ddp_modules_driver[wdma]->power_on(wdma, cmdq_handle); } if(ddp_modules_driver[wdma]->start!= 0) { ddp_modules_driver[wdma]->start(wdma, cmdq_handle); } } return 0; } int dpmgr_path_remove_memout(disp_path_handle dp_handle, void * cmdq_handle) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; ASSERT(handle->scenario ==DDP_SCENARIO_PRIMARY_DISP || handle->scenario ==DDP_SCENARIO_PRIMARY_ALL || handle->scenario ==DDP_SCENARIO_SUB_DISP || handle->scenario ==DDP_SCENARIO_SUB_ALL); DISP_MODULE_ENUM wdma = ddp_is_scenario_on_primary(handle->scenario) ? DISP_MODULE_WDMA0: DISP_MODULE_WDMA1; if(ddp_is_module_in_scenario(handle->scenario, wdma)==0) { DDPERR("dpmgr_path_remove_memout error, wdma is not in scenario=%s \n", ddp_get_scenario_name(handle->scenario)); // ASSERT(0); return -1; } // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[wdma]--; context->module_path_table[wdma] = 0; //wdma just need stop if(ddp_modules_driver[wdma] != 0) { if(ddp_modules_driver[wdma]->stop!= 0) { ddp_modules_driver[wdma]->stop(wdma, cmdq_handle); } if(ddp_modules_driver[wdma]->deinit!= 0) { ddp_modules_driver[wdma]->deinit(wdma, cmdq_handle); } } ddp_disconnect_path(DDP_SCENARIO_PRIMARY_OVL_MEMOUT,cmdq_handle); handle->scenario = DDP_SCENARIO_PRIMARY_DISP; // update connected ddp_connect_path(handle->scenario,cmdq_handle); ddp_mutex_set(handle->hwmutexid, handle->scenario, handle->mode, cmdq_handle); return 0; } int dpmgr_insert_ovl1_sub(disp_path_handle dp_handle, void * cmdq_handle) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; if((handle->scenario != DDP_SCENARIO_SUB_RDMA1_DISP) && (handle->scenario != DDP_SCENARIO_SUB_DISP)) { DDPERR("dpmgr_insert_ovl1_sub error, handle->scenario=%s \n", ddp_get_scenario_name(handle->scenario)); return -1; } if(ddp_is_module_in_scenario(handle->scenario, DISP_MODULE_OVL1) == 1) { return -1; } DDPMSG("dpmgr_insert_ovl1_sub \n"); // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[DISP_MODULE_OVL1]++; context->module_path_table[DISP_MODULE_OVL1] = handle; // update connected ddp_connect_path(DDP_SCENARIO_SUB_DISP, cmdq_handle); ddp_mutex_set(handle->hwmutexid, DDP_SCENARIO_SUB_DISP, handle->mode, cmdq_handle); handle->scenario = DDP_SCENARIO_SUB_DISP; //ovl1 just need start. if(ddp_modules_driver[DISP_MODULE_OVL1] != 0) { if(ddp_modules_driver[DISP_MODULE_OVL1]->init!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->init(DISP_MODULE_OVL1, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->start!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->start(DISP_MODULE_OVL1, cmdq_handle); } } ovl_set_status(DDP_OVL1_STATUS_SUB); return 0; } int dpmgr_remove_ovl1_sub(disp_path_handle dp_handle, void * cmdq_handle) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; if((handle->scenario != DDP_SCENARIO_SUB_RDMA1_DISP) && (handle->scenario != DDP_SCENARIO_SUB_DISP)) { DDPERR("dpmgr_remove_ovl1_sub error, handle->scenario=%s \n", ddp_get_scenario_name(handle->scenario)); return -1; } if(ddp_is_module_in_scenario(handle->scenario, DISP_MODULE_OVL1) == 0) { return -1; } DDPMSG("dpmgr_remove_ovl1_sub \n"); // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[DISP_MODULE_OVL1]--; context->module_path_table[DISP_MODULE_OVL1] = 0; ddp_disconnect_path(handle->scenario,cmdq_handle); ddp_connect_path(DDP_SCENARIO_SUB_RDMA1_DISP,cmdq_handle); ddp_mutex_set(handle->hwmutexid, DDP_SCENARIO_SUB_RDMA1_DISP, handle->mode, cmdq_handle); handle->scenario = DDP_SCENARIO_SUB_RDMA1_DISP; //ovl1 just need stop if(ddp_modules_driver[DISP_MODULE_OVL1] != 0) { if(ddp_modules_driver[DISP_MODULE_OVL1]->stop!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->stop(DISP_MODULE_OVL1, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->deinit!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->deinit(DISP_MODULE_OVL1, cmdq_handle); } } return 0; } disp_path_handle g_dp_handle; void * g_cmdq_handle; int dpmgr_path_get_handle(unsigned int* dp_handle, unsigned int* cmdq_handle) { *dp_handle = (unsigned long)g_dp_handle; *cmdq_handle = (unsigned long)g_cmdq_handle; } int dpmgr_path_enable_cascade(disp_path_handle dp_handle, void * cmdq_handle ) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; // udpate handle { g_dp_handle = dp_handle; g_cmdq_handle = cmdq_handle; } if((handle->scenario !=DDP_SCENARIO_PRIMARY_DISP) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_ALL) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_DITHER_MEMOUT) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_OVL_MEMOUT)) { DDPERR("dpmgr_path_enable_cascade error, handle->scenario=%s \n", ddp_get_scenario_name(handle->scenario)); //ASSERT(0); return -1; } if(ddp_is_module_in_scenario(handle->scenario, DISP_MODULE_OVL1)==1) { //DDPERR("dpmgr_path_enable_cascade error, OVL1 is already in scenario=%s \n", ddp_get_scenario_name(handle->scenario)); // ASSERT(0); ovl_set_status(DDP_OVL1_STATUS_PRIMARY); return -1; } DDPMSG("dpmgr_path_enable_cascade %s\n",ddp_get_scenario_name(handle->scenario)); // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[DISP_MODULE_OVL1]++; context->module_path_table[DISP_MODULE_OVL1] = handle; // update connected //ddp_insert_module(handle->scenario, DISP_MODULE_OVL0, DISP_MODULE_OVL1); ddp_insert_module(DDP_SCENARIO_PRIMARY_DISP, DISP_MODULE_OVL0, DISP_MODULE_OVL1); ddp_insert_module(DDP_SCENARIO_PRIMARY_ALL, DISP_MODULE_OVL0, DISP_MODULE_OVL1); ddp_insert_module(DDP_SCENARIO_PRIMARY_OVL_MEMOUT, DISP_MODULE_OVL0, DISP_MODULE_OVL1); ddp_insert_module(DDP_SCENARIO_PRIMARY_DITHER_MEMOUT, DISP_MODULE_OVL0, DISP_MODULE_OVL1); ddp_connect_path(DDP_SCENARIO_MULTIPLE_OVL, cmdq_handle); ddp_connect_path(handle->scenario, cmdq_handle); ddp_mutex_add_module(handle->hwmutexid, DISP_MODULE_OVL1, cmdq_handle); //ovl1 just need start. if(ddp_modules_driver[DISP_MODULE_OVL1] != 0) { if(ddp_modules_driver[DISP_MODULE_OVL1]->cmd!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->cmd(DISP_MODULE_OVL1, DISP_IOCTL_OVL_ENABLE_CASCADE, 0, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->init!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->init(DISP_MODULE_OVL1, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->start!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->start(DISP_MODULE_OVL1, cmdq_handle); } } if(ovl_get_status()!=DDP_OVL1_STATUS_PRIMARY && ovl_get_status()!=DDP_OVL1_STATUS_SUB_REQUESTING) // from primary-with-OVL1 to primary_all-with-OVL1 should not rebuild trigger loop cmdq { ovl_set_status(DDP_OVL1_STATUS_PRIMARY); } MMProfileLogEx(ddp_mmp_get_events()->cascade_enable, MMProfileFlagPulse, 0, 0); return 0; } int dpmgr_path_disable_cascade(disp_path_handle dp_handle, void * cmdq_handle) { int ret = 0; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; if((handle->scenario !=DDP_SCENARIO_PRIMARY_DISP) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_ALL) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_DITHER_MEMOUT) && ( handle->scenario !=DDP_SCENARIO_PRIMARY_OVL_MEMOUT)) { DDPERR("dpmgr_path_disable_cascade error, handle->scenario=%s \n", ddp_get_scenario_name(handle->scenario)); // ASSERT(0); return -1; } if(ddp_is_module_in_scenario(handle->scenario, DISP_MODULE_OVL1)==0) { //DDPERR("dpmgr_path_disable_cascade error, OVL1 is not in scenario=%s \n", ddp_get_scenario_name(handle->scenario)); // ASSERT(0); return -1; } DDPMSG("dpmgr_path_disable_cascade %s\n",ddp_get_scenario_name(handle->scenario)); // update contxt DDP_MANAGER_CONTEXT * context = _get_context(); context->module_usage_table[DISP_MODULE_OVL1]--; context->module_path_table[DISP_MODULE_OVL1] = 0; ddp_disconnect_path(DDP_SCENARIO_MULTIPLE_OVL, cmdq_handle); //ddp_remove_module(handle->scenario, DISP_MODULE_OVL1); ddp_remove_module(DDP_SCENARIO_PRIMARY_DISP, DISP_MODULE_OVL1); ddp_remove_module(DDP_SCENARIO_PRIMARY_ALL, DISP_MODULE_OVL1); ddp_remove_module(DDP_SCENARIO_PRIMARY_OVL_MEMOUT, DISP_MODULE_OVL1); ddp_remove_module(DDP_SCENARIO_PRIMARY_DITHER_MEMOUT, DISP_MODULE_OVL1); ddp_mutex_remove_module(handle->hwmutexid, DISP_MODULE_OVL1, cmdq_handle); //ovl1 just need stop if(ddp_modules_driver[DISP_MODULE_OVL1] != 0) { if(ddp_modules_driver[DISP_MODULE_OVL1]->cmd!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->cmd(DISP_MODULE_OVL1, DISP_IOCTL_OVL_DISABLE_CASCADE, 0, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->stop!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->stop(DISP_MODULE_OVL1, cmdq_handle); } if(ddp_modules_driver[DISP_MODULE_OVL1]->deinit!= 0) { ddp_modules_driver[DISP_MODULE_OVL1]->deinit(DISP_MODULE_OVL1, cmdq_handle); } } MMProfileLogEx(ddp_mmp_get_events()->cascade_disable, MMProfileFlagPulse, 0, 0); return 0; } int dpmgr_path_release_8_layer_fence() { unsigned int i=0; for(i=OVL_LAYER_NUM_PER_OVL; iscenario >= 0 && handle->scenario < DDP_SCENARIO_MAX)); DISP_LOG_I("set dst module on scenario %s, module %s\n", ddp_get_scenario_name(handle->scenario),ddp_get_module_name(dst_module)); return ddp_set_dst_module(handle->scenario, dst_module); } int dpmgr_path_get_mutex(disp_path_handle dp_handle) { ddp_path_handle handle = NULL; ASSERT(dp_handle != NULL); handle = (ddp_path_handle)dp_handle; return handle->hwmutexid; } DISP_MODULE_ENUM dpmgr_path_get_dst_module(disp_path_handle dp_handle) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; ASSERT((handle->scenario >= 0 && handle->scenario < DDP_SCENARIO_MAX)); DISP_MODULE_ENUM dst_module = ddp_get_dst_module(handle->scenario); DISP_LOG_V("get dst module on scenario %s, module %s\n", ddp_get_scenario_name(handle->scenario),ddp_get_module_name(dst_module)); return dst_module; } int dpmgr_path_connect(disp_path_handle dp_handle, int encmdq) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("dpmgr_path_connect on scenario %s\n",ddp_get_scenario_name(handle->scenario)); ddp_connect_path(handle->scenario,cmdqHandle); ddp_mutex_set(handle->hwmutexid, handle->scenario, handle->mode, cmdqHandle); ddp_mutex_Interrupt_enable(handle->hwmutexid,cmdqHandle); return 0; } int dpmgr_path_disconnect(disp_path_handle dp_handle, int encmdq) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("dpmgr_path_disconnect on scenario %s\n",ddp_get_scenario_name(handle->scenario)); ddp_mutex_clear(handle->hwmutexid,cmdqHandle); ddp_mutex_Interrupt_disable(handle->hwmutexid,cmdqHandle); ddp_disconnect_path(handle->scenario, cmdqHandle); return 0; } int dpmgr_path_init(disp_path_handle dp_handle, int encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path init on scenario %s\n",ddp_get_scenario_name(handle->scenario)); //open top clock path_top_clock_on(); //seting mutex ddp_mutex_set(handle->hwmutexid, handle->scenario, handle->mode, cmdqHandle); ddp_mutex_Interrupt_enable(handle->hwmutexid,cmdqHandle); //connect path; ddp_connect_path(handle->scenario,cmdqHandle); // each module init for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->init!= 0) { DISP_LOG_I("scenario %s init module %s\n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->init(module_name, cmdqHandle); } if(ddp_modules_driver[module_name]->set_listener!= 0) { ddp_modules_driver[module_name]->set_listener(module_name,dpmgr_module_notify); } } } //after init this path will power on; handle->power_sate = 1; return 0; } int dpmgr_path_deinit(disp_path_handle dp_handle, int encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path deinit on scenario %s\n",ddp_get_scenario_name(handle->scenario)); ddp_mutex_Interrupt_disable(handle->hwmutexid,cmdqHandle); ddp_mutex_clear(handle->hwmutexid,cmdqHandle); ddp_disconnect_path(handle->scenario, cmdqHandle); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->deinit!= 0) { DISP_LOG_I("scenario %s deinit module %s\n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->deinit(module_name, cmdqHandle); } if(ddp_modules_driver[module_name]->set_listener!= 0) { ddp_modules_driver[module_name]->set_listener(module_name,NULL); } } } handle->power_sate = 0; //close top clock when last path init path_top_clock_off(); return 0; } int dpmgr_path_start(disp_path_handle dp_handle, int encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path start on scenario %s\n",ddp_get_scenario_name(handle->scenario)); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->start!= 0) { DISP_LOG_V("scenario %s start module %s\n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->start(module_name, cmdqHandle); } } } return 0; } int dpmgr_path_stop(disp_path_handle dp_handle, int encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path stop on scenario %s\n",ddp_get_scenario_name(handle->scenario)); for( i=module_num-1; i>=0;i--) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->stop!= 0) { DISP_LOG_V("scenario %s stop module %s \n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->stop(module_name, cmdqHandle); } } } return 0; } int dpmgr_path_ioctl(disp_path_handle dp_handle, void * cmdq_handle, DDP_IOCTL_NAME ioctl_cmd, unsigned long *params) { int i=0; int ret = 0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("path IOCTL on scenario %s\n",ddp_get_scenario_name(handle->scenario)); for( i=module_num-1; i >= 0 ;i--) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->ioctl!= 0) { printk("scenario %s, module %s ioctl\n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ret += ddp_modules_driver[module_name]->ioctl(module_name, cmdq_handle, (unsigned int)ioctl_cmd, params); } } } return ret; } #ifdef CONFIG_SINGLE_PANEL_OUTPUT int dpmgr_reset_module_handle(disp_path_handle dp_handle) { ddp_path_handle path_handle = NULL; int module_name; int i; ASSERT(dp_handle != NULL); path_handle=(ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(path_handle->scenario); int module_num = ddp_get_module_num(path_handle->scenario); DDP_MANAGER_CONTEXT * content = _get_context(); for( i=0; i< module_num; i++) { module_name = modules[i]; DISP_LOG_I(" scenario %s reset module %s handle\n", ddp_get_scenario_name(path_handle->scenario), ddp_get_module_name(module_name)); content->module_path_table[module_name] = path_handle; } return 0; } #endif int dpmgr_path_reset(disp_path_handle dp_handle, int encmdq) { int i=0; int ret = 0; int error = 0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path reset on scenario %s\n",ddp_get_scenario_name(handle->scenario)); /* first reset mutex */ ddp_mutex_reset(handle->hwmutexid,cmdqHandle); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->reset != 0) { DISP_LOG_I("scenario %s reset module %s \n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ret = ddp_modules_driver[module_name]->reset(module_name, cmdqHandle); if(ret != 0) { error++; } } } } return error > 0? -1: 0; } static int dpmgr_layer_num(disp_ddp_path_config * config) { int i=0; int max_layer = 0; for (i = 0; i < OVL_LAYER_NUM; i++) { if (config->ovl_config[i].layer_en != 0){ if(config->ovl_config[i].layer+1 > max_layer) max_layer = config->ovl_config[i].layer+1; } } return max_layer; } static unsigned int dpmgr_is_PQ(DISP_MODULE_ENUM module) { unsigned int isPQ = 0; switch(module) { case DISP_MODULE_COLOR0: case DISP_MODULE_CCORR : case DISP_MODULE_AAL : case DISP_MODULE_GAMMA : case DISP_MODULE_DITHER: //case DISP_MODULE_UFOE : //case DISP_MODULE_PWM0 : isPQ = 1; break; default: isPQ = 0; } return isPQ; } extern int is_DAL_Enabled(void); int dpmgr_path_config(disp_path_handle dp_handle, disp_ddp_path_config * config, void * cmdq_handle) { int i=0; int ret = 0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); memcpy(&handle->last_config, config, sizeof(disp_ddp_path_config)); // switch between single and dual ovl mode #ifdef OVL_CASCADE_SUPPORT if((config->ovl_dirty==1) && (ovl_get_status()==DDP_OVL1_STATUS_IDLE)/* && dpmgr_layer_num(config)>=4*/) { //DDPMSG("cascade switch, call dpmgr_path_enable_cascade() in dpmgr_path_config()"); dpmgr_path_enable_cascade(dp_handle, cmdq_handle); module_num = ddp_get_module_num(handle->scenario); } else if((config->ovl_dirty==1) && (ovl_get_status()==DDP_OVL1_STATUS_SUB_REQUESTING)) { int enable_layers = dpmgr_layer_num(config); if(enable_layers <= 4) { DDPMSG("cascade switch, call dpmgr_path_disable_cascade() in dpmgr_path_config() %d\n", enable_layers); dpmgr_path_disable_cascade(dp_handle, cmdq_handle); module_num = ddp_get_module_num(handle->scenario); ovl_set_status(DDP_OVL1_STATUS_PRIMARY_RELEASING); } else { DDPMSG("cascade: in path_config(), split ovl1 fail, enable_layers=%d\n", enable_layers); } } #endif for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { #ifndef CONFIG_FPGA_EARLY_PORTING #ifdef CONFIG_FOR_SOURCE_PQ if (module_name == DISP_MODULE_COLOR0) { extern void set_color_bypass(DISP_MODULE_ENUM module, int bypass, void* cmdq_handle); set_color_bypass(DISP_MODULE_COLOR0, 1, cmdq_handle); } #endif if(gDDPError==1 && dpmgr_is_PQ(module_name)==1) #endif { if(ddp_modules_driver[module_name]->bypass!=NULL) { ddp_modules_driver[module_name]->bypass(module_name, 1); //DDPMSG("-- bypass %s\n", ddp_get_module_name(module_name)); } } #ifndef CONFIG_FPGA_EARLY_PORTING else if(ddp_modules_driver[module_name]->config!= 0) #else if(ddp_modules_driver[module_name]->config!= 0) #endif { DISP_LOG_V("scenario %s config module %s \n",ddp_get_scenario_name(handle->scenario), ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->config(module_name, config, cmdq_handle); } } } #ifdef OVL_CASCADE_SUPPORT if(ovl_get_status()==DDP_OVL1_STATUS_PRIMARY_RELEASING) { ovl_set_status(DDP_OVL1_STATUS_PRIMARY_RELEASED); } if(config->ovl_dirty==1 && dpmgr_layer_num(config)==0 && disp_get_session_number()>1 && ovl_get_status()!=DDP_OVL1_STATUS_SUB && ovl_get_status()!=DDP_OVL1_STATUS_IDLE) // all 8 layer disabled { DDPMSG("disable cascade if 8 layer all disabled! \n"); allLayerDisabled = 1; ret = dpmgr_path_disable_cascade(dp_handle, cmdq_handle); allLayerDisabled = 0; ALL_LAYER_DISABLE_STEP = 1; if(ret == 0 && ovl_get_status()==DDP_OVL1_STATUS_PRIMARY) { ovl_set_status(DDP_OVL1_STATUS_PRIMARY_DISABLE); } } #endif return 0; } disp_ddp_path_config *dpmgr_path_get_last_config(disp_path_handle dp_handle) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; handle->last_config.ovl_dirty =0; handle->last_config.rdma_dirty =0; handle->last_config.wdma_dirty =0; handle->last_config.dst_dirty =0; return &handle->last_config; } void dpmgr_get_input_address(disp_path_handle dp_handle, unsigned long * addr) { ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); if (modules[0] == DISP_MODULE_OVL0 || modules[0] == DISP_MODULE_OVL1){ ovl_get_address(modules[0],addr); }else if(modules[0] == DISP_MODULE_RDMA0 || modules[0] == DISP_MODULE_RDMA1 || modules[0] == DISP_MODULE_RDMA2){ rdma_get_address(modules[0],addr); } return ; } int dpmgr_path_build_cmdq(disp_path_handle dp_handle, void *trigger_loop_handle, CMDQ_STATE state) { int ret = 0; int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DDP_SCENARIO_ENUM scenario = handle->scenario; int * modules = ddp_get_scenario_list(scenario); int module_num = ddp_get_module_num(scenario); DISP_LOG_D("path build cmdq on scenario %s\n",ddp_get_scenario_name(scenario)); #if defined(MANUAL_MUTEX_HW_DCM) if (state == CMDQ_BEFORE_STREAM_SOF) { ddp_mutex_hw_dcm_off(handle->hwmutexid,trigger_loop_handle); } if (state == CMDQ_AFTER_STREAM_EOF) { ddp_mutex_hw_dcm_on(handle->hwmutexid,trigger_loop_handle); } #endif for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->build_cmdq!= 0) { DISP_LOG_D("%s build cmdq, state=%d\n",ddp_get_module_name(module_name), state); ret = ddp_modules_driver[module_name]->build_cmdq(module_name, trigger_loop_handle, state); // now just 0; } } } return ret; } int dpmgr_path_trigger(disp_path_handle dp_handle, void *trigger_loop_handle, int encmdq) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DISP_LOG_V("dpmgr_path_trigger on scenario %s\n",ddp_get_scenario_name(handle->scenario)); cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; int i=0; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); int module_name ; ddp_mutex_enable(handle->hwmutexid,handle->scenario,trigger_loop_handle); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->trigger!= 0) { DISP_LOG_V("%s trigger\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->trigger(module_name, trigger_loop_handle); } } } return 0; } int dpmgr_path_flush(disp_path_handle dp_handle,int encmdq) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; cmdqRecHandle cmdqHandle = encmdq ? handle->cmdqhandle : NULL; DISP_LOG_I("path flush on scenario %s\n",ddp_get_scenario_name(handle->scenario)); return ddp_mutex_enable(handle->hwmutexid,handle->scenario,cmdqHandle); } int dpmgr_wdma_path_force_power_off(void) { int i=0; int module_name ; #ifdef WDMA_PATH_CLOCK_DYNAMIC_SWITCH #ifdef CONFIG_FOR_SOURCE_PQ DDP_SCENARIO_ENUM scenario = DDP_SCENARIO_PRIMARY_DITHER_MEMOUT; #else DDP_SCENARIO_ENUM scenario = DDP_SCENARIO_PRIMARY_OVL_MEMOUT; #endif int * modules = ddp_get_scenario_list(scenario); int module_num = ddp_get_module_num(scenario); DISP_LOG_I("wdma path power off on scenario %s\n",ddp_get_scenario_name(scenario)); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_off!= 0) { DISP_LOG_V(" %s power off\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_off(module_name, NULL); // now just 0; } } } #endif return 0; } int dpmgr_wdma_path_force_power_on(void) { int i=0; int module_name ; #ifdef WDMA_PATH_CLOCK_DYNAMIC_SWITCH #ifdef CONFIG_FOR_SOURCE_PQ DDP_SCENARIO_ENUM scenario = DDP_SCENARIO_PRIMARY_DITHER_MEMOUT; #else DDP_SCENARIO_ENUM scenario = DDP_SCENARIO_PRIMARY_OVL_MEMOUT; #endif int * modules = ddp_get_scenario_list(scenario); int module_num = ddp_get_module_num(scenario); DISP_LOG_I("wdma path power on scenario %s\n",ddp_get_scenario_name(scenario)); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_on!= 0) { DISP_LOG_V("%s power on\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_on(module_name, NULL); // now just 0; } } } #endif return 0; } int dpmgr_path_power_off(disp_path_handle dp_handle, CMDQ_SWITCH encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("path power off on scenario %s\n",ddp_get_scenario_name(handle->scenario)); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_off!= 0) { DISP_LOG_V(" %s power off\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_off(module_name, encmdq?handle->cmdqhandle:NULL); // now just 0; } } } handle->power_sate = 0; path_top_clock_off(); return 0; } int dpmgr_path_power_on(disp_path_handle dp_handle, CMDQ_SWITCH encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("path power on scenario %s\n",ddp_get_scenario_name(handle->scenario)); path_top_clock_on(); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_on!= 0) { DISP_LOG_V("%s power on\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_on(module_name, encmdq?handle->cmdqhandle:NULL); // now just 0; } } } //modules on this path will resume power on; handle->power_sate = 1; return 0; } int dpmgr_path_dsi_power_off(disp_path_handle dp_handle, CMDQ_SWITCH encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_MODULE_ENUM dst_module = ddp_get_dst_module(handle->scenario); module_name=dst_module; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_off!= 0) { DISP_LOG_V(" %s power off\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_off(module_name, encmdq?handle->cmdqhandle:NULL); // now just 0; } } return 0; } int dpmgr_path_dsi_power_on(disp_path_handle dp_handle, CMDQ_SWITCH encmdq) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_MODULE_ENUM dst_module = ddp_get_dst_module(handle->scenario); module_name=dst_module; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_on!= 0) { DISP_LOG_V("%s power on\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->power_on(module_name, encmdq?handle->cmdqhandle:NULL); // now just 0; } } return 0; } int dpmgr_path_dsi_off(disp_path_handle dp_handle, void * cmdq_handle,unsigned int level) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_MODULE_ENUM dst_module = ddp_get_dst_module(handle->scenario); module_name=dst_module; // printk("ddp_idle dsi_off on scenario %s\n",ddp_get_scenario_name(handle->scenario)); if( module_name >= 0 && module_name < DISP_MODULE_UNKNOWN){ ddp_modules_driver[module_name]->ioctl(module_name, cmdq_handle, DDP_DSI_IDLE_CLK_CLOSED,&level); }else{ DISP_LOG_E("dpmgr_path_dsi_off unknow module %d",module_name); } ddp_path_lp_top_clock_off(); } int dpmgr_path_dsi_on(disp_path_handle dp_handle, void * cmdq_handle,unsigned int level) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_MODULE_ENUM dst_module = ddp_get_dst_module(handle->scenario); module_name = dst_module; // printk("ddp_idle dsi_on scenario %s\n",ddp_get_scenario_name(handle->scenario)); ddp_path_lp_top_clock_on(); if( module_name >= 0 && module_name < DISP_MODULE_UNKNOWN){ ddp_modules_driver[module_name]->ioctl(module_name, cmdq_handle, DDP_DSI_IDLE_CLK_OPEN, &level); }else{ DISP_LOG_E("dpmgr_path_dsi_on unknow module %d",module_name); } return 0; } int dpmgr_path_idle_off(disp_path_handle dp_handle, void * cmdq_handle,unsigned int level) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("ddp_idle off on scenario %s\n",ddp_get_scenario_name(handle->scenario)); // For DSI CMD mode, do not clock pwm_26M, used to make sure MM clock off but MTCMOS on if(primary_display_is_video_mode()==0) { enable_clock(MT_CG_PERI_DISP_PWM, "screen_idle"); } for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_off!= 0) { DISP_LOG_V(" %s power off\n",ddp_get_module_name(module_name)); if(!((module_name == DISP_MODULE_DSIDUAL) || (module_name == DISP_MODULE_DSI0) || (module_name == DISP_MODULE_DSI1))) ddp_modules_driver[module_name]->power_off(module_name, cmdq_handle); else ddp_modules_driver[module_name]->ioctl(module_name, cmdq_handle, DDP_DSI_IDLE_CLK_CLOSED,&level); } } } //dpmgr_path_dsi_off(dp_handle,cmdq_handle,level); handle->power_sate = 0; path_top_clock_off(); } int dpmgr_path_idle_on(disp_path_handle dp_handle, void * cmdq_handle,unsigned int level) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("ddp_idle on scenario %s\n",ddp_get_scenario_name(handle->scenario)); path_top_clock_on(); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->power_on!= 0) { DISP_LOG_V("%s power on\n",ddp_get_module_name(module_name)); if(!((module_name == DISP_MODULE_DSIDUAL) || (module_name == DISP_MODULE_DSI0) || (module_name == DISP_MODULE_DSI1))) ddp_modules_driver[module_name]->power_on(module_name, cmdq_handle); else ddp_modules_driver[module_name]->ioctl(module_name, cmdq_handle, DDP_DSI_IDLE_CLK_OPEN, &level); } } } // clock on PEM_26M one more time when idle off, so need clock off it here if(primary_display_is_video_mode()==0) { disable_clock(MT_CG_PERI_DISP_PWM, "screen_idle"); } handle->power_sate = 1; return 0; } static int is_module_in_path(DISP_MODULE_ENUM module,ddp_path_handle handle) { DDP_MANAGER_CONTEXT * context = _get_context(); ASSERT(module module_path_table[module]==handle) { return 1; } return 0; } int dpmgr_path_user_cmd(disp_path_handle dp_handle, int msg, unsigned long arg, void *cmdqhandle) { int ret = -1; DISP_MODULE_ENUM dst = DISP_MODULE_UNKNOWN; ddp_path_handle handle = NULL; ASSERT(dp_handle != NULL); handle = (ddp_path_handle)dp_handle; //DISP_LOG_W("dpmgr_path_user_cmd msg 0x%08x\n",msg); switch(msg) { case DISP_IOCTL_AAL_EVENTCTL: case DISP_IOCTL_AAL_GET_HIST: case DISP_IOCTL_AAL_INIT_REG: case DISP_IOCTL_AAL_SET_PARAM: { //TODO: just for verify rootcause, will be removed soon #ifndef CONFIG_FOR_SOURCE_PQ if(is_module_in_path(DISP_MODULE_AAL,handle)) { if(ddp_modules_driver[DISP_MODULE_AAL]->cmd!=NULL) { ret = ddp_modules_driver[DISP_MODULE_AAL]->cmd(DISP_MODULE_AAL,msg,arg, cmdqhandle); } } #endif break; } case DISP_IOCTL_SET_GAMMALUT: if(ddp_modules_driver[DISP_MODULE_GAMMA]->cmd!=NULL) { ret = ddp_modules_driver[DISP_MODULE_GAMMA]->cmd(DISP_MODULE_GAMMA,msg,arg, cmdqhandle); } break; case DISP_IOCTL_SET_CCORR: if(ddp_modules_driver[DISP_MODULE_CCORR]->cmd!=NULL) { ret = ddp_modules_driver[DISP_MODULE_CCORR]->cmd(DISP_MODULE_CCORR,msg,arg, cmdqhandle); } break; case DISP_IOCTL_SET_PQPARAM: case DISP_IOCTL_GET_PQPARAM: case DISP_IOCTL_SET_PQINDEX: case DISP_IOCTL_GET_PQINDEX: case DISP_IOCTL_SET_TDSHPINDEX: case DISP_IOCTL_GET_TDSHPINDEX: case DISP_IOCTL_SET_PQ_CAM_PARAM: case DISP_IOCTL_GET_PQ_CAM_PARAM: case DISP_IOCTL_SET_PQ_GAL_PARAM: case DISP_IOCTL_GET_PQ_GAL_PARAM: case DISP_IOCTL_PQ_SET_BYPASS_COLOR: case DISP_IOCTL_PQ_SET_WINDOW: case DISP_IOCTL_READ_REG: case DISP_IOCTL_MUTEX_CONTROL: case DISP_IOCTL_PQ_GET_TDSHP_FLAG: case DISP_IOCTL_PQ_SET_TDSHP_FLAG: case DISP_IOCTL_PQ_GET_DC_PARAM: case DISP_IOCTL_PQ_SET_DC_PARAM: case DISP_IOCTL_WRITE_SW_REG: case DISP_IOCTL_READ_SW_REG: { if(is_module_in_path(DISP_MODULE_COLOR0,handle)) { dst = DISP_MODULE_COLOR0; } else if(is_module_in_path(DISP_MODULE_COLOR1,handle)) { dst = DISP_MODULE_COLOR1; } else { DISP_LOG_W("dpmgr_path_user_cmd color is not on this path\n"); } if(dst != DISP_MODULE_UNKNOWN) { if(ddp_modules_driver[dst]->cmd!=NULL) { ret = ddp_modules_driver[dst]->cmd(dst,msg,arg, cmdqhandle); } } break; } /* case DISP_IOCTL_OD_CTL: { if(is_module_in_path(DISP_MODULE_OD,handle)) { if(ddp_modules_driver[DISP_MODULE_OD]->cmd!=NULL) { ret = ddp_modules_driver[DISP_MODULE_OD]->cmd(DISP_MODULE_OD,msg,arg, cmdqhandle); } } break; }*/ default: { DISP_LOG_W("dpmgr_path_user_cmd io not supported\n"); break; } } return ret; } int dpmgr_path_set_parameter(disp_path_handle dp_handle, int io_evnet, void * data) { return 0; } int dpmgr_path_get_parameter(disp_path_handle dp_handle,int io_evnet, void * data ) { return 0; } int dpmgr_path_is_idle(disp_path_handle dp_handle) { ASSERT(dp_handle != NULL); return !dpmgr_path_is_busy(dp_handle); } int dpmgr_path_is_busy(disp_path_handle dp_handle) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_V("path check busy on scenario %s\n",ddp_get_scenario_name(handle->scenario)); for( i=module_num-1; i>=0;i--) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->is_busy!= 0) { if(ddp_modules_driver[module_name]->is_busy(module_name)) { DISP_LOG_V("%s is busy\n", ddp_get_module_name(module_name)); return 1; } } } } return 0; } int dpmgr_set_lcm_utils(disp_path_handle dp_handle, void *lcm_drv) { int i=0; int module_name ; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_V("path set lcm drv handle %p\n",handle); for( i=0; i< module_num;i++) { module_name = modules[i]; if(ddp_modules_driver[module_name] != 0) { if((ddp_modules_driver[module_name]->set_lcm_utils!= 0)&&lcm_drv) { DISP_LOG_I("%s set lcm utils\n",ddp_get_module_name(module_name)); ddp_modules_driver[module_name]->set_lcm_utils(module_name, lcm_drv); // now just 0; } } } return 0; } int dpmgr_enable_event(disp_path_handle dp_handle, DISP_PATH_EVENT event) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DPMGR_WQ_HANDLE *wq_handle = &handle->wq_list[event]; DISP_LOG_I("enable event %s on scenario %s, irtbit 0x%x\n", path_event_name(event), ddp_get_scenario_name(handle->scenario), handle->irq_event_map[event].irq_bit); if(!wq_handle->init) { init_waitqueue_head(&(wq_handle->wq)); wq_handle->init = 1; wq_handle->data= 0; wq_handle->event = event; } return 0; } int dpmgr_map_event_to_irq(disp_path_handle dp_handle, DISP_PATH_EVENT event, DDP_IRQ_BIT irq_bit) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DDP_IRQ_EVENT_MAPPING *irq_table = handle->irq_event_map; if(event < DISP_PATH_EVENT_NUM) { DISP_LOG_I("map event %s to irq 0x%x on scenario %s\n",path_event_name(event),irq_bit,ddp_get_scenario_name(handle->scenario)); irq_table[event].irq_bit= irq_bit; return 0; } DISP_LOG_E("fail to map event %s to irq 0x%x on scenario %s\n",path_event_name(event),irq_bit,ddp_get_scenario_name(handle->scenario)); return -1; } int dpmgr_disable_event(disp_path_handle dp_handle, DISP_PATH_EVENT event) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DISP_LOG_I("disable event %s on scenario %s \n",path_event_name(event),ddp_get_scenario_name(handle->scenario)); DPMGR_WQ_HANDLE *wq_handle = &handle->wq_list[event]; wq_handle->init = 0; wq_handle->data= 0; return 0; } int dpmgr_check_status(disp_path_handle dp_handle) { int i =0; int module_name ; if(dp_handle == NULL ) { DISP_LOG_E("check status with NULL handle is invalid.\n"); return -1; // avoid kernel to access invalid address. } ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; int * modules = ddp_get_scenario_list(handle->scenario); int module_num = ddp_get_module_num(handle->scenario); DISP_LOG_I("check status on scenario %s\n", ddp_get_scenario_name(handle->scenario)); ddp_dump_analysis(DISP_MODULE_CONFIG); ddp_check_path(handle->scenario); ddp_check_mutex(handle->hwmutexid,handle->scenario, handle->mode); // dump path { DDPMSG("path:"); for(i=0;i=DISP_MUTEX_DDP_FIRST && mutex_id < (DISP_MUTEX_DDP_FIRST+DISP_MUTEX_DDP_COUNT)) { handle = (disp_path_handle)content->handle_pool[mutex_id]; if(handle) { dpmgr_check_status(handle); } } else { for(i=DISP_MUTEX_DDP_FIRST; i<(DISP_MUTEX_DDP_FIRST+DISP_MUTEX_DDP_COUNT);i++) { handle = (disp_path_handle)content->handle_pool[i]; if(handle) { dpmgr_check_status(handle); } } } return ; } int dpmgr_wait_event_timeout(disp_path_handle dp_handle, DISP_PATH_EVENT event, int timeout) { int ret = -1; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DPMGR_WQ_HANDLE *wq_handle = & handle->wq_list[event]; if(wq_handle->init) { DISP_LOG_V("wait event %s on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); unsigned long long cur_time = sched_clock(); ret = wait_event_interruptible_timeout(wq_handle->wq, cur_time < wq_handle->data,timeout); if(ret == 0) { DISP_LOG_E("wait %s timeout on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); MMProfileLogEx(ddp_mmp_get_events()->dpmgr_wait_event_timeout, MMProfileFlagPulse, ddp_get_scenario_name(handle->scenario), event); dpmgr_check_status(dp_handle); // dpmgr_path_reset(dp_handle, 0); // gDDPError = 1; } else if(ret < 0) { DISP_LOG_E("wait %s interrupt by other timeleft %d on scenario %s\n", path_event_name(event),ret,ddp_get_scenario_name(handle->scenario)); } else { DISP_LOG_V("received event %s timeleft %d on scenario %s\n", path_event_name(event), ret,ddp_get_scenario_name(handle->scenario)); } return ret; } DISP_LOG_E("wait event %s not initialized on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); return ret; } int dpmgr_wait_event(disp_path_handle dp_handle, DISP_PATH_EVENT event) { int ret = -1; ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DPMGR_WQ_HANDLE *wq_handle = & handle->wq_list[event]; if(wq_handle->init) { DISP_LOG_V("wait event %s on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); unsigned long long cur_time = sched_clock(); ret = wait_event_interruptible(wq_handle->wq, cur_time < wq_handle->data); if(ret < 0) { DISP_LOG_E("wait %s interrupt by other ret %d on scenario %s\n", path_event_name(event), ret,ddp_get_scenario_name(handle->scenario)); } else { DISP_LOG_V("received event %s ret %d on scenario %s\n", path_event_name(event), ret,ddp_get_scenario_name(handle->scenario)); } return ret; } DISP_LOG_E("wait event %s not initialized on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); return ret; } int dpmgr_signal_event(disp_path_handle dp_handle, DISP_PATH_EVENT event) { ASSERT(dp_handle != NULL); ddp_path_handle handle = (ddp_path_handle)dp_handle; DPMGR_WQ_HANDLE *wq_handle = &handle->wq_list[event]; if(handle->wq_list[event].init) { wq_handle->data = sched_clock(); DISP_LOG_V("wake up evnet %s on scenario %s\n", path_event_name(event),ddp_get_scenario_name(handle->scenario)); wake_up_interruptible(&(handle->wq_list[event].wq)); } return 0; } static void dpmgr_irq_handler(DISP_MODULE_ENUM module,unsigned int regvalue) { int i = 0; int j = 0; int irq_bits_num =0; int irq_bit = 0; ddp_path_handle handle = NULL; irq_bits_num = ddp_get_module_max_irq_bit(module); for(i = 0; i<=irq_bits_num; i++) { if(regvalue & (0x1<wq_list[j].init && irq_bit == handle->irq_event_map[j].irq_bit) { dprec_stub_event(j); handle->wq_list[j].data =sched_clock(); DDPIRQ("irq signal event %s on cycle %llu on scenario %s\n", path_event_name(j), handle->wq_list[j].data ,ddp_get_scenario_name(handle->scenario)); wake_up_interruptible(&(handle->wq_list[j].wq)); //MMProfileLogEx(ddp_mmp_get_events()->primary_wakeup, MMProfileFlagPulse, j, irq_bit); } } } } return ; } int dpmgr_init(void) { DISP_LOG_I("ddp manager init\n"); if (ddp_manager_init) return 0; ddp_manager_init = 1; ddp_debug_init(); disp_init_irq(); disp_register_irq_callback(dpmgr_irq_handler); memset((void*)hw_mutex_id_to_handle_map, 0, sizeof(hw_mutex_id_to_handle_map)); return 0; } int dpmgr_factory_mode_test(int module_name, void *cmdqhandle, void *config) { if(ddp_modules_driver[module_name] != 0) { if(ddp_modules_driver[module_name]->ioctl!= 0) { DISP_LOG_I(" %s factory_mode_test\n",ddp_get_module_name(DISP_MODULE_DPI)); ddp_modules_driver[DISP_MODULE_DPI]->ioctl(module_name, cmdqhandle, DDP_DPI_FACTORY_TEST, config); } } return 0; }