JEDEC support broken?
Alice Hennessy
ahennessy at mvista.com
Wed Nov 15 13:15:08 EST 2000
David Woodhouse wrote:
> On Tue, 14 Nov 2000, Alice Hennessy wrote:
>
> > Do you mean to use map->size instead of bank_size (to spread the
> > individual start offsets over if there are gaps between chips)
>
> Nope, discard the concept of bank_size altogether. Each chip needs its own
> information structure, much like the 'struct flchip' in
> include/mtd/flashchip.h, which contains the start offset of the chip in
> the map.
>
> It's reasonable to assume that all chips in the array will be the same
> size. You have an array of struct flchip (or your equivalent if you don't
> want to use struct flchip) and you index into that by dividing by the
> individual chip size - and then just address the chip you've selected by
> using the start offset listed for it.
>
> > Also, is spin_lock support going to be added in jedec.c?
>
> It certainly _needs_ doing. Feel free :)
>
> > I have a board that needs support for both cfi and jedec flashes.
> > So, the approach I have taken is to use physmap.c with an array of
> > "physmap_info" structures that describe the window address, window
> > size, buswidth and number of partitions for each flash.
> < ... deletia ... >
>
> > Is this in keeping with the intent of the map file?
>
> Sounds like it. Show us the code though.
>
> --
> dwmw2
>
> To unsubscribe, send "unsubscribe mtd" to majordomo at infradead.org
Attached is my physmap.c.
Alice
-------------- next part --------------
/*
* $Id: physmap.c,v 1.3 2000/07/20 14:18:02 dwmw2 Exp $
*
* Normal mappings of chips in physical memory
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/config.h>
__u8 physmap_read8(struct map_info *map, unsigned long ofs)
{
// printk("physmap_read8 at %x\n",map->map_priv_1 + ofs);
return readb(map->map_priv_1 + ofs);
}
__u16 physmap_read16(struct map_info *map, unsigned long ofs)
{
return readw(map->map_priv_1 + ofs);
}
__u32 physmap_read32(struct map_info *map, unsigned long ofs)
{
return readl(map->map_priv_1 + ofs);
}
void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
{
memcpy_fromio(to, map->map_priv_1 + from, len);
}
void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
{
// printk("physmap_write8 %x at %x\n",d,map->map_priv_1 + adr);
writeb(d, map->map_priv_1 + adr);
}
void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
{
writew(d, map->map_priv_1 + adr);
}
void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
{
//printk("physmap_write32 %x at %x\n",d,map->map_priv_1 + adr);
writel(d, map->map_priv_1 + adr);
}
void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
{
memcpy_toio(map->map_priv_1 + to, from, len);
}
void physmap_set_vpp(int vpp)
{
}
const struct map_info basic_physmap_map = {
NULL,
0,
0,
physmap_read8,
physmap_read16,
physmap_read32,
physmap_copy_from,
physmap_write8,
physmap_write16,
physmap_write32,
physmap_copy_to,
physmap_set_vpp,
0,
0
};
/* board and partition description */
#define MAX_PHYSMAP_PARTITIONS 8
struct physmap_info {
char *name;
unsigned long window_addr;
unsigned long window_size;
int buswidth;
int num_partitions;
};
#define PHYSMAP_NUMBER 2 // number of physmap_info structs needed
const struct physmap_info physmap_board_desc[PHYSMAP_NUMBER] =
{
{ // Am29DL323D in 2x16 configuration
"big flash", // name
0x40000000, // window_addr
0x00800000, // window_size
4, // buswidth
2, // num_partitions
},
{ // Am29W040B in 1x8 configuration
"boot flash", // name
0xfff80000, // window_addr
0x00060000, // window_size
1, // buswidth
2, // num_partitions
},
};
static struct mtd_partition physmap_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
{ // Am29DL323D in 2x16 configuration
{
name: "big flash 128k sectors",
size: 0x007E0000, // 63 x (2 x 64k) byte sectors
offset: 0,
},
{
name: "big flash 16k sectors",
size: 0x00020000, // 8 x (2 x 8k) byte sectors
offset: 0x007E0000,
},
},
{ // Am29W040B in 1x8 configuration
{
name: "boot environment",
size: 0x00010000, // 1 x 64k byte sectors
offset: 0
},
{
name: "boot flash sectors",
size: 0x00050000, // 5 x 64k byte sectors
offset: 0x10000
},
}
};
struct map_info physmap_map[PHYSMAP_NUMBER];
int __init init_physmap(void)
{
int i;
struct mtd_info *mymtd;
struct mtd_partition *parts;
/* Initialize mapping */
for (i=0;i<PHYSMAP_NUMBER;i++) {
printk(KERN_NOTICE "physmap flash device: %x at %x\n", (unsigned int)physmap_board_desc[i].window_size, (unsigned int)physmap_board_desc[i].window_addr);
memcpy((char *)&physmap_map[i],(char *)&basic_physmap_map,sizeof(struct map_info));
physmap_map[i].map_priv_1 = (unsigned long)ioremap(physmap_board_desc[i].window_addr, physmap_board_desc[i].window_size);
if (!physmap_map[i].map_priv_1) {
printk(KERN_WARNING "Failed to ioremap\n");
return -EIO;
}
physmap_map[i].name = physmap_board_desc[i].name;
physmap_map[i].size = physmap_board_desc[i].window_size;
physmap_map[i].buswidth = physmap_board_desc[i].buswidth;
printk(KERN_NOTICE "physmap: ioremap is %x\n",(unsigned int)(physmap_map[i].map_priv_1));
}
for (i=0;i<PHYSMAP_NUMBER;i++) {
parts = &physmap_partitions[i][0];
mymtd = do_cfi_probe(&physmap_map[i]);
if (!mymtd) {
mymtd = do_jedec_probe(&physmap_map[i]);
}
if (mymtd) {
#ifdef MODULE
mymtd->module = &__this_module;
#endif
/* save mymtd for cleanup */
physmap_map[i].map_priv_2 = (unsigned long)mymtd;
add_mtd_partitions(mymtd, parts, physmap_board_desc[i].num_partitions);
}
else
return -ENXIO;
}
return 0;
}
static void __exit cleanup_physmap(void)
{
int i;
struct mtd_info *mymtd;
for (i=0;i<PHYSMAP_NUMBER;i++) {
mymtd = (struct mtd_info *)physmap_map[i].map_priv_2;
if (mymtd) {
del_mtd_partitions(mymtd);
map_destroy(mymtd);
}
if (physmap_map[i].map_priv_1) {
iounmap((void *)physmap_map[i].map_priv_1);
physmap_map[i].map_priv_1 = 0;
}
}
}
#if LINUX_VERSION_CODE > 0x20300
module_init(init_physmap);
module_exit(cleanup_physmap);
#endif
More information about the linux-mtd
mailing list