/*
 * This file is part of the flashprog project.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 <stdbool.h>
#include "flash.h"
#include "chipdrivers.h"
#include "programmer.h"
#include "spi_command.h"
#include "spi.h"

static int spi_enter_exit_4ba(struct flashctx *const flash, const bool enter)
{
	const unsigned char cmd = enter ? JEDEC_ENTER_4_BYTE_ADDR_MODE : JEDEC_EXIT_4_BYTE_ADDR_MODE;
	int ret = 1;

	if (flash->chip->feature_bits & FEATURE_4BA_ENTER)
		ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
	else if (flash->chip->feature_bits & FEATURE_4BA_ENTER_WREN)
		ret = spi_simple_write_cmd(flash, cmd, 0);
	else if (flash->chip->feature_bits & FEATURE_4BA_ENTER_EAR7)
		ret = spi_set_extended_address(flash, enter ? 0x80 : 0x00);

	if (!ret)
		flash->in_4ba_mode = enter;
	return ret;
}

static int spi_enter_4ba(struct flashctx *const flash)
{
	return spi_enter_exit_4ba(flash, true);
}

static int spi_exit_4ba(struct flashctx *flash)
{
	return spi_enter_exit_4ba(flash, false);
}

static int spi_prepare_4ba(struct flashctx *const flash)
{
	flash->address_high_byte = -1;
	flash->in_4ba_mode = false;

	/* Be careful about 4BA chips and broken masters */
	if (flash->chip->total_size > 16 * 1024 && spi_master_no_4ba_modes(flash)) {
		/* If we can't use native instructions, bail out */
		if ((flash->chip->feature_bits & FEATURE_4BA_NATIVE) != FEATURE_4BA_NATIVE
		    || !spi_master_4ba(flash)) {
			msg_cerr("Programmer doesn't support this chip. Aborting.\n");
			return 1;
		}
	}

	/* Enable/disable 4-byte addressing mode if flash chip supports it */
	if (flash->chip->feature_bits & (FEATURE_4BA_ENTER | FEATURE_4BA_ENTER_WREN | FEATURE_4BA_ENTER_EAR7)) {
		int ret;
		if (spi_master_4ba(flash))
			ret = spi_enter_4ba(flash);
		else
			ret = spi_exit_4ba(flash);
		if (ret) {
			msg_cerr("Failed to set correct 4BA mode! Aborting.\n");
			return 1;
		}
	}

	return 0;
}

static int spi_enter_qpi(struct flashctx *const flash)
{
	const unsigned char cmd = flash->chip->feature_bits & FEATURE_QPI_35_F5 ? 0x35 : 0x38;
	const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
	if (!ret) {
		msg_cdbg("Entered QPI mode.\n");
		flash->in_qpi_mode = true;
	}
	return ret;
}

static int spi_exit_qpi(struct flashctx *const flash)
{
	const unsigned char cmd = flash->chip->feature_bits & FEATURE_QPI_35_F5 ? 0xf5 : 0xff;
	const int ret = spi_send_command(flash, sizeof(cmd), 0, &cmd, NULL);
	if (!ret) {
		msg_cdbg("Left QPI mode.\n");
		flash->in_qpi_mode = false;
	}
	return ret;
}

enum io_mode spi_current_io_mode(const struct flashctx *const flash)
{
	return flash->in_qpi_mode ? QPI_4_4_4 : SINGLE_IO_1_1_1;
}

static int spi_prepare_quad_io(struct flashctx *const flash)
{
	if (!spi_master_quad(flash) && !spi_master_qpi(flash))
		return 0;

	/* Check QE bit if present */
	flash->volatile_qe_enabled = false;
	if (flash->chip->reg_bits.qe.reg != INVALID_REG) {
		const struct reg_bit_info qe = flash->chip->reg_bits.qe;
		const uint8_t mask = 1 << qe.bit_index;
		uint8_t reg_val;

		if (spi_read_register(flash, qe.reg, &reg_val)) {
			reg_val = 0;
		} else if (!(reg_val & mask) &&
			   (flash->chip->feature_bits & FEATURE_WRSR_EWSR)) {
			msg_pdbg("Trying to set volatile quad-enable (QE).\n");
			reg_val |= mask;
			if (spi_write_register(flash, qe.reg, reg_val, WRSR_VOLATILE_BITS) ||
			    spi_read_register(flash, qe.reg, &reg_val)) {
				reg_val = 0;
			} else if (reg_val & mask) {
				flash->volatile_qe_enabled = true;
			}
		}

		if (!(reg_val & mask)) {
			msg_cinfo("Quad-enable (QE) bit is unknown or unset, disabling quad i/o.\n");
			flash->chip->feature_bits &= ~FEATURE_ANY_QUAD;
		} else {
			msg_cdbg("Quad-enable (QE) bit is set.\n");
		}
	}

	flash->in_qpi_mode = false;

	if (!(flash->chip->feature_bits & (FEATURE_QPI_35_F5 | FEATURE_QPI_38_FF)) || !spi_master_qpi(flash))
		return 0;

	if (spi_enter_qpi(flash))
		msg_cwarn("Failed to switch to QPI mode!\n");

	return 0;
}

static bool qpi_use_fast_read_qio(const struct flashctx *flash)
{
	return flash->chip->feature_bits & FEATURE_SET_READ_PARAMS ||
		flash->chip->reg_bits.dc[0].reg != INVALID_REG ||
		(flash->chip->dummy_cycles.qpi_fast_read_qio != 0 &&
		 (flash->chip->dummy_cycles.qpi_fast_read == 0 ||
		  flash->chip->dummy_cycles.qpi_fast_read_qio <=
			flash->chip->dummy_cycles.qpi_fast_read));
}

static int qpi_dummy_cycles(const struct flashctx *flash)
{
	if (flash->chip->feature_bits & FEATURE_SET_READ_PARAMS ||
	    flash->chip->reg_bits.dc[0].reg != INVALID_REG)
		/* TODO: Index 00 is assumed to be the default.
		         Could switch to potentially faster params. */
		return flash->chip->dummy_cycles.qpi_read_params.clks00;
	else if (qpi_use_fast_read_qio(flash))
		return flash->chip->dummy_cycles.qpi_fast_read_qio;
	else
		return flash->chip->dummy_cycles.qpi_fast_read;
}

static const struct spi_read_op *select_qpi_fast_read(const struct flashctx *flash)
{
	static const struct spi_read_op fast_read = { QPI_4_4_4, false, JEDEC_FAST_READ, 0x00, 0 };
	static const struct spi_read_op fast_read_qio = { QPI_4_4_4, false, JEDEC_FAST_READ_QIO, 0xff, 0 };
	static const struct spi_read_op fast_read_qio_4ba = { QPI_4_4_4, true, JEDEC_FAST_READ_QIO_4BA, 0xff, 0 };

	if (qpi_use_fast_read_qio(flash)) {
		if (flash->chip->feature_bits & FEATURE_FAST_READ_QPI4B &&
		    spi_master_4ba(flash) && flash->mst.spi->probe_opcode(flash, fast_read_qio_4ba.opcode))
			return &fast_read_qio_4ba;
		else
			return &fast_read_qio;
	} else {
		return &fast_read;
	}
}

static const struct spi_read_op *select_multi_io_fast_read(const struct flashctx *flash)
{
	static const struct {
		unsigned int feature_check;
		unsigned int master_check;
		struct spi_read_op op;
	#define MIO_CHECKS(flash_feature, master_feature) \
		FEATURE_FAST_READ_##flash_feature, SPI_MASTER_##master_feature
	} mio[] = { /*       flash  master                     4BA                              mode  dummies */
		{ MIO_CHECKS(QIO,  QUAD_IO), { QUAD_IO_1_4_4,  true,  JEDEC_FAST_READ_QIO_4BA,  0xff, 3 } },
		{ MIO_CHECKS(QOUT, QUAD_IN), { QUAD_OUT_1_1_4, true,  JEDEC_FAST_READ_QOUT_4BA, 0x00, 4 } },
		{ MIO_CHECKS(DIO,  DUAL_IO), { DUAL_IO_1_2_2,  true,  JEDEC_FAST_READ_DIO_4BA,  0xff, 1 } },
		{ MIO_CHECKS(DOUT, DUAL_IN), { DUAL_OUT_1_1_2, true,  JEDEC_FAST_READ_DOUT_4BA, 0x00, 2 } },
		{ MIO_CHECKS(QIO,  QUAD_IO), { QUAD_IO_1_4_4,  false, JEDEC_FAST_READ_QIO,      0xff, 3 } },
		{ MIO_CHECKS(QOUT, QUAD_IN), { QUAD_OUT_1_1_4, false, JEDEC_FAST_READ_QOUT,     0x00, 4 } },
		{ MIO_CHECKS(DIO,  DUAL_IO), { DUAL_IO_1_2_2,  false, JEDEC_FAST_READ_DIO,      0xff, 1 } },
		{ MIO_CHECKS(DOUT, DUAL_IN), { DUAL_OUT_1_1_2, false, JEDEC_FAST_READ_DOUT,     0x00, 2 } },
	};

	unsigned int i;
	for (i = 0; i < ARRAY_SIZE(mio); ++i) {
		if (mio[i].op.native_4ba && !(flash->chip->feature_bits & FEATURE_4BA_FAST_READ))
			continue;
		if ((flash->chip->feature_bits & mio[i].feature_check) != mio[i].feature_check)
			continue;
		if ((flash->mst.spi->features & mio[i].master_check) != mio[i].master_check)
			continue;
		if (mio[i].op.native_4ba && !spi_master_4ba(flash))
			continue;
		if (flash->mst.spi->probe_opcode(flash, mio[i].op.opcode))
			return &mio[i].op;
	}

	return NULL;
}

static struct spi_read_op *select_spi_fast_read(const struct flashctx *flash)
{
	const struct spi_read_op *const fast_read =
		flash->in_qpi_mode
		? select_qpi_fast_read(flash)
		: select_multi_io_fast_read(flash);
	if (!fast_read)
		return NULL;

	struct spi_read_op *const fast_read_copy = malloc(sizeof(*flash->spi_fast_read));
	if (!fast_read_copy)
		return NULL;

	*fast_read_copy = *fast_read;
	if (flash->in_qpi_mode)
		fast_read_copy->dummy_len = qpi_dummy_cycles(flash) / 2;

	return fast_read_copy;
}

int spi_prepare_io(struct flashctx *const flash, const enum preparation_steps prep)
{
	if (prep != PREPARE_FULL)
		return 0;

	int ret = spi_prepare_4ba(flash);
	if (ret)
		return ret;

	ret = spi_prepare_quad_io(flash);
	if (ret)
		return ret;

	flash->spi_fast_read = select_spi_fast_read(flash);

	if (!flash->spi_fast_read && flash->in_qpi_mode) {
		msg_cwarn("No compatible fast-read operation! Leaving QPI mode.\n");
		if (spi_exit_qpi(flash)) {
			msg_cerr("Failed to exit QPI mode!\n");
			return 1;
		}
		/* Try again w/o QPI */
		flash->spi_fast_read = select_spi_fast_read(flash);
	}

	return 0;
}

void spi_finish_io(struct flashctx *const flash)
{
	if (flash->in_qpi_mode) {
		if (spi_exit_qpi(flash))
			msg_cwarn("Failed to exit QPI mode!\n");
	}
	if (flash->volatile_qe_enabled) {
		msg_pdbg("Trying to restore volatile quad-enable (QE) state.\n");
		const struct reg_bit_info qe = flash->chip->reg_bits.qe;
		uint8_t reg_val;

		if (!spi_read_register(flash, qe.reg, &reg_val)) {
			reg_val &= ~(1 << qe.bit_index);
			spi_write_register(flash, qe.reg, reg_val, WRSR_VOLATILE_BITS);
		}
	}
	free(flash->spi_fast_read);
}
