/* 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}, };
沒有留言:
張貼留言