?? intel28f640_16x1.c
字號(hào):
/* intel28f640_16x1.c:
* Support for INTEL 28f640 or the 28f128 (double the size of the 640).
* Bank configuration is as a single 16-bit device.
*/
#include "config.h"
#if INCLUDE_FLASH
#ifdef PIF_FLASH
#include "endian.h"
#include "stddefs.h"
#include "genlib.h"
#include "cpu.h"
#include "flash.h"
#include "intel28f640_16x1.h"
//stone added
#include "Pif.h"
#include "risc.h"
#include "28F640J3.h"
//stone added end
#define FLASHCFG_16x1 1
#include "strata.h"
/* Manufacturer and device id... */
#define INTEL_DT28F128J5 0x00890018
#define INTEL_28F640 0x00890017
#define INTEL_DT28F640J5 0x00890015
#define ST_M58LW064D 0x00200017
/*
*************************************************************************************
* PifPCMCIAModeRegSet
*
* Description: Set rPIF_PCI_CTL.
*
* Arguments : mode can be the following values:
* PIF_BOOT_MODE;
* PIF_CBUS_MODE;
* PIF_DBUS_MODE
* mstr-bs It specifies the burst size on the memory bus for master
* transactions. can be:
* PCMCIA_MSTR_BS_8BYTE
* PCMCIA_MSTR_BS_16BYTE
* PCMCIA_MSTR_BS_32BYTE
* PCMCIA_MSTR_BS_64BYTE
*
* Return : none.
*
* Note(s) :
*************************************************************************************
*/
void PifPCMCIAModeRegSet(int mode, int mstr_bs)
{
rPIF_PCI_CTL = (mode<<26) | (mstr_bs<<21);
}
/*
*************************************************************************************
* PifTimingRegSet
*
* Description: Set rPIF_PCI_TIM.
*
* Arguments : setup controls the setup time from PCMCIA CS on to the
* OE/WE/IOWR/IORD strobe on. It’s the PIF clock cycles.
* hold controls the hold time from the OE/WE/IOWR/IORD strobe
* off to the CS.
* interval controls the interval of the OE/WE/IOWR/IORD on time.
* wait_cycle This field is useful when 'swait' bit is 1. It is the
* idle cycles between each access started from asserting CS.
* ioack_wait can be:
* PIF_WAIT_INPACK - wait for 'inpack' signal during IORD
* PIF_NO_WAIT - don’t care 'inpack' signal
* pimcia_width can be:
* PCMCIA_WIDTH_8BIT – PCMCIA data is 8 bit wide
* PCMCIA_WIDTH_16BIT – PCMCIA data is 16 bit wide
* PCMCIA_WIDTH_DEPEND – PCMCIA width is depending on
* 'is_16bit' pin input
* wait can be:
* PCMCIA_CHECK_WAIT – PCMCIA check the ‘wait’ input
* pin during OE/WE/IOWR/IORD pulse
* PCMCIA_NO_CHECK – PCMCIA doesn’t check ‘wait’ input pin
* swait can be:
* PCMCIA_INSERT_IDLE – PCMCIA insert idle cycles for
* specified cycles before actual
* transfer cycle
* PCMCIA_NO_INSERT – PCMCIA doesn’t insert idle cycles
* devID controls which PCMCIA device to access. One of the
* 4 CS signals are enabled according to:
* PIF_CS0
* PIF_CS1
* PIF_CS2
* PIF_CS3
*
* xfr_type can be:
* PIF_IORD - IO read use IORD
* PIF_IOWR - IO write use IOWR
* PIF_OE - memory read use OE
* PIF_WE - memory write use WE
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void PifTimingRegSet(int setup, int hold, int interval, int wait_cycle, int ioack_wait,\
int pcmcia_width, int wait, int swait, int devID, int xfr_type)
{
rPIF_PCI_TIM = setup | (hold<<4) | (interval<<8) | (wait_cycle<<16) | (ioack_wait<23)|\
(pcmcia_width<<24) | (wait<<26) | (swait<<27) | (devID<<28) |\
(xfr_type<<30);
}
*********************************************************************************************
* PifWaitTillDone
*
* Description: It is a delay function, waiting the master transaction is finished.
*
* Arguments : none
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void PifWaitTillDone(void)
{
/* Wait till the busy bit is clear & the done bit is set */
while(rPIF_INTR & 0x60000000 ^ (0x1<<29));
/* Clear the done bit */
PIF_DONE_CLEAR();
}
/*
**************************************************************************************
* NorFlashPifInit
*
* Description: initialize the PCMCIA interface
*
* Arguments : devID controls which PCMCIA device to access.
* 0 – CS0
* 1 – CS1
* 2 – CS2
* 3 – CS3
* For Virtex-4, devID = 0.
*
* Return : none
*
* Note(s) : Before any Nor flash operations, you should call it at first.
**************************************************************************************
*/
/*4> word 0xa80a0000
0x04000000
5> word 0xa80a0010
0x890F0FFF
6>*/
void NorFlashPifInit(void)
{
unsigned int tmp;
PifPCMCIAModeRegSet(PIF_CBUS_MODE, PCMCIA_MSTR_BS_8BYTE);
PifTimingRegSet(0xf /* setup */, 0xf /* hold */, 0xf /* interval */, \
0xf /* wait_cycle */, PIF_NO_WAIT /* ioack_wait */, \
PCMCIA_WIDTH_16BIT /* pcmcia_width */, PCMCIA_NO_CHECK /* wait */, \
PCMCIA_INSERT_IDLE /* swait */, PIF_CS0 /* devID */, \
PIF_OE /* xfr_type */);
PIF_INTR_DIS(); // Disable the PIF interrupts
PIF_DONE_CLEAR(); // Clear the bit done
tmp = *(unsigned int *)0xa80a001c;
tmp &= 0x7fffffff;
*(unsigned int *)0xa80a001c = tmp;
}
/*
*********************************************************************************************
* NorFlashRd
*
* Description: read the data from the specified address.
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. It is counted by half-words.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRd(int start_addr, short *data, int number)
{
unsigned int i, tmp;
PIF_READ_SET();
rPIF_PCI_LEN = 2; // rPIF_PCI_LEN is counted by bytes.
for(i = 0; i < number; i++) {
rPIF_PCI_DEV_A = start_addr; // the byte address
start_addr += 2;
PIF_START();
*data++ = rPIF_PCMCIA_DATA;
}
}
/*
*********************************************************************************************
* NorFlashRdData
*
* Description: read the data from the specified address.
*
* Arguments : start_addr is the start byte address.
* data is the data pointer.
* number is the data of number to be read. It is counted by half-words.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRdData(int start_addr, short *data, int number)
{
int i;
/* The read array command */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_RD_ARRAY;
PifWaitTillDone(); // Wait till the first cycle complete
NorFlashRd(start_addr, data, number);
}
/*
*********************************************************************************************
* NorFlashRdID
*
* Description: read the manufacture ID, device ID, and block lock configuration.
*
* Arguments : mID is the manufacture ID pointer.
* deviceID is the device ID pointer.
* block_lock_cfg is the block lock configuration.
*
* Return : none.
*
* Note(s) :
*********************************************************************************************
*/
void NorFlashRdID(short *mID, short *deviceID, short *block_lock_cfg)
{
short status;
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_RD_ID;
PifWaitTillDone(); // Wait till the first cycle complete
NorFlashRd(0, mID, 1);
NorFlashRd(2, deviceID, 1);
NorFlashRd(4, block_lock_cfg, 1);
}
/*
*********************************************************************************************
* NorFlashProg
*
* Description: program a half-word into the specified address
*
* Arguments : addr is the byte address.
* data is the half-word to be programmed.
*
* Return : SUCCESSFUL shows the erasure is successful.
* FAILED shows the erasure is failed.
*
* Note(s) :
*********************************************************************************************
*/
int NorFlashProg(int addr, short data)
//int NorFlashProg(unsigned char *addr, unsigned char *data)
{
short status;
/* the first cycle */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_PROG_WORD;
PifWaitTillDone(); // Wait till the first cycle complete
/* the second cycle */
rPIF_PCI_DEV_A = addr; // the byte address
PIF_START();
rPIF_PCMCIA_DATA = data;
PifWaitTillDone(); // Wait till the second cycle complete
status = 0x0;
while(!(status & 0x80)) { // Flash is busy?
NorFlashRd(0, &status, 1);
}
if(status & 0x1a) // Whether the SR1 SR3 or SR4 is set
return FAILED;
return SUCCESSFUL;
}
/* Intel28f640_16x1_erase():
* Erase sector 'snum'.
* Return 0 if success, else negative.
*/
int
Intel28f640_16x1_erase(struct flashinfo *fdev,int snum)
{
short status;
/* the first cycle of block erase */
PIF_WRITE_SET();
rPIF_PCI_LEN = 2;
rPIF_PCI_DEV_A = fdev->sectors[snum].begin; // the byte address
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_ERASE_BLOCK1;
PifWaitTillDone(); // Wait till the first cycle complete
/* the second cycle of block erase */
PIF_START();
rPIF_PCMCIA_DATA = NOR_FLASH_ERASE_BLOCK2;
PifWaitTillDone(); // Wait till the second cycle complete
status = 0x0;
while(!(status & 0x80)) { // Flash is busy?
NorFlashRd(0, &status, 1);
}
if(status & 0x30) // Whether the SR4 or SR5 is set
{
printf("erase sec[%d] error\r\n",snum);
return -1;
}
printf("erase sec[%d] successful\r\n",snum);
return 0;
//return 0;//zx debug
/*
// Issue the setup/confirm sequence:
STRATACMD_BLOCKERASE(fdev->sectors[snum].begin);
STRATACMD_CONFIRM(fdev->sectors[snum].begin);
// Wait for completion:
WAIT_FOR_WSMS_STATUS_READY();
// Cleanup:
STRATACMD_CLEARSTATUS();
STRATACMD_READARRAY();
WAIT_FOR_FF(fdev->sectors[snum].begin);
return(0);
*/
}
/* EndIntel28f640_16x1_erase():
* Function place holder to determine the end of the above function.
*/
void
EndIntel28f640_16x1_erase(void)
{}
int
Intel28f640_16x1_write(struct flashinfo *fdev,uchar *dest,uchar *src,
long bytecnt)
{
int i,addr;
short data;
uchar temp;
addr = dest;
for(i = 0; i < bytecnt/2; i ++) {
//printf("current char : %c\r\n",src[i]);
temp = *src++;
data = (*src<<8) | temp;
/*data = *src<<8;
src++;
data |= *src;*/
//printf("program data is 0x%x\t Addr is:0x%x\r\n",data,addr);
NorFlashProg(addr, data);
//printf("After program\r\n");
/* Flash program setup command */
addr +=2;
src++;
}
printf("Write %d byte OK!\r\n",bytecnt);
}
int
Intel28f640_16x1_write1(struct flashinfo *fdev,uchar *dest,uchar *src,
long bytecnt)
{
volatile int tot, ret;
int i, giveup, aligntot, size;
volatile uchar buf[BUFFER_SIZE], *aligndest, *block;
return 0;//zx debug
/* The write buffer can only be used on 32-byte blocks; hence, the
* low 5 bits of the destination must be zero at the start of a
* buffer write. This means that we must align the destination
* address on this boundary. To do this, we decrement the destination
* the same data that is already there.
*/
aligntot = 0;
aligndest = dest;
while(((ulong)aligndest & BUFFER_ALIGN) != 0) {
aligndest--;
aligntot++;
bytecnt++;
}
ret = tot = 0;
while((tot < bytecnt) && (ret == 0)) {
size = bytecnt - tot;
if (size > BUFFER_SIZE)
size = BUFFER_SIZE;
block = aligndest;
/* Copy buffer's worth of data into local buffer just in
* case the source is this flash device.
*/
for(i=0;i<size;i++) {
if (aligndest < dest)
buf[i] = *aligndest++;
else
buf[i] = *src++;
}
if (size & 1) {
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -