Procházet zdrojové kódy

add preliminary support for the bifferboard, patch from bifferos

SVN-Revision: 18766
Florian Fainelli před 16 roky
rodič
revize
a39dcb405e

+ 1 - 1
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
 

+ 8 - 0
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

+ 1 - 0
target/linux/rdc/bifferboard/target.mk

@@ -0,0 +1 @@
+BOARDNAME:=Bifferboard

+ 243 - 0
target/linux/rdc/files/drivers/mtd/maps/bifferboard-flash.c

@@ -0,0 +1,243 @@
+/* Flash mapping for Bifferboard, (c) [email protected] 
+ * 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 <[email protected]>");
+MODULE_DESCRIPTION("MTD map driver for Bifferboard");
+

+ 40 - 0
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