/*********************************************************************
 *          (C) COPYRIGHT TEXAS INSTRUMENTS, INC. 2000, 2001
 * flash.c -- Flash Memory handlers for dsk 5510
 */

/* Change Log:
 */
/*
 * $Log: /boards/dsk5509a/flashburn/FBTC55/flash.c $
 * 
 * 1     11/10/05 12:58p Shilpab
 * Revision 1.3  2001/06/27 17:55:14  heeschen
 * v00.32 Beta Prep
 * Capturing all files to prepare for Beta Release
 *
 * Revision 1.2  2001/04/19 18:56:50  heeschen
 * v00.30 Alpha - Updated comments
 *
 *
 */

#include  "flash.h"

#define	FCP5			(FLASH_BASE_ADDR+(0x555ul))		//flash command port 5
#define	FCPA			(FLASH_BASE_ADDR+(0x2aaul))		//flash command port A
#define	FCW5			0x55u
#define	FCWA			0xAAu
#define	FWORDWRITE		0xA0u
#define	FRESET			0xF0u
#define	FCHIPERASE0		0x80u
#define	FCHIPERASE1		0x10u
#define	FSECTORERASE0	0x80u
#define	FSECTORERASE1	0x30u
#define	FCHIPID			0x90u

#define	DQ7				(1u<<7)
#define	DQ6				(1u<<6)
#define	DQ5				(1u<<5)
#define	DQ3				(1u<<3)
#define	DQ2				(1u<<2)

#if(0)
static u32 fcwa[2] = {(FCWA & 0xffff0000), (FCWA & 0xffff)};
static u32 fcw5[2] = {(FCW5 & 0xffff0000), (FCW5 & 0xffff)};
static u32 fwordwrite[2] = {(FWORDWRITE & 0xffff0000), (FWORDWRITE & 0xffff)};
#endif

static int waitFor16bitCompletion(volatile u16 *s, u16 value);

/* Reset the Flash Memory. Places chip in read mode
 */ 
void flash_reset()
{
	/* 2 chips 16 bits wide: 32 bits.
	 */
	*(volatile u32 *)FLASH_BASE_ADDR = FRESET;
}


/* Writes length words from source to dest in flash.
 */
int flash_write(u16 *source, u16 *dest, u16 length)
{
	u16 *pdst = dest;
	u16 *psrc = source;
	u16	i,len = length;
    u16 j;
    volatile ioport u16 *pio;
    
    /* Enable EMIF */
    pio = (ioport u16 *)0x6c00;
    *pio = 1;
    
    /* Set CE1 up for 16-bit async Flash, max timings */
    pio = (ioport u16 *)0x802;
    *pio = 0xFF13;
    
    
	for(i = 0; i < len; i++) 
	{
		*(volatile u16 *)FCP5 = FCWA;
		
		*(volatile u16 *)FCPA = FCW5;
		
		*(volatile u16 *)FCP5 = FWORDWRITE;
		
		*pdst = *psrc;
		
        for (j = 0; j < 10; j++);
        
		while(1)
		    if (*pdst == *psrc)
		        break;
		
		if (waitFor16bitCompletion((volatile u16 *)pdst++, *psrc++) == ERROR) 
			return ERROR;
	}

	return OK;
}



/*****************************************************
 *  int chip_erase()
 *  
 *  This function commands an entire flash erasure
 *  returns immediately. Use checkFor32bitCompletion()
 *  to see when erasing is complete.
 *
 *  Parameters:
 *      none
 * 
 *  Return:
 *  - OK success
 *  - ERROR failure
 * 
 *  Notes:
 * 
 */
void chip_erase(void)
{
    volatile ioport u16 *pio;
    
    /* Enable EMIF */
    pio = (ioport u16 *)0x6c00;
    *pio = 1;
    
    /* Set CE1 up for 16-bit async Flash, max timings */
    pio = (ioport u16 *)0x802;
    *pio = 0xFF13;
    
	*(volatile u16 *)FCP5 = FCWA;
	*(volatile u16 *)FCPA = FCW5;
	*(volatile u16 *)FCP5 = FCHIPERASE0;

	*(volatile u16 *)FCP5 = FCWA;
	*(volatile u16 *)FCPA = FCW5;
	*(volatile u16 *)FCP5 = FCHIPERASE1;
			
	return;
}

/*************
 * Local Funcs
 *************
 */

/*  Waits for the flash operation to complete.
 *
 * s - pointer to location to compare to value
 * value - value to compare to data stored in location pointedt to by s
 * 
 *  Returns OK if success, else ERROR
 */ 

int waitFor16bitCompletion(volatile u16 *s, u16 value)
{
	while(1)
	{
		if ((*s & DQ7) == (value & DQ7))
			return OK;
		
		if (*s & DQ5)
		{
			return ((*s & DQ7) == (value & DQ7)) ? OK : ERROR;
		}
	}
}
