Пример #1
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;
		}
	}
}
Пример #2
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);
		}
	}
}
Пример #3
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;
		}
	}
}
Пример #4
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;
		}
	}
}
Пример #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_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;
		}
	}
}
/* 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;
	}
}
/* 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;
	}
}
/*
 * trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU	
 *	1.wait idle:	     N         N        Y        Y 	 
*/
static int _should_wait_path_idle(void)
{
	if(ext_disp_cmdq_enabled())
	{
		return 0;
	}
	else
	{
		return dpmgr_path_is_busy(pgc->dpmgr_handle);

	}
}
/* trigger operation:  VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU        
  * 8. reset cmdq:     Y         Y        N        N        
*/
static int _should_reset_cmdq_config_handle(void)
{
	return (ext_disp_cmdq_enabled() ? 1 : 0);
}
int ext_disp_config_input_multiple(ext_disp_input_config* input, int idx)
{
	int ret = 0;
	int i=0;
	int layer =0;
	///EXT_DISP_FUNC();
	
	disp_ddp_path_config *data_config;	

	if((is_hdmi_active() == false) || (pgc->state != EXTD_INIT && pgc->state != EXTD_RESUME) )
	{
		EXT_DISP_LOG("[Donglei]config ext disp is already sleeped, hdmi_active:%d, state:%d\n", is_hdmi_active(), pgc->state);	
		MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Config, idx );
		return -2;
	}

    _ext_disp_path_lock();

	// all dirty should be cleared in dpmgr_path_get_last_config()
	data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
    
	// hope we can use only 1 input struct for input config, just set layer number
	if(_should_config_ovl_input())
	{
		for(i = 0;i<HW_OVERLAY_COUNT;i++)
		{	
			if(input[i].dirty)
			{	
				ret = _convert_disp_input_to_ovl(&(data_config->ovl_config[input[i].layer]), &input[i]);
				dprec_mmp_dump_ovl_layer(&(data_config->ovl_config[input[i].layer]), input[i].layer, 2);
			}

			if (init_roi == 1)
			{
				LCM_PARAMS *lcm_param = extd_drv_get_params(pgc->plcm);
				memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS));
				
				if(lcm_param != NULL)
				{
					EXT_DISP_LOG("set dest w:%d, h:%d\n", lcm_param->width, lcm_param->height);
					data_config->dst_w = lcm_param->width;
					data_config->dst_h = lcm_param->height;
				}
				
				data_config->dst_dirty = 1;
				data_config->rdma_config.address = 0;
			}
			data_config->ovl_dirty = 1;	
		}
	}
	else
	{
		OVL_CONFIG_STRUCT  ovl_config;
		_convert_disp_input_to_ovl(&ovl_config, input);
		dprec_mmp_dump_ovl_layer(&ovl_config, input->layer, 2);

		ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), input);
		if (data_config->rdma_config.address)
		{
			data_config->rdma_dirty = 1;
		}
	}

	if(_should_wait_path_idle())
	{
		dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2);
	}

	memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS));
	ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, ext_disp_cmdq_enabled()? pgc->cmdq_handle_config : NULL);

	// this is used for decouple mode, to indicate whether we need to trigger ovl
	pgc->need_trigger_overlay = 1;
	init_roi = 0;

	_ext_disp_path_unlock();
	if (data_config->ovl_dirty)
	{
		EXT_DISP_LOG("config_input_multiple idx:%d -w:%d, h:%d, pitch:%d\n", idx ,data_config->ovl_config[0].src_w, data_config->ovl_config[0].src_h, data_config->ovl_config[0].src_pitch);	
	}else{
		EXT_DISP_LOG("config_input_multiple idx:%d -w:%d, h:%d, pitch:%d, mva:%p\n", idx ,data_config->rdma_config.width, data_config->rdma_config.height, data_config->rdma_config.pitch, data_config->rdma_config.address);
	}
		
	return ret;
}
int ext_disp_config_input(ext_disp_input_config* input)
{
	int ret = 0;
	int i=0;
	int layer =0;
	///EXT_DISP_FUNC();
	
	disp_ddp_path_config *data_config;	
	
	if((is_hdmi_active() == false)|| ext_disp_is_sleepd())
	{
		EXT_DISP_LOG("ext disp is already sleeped\n");		
		return 0;
	}

	_ext_disp_path_lock();
	data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
	
	if(input->layer_en)
	{
		if(input->vaddr)
		{
			///_debug_pattern(0x00000000, input->vaddr, input->dst_w, input->dst_h, input->src_pitch, 0x00000000, input->layer, input->buff_idx);
		}	
		else
		{
			///_debug_pattern(input->addr,0x00000000,  input->dst_w, input->dst_h, input->src_pitch, 0x00000000, input->layer, input->buff_idx);
		}
	}

#ifdef EXTD_DBG_USE_INNER_BUF
    if(input->fmt == eYUY2)    
    {
        ///input->layer_en = 1;
        ///memset(input, 0, sizeof(ext_disp_input_config));
        input->layer_en = 1;
        input->addr = hdmi_mva_r ;
        input->vaddr = hdmi_va ;
        input->fmt = eRGB888;   ///eRGBA8888  eYUY2
        input->src_w = 1280;
        input->src_h = 720;
        input->src_x = 0;
        input->src_y = 0;
        input->src_pitch = 1280*3;        
        input->dst_w = 1280;
        input->dst_h = 720;
        input->dst_x = 0;
        input->dst_y = 0;
        input->aen = 0;
        input->alpha = 0xff;
    }
#endif


	// hope we can use only 1 input struct for input config, just set layer number
	if(_should_config_ovl_input())
	{
		ret = _convert_disp_input_to_ovl(&(data_config->ovl_config[input->layer]), input);
		data_config->ovl_dirty = 1;
	}
	else
	{
		ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), input);
		data_config->rdma_dirty= 1;
	}

	///EXT_DISP_ERR("ext_disp_config_input cmdq %d wi %d ovl %d vm %d\n", ext_disp_cmdq_enabled(), _should_wait_path_idle(), _should_config_ovl_input(), ext_disp_is_video_mode());
	if(_should_wait_path_idle())
	{
		dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2);
	}

	memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS));
	ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, ext_disp_cmdq_enabled()? pgc->cmdq_handle_config : NULL);

	// this is used for decouple mode, to indicate whether we need to trigger ovl
	pgc->need_trigger_overlay = 1;
    ///EXT_DISP_LOG("ext_disp_config_input done \n");

	_ext_disp_path_unlock();
	
	return ret;
}
/* trigger operation:       VDO+CMDQ  CMD+CMDQ VDO+CPU  CMD+CPU    
  * 9. cmdq insert token:   Y         Y        N        N      
*/  
static int _should_insert_wait_frame_done_token(void)
{
	return (ext_disp_cmdq_enabled() ? 1 : 0);
}
static int _trigger_display_interface(int blocking, void *callback, unsigned int userdata)
{
	///EXT_DISP_FUNC();
	int i = 0;
	
	bool reg_flush = false;
	if(_should_wait_path_idle())
	{
		dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2);
	}
	
	if(_should_update_lcm())
	{
		extd_drv_update(pgc->plcm, 0, 0, pgc->plcm->params->width, pgc->plcm->params->height, 0);
	}

	if(_should_start_path())
	{ 
		reg_flush = true;
		dpmgr_path_start(pgc->dpmgr_handle, ext_disp_cmdq_enabled());	
		MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagPulse, Trigger, 1);
	}
	
	if(_should_trigger_path())
	{	
		// trigger_loop_handle is used only for build trigger loop, which should always be NULL for config thread
		dpmgr_path_trigger(pgc->dpmgr_handle, NULL, ext_disp_cmdq_enabled());		
	}
	
	if(_should_set_cmdq_dirty())
	{
		_cmdq_set_config_handle_dirty();
	}
    ///if(reg_flush == false)
	{
#if 0
		if(reg_flush == false)
		{
			if(_should_insert_wait_frame_done_token())
			{
				_cmdq_insert_wait_frame_done_token();
			}
		}
        
		if(_should_flush_cmdq_config_handle())
		{
			_cmdq_flush_config_handle(reg_flush);  
		}

		if(_should_reset_cmdq_config_handle())
		{
			_cmdq_reset_config_handle();
		}

		if(reg_flush == true)
		{
			if(_should_insert_wait_frame_done_token())
			{
				_cmdq_insert_wait_frame_done_token();
			}
		}

		///cmdqRecDumpCommand(cmdqRecHandle handle)
#else

		if(_should_flush_cmdq_config_handle())
		{    	    
			if(reg_flush)
			{
				MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagPulse, Trigger, 2);
			}

			if(_should_start_path())
			{
				EXT_DISP_LOG("Wait Main Display Vsync\n");
				disp_session_vsync_config vsync_config;
				primary_display_wait_for_vsync(&vsync_config);
			}

			_cmdq_flush_config_handle(blocking, callback, userdata);
		}
    	
		if(_should_reset_cmdq_config_handle())
		{
			_cmdq_reset_config_handle();
		}
    	
		if(_should_insert_wait_frame_done_token())
		{
			_cmdq_insert_wait_frame_done_token();
		}
#endif
	}
	
	return 0;
}
Пример #17
0
int ext_disp_config_input_multiple(ext_disp_input_config* input, int idx)
{
	int ret = 0;
	int i=0;
	int layer =0;
	///DISPFUNC();
	
	disp_ddp_path_config *data_config;	

	if((is_hdmi_active() == false) || (pgc->state != EXTD_RESUME) )
	{
		DISPMSG("config ext disp is already sleeped\n");	
		MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Config, idx );
		return 0;
	}

    _ext_disp_path_lock();

	// all dirty should be cleared in dpmgr_path_get_last_config()
	data_config = dpmgr_path_get_last_config(pgc->dpmgr_handle);
	data_config->dst_dirty = 0;
	data_config->ovl_dirty = 0;
	data_config->rdma_dirty = 0;
	data_config->wdma_dirty = 0;

    
	// hope we can use only 1 input struct for input config, just set layer number
	if(_should_config_ovl_input())
	{
		for(i = 0;i<HW_OVERLAY_COUNT;i++)
		{	///dprec_logger_start(DPREC_LOGGER_PRIMARY_CONFIG, input->layer|(input->layer_en<<16), input->addr);


			if(input[i].dirty)
			{
				dprec_mmp_dump_ovl_layer(&(data_config->ovl_config[input[i].layer]), input[i].layer, 2);
				ret = _convert_disp_input_to_ovl(&(data_config->ovl_config[input[i].layer]), &input[i]);
			}
/*
			else
			{
                data_config->ovl_config[input[i].layer].layer_en = input[i].layer_en;
                data_config->ovl_config[input[i].layer].layer = input[i].layer;
			}
*/
			data_config->ovl_dirty = 1;	

			
			///dprec_logger_done(DPREC_LOGGER_PRIMARY_CONFIG, input->src_x, input->src_y);

		}
	}
	else
	{
		ret = _convert_disp_input_to_rdma(&(data_config->rdma_config), input);
		data_config->rdma_dirty= 1;
	}

	if(_should_wait_path_idle())
	{
		dpmgr_wait_event_timeout(pgc->dpmgr_handle, DISP_PATH_EVENT_FRAME_DONE, HZ/2);
	}

	memcpy(&(data_config->dispif_config), &(extd_dpi_params.dispif_config), sizeof(LCM_PARAMS));
	ret = dpmgr_path_config(pgc->dpmgr_handle, data_config, ext_disp_cmdq_enabled()? pgc->cmdq_handle_config : NULL);

	// this is used for decouple mode, to indicate whether we need to trigger ovl
	pgc->need_trigger_overlay = 1;

	_ext_disp_path_unlock();
	DISPMSG("config_input_multiple idx %x -w %d, h %d\n", idx ,data_config->ovl_config[0].src_w, data_config->ovl_config[0].src_h);	
	return ret;
}