static void destroy_external_display_path(unsigned int session, int mode)
{
	int device_id = 0;

	MULTI_COTRL_LOG("destroy_external_display_path session:%08x\n", session);
	if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY) {
		/*virtual device id*/
		device_id = DISP_SESSION_DEV(session);
	} else {
		/*external device id*/
		device_id = DISP_SESSION_DEV(session) - 1;
	}

	if ((path_info.old_session[device_id] == DISP_SESSION_PRIMARY)
	|| (path_info.old_session[device_id] == DISP_SESSION_MEMORY
	&& path_info.old_mode[device_id] >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE)) {
		/*discard for memory session in mirror mode*/
		MULTI_COTRL_LOG("no need destroy path for session:0x%08x, mode:%d\n", path_info.old_session[device_id],
										path_info.old_mode[device_id]);
		return;
	}

	if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) {
		ext_disp_deinit(session);
		extd_set_layer_num(0, session);
		ext_disp_path_change(EXTD_OVL_IDLE_REQ, session);
	} else if (path_info.old_session[device_id] == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT > 0) {
		ovl2mem_deinit();
		ovl2mem_setlayernum(0);
		ext_disp_path_change(EXTD_OVL_IDLE_REQ, session);
	}
}
int external_display_trigger(EXTD_TRIGGER_MODE trigger, unsigned int session)
{
	int ret = 0;
	enum EXTD_OVL_REQ_STATUS ovl_status = EXTD_OVL_NO_REQ;

	if (trigger == TRIGGER_RESUME) {
		ext_disp_resume(session);
		if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL && DISP_SESSION_DEV(session) == DEV_EINK+1) {
			if (extd_driver[DEV_EINK]->power_enable) {
				/*1 for power on, 0 for power off*/
				extd_driver[DEV_EINK]->power_enable(1);
			}
		}
	}

	ret = ext_disp_trigger(0, NULL, 0, session);

	if (trigger == TRIGGER_SUSPEND) {
		ext_disp_suspend_trigger(NULL, 0, session);
		if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL && DISP_SESSION_DEV(session) == DEV_EINK+1) {
			if (extd_driver[DEV_EINK]->power_enable) {
				/*1 for power on, 0 for power off*/
				extd_driver[DEV_EINK]->power_enable(0);
			}
		}
	}

	ovl_status = ext_disp_get_ovl_req_status(session);
	if (ovl_status == EXTD_OVL_REMOVING) {
		/*the new buffer configured, ovl can be removed*/
		ext_disp_path_change(EXTD_OVL_REMOVED, session);
	} else if (ovl_status == EXTD_OVL_INSERT_REQ) {
		/*the new buffer configured, ovl already is inserted in the path*/
		ext_disp_path_change(EXTD_OVL_INSERTED, session);
	}

	return ret;
}
static int create_external_display_path(unsigned int session, int mode)
{
	int ret = 0;
	int extd_type = DISP_IF_MHL;

	MULTI_COTRL_LOG("create_external_display_path session:%08x, mode:%d\n", session, mode);

	if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT > 0) {
		if (mode < DISP_SESSION_DIRECT_LINK_MIRROR_MODE
		&& (path_info.old_mode[DEV_WFD] >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE
		|| path_info.old_session[DEV_WFD] != DISP_SESSION_MEMORY)) {

			if (ext_disp_wait_ovl_available(0) > 0) {
				ovl2mem_init(session);
				ovl2mem_setlayernum(4);
			} else {
				MULTI_COTRL_ERR("mhl path: OVL1 can not be split out!\n");
				ret = -1;
			}
		} else if (mode >= DISP_SESSION_DIRECT_LINK_MIRROR_MODE
			&& path_info.old_session[DEV_WFD] == DISP_SESSION_MEMORY
			&& path_info.old_mode[DEV_WFD] < DISP_SESSION_DIRECT_LINK_MIRROR_MODE) {

			ovl2mem_deinit();
			ovl2mem_setlayernum(0);
			ext_disp_path_change(EXTD_OVL_IDLE_REQ, session);
		}
	} else if (DISP_SESSION_TYPE(session) == DISP_SESSION_EXTERNAL) {
		int device_id = DISP_SESSION_DEV(session) - 1;

		extd_type = extd_get_device_type(session);

		if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) {
			if (EXTD_OVERLAY_CNT < 1) {
				/*external display has no OVL to use, so no actions for mode switch */
				return ret;
			}
		}

		if (extd_type != DISP_IF_EPD && (mode < DISP_SESSION_DIRECT_LINK_MIRROR_MODE
		|| extd_type == DISP_IF_HDMI_SMARTBOOK)) {

			if (ext_disp_wait_ovl_available(0) > 0) {
				if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL
				&& extd_type != DISP_IF_HDMI_SMARTBOOK) {
					/*insert OVL to external dispaly path*/
					ext_disp_path_change(EXTD_OVL_INSERT_REQ, session);
				} else {
					/*create external display path with OVL*/
					extd_create_path(EXTD_DIRECT_LINK_MODE, session);
				}

				extd_set_layer_num(4, session);
			} else {
				MULTI_COTRL_ERR("mhl path: OVL1 can not be split out!\n");
				extd_create_path(EXTD_RDMA_DPI_MODE, session);
				extd_set_layer_num(1, session);
			}
		} else {
			if (path_info.old_session[device_id] == DISP_SESSION_EXTERNAL) {
				ext_disp_path_change(EXTD_OVL_REMOVE_REQ, session);
				extd_set_layer_num(1, session);
			} else {
				extd_create_path(EXTD_RDMA_DPI_MODE, session);
				extd_set_layer_num(1, session);
			}
		}
	} else if (DISP_SESSION_TYPE(session) == DISP_SESSION_MEMORY && EXTD_OVERLAY_CNT == 0) {
		MULTI_COTRL_ERR("memory session and ovl time sharing!\n");
		ovl2mem_setlayernum(4);
	}

	return ret;
}
static int disp_switch_mode_kthread(void *data)
{
	int ret = 0;
	struct sched_param param = { .sched_priority = 94 }; /*RTPM_PRIO_SCRN_UPDATE*/

	sched_setscheduler(current, SCHED_RR, &param);

	MULTI_COTRL_LOG("disp_switch_mode_kthread in!\n");

	for (;;) {
		wait_event_interruptible(switch_mode_wq, atomic_read(&switch_mode_event));
		atomic_set(&switch_mode_event, 0);

		MULTI_COTRL_LOG("switch mode, create or change path, mode:%d, session:0x%x\n",
				path_info.cur_mode, path_info.ext_sid);
		ret = create_external_display_path(path_info.ext_sid, path_info.cur_mode);
		if (ret == 0) {
			path_info.old_session[path_info.switching] = DISP_SESSION_TYPE(path_info.ext_sid);
			path_info.old_mode[path_info.switching]    = path_info.cur_mode;
		}

		path_info.switching = DEV_MAX_NUM;
		path_info.ext_sid   = 0;

		if (kthread_should_stop()) {
			/*thread exit*/
			break;
		}
	}

	return 0;
}

#ifndef OVL_CASCADE_SUPPORT
static int path_change_without_cascade(DISP_MODE mode, unsigned int session_id, unsigned int device_id)
{
	int ret = -1;
	unsigned int session = 0;

	/*MULTI_COTRL_FUNC();*/

	/*destroy external display path*/
	if (session_id == 0 && path_info.old_session[device_id] != DISP_SESSION_PRIMARY) {
		if (device_id == DEV_WFD) {
			/*make memory session for WFD*/
			session = MAKE_DISP_SESSION(DISP_SESSION_MEMORY, device_id);
		} else {
			/*make external session*/
			session = MAKE_DISP_SESSION(DISP_SESSION_EXTERNAL, device_id + 1);
		}

		destroy_external_display_path(session, DISP_SESSION_DIRECT_LINK_MODE);
		path_info.old_session[device_id] = DISP_SESSION_PRIMARY;
		path_info.old_mode[device_id]    = DISP_SESSION_DIRECT_LINK_MODE;
		path_info.switching = DEV_MAX_NUM;

		return 1;
	}

	/*create path or change path*/
	if ((session_id > 0 && path_info.old_session[device_id] == DISP_SESSION_PRIMARY)
	|| (mode != path_info.old_mode[device_id] && path_info.old_session[device_id] != DISP_SESSION_PRIMARY)) {
		ret = create_external_display_path(session_id, mode);
		if (ret == 0) {
			path_info.old_session[device_id] = DISP_SESSION_TYPE(session_id);
			path_info.old_mode[device_id]    = mode;
		}

		path_info.switching = DEV_MAX_NUM;

		return 1;
	}

	return 0;
}
Пример #5
0
void update_frm_seq_info(unsigned int session_id, unsigned int addr, unsigned int addr_offset,unsigned int seq, DISP_FRM_SEQ_STATE state)
{
    int i= 0;
    unsigned device_type = DISP_SESSION_TYPE(session_id);
    //printk("update_frm_seq_info, 0x%x/0x%x/0x%x/%d/%s/%d\n", session_id, addr, addr_offset, seq, get_frame_seq_state_string(state), frm_update_cnt);

    if(seq < 0 || session_id < 0 || state > FRM_RDMA0_EOF)
        return ;
    if(device_type > DISP_SESSION_MEMORY)
    {
        printk("seq_end session_id(0x%x) , seq(%d) \n",session_id, seq);
        return;
    }

    if(device_type == DISP_SESSION_PRIMARY || device_type == DISP_SESSION_PRIMARY - 1)
    {
        if(FRM_CONFIG == state)
        {
            frm_update_sequence[frm_update_cnt].state = state;
            frm_update_sequence[frm_update_cnt].session_type = device_type;
            frm_update_sequence[frm_update_cnt].mva= addr;
            frm_update_sequence[frm_update_cnt].max_offset= addr_offset;
            if(seq > 0)
                frm_update_sequence[frm_update_cnt].seq= seq;
            MMProfileLogEx(MTKFB_MMP_Events.primary_seq_config, MMProfileFlagPulse, addr, seq);
        }
        else if(FRM_TRIGGER == state)
        {
            frm_update_sequence[frm_update_cnt].state = FRM_TRIGGER;
            MMProfileLogEx(MTKFB_MMP_Events.primary_seq_trigger, MMProfileFlagPulse, addr, seq);
            dprec_logger_frame_seq_begin(device_type,  frm_update_sequence[frm_update_cnt].seq);

            frm_update_cnt++;
            frm_update_cnt%=FRM_UPDATE_SEQ_CACHE_NUM;
        }
        else if(FRM_WDMA0_EOF == state)
        {
            for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++)
            {
                //			 if((absabs(addr -frm_update_sequence[i].mva) <=  frm_update_sequence[i].max_offset) && (frm_update_sequence[i].state == FRM_TRIGGER))
                if(frm_update_sequence[i].state == FRM_TRIGGER)
                {
                    frm_update_sequence[i].state = FRM_WDMA0_EOF;
                    frm_update_sequence[i].mva = addr;
                    MMProfileLogEx(MTKFB_MMP_Events.primary_seq_wdma0_efo, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq);
                    ///break;
                }
            }
        }
        else if(FRM_RDMA0_SOF == state)
        {
            for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++)
            {
                if(FRM_WDMA0_EOF == frm_update_sequence[i].state && device_type == DISP_SESSION_PRIMARY && frm_update_sequence[i].mva == addr)
                {
                    frm_update_sequence[i].state = FRM_RDMA0_SOF;
                    dprec_logger_frame_seq_end(device_type,	frm_update_sequence[i].seq);
                    dprec_logger_frame_seq_begin(DISP_SESSION_PRIMARY-1,  frm_update_sequence[i].seq);
                    MMProfileLogEx(MTKFB_MMP_Events.primary_seq_rdma0_sof, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq);
                }
            }
        }
        else if(FRM_RDMA0_EOF == state)
        {
            for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++)
            {
                if(FRM_RDMA0_SOF == frm_update_sequence[i].state && device_type == DISP_SESSION_PRIMARY && frm_update_sequence[i].mva == addr)
                {
                    frm_update_sequence[i].state = FRM_RDMA0_EOF;
                    dprec_logger_frame_seq_end(DISP_SESSION_PRIMARY-1,	frm_update_sequence[i].seq );
                    MMProfileLogEx(MTKFB_MMP_Events.primary_seq_rdma0_eof, MMProfileFlagPulse, frm_update_sequence[i].mva, frm_update_sequence[i].seq);

                }
            }
        }
    }
    else if(device_type == DISP_SESSION_MEMORY)
    {
        if(FRM_CONFIG == state)
        {
            frm_update_sequence_mem[frm_update_cnt_mem].state = state;
            frm_update_sequence_mem[frm_update_cnt_mem].session_type = device_type;
            frm_update_sequence_mem[frm_update_cnt_mem].mva= addr;
            frm_update_sequence_mem[frm_update_cnt_mem].max_offset= addr_offset;
            if(seq > 0)
                frm_update_sequence_mem[frm_update_cnt_mem].seq= seq;

            MMProfileLogEx(MTKFB_MMP_Events.external_seq_config, MMProfileFlagPulse, addr, seq);
        }
        else if(FRM_TRIGGER == state)
        {
            frm_update_sequence_mem[frm_update_cnt_mem].state = FRM_TRIGGER;
            MMProfileLogEx(MTKFB_MMP_Events.external_seq_trigger, MMProfileFlagPulse, addr, seq);
            dprec_logger_frame_seq_begin(device_type,  frm_update_sequence_mem[frm_update_cnt_mem].seq);

            frm_update_cnt_mem++;
            frm_update_cnt_mem%=FRM_UPDATE_SEQ_CACHE_NUM;
        }
        else if(FRM_WDMA0_EOF == state)
        {
            for(i= 0; i< FRM_UPDATE_SEQ_CACHE_NUM; i++)
            {
                //			  if((absabs(addr -frm_update_sequence_mem[i].mva) <=  frm_update_sequence_mem[i].max_offset) && (frm_update_sequence_mem[i].state == FRM_TRIGGER))
                if(frm_update_sequence_mem[i].state == FRM_TRIGGER)
                {
                    MMProfileLogEx(MTKFB_MMP_Events.external_seq_wdma0_efo, MMProfileFlagPulse, frm_update_sequence_mem[i].mva, frm_update_sequence_mem[i].seq);

                    frm_update_sequence_mem[i].state = FRM_WDMA0_EOF;
                    frm_update_sequence_mem[i].mva = addr;
                    dprec_logger_frame_seq_end(device_type,	frm_update_sequence_mem[i].seq);
                    ///break;
                }
            }
        }
    }

}