problem in probing flash for MTD

xiangguo_li at hotmail.com xiangguo_li at hotmail.com
Mon Jun 23 20:21:29 EDT 2008


hello,

the system is similar to HPC-II from Freescale, but a SMP system with two 
MPC7448 and Tsi109. the development platform is ELDK(v4.1, Linux version 
2.6.23.1), and the host system is Fedora 7.

the problem is: the probing result of flash is not correct: the (big) flash 
system is made up of two 16-bit (28F128, x8/x16, in x16 mode), while in 
Linux codes, member '.bankwidth' in 'struct map_info' could not set to 4 
(32-bit) and 2 (16-bit) -- if set so, the result is "map probe failed", but 
could only be set to '1'.

(1) probing in U-Boot is correct and reading\ writting\ erasing are normal. 
the 'fli' command in U-Boot results in the following:
---
Bank # 2: CFI conformant FLASH (32 x 16)  Size: 32 MB in 128 Sectors
  Intel Extended command set, Manufacturer ID: 0x89, Device ID: 0x18
  Erase timeout: 4096 ms, write timeout: 1 ms
  Buffer write timeout: 2 ms, buffer size: 32 bytes

  Sector Start Addresses:
  FC000000        FC040000        ......
DF80000        FDFC0000
---
according to:
printf ("CFI conformant FLASH (%d x %d)",
(info->portwidth << 3), (info->chipwidth << 3));
printf (" Size: %ld MB in %d Sectors\n",
info->size >> 20, info->sector_count);

it's clear that info->portwidth is 32, and info->chipwidth is 16.
the result is correct.

(2) the probing result in Linux initialization is in the following 
(.bankwidth=1):
---
SMP7448 Small Flash: Found 1 x8 devices at 0x0 in 8-bit bank

number of JEDEC chips: 1

cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.

Creating 2 MTD partitions on "SMP7448 Small Flash":

0x00000000-0x00040000 : "u-boot"

mtd: Giving out device 1 to u-boot

0x00040000-0x00080000 : "global"

mtd: Giving out device 2 to global
---
smp7448: big flash mapping: 2000000 @ fc000000

SMP7448 Big Flash: Found 1 x32 devices at 0x0 in 8-bit bank

Intel/Sharp Extended Query Table at 0x0031

Using buffer write method

cfi_cmdset_0001: Erase suspend on write enabled

Creating 4 MTD partitions on "SMP7448 Big Flash":

0x00000000-0x00200000 : "kernel"

mtd: Giving out device 3 to kernel

0x00200000-0x00240000 : "dtb"

mtd: Giving out device 4 to dtb

0x00240000-0x00640000 : "initrd"

mtd: Giving out device 5 to initrd

0x00640000-0x02000000 : "jffs2"

mtd: partition "jffs2" extends beyond the end of device "SMP7448 Big 
Flash" -- size truncated to 0x9c0000

mtd: Giving out device 6 to jffs2
---
the flash system could be probed, but the result is not correct.

according  cofiguration options are like these:
---

CONFIG_MTD=y

CONFIG_MTD_DEBUG=y

CONFIG_MTD_DEBUG_VERBOSE=3

CONFIG_MTD_CONCAT=y

CONFIG_MTD_PARTITIONS=y

CONFIG_MTD_CHAR=y

CONFIG_MTD_BLKDEVS=y

CONFIG_MTD_BLOCK=y

CONFIG_MTD_CFI=y

CONFIG_MTD_JEDECPROBE=y

CONFIG_MTD_GEN_PROBE=y

CONFIG_MTD_MAP_BANK_WIDTH_1=y

CONFIG_MTD_MAP_BANK_WIDTH_2=y

CONFIG_MTD_MAP_BANK_WIDTH_4=y

CONFIG_MTD_CFI_I1=y

CONFIG_MTD_CFI_I2=y

CONFIG_MTD_CFI_INTELEXT=y

CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_ROM=y

CONFIG_MTD_SMP7448=y
---

(3) because HPC-II platform is similar to my board, I compiled the kernel of 
mpc7448_hpc2 with my map_info file added, and the result of flash probing 
was the same as my own, that is, .bankwidth could not be set to 2 and 4, 
when set to 1, the result was the same above.

(4) I printed the register values of Tsi109's HLP interface (the one flash 
attached), the value unchanged.

==>
the result in U-Boot is correct, it seems that hardware wiring and register 
configuration are correct.

it is quite strange that the results in both HPC-II and my own are the same.

I have been puzzled with this for two weeks, please give me any advice and 
information of this problem. what is the possible reason and what may i do?

should i supply more information?

thank you ver much!


----------------------------
/*
 *
 * drivers/mtd/maps/smp7448.c
 *
 * FLASH map for the SMP7448 boards.
 *
 * 2008 IACAS This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>

#include <asm/io.h>

#define SMALL_ADDR	0xfff00000
#define SMALL_SIZE	0x00080000

#define BIG_ADDR 	0xfc000000
#define BIG_SIZE 	0x02000000


static struct mtd_partition smp7448_small_partitions[] = {
	{
		.name = "u-boot",
		.offset = 0x00000000,
		.size = 0x00040000,
		.mask_flags = MTD_WRITEABLE     /* force read-only */
	},
	{
		.name = "global",
		.offset = 0x00040000,
		.size = 0x00040000
	}
};

struct map_info smp7448_small_map = {
	.name = "SMP7448 Small Flash",
	.size = SMALL_SIZE,
	.bankwidth = 1,
	.phys = SMALL_ADDR,
};

static struct mtd_partition smp7448_big_partitions[] = {
	{
		.name = "kernel",		/* Kernel */
		.offset = 0,
		.size = 0x00200000,
		.mask_flags = MTD_WRITEABLE	/* force read-only */
	},
        {
                .name = "dtb",			/* flattened device tree */
                .offset = 0x00200000,
                .size = 0x00040000,
                .mask_flags = MTD_WRITEABLE    /* force read-only */
        },
	{
		.name = "initrd",		/* ramdisk image */
		.offset = 0x00240000,
		.size = 0x00400000,
		.mask_flags = MTD_WRITEABLE    /* force read-only */
	},
	{
		.name = "jffs2",		/* jffs2 fs */
		.offset = 0x00640000,
		.size = 0x019c0000
	}
};


struct map_info smp7448_big_map = {
	.name = "SMP7448 Big Flash",
	.size = BIG_SIZE,
	.bankwidth = 4,
	.phys = BIG_ADDR,
};


static struct mtd_info *smp7448_mtd;

int __init init_smp7448_flash(void)
{

	printk(KERN_NOTICE "smp7448: small flash mapping: %x @ %x\n",
	       SMALL_SIZE, SMALL_ADDR);
	smp7448_small_map.virt = ioremap(SMALL_ADDR, SMALL_SIZE);
	if (!smp7448_small_map.virt) {
		printk("init_smp7448_flash: failed to ioremap for small flash\n");
		return -EIO;
	}
	simple_map_init(&smp7448_small_map);
	smp7448_mtd = do_map_probe("jedec_probe", &smp7448_small_map);
	if (smp7448_mtd) {
		smp7448_mtd->owner = THIS_MODULE;
		add_mtd_partitions(smp7448_mtd,
				   smp7448_small_partitions,
				   ARRAY_SIZE(smp7448_small_partitions));
	} else {
		printk("map probe failed (small flash)\n");
		return -ENXIO;
	}

	printk(KERN_NOTICE "smp7448: big flash mapping: %x @ %x\n",
	       BIG_SIZE, BIG_ADDR);
	smp7448_big_map.virt = ioremap(BIG_ADDR, BIG_SIZE);
	if (!smp7448_big_map.virt) {
		printk("init_smp7448_flash: failed to ioremap for big flash\n");
		return -EIO;
	}
	simple_map_init(&smp7448_big_map);
	smp7448_mtd = do_map_probe("cfi_probe", &smp7448_big_map);
	if (smp7448_mtd) {
		smp7448_mtd->owner = THIS_MODULE;
		add_mtd_partitions(smp7448_mtd,
				   smp7448_big_partitions,
				   ARRAY_SIZE(smp7448_big_partitions));
	} else {
		printk("map probe failed (big flash)\n");
		return -ENXIO;
	}

	return 0;
}

static void __exit cleanup_smp7448_flash(void)
{
	if (smp7448_mtd) {
		del_mtd_partitions(smp7448_mtd);
		/* moved iounmap after map_destroy - armin */
		map_destroy(smp7448_mtd);
	}

	if (smp7448_small_map.virt)
		iounmap((void *)smp7448_small_map.virt);
	if (smp7448_big_map.virt)
		iounmap((void *)smp7448_big_map.virt);
}

module_init(init_smp7448_flash);
module_exit(cleanup_smp7448_flash);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MTD map driver for the SMP7448 board");

-lxg 




More information about the linux-mtd mailing list