コード例 #1
0
static int _should_insert_wait_frame_done_token(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU    
*** 7.flush cmdq:          Y         Y       N        N      */  
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 1;
		}
		else
		{
			return 1;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 0;
		}
	}
}
コード例 #2
0
static int _should_flush_cmdq_config_handle(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU        
*** 7.flush cmdq:          Y         Y       N        N        ***/
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 1;
		}
		else
		{
			return 1;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 0;
		}
	}
}
コード例 #3
0
static int _should_reset_cmdq_config_handle(void)
{
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 1;
		}
		else
		{
			return 1;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 0;
		}
	}
}
コード例 #4
0
static int _should_set_cmdq_dirty(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
*** 6.set cmdq dirty:	    N         Y       N        N     ***/
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 0;
		}
	}
}
コード例 #5
0
static int _should_trigger_path(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU              
*** 4.path trigger:     idle->Y      Y    idle->Y     Y     
*** 5.mutex enable:        N         N    idle->Y     Y        ***/

	// this is not a perfect design, we can't decide path trigger(ovl/rdma/dsi..) seperately with mutex enable
	// but it's lucky because path trigger and mutex enable is the same w/o cmdq, and it's correct w/ CMDQ(Y+N).
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return dpmgr_path_is_idle(pgc->dpmgr_handle);
		}
		else
		{
			return 0;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return dpmgr_path_is_idle(pgc->dpmgr_handle);
		}
		else
		{
			return 1;
		}
	}
}
コード例 #6
0
static int _should_start_path(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
*** 3.path start:      	idle->Y      Y    idle->Y     Y        ***/
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return dpmgr_path_is_idle(pgc->dpmgr_handle);
		}
		else
		{
			return 1;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return dpmgr_path_is_idle(pgc->dpmgr_handle);
		}
		else
		{
			return 1;
		}
	}
}
コード例 #7
0
static int _should_update_lcm(void)
{
/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
*** 2.lcm update:          N         Y       N        Y        **/
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			// TODO: lcm_update can't use cmdq now
			return 0;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}
}
コード例 #8
0
static int _should_wait_path_idle(void)
{
	/***trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU	
	*** 1.wait idle:	          N         N        Y        Y 	 			*/
	if(ext_disp_cmdq_enabled())
	{
		if(ext_disp_is_video_mode())
		{
			return 0;
		}
		else
		{
			return 0;
		}
	}
	else
	{
		if(ext_disp_is_video_mode())
		{
			return dpmgr_path_is_busy(pgc->dpmgr_handle);
		}
		else
		{
			return dpmgr_path_is_busy(pgc->dpmgr_handle);
		}
	}
}
コード例 #9
0
static void _cmdq_set_config_handle_dirty(void)
{
	if(!ext_disp_is_video_mode())
	{
		// only command mode need to set dirty
		cmdqRecSetEventToken(pgc->cmdq_handle_config, CMDQ_SYNC_TOKEN_CONFIG_DIRTY);
		///dprec_event_op(DPREC_EVENT_CMDQ_SET_DIRTY);
	}
}
コード例 #10
0
/* trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
  * 6. set cmdq dirty: N         Y        N        N     
*/
static int _should_set_cmdq_dirty(void)
{
	if(ext_disp_cmdq_enabled() && (ext_disp_is_video_mode() == 0))
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
コード例 #11
0
/* trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
  * 3.path start:      idle->Y   Y        idle->Y  Y        
*/
static int _should_start_path(void)
{
	if(ext_disp_is_video_mode())
	{
		return dpmgr_path_is_idle(pgc->dpmgr_handle);
	}
	else
	{
		return 1;
	}
}
コード例 #12
0
/* trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU  
  * 2.lcm update:      N         Y        N        Y        
*/
static int _should_update_lcm(void)
{
	if(ext_disp_cmdq_enabled() || ext_disp_is_video_mode())
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
コード例 #13
0
static void _cmdq_insert_wait_frame_done_token(void)
{
	if(ext_disp_is_video_mode())
	{
		cmdqRecWaitNoClear(pgc->cmdq_handle_config, dpmgr_path_get_mutex(pgc->dpmgr_handle) + CMDQ_EVENT_MUTEX0_STREAM_EOF);  ///CMDQ_EVENT_MUTEX1_STREAM_EOF  dpmgr_path_get_mutex()
	}
	else
	{
		cmdqRecWaitNoClear(pgc->cmdq_handle_config, CMDQ_SYNC_TOKEN_STREAM_EOF);
	}
	
	///dprec_event_op(DPREC_EVENT_CMDQ_WAIT_STREAM_EOF);
}
コード例 #14
0
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);
	}
	
	EXT_DISP_LOG("START cmdq trigger loop finished\n");
}
コード例 #15
0
int ext_disp_init(char *lcm_name, unsigned int session)
{
	EXT_DISP_FUNC();
	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)
	{
		EXT_DISP_LOG("disp_lcm_probe returns null\n");
		ret = EXT_DISP_STATUS_ERROR;
		//goto done;  //Donglei
	}

	lcm_param = extd_drv_get_params(pgc->plcm);
	if(lcm_param == NULL)
	{
		EXT_DISP_ERR("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)
	{
		EXT_DISP_ERR("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)
	{
		EXT_DISP_LOG("cmdqRecCreate FAIL, ret=%d \n", ret);
		ret = EXT_DISP_STATUS_ERROR;
		goto done;
	}
	else
	{
		EXT_DISP_LOG("cmdqRecCreate SUCCESS, g_cmdq_handle=%p \n", pgc->cmdq_handle_config);
	}

	if(ext_disp_mode == EXTD_DIRECT_LINK_MODE)
	{
		_build_path_direct_link();
//		EXT_DISP_LOG("ext_disp display is DIRECT LINK MODE\n");
	}
	else if(ext_disp_mode == EXTD_DECOUPLE_MODE)
	{
		_build_path_decouple();
//		EXT_DISP_LOG("ext_disp display is DECOUPLE MODE\n");
	}
	else if(ext_disp_mode == EXTD_SINGLE_LAYER_MODE)
	{
		_build_path_single_layer();
//		EXT_DISP_LOG("ext_disp display is SINGLE LAYER MODE\n");
	}
	else if(ext_disp_mode == EXTD_RDMA_DPI_MODE)
	{
		_build_path_rdma_dpi();
//		EXT_DISP_LOG("ext_disp display is RDMA to dpi MODE\n");
	}
	else
	{
		EXT_DISP_LOG("ext_disp display mode is WRONG\n");
	}

	if(ext_disp_use_cmdq == CMDQ_ENABLE)
	{
		_cmdq_build_trigger_loop();
		EXT_DISP_LOG("ext_disp display BUILD cmdq trigger loop finished\n");
    	
		_cmdq_start_trigger_loop();
	}

	pgc->session = session;
	
	EXT_DISP_LOG("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 = (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), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS));

		data_config->dst_w = lcm_param->width;
		data_config->dst_h = lcm_param->height;
		data_config->dst_dirty = 1;
        init_roi = 0;	
		ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, CMDQ_DISABLE);
	}
	else
	{
		EXT_DISP_LOG("allocate buffer failed!!!\n");
	}
	
	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())
	{
			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(); //Fixed me: why insert EOF event before the first frame start
	}

	dpmgr_path_power_on(pgc->dpmgr_handle, CMDQ_DISABLE);
	
	pgc->state = EXTD_INIT;

done:

	_ext_disp_path_unlock();
    dpmgr_path_stop(pgc->dpmgr_handle, CMDQ_DISABLE);
            
	EXT_DISP_LOG("ext_disp_init done \n");
	return ret;
}
コード例 #16
0
static void _cmdq_build_trigger_loop(void)
{
	int ret = 0;
	cmdqRecCreate(CMDQ_SCENARIO_TRIGGER_LOOP, &(pgc->cmdq_handle_trigger));
	EXT_DISP_LOG("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,  dpmgr_path_get_mutex(pgc->dpmgr_handle) + CMDQ_EVENT_MUTEX0_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);
	}
	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);

		// 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);

		// 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);
		
		// 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);

		// 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);
	EXT_DISP_LOG("ext display BUILD cmdq trigger loop finished\n");

	return;
}