/* 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 <linux/of.h>
#include <linux/debugfs.h>
#include <linux/videodev2.h>
#include <linux/uaccess.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include "cam_io_util.h"
#include "cam_hw.h"
#include "cam_hw_intf.h"
#include "ipe_core.h"
#include "ipe_soc.h"
#include "cam_soc_util.h"
#include "cam_io_util.h"
#include "cam_ipe_hw_intf.h"
#include "cam_icp_hw_mgr_intf.h"
#include "cam_cpas_api.h"
#include "cam_debug_util.h"

static int cam_ipe_caps_vote(struct cam_ipe_device_core_info *core_info,
	struct cam_icp_cpas_vote *cpas_vote)
{
	int rc = 0;

	if (cpas_vote->ahb_vote_valid)
		rc = cam_cpas_update_ahb_vote(core_info->cpas_handle,
			&cpas_vote->ahb_vote);
	if (cpas_vote->axi_vote_valid)
		rc = cam_cpas_update_axi_vote(core_info->cpas_handle,
			&cpas_vote->axi_vote);

	if (rc)
		CAM_ERR(CAM_ICP, "cpas vote is failed: %d", rc);

	return rc;
}

int cam_ipe_init_hw(void *device_priv,
	void *init_hw_args, uint32_t arg_size)
{
	struct cam_hw_info *ipe_dev = device_priv;
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_ipe_device_core_info *core_info = NULL;
	struct cam_icp_cpas_vote cpas_vote;
	int rc = 0;

	if (!device_priv) {
		CAM_ERR(CAM_ICP, "Invalid cam_dev_info");
		return -EINVAL;
	}

	soc_info = &ipe_dev->soc_info;
	core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;

	if ((!soc_info) || (!core_info)) {
		CAM_ERR(CAM_ICP, "soc_info = %pK core_info = %pK",
			soc_info, core_info);
		return -EINVAL;
	}

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

	rc = cam_cpas_start(core_info->cpas_handle,
		&cpas_vote.ahb_vote, &cpas_vote.axi_vote);
	if (rc) {
		CAM_ERR(CAM_ICP, "cpass start failed: %d", rc);
		return rc;
	}
	core_info->cpas_start = true;

	rc = cam_ipe_enable_soc_resources(soc_info);
	if (rc) {
		CAM_ERR(CAM_ICP, "soc enable is failed : %d", rc);
		if (cam_cpas_stop(core_info->cpas_handle))
			CAM_ERR(CAM_ICP, "cpas stop is failed");
		else
			core_info->cpas_start = false;
	}

	return rc;
}

int cam_ipe_deinit_hw(void *device_priv,
	void *init_hw_args, uint32_t arg_size)
{
	struct cam_hw_info *ipe_dev = device_priv;
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_ipe_device_core_info *core_info = NULL;
	int rc = 0;

	if (!device_priv) {
		CAM_ERR(CAM_ICP, "Invalid cam_dev_info");
		return -EINVAL;
	}

	soc_info = &ipe_dev->soc_info;
	core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
	if ((!soc_info) || (!core_info)) {
		CAM_ERR(CAM_ICP, "soc_info = %pK core_info = %pK",
			soc_info, core_info);
		return -EINVAL;
	}

	rc = cam_ipe_disable_soc_resources(soc_info);
	if (rc)
		CAM_ERR(CAM_ICP, "soc disable is failed : %d", rc);

	if (core_info->cpas_start) {
		if (cam_cpas_stop(core_info->cpas_handle))
			CAM_ERR(CAM_ICP, "cpas stop is failed");
		else
			core_info->cpas_start = false;
	}

	return rc;
}

static int cam_ipe_handle_pc(struct cam_hw_info *ipe_dev)
{
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_ipe_device_core_info *core_info = NULL;
	struct cam_ipe_device_hw_info *hw_info = NULL;
	int pwr_ctrl;
	int pwr_status;

	soc_info = &ipe_dev->soc_info;
	core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
	hw_info = core_info->ipe_hw_info;

	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl,
		true, &pwr_ctrl);
	if (!(pwr_ctrl & IPE_COLLAPSE_MASK)) {
		cam_cpas_reg_read(core_info->cpas_handle,
			CAM_CPAS_REG_CPASTOP, hw_info->pwr_status,
			true, &pwr_status);
		cam_cpas_reg_write(core_info->cpas_handle,
			CAM_CPAS_REG_CPASTOP,
			hw_info->pwr_ctrl, true, 0x1);

		if (pwr_status >> IPE_PWR_ON_MASK)
			return -EINVAL;

	}
	cam_ipe_get_gdsc_control(soc_info);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl,
		true, &pwr_ctrl);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_status,
		true, &pwr_status);
	CAM_DBG(CAM_ICP, "pwr_ctrl = %x pwr_status = %x",
		pwr_ctrl, pwr_status);

	return 0;
}

static int cam_ipe_handle_resume(struct cam_hw_info *ipe_dev)
{
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_ipe_device_core_info *core_info = NULL;
	struct cam_ipe_device_hw_info *hw_info = NULL;
	int pwr_ctrl;
	int pwr_status;
	int rc = 0;

	soc_info = &ipe_dev->soc_info;
	core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
	hw_info = core_info->ipe_hw_info;

	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl,
		true, &pwr_ctrl);
	if (pwr_ctrl & IPE_COLLAPSE_MASK) {
		CAM_ERR(CAM_ICP, "IPE: resume failed : %d", pwr_ctrl);
		return -EINVAL;
	}
	rc = cam_ipe_transfer_gdsc_control(soc_info);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, &pwr_ctrl);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_status,
		true, &pwr_status);
	CAM_DBG(CAM_ICP, "pwr_ctrl = %x pwr_status = %x",
		pwr_ctrl, pwr_status);

	return rc;
}

int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
	void *cmd_args, uint32_t arg_size)
{
	struct cam_hw_info *ipe_dev = device_priv;
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_ipe_device_core_info *core_info = NULL;
	struct cam_ipe_device_hw_info *hw_info = NULL;
	int rc = 0;

	if (!device_priv) {
		CAM_ERR(CAM_ICP, "Invalid arguments");
		return -EINVAL;
	}

	if (cmd_type >= CAM_ICP_IPE_CMD_MAX) {
		CAM_ERR(CAM_ICP, "Invalid command : %x", cmd_type);
		return -EINVAL;
	}

	soc_info = &ipe_dev->soc_info;
	core_info = (struct cam_ipe_device_core_info *)ipe_dev->core_info;
	hw_info = core_info->ipe_hw_info;

	switch (cmd_type) {
	case CAM_ICP_IPE_CMD_VOTE_CPAS: {
		struct cam_icp_cpas_vote *cpas_vote = cmd_args;

		if (!cmd_args)
			return -EINVAL;

		cam_ipe_caps_vote(core_info, cpas_vote);
		break;
	}

	case CAM_ICP_IPE_CMD_CPAS_START: {
		struct cam_icp_cpas_vote *cpas_vote = cmd_args;

		if (!cmd_args)
			return -EINVAL;

		if (!core_info->cpas_start) {
			rc = cam_cpas_start(core_info->cpas_handle,
				&cpas_vote->ahb_vote, &cpas_vote->axi_vote);
			core_info->cpas_start = true;
		}
		break;
	}

	case CAM_ICP_IPE_CMD_CPAS_STOP:
		if (core_info->cpas_start) {
			cam_cpas_stop(core_info->cpas_handle);
			core_info->cpas_start = false;
		}
		break;
	case CAM_ICP_IPE_CMD_POWER_COLLAPSE:
		rc = cam_ipe_handle_pc(ipe_dev);
		break;
	case CAM_ICP_IPE_CMD_POWER_RESUME:
		rc = cam_ipe_handle_resume(ipe_dev);
		break;
	case CAM_ICP_IPE_CMD_UPDATE_CLK: {
		uint32_t clk_rate = *(uint32_t *)cmd_args;

		CAM_DBG(CAM_ICP, "ipe_src_clk rate = %d", (int)clk_rate);
		rc = cam_ipe_update_clk_rate(soc_info, clk_rate);
		}
		break;
	default:
		break;
	}
	return rc;
}

irqreturn_t cam_ipe_irq(int irq_num, void *data)
{
	return IRQ_HANDLED;
}
