[] (__dabt_svc+0x40/0x60) from [] (s3c24xx_nand_probe+0x2d8/
0x514)
[] (s3c24xx_nand_probe+0x2d8/0x514) from [] (platform_drv_pr
obe+0x18/0x1c)
[] (platform_drv_probe+0x18/0x1c) from [] (driver_probe_devi
ce+0xa8/0x15c)
[] (driver_probe_device+0xa8/0x15c) from [] (__driver_attach
+0x5c/0x7c)
[] (__driver_attach+0x5c/0x7c) from [] (bus_for_each_dev+0x4
8/0x78)
[] (bus_for_each_dev+0x48/0x78) from [] (bus_add_driver+0x98
/0x21c)
[] (bus_add_driver+0x98/0x21c) from [] (driver_register+0xa4
/0x130)
[] (driver_register+0xa4/0x130) from [] (do_one_initcall+0x5
c/0x1b4)
[] (do_one_initcall+0x5c/0x1b4) from [] (kernel_init+0x94/0x
10c)
[] (kernel_init+0x94/0x10c) from [] (kernel_thread_exit+0x0/
0x8)
后来在网上找到相关的问题的解答在ARM9论坛上
回答是这样
图片:
请楼主注意你贴出来的以下信息:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=4, 39ns Twrph0=8 79ns, Twrph1=8 79ns
友善官方启动信息里这部分的内容是:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c2440-nand s3c2440-nand: Tacls=3, 29ns Twrph0=7 69ns, Twrph1=3 29ns
我贴上去的是友善的2.6.29.4内核的,具体的加粗部分前边的可能和友善2.6.32.2的不太一样,但是原理是一样。
从以上差别可以看出你按照友善提供的Linux移植开发实战所修改的下面一个结构体里设置的参数并没有生效:
static struct s3c2410_platform_nand mini2440_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(mini2440_nand_sets),
.sets = mini2440_nand_sets,
};
以上的结构体是mini2440开发板上使用的nand flash的一些配置信息,其中包括芯片操作时序信息。
查看nand flash相应的datasheet里面对nand flash控制器的NFCONF寄存器有如下描述
CLE/ALE是高电平使能 而TACLS是CLE/ALE使能的持续时间,也就是CLE/ALE信号线高电平持续的时间;
nWE是低电平使能 TWRPH0对应于nWE的使能持续时间,也就是nWE信号线低电平的持续时间;
而TWRPH1对应于nWE信号线高电平的持续时间。
而通过内核打印信息+Source Insight查找到输出
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=4, 39ns Twrph0=8 79ns, Twrph1=8 79ns
语句信息的函数在内核源码中nand flash驱动程序里的drivers/mtd/nand/s3c2410.c文件中。
分析Linux内核中的nand flash驱动drivers/mtd/nand/s3c2410.c文件中的相应函数,
其中的static int s3c2410_nand_setrate(struct s3c2410_nand_info *info)函数发现:
struct s3c2410_platform_nand *plat = info->platform;
int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4;
…………
info->clk_rate = clkrate;
clkrate /= 1000; /* turn clock into kHz for ease of use */
if (plat != NULL) {
tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max);
twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8);
} else {
/* default timings */
tacls = tacls_max;
twrph0 = 8;
twrph1 = 8;
}
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
dev_err(info->device, "cannot get suitable timings\n");
return -EINVAL;
}
dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
由以上内容可以看出,你的内核并没有使用你的mini2440_nand_info结构体中的配置,而是使用了它的默认配给,即
} else {
/* default timings */
tacls = tacls_max;
twrph0 = 8;
twrph1 = 8;
}
中的配置信息。这点和你的内核输出s3c24xx-nand s3c2440-nand: Tacls=4, 39ns Twrph0=8 79ns, Twrph1=8 79ns完全符合。
因此可以判断你没有在你的mach-mini2440.c中加入s3c_nand_set_platdata(&mini2440_nand_info);语句来设置你当前平台所使用的存储nand flash配置的相应结构体mini2440_nand_info。
解决方法:
只需在mach-mini2440.c的初始化函数mini2440_machine_init(void)里加入s3c_nand_set_platdata(&mini2440_nand_info);即可。
但是我按上面的回答加入s3c_nand_set_platdata(&mini2440_nand_info);后编译还是出错。在查查资料原来2.6.32.2不支持这个。
因此可以判断我们需要在mach-mini2440.c的mini2440_machine_init()函数中增加s3c_device_nand.dev.platform_data = &mini2440_nand_info; 即可。这个对比友善公司给你那个mach—mini2440对照。
static void __init mini2440_machine_init(void)
{
#if defined (LCD_WIDTH)
s3c24xx_fb_set_platdata(&mini2440_fb_info);
#endif
s3c_i2c0_set_platdata(NULL);
s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);
s3c_device_nand.dev.platform_data = &friendly_arm_nand_info;
s3c_device_sdi.dev.platform_data = &mini2440_mmc_cfg;
platform_add_devices(mini2440_devices, ARRAY_SIZE(mini2440_devices));
s3c_pm_init();
}
static struct s3c2410_platform_nand friendly_arm_nand_info = {
.tacls = 20,
.twrph0 = 60,
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(friendly_arm_nand_sets),
.sets = friendly_arm_nand_sets,
.ignore_unset_ecc = 1,
};
经过对比可以看出。按照移植手册我们需要加入s3c_device_nand.dev.platform_data = &mini2440_nand_info;
重新编译就行了。
阅读(928) | 评论(0) | 转发(0) |