本帖最后由 mrbushy 于 2015-9-16 22:40 编辑
一、仍然先把源码贴出来再分析/*
* Nand Interface Init for SMDKC110
*/
nand_asm_init:
/* Setting GPIO for NAND */
/* This setting is NAND initialze code at booting time in iROM. */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, [r0, #MP01CON_OFFSET]
bic r1, r1, #(0xf<<8)
orr r1, r1, #(0x3<<8)
str r1, [r0, #MP01CON_OFFSET]
ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<4)
str r1, [r0, #MP01PUD_OFFSET]
ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET]
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
ldr r0, =ELFIN_NAND_BASE
ldr r1, [r0, #NFCONF_OFFSET]
ldr r2, =0x777F
bic r1, r1, r2
ldr r2, =NFCONF_VAL
orr r1, r1, r2
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
ldr r1, [r0, #NFCONF_OFFSET]
orr r1, r1, #0x70
orr r1, r1, #0x7700
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
orr r1, r1, #0x03
str r1, [r0, #NFCONT_OFFSET]
mov pc, lr
boardsamsungOK210lowlevel_init.S中找到
在u-boot-2011.06-2013-05-30includeconfigsOK210.h中查找到
#define MP01CON_OFFSET 0x2E0
#define MP01DAT_OFFSET 0x2E4
#define MP01PUD_OFFSET 0x2E8
#define MP01DRV_SR_OFFSET 0x2EC
#define MP01CONPDN_OFFSET 0x2E0
#define MP01PUDPDN_OFFSET 0x2E4
#define MP02CON_OFFSET 0x300
#define MP02DAT_OFFSET 0x304
#define MP02PUD_OFFSET 0x308
#define MP02DRV_SR_OFFSET 0x30c
#define MP02CONPDN_OFFSET 0x310
#define MP02PUDPDN_OFFSET 0x314
#define MP03CON_OFFSET 0x320
#define MP03DAT_OFFSET 0x324
#define MP03PUD_OFFSET 0x328
#define MP03DRV_SR_OFFSET 0x32c
#define MP03CONPDN_OFFSET 0x330
#define MP03PUDPDN_OFFSET 0x334
#define NFCONF_VAL (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)
#define NFCONT_VAL (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)
#define MP03CON_VAL (1<<29)|(1<<25)|(1<<21)|(1<<17)|(1<<13)|(1<<9)|(1<<5)|(1<<1)
/*
* Nand flash controller
*/
#define ELFIN_NAND_BASE 0xB0E00000
#define ELFIN_NAND_ECC_BASE 0xB0E20000
#define NFCONF_OFFSET 0x00
#define NFCONT_OFFSET 0x04
#define NFCMMD_OFFSET 0x08
#define NFADDR_OFFSET 0x0c
#define NFDATA_OFFSET 0x10
#define NFMECCDATA0_OFFSET 0x14
#define NFMECCDATA1_OFFSET 0x18
#define NFSECCDATA0_OFFSET 0x1c
#define NFSBLK_OFFSET 0x20
#define NFEBLK_OFFSET 0x24
#define NFSTAT_OFFSET 0x28
#define NFESTAT0_OFFSET 0x2c
#define NFESTAT1_OFFSET 0x30
#define NFCONF (ELFIN_NAND_BASE+NFCONF_OFFSET)
#define NFCONT (ELFIN_NAND_BASE+NFCONT_OFFSET)
#define NFCMMD (ELFIN_NAND_BASE+NFCMMD_OFFSET)
#define NFADDR (ELFIN_NAND_BASE+NFADDR_OFFSET)
#define NFDATA (ELFIN_NAND_BASE+NFDATA_OFFSET)
#define NFMECCDATA0 (ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
#define NFMECCDATA1 (ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
#define NFSECCDATA0 (ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
#define NFSBLK (ELFIN_NAND_BASE+NFSBLK_OFFSET)
#define NFEBLK (ELFIN_NAND_BASE+NFEBLK_OFFSET)
#define NFSTAT (ELFIN_NAND_BASE+NFSTAT_OFFSET)
#define NFESTAT0 (ELFIN_NAND_BASE+NFESTAT0_OFFSET)
#define NFESTAT1 (ELFIN_NAND_BASE+NFESTAT1_OFFSET)
#define NFMECC0 (ELFIN_NAND_BASE+NFMECC0_OFFSET)
#define NFMECC1 (ELFIN_NAND_BASE+NFMECC1_OFFSET)
#define NFSECC (ELFIN_NAND_BASE+NFSECC_OFFSET)
#define NFMLCBITPT (ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
二.配置原理分析
初始化Nand Flash
在u-boot中,Nand的低级初始化在lowlevel_init.S中的nand_asm_init函数中。打开原理图,配置各个功能引脚----状态引脚R/B1, 读使能引用脚/RE, 片选信号/CE1, 命令使能引脚CLE ,地址使能引脚ALE, 写使能引脚WE
搜索各个引脚的值,比如R/B1接在Xm0FRnB0上,搜索Xm0FRnB0,发现Xm0FRnB0和ONDXL_INT0/MP03_4共用一个引脚。
1.配置片选信号引脚
查找到nCE接在复用引脚Xm0CSn2/NFCSn0/MP01_2上,打开S5PV210芯片手册,P185页查找到MP0_1 Control Registe,MP0_1CON[2]的配置如下:
所以,只需将NFCSN0配置成011,才能识别成Nand Flash。
*
* Nand Interface Init for SMDKC110
*/
nand_asm_init:
/* Setting GPIO for NAND */
/* This setting is NAND initialze code at booting time in iROM. */
ldr r0, =ELFIN_GPIO_BASE
ldr r1, [r0, #MP01CON_OFFSET]
bic r1, r1, #(0xf<<8) // 将MP0_1 Control Register 的第8.9.10.11位清零
orr r1, r1, #(0x3<<8) // 向MP0_1 Control Register 的第8.9.10.11位写0x3(0011)
str r1, [r0, #MP01CON_OFFSET]
将Port Group MP0_1 Control Register 的4-5位全部清为0
ldr r1, [r0, #MP01PUD_OFFSET]
bic r1, r1, #(0x3<<4)
str r1, [r0, #MP01PUD_OFFSET]
配置CLE/ALE/nWE/nRE/R/nB引脚
除了nCE引脚,其余的几个引脚都是复用的MP0,查找MP03,P189,Port Group MP0_3 Control Register,配置如下:
Port Group MP0_3 Control Register (MP0_3CON, R/W, Address = 0xE020_0320)
图中红框中的NF应该是nandflash 的缩写。
先将0-23位全部清零,然后全部置为0010,也就是全部置为2
ldr r1, [r0, #MP03CON_OFFSET]
bic r1, r1, #0xFFFFFF
ldr r2, =0x22222222
orr r1, r1, r2
str r1, [r0, #MP03CON_OFFSET]
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
将Port Group MP0_3 Control Register的0-23位全部清为0
Port Group MP0_3 Control Register (MP0_3PUD, R/W, Address = 0xE020_0328)
ldr r1, [r0, #MP03PUD_OFFSET]
ldr r2, =0x3fff
bic r1, r1, r2
str r1, [r0, #MP03PUD_OFFSET]
2.配置Nandf Flash控制器的寄存器NFCONF
Nand Flash Configuration Register (NFCONF, R/W, Address = 0xB0E0_0000)
先看前四位[3:0]
[0]位保留,置为0。
[1]用来配置页的一个地址周期是,MT29F8G08ABABA是每页4K,那么地址周期是多少,再去看MT29F8G08ABABA的芯片手册,看到第P16页
示地址周期为5th,所以[1]配为1。
先看[3],这里是配置是SLC还是MCL,根据芯片名称,这款MT29F8G08ABABA是SLC存储,所以[3]配为0;
再来看[2],K9F2G08UOBSingle-level cell (SLC) technology,PageSize是4,[2]中没有相应的选项....但是源码中是选1
这里需要配置TACLS, TWRPH0, TWRPH1
查看一下s5pv210芯片手册上的NAND FLASH MEMORY TIMING, P693-P694
TACLS:当将CLE和ALE拉高以后,再过多少时间才能发出写使能信号(nWE)
TWRPH0:nWE使能持续时间,信号被拉低的时间
TWRPH1:当将CLE和ALE拉高以后,WE使能,这时,后面开始发数据,这就是数据起作用的时间(Data hold time)
查看MT29F8G08ABABA的芯片手册18页
查看1页知MT29F8G08ABABA是基于timing mode 4 的
查看103页
这里S5PV210的NandFlash的HCLK频率为133MHz(P522页),NFCON属于HCLKD0 = 133MHz,T = 1/133 = 7.5ns
查看210芯片手册708页
在210芯片手册693页下有一句话
Figure 4-2 CLE and ALE Timing (TACLS=1, TWRPH0=0, TWRPH1=0)
所以
TACLS:配置0,算出时间为7.5*(0+1)= 7.5ns
TWRPH0:配置1,算出时间为7.5*(1+1)= 15ns
TWRPH1:配置0,算出时间为7.5*(0+1)= 7.5ns
通过实际的测试,如果配置成最小值,Nand Flash会出现无法读写的情况,这里我们还是参考提供的Nand Flash的裸机的参考代码,将这三位配成7--7--7
TACLS:配置0,算出时间为7.5*(7+1)= 60ns
TWRPH0:配置1,算出时间为7.5*(7+1)= 60ns
TWRPH1:配置0,算出时间为7.5*(7+1)= 60ns
ldr r0, =ELFIN_NAND_BASE
ldr r1, [r0, #NFCONF_OFFSET]
ldr r2, =0x777F
bic r1, r1, r2
ldr r2, =NFCONF_VAL /#define NFCONF_VAL (7<<12)|(7<<8)|(7<<4)|(0<<3)|(0<<2)|(1<<1)|(0<<0)
orr r1, r1, r2
str r1, [r0, #NFCONF_OFFSET]
3.配置CONTROL REGISTER
(NFCONT, R/W, ADDRESS = 0XE720_0004)
查看210芯片手册709-710页
第[0]位,让NAND Flash控制器Enable,这里设置为1。使能意思就是生效的意思第二位是1Force nRCS[0] to High (Disable chip select)。剩下的几位按源码配置
ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL /#define NFCONT_VAL (0x1<<23)|(0x1<<22)|(0<<18)|(0<<17)|(0<<16)|(0<<10)|(0<<9)|(0<<8)|(0<<7)|(0<<6)|(0x2<<1)|(1<<0)
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
ldr r1, [r0, #NFCONF_OFFSET]
orr r1, r1, #0x70
orr r1, r1, #0x7700 /这一步上面已经做过相同配置不知为何又写一遍,看了其他版本的uboot并没有重复,也许是后来改的人直接在这个源码中添加了内容没有删减也不得而知。。。。
str r1, [r0, #NFCONF_OFFSET]
ldr r1, [r0, #NFCONT_OFFSET]
orr r1, r1, #0x03 /*使能NAND控制器、关闭chip select 这一步以上同样配置过...
str r1, [r0, #NFCONT_OFFSET]
mov pc, lr
注:这里的NANDFLASH配置没有配置ecc
(
ldr r1, [r0, #NFCONT_OFFSET]
ldr r2, =0x707C7
bic r1, r1, r2
ldr r2, =NFCONT_VAL *ECC LOCK INTERRUPT 等设置
orr r1, r1, r2
str r1, [r0, #NFCONT_OFFSET]
)
下篇预告《DDR2工作原理分析》