[rdc] add preliminary support for the bifferboard, patch from bifferos
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@18766 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
6599c8df66
commit
c8469bf0f4
|
@ -11,7 +11,7 @@ BOARD:=rdc
|
||||||
BOARDNAME:=RDC 321x
|
BOARDNAME:=RDC 321x
|
||||||
FEATURES:=squashfs jffs2 pci usb pcmcia
|
FEATURES:=squashfs jffs2 pci usb pcmcia
|
||||||
CFLAGS:=-Os -pipe -march=i486 -funit-at-a-time
|
CFLAGS:=-Os -pipe -march=i486 -funit-at-a-time
|
||||||
SUBTARGETS:=amit ar525w r8610 dir-450 sitecom
|
SUBTARGETS:=amit ar525w r8610 dir-450 sitecom bifferboard
|
||||||
|
|
||||||
LINUX_VERSION:=2.6.30.10
|
LINUX_VERSION:=2.6.30.10
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
CONFIG_CMDLINE="console=ttyS0,115200 rootfstype=squashfs,jffs2"
|
||||||
|
# CONFIG_MTD_PHYSMAP is not set
|
||||||
|
CONFIG_MTD_RDC3210=y
|
||||||
|
CONFIG_MTD_RDC3210_ALLOW_JFFS2=y
|
||||||
|
CONFIG_MTD_RDC3210_BUSWIDTH=2
|
||||||
|
# CONFIG_MTD_RDC3210_FACTORY_PRESENT is not set
|
||||||
|
CONFIG_MTD_RDC3210_SIZE=0x800000
|
||||||
|
# CONFIG_MTD_RDC3210_STATIC_MAP is not set
|
|
@ -0,0 +1 @@
|
||||||
|
BOARDNAME:=Bifferboard
|
|
@ -0,0 +1,243 @@
|
||||||
|
/* Flash mapping for Bifferboard, (c) bifferos@yahoo.co.uk
|
||||||
|
* Works with 1, 4 and 8MB flash versions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/mtd/mtd.h>
|
||||||
|
#include <linux/mtd/map.h>
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
|
||||||
|
#define DRV "bifferboard-flash: "
|
||||||
|
|
||||||
|
static struct mtd_info *bb_mtd = NULL;
|
||||||
|
|
||||||
|
#define SIZE_BIFFBOOT 0x10000
|
||||||
|
#define SIZE_SECTOR 0x10000
|
||||||
|
#define SIZE_CONFIG 0x02000
|
||||||
|
#define SIZE_1MB 0x00100000
|
||||||
|
#define SIZE_4MB 0x00400000
|
||||||
|
#define SIZE_8MB 0x00800000
|
||||||
|
|
||||||
|
#define BASE_1MB 0xfff00000
|
||||||
|
#define BASE_4MB 0xffc00000
|
||||||
|
#define BASE_8MB 0xff800000
|
||||||
|
|
||||||
|
#define OFFS_KERNEL 0x6000
|
||||||
|
#define OFFS_CONFIG 0x4000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flash detection code. This is needed because the cfi_probe doesn't probe
|
||||||
|
* for the size correctly. You actually have to know the flash size before you
|
||||||
|
* call it, or so it seems. It does work correctly if you map the entire flash
|
||||||
|
* chip, but unsure of the implications for mapping more mem than exists.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char ReadFlash(void* base, u32 addr)
|
||||||
|
{
|
||||||
|
unsigned char val = *(volatile unsigned char *)(base+addr);
|
||||||
|
udelay(1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteFlash(void* base, u32 addr, unsigned short data)
|
||||||
|
{
|
||||||
|
*(volatile unsigned short *)(base+addr) = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(flash_lock);
|
||||||
|
|
||||||
|
static u32 bb_detect(void)
|
||||||
|
{
|
||||||
|
u32 ret = 0;
|
||||||
|
ulong flags;
|
||||||
|
|
||||||
|
/* for detection, map in just the 1MB device, 1st 64k is enough */
|
||||||
|
void* base = ioremap_nocache(BASE_1MB, 0x10000);
|
||||||
|
|
||||||
|
if (!base)
|
||||||
|
{
|
||||||
|
pr_err(DRV "Failed to map flash for probing\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_lock_irqsave(&flash_lock, flags);
|
||||||
|
|
||||||
|
/* put flash in auto-detect mode */
|
||||||
|
WriteFlash(base, 0xaaaa, 0xaaaa);
|
||||||
|
WriteFlash(base, 0x5554, 0x5555);
|
||||||
|
WriteFlash(base, 0xaaaa, 0x9090);
|
||||||
|
|
||||||
|
/* Read the auto-config data - 4 values in total */
|
||||||
|
ret = ReadFlash(base, 0x0000); ret <<= 8;
|
||||||
|
ret |= ReadFlash(base, 0x0200); ret <<= 8;
|
||||||
|
ret |= ReadFlash(base, 0x0003); ret <<= 8;
|
||||||
|
ret |= ReadFlash(base, 0x0002);
|
||||||
|
|
||||||
|
/* exit the autodetect state */
|
||||||
|
WriteFlash(base, 0x0000, 0xf0f0);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&flash_lock, flags);
|
||||||
|
|
||||||
|
/* unmap it, it'll be re-mapped based on the detection */
|
||||||
|
iounmap(base);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct map_info bb_map;
|
||||||
|
|
||||||
|
/* Update the map, using the detected flash signature. */
|
||||||
|
static int bb_adjust_map(unsigned long sig, struct map_info* m)
|
||||||
|
{
|
||||||
|
m->bankwidth = 2;
|
||||||
|
switch (sig)
|
||||||
|
{
|
||||||
|
case 0x7f1c225b :
|
||||||
|
m->name = "ENLV800B";
|
||||||
|
m->phys = BASE_1MB;
|
||||||
|
m->size = SIZE_1MB;
|
||||||
|
break;
|
||||||
|
case 0x7f1c22f9 :
|
||||||
|
m->name = "ENLV320B";
|
||||||
|
m->phys = BASE_4MB;
|
||||||
|
m->size = SIZE_4MB;
|
||||||
|
break;
|
||||||
|
case 0x7f1c22cb :
|
||||||
|
m->name = "ENLV640B";
|
||||||
|
m->phys = BASE_8MB;
|
||||||
|
m->size = SIZE_8MB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* adjust partition sizes, prior to adding the partition
|
||||||
|
* Values not specified by defines here are subject to replacement based on
|
||||||
|
* the real flash size. (0x00000000 being the exception, of course) */
|
||||||
|
|
||||||
|
static struct mtd_partition bb_parts[] =
|
||||||
|
{
|
||||||
|
/* 0 */ { name: "kernel", offset: 0x00000000, size: 0x000fa000 },
|
||||||
|
/* 1 */ { name: "rootfs", offset: MTDPART_OFS_APPEND, size: 0x002F0000 },
|
||||||
|
/* 2 */ { name: "biffboot", offset: MTDPART_OFS_APPEND, size: MTDPART_SIZ_FULL, mask_flags: MTD_WRITEABLE },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* returns the count of partitions to be used */
|
||||||
|
static ulong bb_adjust_partitions(struct map_info* m)
|
||||||
|
{
|
||||||
|
/* Read the kernel offset value, 1036 bytes into the config block. */
|
||||||
|
u16 km_units = *((u16*)(m->virt + OFFS_CONFIG + 1036));
|
||||||
|
u32 kernelmax = 0x200000; /* Biffboot 2.7 or earlier default */
|
||||||
|
|
||||||
|
/* special-case 1MB devices, because there are fewer partitions */
|
||||||
|
if (m->size == SIZE_1MB)
|
||||||
|
{
|
||||||
|
bb_parts[0].size = SIZE_1MB - SIZE_BIFFBOOT; /* kernel */
|
||||||
|
bb_parts[1].name = "biffboot"; /* biffboot */
|
||||||
|
bb_parts[1].offset = MTDPART_OFS_APPEND; /* biffboot */
|
||||||
|
bb_parts[1].size = MTDPART_SIZ_FULL; /* biffboot */
|
||||||
|
bb_parts[1].mask_flags = MTD_WRITEABLE;
|
||||||
|
return 2; /* because there's no rootfs now */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (km_units > ((m->size-SIZE_BIFFBOOT)/SIZE_SECTOR))
|
||||||
|
{
|
||||||
|
pr_err(DRV "config block has invalid kernelmax\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernelmax = km_units * SIZE_SECTOR;
|
||||||
|
|
||||||
|
/* Kernel */
|
||||||
|
bb_parts[0].size = kernelmax;
|
||||||
|
|
||||||
|
/* rootfs */
|
||||||
|
bb_parts[1].size = m->size - kernelmax - SIZE_BIFFBOOT;
|
||||||
|
|
||||||
|
return 3; /* 3 partitions */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __init init_bb_map(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ulong signature = bb_detect();
|
||||||
|
ulong part_len;
|
||||||
|
|
||||||
|
if (!signature)
|
||||||
|
{
|
||||||
|
pr_err(DRV "Undetected flash chip");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bb_adjust_map(signature, &bb_map);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
pr_err(DRV "Unrecognised flash chip (signature: 0x%lx)\n", signature);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb_map.virt = ioremap_nocache(bb_map.phys, bb_map.size);
|
||||||
|
if (!bb_map.virt)
|
||||||
|
{
|
||||||
|
pr_err(DRV "ioremap\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb_mtd = do_map_probe("cfi_probe", &bb_map);
|
||||||
|
if (!bb_mtd)
|
||||||
|
{
|
||||||
|
/* cfi_probe fails here for 1MB devices */
|
||||||
|
pr_err(DRV "cfi_probe\n");
|
||||||
|
ret = -ENXIO;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
part_len = bb_adjust_partitions(&bb_map);
|
||||||
|
if (!part_len)
|
||||||
|
{
|
||||||
|
pr_err(DRV "no partitions established");
|
||||||
|
ret = -ENXIO;
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bb_mtd->owner = THIS_MODULE;
|
||||||
|
ret = add_mtd_partitions(bb_mtd, bb_parts, part_len);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
pr_err(DRV "add_mtd_partitions\n");
|
||||||
|
ret = -ENXIO;
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err2:
|
||||||
|
map_destroy(bb_mtd);
|
||||||
|
err:
|
||||||
|
iounmap(bb_map.virt);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit exit_bb_map(void)
|
||||||
|
{
|
||||||
|
del_mtd_partitions(bb_mtd);
|
||||||
|
map_destroy(bb_mtd);
|
||||||
|
iounmap(bb_map.virt);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(init_bb_map);
|
||||||
|
module_exit(exit_bb_map);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Bifferos <bifferos@yahoo.co.uk>");
|
||||||
|
MODULE_DESCRIPTION("MTD map driver for Bifferboard");
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Create firmware for 8MB Bifferboards
|
||||||
|
Firmware does not include the config blocks
|
||||||
|
Firmware starts just after config
|
||||||
|
"""
|
||||||
|
|
||||||
|
import struct, sys
|
||||||
|
|
||||||
|
kernel_extent = 0x200000
|
||||||
|
config = 0x6000
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
print "usage: mkimg_bifferboard.py <kernel> <64k JFFS> <output file>"
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
bzimage = sys.argv[1]
|
||||||
|
rootfs = sys.argv[2]
|
||||||
|
target = sys.argv[3]
|
||||||
|
|
||||||
|
# Kernel first
|
||||||
|
fw = file(bzimage).read()
|
||||||
|
if len(fw) > (kernel_extent - config):
|
||||||
|
raise IOError("Kernel too large")
|
||||||
|
|
||||||
|
# Pad up to 0x200000
|
||||||
|
while len(fw) < (kernel_extent - config):
|
||||||
|
fw += "\xff"
|
||||||
|
|
||||||
|
fw += file(rootfs).read()
|
||||||
|
|
||||||
|
# Check length of total
|
||||||
|
if len(fw) > (0x800000 - 0x10000 - 0x6000):
|
||||||
|
raise IOError("Rootfs too large")
|
||||||
|
|
||||||
|
file(target,"wb").write(fw)
|
||||||
|
print "Firmware written to '%s'" % target
|
Loading…
Reference in New Issue