/*
 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
 *
 * Authors: Shaik Ameer Basha <shaik.ameer@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 and
 * only version 2 as published by the Free Software Foundation.
 */

#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <asm/segment.h>
#include <linux/firmware.h>
#include <linux/pci.h>
#include <linux/airbrush-sm-ctrl.h>
#include <linux/clk.h>

#include "airbrush-ddr.h"
#include "airbrush-pmic-ctrl.h"
#include "airbrush-regs.h"
#include "airbrush-spi.h"
#include "airbrush-thermal.h"

#define REG_AON_PCI_OTP	0x10b3000c
#define REG_SRAM_ADDR	0x10b30374
#define REG_DDR_INIT	0x10b30378
#define REG_UPL_CMPL	0x10b30384
#define RAM_CRC_CLR	0x10b30390
#define RAM_CRC_En	0x10b30394
#define RAM_CRC_VAL	0x10b30398
#define GPB0_DRV	0x10b4006c

#define ROM_BL_ADDR	0
#define SRAM_PCI_OTP	0x20414
#define SRAM_PCI_BAR	(SRAM_PCI_OTP + 4*253)

#define SOC_PWRGOOD_WAIT_TIMEOUT	msecs_to_jiffies(100)
#define AB_READY_WAIT_TIMEOUT		msecs_to_jiffies(100)
#define POLL_USLEEP_MIN			(100)

#define M0_FIRMWARE_PATH "ab.fw"

static int enable_ref_clk(struct device *dev)
{
	struct clk *ref_clk = clk_get(dev, "ab_ref");

	if (!IS_ERR(ref_clk))
		return clk_prepare_enable(ref_clk);
	else
		return PTR_ERR(ref_clk);
}

void parse_fw(uint32_t *image_dw_buf, const unsigned char *image_buf,
		int image_size_dw)
{
	int dw, byte;

	for (dw = 0; dw < image_size_dw; dw++) {
		byte = dw * 4;
		image_dw_buf[dw] = (image_buf[byte + 3] << 24 |
			image_buf[byte + 2] << 16 | image_buf[byte + 1] << 8 |
			image_buf[byte]);
	}
}

/* Caller must hold ab_ctx->state_lock */
int ab_bootsequence(struct ab_state_context *ab_ctx, enum chip_state prev_state)
{
	/* Number of attempts to flash SRAM bootcode when CRC error happens */
	int num_attempts = 1;
	int crc_ok = 1;
	unsigned int data;
	struct airbrush_spi_packet spi_packet;
	int ret;
	struct platform_device *plat_dev = ab_ctx->pdev;
	unsigned long timeout;
	uint32_t dummy[3] = { 0 };
	enum ab_chip_id saved_chip_id, raw_chip_id;

	if (!ab_ctx)
		return -EINVAL;

	if (ab_ctx->cold_boot) {
		ab_disable_pgood(ab_ctx);
		msm_pcie_assert_perst(1);

		/* Disable PCIe equalization only for Airbrush A0 parts.
		 *   A0 => PCIe EQ disable
		 *   B0 => PCIe EQ enable
		 */
		saved_chip_id = ab_get_chip_id(ab_ctx);
		if (saved_chip_id == CHIP_ID_B0) {
			dev_info(ab_ctx->dev,
				 "AB version is B0\n");
			msm_pcie_eq_ctrl(1, /*enable=*/true);
		} else if (saved_chip_id == CHIP_ID_A0) {
			dev_err(ab_ctx->dev,
				"AB version is A0, which is not fully supported\n");
			msm_pcie_eq_ctrl(1, /*enable=*/false);
		} else {
			dev_warn(ab_ctx->dev,
				"WARNING: AB version is unknown\n");
			msm_pcie_eq_ctrl(1, /*enable=*/false);
		}
	}

	ret = ab_pmic_on(ab_ctx);
	if (ret) {
		dev_err(ab_ctx->dev, "ERROR!!! PMIC failure during ABC Boot");
		return ret;
	}

	ret = enable_ref_clk(ab_ctx->dev);
	if (ret) {
		dev_err(ab_ctx->dev,
			"Unable to enable reference clock (err %d)",
			ret);
		return ret;
	}

	if (prev_state == CHIP_STATE_100) {
		/* M0 samples DDR_SR for its ddr_train sequence */
		ab_gpio_enable_ddr_sr(ab_ctx);

		/*
		 * DDRCKE_ISO stays on during suspend in production.
		 * Disable it during resume before asserting pgood
		 * (b/128545111).
		 */
		if (!ab_ctx->ddrcke_iso_clamp_wr)
			ab_gpio_disable_ddr_iso(ab_ctx);
	}

	if (ab_ctx->alternate_boot)
		ab_gpio_enable_fw_patch(ab_ctx);

	msm_pcie_deassert_perst(1);
	ab_enable_pgood(ab_ctx);

	timeout = jiffies + SOC_PWRGOOD_WAIT_TIMEOUT;
	/* Wait until soc_pwrgood is set by PMIC */
	while (!gpiod_get_value_cansleep(ab_ctx->soc_pwrgood) &&
			time_before(jiffies, timeout))
		usleep_range(POLL_USLEEP_MIN, POLL_USLEEP_MIN + 1);

	if (!gpiod_get_value_cansleep(ab_ctx->soc_pwrgood)) {
		dev_err(&plat_dev->dev, "ABC PWRGOOD is not enabled");
		return -EIO;
	}

	ab_sm_start_ts(AB_SM_TS_ALT_BOOT);
	if (ab_ctx->alternate_boot) {
		dev_info(ab_ctx->dev, "alternate boot\n");

		/* Wait for AB_READY = 1,
		 * this ensures the SPI FSM is initialized to flash the
		 * alternate bootcode to SRAM.
		 */
		timeout = jiffies + AB_READY_WAIT_TIMEOUT;
		while (!gpiod_get_value_cansleep(ab_ctx->ab_ready) &&
				time_before(jiffies, timeout))
			usleep_range(POLL_USLEEP_MIN, POLL_USLEEP_MIN + 1);

		if (!gpiod_get_value_cansleep(ab_ctx->ab_ready)) {
			dev_err(&plat_dev->dev,
				"ab_ready is not high before fw load");
			return -EIO;
		}

		/* Enable CRC via SPI-FSM */
		while (num_attempts) {
			/* [TBD] Reset CRC Register via SPI-FSM */

			/* PCIe PHY OTP patch count  */
			spi_packet.command = AB_SPI_CMD_FSM_WRITE_SINGLE;
			spi_packet.granularity = FOUR_BYTE;
			spi_packet.base_address = SRAM_PCI_OTP;
			spi_packet.data_length = 1;
			spi_packet.data = dummy;

			if (airbrush_spi_run_cmd(&spi_packet))
				return -EIO;

			/* BAR0, 2, and 4 sizes  */
			spi_packet.command = AB_SPI_CMD_FSM_BURST_WRITE;
			spi_packet.granularity = FOUR_BYTE;
			spi_packet.base_address = SRAM_PCI_BAR;
			spi_packet.data_length = 3;
			spi_packet.data = dummy;

			if (airbrush_spi_run_cmd(&spi_packet))
				return -EIO;

			/* Stop OTP read of PCIe configuration  */
			dummy[0] = 2;
			spi_packet.command = AB_SPI_CMD_FSM_WRITE_SINGLE;
			spi_packet.granularity = FOUR_BYTE;
			spi_packet.base_address = REG_AON_PCI_OTP;
			spi_packet.data_length = 1;
			spi_packet.data = dummy;

			if (airbrush_spi_run_cmd(&spi_packet))
				return -EIO;

			/* if CRC is OK, break the loop */
			if (crc_ok)
				break;

			/* Decrement the number of attempts and retry */
			num_attempts--;

			if (!num_attempts)
				return -EIO;
		}

		/* set REG_SRAM_ADDR=SRAM_BL_ADDR via SPI-FSM */
		data = ROM_BL_ADDR;
		spi_packet.command = AB_SPI_CMD_FSM_WRITE_SINGLE;
		spi_packet.granularity = FOUR_BYTE;
		spi_packet.base_address = REG_SRAM_ADDR;
		spi_packet.data_length = 1;
		spi_packet.data = &data;

		if (airbrush_spi_run_cmd(&spi_packet))
			return -EIO;

		/* set REG_UPL_CMPL=1  via SPI-FSM */
		data = 0x1; // used to write REG_UPL_CMPL = 0x1
		spi_packet.command = AB_SPI_CMD_FSM_WRITE_SINGLE;
		spi_packet.granularity = FOUR_BYTE;
		spi_packet.base_address = REG_UPL_CMPL;
		spi_packet.data_length = 1;
		spi_packet.data = &data;

		if (airbrush_spi_run_cmd(&spi_packet))
			return -EIO;

		/* Read the REG_UPL_COMPL register to make sure the
		 * AB_READY is deasserted by the Airbrush.
		 * Note: Assumption is that, by the time host reads the
		 * REG_UPL_CMPL register, Airbrush would have deasserted
		 * the AB_READY gpio.
		 */
		spi_packet.command = AB_SPI_CMD_FSM_READ_SINGLE;
		spi_packet.granularity = FOUR_BYTE;
		spi_packet.base_address = REG_UPL_CMPL;
		spi_packet.data_length = 1;
		spi_packet.data = NULL;

		if (airbrush_spi_run_cmd(&spi_packet))
			return -EIO;
	}
	ab_sm_record_ts(AB_SM_TS_ALT_BOOT);

	if (ab_ctx->cold_boot) {
		ab_sm_start_ts(AB_SM_TS_PCIE_ENUM);
		ret = ab_sm_enumerate_pcie(ab_ctx);
		ab_sm_record_ts(AB_SM_TS_PCIE_ENUM);
		if (ret)
			return ret;

		ab_ctx->cold_boot = false;

		/* Cross-check chip id after cold boot. */
		raw_chip_id = ab_get_raw_chip_id(ab_ctx);
		if (saved_chip_id != raw_chip_id) {
			dev_warn(ab_ctx->dev,
				 "saved_chip_id %d does not match raw_chip_id %d\n",
				 saved_chip_id, raw_chip_id);

			if (raw_chip_id == CHIP_ID_UNKNOWN) {
				dev_warn(ab_ctx->dev,
					 "Keep %d as chip_id\n",
					 ab_ctx->chip_id);
			} else {
				dev_warn(ab_ctx->dev,
					 "Use %d as chip_id\n",
					 raw_chip_id);
				ab_ctx->chip_id = raw_chip_id;
			}
		}

		ab_sm_start_ts(AB_SM_TS_LVCC_INIT);
		ab_lvcc_init(&ab_ctx->asv_info);
		ab_sm_record_ts(AB_SM_TS_LVCC_INIT);
	} else {
		ab_sm_start_ts(AB_SM_TS_PCIE_ENUM);

		if (ab_ctx->debug_skip_pcie_link_init) {
			dev_warn(ab_ctx->dev,
				 "Skip PCIe link resume for testing\n");
			ab_sm_record_ts(AB_SM_TS_PCIE_ENUM);
			return -ENODEV;
		}

		ret = ab_sm_enable_pcie(ab_ctx);
		ab_sm_record_ts(AB_SM_TS_PCIE_ENUM);
		if (ret)
			return ret;
	}

	/* Wait for AB_READY = 1,
	 * this ensures the SPI FSM is initialized to flash the
	 * alternate bootcode to SRAM.
	 */
	timeout = jiffies + AB_READY_WAIT_TIMEOUT;
	while (!gpiod_get_value_cansleep(ab_ctx->ab_ready) &&
			time_before(jiffies, timeout)) {
		usleep_range(POLL_USLEEP_MIN, POLL_USLEEP_MIN + 1);
	}

	if (!gpiod_get_value_cansleep(ab_ctx->ab_ready)) {
		dev_err(&plat_dev->dev,
			"ab_ready is not high after fw load\n");
		return -EIO;
	}

	ab_sm_start_ts(AB_SM_TS_AB_READY_NOTIFY);
	mutex_lock(&ab_ctx->mfd_lock);
	ret = ab_ctx->mfd_ops->ab_ready(ab_ctx->mfd_ops->ctx);
	mutex_unlock(&ab_ctx->mfd_lock);
	ab_sm_record_ts(AB_SM_TS_AB_READY_NOTIFY);

	/* b/129788388: configure PCIe PCS block to disable PLL at the start of
	 * P1.CPM state
	 */
	ABC_WRITE(PCS_OUT_VEC_4, 0x700DD);

	/* Enable schmitt trigger mode for SPI clk pad.
	 * This is to filter out any noise on SPI clk line.
	 * Also reset the SPI controller in case it's already
	 * in a glitched state.
	 */
	ABC_WRITE(GPB0_DRV, 0x22222262);
	ABC_WRITE(SYSREG_AON_SPI0_AHB_ENABLE, 0x0);
	ABC_WRITE(SYSREG_AON_SPI0_AHB_ENABLE, 0x1);

	/* Set clocks to usable states */
	ab_sm_start_ts(AB_SM_TS_CLK_INIT);
	ab_ctx->clk_ops->init(ab_ctx->clk_ops->ctx);
	ab_sm_record_ts(AB_SM_TS_CLK_INIT);

	ab_sm_start_ts(AB_SM_TS_DDR_INIT);
	/* Setup the function pointer to read DDR OTPs */
	ret = ab_ctx->dram_ops->setup(ab_ctx->dram_ops->ctx, ab_ctx);
	if (ret) {
		dev_err(ab_ctx->dev, "ddr setup failed\n");
		return ret;
	}
	/* Wait till the ddr init & training is completed in case of ddr
	 * initialization is done by BootROM
	 */
	if (IS_M0_DDR_INIT()) {
		if (ab_ctx->dram_ops->wait_for_m0_ddr_init(
					ab_ctx->dram_ops->ctx))
			return -EIO;
	}
	ret = ab_ctx->dram_ops->init(ab_ctx->dram_ops->ctx);
	if (ret) {
		dev_err(ab_ctx->dev, "ddr init failed\n");
		return ret;
	}
	ab_sm_record_ts(AB_SM_TS_DDR_INIT);

	/*
	 * Enable thermal after boot sequence finished successfully. Do not
	 * let thermal throttle intefere the bootsequence.
	 */
	ab_thermal_enable(ab_ctx->thermal);

	return 0;
}
EXPORT_SYMBOL(ab_bootsequence);
