From: M. R. B. <mr...@us...> - 2002-11-03 12:27:29
|
Update of /cvsroot/linuxdc/linux-sh-dc/drivers/mtd/maps In directory usw-pr-cvs1:/tmp/cvs-serv30413/drivers/mtd/maps Modified Files: Tag: linux-sh-dc-2_4-branch Config.in Makefile Added Files: Tag: linux-sh-dc-2_4-branch dreamcast-flash.c Log Message: Dreamcast internal flash support (read tested only) --- NEW FILE: dreamcast-flash.c --- /* * drivers/mtd/maps/dreamcast-flash.c * * SEGA Dreamcast internal flash device support. * * Copyright (C) 2002 M. R. Brown * * Released under the terms of the GNU GPL v2. * * This code is based dbox2-flash.c, written by Kári Davíðsson <kd...@fl...> */ #include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/mtd/mtd.h> #include <linux/mtd/map.h> #include <linux/mtd/partitions.h> #include <asm/io.h> #define DREAMCAST_FLASH_ADDR 0x00200000 #define DREAMCAST_FLASH_SIZE 0x20000 static struct mtd_info *dreamcast_mtd; /* * SEGA Dreamcast "Dare to be different" * * The Dreamcast utilizes a Fujitsu MBM29LV002TC 256k x 8bit flash device. * The device is sold with a default of 7 sectors, totalling 256kb. For * whatever reason, SEGA decided to only allow the latter 5 sectors to be * physically accessible on the bus, so that only the last 128k of flash are * available. They also devised a nifty logical partition layout that isn't * contiguous to the physical layout. * Here is the mapping from device physical sectors to SEGA logical ones: * * Phys | Log | Offset | Size | * ------------------------------ * 0 | N/A | 0 | 64k | * 1 | N/A | 10000 | 64k | * 2 | 4 | 20000 | 64k | * 3 | 3 | 30000 | 32k | * 4 | 1 | 38000 | 8k | * 5 | 0 | 3a000 | 8k | * 6 | 2 | 3c000 | 16k | * * It gets better. After reaching the end of the first 128k block of flash * (remember that this is really the second half of the full 256k) the flash * repeats itself every 128k beginning with physical sector 2. Our only * saving grace is that because the first 128k are missing, using the physical * sector 2 address for logical partition 4 puts us on an erase block. * Thankfully we can use the absolute sector addresses as is within the MTD * partition layout. * * Thank you SEGA, for daring to be different. */ static struct mtd_partition dreamcast_partitions[] = { { name: "System configuration", size: 8 * 1024, offset: 0x3a000, mask_flags: MTD_WRITEABLE, /* _not_ writeable */ }, { name: "Microsoft reserved", size: 8 * 1024, offset: 0x38000, }, { name: "Network configuration", size: 16 * 1024, offset: 0x3c000, }, { name: "Game / User save area", size: 32 * 1024, offset: 0x30000, }, { name: "Backup / metainformation", size: 64 * 1024, offset: 0x20000, } }; #define NUM_PARTITIONS (sizeof(dreamcast_partitions) / \ sizeof(dreamcast_partitions[0])) /* * Access routines. */ static __u8 dreamcast_flash_read8(struct map_info *map, unsigned long ofs) { return __raw_readb(map->map_priv_1 + ofs); } static __u16 dreamcast_flash_read16(struct map_info *map, unsigned long ofs) { return __raw_readw(map->map_priv_1 + ofs); } static __u32 dreamcast_flash_read32(struct map_info *map, unsigned long ofs) { return __raw_readl(map->map_priv_1 + ofs); } static void dreamcast_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { memcpy_fromio(to, map->map_priv_1 + from, len); } static void dreamcast_flash_write8(struct map_info *map, __u8 d, unsigned long adr) { __raw_writeb(d, map->map_priv_1 + adr); mb(); } static void dreamcast_flash_write16(struct map_info *map, __u16 d, unsigned long adr) { __raw_writew(d, map->map_priv_1 + adr); mb(); } static void dreamcast_flash_write32(struct map_info *map, __u32 d, unsigned long adr) { __raw_writel(d, map->map_priv_1 + adr); mb(); } static void dreamcast_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { memcpy_toio(map->map_priv_1 + to, from, len); } static struct map_info dreamcast_flash_map = { name: "Dreamcast internal flash", size: DREAMCAST_FLASH_SIZE, buswidth: 1, read8: dreamcast_flash_read8, read16: dreamcast_flash_read16, read32: dreamcast_flash_read32, copy_from: dreamcast_flash_copy_from, write8: dreamcast_flash_write8, write16: dreamcast_flash_write16, write32: dreamcast_flash_write32, copy_to: dreamcast_flash_copy_to, }; static int __init dreamcast_flash_init(void) { if (!(dreamcast_flash_map.map_priv_1 = (__u32) ioremap(DREAMCAST_FLASH_ADDR, DREAMCAST_FLASH_SIZE))) { printk("DC flash: Unable to map flash memory!\n"); return -EIO; } dreamcast_mtd = do_map_probe("jedec_probe", &dreamcast_flash_map); if (!dreamcast_mtd) { iounmap((void *)dreamcast_flash_map.map_priv_1); panic("Couldn't find the flash chip?!? Fix.\n"); } dreamcast_mtd->module = THIS_MODULE; #ifdef CONFIG_MTD_DREAMCAST_NO_PART add_mtd_device(dreamcast_mtd); #else add_mtd_partitions(dreamcast_mtd, dreamcast_partitions, NUM_PARTITIONS); #endif return 0; } static void __exit dreamcast_flash_exit(void) { if (dreamcast_mtd) { #ifdef CONFIG_MTD_DREAMCAST_NO_PART del_mtd_device(dreamcast_mtd); #else del_mtd_partitions(dreamcast_mtd); #endif map_destroy(dreamcast_mtd); } if (dreamcast_flash_map.map_priv_1) { iounmap((void *)dreamcast_flash_map.map_priv_1); dreamcast_flash_map.map_priv_1 = 0; } } module_init(dreamcast_flash_init); module_exit(dreamcast_flash_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("M. R. Brown <mr...@li...>"); MODULE_DESCRIPTION("MTD map driver for the SEGA Dreamcast"); Index: Config.in =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/drivers/mtd/maps/Config.in,v retrieving revision 1.3.4.1 retrieving revision 1.3.4.2 diff -u -d -r1.3.4.1 -r1.3.4.2 --- Config.in 26 Oct 2002 14:14:01 -0000 1.3.4.1 +++ Config.in 3 Nov 2002 12:27:27 -0000 1.3.4.2 @@ -61,7 +61,11 @@ if [ "$CONFIG_MTD_SOLUTIONENGINE" != "n" ]; then hex ' Default reserved Flash size' CONFIG_MTD_SUPERH_RESERVE 0x00010000 fi - dep_tristate ' Flash device mapping on Sega Dreamcast VMU' CONFIG_MTD_VMU $CONFIG_SH_DREAMCAST + if [ "$CONFIG_SH_DREAMCAST" = "y" ]; then + tristate ' Flash device mapping on SEGA Dreamcast VMU' CONFIG_MTD_VMU + dep_tristate ' SEGA Dreamcast internal JEDEC-compatible flash device' CONFIG_MTD_DREAMCAST $CONFIG_MTD_JEDECPROBE + dep_bool ' Disable SEGAs logical partition mapping' CONFIG_MTD_DREAMCAST_NO_PART $CONFIG_MTD_DREAMCAST + fi fi if [ "$CONFIG_ARM" = "y" ]; then Index: Makefile =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/drivers/mtd/maps/Makefile,v retrieving revision 1.3.4.2 retrieving revision 1.3.4.3 diff -u -d -r1.3.4.2 -r1.3.4.3 --- Makefile 26 Oct 2002 14:14:01 -0000 1.3.4.2 +++ Makefile 3 Nov 2002 12:27:27 -0000 1.3.4.3 @@ -41,5 +41,6 @@ obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o obj-$(CONFIG_MTD_VMU) += vmu-flash.o +obj-$(CONFIG_MTD_DREAMCAST) += dreamcast-flash.o include $(TOPDIR)/Rules.make |