/*
 * This file is part of the flashrom project.
 *
 * Copyright (C) 2014 Google LLC.
 *
 * 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.
 */

/*
 * s25f.c - Helper functions for Spansion S25FL and S25FS SPI flash chips.
 * Uses 24 bit addressing for the FS chips and 32 bit addressing for the FL
 * chips (which is required by the overlayed sector size devices).
 * TODO: Implement fancy hybrid sector architecture helpers.
 */

#include <string.h>

#include "chipdrivers.h"
#include "spi.h"
#include "writeprotect.h"

/*
 * RDAR and WRAR are supported on chips which have more than one set of status
 * and control registers and take an address of the register to read/write.
 * WRR, RDSR2, and RDCR are used on chips with a more limited set of control/
 * status registers.
 *
 * WRR is somewhat peculiar. It shares the same opcode as JEDEC_WRSR, and if
 * given one data byte (following the opcode) it acts the same way. If it's
 * given two data bytes, the first data byte overwrites status register 1
 * and the second data byte overwrites config register 1.
 */
#define CMD_WRR		0x01
#define CMD_WRDI	0x04
#define CMD_RDSR2	0x07	/* note: read SR1 with JEDEC RDSR opcode */
#define CMD_RDCR	0x35
#define CMD_RDAR	0x65
#define CMD_WRAR	0x71

/* TODO: For now, commands which use an address assume 24-bit addressing */
#define CMD_WRR_LEN	3
#define CMD_WRDI_LEN	1
#define CMD_RDAR_LEN	4
#define CMD_WRAR_LEN	5

#define CMD_RSTEN	0x66
#define CMD_RST		0x99

#define CR1NV_ADDR	0x000002
#define CR1_BPNV_O	(1 << 3)
#define CR1_TBPROT_O	(1 << 5)
#define CR3NV_ADDR	0x000004
#define CR3NV_20H_NV	(1 << 3)

/* See "Embedded Algorithm Performance Tables for additional timing specs. */
#define T_W		145 * 1000	/* NV register write time (145ms) */
#define T_RPH		35		/* Reset pulse hold time (35us) */
#define S25FS_T_SE	145 * 1000	/* Sector Erase Time (145ms) */
#define S25FL_T_SE	130 * 1000	/* Sector Erase Time (130ms) */

static int s25f_legacy_software_reset(const struct flashctx *flash)
{
	struct spi_command cmds[] = {
	{
		.writecnt	= 1,
		.writearr	= (const uint8_t[]){ CMD_RSTEN },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 1,
		.writearr	= (const uint8_t[]){ 0xf0 },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 0,
		.writearr	= NULL,
		.readcnt	= 0,
		.readarr	= NULL,
	}};

	int result = spi_send_multicommand(flash, cmds);
	if (result) {
		msg_cerr("%s failed during command execution\n", __func__);
		return result;
	}

	/* Allow time for reset command to execute. The datasheet specifies
	 * Trph = 35us, double that to be safe. */
	programmer_delay(T_RPH * 2);

	return 0;
}

/* "Legacy software reset" is disabled by default on S25FS, use this instead. */
static int s25fs_software_reset(struct flashctx *flash)
{
	struct spi_command cmds[] = {
	{
		.writecnt	= 1,
		.writearr	= (const uint8_t[]){ CMD_RSTEN },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 1,
		.writearr	= (const uint8_t[]){ CMD_RST },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 0,
		.writearr	= NULL,
		.readcnt	= 0,
		.readarr	= NULL,
	}};

	int result = spi_send_multicommand(flash, cmds);
	if (result) {
		msg_cerr("%s failed during command execution\n", __func__);
		return result;
	}

	/* Allow time for reset command to execute. Double tRPH to be safe. */
	programmer_delay(T_RPH * 2);

	return 0;
}

static int s25f_poll_status(const struct flashctx *flash)
{
	uint8_t tmp = spi_read_status_register(flash);

	while (tmp & SPI_SR_WIP) {
		/*
		 * The WIP bit on S25F chips remains set to 1 if erase or
		 * programming errors occur, so we must check for those
		 * errors here. If an error is encountered, do a software
		 * reset to clear WIP and other volatile bits, otherwise
		 * the chip will be unresponsive to further commands.
		 */
		if (tmp & SPI_SR_ERA_ERR) {
			msg_cerr("Erase error occurred\n");
			s25f_legacy_software_reset(flash);
			return -1;
		}

		if (tmp & (1 << 6)) {
			msg_cerr("Programming error occurred\n");
			s25f_legacy_software_reset(flash);
			return -1;
		}

		programmer_delay(1000 * 10);
		tmp = spi_read_status_register(flash);
	}

	return 0;
}

/* "Read Any Register" instruction only supported on S25FS */
static int s25fs_read_cr(const struct flashctx *flash, uint32_t addr)
{
	uint8_t cfg;
	/* By default, 8 dummy cycles are necessary for variable-latency
	   commands such as RDAR (see CR2NV[3:0]). */
	uint8_t read_cr_cmd[] = {
		CMD_RDAR,
		(addr >> 16) & 0xff,
		(addr >> 8) & 0xff,
		(addr & 0xff),
		0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00,
	};

	int result = spi_send_command(flash, sizeof(read_cr_cmd), 1, read_cr_cmd, &cfg);
	if (result) {
		msg_cerr("%s failed during command execution at address 0x%x\n",
			__func__, addr);
		return -1;
	}

	return cfg;
}

static int s25f_read_cr1(const struct flashctx *flash)
{
	int result;
	uint8_t cfg;
	unsigned char read_cr_cmd[] = { CMD_RDCR };

	result = spi_send_command(flash, sizeof(read_cr_cmd), 1, read_cr_cmd, &cfg);
	if (result) {
		msg_cerr("%s failed during command execution\n", __func__);
		return -1;
	}

	return cfg;
}

/* "Write Any Register" instruction only supported on S25FS */
static int s25fs_write_cr(const struct flashctx *flash,
			  uint32_t addr, uint8_t data)
{
	struct spi_command cmds[] = {
	{
		.writecnt	= JEDEC_WREN_OUTSIZE,
		.writearr	= (const uint8_t[]){ JEDEC_WREN },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= CMD_WRAR_LEN,
		.writearr	= (const uint8_t[]){
					CMD_WRAR,
					(addr >> 16) & 0xff,
					(addr >> 8) & 0xff,
					(addr & 0xff),
					data
				},
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 0,
		.writearr	= NULL,
		.readcnt	= 0,
		.readarr	= NULL,
	}};

	int result = spi_send_multicommand(flash, cmds);
	if (result) {
		msg_cerr("%s failed during command execution at address 0x%x\n",
			__func__, addr);
		return -1;
	}

	programmer_delay(T_W);
	return s25f_poll_status(flash);
}

static int s25f_write_cr1(const struct flashctx *flash, uint8_t data)
{
	int result;
	struct spi_command cmds[] = {
	{
		.writecnt	= JEDEC_WREN_OUTSIZE,
		.writearr	= (const unsigned char[]){ JEDEC_WREN },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= CMD_WRR_LEN,
		.writearr	= (const unsigned char[]){
					CMD_WRR,
					spi_read_status_register(flash),
					data,
				},
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 0,
		.writearr	= NULL,
		.readcnt	= 0,
		.readarr	= NULL,
	}};

	result = spi_send_multicommand(flash, cmds);
	if (result) {
		msg_cerr("%s failed during command execution\n", __func__);
		return -1;
	}

	programmer_delay(T_W);
	return s25f_poll_status(flash);
}

static int s25fs_restore_cr3nv(struct flashctx *flash, uint8_t cfg)
{
	int ret = 0;

	msg_cdbg("Restoring CR3NV value to 0x%02x\n", cfg);
	ret |= s25fs_write_cr(flash, CR3NV_ADDR, cfg);
	ret |= s25fs_software_reset(flash);
	return ret;
}

/* returns state of top/bottom block protection, or <0 to indicate error */
static int s25f_get_tbprot_o(const struct flashctx *flash)
{
	int cr1 = s25f_read_cr1(flash);

	if (cr1 < 0)
		return -1;

	/*
	 * 1 = BP starts at bottom (low address)
	 * 0 = BP start at top (high address)
	 */
	return cr1 & CR1_TBPROT_O ? 1 : 0;
}

/* fills modifier_bits struct, returns 0 to indicate success */
int s25f_get_modifier_bits(const struct flashctx *flash,
					struct modifier_bits *m)
{
	int tmp;

	memset(m, 0, sizeof(*m));

	tmp = s25f_get_tbprot_o(flash);
	if (tmp < 0)
		return -1;
	m->tb = tmp;

	return 0;
}

int s25f_set_modifier_bits(const struct flashctx *flash,
					struct modifier_bits *m)
{
	int cr1, cr1_orig;

	cr1 = cr1_orig = s25f_read_cr1(flash);
	if (cr1 < 0)
		return -1;

	/*
	 * Clear BPNV so that setting BP2-0 in status register gets
	 * written to non-volatile memory.
	 *
	 * For TBPROT:
	 * 1 = BP starts at bottom (low address)
	 * 0 = BP start at top (high address)
	 */
	cr1 &= ~(CR1_BPNV_O | CR1_TBPROT_O);
	cr1 |= m->tb ? CR1_TBPROT_O : 0;

	if (cr1 != cr1_orig) {
		msg_cdbg("%s: setting cr1 bits to 0x%02x\n", __func__, cr1);
		if (s25f_write_cr1(flash, cr1) < 0)
			return -1;
		if (s25f_read_cr1(flash) != cr1) {
			msg_cerr("%s: failed to set CR1 value\n", __func__);
			return -1;
		}
	} else {
		msg_cdbg("%s: cr1 bits already match desired value: "
				"0x%02x\n", __func__, cr1);
	}

	return 0;
}

int s25fs_block_erase_d8(struct flashctx *flash,
			 uint32_t addr, uint32_t blocklen)
{
	static int cr3nv_checked = 0;

	struct spi_command erase_cmds[] = {
	{
		.writecnt	= JEDEC_WREN_OUTSIZE,
		.writearr	= (const uint8_t[]){ JEDEC_WREN },
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= JEDEC_BE_D8_OUTSIZE,
		.writearr	= (const uint8_t[]){
					JEDEC_BE_D8,
					(addr >> 16) & 0xff,
					(addr >> 8) & 0xff,
					(addr & 0xff)
				},
		.readcnt	= 0,
		.readarr	= NULL,
	}, {
		.writecnt	= 0,
		.writearr	= NULL,
		.readcnt	= 0,
		.readarr	= NULL,
	}};

	/* Check if hybrid sector architecture is in use and, if so,
	 * switch to uniform sectors. */
	if (!cr3nv_checked) {
		uint8_t cfg = s25fs_read_cr(flash, CR3NV_ADDR);
		if (!(cfg & CR3NV_20H_NV)) {
			s25fs_write_cr(flash, CR3NV_ADDR, cfg | CR3NV_20H_NV);
			s25fs_software_reset(flash);

			cfg = s25fs_read_cr(flash, CR3NV_ADDR);
			if (!(cfg & CR3NV_20H_NV)) {
				msg_cerr("%s: Unable to enable uniform "
					"block sizes.\n", __func__);
				return 1;
			}

			msg_cdbg("\n%s: CR3NV updated (0x%02x -> 0x%02x)\n",
					__func__, cfg,
					s25fs_read_cr(flash, CR3NV_ADDR));
			/* Restore CR3V when flashrom exits */
			register_chip_restore(s25fs_restore_cr3nv, flash, cfg);
		}

		cr3nv_checked = 1;
	}

	int result = spi_send_multicommand(flash, erase_cmds);
	if (result) {
		msg_cerr("%s failed during command execution at address 0x%x\n",
			__func__, addr);
		return result;
	}

	programmer_delay(S25FS_T_SE);
	return s25f_poll_status(flash);
}

int s25fl_block_erase(struct flashctx *flash,
		      uint32_t addr, uint32_t blocklen)
{
	struct spi_command erase_cmds[] = {
		{
			.writecnt	= JEDEC_WREN_OUTSIZE,
			.writearr	= (const uint8_t[]){
				JEDEC_WREN
			},
			.readcnt	= 0,
			.readarr	= NULL,
		}, {
			.writecnt	= JEDEC_BE_DC_OUTSIZE,
			.writearr	= (const uint8_t[]){
				JEDEC_BE_DC,
				(addr >> 24) & 0xff,
				(addr >> 16) & 0xff,
				(addr >> 8) & 0xff,
				(addr & 0xff)
			},
			.readcnt	= 0,
			.readarr	= NULL,
		}, {
			.writecnt	= 0,
			.readcnt	= 0,
		}
	};

	int result = spi_send_multicommand(flash, erase_cmds);
	if (result) {
		msg_cerr("%s failed during command execution at address 0x%x\n",
			__func__, addr);
		return result;
	}

	programmer_delay(S25FL_T_SE);
	return s25f_poll_status(flash);
}


int probe_spi_big_spansion(struct flashctx *flash)
{
	uint8_t cmd = JEDEC_RDID;
	uint8_t dev_id[6]; /* We care only about 6 first bytes */

	if (spi_send_command(flash, sizeof(cmd), sizeof(dev_id), &cmd, dev_id))
		return 0;

	msg_gdbg("Read id bytes: ");
	for (size_t i = 0; i < sizeof(dev_id); i++)
		msg_gdbg(" 0x%02x", dev_id[i]);
	msg_gdbg(".\n");

	/*
	 * The structure of the RDID output is as follows:
	 *
	 *     offset   value              meaning
	 *       00h     01h      Manufacturer ID for Spansion
	 *       01h     20h           128 Mb capacity
	 *       01h     02h           256 Mb capacity
	 *       02h     18h           128 Mb capacity
	 *       02h     19h           256 Mb capacity
	 *       03h     4Dh       Full size of the RDID output (ignored)
	 *       04h     00h       FS: 256-kB physical sectors
	 *       04h     01h       FS: 64-kB physical sectors
	 *       04h     00h       FL: 256-kB physical sectors
	 *       04h     01h       FL: Mix of 64-kB and 4KB overlayed sectors
	 *       05h     80h       FL family
	 *       05h     81h       FS family
	 *
	 * Need to use bytes 1, 2, 4, and 5 to properly identify one of eight
	 * possible chips:
	 *
	 * 2 types * 2 possible sizes * 2 possible sector layouts
	 *
	 */

	uint32_t model_id =
		dev_id[1] << 24 |
		dev_id[2] << 16 |
		dev_id[4] << 8  |
		dev_id[5] << 0;

	if (dev_id[0] == flash->chip->manufacture_id && model_id == flash->chip->model_id)
		return 1;

	return 0;
}
