diff options
Diffstat (limited to 'target')
| -rw-r--r-- | target/linux/rdc/Makefile | 2 | ||||
| -rw-r--r-- | target/linux/rdc/bifferboard/config-2.6.30 | 8 | ||||
| -rw-r--r-- | target/linux/rdc/bifferboard/target.mk | 1 | ||||
| -rw-r--r-- | target/linux/rdc/files/drivers/mtd/maps/bifferboard-flash.c | 243 | ||||
| -rwxr-xr-x | target/linux/rdc/image/mkimg_bifferboard.py | 40 | 
5 files changed, 293 insertions, 1 deletions
| diff --git a/target/linux/rdc/Makefile b/target/linux/rdc/Makefile index 141e86e8f..a8ca8f856 100644 --- a/target/linux/rdc/Makefile +++ b/target/linux/rdc/Makefile @@ -11,7 +11,7 @@ BOARD:=rdc  BOARDNAME:=RDC 321x  FEATURES:=squashfs jffs2 pci usb pcmcia  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 diff --git a/target/linux/rdc/bifferboard/config-2.6.30 b/target/linux/rdc/bifferboard/config-2.6.30 new file mode 100644 index 000000000..e37e74ca0 --- /dev/null +++ b/target/linux/rdc/bifferboard/config-2.6.30 @@ -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 diff --git a/target/linux/rdc/bifferboard/target.mk b/target/linux/rdc/bifferboard/target.mk new file mode 100644 index 000000000..24dd13f5a --- /dev/null +++ b/target/linux/rdc/bifferboard/target.mk @@ -0,0 +1 @@ +BOARDNAME:=Bifferboard diff --git a/target/linux/rdc/files/drivers/mtd/maps/bifferboard-flash.c b/target/linux/rdc/files/drivers/mtd/maps/bifferboard-flash.c new file mode 100644 index 000000000..e732334e9 --- /dev/null +++ b/target/linux/rdc/files/drivers/mtd/maps/bifferboard-flash.c @@ -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"); + diff --git a/target/linux/rdc/image/mkimg_bifferboard.py b/target/linux/rdc/image/mkimg_bifferboard.py new file mode 100755 index 000000000..040c46274 --- /dev/null +++ b/target/linux/rdc/image/mkimg_bifferboard.py @@ -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 | 
