// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2018 IBM Corp. */

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include <libflash/libflash.h>
#include <libflash/libflash-priv.h>
#ifdef __SKIBOOT__
#include "lpc.h"
#endif

#include "ast.h"

#ifndef __unused
#define __unused __attribute__((unused))
#endif

#define CALIBRATE_BUF_SIZE	16384

struct ast_sf_ctrl {
	/* We have 2 controllers, one for the BMC flash, one for the PNOR */
	uint8_t			type;

	/* Address and previous value of the ctrl register */
	uint32_t		ctl_reg;

	/* Control register value for normal commands */
	uint32_t		ctl_val;

	/* Control register value for (fast) reads */
	uint32_t		ctl_read_val;

	/* Flash read timing register  */
	uint32_t		fread_timing_reg;
	uint32_t		fread_timing_val;

	/* Address of the flash mapping */
	uint32_t		flash;

	/* Current 4b mode */
	bool			mode_4b;

	/* Callbacks */
	struct spi_flash_ctrl	ops;
};

static uint32_t ast_ahb_freq;

static const uint32_t ast_ct_hclk_divs[] = {
	0xf, /* HCLK */
	0x7, /* HCLK/2 */
	0xe, /* HCLK/3 */
	0x6, /* HCLK/4 */
	0xd, /* HCLK/5 */
};

#ifdef __SKIBOOT__
#define PNOR_AHB_ADDR	0x30000000
static uint32_t pnor_lpc_offset;

static int ast_copy_to_ahb(uint32_t reg, const void *src, uint32_t len)
{
	/* Check we don't cross IDSEL segments */
	if ((reg ^ (reg + len - 1)) >> 28)
		return -EINVAL;

	/* SPI flash, use LPC->AHB bridge */
	if ((reg >> 28) == (PNOR_AHB_ADDR >> 28)) {
		uint32_t chunk, off = reg - PNOR_AHB_ADDR + pnor_lpc_offset;
		int64_t rc;

		while(len) {
			/* Chose access size */
			if (len > 3 && !(off & 3)) {
				/* endian swap: see ast_copy_from_ahb */
				uint32_t dat = be32_to_cpu(*(__be32 *)src);

				rc = lpc_write(OPAL_LPC_FW, off,
					       dat, 4);
				chunk = 4;
			} else {
				rc = lpc_write(OPAL_LPC_FW, off,
					       *(uint8_t *)src, 1);
				chunk = 1;
			}
			if (rc) {
				prerror("AST_IO: lpc_write.sb failure %lld"
					" to FW 0x%08x\n", rc, off);
				return rc;
			}
			len -= chunk;
			off += chunk;
			src += chunk;
		}
		return 0;
	}

	/* Otherwise we don't do byte access (... yet)  */
	prerror("AST_IO: Attempted write bytes access to %08x\n", reg);
	return -EINVAL;
}

static int ast_copy_from_ahb(void *dst, uint32_t reg, uint32_t len)
{
	/* Check we don't cross IDSEL segments */
	if ((reg ^ (reg + len - 1)) >> 28)
		return -EINVAL;

	/* SPI flash, use LPC->AHB bridge */
	if ((reg >> 28) == (PNOR_AHB_ADDR >> 28)) {
		uint32_t chunk, off = reg - PNOR_AHB_ADDR + pnor_lpc_offset;
		int64_t rc;

		while(len) {
			uint32_t dat;

			/* Chose access size */
			if (len > 3 && !(off & 3)) {
				rc = lpc_read(OPAL_LPC_FW, off, &dat, 4);
				if (!rc) {
					/*
					 * lpc_read swaps to CPU endian but it's not
					 * really a 32-bit value, so convert back.
					 */
					*(__be32 *)dst = cpu_to_be32(dat);
				}
				chunk = 4;
			} else {
				rc = lpc_read(OPAL_LPC_FW, off, &dat, 1);
				if (!rc)
					*(uint8_t *)dst = dat;
				chunk = 1;
			}
			if (rc) {
				prerror("AST_IO: lpc_read.sb failure %lld"
					" to FW 0x%08x\n", rc, off);
				return rc;
			}
			len -= chunk;
			off += chunk;
			dst += chunk;
		}
		return 0;
	}
	/* Otherwise we don't do byte access (... yet)  */
	prerror("AST_IO: Attempted read bytes access to %08x\n", reg);
	return -EINVAL;
}
#endif /* __SKIBOOT__ */

static int ast_sf_start_cmd(struct ast_sf_ctrl *ct, uint8_t cmd)
{
	/* Switch to user mode, CE# dropped */
	ast_ahb_writel(ct->ctl_val | 7, ct->ctl_reg);

	/* user mode, CE# active */
	ast_ahb_writel(ct->ctl_val | 3, ct->ctl_reg);

	/* write cmd */
	return ast_copy_to_ahb(ct->flash, &cmd, 1);
}

static void ast_sf_end_cmd(struct ast_sf_ctrl *ct)
{
	/* clear CE# */
	ast_ahb_writel(ct->ctl_val | 7, ct->ctl_reg);

	/* Switch back to read mode */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
}

static int ast_sf_send_addr(struct ast_sf_ctrl *ct, uint32_t addr)
{
	const void *ap;
	beint32_t tmp;

	/* Layout address MSB first in memory */
	tmp = cpu_to_be32(addr);

	/* Send the right amount of bytes */
	ap = (char *)&tmp;

	if (ct->mode_4b)
		return ast_copy_to_ahb(ct->flash, ap, 4);
	else
		return ast_copy_to_ahb(ct->flash, ap + 1, 3);
}

static int ast_sf_cmd_rd(struct spi_flash_ctrl *ctrl, uint8_t cmd,
			 bool has_addr, uint32_t addr, void *buffer,
			 uint32_t size)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
	int rc;

	rc = ast_sf_start_cmd(ct, cmd);
	if (rc)
		goto bail;
	if (has_addr) {
		rc = ast_sf_send_addr(ct, addr);
		if (rc)
			goto bail;
	}
	if (buffer && size)
		rc = ast_copy_from_ahb(buffer, ct->flash, size);
 bail:
	ast_sf_end_cmd(ct);
	return rc;
}

static int ast_sf_cmd_wr(struct spi_flash_ctrl *ctrl, uint8_t cmd,
			 bool has_addr, uint32_t addr, const void *buffer,
			 uint32_t size)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
	int rc;

	rc = ast_sf_start_cmd(ct, cmd);
	if (rc)
		goto bail;
	if (has_addr) {
		rc = ast_sf_send_addr(ct, addr);
		if (rc)
			goto bail;
	}
	if (buffer && size)
		rc = ast_copy_to_ahb(ct->flash, buffer, size);
 bail:
	ast_sf_end_cmd(ct);
	return rc;
}

static int ast_sf_set_4b(struct spi_flash_ctrl *ctrl, bool enable)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
	uint32_t ce_ctrl = 0;

	if (ct->type == AST_SF_TYPE_BMC && ct->ops.finfo->size > 0x1000000)
		ce_ctrl = ast_ahb_readl(BMC_SPI_FCTL_CE_CTRL);
	else if (ct->type != AST_SF_TYPE_PNOR)
		return enable ? FLASH_ERR_4B_NOT_SUPPORTED : 0;

	/*
	 * We update the "old" value as well since when quitting
	 * we don't restore the mode of the flash itself so we need
	 * to leave the controller in a compatible setup
	 */
	if (enable) {
		ct->ctl_val |= 0x2000;
		ct->ctl_read_val |= 0x2000;
		ce_ctrl |= 0x1;
	} else {
		ct->ctl_val &= ~0x2000;
		ct->ctl_read_val &= ~0x2000;
		ce_ctrl &= ~0x1;
	}
	ct->mode_4b = enable;

	/* Update read mode */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	if (ce_ctrl && ct->type == AST_SF_TYPE_BMC)
		ast_ahb_writel(ce_ctrl, BMC_SPI_FCTL_CE_CTRL);

	return 0;
}

static int ast_sf_read(struct spi_flash_ctrl *ctrl, uint32_t pos,
		       void *buf, uint32_t len)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);

	/*
	 * We are in read mode by default. We don't yet support fancy
	 * things like fast read or X2 mode
	 */
	return ast_copy_from_ahb(buf, ct->flash + pos, len);
}

static void ast_get_ahb_freq(void)
{
	static const uint32_t cpu_freqs_24_48[] = {
		384000000,
		360000000,
		336000000,
		408000000
	};
	static const uint32_t cpu_freqs_25[] = {
		400000000,
		375000000,
		350000000,
		425000000
	};
	static const uint32_t ahb_div[] = { 1, 2, 4, 3 };
	uint32_t strap, cpu_clk, div;

	if (ast_ahb_freq)
		return;

	/* HW strapping gives us the CPU freq and AHB divisor */
	strap = ast_ahb_readl(SCU_HW_STRAPPING);
	if (strap & 0x00800000) {
		FL_DBG("AST: CLKIN 25Mhz\n");
		cpu_clk = cpu_freqs_25[(strap >> 8) & 3];
	} else {
		FL_DBG("AST: CLKIN 24/48Mhz\n");
		cpu_clk = cpu_freqs_24_48[(strap >> 8) & 3];
	}
	FL_DBG("AST: CPU frequency: %d Mhz\n", cpu_clk / 1000000);
	div = ahb_div[(strap >> 10) & 3];
	ast_ahb_freq = cpu_clk / div;
	FL_DBG("AST: AHB frequency: %d Mhz\n", ast_ahb_freq / 1000000);
}

static int ast_sf_check_reads(struct ast_sf_ctrl *ct,
			      const uint8_t *golden_buf, uint8_t *test_buf)
{
	int i, rc;

	for (i = 0; i < 10; i++) {
		rc = ast_copy_from_ahb(test_buf, ct->flash, CALIBRATE_BUF_SIZE);
		if (rc)
			return rc;
		if (memcmp(test_buf, golden_buf, CALIBRATE_BUF_SIZE) != 0)
			return FLASH_ERR_VERIFY_FAILURE;
	}
	return 0;
}

static int ast_sf_calibrate_reads(struct ast_sf_ctrl *ct, uint32_t hdiv,
				  const uint8_t *golden_buf, uint8_t *test_buf)
{
	int i, rc;
	int good_pass = -1, pass_count = 0;
	uint32_t shift = (hdiv - 1) << 2;
	uint32_t mask = ~(0xfu << shift);

#define FREAD_TPASS(i)	(((i) / 2) | (((i) & 1) ? 0 : 8))

	/* Try HCLK delay 0..5, each one with/without delay and look for a
	 * good pair.
	 */
	for (i = 0; i < 12; i++) {
		bool pass;

		ct->fread_timing_val &= mask;
		ct->fread_timing_val |= FREAD_TPASS(i) << shift;
		ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
		rc = ast_sf_check_reads(ct, golden_buf, test_buf);
		if (rc && rc != FLASH_ERR_VERIFY_FAILURE)
			return rc;
		pass = (rc == 0);
		FL_DBG("  * [%08x] %d HCLK delay, %dns DI delay : %s\n",
		       ct->fread_timing_val, i/2, (i & 1) ? 0 : 4, pass ? "PASS" : "FAIL");
		if (pass) {
			pass_count++;
			if (pass_count == 3) {
				good_pass = i - 1;
				break;
			}
		} else
			pass_count = 0;
	}

	/* No good setting for this frequency */
	if (good_pass < 0)
		return FLASH_ERR_VERIFY_FAILURE;

	/* We have at least one pass of margin, let's use first pass */
	ct->fread_timing_val &= mask;
	ct->fread_timing_val |= FREAD_TPASS(good_pass) << shift;
	ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
	FL_DBG("AST:  * -> good is pass %d [0x%08x]\n",
	       good_pass, ct->fread_timing_val);
	return 0;
}

static bool ast_calib_data_usable(const uint8_t *test_buf, uint32_t size)
{
	const uint32_t *tb32 = (const uint32_t *)test_buf;
	uint32_t i, cnt = 0;

	/* We check if we have enough words that are neither all 0
	 * nor all 1's so the calibration can be considered valid.
	 *
	 * I use an arbitrary threshold for now of 64
	 */
	size >>= 2;
	for (i = 0; i < size; i++) {
		if (tb32[i] != 0 && tb32[i] != 0xffffffff)
			cnt++;
	}
	return cnt >= 64;
}

static int ast_sf_optimize_reads(struct ast_sf_ctrl *ct,
				 struct flash_info *info __unused,
				 uint32_t max_freq)
{
	uint8_t *golden_buf, *test_buf;
	int i, rc, best_div = -1;
	uint32_t save_read_val = ct->ctl_read_val;

	test_buf = malloc(CALIBRATE_BUF_SIZE * 2);
	golden_buf = test_buf + CALIBRATE_BUF_SIZE;

	/* We start with the dumbest setting and read some data */
	ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x00 << 24) | /* CE# max */
		(0x03 << 16) | /* use normal reads */
		(0x00 <<  8) | /* HCLK/16 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);        /* normal read */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	rc = ast_copy_from_ahb(golden_buf, ct->flash, CALIBRATE_BUF_SIZE);
	if (rc) {
		free(test_buf);
		return rc;
	}

	/* Establish our read mode with freq field set to 0 */
	ct->ctl_read_val = save_read_val & 0xfffff0ff;

	/* Check if calibration data is suitable */
	if (!ast_calib_data_usable(golden_buf, CALIBRATE_BUF_SIZE)) {
		FL_INF("AST: Calibration area too uniform, "
		       "using low speed\n");
		ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
		free(test_buf);
		return 0;
	}

	/* Now we iterate the HCLK dividers until we find our breaking point */
	for (i = 5; i > 0; i--) {
		uint32_t tv, freq;

		/* Compare timing to max */
		freq = ast_ahb_freq / i;
		if (freq >= max_freq)
			continue;

		/* Set the timing */
		tv = ct->ctl_read_val | (ast_ct_hclk_divs[i - 1] << 8);
		ast_ahb_writel(tv, ct->ctl_reg);
		FL_DBG("AST: Trying HCLK/%d...\n", i);
		rc = ast_sf_calibrate_reads(ct, i, golden_buf, test_buf);

		/* Some other error occurred, bail out */
		if (rc && rc != FLASH_ERR_VERIFY_FAILURE) {
			free(test_buf);
			return rc;
		}
		if (rc == 0)
			best_div = i;
	}
	free(test_buf);

	/* Nothing found ? */
	if (best_div < 0)
		FL_ERR("AST: No good frequency, using dumb slow\n");
	else {
		FL_DBG("AST: Found good read timings at HCLK/%d\n", best_div);
		ct->ctl_read_val |= (ast_ct_hclk_divs[best_div - 1] << 8);
	}
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	return 0;
}

static int ast_sf_get_hclk(uint32_t *ctl_val, uint32_t max_freq)
{
	int i;

	/* It appears that running commands at HCLK/2 on some micron
	 * chips results in occasionally reads of bogus status (that
	 * or unrelated chip hangs).
	 *
	 * Since we cannot calibrate properly the reads for commands,
	 * instead, let's limit our SPI frequency to HCLK/4 to stay
	 * on the safe side of things
	 */
#define MIN_CMD_FREQ	4
	for (i = MIN_CMD_FREQ; i <= 5; i++) {
		uint32_t freq = ast_ahb_freq / i;
		if (freq >= max_freq)
			continue;
		*ctl_val |= (ast_ct_hclk_divs[i - 1] << 8);
		return i;
	}
	return 0;
}

static int ast_sf_setup_macronix(struct ast_sf_ctrl *ct, struct flash_info *info)
{
	int rc, div __unused;
	uint8_t srcr[2];

	/*
	 * Those Macronix chips support dual reads at 104Mhz
	 * and dual IO at 84Mhz with 4 dummies.
	 *
	 * Our calibration algo should give us something along
	 * the lines of HCLK/3 (HCLK/2 seems to work sometimes
	 * but appears to be fairly unreliable) which is 64Mhz
	 *
	 * So we chose dual IO mode.
	 *
	 * The CE# inactive width for reads must be 7ns, we set it
	 * to 3T which is about 15ns at the fastest speed we support
	 * HCLK/2) as I've had issue with smaller values.
	 *
	 * For write and program it's 30ns so let's set the value
	 * for normal ops to 6T.
	 *
	 * Preserve the current 4b mode.
	 */
	FL_DBG("AST: Setting up Macronix...\n");

	/*
	 * Read the status and config registers
	 */
	rc = ast_sf_cmd_rd(&ct->ops, CMD_RDSR, false, 0, &srcr[0], 1);
	if (rc != 0) {
		FL_ERR("AST: Failed to read status\n");
		return rc;
	}
	rc = ast_sf_cmd_rd(&ct->ops, CMD_RDCR, false, 0, &srcr[1], 1);
	if (rc != 0) {
		FL_ERR("AST: Failed to read configuration\n");
		return rc;
	}

	FL_DBG("AST: Macronix SR:CR: 0x%02x:%02x\n", srcr[0], srcr[1]);

	/* Switch to 8 dummy cycles to enable 104Mhz operations */
	srcr[1] = (srcr[1] & 0x3f) | 0x80;

	rc = fl_wren(&ct->ops);
	if (rc) {
		FL_ERR("AST: Failed to WREN for Macronix config\n");
		return rc;
	}

	rc = ast_sf_cmd_wr(&ct->ops, CMD_WRSR, false, 0, srcr, 2);
	if (rc != 0) {
		FL_ERR("AST: Failed to write Macronix config\n");
		return rc;
	}
	rc = fl_sync_wait_idle(&ct->ops);;
	if (rc != 0) {
		FL_ERR("AST: Failed waiting for config write\n");
		return rc;
	}

	FL_DBG("AST: Macronix SR:CR: 0x%02x:%02x\n", srcr[0], srcr[1]);

	/* Use 2READ */
	ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
		(0x03 << 28) | /* Dual IO */
		(0x0d << 24) | /* CE# width 3T */
		(0xbb << 16) | /* 2READ command */
		(0x00 <<  8) | /* HCLK/16 (optimize later) */
		(0x02 <<  6) | /* 2 bytes dummy cycle (8 clocks) */
		(0x01);	       /* fast read */

	/* Configure SPI flash read timing */
	rc = ast_sf_optimize_reads(ct, info, 104000000);
	if (rc) {
		FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
		return rc;
	}

	/*
	 * For other commands and writes also increase the SPI clock
	 * to HCLK/2 since the chip supports up to 133Mhz and set
	 * CE# inactive to 6T. We request a timing that is 20% below
	 * the limit of the chip, so about 106Mhz which should fit.
	 */
	ct->ctl_val = (ct->ctl_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x0a << 24) | /* CE# width 6T (b1010) */
		(0x00 << 16) | /* no command */
		(0x00 <<  8) | /* HCLK/16 (done later) */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);	       /* normal read */

	div = ast_sf_get_hclk(&ct->ctl_val, 106000000);
	FL_DBG("AST: Command timing set to HCLK/%d\n", div);

	/* Update chip with current read config */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
	return 0;
}

static int ast_sf_setup_winbond(struct ast_sf_ctrl *ct, struct flash_info *info)
{
	int rc, div __unused;

	FL_DBG("AST: Setting up Windbond...\n");

	/*
	 * This Windbond chip support dual reads at 104Mhz
	 * with 8 dummy cycles.
	 *
	 * The CE# inactive width for reads must be 10ns, we set it
	 * to 3T which is about 15.6ns.
	 */
	ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
		(0x02 << 28) | /* Dual bit data only */
		(0x0e << 24) | /* CE# width 2T (b1110) */
		(0x3b << 16) | /* DREAD command */
		(0x00 <<  8) | /* HCLK/16 */
		(0x01 <<  6) | /* 1-byte dummy cycle */
		(0x01);	       /* fast read */

	/* Configure SPI flash read timing */
	rc = ast_sf_optimize_reads(ct, info, 104000000);
	if (rc) {
		FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
		return rc;
	}

	/*
	 * For other commands and writes also increase the SPI clock
	 * to HCLK/2 since the chip supports up to 133Mhz. CE# inactive
	 * for write and erase is 50ns so let's set it to 10T.
	 */
	ct->ctl_val = (ct->ctl_read_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x06 << 24) | /* CE# width 10T (b0110) */
		(0x00 << 16) | /* no command */
		(0x00 <<  8) | /* HCLK/16 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x01);	       /* fast read */

	div = ast_sf_get_hclk(&ct->ctl_val, 106000000);
	FL_DBG("AST: Command timing set to HCLK/%d\n", div);

	/* Update chip with current read config */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
	return 0;
}

static int ast_sf_setup_micron(struct ast_sf_ctrl *ct, struct flash_info *info)
{
	uint8_t	vconf, ext_id[6];
	int rc, div __unused;

	FL_DBG("AST: Setting up Micron...\n");

	/*
	 * Read the extended chip ID to try to detect old vs. new
	 * flashes since old Micron flashes have a lot of issues
	 */
	rc = ast_sf_cmd_rd(&ct->ops, CMD_RDID, false, 0, ext_id, 6);
	if (rc != 0) {
		FL_ERR("AST: Failed to read Micron ext ID, sticking to dumb speed\n");
		return 0;
	}
	/* Check ID matches expectations */
	if (ext_id[0] != ((info->id >> 16) & 0xff) ||
	    ext_id[1] != ((info->id >>  8) & 0xff) ||
	    ext_id[2] != ((info->id      ) & 0xff)) {
		FL_ERR("AST: Micron ext ID mismatch, sticking to dumb speed\n");
		return 0;
	}
	FL_DBG("AST: Micron ext ID byte: 0x%02x\n", ext_id[4]);

	/* Check for old (<45nm) chips, don't try to be fancy on those */
	if (!(ext_id[4] & 0x40)) {
		FL_DBG("AST: Old chip, using dumb timings\n");
		goto dumb;
	}

	/*
	 * Read the micron specific volatile configuration reg
	 */
	rc = ast_sf_cmd_rd(&ct->ops, CMD_MIC_RDVCONF, false, 0, &vconf, 1);
	if (rc != 0) {
		FL_ERR("AST: Failed to read Micron vconf, sticking to dumb speed\n");
		goto dumb;
	}
	FL_DBG("AST: Micron VCONF: 0x%02x\n", vconf);

	/* Switch to 8 dummy cycles (we might be able to operate with 4
	 * but let's keep some margin
	 */
	vconf = (vconf & 0x0f) | 0x80;

	rc = ast_sf_cmd_wr(&ct->ops, CMD_MIC_WRVCONF, false, 0, &vconf, 1);
	if (rc != 0) {
		FL_ERR("AST: Failed to write Micron vconf, "
		       " sticking to dumb speed\n");
		goto dumb;
	}
	rc = fl_sync_wait_idle(&ct->ops);;
	if (rc != 0) {
		FL_ERR("AST: Failed waiting for config write\n");
		return rc;
	}
	FL_DBG("AST: Updated to  : 0x%02x\n", vconf);

	/*
	 * Try to do full dual IO, with 8 dummy cycles it supports 133Mhz
	 *
	 * The CE# inactive width for reads must be 20ns, we set it
	 * to 4T which is about 20.8ns.
	 */
	ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
		(0x03 << 28) | /* Single bit */
		(0x0c << 24) | /* CE# 4T */
		(0xbb << 16) | /* 2READ command */
		(0x00 <<  8) | /* HCLK/16 (optimize later) */
		(0x02 <<  6) | /* 8 dummy cycles (2 bytes) */
		(0x01);	       /* fast read */

	/* Configure SPI flash read timing */
	rc = ast_sf_optimize_reads(ct, info, 133000000);
	if (rc) {
		FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
		return rc;
	}

	/*
	 * For other commands and writes also increase the SPI clock
	 * to HCLK/2 since the chip supports up to 133Mhz. CE# inactive
	 * for write and erase is 50ns so let's set it to 10T.
	 */
	ct->ctl_val = (ct->ctl_read_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x06 << 24) | /* CE# width 10T (b0110) */
		(0x00 << 16) | /* no command */
		(0x00 <<  8) | /* HCLK/16 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);	       /* norm read */

	div = ast_sf_get_hclk(&ct->ctl_val, 133000000);
	FL_DBG("AST: Command timing set to HCLK/%d\n", div);

	/* Update chip with current read config */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	return 0;

 dumb:
	ct->ctl_val = ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x00 << 24) | /* CE# max */
		(0x03 << 16) | /* use normal reads */
		(0x06 <<  8) | /* HCLK/4 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);	       /* normal read */

	/* Update chip with current read config */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	return 0;
}

static int ast_sf_setup(struct spi_flash_ctrl *ctrl, uint32_t *tsize)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
	struct flash_info *info = ctrl->finfo;

	(void)tsize;

	/*
	 * Configure better timings and read mode for known
	 * flash chips
	 */
	switch(info->id) {
	case 0xc22018: /* MX25L12835F */
	case 0xc22019: /* MX25L25635F */
	case 0xc2201a: /* MX66L51235F */
	case 0xc2201b: /* MX66L1G45G */
		return ast_sf_setup_macronix(ct, info);
	case 0xef4018: /* W25Q128BV */
		return ast_sf_setup_winbond(ct, info);
	case 0x20ba20: /* MT25Qx512xx */
		return ast_sf_setup_micron(ct, info);
	}
	/* No special tuning */
	return 0;
}

static bool ast_sf_init_pnor(struct ast_sf_ctrl *ct)
{
	uint32_t reg;

	ct->ctl_reg = PNOR_SPI_FCTL_CTRL;
	ct->fread_timing_reg = PNOR_SPI_FREAD_TIMING;
	ct->flash = PNOR_FLASH_BASE;

	/* Enable writing to the controller */
	reg = ast_ahb_readl(PNOR_SPI_FCTL_CONF);
	if (reg == 0xffffffff) {
		FL_ERR("AST_SF: Failed read from controller config\n");
		return false;
	}
	ast_ahb_writel(reg | 1, PNOR_SPI_FCTL_CONF);

	/*
	 * Snapshot control reg and sanitize it for our
	 * use, switching to 1-bit mode, clearing user
	 * mode if set, etc...
	 *
	 * Also configure SPI clock to something safe
	 * like HCLK/8 (24Mhz)
	 */
	ct->ctl_val = ast_ahb_readl(ct->ctl_reg);
	if (ct->ctl_val == 0xffffffff) {
		FL_ERR("AST_SF: Failed read from controller control\n");
		return false;
	}

	ct->ctl_val = (ct->ctl_val & 0x2000) |
		(0x00 << 28) | /* Single bit */
		(0x00 << 24) | /* CE# width 16T */
		(0x00 << 16) | /* no command */
		(0x04 <<  8) | /* HCLK/8 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);	       /* normal read */

	/* Initial read mode is default */
	ct->ctl_read_val = ct->ctl_val;

	/* Initial read timings all 0 */
	ct->fread_timing_val = 0;

	/* Configure for read */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
	ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);

	if (ct->ctl_val & 0x2000)
		ct->mode_4b = true;
	else
		ct->mode_4b = false;

	return true;
}

static bool ast_sf_init_bmc(struct ast_sf_ctrl *ct)
{
	ct->ctl_reg = BMC_SPI_FCTL_CTRL;
	ct->fread_timing_reg = BMC_SPI_FREAD_TIMING;
	ct->flash = BMC_FLASH_BASE;

	/*
	 * Snapshot control reg and sanitize it for our
	 * use, switching to 1-bit mode, clearing user
	 * mode if set, etc...
	 *
	 * Also configure SPI clock to something safe
	 * like HCLK/8 (24Mhz)
	 */
	ct->ctl_val =
		(0x00 << 28) | /* Single bit */
		(0x00 << 24) | /* CE# width 16T */
		(0x00 << 16) | /* no command */
		(0x04 <<  8) | /* HCLK/8 */
		(0x00 <<  6) | /* no dummy cycle */
		(0x00);	       /* normal read */

	/* Initial read mode is default */
	ct->ctl_read_val = ct->ctl_val;

	/* Initial read timings all 0 */
	ct->fread_timing_val = 0;

	/* Configure for read */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
	ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);

	ct->mode_4b = false;

	return true;
}

static int ast_mem_set4b(struct spi_flash_ctrl *ctrl __unused,
			 bool enable __unused)
{
	return 0;
}

static int ast_mem_setup(struct spi_flash_ctrl *ctrl __unused,
			 uint32_t *tsize __unused)
{
	return 0;
}

static int ast_mem_chipid(struct spi_flash_ctrl *ctrl __unused, uint8_t *id_buf,
			  uint32_t *id_size)
{
	if (*id_size < 3)
		return -1;

	id_buf[0] = 0xaa;
	id_buf[1] = 0x55;
	id_buf[2] = 0xaa;
	*id_size = 3;
	return 0;
}

static int ast_mem_write(struct spi_flash_ctrl *ctrl, uint32_t pos,
			const void *buf, uint32_t len)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);

	/*
	 * This only works when the ahb is pointed at system memory.
	 */
	return ast_copy_to_ahb(ct->flash + pos, buf, len);
}

static int ast_mem_erase(struct spi_flash_ctrl *ctrl, uint32_t addr, uint32_t size)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
	uint32_t pos, len, end = addr + size;
	uint64_t zero = 0;
	int ret;

	for (pos = addr; pos < end; pos += sizeof(zero)) {
		if (pos + sizeof(zero) > end)
			len = end - pos;
		else
			len = sizeof(zero);

		ret = ast_copy_to_ahb(ct->flash + pos, &zero, len);
		if (ret)
			return ret;
	}

	return 0;
}

int ast_sf_open(uint8_t type, struct spi_flash_ctrl **ctrl)
{
	struct ast_sf_ctrl *ct;
#ifdef __SKIBOOT__
	uint32_t hicr7;

	if (!ast_sio_is_enabled())
		return -ENODEV;
#endif /* __SKIBOOT__ */

	if (type != AST_SF_TYPE_PNOR && type != AST_SF_TYPE_BMC
	    && type != AST_SF_TYPE_MEM)
		return -EINVAL;

	*ctrl = NULL;
	ct = malloc(sizeof(*ct));
	if (!ct) {
		FL_ERR("AST_SF: Failed to allocate\n");
		return -ENOMEM;
	}
	memset(ct, 0, sizeof(*ct));
	ct->type = type;

	if (type == AST_SF_TYPE_MEM) {
		ct->ops.cmd_wr = NULL;
		ct->ops.cmd_rd = NULL;
		ct->ops.read = ast_sf_read;
		ct->ops.set_4b = ast_mem_set4b;
		ct->ops.write = ast_mem_write;
		ct->ops.erase = ast_mem_erase;
		ct->ops.setup = ast_mem_setup;
		ct->ops.chip_id = ast_mem_chipid;
		ct->flash = PNOR_FLASH_BASE;
	} else {
		ct->ops.cmd_wr = ast_sf_cmd_wr;
		ct->ops.cmd_rd = ast_sf_cmd_rd;
		ct->ops.set_4b = ast_sf_set_4b;
		ct->ops.read = ast_sf_read;
		ct->ops.setup = ast_sf_setup;
	}

	ast_get_ahb_freq();

	if (type == AST_SF_TYPE_PNOR) {
		if (!ast_sf_init_pnor(ct))
			goto fail;
	} else if (type == AST_SF_TYPE_BMC) {
		if (!ast_sf_init_bmc(ct))
			goto fail;
	}

#ifdef __SKIBOOT__
	/* Read the configuration of the LPC->AHB bridge for PNOR
	 * to extract the PNOR LPC offset which can be different
	 * depending on flash size
	 */
	hicr7 = ast_ahb_readl(LPC_HICR7);
	pnor_lpc_offset = (hicr7 & 0xffffu) << 16;
	prlog(PR_DEBUG, "AST: PNOR LPC offset: 0x%08x\n", pnor_lpc_offset);
#endif /* __SKIBOOT__ */

	*ctrl = &ct->ops;

	return 0;
 fail:
	free(ct);
	return -EIO;
}

void ast_sf_close(struct spi_flash_ctrl *ctrl)
{
	struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);

	/* Restore control reg to read */
	ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);

	/* Additional cleanup */
	if (ct->type == AST_SF_TYPE_PNOR) {
		uint32_t reg = ast_ahb_readl(PNOR_SPI_FCTL_CONF);
		if (reg != 0xffffffff)
			ast_ahb_writel(reg & ~1, PNOR_SPI_FCTL_CONF);
	}

	/* Free the whole lot */
	free(ct);
}
