示例#1
0
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;
}
示例#9
0
文件: extd_lcm.c 项目: SelfImp/m75
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;
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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;
}