/*
 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <bouncebuf.h>
#include <common.h>
#include <malloc.h>
#include <nand.h>
#include <asm/io.h>

#define BUS_WIDTH	8		/* AXI data bus width in bytes	*/

/* DMA buffer descriptor bits & masks */
#define BD_STAT_OWN			(1 << 31)
#define BD_STAT_BD_FIRST		(1 << 3)
#define BD_STAT_BD_LAST			(1 << 2)
#define BD_SIZES_BUFFER1_MASK		0xfff

#define BD_STAT_BD_COMPLETE	(BD_STAT_BD_FIRST | BD_STAT_BD_LAST)

/* Controller command flags */
#define B_WFR		(1 << 19)	/* 1b - Wait for ready		*/
#define B_LC		(1 << 18)	/* 1b - Last cycle		*/
#define B_IWC		(1 << 13)	/* 1b - Interrupt when complete	*/

/* NAND cycle types */
#define B_CT_ADDRESS	(0x0 << 16)	/* Address operation		*/
#define B_CT_COMMAND	(0x1 << 16)	/* Command operation		*/
#define B_CT_WRITE	(0x2 << 16)	/* Write operation		*/
#define B_CT_READ	(0x3 << 16)	/* Write operation		*/

enum nand_isr_t {
	NAND_ISR_DATAREQUIRED = 0,
	NAND_ISR_TXUNDERFLOW,
	NAND_ISR_TXOVERFLOW,
	NAND_ISR_DATAAVAILABLE,
	NAND_ISR_RXUNDERFLOW,
	NAND_ISR_RXOVERFLOW,
	NAND_ISR_TXDMACOMPLETE,
	NAND_ISR_RXDMACOMPLETE,
	NAND_ISR_DESCRIPTORUNAVAILABLE,
	NAND_ISR_CMDDONE,
	NAND_ISR_CMDAVAILABLE,
	NAND_ISR_CMDERROR,
	NAND_ISR_DATATRANSFEROVER,
	NAND_ISR_NONE
};

enum nand_regs_t {
	AC_FIFO = 0,		/* address and command fifo */
	IDMAC_BDADDR = 0x18,	/* idmac descriptor list base address */
	INT_STATUS = 0x118,	/* interrupt status register */
	INT_CLR_STATUS = 0x120,	/* interrupt clear status register */
};

struct nand_bd {
	uint32_t status;	/* DES0 */
	uint32_t sizes;		/* DES1 */
	uint32_t buffer_ptr0;	/* DES2 */
	uint32_t buffer_ptr1;	/* DES3 */
};

#define NAND_REG_WRITE(r, v)	writel(v, CONFIG_SYS_NAND_BASE + r)
#define NAND_REG_READ(r)	readl(CONFIG_SYS_NAND_BASE + r)

static struct nand_bd *bd;	/* DMA buffer descriptors	*/

/**
 * axs101_nand_write_buf -  write buffer to chip
 * @mtd:	MTD device structure
 * @buf:	data buffer
 * @len:	number of bytes to write
 */
static uint32_t nand_flag_is_set(uint32_t flag)
{
	uint32_t reg = NAND_REG_READ(INT_STATUS);

	if (reg & (1 << NAND_ISR_CMDERROR))
		return 0;

	if (reg & (1 << flag)) {
		NAND_REG_WRITE(INT_CLR_STATUS, 1 << flag);
		return 1;
	}

	return 0;
}

/**
 * axs101_nand_write_buf -  write buffer to chip
 * @mtd:	MTD device structure
 * @buf:	data buffer
 * @len:	number of bytes to write
 */
static void axs101_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
				   int len)
{
	struct bounce_buffer bbstate;

	bounce_buffer_start(&bbstate, (void *)buf, len, GEN_BB_READ);

	/* Setup buffer descriptor */
	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
	writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
	writel(0, &bd->buffer_ptr1);

	/* Flush modified buffer descriptor */
	flush_dcache_range((unsigned long)bd,
			   (unsigned long)bd + sizeof(struct nand_bd));

	/* Issue "write" command */
	NAND_REG_WRITE(AC_FIFO, B_CT_WRITE | B_WFR | B_IWC | B_LC | (len-1));

	/* Wait for NAND command and DMA to complete */
	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
		;
	while (!nand_flag_is_set(NAND_ISR_TXDMACOMPLETE))
		;

	bounce_buffer_stop(&bbstate);
}

/**
 * axs101_nand_read_buf -  read chip data into buffer
 * @mtd:	MTD device structure
 * @buf:	buffer to store data
 * @len:	number of bytes to read
 */
static void axs101_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{
	struct bounce_buffer bbstate;

	bounce_buffer_start(&bbstate, buf, len, GEN_BB_WRITE);

	/* Setup buffer descriptor */
	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status);
	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes);
	writel(bbstate.bounce_buffer, &bd->buffer_ptr0);
	writel(0, &bd->buffer_ptr1);

	/* Flush modified buffer descriptor */
	flush_dcache_range((unsigned long)bd,
			   (unsigned long)bd + sizeof(struct nand_bd));

	/* Issue "read" command */
	NAND_REG_WRITE(AC_FIFO, B_CT_READ | B_WFR | B_IWC | B_LC | (len - 1));

	/* Wait for NAND command and DMA to complete */
	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
		;
	while (!nand_flag_is_set(NAND_ISR_RXDMACOMPLETE))
		;

	bounce_buffer_stop(&bbstate);
}

/**
 * axs101_nand_read_byte -  read one byte from the chip
 * @mtd:	MTD device structure
 */
static u_char axs101_nand_read_byte(struct mtd_info *mtd)
{
	u8 byte;

	axs101_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte));
	return byte;
}

/**
 * axs101_nand_read_word -  read one word from the chip
 * @mtd:	MTD device structure
 */
static u16 axs101_nand_read_word(struct mtd_info *mtd)
{
	u16 word;

	axs101_nand_read_buf(mtd, (uchar *)&word, sizeof(word));
	return word;
}

/**
 * axs101_nand_hwcontrol - NAND control functions wrapper.
 * @mtd:	MTD device structure
 * @cmd:	Command
 */
static void axs101_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd,
				   unsigned int ctrl)
{
	if (cmd == NAND_CMD_NONE)
		return;

	cmd = cmd & 0xff;

	switch (ctrl & (NAND_ALE | NAND_CLE)) {
	/* Address */
	case NAND_ALE:
		cmd |= B_CT_ADDRESS;
		break;

	/* Command */
	case NAND_CLE:
		cmd |= B_CT_COMMAND | B_WFR;

		break;

	default:
		debug("%s: unknown ctrl %#x\n", __func__, ctrl);
	}

	NAND_REG_WRITE(AC_FIFO, cmd | B_LC);
	while (!nand_flag_is_set(NAND_ISR_CMDDONE))
		;
}

int board_nand_init(struct nand_chip *nand)
{
	bd = (struct nand_bd *)memalign(ARCH_DMA_MINALIGN,
					sizeof(struct nand_bd));

	/* Set buffer descriptor address in IDMAC */
	NAND_REG_WRITE(IDMAC_BDADDR, bd);

	nand->ecc.mode = NAND_ECC_SOFT;
	nand->cmd_ctrl = axs101_nand_hwcontrol;
	nand->read_byte = axs101_nand_read_byte;
	nand->read_word = axs101_nand_read_word;
	nand->write_buf = axs101_nand_write_buf;
	nand->read_buf = axs101_nand_read_buf;

	return 0;
}
