/*
 * BLSP QUP SPI controller driver.
 * Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *  * Neither the name of The Linux Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <common.h>
#include <spi.h>
#include <malloc.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch-qca-common/bam.h>
#include "qca_qup_spi_bam.h"
#include <asm/arch-qca-common/gpio.h>
#include <fdtdec.h>

DECLARE_GLOBAL_DATA_PTR;

static unsigned int read_pipe[NO_OF_QUPS];
static unsigned int write_pipe[NO_OF_QUPS];
static unsigned char qup_pipe_initialized = 0;

static int check_bit_state(uint32_t reg_addr, int bit_num, int val,
							int us_delay)
{
	unsigned int count = TIMEOUT_CNT;
	unsigned int bit_val = ((readl(reg_addr) >> bit_num) & 0x01);

	while (bit_val != val) {
		count--;
		if (count == 0)
			return -ETIMEDOUT;
		udelay(us_delay);
		bit_val = ((readl(reg_addr) >> bit_num) & 0x01);
	}

	return SUCCESS;
}

/*
 * Check whether QUPn State is valid
 */
static int check_qup_state_valid(struct ipq_spi_slave *ds)
{
	return check_bit_state(ds->regs->qup_state, QUP_STATE_VALID_BIT,
				QUP_STATE_VALID, 1);
}

/*
 * Configure QUPn Core state
 */
static int config_spi_state(struct ipq_spi_slave *ds, unsigned int state)
{
	uint32_t val;
	int ret;

	ret = check_qup_state_valid(ds);
	if (ret != SUCCESS)
		return ret;

	switch (state) {
	case SPI_RUN_STATE:
		/* Set the state to RUN */
		val = ((readl(ds->regs->qup_state) & ~QUP_STATE_MASK)
					| QUP_STATE_RUN_STATE);
		writel(val, ds->regs->qup_state);
		ret = check_qup_state_valid(ds);
		if (ret != SUCCESS)
			return ret;
		ds->core_state = SPI_CORE_RUNNING;
		break;
	case SPI_RESET_STATE:
		/* Set the state to RESET */
		val = ((readl(ds->regs->qup_state) & ~QUP_STATE_MASK)
					| QUP_STATE_RESET_STATE);
		writel(val, ds->regs->qup_state);
		ret = check_qup_state_valid(ds);
		if (ret != SUCCESS)
			return ret;
		ds->core_state = SPI_CORE_RESET;
		break;
	default:
		printf("err: unsupported QUP SPI state : %d\n", state);
		ret = -EINVAL;
		break;
	}
	return ret;
}

/*
 * Set QUPn SPI Mode
 */
static void spi_set_mode(struct ipq_spi_slave *ds, unsigned int mode)
{
	unsigned int clk_idle_state;
	unsigned int input_first_mode;
	uint32_t val;

	switch (mode) {
	case SPI_MODE0:
		clk_idle_state = 0;
		input_first_mode = SPI_INPUT_FIRST_MODE;
		break;
	case SPI_MODE1:
		clk_idle_state = 0;
		input_first_mode = 0;
		break;
	case SPI_MODE2:
		clk_idle_state = 1;
		input_first_mode = SPI_INPUT_FIRST_MODE;
		break;
	case SPI_MODE3:
		clk_idle_state = 1;
		input_first_mode = 0;
		break;
	default:
		printf("err : unsupported spi mode : %d\n", mode);
		return;
	}

	val = readl(ds->regs->spi_config);
	val |= input_first_mode;
	writel(val, ds->regs->spi_config);

	val = readl(ds->regs->io_control);
	if (clk_idle_state)
		val |= SPI_IO_CONTROL_CLOCK_IDLE_HIGH;
	else
		val &= ~SPI_IO_CONTROL_CLOCK_IDLE_HIGH;

	writel(val, ds->regs->io_control);
}

/*
 * Reset entire QUP and all mini cores
 */
static void spi_reset(struct ipq_spi_slave *ds)
{
	writel(0x1, ds->regs->qup_sw_reset);
	udelay(5);
}

void spi_init()
{
	/* do nothing */
}

static void qup_pipe_init(void)
{
	char rd_pipe_name[10], wr_pipe_name[10];
	int node,i;

	qup_pipe_initialized = 1;
	node = fdt_path_offset(gd->fdt_blob, "/spi");
	if (node >= 0) {
		for(i = 0; i < NO_OF_QUPS; i++) {

		        snprintf(rd_pipe_name, sizeof(rd_pipe_name),
				"rd_pipe_%01d", i);

		        snprintf(wr_pipe_name, sizeof(wr_pipe_name),
				"wr_pipe_%01d", i);

			read_pipe[i] = fdtdec_get_uint(gd->fdt_blob,
					node, rd_pipe_name, 0);
			write_pipe[i] = fdtdec_get_uint(gd->fdt_blob,
					node, wr_pipe_name, 0);
		}
	}
}

/*
 * Function to assert and De-assert chip select
 */
static void CS_change(int port_num, int cs_num, int enable)
{
	unsigned int cs_gpio = 0;
	uint32_t addr = 0;
	uint32_t val = 0;
        char spi_node_path[32];
	int spi_cs_node = 0, spi_cs_gpio_node = 0;

	snprintf(spi_node_path, sizeof(spi_node_path),
			"/spi/spi%d/cs%d", port_num, cs_num);

        spi_cs_node = fdt_path_offset(gd->fdt_blob, spi_node_path);
	spi_cs_gpio_node = fdt_first_subnode(gd->fdt_blob, spi_cs_node);

	cs_gpio = fdtdec_get_uint(gd->fdt_blob, spi_cs_gpio_node, "gpio", 0);

	addr = GPIO_IN_OUT_ADDR(cs_gpio);
	val = readl(addr);

	val &= (~(GPIO_OUT));
	if (!enable)
		val |= (GPIO_OUT);
	writel(val, addr);
}

/*
 * BLSP TLMM configuration
 */
int blsp_pin_config(unsigned int port_num, int cs_num)
{
	char spi_node_path[32];
	int spi_node = 0;

	snprintf(spi_node_path, sizeof(spi_node_path),
			"/spi/spi%d/cs%d", port_num, cs_num);

        spi_node = fdt_path_offset(gd->fdt_blob, spi_node_path);
	if (spi_node >= 0) {
	        qca_gpio_init(spi_node);
	} else {
		printf("SPI : Node not found, skipping initialization\n");
		return -1;
	}

	return 0;
}

int cs_is_valid(unsigned int port_num, int cs_num)
{
	char spi_node_path[32];
	int spi_node = 0;

	snprintf(spi_node_path, sizeof(spi_node_path),
			"/spi/spi%d/cs%d", port_num, cs_num);

        spi_node = fdt_path_offset(gd->fdt_blob, spi_node_path);
	if (spi_node >= 0)
	        return 1;
	else
		return 0;
}

int qup_bam_init(struct ipq_spi_slave *ds)
{
	uint8_t read_pipe_grp = QUP0_DATA_PRODUCER_PIPE_GRP;
	uint8_t write_pipe_grp = QUP0_DATA_CONSUMER_PIPE_GRP;
	int bam_ret;

	if (!qup_pipe_initialized)
		qup_pipe_init();

	/* Pipe numbers based on the QUP index */
	if (ds->slave.bus == BLSP0_SPI) {
		read_pipe_grp = QUP0_DATA_PRODUCER_PIPE_GRP;
		write_pipe_grp = QUP0_DATA_CONSUMER_PIPE_GRP;
	} else if (ds->slave.bus == BLSP1_SPI) {
		read_pipe_grp = QUP1_DATA_PRODUCER_PIPE_GRP;
		write_pipe_grp = QUP1_DATA_CONSUMER_PIPE_GRP;
	}

	bam.base = BLSP0_BAM_BASE;
	/* Set Read Pipe Params */
	bam.pipe[DATA_PRODUCER_PIPE_INDEX].pipe_num = read_pipe[ds->slave.bus];
	bam.pipe[DATA_PRODUCER_PIPE_INDEX].trans_type = BAM2SYS;
	bam.pipe[DATA_PRODUCER_PIPE_INDEX].fifo.size = QUP_BAM_DATA_FIFO_SIZE;
	bam.pipe[DATA_PRODUCER_PIPE_INDEX].fifo.head = qup_spi_data_desc_fifo;
	bam.pipe[DATA_PRODUCER_PIPE_INDEX].lock_grp = read_pipe_grp;

	/* Set Write pipe params. */
	bam.pipe[DATA_CONSUMER_PIPE_INDEX].pipe_num = write_pipe[ds->slave.bus];
	bam.pipe[DATA_CONSUMER_PIPE_INDEX].trans_type = SYS2BAM;
	bam.pipe[DATA_CONSUMER_PIPE_INDEX].fifo.size = QUP_BAM_DATA_FIFO_SIZE;
	bam.pipe[DATA_CONSUMER_PIPE_INDEX].fifo.head = qup_spi_data_desc_fifo;
	bam.pipe[DATA_CONSUMER_PIPE_INDEX].lock_grp = write_pipe_grp;

	/* Programs the threshold for BAM transfer
	 * When this threshold is reached, BAM signals the peripheral via the
	 * pipe_bytes_available interface.
	 * The peripheral is signalled with this notification in the following
	 * cases:
	 * a.  It has accumulated all the descriptors.
	 * b.  It has accumulated more than threshold bytes.
	 * c.  It has reached EOT (End Of Transfer).
	 * Note: this value needs to be set by the h/w folks and is specific for
	 * each peripheral.
	 */
	bam.threshold = QUP_SPI_BAM_THRESHOLD;
	/* Set the EE.  */
	bam.ee = QUP_SPI_EE;
	/* Set the max desc length for this BAM. */
	bam.max_desc_len = QUP_SPI_MAX_DESC_LEN;
	/* BAM Init. */
	bam_init(&bam);
	/* Initialize BAM QPIC read pipe */
	bam_sys_pipe_init(&bam, DATA_PRODUCER_PIPE_INDEX);
	/* Init read fifo */
	bam_ret = bam_pipe_fifo_init(&bam, DATA_PRODUCER_PIPE_INDEX);
	if (bam_ret) {
		printf("QUP: SPI:  BAM Read FIFO init error\n");
		bam_ret = FAILURE;
		goto qup_spi_bam_init_error;
	}

	/* Initialize BAM QPIC write pipe */
	bam_sys_pipe_init(&bam, DATA_CONSUMER_PIPE_INDEX);

	/* Init write fifo. Use the same fifo as read fifo. */
	bam_ret = bam_pipe_fifo_init(&bam, DATA_CONSUMER_PIPE_INDEX);
	if (bam_ret) {
		printf("QUP: SPI: BAM Write FIFO init error\n");
		bam_ret = FAILURE;
		goto qup_spi_bam_init_error;
	}
qup_spi_bam_init_error:
	return bam_ret;
}

struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
				unsigned int max_hz, unsigned int mode)
{
	struct ipq_spi_slave *ds;

	/*
	 * spi gpios are not initialised for DK07-C2. If probed, the
	 * controller will indefinitely wait for response from slave.
	 * Hence, return NULL.
	 */
	ds = malloc(sizeof(struct ipq_spi_slave));
	if (!ds) {
		printf("SPI error: malloc of SPI structure failed\n");
		return NULL;
	}

	memset(ds, 0, sizeof(struct ipq_spi_slave));
	/*
	 * QCA BLSP supports SPI Flash
	 * on different BLSP0 and BLSP1
	 * with different number of chip selects (CS, channels):
	*/
	if ((bus > BLSP1_SPI)
		|| ((bus == BLSP0_SPI) && (cs > 2))
		|| ((bus == BLSP1_SPI) && (cs > 0))) {
		printf("SPI error: unsupported bus %d "
			"(Supported busses 0,1 and 2) or chipselect\n", bus);
		goto err;
	}
	ds->slave.bus	= bus;
	ds->slave.cs	= cs;

	ds->regs	= &spi_reg[bus];

	/* TODO For different clock frequency */
	if (max_hz > MSM_QUP_MAX_FREQ) {
		printf("SPI error: unsupported frequency %d Hz "
			"Max frequency is %d Hz\n", max_hz, MSM_QUP_MAX_FREQ);
		goto err;
	}
	ds->freq = max_hz;

	if (mode > SPI_MODE3) {
		printf("SPI error: unsupported SPI mode %d\n", mode);
		goto err;
	}
	ds->mode = mode;

	/* DMA mode */
	ds->use_dma = CONFIG_QUP_SPI_USE_DMA;

	if (ds->slave.cs == 1 &&
		cs_is_valid(ds->slave.bus, ds->slave.cs)) {
		/* GPIO Configuration for SPI NAND */
		blsp_pin_config(ds->slave.bus, ds->slave.cs);
		CS_change(ds->slave.bus, ds->slave.cs, CS_DEASSERT);
	}
#if !defined(CONFIG_SYS_DCACHE_OFF)
	flush_cache((unsigned long)ds,
		    (unsigned long)sizeof(struct ipq_spi_slave));
#endif
	return &ds->slave;
err:
	free(ds);
	return NULL;
}

void spi_free_slave(struct spi_slave *slave)
{
	struct ipq_spi_slave *ds = to_ipq_spi(slave);

	if (ds != NULL)
		free(ds);
}

/*
 * BLSP QUPn SPI Hardware Initialisation
 */
static int spi_hw_init(struct ipq_spi_slave *ds)
{
	int ret;

	ds->initialized = 0;

	/* QUPn module configuration */
	spi_reset(ds);

	/* Set the QUPn state */
	ret = config_spi_state(ds, SPI_RESET_STATE);
	if (ret)
		return ret;

	/* Initialize BAM */
	if(ds->use_dma) {
		ret = qup_bam_init(ds);
		if (ret != SUCCESS)
			return ret;
	}


	/*
	 * Configure Mini core to SPI core with Input Output enabled,
	 * SPI master, N = 8 bits
	 */
	clrsetbits_le32(ds->regs->qup_config, (QUP_CONFIG_MINI_CORE_MSK |
						QUP_CONF_INPUT_MSK |
						QUP_CONF_OUTPUT_MSK |
						SPI_BIT_WORD_MSK),
						(QUP_CONFIG_MINI_CORE_SPI |
						QUP_CONF_INPUT_ENA |
						QUP_CONF_OUTPUT_ENA |
						SPI_8_BIT_WORD));

	/*
	 * Configure Input first SPI protocol,
	 * SPI master mode and no loopback
	 */
	clrsetbits_le32(ds->regs->spi_config, (LOOP_BACK_MSK |
						SLAVE_OPERATION_MSK),
						(NO_LOOP_BACK |
						SLAVE_OPERATION));

	/*
	 * Configure SPI IO Control Register
	 * CLK_ALWAYS_ON = 0
	 * MX_CS_MODE = 0
	 * NO_TRI_STATE = 1
	 */
	writel((CLK_ALWAYS_ON | NO_TRI_STATE),
				ds->regs->io_control);

	/*
	 * Configure SPI IO Modes.
	 * OUTPUT_BIT_SHIFT_EN = 1
	 * INPUT_MODE = BAM Mode
	 * OUTPUT MODE = BAM Mode
	 */

	if (ds->use_dma)
		clrsetbits_le32(ds->regs->qup_io_modes, (OUTPUT_BIT_SHIFT_MSK |
						INPUT_BLOCK_MODE_MSK |
						OUTPUT_BLOCK_MODE_MSK |
						PACK_EN_MSK |
						UNPACK_EN_MSK),
						(OUTPUT_BIT_SHIFT_EN |
						INPUT_BAM_MODE |
						OUTPUT_BAM_MODE | PACK_EN |
						UNPACK_EN));
	else
	/*
	 * Configure SPI IO Modes.
	 * OUTPUT_BIT_SHIFT_EN = 1
	 * INPUT_MODE = Block Mode
	 * OUTPUT MODE = Block Mode
	 */

		clrsetbits_le32(ds->regs->qup_io_modes, (OUTPUT_BIT_SHIFT_MSK |
					INPUT_BLOCK_MODE_MSK |
					OUTPUT_BLOCK_MODE_MSK),
					(OUTPUT_BIT_SHIFT_EN |
					INPUT_BLOCK_MODE |
					OUTPUT_BLOCK_MODE));

	spi_set_mode(ds, ds->mode);

	/* Disable Error mask */
	writel(0, ds->regs->error_flags_en);
	writel(0, ds->regs->qup_error_flags_en);
	writel(0, ds->regs->qup_deassert_wait);

	if (ds->use_dma)
		clrsetbits_le32(ds->regs->qup_op_mask, (OUTPUT_SERVICE_MSK |
					INPUT_SERVICE_MSK),
					(OUTPUT_SERVICE_DIS |
					INPUT_SERVICE_DIS));
	ds->initialized = 1;

	return ret;
}

int spi_claim_bus(struct spi_slave *slave)
{
	struct ipq_spi_slave *ds = to_ipq_spi(slave);
	unsigned int ret;

	ret = spi_hw_init(ds);
	if (ret)
		return -EIO;

	return SUCCESS;
}

void spi_release_bus(struct spi_slave *slave)
{
	struct ipq_spi_slave *ds = to_ipq_spi(slave);

	/* Reset the SPI hardware */
	spi_reset(ds);
	ds->initialized = 0;
}

static void write_force_cs(struct spi_slave *slave, int assert)
{
	struct ipq_spi_slave *ds = to_ipq_spi(slave);

	if (assert)
		clrsetbits_le32(ds->regs->io_control,
			FORCE_CS_MSK, FORCE_CS_EN);
	else
		clrsetbits_le32(ds->regs->io_control,
			FORCE_CS_MSK, FORCE_CS_DIS);

	return;

}

/*
 * Function to write data to OUTPUT FIFO
 */
static void spi_write_byte(struct ipq_spi_slave *ds, unsigned char data)
{
	/* Wait for space in the FIFO */
	while ((readl(ds->regs->qup_operational) & QUP_OUTPUT_FIFO_FULL))
		udelay(1);

	/* Write the byte of data */
	writel(data, ds->regs->qup_output_fifo);
}

/*
 * Function to read data from Input FIFO
 */
static unsigned char spi_read_byte(struct ipq_spi_slave *ds)
{
	/* Wait for Data in FIFO */
	while (!(readl(ds->regs->qup_operational) &
			QUP_DATA_AVAILABLE_FOR_READ)) {
		udelay(1);
	}

	/* Read a byte of data */
	return readl(ds->regs->qup_input_fifo) & 0xff;
}

/*
 * Function to check wheather Input or Output FIFO
 * has data to be serviced
 */
static int check_fifo_status(uint32_t reg_addr)
{
	unsigned int count = TIMEOUT_CNT;
	unsigned int status_flag;
	unsigned int val;

	do {
		val = readl(reg_addr);
		count--;
		if (count == 0)
			return -ETIMEDOUT;
		status_flag = ((val & OUTPUT_SERVICE_FLAG) | (val & INPUT_SERVICE_FLAG));
	} while (!status_flag);

	return SUCCESS;
}

/*
 * Function to configure Input and Output enable/disable
 */
static void enable_io_config(struct ipq_spi_slave *ds,
				uint32_t write_cnt, uint32_t read_cnt)
{
	if (write_cnt) {
		clrsetbits_le32(ds->regs->qup_config,
				QUP_CONF_OUTPUT_MSK, QUP_CONF_OUTPUT_ENA);
	} else {
		clrsetbits_le32(ds->regs->qup_config,
				QUP_CONF_OUTPUT_MSK, QUP_CONF_NO_OUTPUT);
	}

	if (read_cnt) {
		clrsetbits_le32(ds->regs->qup_config,
				QUP_CONF_INPUT_MSK, QUP_CONF_INPUT_ENA);
	} else {
		clrsetbits_le32(ds->regs->qup_config,
				QUP_CONF_INPUT_MSK, QUP_CONF_NO_INPUT);
	}

	return;
}

static void
blsp_spi_wait_for_data(uint32_t pipe_num)
{
	/* Wait for the descriptors to be processed */
	bam_wait_for_interrupt(&bam, pipe_num, P_PRCSD_DESC_EN_MASK);

	/* Read offset update for the circular FIFO */
	bam_read_offset_update(&bam, pipe_num);
}


static int blsp_spi_bam_begin_xfer(struct ipq_spi_slave *ds, const u8 *buffer,
                unsigned int bytes, unsigned int type)
{
	u32 tx_bytes_to_send = 0, rx_bytes_to_recv = 0;
	u32 n_words_xfr;
	u32 ret = 0;
	u32 prod_desc_cnt = SPI_BAM_MAX_DESC_NUM - 1;
	u32 cons_desc_cnt = SPI_BAM_MAX_DESC_NUM - 1;
	u32 tx_bytes_sent = 0;
	u32 rx_bytes_rcvd = 0;
	int state_config;
	u32 data_xfer_size;
	int cons_flag = 0, prod_flag = 0;
	int num_desc = 0;
	u32 rem_bytes = 0;

	rem_bytes = bytes;

#if !defined(CONFIG_SYS_DCACHE_OFF)
	flush_cache((unsigned long)buffer, (unsigned long)bytes);
#endif
	while (rem_bytes) {
		tx_bytes_to_send = min_t(u32, bytes,
			SPI_MAX_TRFR_BTWN_RESETS);

		rx_bytes_to_recv = min_t(u32, bytes,
			SPI_MAX_TRFR_BTWN_RESETS);

		if (bytes > SPI_MAX_TRFR_BTWN_RESETS)
			rem_bytes = bytes - SPI_MAX_TRFR_BTWN_RESETS;
		else
			rem_bytes = 0;

		writel(0, ds->regs->qup_mx_output_count);
		if (type == READ) {
			n_words_xfr = rx_bytes_to_recv;
			writel(n_words_xfr, ds->regs->qup_mx_input_count);
		}

		state_config = config_spi_state(ds, SPI_RUN_STATE);
		if (state_config)
			return state_config;


		if (type == WRITE) {
			if (cons_desc_cnt > 0) {
				data_xfer_size = tx_bytes_to_send;

				if (rem_bytes == 0 || cons_desc_cnt == 1)
					cons_flag = BAM_DESC_EOT_FLAG |
							BAM_DESC_NWD_FLAG;
				cons_flag |= BAM_DESC_INT_FLAG;
				bam_add_one_desc(&bam, DATA_CONSUMER_PIPE_INDEX,
						 (unsigned char*)(buffer),
						 data_xfer_size, cons_flag);
				num_desc++;
				bam_sys_gen_event(&bam, DATA_CONSUMER_PIPE_INDEX,
						  num_desc);
				blsp_spi_wait_for_data(DATA_CONSUMER_PIPE_INDEX);
				num_desc = 0;
				tx_bytes_sent += data_xfer_size;
				buffer = buffer + data_xfer_size;
				bytes = rem_bytes;
				cons_desc_cnt--;
				if (cons_desc_cnt == 0)
					cons_desc_cnt = SPI_BAM_MAX_DESC_NUM - 1;

			}
		} else if (type == READ) {
			if (prod_desc_cnt > 0) {
				data_xfer_size = rx_bytes_to_recv;
				if (rem_bytes == 0 || prod_desc_cnt == 1)
					prod_flag = (BAM_DESC_EOT_FLAG |
							BAM_DESC_NWD_FLAG);
				prod_flag |= BAM_DESC_INT_FLAG;
				bam_add_one_desc(&bam, DATA_PRODUCER_PIPE_INDEX,
						 (unsigned char*)(buffer), data_xfer_size, prod_flag);
				num_desc++;
				bam_sys_gen_event(&bam, DATA_PRODUCER_PIPE_INDEX,
						  num_desc);
				blsp_spi_wait_for_data(DATA_PRODUCER_PIPE_INDEX);
#if !defined(CONFIG_SYS_DCACHE_OFF)
				flush_cache((unsigned long)buffer,
					    (unsigned long)bytes);
#endif
				num_desc = 0;
				rx_bytes_rcvd += data_xfer_size;
				buffer = buffer + data_xfer_size;
				bytes = rem_bytes;
				prod_desc_cnt--;
				if (prod_desc_cnt == 0)
					prod_desc_cnt = SPI_BAM_MAX_DESC_NUM - 1;
			}
		}
		state_config = config_spi_state(ds, SPI_RESET_STATE);
		if (state_config)
		return state_config;
	}

	return ret;
}

/*
 * Function to read bytes number of data from the Input FIFO
 */
static int __blsp_spi_read(struct ipq_spi_slave *ds, u8 *data_buffer,
				unsigned int bytes)
{
	uint32_t val;
	unsigned int i;
	unsigned int read_bytes = bytes;
	unsigned int fifo_count;
	int ret = SUCCESS;
	int state_config;


	/* Configure no of bytes to read */
	state_config = config_spi_state(ds, SPI_RESET_STATE);
	if (state_config)
		return state_config;

	/* Configure input and output enable */
	enable_io_config(ds, 0, read_bytes);

	if (!(ds->use_dma))
		writel(bytes, ds->regs->qup_mx_input_count);

	if (ds->use_dma && read_bytes)
		blsp_spi_bam_begin_xfer(ds, data_buffer,
			bytes, READ);
	else {
		state_config = config_spi_state(ds, SPI_RUN_STATE);
		if (state_config)
			return state_config;

		while (read_bytes) {
			ret = check_fifo_status(ds->regs->qup_operational);
			if (ret != SUCCESS)
				goto out;

			val = readl(ds->regs->qup_operational);
			if (val & INPUT_SERVICE_FLAG) {
				/*
				 * acknowledge to hw that software will
				 * read input data
				 */
				val &= INPUT_SERVICE_FLAG;
				writel(val, ds->regs->qup_operational);

				fifo_count = ((read_bytes > SPI_INPUT_BLOCK_SIZE) ?
						SPI_INPUT_BLOCK_SIZE : read_bytes);

				for (i = 0; i < fifo_count; i++) {
					*data_buffer = spi_read_byte(ds);
					data_buffer++;
					read_bytes--;
				}
			}
		}
	}
out:
	/*
	 * Put the SPI Core back in the Reset State
	 * to end the transfer
	 */
	(void)config_spi_state(ds, SPI_RESET_STATE);

	return ret;

}

static int blsp_spi_read(struct ipq_spi_slave *ds, u8 *data_buffer,
				unsigned int bytes)
{
	int length, ret;

	if (!(ds->use_dma)) {
		while (bytes) {
			length = (bytes < MAX_COUNT_SIZE) ? bytes : MAX_COUNT_SIZE;

			ret = __blsp_spi_read(ds, data_buffer, length);
			if (ret != SUCCESS)
				return ret;

			data_buffer += length;
			bytes -= length;
		}
	} else {
		ret = __blsp_spi_read(ds, data_buffer, bytes);
		if (ret != SUCCESS)
			return ret;
	}
	return 0;
}

/*
 * Function to write data to the Output FIFO
 */
static int __blsp_spi_write(struct ipq_spi_slave *ds, const u8 *cmd_buffer,
				unsigned int bytes)
{
	uint32_t val;
	unsigned int i;
	unsigned int write_len = bytes;
	unsigned int read_len = bytes;
	unsigned int fifo_count;
	int ret = SUCCESS;
	int state_config;

	state_config = config_spi_state(ds, SPI_RESET_STATE);
	if (state_config)
		return state_config;

	if (ds->use_dma) {
	/* No of bytes to be written in Output FIFO */
		writel(0, ds->regs->qup_mx_read_count);
		writel(0, ds->regs->qup_mx_write_count);
		writel(0, ds->regs->qup_mx_output_count);
		writel(0, ds->regs->qup_mx_input_count);
	}
	else {
		writel(bytes, ds->regs->qup_mx_output_count);
		writel(bytes, ds->regs->qup_mx_input_count);
		state_config = config_spi_state(ds, SPI_RUN_STATE);
		if (state_config)
			return state_config;
	}

	/* Configure input and output enable */
	if (!(ds->use_dma)) {
		enable_io_config(ds, write_len, read_len);
	} else {
		enable_io_config(ds, write_len, 0);
	}

	if (ds->use_dma && write_len)
		blsp_spi_bam_begin_xfer(ds, cmd_buffer,
							    bytes, WRITE);

	else {
		/*
		 * read_len considered to ensure that we read the dummy data for the
		 * write we performed. This is needed to ensure with WR-RD transaction
		 * to get the actual data on the subsequent read cycle that happens
		 */
		while (write_len || read_len) {
			ret = check_fifo_status(ds->regs->qup_operational);
			if (ret != SUCCESS)
				goto out;

			val = readl(ds->regs->qup_operational);
			if (val & OUTPUT_SERVICE_FLAG) {
				/*
				 * acknowledge to hw that software will write
				 * expected output data
				 */
				val &= OUTPUT_SERVICE_FLAG;
				writel(val, ds->regs->qup_operational);

				if (write_len > SPI_OUTPUT_BLOCK_SIZE)
					fifo_count = SPI_OUTPUT_BLOCK_SIZE;
				else
					fifo_count = write_len;

				for (i = 0; i < fifo_count; i++) {
					/* Write actual data to output FIFO */
					spi_write_byte(ds, *cmd_buffer);
					cmd_buffer++;
					write_len--;
				}
			}
			if (val & INPUT_SERVICE_FLAG) {
				/*
				 * acknowledge to hw that software
				 * will read input data
				 */
				val &= INPUT_SERVICE_FLAG;
				writel(val, ds->regs->qup_operational);

				if (read_len > SPI_INPUT_BLOCK_SIZE)
					fifo_count = SPI_INPUT_BLOCK_SIZE;
				else
					fifo_count = read_len;

				for (i = 0; i < fifo_count; i++) {
					/* Read dummy data for the data written */
					(void)spi_read_byte(ds);

					/* Decrement the write count after reading the
					 * dummy data from the device. This is to make
					 * sure we read dummy data before we write the
					 * data to fifo
					 */
					read_len--;
				}
			}
		}

	}
out:
	/*
	 * Put the SPI Core back in the Reset State
	 * to end the transfer
	 */
	(void)config_spi_state(ds, SPI_RESET_STATE);

	return ret;
}

static int blsp_spi_write(struct ipq_spi_slave *ds, const u8 *cmd_buffer,
                                unsigned int bytes)
{
	int length, ret;

	if (!(ds->use_dma)) {
		while (bytes) {
			length = (bytes < MAX_COUNT_SIZE) ? bytes : MAX_COUNT_SIZE;

			ret = __blsp_spi_write(ds, cmd_buffer, length);
			if (ret != SUCCESS)
				return ret;

			cmd_buffer += length;
			bytes -= length;
		}
	} else {
		ret = __blsp_spi_write(ds, cmd_buffer, bytes);
		if (ret != SUCCESS)
			return ret;
	}

	return 0;
}
/*
 * This function is invoked with either tx_buf or rx_buf.
 * Calling this function with both null does a chip select change.
 */
int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
		const void *dout, void *din, unsigned long flags)
{
	struct ipq_spi_slave *ds = to_ipq_spi(slave);
	unsigned int len;
	const u8 *txp = dout;
	u8 *rxp = din;
	int ret = SUCCESS;

	if (bitlen & SPI_BITLEN_MSK) {
		printf("err : Invalid bit length");
		return -EINVAL;
	}

	len = bitlen >> 3;

	if (flags & SPI_XFER_BEGIN) {
		if (!(ds->use_dma)) {
			ret = spi_hw_init(ds);
			if (ret != SUCCESS)
				return ret;
		}

		if (ds->slave.cs == 1 &&
			cs_is_valid(ds->slave.bus, ds->slave.cs)) {
			/* SPI NAND CS Settings */
			setbits_le32(ds->regs->io_control, CS_POLARITY_MASK);
			CS_change(ds->slave.bus, ds->slave.cs, CS_ASSERT);
		} else {
			write_force_cs(slave, 1);
		}
	}

	if (dout != NULL) {
		ret = blsp_spi_write(ds, txp, len);
		if (ret != SUCCESS)
			return ret;
	}

	if (din != NULL) {
		ret = blsp_spi_read(ds, rxp, len);
		if (ret != SUCCESS)
		return ret;
	}

	if (flags & SPI_XFER_END) {
		if (ds->slave.cs == 1 &&
			cs_is_valid(ds->slave.bus, ds->slave.cs)) {
			/* SPI NAND CS Settings */
			clrbits_le32(ds->regs->io_control, CS_POLARITY_MASK);
			CS_change(ds->slave.bus, ds->slave.cs, CS_DEASSERT);
		} else {
			write_force_cs(slave, 0);
		}
	}

	return ret;
}

int spi_cs_is_valid(unsigned int bus, unsigned int cs)
{
	return 1;
}

void spi_cs_activate(struct spi_slave *slave)
{

}

void spi_cs_deactivate(struct spi_slave *slave)
{

}
