/* kernel 2.6.21 */
kernel 2.6.21 的 pxa3xx_nand.c 程式碼跟 WinCE 在結構上來說是大同小異, 值得關注的就是 dfc_flash_info 這個結構, 大部份的 flash 資訊都在這裡:
struct dfc_flash_info {
struct dfc_flash_timing timing; /* NAND Flash timing */
int enable_arbiter;/* Data flash bus arbiter enable (ND_ARB_EN) */
uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
uint32_t row_addr_start;/* Row address start position (RA_START) */
uint32_t read_id_bytes; /* returned ID bytes(RD_ID_CNT) */
uint32_t dfc_mode; /* NAND, CARBONDALE, PIXLEY... (ND_MODE) */
uint32_t ncsx; /* Chip select don't care bit (NCSX) */
uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
uint32_t oob_size; /* OOB size */
uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
uint32_t num_blocks; /* Number of physical blocks in Flash */
uint32_t chip_id;
uint32_t read_prog_cycles; /* Read Program address cycles */
/* command codes */
uint32_t read1; /* Read */
uint32_t read2; /* unused, DFC don't support yet */
uint32_t program; /* two cycle command */
uint32_t read_status;
uint32_t read_id;
uint32_t erase; /* two cycle command */
uint32_t reset;
uint32_t lock; /* lock whole flash */
uint32_t unlock; /* two cycle command, supporting partial unlock */
uint32_t lock_status; /* read block lock status */
/* addr2ndcb1 - encode address cycles into register NDCB1 */
/* ndbbr2addr - convert register NDBBR to bad block address */
int (*addr2ndcb1)(uint16_t cmd, uint32_t addr, uint32_t *p);
int (*ndbbr2addr)(uint16_t cmd, uint32_t ndbbr,uint32_t *p);
};
大部份的東西對應 datasheet 都可以知道, 比較特別的名詞是 OOB (Out of Band), 這東西其實就是 datasheet 上的 spare area.
除此之外, 還有兩個 pointer to function, 這兩個 function 主要是用來做讀寫時位址換算, 因為 nand flash write 時是 by page, 而 erase 時是 by block, 所以在讀寫位置要特別處理.
/* kernel 2.6.36 */
kernel 2.6.36 值得注意的是 pxa3xx_nand_flash 這個結構如下:
struct pxa3xx_nand_flash {
const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
const struct pxa3xx_nand_cmdset *cmdset;
uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
uint32_t num_blocks; /* Number of physical blocks in Flash */
uint32_t chip_id;
};
可以看到裡面包含了 chip_id, page_size 等相關資訊, 以及 timing 跟 command set 這兩個結構:
struct pxa3xx_nand_timing {
unsigned int tCH; /* Enable signal hold time */
unsigned int tCS; /* Enable signal setup time */
unsigned int tWH; /* ND_nWE high duration */
unsigned int tWP; /* ND_nWE pulse time */
unsigned int tRH; /* ND_nRE high duration */
unsigned int tRP; /* ND_nRE pulse width */
unsigned int tR; /* ND_nWE high to ND_nRE low for read */
unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */
unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
};
timing 的部份, 請參考 datasheet 裡面有詳細的解說, 簡單來說就是在定義讀取跟寫入資料時, 哪幾條線要 pull high 幾個 clock 之類, 而這些 timing 每片 flash 都不盡相同.
struct pxa3xx_nand_cmdset {
uint16_t read1;
uint16_t read2;
uint16_t program;
uint16_t read_status;
uint16_t read_id;
uint16_t erase;
uint16_t reset;
uint16_t lock;
uint16_t unlock;
uint16_t lock_status;
};
再來就是 command set, 一般來說 nor flash 接法與 DRAM 一樣, 讀寫方式也類似, 最多要注意的就是 data bus 幾條跟 block 是由大到小或由小到大而已, 而 nand flash 都是用 command 來做資料傳輸的方式, 目前看得到的 nand flash, page size 基本上只有兩種: 512 跟 2048, 以後會不會有新的還不知道, 而這兩者 command set 大部份幾乎都一樣, 主要差別在 small page 跟 large page 的 read 會有點不同, 只要依照 datasheet 把正確的數值加上去就可以了.
要參考的函式:
dfc_init->dfc_get_flash_info
要修改的 struct:
enum {
DFC_FLASH_NULL = 0 ,
DFC_FLASH_Samsung_512Mb_X_16 = 1,
DFC_FLASH_Micron_1Gb_X_8 = 2,
DFC_FLASH_Micron_1Gb_X_16 = 3,
DFC_FLASH_STM_1Gb_X_16 = 4,
DFC_FLASH_STM_2Gb_X_16 = 5,
DFC_FLASH_STM_MCP_1Gb_X_16 = 6,
DFC_FLASH_Toshiba2GbX16 = 7,
DFC_FLASH_END,
};
static struct {
int type;
struct dfc_flash_info *flash_info;
} type_info[] = {
{ DFC_FLASH_Samsung_512Mb_X_16, &samsung512MbX16},
{ DFC_FLASH_Micron_1Gb_X_8, µn1GbX8},
{ DFC_FLASH_Micron_1Gb_X_16, µn1GbX16},
{ DFC_FLASH_STM_1Gb_X_16, &stm1GbX16},
{ DFC_FLASH_STM_2Gb_X_16, &stm2GbX16},
{ DFC_FLASH_STM_MCP_1Gb_X_16, &stm70nm1GbX16},
{ DFC_FLASH_Toshiba2GbX16, &toshiba2GbX16},
{ DFC_FLASH_NULL, NULL},
};
沒有留言:
張貼留言