Exemple #1
0
static int fimc_isp_subdev_s_stream(struct v4l2_subdev *sd, int on)
{
	struct fimc_isp *isp = v4l2_get_subdevdata(sd);
	struct fimc_is *is = fimc_isp_to_is(isp);
	int ret;

	isp_dbg(1, sd, "%s: on: %d\n", __func__, on);

	if (!test_bit(IS_ST_INIT_DONE, &is->state))
		return -EBUSY;

	fimc_is_mem_barrier();

	if (on) {
		if (__get_pending_param_count(is)) {
			ret = fimc_is_itf_s_param(is, true);
			if (ret < 0)
				return ret;
		}

		isp_dbg(1, sd, "changing mode to %d\n", is->config_index);

		ret = fimc_is_itf_mode_change(is);
		if (ret)
			return -EINVAL;

		clear_bit(IS_ST_STREAM_ON, &is->state);
		fimc_is_hw_stream_on(is);
		ret = fimc_is_wait_event(is, IS_ST_STREAM_ON, 1,
					 FIMC_IS_CONFIG_TIMEOUT);
		if (ret < 0) {
			v4l2_err(sd, "stream on timeout\n");
			return ret;
		}
	} else {
		clear_bit(IS_ST_STREAM_OFF, &is->state);
		fimc_is_hw_stream_off(is);
		ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,
					 FIMC_IS_CONFIG_TIMEOUT);
		if (ret < 0) {
			v4l2_err(sd, "stream off timeout\n");
			return ret;
		}
		is->setfile.sub_index = 0;
	}

	return 0;
}
Exemple #2
0
static int fimc_is_hw_open_sensor(struct fimc_is *is,
				  struct fimc_is_sensor *sensor)
{
	struct sensor_open_extended *soe = (void *)&is->is_p_region->shared;

	fimc_is_hw_wait_intmsr0_intmsd0(is);

	soe->self_calibration_mode = 1;
	soe->actuator_type = 0;
	soe->mipi_lane_num = 0;
	soe->mclk = 0;
	soe->mipi_speed	= 0;
	soe->fast_open_sensor = 0;
	soe->i2c_sclk = 88000000;

	fimc_is_mem_barrier();

	mcuctl_write(HIC_OPEN_SENSOR, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(sensor->drvdata->id, is, MCUCTL_REG_ISSR(2));
	mcuctl_write(sensor->i2c_bus, is, MCUCTL_REG_ISSR(3));
	mcuctl_write(is->is_dma_p_region, is, MCUCTL_REG_ISSR(4));

	fimc_is_hw_set_intgr0_gd0(is);

	return fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 1,
				  FIMC_IS_SENSOR_OPEN_TIMEOUT);
}
Exemple #3
0
int fimc_is_itf_mode_change(struct fimc_is *is)
{
	int ret;

	clear_bit(IS_ST_CHANGE_MODE, &is->state);
	fimc_is_hw_change_mode(is);
	ret = fimc_is_wait_event(is, IS_ST_CHANGE_MODE, 1,
				FIMC_IS_CONFIG_TIMEOUT);
	if (!ret < 0)
		dev_err(&is->pdev->dev, "%s(): mode change (%d) timeout\n",
			__func__, is->config_index);
	return ret;
}
Exemple #4
0
int fimc_is_itf_s_param(struct fimc_is *is, bool update)
{
	int ret;

	if (update)
		__is_hw_update_params(is);

	fimc_is_mem_barrier();

	clear_bit(IS_ST_BLOCK_CMD_CLEARED, &is->state);
	fimc_is_hw_set_param(is);
	ret = fimc_is_wait_event(is, IS_ST_BLOCK_CMD_CLEARED, 1,
				FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0)
		dev_err(&is->pdev->dev, "%s() timeout\n", __func__);

	return ret;
}
Exemple #5
0
int fimc_is_start_firmware(struct fimc_is *is)
{
	struct device *dev = &is->pdev->dev;
	int ret;

	memcpy(is->memory.vaddr, is->fw.f_w->data, is->fw.f_w->size);
	wmb();

	ret = fimc_is_cpu_set_power(is, 1);
	if (ret < 0)
		return ret;

	ret = fimc_is_wait_event(is, IS_ST_A5_PWR_ON, 1,
				 msecs_to_jiffies(FIMC_IS_FW_LOAD_TIMEOUT));
	if (ret < 0)
		dev_err(dev, "FIMC-IS CPU power on failed\n");

	return ret;
}
Exemple #6
0
static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
{
	struct fimc_isp *isp = v4l2_get_subdevdata(sd);
	struct fimc_is *is = fimc_isp_to_is(isp);
	int ret = 0;

	pr_debug("on: %d\n", on);

	if (on) {
		ret = pm_runtime_get_sync(&is->pdev->dev);
		if (ret < 0)
			return ret;
		set_bit(IS_ST_PWR_ON, &is->state);

		ret = fimc_is_start_firmware(is);
		if (ret < 0) {
			v4l2_err(sd, "firmware booting failed\n");
			pm_runtime_put(&is->pdev->dev);
			return ret;
		}
		set_bit(IS_ST_PWR_SUBIP_ON, &is->state);

		ret = fimc_is_hw_initialize(is);
	} else {
		/* Close sensor */
		if (!test_bit(IS_ST_PWR_ON, &is->state)) {
			fimc_is_hw_close_sensor(is, 0);

			ret = fimc_is_wait_event(is, IS_ST_OPEN_SENSOR, 0,
						 FIMC_IS_CONFIG_TIMEOUT);
			if (ret < 0) {
				v4l2_err(sd, "sensor close timeout\n");
				return ret;
			}
		}

		/* SUB IP power off */
		if (test_bit(IS_ST_PWR_SUBIP_ON, &is->state)) {
			fimc_is_hw_subip_power_off(is);
			ret = fimc_is_wait_event(is, IS_ST_PWR_SUBIP_ON, 0,
						 FIMC_IS_CONFIG_TIMEOUT);
			if (ret < 0) {
				v4l2_err(sd, "sub-IP power off timeout\n");
				return ret;
			}
		}

		fimc_is_cpu_set_power(is, 0);
		pm_runtime_put_sync(&is->pdev->dev);

		clear_bit(IS_ST_PWR_ON, &is->state);
		clear_bit(IS_ST_INIT_DONE, &is->state);
		is->state = 0;
		is->config[is->config_index].p_region_index[0] = 0;
		is->config[is->config_index].p_region_index[1] = 0;
		set_bit(IS_ST_IDLE, &is->state);
		wmb();
	}

	return ret;
}
Exemple #7
0
int fimc_is_hw_initialize(struct fimc_is *is)
{
	const int config_ids[] = {
		IS_SC_PREVIEW_STILL, IS_SC_PREVIEW_VIDEO,
		IS_SC_CAPTURE_STILL, IS_SC_CAPTURE_VIDEO
	};
	struct device *dev = &is->pdev->dev;
	u32 prev_id;
	int i, ret;

	/* Sensor initialization. */
	ret = fimc_is_hw_open_sensor(is, is->sensor);
	if (ret < 0)
		return ret;

	/* Get the setfile address. */
	fimc_is_hw_get_setfile_addr(is);

	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "get setfile address timed out\n");
		return ret;
	}
	pr_debug("setfile.base: %#x\n", is->setfile.base);

	/* Load the setfile. */
	fimc_is_load_setfile(is, FIMC_IS_SETFILE_6A3);
	clear_bit(IS_ST_SETFILE_LOADED, &is->state);
	fimc_is_hw_load_setfile(is);
	ret = fimc_is_wait_event(is, IS_ST_SETFILE_LOADED, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "loading setfile timed out\n");
		return ret;
	}

	pr_debug("setfile: base: %#x, size: %d\n",
		 is->setfile.base, is->setfile.size);
	pr_info("FIMC-IS Setfile info: %s\n", is->fw.setfile_info);

	/* Check magic number. */
	if (is->is_p_region->shared[MAX_SHARED_COUNT - 1] !=
	    FIMC_IS_MAGIC_NUMBER) {
		dev_err(dev, "magic number error!\n");
		return -EIO;
	}

	pr_debug("shared region: %#x, parameter region: %#x\n",
		 is->memory.paddr + FIMC_IS_SHARED_REGION_OFFSET,
		 is->is_dma_p_region);

	is->setfile.sub_index = 0;

	/* Stream off. */
	fimc_is_hw_stream_off(is);
	ret = fimc_is_wait_event(is, IS_ST_STREAM_OFF, 1,
				 FIMC_IS_CONFIG_TIMEOUT);
	if (ret < 0) {
		dev_err(dev, "stream off timeout\n");
		return ret;
	}

	/* Preserve previous mode. */
	prev_id = is->config_index;

	/* Set initial parameter values. */
	for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
		is->config_index = config_ids[i];
		fimc_is_set_initial_params(is);
		ret = fimc_is_itf_s_param(is, true);
		if (ret < 0) {
			is->config_index = prev_id;
			return ret;
		}
	}
	is->config_index = prev_id;

	set_bit(IS_ST_INIT_DONE, &is->state);
	dev_info(dev, "initialization sequence completed (%d)\n",
						is->config_index);
	return 0;
}