|
目前我在偿试往IMX233平台上增加新的NADN FLASH驱动,支持K9GAG08U0E。
由于K9GAG08U0E的PAGE SIZE是8K,而233的ECC加速器只支持一次处理4K的数据编码,或解码。
而且也不支持24位的ECC校验。
所以我修改了数据缓冲区大小
#define NAND_MAX_OOBSIZE (436 * NAND_MAX_CHIPS)
#define NAND_MAX_PAGESIZE (8192 * NAND_MAX_CHIPS)
同时修改了GPMI底层位于gpmi-nfc-hal-v0.c的两个函数,
static int read_page(struct gpmi_nfc_data *this, unsigned chip,dma_addr_t payload, dma_addr_t auxiliary)
static int send_page(struct gpmi_nfc_data *this, unsigned chip,dma_addr_t payload, dma_addr_t auxiliary)
将这个两函数改成:对于8K PAGE SIZE的FLASH读写操作分成两次4K的数据读写。使得命令的执行过程变成如下:
页读命令+地址--ECC读4K数据+ECC读4K数据--等待就绪
页写命令+地址--ECC写4K数据+ECC写4K数据--执行页写入命令--读状态字
其中 read_page_4k、 send_page_4k 是由原来的页读写函数修改而来,只是DMA读写的数据长度由current_page_size传递
(原文件名:11.png)
(原文件名:12.png)
为了确保ECC仍然是16位模式我修改了
gpmi-nfc-hal-common.c int gpmi_nfc_set_geometry(struct gpmi_nfc_data *this)
gpmi-nfc-hal-v0.c static int set_geometry(struct gpmi_nfc_data *this) 类似于如下形式:(选中高亮的部分为新增加的代码)
(原文件名:13.png)
类似的 gpmi_nfc_set_geometry函数也做了相应的调整 。
然后增加新的FLASH器件信息,修改了
nand_device_info.c
static struct nand_device_info
nand_device_info_table_type_15[]
增加如下信息:
(原文件名:14.png)
同时修改了nand_base.c
static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
struct nand_chip *chip, int busw, int *maf_id)
经过以上修改后,使用Manufacturing Tool MfgTool.exe下载编译后的文件,可以看到程序顺利执行完成下载动作。并且如果打开MTD DEBUG选项,可以看到往FLASH里写数据返回状态字0XE0,FLASH器件返回写入成功。
(MfgTool.exe这个工具是先将LINUX内核通过USB下载到板上的RAM,然后跳转执行,再利用内核对NAND FLASH驱动支持,将数据下载到NAND FLASH中。)
但是重启后并没有执行,现在我怀疑NAND FLASH驱动逻辑虽然正确,但可能是由于时序的差异造成读写数据不正确。于是我继续跟踪代码。找到位于
gpmi-nfc-hal-v0.c
static int set_timing(struct gpmi_nfc_data *this,const struct gpmi_nfc_timing *timing)
{
struct nfc_hal *nfc = this->nfc;
/* Accept the new timing. */
nfc->timing = *timing;
/* Return success. */
return 0;
}
发现这个函数只是简单的将nfc->timing这个指针指向参数timing所指向的地址,并没有使用这些参数具体的设置GPMI相关的寄存器。
我现在不明白为什么原来的BSP只做到这一步,是不是由于所有的对NAND FLASH操作都是通过等待ready/busy信号来判断操作是否完成,所以不需要去设置这些?
但是我想应该还是要设置的吧。
但接下去我要补充这部分代码我就需要知道GPMI_CLK的设置是多少,于是我根据这张图去寻找:
(原文件名:Screenshot-1.png)
最后找到位于linux-2.6.31/arch/arm/plat-stmp3xxx/clock.c 对于GPMI时钟设定相关的地方:
static struct clk_lookup onchip_clks[] = {
….....
{
.con_id = "pll",
.clk = &pll_clk,
},
…........
….......
{
.con_id = "gpmi",
.clk = &gpmi_clk,
},
…....
}
static struct clk pll_clk = {
.parent = &osc_24M,
.enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0,
.enable_shift = 16,
.enable_wait = 10,
.flags = FIXED_RATE | ENABLED,
.rate = 480000,
.ops = &min_ops,
};
static struct clk gpmi_clk = {
.parent = &io_clk,
.scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
.busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
.busy_bit = 29,
.enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
.enable_shift = 31,
.enable_negate = 1,
.bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
.bypass_shift = 4,
.flags = NEEDS_SET_PARENT,
.ops = &std_ops,
};
它并没有像pll_clk那样子设置 .rate这个域。
我想知道它在哪设置了GPMI_CLK,还有为什么明明下载工具提示下载完成。可运行不起来。 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|