Exemplo n.º 1
0
int fimc_is_dvfs_sel_static(struct fimc_is_device_ischain *device)
{
	struct fimc_is_core *core;
	struct fimc_is_dvfs_ctrl *dvfs_ctrl;
	struct fimc_is_dvfs_scenario_ctrl *static_ctrl;
	struct fimc_is_dvfs_scenario *scenarios;
	struct fimc_is_resourcemgr *resourcemgr;
	int i, scenario_id, scenario_cnt;

	BUG_ON(!device);
	BUG_ON(!device->interface);

	core = (struct fimc_is_core *)device->interface->core;
	resourcemgr = device->resourcemgr;
	dvfs_ctrl = &(resourcemgr->dvfs_ctrl);
	static_ctrl = dvfs_ctrl->static_ctrl;

	/* static scenario */
	if (!static_ctrl) {
		err("static_dvfs_ctrl is NULL\n");
		return -EINVAL;
	}

	if (static_ctrl->scenario_cnt == 0) {
		pr_debug("static_scenario's count is zero\n");
		return -EINVAL;
	}

	scenarios = static_ctrl->scenarios;
	scenario_cnt = static_ctrl->scenario_cnt;

	for (i = 0; i < scenario_cnt; i++) {
		if (!scenarios[i].check_func) {
			warn("check_func[%d] is NULL\n", i);
			continue;
		}

		if ((scenarios[i].check_func(device)) > 0) {
			scenario_id = scenarios[i].scenario_id;
			static_ctrl->cur_scenario_id = scenario_id;
			static_ctrl->cur_scenario_idx = i;
			static_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
			return scenario_id;
		}
	}

	warn("couldn't find static dvfs scenario [sensor:(%d/%d)/fps:%d/setfile:%d/scp size:(%d/%d)]\n",
		fimc_is_get_open_sensor_cnt(core),
		device->sensor->pdev->id,
		fimc_is_sensor_g_framerate(device->sensor),
		(device->setfile & FIMC_IS_SETFILE_MASK),
		device->scp.output.width,
		device->scp.output.height);

	static_ctrl->cur_scenario_id = FIMC_IS_SN_DEFAULT;
	static_ctrl->cur_scenario_idx = -1;
	static_ctrl->cur_frame_tick = -1;

	return FIMC_IS_SN_DEFAULT;
}
Exemplo n.º 2
0
int fimc_is_dvfs_sel_dynamic(struct fimc_is_device_ischain *device)
{
	struct fimc_is_dvfs_ctrl *dvfs_ctrl;
	struct fimc_is_dvfs_scenario_ctrl *dynamic_ctrl;
	struct fimc_is_dvfs_scenario *scenarios;
	struct fimc_is_resourcemgr *resourcemgr;
	int i, scenario_id, scenario_cnt;
	int position, resol, fps;

	BUG_ON(!device);

	resourcemgr = device->resourcemgr;
	dvfs_ctrl = &(resourcemgr->dvfs_ctrl);
	dynamic_ctrl = dvfs_ctrl->dynamic_ctrl;

	if (!test_bit(FIMC_IS_DVFS_SEL_TABLE, &dvfs_ctrl->state)) {
		err("dvfs table is NOT selected");
		return -EINVAL;
	}

	/* dynamic scenario */
	if (!dynamic_ctrl) {
		err("dynamic_dvfs_ctrl is NULL");
		return -EINVAL;
	}

	if (dynamic_ctrl->scenario_cnt == 0) {
		pr_debug("dynamic_scenario's count is zero");
		return -EINVAL;
	}

	scenarios = dynamic_ctrl->scenarios;
	scenario_cnt = dynamic_ctrl->scenario_cnt;

	if (dynamic_ctrl->cur_frame_tick >= 0) {
		(dynamic_ctrl->cur_frame_tick)--;
		/*
		 * when cur_frame_tick is lower than 0, clear current scenario.
		 * This means that current frame tick to keep dynamic scenario
		 * was expired.
		 */
		if (dynamic_ctrl->cur_frame_tick < 0) {
			dynamic_ctrl->cur_scenario_id = -1;
			dynamic_ctrl->cur_scenario_idx = -1;
		}
	}

	if (!test_bit(FIMC_IS_ISCHAIN_REPROCESSING, &device->state))
		return -EAGAIN;

	position = fimc_is_sensor_g_postion(device->sensor);
	resol = fimc_is_get_target_resol(device);
	fps = fimc_is_sensor_g_framerate(device->sensor);

	for (i = 0; i < scenario_cnt; i++) {
		if (!scenarios[i].check_func) {
			warn("check_func[%d] is NULL\n", i);
			continue;
		}

		if ((scenarios[i].check_func(device, position, resol, fps, 0)) > 0) {
			scenario_id = scenarios[i].scenario_id;
			dynamic_ctrl->cur_scenario_id = scenario_id;
			dynamic_ctrl->cur_scenario_idx = i;
			dynamic_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
			return scenario_id;
		}
	}

	return  -EAGAIN;
}
Exemplo n.º 3
0
int fimc_is_dvfs_sel_static(struct fimc_is_device_ischain *device)
{
	struct fimc_is_core *core;
	struct fimc_is_dvfs_ctrl *dvfs_ctrl;
	struct fimc_is_dvfs_scenario_ctrl *static_ctrl;
	struct fimc_is_dvfs_scenario *scenarios;
	struct fimc_is_resourcemgr *resourcemgr;
	int i, scenario_id, scenario_cnt;
	int position, resol, fps, stream_cnt;

	BUG_ON(!device);
	BUG_ON(!device->interface);

	core = (struct fimc_is_core *)device->interface->core;
	resourcemgr = device->resourcemgr;
	dvfs_ctrl = &(resourcemgr->dvfs_ctrl);
	static_ctrl = dvfs_ctrl->static_ctrl;

	if (!test_bit(FIMC_IS_DVFS_SEL_TABLE, &dvfs_ctrl->state)) {
		err("dvfs table is NOT selected");
		return -EINVAL;
	}

	/* static scenario */
	if (!static_ctrl) {
		err("static_dvfs_ctrl is NULL");
		return -EINVAL;
	}

	if (static_ctrl->scenario_cnt == 0) {
		pr_debug("static_scenario's count is zero");
		return -EINVAL;
	}

	scenarios = static_ctrl->scenarios;
	scenario_cnt = static_ctrl->scenario_cnt;
	position = fimc_is_sensor_g_postion(device->sensor);
	resol = fimc_is_get_target_resol(device);
	fps = fimc_is_sensor_g_framerate(device->sensor);
	stream_cnt = fimc_is_get_start_sensor_cnt(core);

	for (i = 0; i < scenario_cnt; i++) {
		if (!scenarios[i].check_func) {
			warn("check_func[%d] is NULL\n", i);
			continue;
		}

		if ((scenarios[i].check_func(device, position, resol, fps, stream_cnt)) > 0) {
			scenario_id = scenarios[i].scenario_id;
			static_ctrl->cur_scenario_id = scenario_id;
			static_ctrl->cur_scenario_idx = i;
			static_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
			return scenario_id;
		}
	}

	warn("couldn't find static dvfs scenario [sensor:(%d/%d)/fps:%d/setfile:%d/resol:(%d)]\n",
		fimc_is_get_start_sensor_cnt(core),
		device->sensor->pdev->id,
		fps, (device->setfile & FIMC_IS_SETFILE_MASK), resol);

	static_ctrl->cur_scenario_id = FIMC_IS_SN_DEFAULT;
	static_ctrl->cur_scenario_idx = -1;
	static_ctrl->cur_frame_tick = -1;

	return FIMC_IS_SN_DEFAULT;
}
int fimc_is_dvfs_sel_scenario(u32 type, struct fimc_is_device_ischain *device, struct fimc_is_frame *frame)
{
	struct fimc_is_dvfs_ctrl *dvfs_ctrl;
	struct fimc_is_dvfs_scenario_ctrl *static_ctrl, *dynamic_ctrl;
	struct fimc_is_dvfs_scenario *scenarios;
	struct fimc_is_dvfs_scenario *cur_scenario;
	struct fimc_is_resourcemgr *resourcemgr;
	int i, scenario_id, scenario_cnt;

	if (device == NULL) {
		err("device is NULL\n");
		return -EINVAL;
	}

	resourcemgr = device->resourcemgr;
	dvfs_ctrl = &(resourcemgr->dvfs_ctrl);
	static_ctrl = dvfs_ctrl->static_ctrl;
	dynamic_ctrl = dvfs_ctrl->dynamic_ctrl;

	if (type == FIMC_IS_DYNAMIC_SN) {
		/* dynamic scenario */
		if (!dynamic_ctrl) {
			err("dynamic_dvfs_ctrl is NULL\n");
			return -EINVAL;
		}

		if (dynamic_ctrl->scenario_cnt == 0) {
			pr_debug("dynamic_scenario's count is jero\n");
			return -EINVAL;
		}

		scenarios = dynamic_ctrl->scenarios;
		scenario_cnt = dynamic_ctrl->scenario_cnt;

		if (dynamic_ctrl->cur_frame_tick >= 0) {
			(dynamic_ctrl->cur_frame_tick)--;
			/*
			 * when cur_frame_tick is lower than 0, clear current scenario.
			 * This means that current frame tick to keep dynamic scenario
			 * was expired.
			 */
			if (dynamic_ctrl->cur_frame_tick < 0) {
				dynamic_ctrl->cur_scenario_id = -1;
				dynamic_ctrl->cur_scenario_idx = -1;
			}
		}
	} else {
		/* static scenario */
		if (!static_ctrl) {
			err("static_dvfs_ctrl is NULL\n");
			return -EINVAL;
		}

		if (static_ctrl->scenario_cnt == 0) {
			pr_debug("static_scenario's count is jero\n");
			return -EINVAL;
		}

		scenarios = static_ctrl->scenarios;
		scenario_cnt = static_ctrl->scenario_cnt;
	}

	for (i = 0; i < scenario_cnt; i++) {
		if (!scenarios[i].check_func) {
			warn("check_func[%d] is NULL\n", i);
			continue;
		}

		if ((scenarios[i].check_func(device, frame)) > 0) {
			scenario_id = scenarios[i].scenario_id;

			if (type == FIMC_IS_DYNAMIC_SN) {
				cur_scenario = &scenarios[dynamic_ctrl->cur_scenario_idx];

				/*
				 * if condition 1 or 2 is true
				 * condition 1 : There's no dynamic scenario applied.
				 * condition 2 : Finded scenario's prority was higher than current
				 */
				if ((dynamic_ctrl->cur_scenario_id <= 0) ||
						(scenarios[i].priority < (cur_scenario->priority))) {
					dynamic_ctrl->cur_scenario_id = scenarios[i].scenario_id;
					dynamic_ctrl->cur_scenario_idx = i;
					dynamic_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
				} else {
					/* if finded scenario is same */
					if (scenarios[i].priority == (cur_scenario->priority))
						dynamic_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
					return -EAGAIN;
				}
			} else {
				static_ctrl->cur_scenario_id = scenario_id;
				static_ctrl->cur_scenario_idx = i;
				static_ctrl->cur_frame_tick = scenarios[i].keep_frame_tick;
			}

			return scenario_id;
		}
	}

	if (type == FIMC_IS_DYNAMIC_SN)
		return -EAGAIN;

	{
		struct fimc_is_core *core;
		int sensor_cnt = 0;
		core = (struct fimc_is_core *)device->interface->core;
		sensor_cnt = fimc_is_get_open_sensor_cnt(core);

		warn("couldn't find static dvfs scenario [sensor:(%d/%d)/fps:%d/setfile:%d/scp size:(%d/%d)]\n",
			sensor_cnt,
			device->sensor->pdev->id,
			fimc_is_sensor_g_framerate(device->sensor),
			(device->setfile & FIMC_IS_SETFILE_MASK),
			device->chain3_width,
			device->chain3_height);
	}

	static_ctrl->cur_scenario_id = FIMC_IS_SN_DEFAULT;
	static_ctrl->cur_scenario_idx = -1;
	static_ctrl->cur_frame_tick = -1;

	return FIMC_IS_SN_DEFAULT;
}
Exemplo n.º 5
0
static void monitor_report(void *group_data,
	void *frame_data)
{
	u32 index, shotindex;
	u32 fduration, ctime, dtime;
	u32 temp1, temp2, temp3, temp4, temp;
	struct fimc_is_monitor *mp;
	struct fimc_is_device_ischain *device;
	struct fimc_is_group *group;
	struct fimc_is_frame *frame;
	struct fimc_is_time *time;
	bool valid = true;

	BUG_ON(!group_data);
	BUG_ON(!frame_data);

	group = group_data;
	device = group->device;
	time = &group->time;
	frame = frame_data;
	mp = frame->mpoint;
	fduration = (1000000 / fimc_is_sensor_g_framerate(device->sensor)) + MONITOR_TIMEOUT;
	ctime = 15000;
	dtime = 15000;

	/* Q interval */
	if (!frame->result && mp[TMM_QUEUE].check && mp[TMM_START].check) {
		temp1 = fimc_is_get_time(&mp[TMM_QUEUE].time, &mp[TMM_START].time);
		if (temp1 > fduration) {
			mgrinfo("[TIM] Q(%dus > %dus)\n", device, group, frame, temp1, fduration);
		}
	} else {
		valid = false;
	}

	/* Callback interval */
	if (!frame->result && mp[TMM_SCALL].check && mp[TMM_ECALL].check) {
		temp2 = fimc_is_get_time(&mp[TMM_SCALL].time, &mp[TMM_ECALL].time);
		if (temp2 > ctime) {
			mgrinfo("[TIM] C(%dus > %dus)\n", device, group, frame, temp2, ctime);
			for (index = TMM_SCALL; index < TMM_ECALL; ++index) {
				temp = fimc_is_get_time(&mp[index].time, &mp[index + 1].time);
				mgrinfo("[TIM] %02d-%02d(%dus)\n", device, group, frame, index, index + 1, temp);
			}
		}
	} else {
		valid = false;
	}

	/* Shot interval */
	if (test_bit(FIMC_IS_GROUP_OTF_INPUT, &group->state)) {
		shotindex = TMM_SHOT2;
	} else {
		shotindex = TMM_SHOT1;
	}

	if (!frame->result && mp[shotindex].check && mp[TMM_SDONE].check) {
		temp3 = fimc_is_get_time(&mp[shotindex].time, &mp[TMM_SDONE].time);
		if (temp3 > fduration) {
			mgrinfo("[TIM] S(%dus > %dus)\n", device, group, frame, temp3, fduration);
		}
	} else {
		valid = false;
	}

	/* Deque interval */
	if (!frame->result && mp[TMM_SDONE].check && mp[TMM_DEQUE].check) {
		temp4 = fimc_is_get_time(&mp[TMM_SDONE].time, &mp[TMM_DEQUE].time);
		if (temp4 > dtime) {
			mgrinfo("[TIM] D(%dus > %dus)\n", device, group, frame, temp4, dtime);
			for (index = TMM_SDONE; index < TMM_DEQUE; ++index) {
				temp = fimc_is_get_time(&mp[index].time, &mp[index + 1].time);
				mgrinfo("[TIM] %02d-%02d(%dus)\n", device, group, frame, index, index + 1, temp);
			}
		}
	} else {
		valid = false;
	}

	for (index = 0; index < TMM_END; ++index)
		mp[index].check = false;

	if (!valid)
		return;

#ifdef MONITOR_REPORT
	temp1 += temp2;
	temp2 = temp3;
	temp3 = temp4;

	if (!time->time_count) {
		time->time1_min = temp1;
		time->time1_max = temp1;
		time->time2_min = temp2;
		time->time2_max = temp2;
		time->time3_min = temp3;
		time->time3_max = temp3;
	} else {
		if (time->time1_min > temp1)
			time->time1_min = temp1;

		if (time->time1_max < temp1)
			time->time1_max = temp1;

		if (time->time2_min > temp2)
			time->time2_min = temp2;

		if (time->time2_max < temp2)
			time->time2_max = temp2;

		if (time->time3_min > temp3)
			time->time3_min = temp3;

		if (time->time3_max < temp3)
			time->time3_max = temp3;
	}

	time->time1_tot += temp1;
	time->time2_tot += temp2;
	time->time3_tot += temp3;

	time->time4_cur = mp[TMM_QUEUE].time.tv_sec * 1000000 + mp[TMM_QUEUE].time.tv_usec;
	time->time4_tot += (time->time4_cur - time->time4_old);
	time->time4_old = time->time4_cur;

	time->time_count++;

	if (time->time_count % time->report_period)
		return;

	mginfo("[TIM] Q(%05d,%05d,%05d), S(%05d,%05d,%05d), D(%05d,%05d,%05d) : %d(%dfps)\n",
		device, group,
		temp1, time->time1_max, time->time1_tot / time->time_count,
		temp2, time->time2_max, time->time2_tot / time->time_count,
		temp3, time->time3_max, time->time3_tot / time->time_count,
		time->time4_tot / time->report_period,
		(1000000 * time->report_period) / time->time4_tot);

	time->time_count = 0;
	time->time1_tot = 0;
	time->time2_tot = 0;
	time->time3_tot = 0;
	time->time4_tot = 0;
#endif
}
static int fimc_is_ischain_dis_cfg(struct fimc_is_subdev *leader,
	void *device_data,
	struct fimc_is_frame *frame,
	struct fimc_is_crop *incrop,
	struct fimc_is_crop *otcrop,
	u32 *lindex,
	u32 *hindex,
	u32 *indexes)
{
	int ret = 0;
	struct fimc_is_group *group;
	struct fimc_is_queue *queue;
	struct param_otf_input *otf_input;
	struct param_otf_output *otf_output;
	struct param_dma_input *dma_input;
	struct fimc_is_device_ischain *device;
	u32 width, height, dis_width, dis_height;
	int fps;
	u32 setfile;
	bool full_bypass;

	device = (struct fimc_is_device_ischain *)device_data;

	BUG_ON(!leader);
	BUG_ON(!device);
	BUG_ON(!incrop);
	BUG_ON(!lindex);
	BUG_ON(!hindex);
	BUG_ON(!indexes);

	otf_input = NULL;
	otf_output = NULL;
	dma_input = NULL;
	width = incrop->w;
	height = incrop->h;
	dis_width = otcrop->w;
	dis_height = otcrop->h;
	group = &device->group_dis;
	otf_output = NULL;
	dma_input = NULL;
	queue = GET_SUBDEV_QUEUE(leader);
	if (!queue) {
		merr("queue is NULL", device);
		ret = -EINVAL;
		goto p_err;
	}

	/*
	 * Full bypass enable condition
	 * 1) 120fps, 240fps
	 * 2) UHD@60fps
	 * 3) DUAL(PIP)
	 */
	fps = fimc_is_sensor_g_framerate(device->sensor);
	setfile = device->setfile;
	if (fps > 60 || (fps > 30 && ((width * height) >= SIZE_UHD)) ||
		((setfile & FIMC_IS_SETFILE_MASK) == ISS_SUB_SCENARIO_DUAL_STILL) ||
		((setfile & FIMC_IS_SETFILE_MASK) == ISS_SUB_SCENARIO_DUAL_VIDEO))
		full_bypass = true;
	else
		full_bypass = false;

	/* control setting */
	fimc_is_ischain_dis_ctrl(device, frame, lindex, hindex, indexes, full_bypass);

	otf_input = fimc_is_itf_g_param(device, frame, PARAM_TPU_OTF_INPUT);
	if (test_bit(FIMC_IS_GROUP_OTF_INPUT, &group->state))
		otf_input->cmd = OTF_INPUT_COMMAND_ENABLE;
	else
		otf_input->cmd = OTF_INPUT_COMMAND_DISABLE;
	otf_input->width = width;
	otf_input->height = height;
	otf_input->format = OTF_YUV_FORMAT;
	*lindex |= LOWBIT_OF(PARAM_TPU_OTF_INPUT);
	*hindex |= HIGHBIT_OF(PARAM_TPU_OTF_INPUT);
	(*indexes)++;

	dma_input = fimc_is_itf_g_param(device, frame, PARAM_TPU_DMA_INPUT);
	if (test_bit(FIMC_IS_GROUP_OTF_INPUT, &group->state))
		dma_input->cmd = DMA_INPUT_COMMAND_DISABLE;
	else
		dma_input->cmd = DMA_INPUT_COMMAND_ENABLE;
	dma_input->width = width;
	dma_input->height = height;
	dma_input->format = DMA_INPUT_FORMAT_YUV422_CHUNKER;
	*lindex |= LOWBIT_OF(PARAM_TPU_DMA_INPUT);
	*hindex |= HIGHBIT_OF(PARAM_TPU_DMA_INPUT);
	(*indexes)++;

	otf_output = fimc_is_itf_g_param(device, frame, PARAM_TPU_OTF_OUTPUT);
	otf_output->width = dis_width;
	otf_output->height = dis_height;
	otf_output->format = OTF_YUV_FORMAT;
	*lindex |= LOWBIT_OF(PARAM_TPU_OTF_OUTPUT);
	*hindex |= HIGHBIT_OF(PARAM_TPU_OTF_OUTPUT);
	(*indexes)++;

	leader->input.crop = *incrop;

p_err:
	return ret;
}