/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "cam_cci_dev.h"
#include "cam_cci_core.h"

int cam_cci_init(struct v4l2_subdev *sd,
	struct cam_cci_ctrl *c_ctrl)
{
	uint8_t i = 0, j = 0;
	int32_t rc = 0;
	struct cci_device *cci_dev;
	enum cci_i2c_master_t master = MASTER_0;
	struct cam_ahb_vote ahb_vote;
	struct cam_axi_vote axi_vote;
	struct cam_hw_soc_info *soc_info = NULL;
	void __iomem *base = NULL;

	cci_dev = v4l2_get_subdevdata(sd);
	if (!cci_dev || !c_ctrl) {
		CAM_ERR(CAM_CCI, "failed: invalid params %pK %pK",
			cci_dev, c_ctrl);
		rc = -EINVAL;
		return rc;
	}

	soc_info = &cci_dev->soc_info;
	base = soc_info->reg_map[0].mem_base;

	if (!soc_info || !base) {
		CAM_ERR(CAM_CCI, "failed: invalid params %pK %pK",
			soc_info, base);
		rc = -EINVAL;
		return rc;
	}

	CAM_DBG(CAM_CCI, "Base address %pK", base);

	if (cci_dev->ref_count++) {
		CAM_DBG(CAM_CCI, "ref_count %d", cci_dev->ref_count);
		master = c_ctrl->cci_info->cci_i2c_master;
		CAM_DBG(CAM_CCI, "master %d", master);
		if (master < MASTER_MAX && master >= 0) {
			mutex_lock(&cci_dev->cci_master_info[master].mutex);
			flush_workqueue(cci_dev->write_wq[master]);
			/* Re-initialize the completion */
			reinit_completion(&cci_dev->
				cci_master_info[master].reset_complete);
			for (i = 0; i < NUM_QUEUES; i++)
				reinit_completion(&cci_dev->
					cci_master_info[master].report_q[i]);
			/* Set reset pending flag to TRUE */
			cci_dev->cci_master_info[master].reset_pending = TRUE;
			/* Set proper mask to RESET CMD address */
			if (master == MASTER_0)
				cam_io_w_mb(CCI_M0_RESET_RMSK,
					base + CCI_RESET_CMD_ADDR);
			else
				cam_io_w_mb(CCI_M1_RESET_RMSK,
					base + CCI_RESET_CMD_ADDR);
			/* wait for reset done irq */
			rc = wait_for_completion_timeout(
				&cci_dev->cci_master_info[master].
				reset_complete,
				CCI_TIMEOUT);
			if (rc <= 0)
				CAM_ERR(CAM_CCI, "wait failed %d", rc);
			mutex_unlock(&cci_dev->cci_master_info[master].mutex);
		}
		return 0;
	}

	ahb_vote.type = CAM_VOTE_ABSOLUTE;
	ahb_vote.vote.level = CAM_SVS_VOTE;
	axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
	axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;

	rc = cam_cpas_start(cci_dev->cpas_handle,
		&ahb_vote, &axi_vote);
	if (rc != 0) {
		CAM_ERR(CAM_CCI, "CPAS start failed");
	}
	cam_cci_get_clk_rates(cci_dev, c_ctrl);

	/* Re-initialize the completion */
	reinit_completion(&cci_dev->cci_master_info[master].reset_complete);
	for (i = 0; i < NUM_QUEUES; i++)
		reinit_completion(&cci_dev->cci_master_info[master].
			report_q[i]);

	/* Enable Regulators and IRQ*/
	rc = cam_soc_util_enable_platform_resource(soc_info, true,
		CAM_TURBO_VOTE, true);
	if (rc < 0) {
		CAM_DBG(CAM_CCI, "request platform resources failed");
		goto platform_enable_failed;
	}

	cci_dev->hw_version = cam_io_r_mb(base +
		CCI_HW_VERSION_ADDR);
	CAM_DBG(CAM_CCI, "hw_version = 0x%x", cci_dev->hw_version);

	cci_dev->payload_size =
		MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
	cci_dev->support_seq_write = 1;

	for (i = 0; i < NUM_MASTERS; i++) {
		for (j = 0; j < NUM_QUEUES; j++) {
			if (j == QUEUE_0)
				cci_dev->cci_i2c_queue_info[i][j].
					max_queue_size =
						CCI_I2C_QUEUE_0_SIZE;
			else
				cci_dev->cci_i2c_queue_info[i][j].
					max_queue_size =
						CCI_I2C_QUEUE_1_SIZE;

			CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0 : %d Q1 : %d", i
				, cci_dev->cci_i2c_queue_info[i][j].
					max_queue_size,
				cci_dev->cci_i2c_queue_info[i][j].
					max_queue_size);
		}
	}

	cci_dev->cci_master_info[MASTER_0].reset_pending = TRUE;
	cam_io_w_mb(CCI_RESET_CMD_RMSK, base +
			CCI_RESET_CMD_ADDR);
	cam_io_w_mb(0x1, base + CCI_RESET_CMD_ADDR);
	rc = wait_for_completion_timeout(
		&cci_dev->cci_master_info[MASTER_0].reset_complete,
		CCI_TIMEOUT);
	if (rc <= 0) {
		CAM_ERR(CAM_CCI, "wait_for_completion_timeout");
		if (rc == 0)
			rc = -ETIMEDOUT;
		goto reset_complete_failed;
	}
	for (i = 0; i < MASTER_MAX; i++)
		cci_dev->i2c_freq_mode[i] = I2C_MAX_MODES;
	cam_io_w_mb(CCI_IRQ_MASK_0_RMSK,
		base + CCI_IRQ_MASK_0_ADDR);
	cam_io_w_mb(CCI_IRQ_MASK_0_RMSK,
		base + CCI_IRQ_CLEAR_0_ADDR);
	cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);

	for (i = 0; i < MASTER_MAX; i++) {
		if (!cci_dev->write_wq[i]) {
			CAM_ERR(CAM_CCI, "Failed to flush write wq");
			rc = -ENOMEM;
			goto reset_complete_failed;
		} else {
			flush_workqueue(cci_dev->write_wq[i]);
		}
	}
	cci_dev->cci_state = CCI_STATE_ENABLED;

	return 0;

reset_complete_failed:
	cam_soc_util_disable_platform_resource(soc_info, 1, 1);

platform_enable_failed:
	cci_dev->ref_count--;
	cam_cpas_stop(cci_dev->cpas_handle);

	return rc;
}

void cam_cci_soc_remove(struct platform_device *pdev,
	struct cci_device *cci_dev)
{
	struct cam_hw_soc_info *soc_info = &cci_dev->soc_info;

	cam_soc_util_release_platform_resource(soc_info);
}

static void cam_cci_init_cci_params(struct cci_device *new_cci_dev)
{
	uint8_t i = 0, j = 0;

	for (i = 0; i < NUM_MASTERS; i++) {
		new_cci_dev->cci_master_info[i].status = 0;
		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
		init_completion(&new_cci_dev->
			cci_master_info[i].reset_complete);

		for (j = 0; j < NUM_QUEUES; j++) {
			mutex_init(&new_cci_dev->cci_master_info[i].mutex_q[j]);
			init_completion(&new_cci_dev->
				cci_master_info[i].report_q[j]);
			}
	}
}

static void cam_cci_init_default_clk_params(struct cci_device *cci_dev,
	uint8_t index)
{
	/* default clock params are for 100Khz */
	cci_dev->cci_clk_params[index].hw_thigh = 201;
	cci_dev->cci_clk_params[index].hw_tlow = 174;
	cci_dev->cci_clk_params[index].hw_tsu_sto = 204;
	cci_dev->cci_clk_params[index].hw_tsu_sta = 231;
	cci_dev->cci_clk_params[index].hw_thd_dat = 22;
	cci_dev->cci_clk_params[index].hw_thd_sta = 162;
	cci_dev->cci_clk_params[index].hw_tbuf = 227;
	cci_dev->cci_clk_params[index].hw_scl_stretch_en = 0;
	cci_dev->cci_clk_params[index].hw_trdhld = 6;
	cci_dev->cci_clk_params[index].hw_tsp = 3;
	cci_dev->cci_clk_params[index].cci_clk_src = 37500000;
}

static void cam_cci_init_clk_params(struct cci_device *cci_dev)
{
	int32_t rc = 0;
	uint32_t val = 0;
	uint8_t count = 0;
	struct device_node *of_node = cci_dev->v4l2_dev_str.pdev->dev.of_node;
	struct device_node *src_node = NULL;

	for (count = 0; count < I2C_MAX_MODES; count++) {

		if (count == I2C_STANDARD_MODE)
			src_node = of_find_node_by_name(of_node,
				"qcom,i2c_standard_mode");
		else if (count == I2C_FAST_MODE)
			src_node = of_find_node_by_name(of_node,
				"qcom,i2c_fast_mode");
		else if (count == I2C_FAST_PLUS_MODE)
			src_node = of_find_node_by_name(of_node,
				"qcom,i2c_fast_plus_mode");
		else
			src_node = of_find_node_by_name(of_node,
				"qcom,i2c_custom_mode");

		rc = of_property_read_u32(src_node, "hw-thigh", &val);
		CAM_DBG(CAM_CCI, "hw-thigh %d, rc %d", val, rc);
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_thigh = val;
			rc = of_property_read_u32(src_node, "hw-tlow",
				&val);
			CAM_DBG(CAM_CCI, "hw-tlow %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_tlow = val;
			rc = of_property_read_u32(src_node, "hw-tsu-sto",
				&val);
			CAM_DBG(CAM_CCI, "hw-tsu-sto %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_tsu_sto = val;
			rc = of_property_read_u32(src_node, "hw-tsu-sta",
				&val);
			CAM_DBG(CAM_CCI, "hw-tsu-sta %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_tsu_sta = val;
			rc = of_property_read_u32(src_node, "hw-thd-dat",
				&val);
			CAM_DBG(CAM_CCI, "hw-thd-dat %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_thd_dat = val;
			rc = of_property_read_u32(src_node, "hw-thd-sta",
				&val);
			CAM_DBG(CAM_CCI, "hw-thd-sta %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_thd_sta = val;
			rc = of_property_read_u32(src_node, "hw-tbuf",
				&val);
			CAM_DBG(CAM_CCI, "hw-tbuf %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_tbuf = val;
			rc = of_property_read_u32(src_node,
				"hw-scl-stretch-en", &val);
			CAM_DBG(CAM_CCI, "hw-scl-stretch-en %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_scl_stretch_en = val;
			rc = of_property_read_u32(src_node, "hw-trdhld",
				&val);
			CAM_DBG(CAM_CCI, "hw-trdhld %d, rc %d",
				val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_trdhld = val;
			rc = of_property_read_u32(src_node, "hw-tsp",
				&val);
			CAM_DBG(CAM_CCI, "hw-tsp %d, rc %d", val, rc);
		}
		if (!rc) {
			cci_dev->cci_clk_params[count].hw_tsp = val;
			val = 0;
			rc = of_property_read_u32(src_node, "cci-clk-src",
				&val);
			CAM_DBG(CAM_CCI, "cci-clk-src %d, rc %d", val, rc);
			cci_dev->cci_clk_params[count].cci_clk_src = val;
		} else
			cam_cci_init_default_clk_params(cci_dev, count);

		of_node_put(src_node);
	}
}

int cam_cci_parse_dt_info(struct platform_device *pdev,
	struct cci_device *new_cci_dev)
{
	int rc = 0, i = 0;
	struct cam_hw_soc_info *soc_info =
		&new_cci_dev->soc_info;

	rc = cam_soc_util_get_dt_properties(soc_info);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "Parsing DT data failed:%d", rc);
		return -EINVAL;
	}

	new_cci_dev->ref_count = 0;

	rc = cam_soc_util_request_platform_resource(soc_info,
		cam_cci_irq, new_cci_dev);
	if (rc < 0) {
		CAM_ERR(CAM_CCI, "requesting platform resources failed:%d", rc);
		return -EINVAL;
	}
	new_cci_dev->v4l2_dev_str.pdev = pdev;
	cam_cci_init_cci_params(new_cci_dev);
	cam_cci_init_clk_params(new_cci_dev);

	rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
	if (rc)
		CAM_ERR(CAM_CCI, "failed to add child nodes, rc=%d", rc);

	for (i = 0; i < MASTER_MAX; i++) {
		new_cci_dev->write_wq[i] = create_singlethread_workqueue(
			"cam_cci_wq");
		if (!new_cci_dev->write_wq[i])
			CAM_ERR(CAM_CCI, "Failed to create write wq");
	}
	CAM_DBG(CAM_CCI, "Exit");
	return 0;
}

int cam_cci_soc_release(struct cci_device *cci_dev)
{
	uint8_t i = 0, rc = 0;
	struct cam_hw_soc_info *soc_info =
		&cci_dev->soc_info;

	if (!cci_dev->ref_count || cci_dev->cci_state != CCI_STATE_ENABLED) {
		CAM_ERR(CAM_CCI, "invalid ref count %d / cci state %d",
			cci_dev->ref_count, cci_dev->cci_state);
		return -EINVAL;
	}
	if (--cci_dev->ref_count) {
		CAM_DBG(CAM_CCI, "ref_count Exit %d", cci_dev->ref_count);
		return 0;
	}
	for (i = 0; i < MASTER_MAX; i++)
		if (cci_dev->write_wq[i])
			flush_workqueue(cci_dev->write_wq[i]);

	for (i = 0; i < MASTER_MAX; i++)
		cci_dev->i2c_freq_mode[i] = I2C_MAX_MODES;

	rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
	if (rc) {
		CAM_ERR(CAM_CCI, "platform resources disable failed, rc=%d",
			rc);
		return rc;
	}

	cci_dev->cci_state = CCI_STATE_DISABLED;
	cci_dev->cycles_per_us = 0;
	soc_info->src_clk_idx = 0;

	cam_cpas_stop(cci_dev->cpas_handle);

	return rc;
}
