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