/*
 *  Copyright (c) 2013 Qualcomm Atheros, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 */

/*
 * This file contains glue for Atheros ath spi flash interface
 * Primitives are ath_spi_*
 * mtd flash implements are ath_flash_*
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <asm/div64.h>

#include <atheros.h>
#include "ath_flash.h"

/* Legacy flash driver only supports 16M */
#define LEGACY_SPI_ADDR_BOUNDARY 0x1000000

static void ath_spi_wrear(uint32_t data);
static u_char ath_spi_rdear(void);

static int write_buff_ext(struct mtd_info *info, u_char *src,
				loff_t offset, size_t cnt, size_t *retlen);
static int read_buff_ext(struct mtd_info *info, u_char *buf,
				loff_t offset, size_t cnt, size_t *retlen);

/* this is passed in as a boot parameter by bootloader */
extern int __ath_flash_size;

/*
 * statics
 */
static void ath_spi_write_enable(void);
static void ath_spi_poll(void);
#if !defined(ATH_SST_FLASH)
static void ath_spi_write_page(uint32_t addr, uint8_t * data, int len);
#endif
static void ath_spi_sector_erase(uint32_t addr);

static const char *part_probes[] __initdata = { "cmdlinepart", "RedBoot", NULL };

#define ATH_FLASH_SIZE_2MB          (2*1024*1024)
#define ATH_FLASH_SIZE_4MB          (4*1024*1024)
#define ATH_FLASH_SIZE_8MB          (8*1024*1024)
#define ATH_FLASH_SIZE_32MB         (32*1024*1024)
#define ATH_FLASH_SECTOR_SIZE_64KB  (64*1024)
#define ATH_FLASH_PG_SIZE_256B       256
#define ATH_FLASH_NAME               "ath-nor0"
/*
 * bank geometry
 */
typedef struct ath_flash_geom {
	uint32_t size;
	uint32_t sector_size;
	uint32_t nsectors;
	uint32_t pgsize;
} ath_flash_geom_t;

ath_flash_geom_t flash_geom_tbl[ATH_FLASH_MAX_BANKS] = {
	{
		.size		= ATH_FLASH_SIZE_32MB,
		.sector_size	= ATH_FLASH_SECTOR_SIZE_64KB,
		.pgsize		= ATH_FLASH_PG_SIZE_256B
	}
};

static int
ath_flash_probe(void)
{
	return 0;
}

#if defined(ATH_SST_FLASH)
void
ath_spi_flash_unblock(void)
{
	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_WRITE_SR);
	ath_spi_bit_banger(0x0);
	ath_spi_go();
	ath_spi_poll();
}
#endif

static int
ath_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
{
	int nsect, s_curr, s_last;
	uint64_t  res;

	if (instr->addr + instr->len > mtd->size)
		return (-EINVAL);

	ath_mn_spi_enable_flash_cs();

	res = instr->len;
	do_div(res, mtd->erasesize);
	nsect = res;

	if (((uint32_t)instr->len) % mtd->erasesize)
		nsect ++;

	res = instr->addr;
	do_div(res,mtd->erasesize);
	s_curr = res;

	s_last  = s_curr + nsect;

	do {
		ath_spi_sector_erase(s_curr * ATH_SPI_SECTOR_SIZE);
	} while (++s_curr < s_last);

	ath_spi_done();

	ath_mn_spi_disable_cs();

	if (instr->callback) {
		instr->state |= MTD_ERASE_DONE;
		instr->callback(instr);
	}

	return 0;
}

static int
read_buff_under16m(struct mtd_info *mtd, loff_t from, size_t len,
		size_t *retlen, u_char *buf)
{
	size_t i;
	if (len == 0) {
		return 0;
	}
	if (from + len > mtd->size) {
		return (-EINVAL);
	}

	ath_mn_spi_enable_flash_cs();

	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_READ);
	ath_spi_send_addr((uint32_t) from);
	for (i = 0; i < len; ++i) {
		ath_spi_delay_8();
		buf[i] = (u_char) ath_reg_rd(ATH_SPI_RD_STATUS);
	}
	ath_spi_go();
	ath_spi_done();

	ath_mn_spi_disable_cs();

	*retlen = len;
	return 0;
}

#if defined(ATH_SST_FLASH)
static int
write_buff_under16m(struct mtd_info *mtd, loff_t dst, size_t len,
		   size_t * retlen, const u_char * src)
{
	uint32_t val;

	//printk("write len: %lu dst: 0x%x src: %p\n", len, dst, src);

	*retlen = len;

	for (; len; len--, dst++, src++) {
		ath_spi_write_enable();	// dont move this above 'for'
		ath_spi_bit_banger(ATH_SPI_CMD_PAGE_PROG);
		ath_spi_send_addr(dst);

		val = *src & 0xff;
		ath_spi_bit_banger(val);

		// Back ported bug fix, always write CE_LOW, CS_DIS before poll.
		ath_spi_go();
		ath_spi_poll();
	}
	/*
	 * Disable the Function Select
	 * Without this we can't re-read the written data
	 */
	ath_reg_wr(ATH_SPI_FS, 0);

	if (len) {
		*retlen -= len;
		return -EIO;
	}
	return 0;
}
#else
static int
write_buff_under16m(struct mtd_info *mtd, loff_t to, size_t len,
		   size_t *retlen, const u_char *buf)
{
	int total = 0, len_this_lp, bytes_this_page;
	uint32_t addr = 0;
	u_char *mem;

	ath_mn_spi_enable_flash_cs();

	while (total < len) {
		mem = (u_char *) (buf + total);
		addr = to + total;
		bytes_this_page =
		    ATH_SPI_PAGE_SIZE - (addr % ATH_SPI_PAGE_SIZE);
		len_this_lp = min(((int)len - total), bytes_this_page);

		ath_spi_write_page(addr, mem, len_this_lp);
		total += len_this_lp;
	}

	ath_spi_done();

	ath_mn_spi_disable_cs();

	*retlen = len;
	return 0;
}
#endif

#ifdef ATH_SST_FLASH
static void
ath_spi_flash_chip_erase(void)
{
	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_CHIP_ERASE);
	ath_spi_go();
	ath_spi_poll();
}

static int
ath_write_buff(flash_info_t *info, uchar *src, ulong dst, ulong len)
{
	uint32_t val;

	for (; len; len--, dst++, src++) {
		ath_spi_write_enable(); // dont move this above 'for'
		ath_spi_bit_banger(ATH_SPI_CMD_PAGE_PROG);
		ath_spi_send_addr(dst);

		val = *src & 0xff;
		ath_spi_bit_banger(val);

		ath_spi_go();
		ath_spi_poll();
	}
	/*
	 * Disable the Function Select
	 * Without this we can't read from the chip again
	 */
	ath_reg_wr(ATH_SPI_FS, 0);

	if (len) {
		// how to differentiate errors ??
		return ERR_PROG_ERROR;
	} else {
		return ERR_OK;
	}
}
#else
static int
ath_write_buff(struct mtd_info *info, u_char *source, loff_t addr, size_t len)
{
	int total = 0, len_this_lp, bytes_this_page;
	ulong dst;
	u_char *src;

	while (total < len) {
		src = source + total;
		dst = addr + total;
		bytes_this_page = ATH_SPI_PAGE_SIZE - (addr % ATH_SPI_PAGE_SIZE);
		len_this_lp = ((len - total) > bytes_this_page) ?
				bytes_this_page : (len - total);
		ath_spi_write_page(dst, src, len_this_lp);
		total += len_this_lp;
	}

	ath_spi_done();

	return 0;
}
#endif

static int ath_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
				size_t *retlen, u_char *buf)
{
	if (from >= LEGACY_SPI_ADDR_BOUNDARY) {
		return read_buff_ext (mtd, buf, from, len, retlen);
	} else {
		return read_buff_under16m(mtd, from, len, retlen, buf);
	}
}

static int ath_flash_write(struct mtd_info *mtd, loff_t dst, size_t len,
				size_t * retlen, const u_char * src) {
	if (dst >= LEGACY_SPI_ADDR_BOUNDARY) {
		return write_buff_ext (mtd, src, dst, len, retlen);
	} else {
		return write_buff_under16m(mtd, dst, len, retlen, src);
	}
}

/*
 * sets up flash_info and returns size of FLASH (bytes)
 */
static int __init ath_flash_init(void)
{
	int i, np;
	ath_flash_geom_t *geom;
	struct mtd_info *mtd;
	struct mtd_partition *mtd_parts;
	uint8_t index;

#if !(defined(CONFIG_MACH_AR934x) || defined(CONFIG_MACH_QCA955x) || defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x))
#if defined(ATH_SST_FLASH)
	ath_reg_wr_nf(ATH_SPI_CLOCK, 0x3);
	ath_spi_flash_unblock();
	ath_reg_wr(ATH_SPI_FS, 0);
#else
	ath_reg_wr_nf(ATH_SPI_CLOCK, 0x43);
#endif
#endif
	for (i = 0; i < ATH_FLASH_MAX_BANKS; i++) {

		index = ath_flash_probe();
		geom = &flash_geom_tbl[index];

		/* set flash size to value from bootloader if it passed valid value */
		/* otherwise use the default 4MB.                                   */
		if (__ath_flash_size >= 4 && __ath_flash_size <= 16)
			geom->size = __ath_flash_size * 1024 * 1024;

		mtd = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
		if (!mtd) {
			printk("Cant allocate mtd stuff\n");
			return -1;
		}
		memset(mtd, 0, sizeof(struct mtd_info));

		mtd->name		= ATH_FLASH_NAME;
		mtd->type		= MTD_NORFLASH;
		mtd->flags		= MTD_CAP_NORFLASH | MTD_WRITEABLE;
		mtd->size		= geom->size;
		mtd->erasesize		= geom->sector_size;
		mtd->numeraseregions	= 0;
		mtd->eraseregions	= NULL;
		mtd->owner		= THIS_MODULE;
		mtd->erase		= ath_flash_erase;
		mtd->read		= ath_flash_read;
		mtd->write		= ath_flash_write;
		mtd->writesize		= 1;

		np = parse_mtd_partitions(mtd, part_probes, &mtd_parts, 0);
		if (np > 0) {
			add_mtd_partitions(mtd, mtd_parts, np);
		} else {
			printk("No partitions found on flash bank %d\n", i);
		}
	}

        /* Sanity check for module load order. */
        printk(KERN_NOTICE "ath_flash driver initialized.");
	return 0;
}

static void __exit ath_flash_exit(void)
{
	/*
	 * nothing to do
	 */
}

/*
 * Primitives to implement flash operations
 */
static void
ath_spi_write_enable()
{
	ath_reg_wr_nf(ATH_SPI_FS, 1);
	ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_DIS);
	ath_spi_bit_banger(ATH_SPI_CMD_WREN);
	ath_spi_go();
}

static void
ath_spi_poll()
{
	int rd;

	do {
		ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_DIS);
		ath_spi_bit_banger(ATH_SPI_CMD_RD_STATUS);
		ath_spi_delay_8();
		ath_spi_go();
		rd = (ath_reg_rd(ATH_SPI_RD_STATUS) & 1);
	} while (rd);
}

static void
ath_spi_write_page(uint32_t addr, uint8_t *data, int len)
{
	int i;
	uint8_t ch;

	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_PAGE_PROG);
	ath_spi_send_addr(addr);

	for (i = 0; i < len; i++) {
		ch = *(data + i);
		ath_spi_bit_banger(ch);
	}

	ath_spi_go();
	ath_spi_poll();
}

static void
ath_spi_sector_erase(uint32_t addr)
{
	uint32_t ori_ear = (uint32_t) ath_spi_rdear();
	uint32_t new_ear = addr >> 24;

	if (new_ear != ori_ear)
		ath_spi_wrear(new_ear);

	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_SECTOR_ERASE);
	ath_spi_send_addr(addr);
	ath_spi_go();
#if 0
	/*
	 * Do not touch the GPIO's unnecessarily. Might conflict
	 * with customer's settings.
	 */
	display(0x7d);
#endif
	ath_spi_poll();

	/* recover extended address register */
	if (new_ear != ori_ear)
		ath_spi_wrear(ori_ear);
}

/* 32M extension */

static void ath_spi_wrear(uint32_t data)
{
	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_WREAR);
	ath_spi_bit_banger((u_char)data);
	ath_spi_go();

	ath_spi_poll();
}

static u_char ath_spi_rdear(void)
{
	u_char data;

	ath_spi_write_enable();
	ath_spi_bit_banger(ATH_SPI_CMD_RDEAR);
	ath_spi_delay_8();
	ath_spi_go();
	data = (u_char)(ath_reg_rd(ATH_SPI_RD_STATUS));
	ath_spi_poll();
	return(data);
}

static int
read_buff_ext(struct mtd_info *info, u_char *buf, loff_t offset, size_t len, size_t *retlen)
{
	size_t i = 0;
	uint32_t curr_addr = offset;
	uint32_t ori_ear = (uint32_t)ath_spi_rdear();
	uint32_t new_ear;

	while (i < len) {
		new_ear = curr_addr >> 24;
		ath_spi_wrear(new_ear);
		ath_spi_write_enable();
		ath_spi_bit_banger(ATH_SPI_CMD_READ);
		ath_spi_send_addr(curr_addr);
		do{
			ath_spi_delay_8();
			*(buf + i++) = (u_char)(ath_reg_rd(ATH_SPI_RD_STATUS));
			/* update the extended adress update if it's a multiple of 16M */
			if(!((++ curr_addr) & (LEGACY_SPI_ADDR_BOUNDARY - 1))) {
				break;
			}
		} while(i < len);
		ath_spi_go();
	}
	if (new_ear != ori_ear) {
		ath_spi_wrear(ori_ear);
	}
	ath_spi_done();
	*retlen = i;
	return 0;
}

static int
write_buff_ext(struct mtd_info *info, u_char *source, loff_t offset, size_t len, size_t *retlen)
{
	int      status;
	uint32_t ori_ear = (uint32_t)ath_spi_rdear();
	uint32_t new_ear = 0;
	uint32_t curr_addr = offset;
	uint32_t bytes_this_16M, total = 0;
	*retlen = len;

	while (len) {
		size_t tmp;
		new_ear = curr_addr >> 24;
		ath_spi_wrear(new_ear);
		bytes_this_16M = LEGACY_SPI_ADDR_BOUNDARY - curr_addr % LEGACY_SPI_ADDR_BOUNDARY;
		bytes_this_16M = (bytes_this_16M < len) ? bytes_this_16M : len;
		if((status = ath_write_buff(info, source + total, curr_addr, bytes_this_16M))
			!= 0) {
			printk(KERN_CRIT"failed to write 0x%x bytes to 0x%x\n", bytes_this_16M,
				curr_addr);
			break;
		}
		curr_addr += bytes_this_16M;
		total += bytes_this_16M;
		len -= bytes_this_16M;
	}
	if (new_ear != ori_ear) {
		ath_spi_wrear(ori_ear);
	}
	ath_spi_done();

	*retlen -= len;

	return(status);
}

module_init(ath_flash_init);
module_exit(ath_flash_exit);
