summaryrefslogtreecommitdiffstats
path: root/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c')
-rw-r--r--uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c558
1 files changed, 279 insertions, 279 deletions
diff --git a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
index ba4f0a3..9398461 100644
--- a/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
+++ b/uClinux-2.4.20-uc1/drivers/block/wbflash/cfi.c
@@ -1,279 +1,279 @@
-/******************************************************************************
- *
- * Copyright (c) 2007 Windond Electronics Corp.
- * All rights reserved.
- *
- * $Workfile: cfi.c $
- *
- *
- ******************************************************************************/
-
-//#include <stdio.h>
-//#include <string.h>
-//#include <stdlib.h>
-//#include "wblib.h"
-#include <asm/arch/flash.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-
-#include "cfi.h"
-//#include "platform.h"
-
-//#define FLASH_BASE 0xFF000000
-#define MAX_REGION_NUM 10
-
-static unsigned short cfiCmdSet = 0;
-static unsigned short cfiExtTab = 0;
-static unsigned int cfiDevSize = 0;
-static unsigned short cfiNumEraseBlkRegion = 0;
-
-static struct cfi_erase_block_region_info cfiEraseBlkRegionInfo[MAX_REGION_NUM];
-static int dummyErase(unsigned int address, unsigned int size);
-static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size);
-
-struct cfi_command cfiCmd = {
- write: dummyWrite,
- erase: dummyErase,
-};
-
-
-/* Retrun 0: OK, otherwise: CFI not found */
-static int cfiCheckIdent(void)
-{
- unsigned short i[3];
-
- CFI_READ(FLASH_BASE, 0x10, i[0]);
- CFI_READ(FLASH_BASE, 0x11, i[1]);
- CFI_READ(FLASH_BASE, 0x12, i[2]);
-
- if(i[0] == 'Q' && i[1] == 'R' && i[2] == 'Y')
- return(0);
- else
- return(-1);
-
-}
-
-unsigned int cfiGetFlashSize(void)
-{
- return(cfiDevSize);
-}
-
-unsigned int cfiGetBlockSize(unsigned int address)
-{
- int i, offset = 0;
-
- address = (address | 0x80000000) - (FLASH_BASE | 0x80000000);
- //printk("addr %x %x\n", address, FLASH_BASE);
-
- for(i = 0; i < cfiNumEraseBlkRegion; i++) {
- if(address < (offset += (cfiEraseBlkRegionInfo[i].num * cfiEraseBlkRegionInfo[i].size)))
- return(cfiEraseBlkRegionInfo[i].size);
- }
- //uprintf("get size error\n");
-
- return(0);
-
-}
-
-static void flushDCache(void)
-{
-
- if( *(unsigned int volatile *)(0xFFF02000) & 0x6 ) /* If write buffer or data cache is enabled */
- {
- *(unsigned int volatile *)(0xFFF02004) = 0x86;
- while( *(unsigned int volatile *)(0xFFF02004));
- }
-
-}
-
-
-static int polling16(unsigned int addr, unsigned short data)
-{
- unsigned short rdata;
- int timeout = 0x600000;
-
- rdata = *(unsigned short volatile *)(addr);
- while( rdata != data )
- {
- rdata = *(unsigned short volatile *)(addr);
- if( !(timeout--) )
- {
- rdata = *(unsigned short volatile *)(addr);
- if( rdata != data )
- {
- //printf("timeout\n");
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-static int intelWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- unsigned int i;
- int status = 0;
-
- address |= 0x80000000;
- for(i = address; i < address + size; i += 2)
- {
- CFI_WRITE(i, 0, 0x40);
- CFI_WRITE(i, 0, *(unsigned short *)data);
- CFI_WRITE(address, 0, 0x70);
- while(!( *(unsigned short *)(address) & 0x80));
- if(*(unsigned short *)(address) & 0x19) {
- status = -1;
- goto exit;
- }
- data+=2;
- }
-
-exit:
- CFI_WRITE(address,0,0xFF);
- flushDCache();
- return(status);
-}
-
-static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- printk("Dummy Write\n");
- return(-1);
-}
-static int amdWrite(unsigned int address, unsigned char *data, unsigned int size)
-{
- int status;
- unsigned int i;
-
- address |= 0x80000000;
- for(i = address; i < address+size; i += 2)
- {
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(FLASH_BASE, 0x555, 0xA0);
- CFI_WRITE(i, 0, *(unsigned short *)data);
- status = polling16( i, *(unsigned short *)data);
- if(status < 0) {
- printk("write failed, time out!\n");
- return(status); // time-out
- }
- data+=2;
- }
-
- flushDCache();
- return(0);
-
-}
-
-static int intelErase(unsigned int address, unsigned int size)
-{
- int status = 0;
-
- address|=0x80000000;
-
- CFI_WRITE(address, 0, 0x50); // Clear sttaus register
- CFI_WRITE(address, 0, 0x20);
- CFI_WRITE(address, 0, 0xD0);
-
- CFI_WRITE(address, 0, 0x70);
- while(!( *(unsigned short *)(address) & 0x80));
- if(*(unsigned short *)(address) & 0x39)
- status = -1;
-
- CFI_WRITE(address, 0, 0xFF);
- flushDCache();
- return(status);
-}
-
-static int dummyErase(unsigned int address, unsigned int size)
-{
- printk("Dummy Erase\n");
- return(-1);
-}
-static int amdErase(unsigned int address, unsigned int size)
-{
- int status;
-
- //printk("erase addr: %x\n", address);
-
- if((address & (size - 1)) != 0x0)
- return -1;// not in the start of a block
- address |= 0x80000000;
- //printf("erase addr: %08x\n", address);
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(FLASH_BASE, 0x555, 0x80);
- CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
- CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
- CFI_WRITE(address, 0, 0x30);
- status = polling16(address, 0xFFFF);
- CFI_WRITE(FLASH_BASE, 0, 0xFF);
- flushDCache();
- if(status < 0)
- printk("erase failed, time out!\n");
- return(status);
-
-}
-
-int cfiGetFlashInfo(void)
-{
-
- unsigned int i;
-
- // goes into query mode
- DESELECT_QUERY_MODE(FLASH_BASE);
- SELECT_QUERY_MODE(FLASH_BASE);
-
- if(cfiCheckIdent() != 0) {
- printk("No CFI information found\n");
- goto exit;
- }
-
- CFI_READ(FLASH_BASE, 0x13, cfiCmdSet);
- CFI_READ(FLASH_BASE, 0x15, cfiExtTab);
- CFI_READ(FLASH_BASE, 0x27, cfiDevSize);
- cfiDevSize = 1 << cfiDevSize;
-
- CFI_READ(FLASH_BASE, 0x2C, cfiNumEraseBlkRegion);
- //cfiEraseBlkRegionInfo = (struct cfi_erase_block_region_info *)malloc(sizeof(struct cfi_erase_block_region_info) * cfiNumEraseBlkRegion);
-
- if(cfiNumEraseBlkRegion > MAX_REGION_NUM) {
- //sysprintf("Out of memory\n");
- goto exit;
- }
-
- for(i = 0; i < cfiNumEraseBlkRegion * 4; i += 4) {
- unsigned short s1, s2;
- CFI_READ(FLASH_BASE, 0x2D + i, s1);
- CFI_READ(FLASH_BASE, 0x2E + i, s2);
-
- cfiEraseBlkRegionInfo[i/4].num = s1 + (s2 << 8) + 1;
- //printk("num %d ", (cfiEraseBlkRegionInfo + i/4)->num);
-
- CFI_READ(FLASH_BASE, 0x2F + i, s1);
- CFI_READ(FLASH_BASE, 0x30 + i, s2);
-
- cfiEraseBlkRegionInfo[i/4].size = (s1 + (s2 << 8)) * 256;
- //printk("size %x \n", (cfiEraseBlkRegionInfo + i/4)->size);
-
- }
-
- DESELECT_QUERY_MODE(FLASH_BASE);
- if(cfiCmdSet == AMD_CMD_SET) {
- cfiCmd.write = amdWrite;
- cfiCmd.erase = amdErase;
-
- }else if(cfiCmdSet == INTEL_CMD_SET) {
- cfiCmd.write = intelWrite;
- cfiCmd.erase = intelErase;
-
- } else {
- printk("CFI command set %04x not support!\n", cfiCmdSet);
- return(-1);
- }
- printk("CFI command set %04x will be used\n", cfiCmdSet);
-
-exit:
- return(0);
-
-}
+/******************************************************************************
+ *
+ * Copyright (c) 2007 Windond Electronics Corp.
+ * All rights reserved.
+ *
+ * $Workfile: cfi.c $
+ *
+ *
+ ******************************************************************************/
+
+//#include <stdio.h>
+//#include <string.h>
+//#include <stdlib.h>
+//#include "wblib.h"
+#include <asm/arch/flash.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+
+#include "cfi.h"
+//#include "platform.h"
+
+//#define FLASH_BASE 0xFF000000
+#define MAX_REGION_NUM 10
+
+static unsigned short cfiCmdSet = 0;
+static unsigned short cfiExtTab = 0;
+static unsigned int cfiDevSize = 0;
+static unsigned short cfiNumEraseBlkRegion = 0;
+
+static struct cfi_erase_block_region_info cfiEraseBlkRegionInfo[MAX_REGION_NUM];
+static int dummyErase(unsigned int address, unsigned int size);
+static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size);
+
+struct cfi_command cfiCmd = {
+ write: dummyWrite,
+ erase: dummyErase,
+};
+
+
+/* Retrun 0: OK, otherwise: CFI not found */
+static int cfiCheckIdent(void)
+{
+ unsigned short i[3];
+
+ CFI_READ(FLASH_BASE, 0x10, i[0]);
+ CFI_READ(FLASH_BASE, 0x11, i[1]);
+ CFI_READ(FLASH_BASE, 0x12, i[2]);
+
+ if(i[0] == 'Q' && i[1] == 'R' && i[2] == 'Y')
+ return(0);
+ else
+ return(-1);
+
+}
+
+unsigned int cfiGetFlashSize(void)
+{
+ return(cfiDevSize);
+}
+
+unsigned int cfiGetBlockSize(unsigned int address)
+{
+ int i, offset = 0;
+
+ address = (address | 0x80000000) - (FLASH_BASE | 0x80000000);
+ //printk("addr %x %x\n", address, FLASH_BASE);
+
+ for(i = 0; i < cfiNumEraseBlkRegion; i++) {
+ if(address < (offset += (cfiEraseBlkRegionInfo[i].num * cfiEraseBlkRegionInfo[i].size)))
+ return(cfiEraseBlkRegionInfo[i].size);
+ }
+ //uprintf("get size error\n");
+
+ return(0);
+
+}
+
+static void flushDCache(void)
+{
+
+ if( *(unsigned int volatile *)(0xFFF02000) & 0x6 ) /* If write buffer or data cache is enabled */
+ {
+ *(unsigned int volatile *)(0xFFF02004) = 0x86;
+ while( *(unsigned int volatile *)(0xFFF02004));
+ }
+
+}
+
+
+static int polling16(unsigned int addr, unsigned short data)
+{
+ unsigned short rdata;
+ int timeout = 0x600000;
+
+ rdata = *(unsigned short volatile *)(addr);
+ while( rdata != data )
+ {
+ rdata = *(unsigned short volatile *)(addr);
+ if( !(timeout--) )
+ {
+ rdata = *(unsigned short volatile *)(addr);
+ if( rdata != data )
+ {
+ //printf("timeout\n");
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int intelWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ unsigned int i;
+ int status = 0;
+
+ address |= 0x80000000;
+ for(i = address; i < address + size; i += 2)
+ {
+ CFI_WRITE(i, 0, 0x40);
+ CFI_WRITE(i, 0, *(unsigned short *)data);
+ CFI_WRITE(address, 0, 0x70);
+ while(!( *(unsigned short *)(address) & 0x80));
+ if(*(unsigned short *)(address) & 0x19) {
+ status = -1;
+ goto exit;
+ }
+ data+=2;
+ }
+
+exit:
+ CFI_WRITE(address,0,0xFF);
+ flushDCache();
+ return(status);
+}
+
+static int dummyWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ printk("Dummy Write\n");
+ return(-1);
+}
+static int amdWrite(unsigned int address, unsigned char *data, unsigned int size)
+{
+ int status;
+ unsigned int i;
+
+ address |= 0x80000000;
+ for(i = address; i < address+size; i += 2)
+ {
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xA0);
+ CFI_WRITE(i, 0, *(unsigned short *)data);
+ status = polling16( i, *(unsigned short *)data);
+ if(status < 0) {
+ printk("write failed, time out!\n");
+ return(status); // time-out
+ }
+ data+=2;
+ }
+
+ flushDCache();
+ return(0);
+
+}
+
+static int intelErase(unsigned int address, unsigned int size)
+{
+ int status = 0;
+
+ address|=0x80000000;
+
+ CFI_WRITE(address, 0, 0x50); // Clear sttaus register
+ CFI_WRITE(address, 0, 0x20);
+ CFI_WRITE(address, 0, 0xD0);
+
+ CFI_WRITE(address, 0, 0x70);
+ while(!( *(unsigned short *)(address) & 0x80));
+ if(*(unsigned short *)(address) & 0x39)
+ status = -1;
+
+ CFI_WRITE(address, 0, 0xFF);
+ flushDCache();
+ return(status);
+}
+
+static int dummyErase(unsigned int address, unsigned int size)
+{
+ printk("Dummy Erase\n");
+ return(-1);
+}
+static int amdErase(unsigned int address, unsigned int size)
+{
+ int status;
+
+ //printk("erase addr: %x\n", address);
+
+ if((address & (size - 1)) != 0x0)
+ return -1;// not in the start of a block
+ address |= 0x80000000;
+ //printf("erase addr: %08x\n", address);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(FLASH_BASE, 0x555, 0x80);
+ CFI_WRITE(FLASH_BASE, 0x555, 0xAA);
+ CFI_WRITE(FLASH_BASE, 0x2AA, 0x55);
+ CFI_WRITE(address, 0, 0x30);
+ status = polling16(address, 0xFFFF);
+ CFI_WRITE(FLASH_BASE, 0, 0xFF);
+ flushDCache();
+ if(status < 0)
+ printk("erase failed, time out!\n");
+ return(status);
+
+}
+
+int cfiGetFlashInfo(void)
+{
+
+ unsigned int i;
+
+ // goes into query mode
+ DESELECT_QUERY_MODE(FLASH_BASE);
+ SELECT_QUERY_MODE(FLASH_BASE);
+
+ if(cfiCheckIdent() != 0) {
+ printk("No CFI information found\n");
+ goto exit;
+ }
+
+ CFI_READ(FLASH_BASE, 0x13, cfiCmdSet);
+ CFI_READ(FLASH_BASE, 0x15, cfiExtTab);
+ CFI_READ(FLASH_BASE, 0x27, cfiDevSize);
+ cfiDevSize = 1 << cfiDevSize;
+
+ CFI_READ(FLASH_BASE, 0x2C, cfiNumEraseBlkRegion);
+ //cfiEraseBlkRegionInfo = (struct cfi_erase_block_region_info *)malloc(sizeof(struct cfi_erase_block_region_info) * cfiNumEraseBlkRegion);
+
+ if(cfiNumEraseBlkRegion > MAX_REGION_NUM) {
+ //sysprintf("Out of memory\n");
+ goto exit;
+ }
+
+ for(i = 0; i < cfiNumEraseBlkRegion * 4; i += 4) {
+ unsigned short s1, s2;
+ CFI_READ(FLASH_BASE, 0x2D + i, s1);
+ CFI_READ(FLASH_BASE, 0x2E + i, s2);
+
+ cfiEraseBlkRegionInfo[i/4].num = s1 + (s2 << 8) + 1;
+ //printk("num %d ", (cfiEraseBlkRegionInfo + i/4)->num);
+
+ CFI_READ(FLASH_BASE, 0x2F + i, s1);
+ CFI_READ(FLASH_BASE, 0x30 + i, s2);
+
+ cfiEraseBlkRegionInfo[i/4].size = (s1 + (s2 << 8)) * 256;
+ //printk("size %x \n", (cfiEraseBlkRegionInfo + i/4)->size);
+
+ }
+
+ DESELECT_QUERY_MODE(FLASH_BASE);
+ if(cfiCmdSet == AMD_CMD_SET) {
+ cfiCmd.write = amdWrite;
+ cfiCmd.erase = amdErase;
+
+ }else if(cfiCmdSet == INTEL_CMD_SET) {
+ cfiCmd.write = intelWrite;
+ cfiCmd.erase = intelErase;
+
+ } else {
+ printk("CFI command set %04x not support!\n", cfiCmdSet);
+ return(-1);
+ }
+ printk("CFI command set %04x will be used\n", cfiCmdSet);
+
+exit:
+ return(0);
+
+}