// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2011-12 The Chromium OS Authors.
 *
 * This file is derived from the flashrom project.
 */

#define LOG_CATEGORY	UCLASS_SPI

#include <common.h>
#include <bootstage.h>
#include <div64.h>
#include <dm.h>
#include <dt-structs.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <pch.h>
#include <pci.h>
#include <pci_ids.h>
#include <spi.h>
#include <spi_flash.h>
#include <spi-mem.h>
#include <spl.h>
#include <asm/fast_spi.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <asm/mtrr.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/sizes.h>

#include "ich.h"

#ifdef DEBUG_TRACE
#define debug_trace(fmt, args...) debug(fmt, ##args)
#else
#define debug_trace(x, args...)
#endif

static u8 ich_readb(struct ich_spi_priv *priv, int reg)
{
	u8 value = readb(priv->base + reg);

	debug_trace("read %2.2x from %4.4x\n", value, reg);

	return value;
}

static u16 ich_readw(struct ich_spi_priv *priv, int reg)
{
	u16 value = readw(priv->base + reg);

	debug_trace("read %4.4x from %4.4x\n", value, reg);

	return value;
}

static u32 ich_readl(struct ich_spi_priv *priv, int reg)
{
	u32 value = readl(priv->base + reg);

	debug_trace("read %8.8x from %4.4x\n", value, reg);

	return value;
}

static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg)
{
	writeb(value, priv->base + reg);
	debug_trace("wrote %2.2x to %4.4x\n", value, reg);
}

static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg)
{
	writew(value, priv->base + reg);
	debug_trace("wrote %4.4x to %4.4x\n", value, reg);
}

static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg)
{
	writel(value, priv->base + reg);
	debug_trace("wrote %8.8x to %4.4x\n", value, reg);
}

static void write_reg(struct ich_spi_priv *priv, const void *value,
		      int dest_reg, uint32_t size)
{
	memcpy_toio(priv->base + dest_reg, value, size);
}

static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value,
		     uint32_t size)
{
	memcpy_fromio(value, priv->base + src_reg, size);
}

static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr)
{
	const uint32_t bbar_mask = 0x00ffff00;
	uint32_t ichspi_bbar;

	if (ctlr->bbar) {
		minaddr &= bbar_mask;
		ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
		ichspi_bbar |= minaddr;
		ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
	}
}

/* @return 1 if the SPI flash supports the 33MHz speed */
static bool ich9_can_do_33mhz(struct udevice *dev)
{
	struct ich_spi_priv *priv = dev_get_priv(dev);
	u32 fdod, speed;

	if (!CONFIG_IS_ENABLED(PCI))
		return false;
	/* Observe SPI Descriptor Component Section 0 */
	dm_pci_write_config32(priv->pch, 0xb0, 0x1000);

	/* Extract the Write/Erase SPI Frequency from descriptor */
	dm_pci_read_config32(priv->pch, 0xb4, &fdod);

	/* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
	speed = (fdod >> 21) & 7;

	return speed == 1;
}

static void spi_lock_down(struct ich_spi_plat *plat, void *sbase)
{
	if (plat->ich_version == ICHV_7) {
		struct ich7_spi_regs *ich7_spi = sbase;

		setbits_le16(&ich7_spi->spis, SPIS_LOCK);
	} else if (plat->ich_version == ICHV_9) {
		struct ich9_spi_regs *ich9_spi = sbase;

		setbits_le16(&ich9_spi->hsfs, HSFS_FLOCKDN);
	}
}

static bool spi_lock_status(struct ich_spi_plat *plat, void *sbase)
{
	int lock = 0;

	if (plat->ich_version == ICHV_7) {
		struct ich7_spi_regs *ich7_spi = sbase;

		lock = readw(&ich7_spi->spis) & SPIS_LOCK;
	} else if (plat->ich_version == ICHV_9) {
		struct ich9_spi_regs *ich9_spi = sbase;

		lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
	}

	return lock != 0;
}

static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
			    bool lock)
{
	uint16_t optypes;
	uint8_t opmenu[ctlr->menubytes];

	if (!lock) {
		/* The lock is off, so just use index 0. */
		ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
		optypes = ich_readw(ctlr, ctlr->optype);
		optypes = (optypes & 0xfffc) | (trans->type & 0x3);
		ich_writew(ctlr, optypes, ctlr->optype);
		return 0;
	} else {
		/* The lock is on. See if what we need is on the menu. */
		uint8_t optype;
		uint16_t opcode_index;

		/* Write Enable is handled as atomic prefix */
		if (trans->opcode == SPI_OPCODE_WREN)
			return 0;

		read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu));
		for (opcode_index = 0; opcode_index < ctlr->menubytes;
				opcode_index++) {
			if (opmenu[opcode_index] == trans->opcode)
				break;
		}

		if (opcode_index == ctlr->menubytes) {
			debug("ICH SPI: Opcode %x not found\n", trans->opcode);
			return -EINVAL;
		}

		optypes = ich_readw(ctlr, ctlr->optype);
		optype = (optypes >> (opcode_index * 2)) & 0x3;

		if (optype != trans->type) {
			debug("ICH SPI: Transaction doesn't fit type %d\n",
			      optype);
			return -ENOSPC;
		}
		return opcode_index;
	}
}

/*
 * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
 * below is true) or 0. In case the wait was for the bit(s) to set - write
 * those bits back, which would cause resetting them.
 *
 * Return the last read status value on success or -1 on failure.
 */
static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
			   int wait_til_set)
{
	int timeout = 600000; /* This will result in 6s */
	u16 status = 0;

	while (timeout--) {
		status = ich_readw(ctlr, ctlr->status);
		if (wait_til_set ^ ((status & bitmask) == 0)) {
			if (wait_til_set) {
				ich_writew(ctlr, status & bitmask,
					   ctlr->status);
			}
			return status;
		}
		udelay(10);
	}
	debug("ICH SPI: SCIP timeout, read %x, expected %x, wts %x %x\n",
	      status, bitmask, wait_til_set, status & bitmask);

	return -ETIMEDOUT;
}

static void ich_spi_config_opcode(struct udevice *dev)
{
	struct ich_spi_priv *ctlr = dev_get_priv(dev);

	/*
	 * PREOP, OPTYPE, OPMENU1/OPMENU2 registers can be locked down
	 * to prevent accidental or intentional writes. Before they get
	 * locked down, these registers should be initialized properly.
	 */
	ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop);
	ich_writew(ctlr, SPI_OPTYPE, ctlr->optype);
	ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu);
	ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
}

static int ich_spi_exec_op_swseq(struct spi_slave *slave,
				 const struct spi_mem_op *op)
{
	struct udevice *bus = dev_get_parent(slave->dev);
	struct ich_spi_plat *plat = dev_get_plat(bus);
	struct ich_spi_priv *ctlr = dev_get_priv(bus);
	uint16_t control;
	int16_t opcode_index;
	int with_address;
	int status;
	struct spi_trans *trans = &ctlr->trans;
	bool lock = spi_lock_status(plat, ctlr->base);
	int ret = 0;

	trans->in = NULL;
	trans->out = NULL;
	trans->type = 0xFF;

	if (op->data.nbytes) {
		if (op->data.dir == SPI_MEM_DATA_IN) {
			trans->in = op->data.buf.in;
			trans->bytesin = op->data.nbytes;
		} else {
			trans->out = op->data.buf.out;
			trans->bytesout = op->data.nbytes;
		}
	}

	if (trans->opcode != op->cmd.opcode)
		trans->opcode = op->cmd.opcode;

	if (lock && trans->opcode == SPI_OPCODE_WRDIS)
		return 0;

	if (trans->opcode == SPI_OPCODE_WREN) {
		/*
		 * Treat Write Enable as Atomic Pre-Op if possible
		 * in order to prevent the Management Engine from
		 * issuing a transaction between WREN and DATA.
		 */
		if (!lock)
			ich_writew(ctlr, trans->opcode, ctlr->preop);
		return 0;
	}

	ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
	if (ret < 0)
		return ret;

	if (plat->ich_version == ICHV_7)
		ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
	else
		ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);

	/* Try to guess spi transaction type */
	if (op->data.dir == SPI_MEM_DATA_OUT) {
		if (op->addr.nbytes)
			trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
		else
			trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
	} else {
		if (op->addr.nbytes)
			trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
		else
			trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
	}
	/* Special erase case handling */
	if (op->addr.nbytes && !op->data.buswidth)
		trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;

	opcode_index = spi_setup_opcode(ctlr, trans, lock);
	if (opcode_index < 0)
		return -EINVAL;

	if (op->addr.nbytes) {
		trans->offset = op->addr.val;
		with_address = 1;
	}

	if (ctlr->speed && ctlr->max_speed >= 33000000) {
		int byte;

		byte = ich_readb(ctlr, ctlr->speed);
		if (ctlr->cur_speed >= 33000000)
			byte |= SSFC_SCF_33MHZ;
		else
			byte &= ~SSFC_SCF_33MHZ;
		ich_writeb(ctlr, byte, ctlr->speed);
	}

	/* Preset control fields */
	control = SPIC_SCGO | ((opcode_index & 0x07) << 4);

	/* Issue atomic preop cycle if needed */
	if (ich_readw(ctlr, ctlr->preop))
		control |= SPIC_ACS;

	if (!trans->bytesout && !trans->bytesin) {
		/* SPI addresses are 24 bit only */
		if (with_address) {
			ich_writel(ctlr, trans->offset & 0x00FFFFFF,
				   ctlr->addr);
		}
		/*
		 * This is a 'no data' command (like Write Enable), its
		 * bitesout size was 1, decremented to zero while executing
		 * spi_setup_opcode() above. Tell the chip to send the
		 * command.
		 */
		ich_writew(ctlr, control, ctlr->control);

		/* wait for the result */
		status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
		if (status < 0)
			return status;

		if (status & SPIS_FCERR) {
			debug("ICH SPI: Command transaction error\n");
			return -EIO;
		}

		return 0;
	}

	while (trans->bytesout || trans->bytesin) {
		uint32_t data_length;

		/* SPI addresses are 24 bit only */
		ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr);

		if (trans->bytesout)
			data_length = min(trans->bytesout, ctlr->databytes);
		else
			data_length = min(trans->bytesin, ctlr->databytes);

		/* Program data into FDATA0 to N */
		if (trans->bytesout) {
			write_reg(ctlr, trans->out, ctlr->data, data_length);
			trans->bytesout -= data_length;
		}

		/* Add proper control fields' values */
		control &= ~((ctlr->databytes - 1) << 8);
		control |= SPIC_DS;
		control |= (data_length - 1) << 8;

		/* write it */
		ich_writew(ctlr, control, ctlr->control);

		/* Wait for Cycle Done Status or Flash Cycle Error */
		status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
		if (status < 0)
			return status;

		if (status & SPIS_FCERR) {
			debug("ICH SPI: Data transaction error %x\n", status);
			return -EIO;
		}

		if (trans->bytesin) {
			read_reg(ctlr, ctlr->data, trans->in, data_length);
			trans->bytesin -= data_length;
		}
	}

	/* Clear atomic preop now that xfer is done */
	if (!lock)
		ich_writew(ctlr, 0, ctlr->preop);

	return 0;
}

/*
 * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and
 * that the operation does not cross page boundary.
 */
static uint get_xfer_len(u32 offset, int len, int page_size)
{
	uint xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
	uint bytes_left = ALIGN(offset, page_size) - offset;

	if (bytes_left)
		xfer_len = min(xfer_len, bytes_left);

	return xfer_len;
}

/* Fill FDATAn FIFO in preparation for a write transaction */
static void fill_xfer_fifo(struct fast_spi_regs *regs, const void *data,
			   uint len)
{
	memcpy(regs->fdata, data, len);
}

/* Drain FDATAn FIFO after a read transaction populates data */
static void drain_xfer_fifo(struct fast_spi_regs *regs, void *dest, uint len)
{
	memcpy(dest, regs->fdata, len);
}

/* Fire up a transfer using the hardware sequencer */
static void start_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
			     uint offset, uint len)
{
	/* Make sure all W1C status bits get cleared */
	u32 hsfsts;

	hsfsts = readl(&regs->hsfsts_ctl);
	hsfsts &= ~(HSFSTS_FCYCLE_MASK | HSFSTS_FDBC_MASK);
	hsfsts |= HSFSTS_AEL | HSFSTS_FCERR | HSFSTS_FDONE;

	/* Set up transaction parameters */
	hsfsts |= hsfsts_cycle << HSFSTS_FCYCLE_SHIFT;
	hsfsts |= ((len - 1) << HSFSTS_FDBC_SHIFT) & HSFSTS_FDBC_MASK;
	hsfsts |= HSFSTS_FGO;

	writel(offset, &regs->faddr);
	writel(hsfsts, &regs->hsfsts_ctl);
}

static int wait_for_hwseq_xfer(struct fast_spi_regs *regs, uint offset)
{
	ulong start;
	u32 hsfsts;

	start = get_timer(0);
	do {
		hsfsts = readl(&regs->hsfsts_ctl);
		if (hsfsts & HSFSTS_FCERR) {
			debug("SPI transaction error at offset %x HSFSTS = %08x\n",
			      offset, hsfsts);
			return -EIO;
		}
		if (hsfsts & HSFSTS_AEL)
			return -EPERM;

		if (hsfsts & HSFSTS_FDONE)
			return 0;
	} while (get_timer(start) < SPIBAR_HWSEQ_XFER_TIMEOUT_MS);

	debug("SPI transaction timeout at offset %x HSFSTS = %08x, timer %d\n",
	      offset, hsfsts, (uint)get_timer(start));

	return -ETIMEDOUT;
}

/**
 * exec_sync_hwseq_xfer() - Execute flash transfer by hardware sequencing
 *
 * This waits until complete or timeout
 *
 * @regs: SPI registers
 * @hsfsts_cycle: Cycle type (enum hsfsts_cycle_t)
 * @offset: Offset to access
 * @len: Number of bytes to transfer (can be 0)
 * @return 0 if OK, -EIO on flash-cycle error (FCERR), -EPERM on access error
 *	(AEL), -ETIMEDOUT on timeout
 */
static int exec_sync_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
				uint offset, uint len)
{
	start_hwseq_xfer(regs, hsfsts_cycle, offset, len);

	return wait_for_hwseq_xfer(regs, offset);
}

static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
				 const struct spi_mem_op *op)
{
	struct spi_flash *flash = dev_get_uclass_priv(slave->dev);
	struct udevice *bus = dev_get_parent(slave->dev);
	struct ich_spi_priv *priv = dev_get_priv(bus);
	struct fast_spi_regs *regs = priv->base;
	uint page_size;
	uint offset;
	int cycle;
	uint len;
	bool out;
	int ret;
	u8 *buf;

	offset = op->addr.val;
	len = op->data.nbytes;

	switch (op->cmd.opcode) {
	case SPINOR_OP_RDID:
		cycle = HSFSTS_CYCLE_RDID;
		break;
	case SPINOR_OP_READ_FAST:
		cycle = HSFSTS_CYCLE_READ;
		break;
	case SPINOR_OP_PP:
		cycle = HSFSTS_CYCLE_WRITE;
		break;
	case SPINOR_OP_WREN:
		/* Nothing needs to be done */
		return 0;
	case SPINOR_OP_WRSR:
		cycle = HSFSTS_CYCLE_WR_STATUS;
		break;
	case SPINOR_OP_RDSR:
		cycle = HSFSTS_CYCLE_RD_STATUS;
		break;
	case SPINOR_OP_WRDI:
		return 0;  /* ignore */
	case SPINOR_OP_BE_4K:
		cycle = HSFSTS_CYCLE_4K_ERASE;
		ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
		return ret;
	default:
		debug("Unknown cycle %x\n", op->cmd.opcode);
		return -EINVAL;
	};

	out = op->data.dir == SPI_MEM_DATA_OUT;
	buf = out ? (u8 *)op->data.buf.out : op->data.buf.in;
	page_size = flash->page_size ? : 256;

	while (len) {
		uint xfer_len = get_xfer_len(offset, len, page_size);

		if (out)
			fill_xfer_fifo(regs, buf, xfer_len);

		ret = exec_sync_hwseq_xfer(regs, cycle, offset, xfer_len);
		if (ret)
			return ret;

		if (!out)
			drain_xfer_fifo(regs, buf, xfer_len);

		offset += xfer_len;
		buf += xfer_len;
		len -= xfer_len;
	}

	return 0;
}

static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
{
	struct udevice *bus = dev_get_parent(slave->dev);
	struct ich_spi_plat *plat = dev_get_plat(bus);
	int ret;

	bootstage_start(BOOTSTAGE_ID_ACCUM_SPI, "fast_spi");
	if (plat->hwseq)
		ret = ich_spi_exec_op_hwseq(slave, op);
	else
		ret = ich_spi_exec_op_swseq(slave, op);
	bootstage_accum(BOOTSTAGE_ID_ACCUM_SPI);

	return ret;
}

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
/**
 * ich_spi_get_basics() - Get basic information about the ICH device
 *
 * This works without probing any devices if requested.
 *
 * @bus: SPI controller to use
 * @can_probe: true if this function is allowed to probe the PCH
 * @pchp: Returns a pointer to the pch, or NULL if not found
 * @ich_versionp: Returns ICH version detected on success
 * @mmio_basep: Returns the address of the SPI registers on success
 * @return 0 if OK, -EPROTOTYPE if the PCH could not be found, -EAGAIN if
 *	the function cannot success without probing, possible another error if
 *	pch_get_spi_base() fails
 */
static int ich_spi_get_basics(struct udevice *bus, bool can_probe,
			      struct udevice **pchp,
			      enum ich_version *ich_versionp, ulong *mmio_basep)
{
	struct udevice *pch = NULL;
	int ret = 0;

	/* Find a PCH if there is one */
	if (can_probe) {
		pch = dev_get_parent(bus);
		if (device_get_uclass_id(pch) != UCLASS_PCH) {
			uclass_first_device(UCLASS_PCH, &pch);
			if (!pch)
				return log_msg_ret("uclass", -EPROTOTYPE);
		}
	}

	*ich_versionp = dev_get_driver_data(bus);
	if (*ich_versionp == ICHV_APL)
		*mmio_basep = dm_pci_read_bar32(bus, 0);
	else if (pch)
		ret = pch_get_spi_base(pch, mmio_basep);
	else
		return -EAGAIN;
	*pchp = pch;

	return ret;
}
#endif

/**
 * ich_get_mmap_bus() - Handle the get_mmap() method for a bus
 *
 * There are several cases to consider:
 * 1. Using of-platdata, in which case we have the BDF and can access the
 *	registers by reading the BAR
 * 2. Not using of-platdata, but still with a SPI controller that is on its own
 * PCI PDF. In this case we read the BDF from the parent plat and again get
 *	the registers by reading the BAR
 * 3. Using a SPI controller that is a child of the PCH, in which case we try
 *	to find the registers by asking the PCH. This only works if the PCH has
 *	been probed (which it will be if the bus is probed since parents are
 *	probed before children), since the PCH may not have a PCI address until
 *	its parent (the PCI bus itself) has been probed. If you are using this
 *	method then you should make sure the SPI bus is probed.
 *
 * The first two cases are useful in early init. The last one is more useful
 * afterwards.
 */
static int ich_get_mmap_bus(struct udevice *bus, ulong *map_basep,
			    uint *map_sizep, uint *offsetp)
{
	pci_dev_t spi_bdf;
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	if (device_is_on_pci_bus(bus)) {
		struct pci_child_plat *pplat;

		pplat = dev_get_parent_plat(bus);
		spi_bdf = pplat->devfn;
	} else {
		enum ich_version ich_version;
		struct fast_spi_regs *regs;
		struct udevice *pch;
		ulong mmio_base;
		int ret;

		ret = ich_spi_get_basics(bus, device_active(bus), &pch,
					 &ich_version, &mmio_base);
		if (ret)
			return log_msg_ret("basics", ret);
		regs = (struct fast_spi_regs *)mmio_base;

		return fast_spi_get_bios_mmap_regs(regs, map_basep, map_sizep,
						   offsetp);
	}
#else
	struct ich_spi_plat *plat = dev_get_plat(bus);

	/*
	 * We cannot rely on plat->bdf being set up yet since this method can
	 * be called before the device is probed. Use the of-platdata directly
	 * instead.
	 */
	spi_bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
#endif

	return fast_spi_get_bios_mmap(spi_bdf, map_basep, map_sizep, offsetp);
}

static int ich_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
			uint *offsetp)
{
	struct udevice *bus = dev_get_parent(dev);

	return ich_get_mmap_bus(bus, map_basep, map_sizep, offsetp);
}

static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op)
{
	unsigned int page_offset;
	int addr = op->addr.val;
	unsigned int byte_count = op->data.nbytes;

	if (hweight32(ICH_BOUNDARY) == 1) {
		page_offset = addr & (ICH_BOUNDARY - 1);
	} else {
		u64 aux = addr;

		page_offset = do_div(aux, ICH_BOUNDARY);
	}

	if (op->data.dir == SPI_MEM_DATA_IN) {
		if (slave->max_read_size) {
			op->data.nbytes = min(ICH_BOUNDARY - page_offset,
					      slave->max_read_size);
		}
	} else if (slave->max_write_size) {
		op->data.nbytes = min(ICH_BOUNDARY - page_offset,
				      slave->max_write_size);
	}

	op->data.nbytes = min(op->data.nbytes, byte_count);

	return 0;
}

static int ich_protect_lockdown(struct udevice *dev)
{
	struct ich_spi_plat *plat = dev_get_plat(dev);
	struct ich_spi_priv *priv = dev_get_priv(dev);
	int ret = -ENOSYS;

	/* Disable the BIOS write protect so write commands are allowed */
	if (priv->pch)
		ret = pch_set_spi_protect(priv->pch, false);
	if (ret == -ENOSYS) {
		u8 bios_cntl;

		bios_cntl = ich_readb(priv, priv->bcr);
		bios_cntl &= ~BIT(5);	/* clear Enable InSMM_STS (EISS) */
		bios_cntl |= 1;		/* Write Protect Disable (WPD) */
		ich_writeb(priv, bios_cntl, priv->bcr);
	} else if (ret) {
		debug("%s: Failed to disable write-protect: err=%d\n",
		      __func__, ret);
		return ret;
	}

	/* Lock down SPI controller settings if required */
	if (plat->lockdown) {
		ich_spi_config_opcode(dev);
		spi_lock_down(plat, priv->base);
	}

	return 0;
}

static int ich_init_controller(struct udevice *dev,
			       struct ich_spi_plat *plat,
			       struct ich_spi_priv *ctlr)
{
	if (spl_phase() == PHASE_TPL) {
		struct ich_spi_plat *plat = dev_get_plat(dev);
		int ret;

		ret = fast_spi_early_init(plat->bdf, plat->mmio_base);
		if (ret)
			return ret;
	}

	ctlr->base = (void *)plat->mmio_base;
	if (plat->ich_version == ICHV_7) {
		struct ich7_spi_regs *ich7_spi = ctlr->base;

		ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
		ctlr->menubytes = sizeof(ich7_spi->opmenu);
		ctlr->optype = offsetof(struct ich7_spi_regs, optype);
		ctlr->addr = offsetof(struct ich7_spi_regs, spia);
		ctlr->data = offsetof(struct ich7_spi_regs, spid);
		ctlr->databytes = sizeof(ich7_spi->spid);
		ctlr->status = offsetof(struct ich7_spi_regs, spis);
		ctlr->control = offsetof(struct ich7_spi_regs, spic);
		ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
		ctlr->preop = offsetof(struct ich7_spi_regs, preop);
	} else if (plat->ich_version == ICHV_9) {
		struct ich9_spi_regs *ich9_spi = ctlr->base;

		ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
		ctlr->menubytes = sizeof(ich9_spi->opmenu);
		ctlr->optype = offsetof(struct ich9_spi_regs, optype);
		ctlr->addr = offsetof(struct ich9_spi_regs, faddr);
		ctlr->data = offsetof(struct ich9_spi_regs, fdata);
		ctlr->databytes = sizeof(ich9_spi->fdata);
		ctlr->status = offsetof(struct ich9_spi_regs, ssfs);
		ctlr->control = offsetof(struct ich9_spi_regs, ssfc);
		ctlr->speed = ctlr->control + 2;
		ctlr->bbar = offsetof(struct ich9_spi_regs, bbar);
		ctlr->preop = offsetof(struct ich9_spi_regs, preop);
		ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
		ctlr->pr = &ich9_spi->pr[0];
	} else if (plat->ich_version == ICHV_APL) {
	} else {
		debug("ICH SPI: Unrecognised ICH version %d\n",
		      plat->ich_version);
		return -EINVAL;
	}

	/* Work out the maximum speed we can support */
	ctlr->max_speed = 20000000;
	if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev))
		ctlr->max_speed = 33000000;
	debug("ICH SPI: Version ID %d detected at %lx, speed %ld\n",
	      plat->ich_version, plat->mmio_base, ctlr->max_speed);

	ich_set_bbar(ctlr, 0);

	return 0;
}

static int ich_cache_bios_region(struct udevice *dev)
{
	ulong map_base;
	uint map_size;
	uint offset;
	ulong base;
	int ret;

	ret = ich_get_mmap_bus(dev, &map_base, &map_size, &offset);
	if (ret)
		return ret;

	/* Don't use WRBACK since we are not supposed to write to SPI flash */
	base = SZ_4G - map_size;
	mtrr_set_next_var(MTRR_TYPE_WRPROT, base, map_size);
	log_debug("BIOS cache base=%lx, size=%x\n", base, (uint)map_size);

	return 0;
}

static int ich_spi_probe(struct udevice *dev)
{
	struct ich_spi_plat *plat = dev_get_plat(dev);
	struct ich_spi_priv *priv = dev_get_priv(dev);
	int ret;

	ret = ich_init_controller(dev, plat, priv);
	if (ret)
		return ret;

	if (spl_phase() == PHASE_TPL) {
		/* Cache the BIOS to speed things up */
		ret = ich_cache_bios_region(dev);
		if (ret)
			return ret;
	} else {
		ret = ich_protect_lockdown(dev);
		if (ret)
			return ret;
	}
	priv->cur_speed = priv->max_speed;

	return 0;
}

static int ich_spi_remove(struct udevice *bus)
{
	/*
	 * Configure SPI controller so that the Linux MTD driver can fully
	 * access the SPI NOR chip
	 */
	ich_spi_config_opcode(bus);

	return 0;
}

static int ich_spi_set_speed(struct udevice *bus, uint speed)
{
	struct ich_spi_priv *priv = dev_get_priv(bus);

	priv->cur_speed = speed;

	return 0;
}

static int ich_spi_set_mode(struct udevice *bus, uint mode)
{
	debug("%s: mode=%d\n", __func__, mode);

	return 0;
}

static int ich_spi_child_pre_probe(struct udevice *dev)
{
	struct udevice *bus = dev_get_parent(dev);
	struct ich_spi_plat *plat = dev_get_plat(bus);
	struct ich_spi_priv *priv = dev_get_priv(bus);
	struct spi_slave *slave = dev_get_parent_priv(dev);

	/*
	 * Yes this controller can only write a small number of bytes at
	 * once! The limit is typically 64 bytes. For hardware sequencing a
	 * a loop is used to get around this.
	 */
	if (!plat->hwseq)
		slave->max_write_size = priv->databytes;
	/*
	 * ICH 7 SPI controller only supports array read command
	 * and byte program command for SST flash
	 */
	if (plat->ich_version == ICHV_7)
		slave->mode = SPI_RX_SLOW | SPI_TX_BYTE;

	return 0;
}

static int ich_spi_of_to_plat(struct udevice *dev)
{
	struct ich_spi_plat *plat = dev_get_plat(dev);

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct ich_spi_priv *priv = dev_get_priv(dev);
	int ret;

	ret = ich_spi_get_basics(dev, true, &priv->pch, &plat->ich_version,
				 &plat->mmio_base);
	if (ret)
		return log_msg_ret("basics", ret);
	plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
	/*
	 * Use an int so that the property is present in of-platdata even
	 * when false.
	 */
	plat->hwseq = dev_read_u32_default(dev, "intel,hardware-seq", 0);
#else
	plat->ich_version = ICHV_APL;
	plat->mmio_base = plat->dtplat.early_regs[0];
	plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
	plat->hwseq = plat->dtplat.intel_hardware_seq;
#endif
	debug("%s: mmio_base=%lx\n", __func__, plat->mmio_base);

	return 0;
}

static const struct spi_controller_mem_ops ich_controller_mem_ops = {
	.adjust_op_size	= ich_spi_adjust_size,
	.supports_op	= NULL,
	.exec_op	= ich_spi_exec_op,
};

static const struct dm_spi_ops ich_spi_ops = {
	/* xfer is not supported */
	.set_speed	= ich_spi_set_speed,
	.set_mode	= ich_spi_set_mode,
	.mem_ops	= &ich_controller_mem_ops,
	.get_mmap	= ich_get_mmap,
	/*
	 * cs_info is not needed, since we require all chip selects to be
	 * in the device tree explicitly
	 */
};

static const struct udevice_id ich_spi_ids[] = {
	{ .compatible = "intel,ich7-spi", ICHV_7 },
	{ .compatible = "intel,ich9-spi", ICHV_9 },
	{ .compatible = "intel,fast-spi", ICHV_APL },
	{ }
};

U_BOOT_DRIVER(intel_fast_spi) = {
	.name	= "intel_fast_spi",
	.id	= UCLASS_SPI,
	.of_match = ich_spi_ids,
	.ops	= &ich_spi_ops,
	.of_to_plat = ich_spi_of_to_plat,
	.plat_auto	= sizeof(struct ich_spi_plat),
	.priv_auto	= sizeof(struct ich_spi_priv),
	.child_pre_probe = ich_spi_child_pre_probe,
	.probe	= ich_spi_probe,
	.remove	= ich_spi_remove,
	.flags	= DM_FLAG_OS_PREPARE,
};
