/*
 * 49lfxxxc.c: driver for SST49LFXXXC flash models.
 *
 *
 * Copyright 2000 Silicon Integrated System Corporation
 * Copyright 2005 coresystems GmbH <stepan@openbios.org>
 *
 *	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 program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 * Reference:
 *	SST49LFxxxC data sheets
 *
 */

#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include "flash.h"
#include "jedec.h"
#include "debug.h"

#define SECTOR_ERASE		0x30
#define BLOCK_ERASE		0x20
#define ERASE			0xD0
#define AUTO_PGRM		0x10
#define RESET			0xFF
#define READ_ID			0x90
#define READ_STATUS		0x70
#define CLEAR_STATUS		0x50

#define STATUS_BPS		(1 << 1)
#define	STATUS_ESS		(1 << 6)
#define	STATUS_WSMS		(1 << 7)


static __inline__ int write_lockbits_49lfxxxc(volatile uint8_t *bios, int size,
					    unsigned char bits)
{
	int i, left = size;
	unsigned long address;

	//printf("bios=0x%08lx\n", (unsigned long)bios);
	for (i = 0; left > 65536; i++, left -= 65536) {
		//printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFC00000 - size + (i * 65536) + 2, *(bios + (i * 65536) + 2) );
		*(bios + (i * 65536) + 2) = bits;
	}
	address = i * 65536;
		//printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
	*(bios + address + 2) = bits;
	address += 32768;
		//printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
	*(bios + address + 2) = bits;
	address += 8192;
		//printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
	*(bios + address + 2) = bits;
	address += 8192;
		//printf("lockbits at address=0x%08lx is 0x%01x\n", (unsigned long)0xFFc00000 - size + address + 2, *(bios + address + 2) );
	*(bios + address + 2) = bits;


	return (0);
}

static __inline__ int erase_sector_49lfxxxc(volatile uint8_t *bios,
					   unsigned long address)
{
	unsigned char status;

	*bios = SECTOR_ERASE;
	*(bios + address) = ERASE;

	do {
    		status = *bios;
		if (status & (STATUS_ESS | STATUS_BPS)) {
			printf("sector erase FAILED at address=0x%08lx status=0x%01x\n", (unsigned long)bios + address, status); 
			*bios = CLEAR_STATUS;
			return(-1);
		}
        } while (!(status & STATUS_WSMS));

	return (0);
}

static __inline__ int write_sector_49lfxxxc(volatile uint8_t *bios,
					   uint8_t *src,
					   volatile uint8_t *dst,
					   unsigned int page_size)
{
	int i;
	unsigned char status;

	*bios = CLEAR_STATUS;
	for (i = 0; i < page_size; i++) {
		/* transfer data from source to destination */
		if (*src == 0xFF) {
			dst++, src++;
			/* If the data is 0xFF, don't program it */
			continue;
		}
		/*issue AUTO PROGRAM command */
		*bios = AUTO_PGRM;
		*dst++ = *src++;

		do {
			status = *bios;
			if (status & (STATUS_ESS | STATUS_BPS)) {
				printf("sector write FAILED at address=0x%08lx status=0x%01x\n", (unsigned long)dst, status); 
				*bios = CLEAR_STATUS;
				return(-1);
			}
		} while (!(status & STATUS_WSMS));
	}

	return (0);
}

int probe_49lfxxxc(struct flashchip *flash)
{
	volatile uint8_t *bios = flash->virt_addr;
	uint8_t id1, id2;
	size_t size = flash->total_size * 1024;

	*bios = RESET;

	*bios = READ_ID;
	id1 = *(volatile uint8_t *) bios;
	id2 = *(volatile uint8_t *) (bios + 0x01);

	*bios = RESET;

	printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, id1, id2);
	if (!(id1 == flash->manufacture_id && id2 == flash->model_id))
		return 0;

	bios = mmap(0, size, PROT_WRITE | PROT_READ, MAP_SHARED,
		    flash->fd_mem, (off_t) (0xFFFFFFFF - 0x400000 - size + 1));
	if (bios == MAP_FAILED) {
		// it's this part but we can't map it ...
		perror("Error MMAP /dev/mem");
		exit(1);
	}
	flash->virt_addr_2 = bios;
	return 1;
}

int erase_49lfxxxc(struct flashchip *flash)
{
	volatile uint8_t *bios = flash->virt_addr;
	volatile uint8_t *bios2 = flash->virt_addr_2;
	int i;
	unsigned int total_size = flash->total_size * 1024;

	write_lockbits_49lfxxxc(bios2, total_size, 0);
	for (i = 0; i < total_size; i += flash->page_size)
		if (erase_sector_49lfxxxc(bios, i) != 0 )
		    return (-1);

	*bios = RESET;
	return (0);
}

int write_49lfxxxc(struct flashchip *flash, uint8_t *buf)
{
	int i;
	int total_size = flash->total_size * 1024, page_size =
	    flash->page_size;
	volatile uint8_t *bios = flash->virt_addr;


	write_lockbits_49lfxxxc(flash->virt_addr_2, total_size, 0);
	printf("Programming Page: ");
	for (i = 0; i < total_size / page_size; i++) {
		/* erase the page before programming */
		erase_sector_49lfxxxc(bios, i * page_size);

		/* write to the sector */
		printf("%04d at address: 0x%08x", i, i * page_size);
		write_sector_49lfxxxc(bios, buf + i * page_size,
				     bios + i * page_size, page_size);
		printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
	}
	printf("\n");

	*bios = RESET;
	return (0);
}
