分类: LINUX
2008-09-17 13:52:02
#include #include #include |
/* * NAND flash initialization. */ #if (CONFIG_COMMANDS & CFG_CMD_NAND) extern ulong nand_probe(ulong physadr); static inline void NF_Reset(void) { int i; NF_SetCE(NFCE_LOW); NF_Cmd(0xFF); /* reset command */ for(i = 0; i < 10; i++); /* tWB = 100ns. */ NF_WaitRB(); /* wait 200~500us; */ NF_SetCE(NFCE_HIGH); } static inline void NF_Init(void) { #if 0 /* a little bit too optimistic */ #define TACLS 0 #define TWRPH0 3 #define TWRPH1 0 #else #define TACLS 0 #define TWRPH0 4 #define TWRPH1 2 #endif NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0)); /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */ /* 1 1 1 1, 1 xxx, r xxx, r xxx*/ /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */ NF_Reset(); } void nand_init(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); NF_Init(); #ifdef DEBUG printf("NAND flash probing at 0x%.8lX\n", (ulong)nand); #endif printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20); } #endif |
#include #define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) #define NF_BASE 0x4e000000 #define NFCONF __REGi(NF_BASE + 0x0) #define NFCONT __REGi(NF_BASE + 0x4) #define NFCMD __REGb(NF_BASE + 0x8) #define NFADDR __REGb(NF_BASE + 0xC) #define NFDATA __REGb(NF_BASE + 0x10) #define NFSTAT __REGb(NF_BASE + 0x20) //#define GPDAT __REGi(GPIO_CTL_BASE+oGPIO_F+oGPIO_DAT) #define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1)) #define NAND_CHIP_DISABLE (NFCONT |= (1<<1)) #define NAND_CLEAR_RB (NFSTAT |= (1<<2)) #define NAND_DETECT_RB { while(! (NFSTAT&(1<<2)) );} #define BUSY 4 inline void wait_idle(void) { while(!(NFSTAT & BUSY)); NFSTAT |= BUSY; } #define NAND_SECTOR_SIZE 512 #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1) /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) { return -1; /* invalid alignment */ } NAND_CHIP_ENABLE; for(i=start_addr; i < (start_addr + size);) { /* READ0 */ NAND_CLEAR_RB; NFCMD = 0; /* Write Address */ NFADDR = i & 0xff; NFADDR = (i >> 9) & 0xff; NFADDR = (i >> 17) & 0xff; NFADDR = (i >> 25) & 0xff; NAND_DETECT_RB; for(j=0; j < NAND_SECTOR_SIZE; j++, i++) { *buf = (NFDATA & 0xff); buf++; } } NAND_CHIP_DISABLE; return 0; } |
LIB = $(obj)lib$(BOARD).a COBJS := fs2410.o nand_read.o flash.o SOBJS := lowlevel_init.o |
#include extern int mem_test(unsigned long start, unsigned long ramsize,int mode); #if (CONFIG_COMMANDS & CFG_CMD_NAND) typedef enum { NFCE_LOW, NFCE_HIGH } NFCE_STATE; static inline void NF_Conf(u16 conf) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); nand->NFCONF = conf; } static inline void NF_Cmd(u8 cmd) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); nand->NFCMD = cmd; } static inline void NF_CmdW(u8 cmd) { NF_Cmd(cmd); udelay(1); } static inline void NF_Addr(u8 addr) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); nand->NFADDR = addr; } static inline void NF_SetCE(NFCE_STATE s) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); switch (s) { case NFCE_LOW: nand->NFCONF &= ~(1<<11); break; case NFCE_HIGH: nand->NFCONF |= (1<<11); break; } } static inline void NF_WaitRB(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); while (!(nand->NFSTAT & (1<<0))); } static inline void NF_Write(u8 data) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); nand->NFDATA = data; } static inline u8 NF_Read(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); return(nand->NFDATA); } static inline void NF_Init_ECC(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); nand->NFCONF |= (1<<12); } static inline u32 NF_Read_ECC(void) { S3C2410_NAND * const nand = S3C2410_GetBase_NAND(); return(nand->NFECC); } #endif |
…………………… /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] /* END stuff after relocation */ #endif #ifdef CONFIG_S3C2440_NAND_BOOT bl copy_myself #if 1 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0x00 str r2, [r1, #oGPIO_DAT] #endif @ jump to ram ldr r1, =on_the_ram add pc, r1, #0 nop nop 1: b 1b @ infinite loop on_the_ram: #endif ldr pc, _start_armboot _start_armboot: .word start_armboot …………………… |
…………………… ldr pc, _start_armboot _start_armboot: .word start_armboot #ifdef CONFIG_S3C2440_NAND_BOOT copy_myself: mov r10, lr @ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) str r2, [r1, #oNFCONF] ldr r2, [r1, #oNFCONF] ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT] ldr r2, [r1, #oNFCONT] ldr r2, =(0x6) @ RnB Clear str r2, [r1, #oNFSTAT] ldr r2, [r1, #oNFSTAT] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait 1: add r3, r3, #0x1 cmp r3, #0xa blt 1b 2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x4 beq 2b ldr r2, [r1, #oNFCONT] orr r2, r2, #0x2 @ Flash Memory Chip Disable str r2, [r1, #oNFCONT] @ get read to call C functions (for nand_read()) ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0xe0 str r2, [r1, #oGPIO_DAT] @ copy UBOOT to RAM ldr r0, =UBOOT_RAM_BASE mov r1, #0x0 mov r2, #0x20000 bl nand_read_ll #if 1 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0xb0 str r2, [r1, #oGPIO_DAT] #endif tst r0, #0x0 beq ok_nand_read #ifdef CONFIG_DEBUG_LL bad_nand_read: ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord 1: b 1b @ infinite loop #endif ok_nand_read: #ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif @ verify mov r0, #0 ldr r1, =UBOOT_RAM_BASE mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq done_nand_read bne go_next notmatch: #ifdef CONFIG_DEBUG_LL sub r0, r0, #4 ldr r1, SerBase bl PrintHexWord ldr r0, STR_FAIL ldr r1, SerBase bl PrintWord #endif 1: b 1b done_nand_read: #ifdef CONFIG_DEBUG_LL ldr r0, STR_OK ldr r1, SerBase bl PrintWord #endif #if 1 mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_F mov r2, #0x70 str r2, [r1, #oGPIO_DAT] #endif mov pc, r10 @ clear memory @ r0: start address @ r1: length mem_clear: mov r2, #0 mov r3, r2 mov r4, r2 mov r5, r2 mov r6, r2 mov r7, r2 mov r8, r2 mov r9, r2 clear_loop: stmia r0!, {r2-r9} subs r1, r1, #(8 * 4) bne clear_loop mov pc, lr #endif @ CONFIG_S3C2440_NAND_BOOT |
#ifdef CONFIG_S3C2410_NAND_BOOT .align 2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 #endif |
#define CONFIG_COMMANDS \ (CONFIG_CMD_DFL | \ CFG_CMD_CACHE | \ CFG_CMD_NAND | \ /*CFG_CMD_EEPROM |*/ \ /*CFG_CMD_I2C |*/ \ /*CFG_CMD_USB |*/ \ CFG_CMD_REGINFO | \ CFG_CMD_DATE | \ CFG_CMD_ELF) |
//#define CFG_ENV_IS_IN_FLASH 1 //#define CFG_ENV_SIZE 0x10000 #define CFG_ENV_IS_IN_NAND 1 #define CFG_ENV_OFFSET 0x020000 #define CFG_NAND_BASE 0x4E000000 #define CMD_SAVEENV #define CFG_NAND_LEGACY #define CFG_ENV_SIZE 0x10000 |
#if (CONFIG_COMMANDS & CFG_CMD_NAND) #define CONFIG_S3C2410_NAND_BOOT 1 #define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */ #define SECTORSIZE 512 #define ADDR_COLUMN 1 #define ADDR_PAGE 2 #define ADDR_COLUMN_PAGE 3 #define NAND_ChipID_UNKNOWN 0x00 #define NAND_MAX_FLOORS 1 #define NAND_MAX_CHIPS 1 #define NAND_WAIT_READY(nand) NF_WaitRB() #define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH) #define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW) #define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d) #define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d) #define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d) #define WRITE_NAND(d, adr) NF_Write(d) #define READ_NAND(adr) NF_Read() /* the following functions are NOP's because S3C24X0 handles this in hardware */ #define NAND_CTL_CLRALE(nandptr) #define NAND_CTL_SETALE(nandptr) #define NAND_CTL_CLRCLE(nandptr) #define NAND_CTL_SETCLE(nandptr) #define CONFIG_MTD_NAND_VERIFY_WRITE 1 #define CONFIG_MTD_NAND_ECC_JFFS2 1 /*define NAND BOOT*/ #define UBOOT_RAM_BASE 0x33f80000 #define STACK_BASE 0x33f00000 #define STACK_SIZE 0x8000 #define NAND_CTL_BASE 0x4E000000 #define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb)) #define oNFCONF 0x00 #define oNFCMD 0x04 #define oNFADDR 0x08 #define oNFDATA 0x0c #define oNFSTAT 0x10 #define oNFECC 0x14 #endif #endif |
drivers/nand_legacy/nand_legacy.c include/linux/mtd/nand_ids.h include/linux/mtd/nand.h |
{"Samsung K9K1216Q0C", NAND_MFR_SAMSUNG, 0x46, 26, 0, 3, 0x4000, 1}, {"Samsung K9F1208U0M", NAND_MFR_SAMSUNG, 0xf6, 26, 0, 4, 0X4000, 0}, { NULL,} |
ifeq ($(ARCH),arm) CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux- endif |
make fs2410_config |
make all ARCH=ARM |