/* Copyright 2013-2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#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>

#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 */
};

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;

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

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

	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);

	/*
	 * 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)
		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 */
		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;

	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;
	}

	*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);
}
