/*
 * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
 *
 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
 *
 * Authors: Younghwan Joo <yhwan.joo@samsung.com>
 *          Sylwester Nawrocki <s.nawrocki@samsung.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/delay.h>

#include "fimc-is.h"
#include "fimc-is-command.h"
#include "fimc-is-regs.h"
#include "fimc-is-sensor.h"

void fimc_is_fw_clear_irq1(struct fimc_is *is, unsigned int nr)
{
	mcuctl_write(1UL << nr, is, MCUCTL_REG_INTCR1);
}

void fimc_is_fw_clear_irq2(struct fimc_is *is)
{
	u32 cfg = mcuctl_read(is, MCUCTL_REG_INTSR2);
	mcuctl_write(cfg, is, MCUCTL_REG_INTCR2);
}

void fimc_is_hw_set_intgr0_gd0(struct fimc_is *is)
{
	mcuctl_write(INTGR0_INTGD(0), is, MCUCTL_REG_INTGR0);
}

int fimc_is_hw_wait_intmsr0_intmsd0(struct fimc_is *is)
{
	unsigned int timeout = 2000;
	u32 cfg, status;

	do {
		cfg = mcuctl_read(is, MCUCTL_REG_INTMSR0);
		status = INTMSR0_GET_INTMSD(0, cfg);

		if (--timeout == 0) {
			dev_warn(&is->pdev->dev, "%s timeout\n",
				 __func__);
			return -ETIMEDOUT;
		}
		udelay(1);
	} while (status != 0);

	return 0;
}

int fimc_is_hw_set_param(struct fimc_is *is)
{
	struct chain_config *config = &is->config[is->config_index];
	unsigned int param_count = __get_pending_param_count(is);

	fimc_is_hw_wait_intmsr0_intmsd0(is);

	mcuctl_write(HIC_SET_PARAMETER, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(is->config_index, is, MCUCTL_REG_ISSR(2));

	mcuctl_write(param_count, is, MCUCTL_REG_ISSR(3));
	mcuctl_write(config->p_region_index[0], is, MCUCTL_REG_ISSR(4));
	mcuctl_write(config->p_region_index[1], is, MCUCTL_REG_ISSR(5));

	fimc_is_hw_set_intgr0_gd0(is);
	return 0;
}

static int __maybe_unused fimc_is_hw_set_tune(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);

	mcuctl_write(HIC_SET_TUNE, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(is->h2i_cmd.entry_id, is, MCUCTL_REG_ISSR(2));

	fimc_is_hw_set_intgr0_gd0(is);
	return 0;
}

#define FIMC_IS_MAX_PARAMS	4

int fimc_is_hw_get_params(struct fimc_is *is, unsigned int num_args)
{
	int i;

	if (num_args > FIMC_IS_MAX_PARAMS)
		return -EINVAL;

	is->i2h_cmd.num_args = num_args;

	for (i = 0; i < FIMC_IS_MAX_PARAMS; i++) {
		if (i < num_args)
			is->i2h_cmd.args[i] = mcuctl_read(is,
					MCUCTL_REG_ISSR(12 + i));
		else
			is->i2h_cmd.args[i] = 0;
	}
	return 0;
}

void fimc_is_hw_set_isp_buf_mask(struct fimc_is *is, unsigned int mask)
{
	if (hweight32(mask) == 1) {
		dev_err(&is->pdev->dev, "%s(): not enough buffers (mask %#x)\n",
							__func__, mask);
		return;
	}

	if (mcuctl_read(is, MCUCTL_REG_ISSR(23)) != 0)
		dev_dbg(&is->pdev->dev, "non-zero DMA buffer mask\n");

	mcuctl_write(mask, is, MCUCTL_REG_ISSR(23));
}

void fimc_is_hw_set_sensor_num(struct fimc_is *is)
{
	pr_debug("setting sensor index to: %d\n", is->sensor_index);

	mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2));
	mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3));
}

void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index)
{
	if (is->sensor_index != index)
		return;

	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_CLOSE_SENSOR, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(2));
	fimc_is_hw_set_intgr0_gd0(is);
}

void fimc_is_hw_get_setfile_addr(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_GET_SET_FILE_ADDR, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	fimc_is_hw_set_intgr0_gd0(is);
}

void fimc_is_hw_load_setfile(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_LOAD_SET_FILE, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	fimc_is_hw_set_intgr0_gd0(is);
}

int fimc_is_hw_change_mode(struct fimc_is *is)
{
	static const u8 cmd[] = {
		HIC_PREVIEW_STILL, HIC_PREVIEW_VIDEO,
		HIC_CAPTURE_STILL, HIC_CAPTURE_VIDEO,
	};

	if (WARN_ON(is->config_index >= ARRAY_SIZE(cmd)))
		return -EINVAL;

	mcuctl_write(cmd[is->config_index], is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(is->setfile.sub_index, is, MCUCTL_REG_ISSR(2));
	fimc_is_hw_set_intgr0_gd0(is);
	return 0;
}

void fimc_is_hw_stream_on(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_STREAM_ON, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	mcuctl_write(0, is, MCUCTL_REG_ISSR(2));
	fimc_is_hw_set_intgr0_gd0(is);
}

void fimc_is_hw_stream_off(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_STREAM_OFF, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	fimc_is_hw_set_intgr0_gd0(is);
}

void fimc_is_hw_subip_power_off(struct fimc_is *is)
{
	fimc_is_hw_wait_intmsr0_intmsd0(is);
	mcuctl_write(HIC_POWER_DOWN, is, MCUCTL_REG_ISSR(0));
	mcuctl_write(is->sensor_index, is, MCUCTL_REG_ISSR(1));
	fimc_is_hw_set_intgr0_gd0(is);
}

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;
}

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;
}
