/*
 * FM3 On-Chip Flash memory lowlevel driver
 * Copyright (C) 2012 Yoshinori Sato <ysato@users.sourceforge.jp>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <flash.h>
#include <asm/io.h>

#define FASZR	0x40000000

int erase_sector_low(unsigned long addr) __attribute__((section(".ram_text")));
int write_sector_low(unsigned long addr, uchar *src, int size)
	__attribute__((section(".ram_text")));
int erase_sector_low(unsigned long addr)
{
	unsigned short status;
	int ret = ERR_OK;
	writeb(0x01, FASZR);
	writew(0x00aa, 0x00001550);
	writew(0x0055, 0x00000aa8);
	writew(0x0080, 0x00001550);
	writew(0x00aa, 0x00001550);
	writew(0x0055, 0x00000aa8);
	writew(0x0030, addr);
	readw(addr);
	while ((readw(addr) & 0x0008) == 0);
	while (((status = readw(addr)) & 0x0080) == 0) {
		if (status & 0x0020) {
			writew(0xf0, addr);
			ret = ERR_TIMOUT;
			break;
		}
	}
	writeb(0x02, FASZR);
	return ret;
}

int write_sector_low(unsigned long addr, uchar *src, int size)
{
	unsigned short *p = (unsigned short *)src;
	unsigned short status;
	int ret = ERR_OK;

	writeb(0x01, FASZR);
	for(; size > 0; p++, addr += 2, size -= 2) {
		if (*p == 0xffff)
			continue;
		writew(0x00aa, 0x00001550);
		writew(0x0055, 0x00000aa8);
		writew(0x00a0, 0x00001550);
		writew(*p, addr);
		readw(addr);
		while(((status = readw(addr)) ^ *p) & 0x0080) {
			if(status & 0x0020) {
				writew(0xf0, addr);
				ret = ERR_TIMOUT;
				goto done;
			}
		}
	}
done:
	writeb(0x02, FASZR);
	return ret;
}
