/*
 * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
 * Copyright (c) 2019, Intel Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <common/debug.h>
#include <lib/mmio.h>
#include <string.h>
#include <drivers/delay_timer.h>
#include <drivers/console.h>

#include "cadence_qspi.h"

#define LESS(a, b)   (((a) < (b)) ? (a) : (b))
#define MORE(a, b)   (((a) > (b)) ? (a) : (b))


uint32_t qspi_device_size;
int cad_qspi_cs;

int cad_qspi_idle(void)
{
	return (mmio_read_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG)
			& CAD_QSPI_CFG_IDLE) >> 31;
}

int cad_qspi_set_baudrate_div(uint32_t div)
{
	if (div > 0xf)
		return CAD_INVALID;

	mmio_clrsetbits_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG,
			~CAD_QSPI_CFG_BAUDDIV_MSK,
			CAD_QSPI_CFG_BAUDDIV(div));

	return 0;
}

int cad_qspi_configure_dev_size(uint32_t addr_bytes,
		uint32_t bytes_per_dev, uint32_t bytes_per_block)
{

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_DEVSZ,
			CAD_QSPI_DEVSZ_ADDR_BYTES(addr_bytes) |
			CAD_QSPI_DEVSZ_BYTES_PER_PAGE(bytes_per_dev) |
			CAD_QSPI_DEVSZ_BYTES_PER_BLOCK(bytes_per_block));
	return 0;
}

int cad_qspi_set_read_config(uint32_t opcode, uint32_t instr_type,
		uint32_t addr_type, uint32_t data_type,
		uint32_t mode_bit, uint32_t dummy_clk_cycle)
{
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_DEVRD,
			CAD_QSPI_DEV_OPCODE(opcode) |
			CAD_QSPI_DEV_INST_TYPE(instr_type) |
			CAD_QSPI_DEV_ADDR_TYPE(addr_type) |
			CAD_QSPI_DEV_DATA_TYPE(data_type) |
			CAD_QSPI_DEV_MODE_BIT(mode_bit) |
			CAD_QSPI_DEV_DUMMY_CLK_CYCLE(dummy_clk_cycle));

	return 0;
}

int cad_qspi_set_write_config(uint32_t opcode, uint32_t addr_type,
		uint32_t data_type, uint32_t dummy_clk_cycle)
{
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_DEVWR,
			CAD_QSPI_DEV_OPCODE(opcode) |
			CAD_QSPI_DEV_ADDR_TYPE(addr_type) |
			CAD_QSPI_DEV_DATA_TYPE(data_type) |
			CAD_QSPI_DEV_DUMMY_CLK_CYCLE(dummy_clk_cycle));

	return 0;
}

int cad_qspi_timing_config(uint32_t clkphase, uint32_t clkpol, uint32_t csda,
		uint32_t csdads, uint32_t cseot, uint32_t cssot,
		uint32_t rddatacap)
{
	uint32_t cfg = mmio_read_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG);

	cfg &= CAD_QSPI_CFG_SELCLKPHASE_CLR_MSK &
		CAD_QSPI_CFG_SELCLKPOL_CLR_MSK;
	cfg |= CAD_QSPI_SELCLKPHASE(clkphase) | CAD_QSPI_SELCLKPOL(clkpol);

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG, cfg);

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_DELAY,
		CAD_QSPI_DELAY_CSSOT(cssot) | CAD_QSPI_DELAY_CSEOT(cseot) |
		CAD_QSPI_DELAY_CSDADS(csdads) | CAD_QSPI_DELAY_CSDA(csda));

	return 0;
}

int cad_qspi_stig_cmd_helper(int cs, uint32_t cmd)
{
	uint32_t count = 0;

	/* chip select */
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG,
			(mmio_read_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG)
			 & CAD_QSPI_CFG_CS_MSK) | CAD_QSPI_CFG_CS(cs));

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD, cmd);
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD,
			cmd | CAD_QSPI_FLASHCMD_EXECUTE);

	do {
		uint32_t reg = mmio_read_32(CAD_QSPI_OFFSET +
					CAD_QSPI_FLASHCMD);
		if (!(reg & CAD_QSPI_FLASHCMD_EXECUTE_STAT))
			break;
		count++;
	} while (count < CAD_QSPI_COMMAND_TIMEOUT);

	if (count >= CAD_QSPI_COMMAND_TIMEOUT) {
		ERROR("Error sending QSPI command %x, timed out\n",
				cmd);
		return CAD_QSPI_ERROR;
	}

	return 0;
}

int cad_qspi_stig_cmd(uint32_t opcode, uint32_t dummy)
{
	if (dummy > ((1 << CAD_QSPI_FLASHCMD_NUM_DUMMYBYTES_MAX) - 1)) {
		ERROR("Faulty dummy bytes\n");
		return -1;
	}

	return cad_qspi_stig_cmd_helper(cad_qspi_cs,
			CAD_QSPI_FLASHCMD_OPCODE(opcode) |
			CAD_QSPI_FLASHCMD_NUM_DUMMYBYTES(dummy));
}

int cad_qspi_stig_read_cmd(uint32_t opcode, uint32_t dummy, uint32_t num_bytes,
		uint32_t *output)
{
	if (dummy > ((1 << CAD_QSPI_FLASHCMD_NUM_DUMMYBYTES_MAX) - 1)) {
		ERROR("Faulty dummy byes\n");
		return -1;
	}

	if ((num_bytes > 8) || (num_bytes == 0))
		return -1;

	uint32_t cmd =
		CAD_QSPI_FLASHCMD_OPCODE(opcode) |
		CAD_QSPI_FLASHCMD_ENRDDATA(1) |
		CAD_QSPI_FLASHCMD_NUMRDDATABYTES(num_bytes - 1) |
		CAD_QSPI_FLASHCMD_ENCMDADDR(0) |
		CAD_QSPI_FLASHCMD_ENMODEBIT(0) |
		CAD_QSPI_FLASHCMD_NUMADDRBYTES(0) |
		CAD_QSPI_FLASHCMD_ENWRDATA(0) |
		CAD_QSPI_FLASHCMD_NUMWRDATABYTES(0) |
		CAD_QSPI_FLASHCMD_NUMDUMMYBYTES(dummy);

	if (cad_qspi_stig_cmd_helper(cad_qspi_cs, cmd)) {
		ERROR("failed to send stig cmd\n");
		return -1;
	}

	output[0] = mmio_read_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD_RDDATA0);

	if (num_bytes > 4) {
		output[1] = mmio_read_32(CAD_QSPI_OFFSET +
				CAD_QSPI_FLASHCMD_RDDATA1);
	}

	return 0;
}

int cad_qspi_stig_wr_cmd(uint32_t opcode, uint32_t dummy, uint32_t num_bytes,
		uint32_t *input)
{
	if (dummy > ((1 << CAD_QSPI_FLASHCMD_NUM_DUMMYBYTES_MAX) - 1)) {
		ERROR("Faulty dummy byes\n");
		return -1;
	}

	if ((num_bytes > 8) || (num_bytes == 0))
		return -1;

	uint32_t cmd = CAD_QSPI_FLASHCMD_OPCODE(opcode) |
		CAD_QSPI_FLASHCMD_ENRDDATA(0) |
		CAD_QSPI_FLASHCMD_NUMRDDATABYTES(0) |
		CAD_QSPI_FLASHCMD_ENCMDADDR(0) |
		CAD_QSPI_FLASHCMD_ENMODEBIT(0) |
		CAD_QSPI_FLASHCMD_NUMADDRBYTES(0) |
		CAD_QSPI_FLASHCMD_ENWRDATA(1) |
		CAD_QSPI_FLASHCMD_NUMWRDATABYTES(num_bytes - 1) |
		CAD_QSPI_FLASHCMD_NUMDUMMYBYTES(dummy);

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD_WRDATA0, input[0]);

	if (num_bytes > 4)
		mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD_WRDATA1,
				input[1]);

	return cad_qspi_stig_cmd_helper(cad_qspi_cs, cmd);
}

int cad_qspi_stig_addr_cmd(uint32_t opcode, uint32_t dummy, uint32_t addr)
{
	uint32_t cmd;

	if (dummy > ((1 << CAD_QSPI_FLASHCMD_NUM_DUMMYBYTES_MAX) - 1))
		return -1;

	cmd = CAD_QSPI_FLASHCMD_OPCODE(opcode) |
		CAD_QSPI_FLASHCMD_NUMDUMMYBYTES(dummy) |
		CAD_QSPI_FLASHCMD_ENCMDADDR(1) |
		CAD_QSPI_FLASHCMD_NUMADDRBYTES(2);

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_FLASHCMD_ADDR, addr);

	return cad_qspi_stig_cmd_helper(cad_qspi_cs, cmd);
}

int cad_qspi_device_bank_select(uint32_t bank)
{
	int status = 0;

	status = cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_WREN, 0);
	if (status != 0)
		return status;

	status = cad_qspi_stig_wr_cmd(CAD_QSPI_STIG_OPCODE_WREN_EXT_REG,
			0, 1, &bank);
	if (status != 0)
		return status;

	return cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_WRDIS, 0);
}

int cad_qspi_device_status(uint32_t *status)
{
	return cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDSR, 0, 1, status);
}

#if CAD_QSPI_MICRON_N25Q_SUPPORT
int cad_qspi_n25q_enable(void)
{
	cad_qspi_set_read_config(QSPI_FAST_READ, CAD_QSPI_INST_SINGLE,
			CAD_QSPI_ADDR_FASTREAD, CAT_QSPI_ADDR_SINGLE_IO, 1,
			0);
	cad_qspi_set_write_config(QSPI_WRITE, 0, 0, 0);

	return 0;
}

int cad_qspi_n25q_wait_for_program_and_erase(int program_only)
{
	uint32_t status, flag_sr;
	int count = 0;

	while (count < CAD_QSPI_COMMAND_TIMEOUT) {
		status = cad_qspi_device_status(&status);
		if (status != 0) {
			ERROR("Error getting device status\n");
			return -1;
		}
		if (!CAD_QSPI_STIG_SR_BUSY(status))
			break;
		count++;
	}

	if (count >= CAD_QSPI_COMMAND_TIMEOUT) {
		ERROR("Timed out waiting for idle\n");
		return -1;
	}

	count = 0;

	while (count < CAD_QSPI_COMMAND_TIMEOUT) {
		status = cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDFLGSR,
				0, 1, &flag_sr);
		if (status != 0) {
			ERROR("Error waiting program and erase.\n");
			return status;
		}

		if ((program_only &&
			CAD_QSPI_STIG_FLAGSR_PROGRAMREADY(flag_sr)) ||
			(!program_only &&
			CAD_QSPI_STIG_FLAGSR_ERASEREADY(flag_sr)))
			break;
	}

	if (count >= CAD_QSPI_COMMAND_TIMEOUT)
		ERROR("Timed out waiting for program and erase\n");

	if ((program_only && CAD_QSPI_STIG_FLAGSR_PROGRAMERROR(flag_sr)) ||
			(!program_only &&
			CAD_QSPI_STIG_FLAGSR_ERASEERROR(flag_sr))) {
		ERROR("Error programming/erasing flash\n");
		cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_CLFSR, 0);
		return -1;
	}

	return 0;
}
#endif

int cad_qspi_indirect_read_start_bank(uint32_t flash_addr, uint32_t num_bytes)
{
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDRDSTADDR, flash_addr);
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDRDCNT, num_bytes);
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDRD,
			CAD_QSPI_INDRD_START |
			CAD_QSPI_INDRD_IND_OPS_DONE);

	return 0;
}


int cad_qspi_indirect_write_start_bank(uint32_t flash_addr,
					uint32_t num_bytes)
{
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDWRSTADDR, flash_addr);
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDWRCNT, num_bytes);
	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_INDWR,
			CAD_QSPI_INDWR_START |
			CAD_QSPI_INDWR_INDDONE);

	return 0;
}

int cad_qspi_indirect_write_finish(void)
{
#if CAD_QSPI_MICRON_N25Q_SUPPORT
	return cad_qspi_n25q_wait_for_program_and_erase(1);
#else
	return 0;
#endif

}

int cad_qspi_enable(void)
{
	int status;

	mmio_setbits_32(CAD_QSPI_OFFSET + CAD_QSPI_CFG, CAD_QSPI_CFG_ENABLE);

#if CAD_QSPI_MICRON_N25Q_SUPPORT
	status = cad_qspi_n25q_enable();
	if (status != 0)
		return status;
#endif
	return 0;
}

int cad_qspi_enable_subsector_bank(uint32_t addr)
{
	int status = 0;

	status = cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_WREN, 0);
	if (status != 0)
		return status;

	status = cad_qspi_stig_addr_cmd(CAD_QSPI_STIG_OPCODE_SUBSEC_ERASE, 0,
					addr);
	if (status != 0)
		return status;

#if CAD_QSPI_MICRON_N25Q_SUPPORT
	status = cad_qspi_n25q_wait_for_program_and_erase(0);
#endif
	return status;
}

int cad_qspi_erase_subsector(uint32_t addr)
{
	int status = 0;

	status = cad_qspi_device_bank_select(addr >> 24);
	if (status != 0)
		return status;

	return cad_qspi_enable_subsector_bank(addr);
}

int cad_qspi_erase_sector(uint32_t addr)
{
	int status = 0;

	status = cad_qspi_device_bank_select(addr >> 24);
	if (status != 0)
		return status;

	status = cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_WREN, 0);
	if (status != 0)
		return status;

	status = cad_qspi_stig_addr_cmd(CAD_QSPI_STIG_OPCODE_SEC_ERASE, 0,
					addr);
	if (status != 0)
		return status;

#if CAD_QSPI_MICRON_N25Q_SUPPORT
	status = cad_qspi_n25q_wait_for_program_and_erase(0);
#endif
	return status;
}

void cad_qspi_calibration(uint32_t dev_clk, uint32_t qspi_clk_mhz)
{
	int status;
	uint32_t dev_sclk_mhz = 27; /*min value to get biggest 0xF div factor*/
	uint32_t data_cap_delay;
	uint32_t sample_rdid;
	uint32_t rdid;
	uint32_t div_actual;
	uint32_t div_bits;
	int first_pass, last_pass;

	/*1.  Set divider to bigger value (slowest SCLK)
	 *2.  RDID and save the value
	 */
	div_actual = (qspi_clk_mhz + (dev_sclk_mhz - 1)) / dev_sclk_mhz;
	div_bits = (((div_actual + 1) / 2) - 1);
	status = cad_qspi_set_baudrate_div(0xf);

	status = cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDID,
					0, 3, &sample_rdid);
	if (status != 0)
		return;

	/*3. Set divider to the intended frequency
	 *4.  Set the read delay = 0
	 *5.  RDID and check whether the value is same as item 2
	 *6.  Increase read delay and compared the value against item 2
	 *7.  Find the range of read delay that have same as
	 *    item 2 and divide it to 2
	 */
	div_actual = (qspi_clk_mhz + (dev_clk - 1)) / dev_clk;
	div_bits = (((div_actual + 1) / 2) - 1);
	status = cad_qspi_set_baudrate_div(div_bits);
	if (status != 0)
		return;

	data_cap_delay = 0;
	first_pass = -1;
	last_pass = -1;

	do {
		if (status != 0)
			break;
		status = cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDID, 0,
						3, &rdid);
		if (status != 0)
			break;
		if (rdid == sample_rdid) {
			if (first_pass == -1)
				first_pass = data_cap_delay;
			else
				last_pass = data_cap_delay;
		}

		data_cap_delay++;

		mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_RDDATACAP,
				CAD_QSPI_RDDATACAP_BYP(1) |
				CAD_QSPI_RDDATACAP_DELAY(data_cap_delay));

	} while (data_cap_delay < 0x10);

	if (first_pass > 0) {
		int diff = first_pass - last_pass;

		data_cap_delay = first_pass + diff / 2;
	}

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_RDDATACAP,
			CAD_QSPI_RDDATACAP_BYP(1) |
			CAD_QSPI_RDDATACAP_DELAY(data_cap_delay));
	status = cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDID, 0, 3, &rdid);

	if (status != 0)
		return;
}

int cad_qspi_int_disable(uint32_t mask)
{
	if (cad_qspi_idle() == 0)
		return -1;

	if ((CAD_QSPI_INT_STATUS_ALL & mask) == 0)
		return -1;

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_IRQMSK, mask);
	return 0;
}

void cad_qspi_set_chip_select(int cs)
{
	cad_qspi_cs = cs;
}

int cad_qspi_init(uint32_t desired_clk_freq, uint32_t clk_phase,
			uint32_t clk_pol, uint32_t csda, uint32_t csdads,
			uint32_t cseot, uint32_t cssot, uint32_t rddatacap)
{
	int status = 0;
	uint32_t qspi_desired_clk_freq;
	uint32_t rdid = 0;
	uint32_t cap_code;

	INFO("Initializing Qspi\n");

	if (cad_qspi_idle() == 0) {
		ERROR("device not idle\n");
		return -1;
	}


	status = cad_qspi_timing_config(clk_phase, clk_pol, csda, csdads,
					cseot, cssot, rddatacap);

	if (status != 0) {
		ERROR("config set timing failure\n");
		return status;
	}

	mmio_write_32(CAD_QSPI_OFFSET + CAD_QSPI_REMAPADDR,
			CAD_QSPI_REMAPADDR_VALUE_SET(0));

	status = cad_qspi_int_disable(CAD_QSPI_INT_STATUS_ALL);
	if (status != 0) {
		ERROR("failed disable\n");
		return status;
	}

	cad_qspi_set_baudrate_div(0xf);
	status = cad_qspi_enable();
	if (status != 0) {
		ERROR("failed enable\n");
		return status;
	}

	qspi_desired_clk_freq = 100;
	cad_qspi_calibration(qspi_desired_clk_freq, 50000000);

	status = cad_qspi_stig_read_cmd(CAD_QSPI_STIG_OPCODE_RDID, 0, 3,
					&rdid);

	if (status != 0) {
		ERROR("Error reading RDID\n");
		return status;
	}

	/*
	 * NOTE: The Size code seems to be a form of BCD (binary coded decimal).
	 * The first nibble is the 10's digit and the second nibble is the 1's
	 * digit in the number of bytes.
	 *
	 * Capacity ID samples:
	 * 0x15 :   16 Mb =>   2 MiB => 1 << 21 ; BCD=15
	 * 0x16 :   32 Mb =>   4 MiB => 1 << 22 ; BCD=16
	 * 0x17 :   64 Mb =>   8 MiB => 1 << 23 ; BCD=17
	 * 0x18 :  128 Mb =>  16 MiB => 1 << 24 ; BCD=18
	 * 0x19 :  256 Mb =>  32 MiB => 1 << 25 ; BCD=19
	 * 0x1a
	 * 0x1b
	 * 0x1c
	 * 0x1d
	 * 0x1e
	 * 0x1f
	 * 0x20 :  512 Mb =>  64 MiB => 1 << 26 ; BCD=20
	 * 0x21 : 1024 Mb => 128 MiB => 1 << 27 ; BCD=21
	 */

	cap_code = CAD_QSPI_STIG_RDID_CAPACITYID(rdid);

	if (!(((cap_code >> 4) > 0x9) || ((cap_code & 0xf) > 0x9))) {
		uint32_t decoded_cap = ((cap_code >> 4) * 10) +
					(cap_code & 0xf);
		qspi_device_size = 1 << (decoded_cap + 6);
		INFO("QSPI Capacity: %x\n\n", qspi_device_size);

	} else {
		ERROR("Invalid CapacityID encountered: 0x%02x\n",
				cap_code);
		return -1;
	}

	cad_qspi_configure_dev_size(INTEL_QSPI_ADDR_BYTES,
				INTEL_QSPI_BYTES_PER_DEV,
				INTEL_BYTES_PER_BLOCK);

	INFO("Flash size: %d Bytes\n", qspi_device_size);

	return status;
}

int cad_qspi_indirect_page_bound_write(uint32_t offset,
		uint8_t *buffer, uint32_t len)
{
	int status = 0, i;
	uint32_t write_count, write_capacity, *write_data, space,
		write_fill_level, sram_partition;

	status = cad_qspi_indirect_write_start_bank(offset, len);
	if (status != 0)
		return status;

	write_count = 0;
	sram_partition = CAD_QSPI_SRAMPART_ADDR(mmio_read_32(CAD_QSPI_OFFSET +
			 CAD_QSPI_SRAMPART));
	write_capacity = (uint32_t) CAD_QSPI_SRAM_FIFO_ENTRY_COUNT -
			sram_partition;

	while (write_count < len) {
		write_fill_level = CAD_QSPI_SRAMFILL_INDWRPART(
					mmio_read_32(CAD_QSPI_OFFSET +
							CAD_QSPI_SRAMFILL));
		space = LESS(write_capacity - write_fill_level,
				(len - write_count) / sizeof(uint32_t));
		write_data = (uint32_t *)(buffer + write_count);
		for (i = 0; i < space; ++i)
			mmio_write_32(CAD_QSPIDATA_OFST, *write_data++);

		write_count += space * sizeof(uint32_t);
	}
	return cad_qspi_indirect_write_finish();
}

int cad_qspi_read_bank(uint8_t *buffer, uint32_t offset, uint32_t size)
{
	int status;
	uint32_t read_count = 0, *read_data;
	int level = 1, count = 0, i;

	status = cad_qspi_indirect_read_start_bank(offset, size);

	if (status != 0)
		return status;

	while (read_count < size) {
		do {
			level = CAD_QSPI_SRAMFILL_INDRDPART(
				mmio_read_32(CAD_QSPI_OFFSET +
					CAD_QSPI_SRAMFILL));
			read_data = (uint32_t *)(buffer + read_count);
			for (i = 0; i < level; ++i)
				*read_data++ = mmio_read_32(CAD_QSPIDATA_OFST);

			read_count += level * sizeof(uint32_t);
			count++;
		} while (level > 0);
	}

	return 0;
}

int cad_qspi_write_bank(uint32_t offset, uint8_t *buffer, uint32_t size)
{
	int status = 0;
	uint32_t page_offset  = offset & (CAD_QSPI_PAGE_SIZE - 1);
	uint32_t write_size = LESS(size, CAD_QSPI_PAGE_SIZE - page_offset);

	while (size) {
		status = cad_qspi_indirect_page_bound_write(offset, buffer,
							write_size);
		if (status != 0)
			break;

		offset  += write_size;
		buffer  += write_size;
		size -= write_size;
		write_size = LESS(size, CAD_QSPI_PAGE_SIZE);
	}
	return status;
}

int cad_qspi_read(void *buffer, uint32_t  offset, uint32_t  size)
{
	uint32_t bank_count, bank_addr, bank_offset, copy_len;
	uint8_t *read_data;
	int i, status;

	status = 0;

	if ((offset >= qspi_device_size) ||
			(offset + size - 1 >= qspi_device_size) ||
			(size == 0) ||
			((long) ((int *)buffer) & 0x3)  ||
			(offset & 0x3) ||
			(size & 0x3)) {
		ERROR("Invalid read parameter\n");
		return -1;
	}

	if (CAD_QSPI_INDRD_RD_STAT(mmio_read_32(CAD_QSPI_OFFSET +
						CAD_QSPI_INDRD))) {
		ERROR("Read in progress\n");
		return -1;
	}

	/*
	 * bank_count : Number of bank(s) affected, including partial banks.
	 * bank_addr  : Aligned address of the first bank,
	 *		including partial bank.
	 * bank_ofst  : The offset of the bank to read.
	 *		Only used when reading the first bank.
	 */
	bank_count = CAD_QSPI_BANK_ADDR(offset + size - 1) -
			CAD_QSPI_BANK_ADDR(offset) + 1;
	bank_addr  = offset & CAD_QSPI_BANK_ADDR_MSK;
	bank_offset  = offset & (CAD_QSPI_BANK_SIZE - 1);

	read_data = (uint8_t *)buffer;

	copy_len = LESS(size, CAD_QSPI_BANK_SIZE - bank_offset);

	for (i = 0; i < bank_count; ++i) {
		status = cad_qspi_device_bank_select(CAD_QSPI_BANK_ADDR(
								bank_addr));
		if (status != 0)
			break;
		status = cad_qspi_read_bank(read_data, bank_offset, copy_len);
		if (status != 0)
			break;

		bank_addr += CAD_QSPI_BANK_SIZE;
		read_data += copy_len;
		size -= copy_len;
		bank_offset = 0;
		copy_len = LESS(size, CAD_QSPI_BANK_SIZE);
	}

	return status;
}

int cad_qspi_erase(uint32_t offset, uint32_t size)
{
	int status = 0;
	uint32_t subsector_offset  = offset & (CAD_QSPI_SUBSECTOR_SIZE - 1);
	uint32_t erase_size = LESS(size,
				CAD_QSPI_SUBSECTOR_SIZE - subsector_offset);

	while (size) {
		status = cad_qspi_erase_subsector(offset);
		if (status != 0)
			break;

		offset  += erase_size;
		size -= erase_size;
		erase_size = LESS(size, CAD_QSPI_SUBSECTOR_SIZE);
	}
	return status;
}

int cad_qspi_write(void *buffer, uint32_t offset, uint32_t size)
{
	int status, i;
	uint32_t bank_count, bank_addr, bank_offset, copy_len;
	uint8_t *write_data;

	status = 0;

	if ((offset >= qspi_device_size) ||
			(offset + size - 1 >= qspi_device_size) ||
			(size == 0) ||
			((long)buffer & 0x3)  ||
			(offset & 0x3) ||
			(size & 0x3))
		return -2;

	if (CAD_QSPI_INDWR_RDSTAT(mmio_read_32(CAD_QSPI_OFFSET +
						CAD_QSPI_INDWR))) {
		ERROR("QSPI Error: Write in progress\n");
		return -1;
	}

	bank_count = CAD_QSPI_BANK_ADDR(offset + size - 1) -
			CAD_QSPI_BANK_ADDR(offset) + 1;
	bank_addr = offset & CAD_QSPI_BANK_ADDR_MSK;
	bank_offset = offset & (CAD_QSPI_BANK_SIZE - 1);

	write_data = buffer;

	copy_len = LESS(size, CAD_QSPI_BANK_SIZE - bank_offset);

	for (i = 0; i < bank_count; ++i) {
		status = cad_qspi_device_bank_select(
				CAD_QSPI_BANK_ADDR(bank_addr));
		if (status != 0)
			break;

		status = cad_qspi_write_bank(bank_offset, write_data,
						copy_len);
		if (status != 0)
			break;

		bank_addr += CAD_QSPI_BANK_SIZE;
		write_data += copy_len;
		size -= copy_len;
		bank_offset = 0;

		copy_len = LESS(size, CAD_QSPI_BANK_SIZE);
	}
	return status;
}

int cad_qspi_update(void *Buffer, uint32_t offset, uint32_t size)
{
	int status = 0;

	status = cad_qspi_erase(offset, size);
	if (status != 0)
		return status;

	return cad_qspi_write(Buffer, offset, size);
}

void cad_qspi_reset(void)
{
	cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_RESET_EN, 0);
	cad_qspi_stig_cmd(CAD_QSPI_STIG_OPCODE_RESET_MEM, 0);
}

