diff options
Diffstat (limited to 'arch/mips/txx9/rbtx4939/setup.c')
| -rw-r--r-- | arch/mips/txx9/rbtx4939/setup.c | 183 |
1 files changed, 175 insertions, 8 deletions
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c index 656603b85b7..2da5f25f98b 100644 --- a/arch/mips/txx9/rbtx4939/setup.c +++ b/arch/mips/txx9/rbtx4939/setup.c @@ -12,10 +12,15 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> +#include <linux/slab.h> +#include <linux/export.h> #include <linux/platform_device.h> #include <linux/leds.h> #include <linux/interrupt.h> #include <linux/smc91x.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/map.h> #include <asm/reboot.h> #include <asm/txx9/generic.h> #include <asm/txx9/pci.h> @@ -35,8 +40,7 @@ static void __init rbtx4939_time_init(void) tx4939_time_init(0); } -#if defined(__BIG_ENDIAN) && \ - (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) +#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_SMC91X) #define HAVE_RBTX4939_IOSWAB #define IS_CE1_ADDR(addr) \ ((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1)) @@ -182,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void) #define RBTX4939_MAX_7SEGLEDS 8 -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#if IS_ENABLED(CONFIG_LEDS_CLASS) static u8 led_val[RBTX4939_MAX_7SEGLEDS]; struct rbtx4939_led_data { struct led_classdev cdev; @@ -239,7 +243,7 @@ static int __init rbtx4939_led_probe(struct platform_device *pdev) } static struct platform_driver rbtx4939_led_driver = { - .driver = { + .driver = { .name = "rbtx4939-led", .owner = THIS_MODULE, }, @@ -258,7 +262,7 @@ static inline void rbtx4939_led_setup(void) static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val) { -#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) +#if IS_ENABLED(CONFIG_LEDS_CLASS) unsigned long flags; local_irq_save(flags); /* bit7: reserved for LED class */ @@ -282,6 +286,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val) __rbtx4939_7segled_putc(pos, val); } +#if IS_ENABLED(CONFIG_MTD_RBTX4939) +/* special mapping for boot rom */ +static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs) +{ + u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; + unsigned char shift; + + if (bdipsw & 8) { + /* BOOT Mode: USER ROM1 / USER ROM2 */ + shift = bdipsw & 3; + /* rotate A[23:22] */ + return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22); + } +#ifdef __BIG_ENDIAN + if (bdipsw == 0) + /* BOOT Mode: Monitor ROM */ + ofs ^= 0x400000; /* swap A[22] */ +#endif + return ofs; +} + +static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs) +{ + map_word r; + + ofs = rbtx4939_flash_fixup_ofs(ofs); + r.x[0] = __raw_readw(map->virt + ofs); + return r; +} + +static void rbtx4939_flash_write16(struct map_info *map, const map_word datum, + unsigned long ofs) +{ + ofs = rbtx4939_flash_fixup_ofs(ofs); + __raw_writew(datum.x[0], map->virt + ofs); + mb(); /* see inline_map_write() in mtd/map.h */ +} + +static void rbtx4939_flash_copy_from(struct map_info *map, void *to, + unsigned long from, ssize_t len) +{ + u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; + unsigned char shift; + ssize_t curlen; + + from += (unsigned long)map->virt; + if (bdipsw & 8) { + /* BOOT Mode: USER ROM1 / USER ROM2 */ + shift = bdipsw & 3; + while (len) { + curlen = min_t(unsigned long, len, + 0x400000 - (from & (0x400000 - 1))); + memcpy(to, + (void *)((from & ~0xc00000) | + ((((from >> 22) + shift) & 3) << 22)), + curlen); + len -= curlen; + from += curlen; + to += curlen; + } + return; + } +#ifdef __BIG_ENDIAN + if (bdipsw == 0) { + /* BOOT Mode: Monitor ROM */ + while (len) { + curlen = min_t(unsigned long, len, + 0x400000 - (from & (0x400000 - 1))); + memcpy(to, (void *)(from ^ 0x400000), curlen); + len -= curlen; + from += curlen; + to += curlen; + } + return; + } +#endif + memcpy(to, (void *)from, len); +} + +static void rbtx4939_flash_map_init(struct map_info *map) +{ + map->read = rbtx4939_flash_read16; + map->write = rbtx4939_flash_write16; + map->copy_from = rbtx4939_flash_copy_from; +} + +static void __init rbtx4939_mtd_init(void) +{ + static struct { + struct platform_device dev; + struct resource res; + struct rbtx4939_flash_data data; + } pdevs[4]; + int i; + static char names[4][8]; + static struct mtd_partition parts[4]; + struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data; + u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; + + if (bdipsw & 8) { + /* BOOT Mode: USER ROM1 / USER ROM2 */ + boot_pdata->nr_parts = 4; + for (i = 0; i < boot_pdata->nr_parts; i++) { + sprintf(names[i], "img%d", 4 - i); + parts[i].name = names[i]; + parts[i].size = 0x400000; + parts[i].offset = MTDPART_OFS_NXTBLK; + } + } else if (bdipsw == 0) { + /* BOOT Mode: Monitor ROM */ + boot_pdata->nr_parts = 2; + strcpy(names[0], "big"); + strcpy(names[1], "little"); + for (i = 0; i < boot_pdata->nr_parts; i++) { + parts[i].name = names[i]; + parts[i].size = 0x400000; + parts[i].offset = MTDPART_OFS_NXTBLK; + } + } else { + /* BOOT Mode: ROM Emulator */ + boot_pdata->nr_parts = 2; + parts[0].name = "boot"; + parts[0].offset = 0xc00000; + parts[0].size = 0x400000; + parts[1].name = "user"; + parts[1].offset = 0; + parts[1].size = 0xc00000; + } + boot_pdata->parts = parts; + boot_pdata->map_init = rbtx4939_flash_map_init; + + for (i = 0; i < ARRAY_SIZE(pdevs); i++) { + struct resource *r = &pdevs[i].res; + struct platform_device *dev = &pdevs[i].dev; + + r->start = 0x1f000000 - i * 0x1000000; + r->end = r->start + 0x1000000 - 1; + r->flags = IORESOURCE_MEM; + pdevs[i].data.width = 2; + dev->num_resources = 1; + dev->resource = r; + dev->id = i; + dev->name = "rbtx4939-flash"; + dev->dev.platform_data = &pdevs[i].data; + platform_device_register(dev); + } +} +#else +static void __init rbtx4939_mtd_init(void) +{ +} +#endif + static void __init rbtx4939_arch_init(void) { rbtx4939_pci_setup(); @@ -305,7 +462,7 @@ static void __init rbtx4939_device_init(void) .flags = SMC91X_USE_16BIT, }; struct platform_device *pdev; -#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE) +#if IS_ENABLED(CONFIG_TC35815) int i, j; unsigned char ethaddr[2][6]; u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f; @@ -333,10 +490,20 @@ static void __init rbtx4939_device_init(void) platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) || platform_device_add(pdev)) platform_device_put(pdev); + rbtx4939_mtd_init(); + /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */ + tx4939_ndfmc_init(10, 35, + (1 << 1) | (1 << 2), + (1 << 2)); /* ch1:8bit, ch2:16bit */ rbtx4939_led_setup(); tx4939_wdt_init(); tx4939_ata_init(); tx4939_rtc_init(); + tx4939_dmac_init(0, 2); + tx4939_aclc_init(); + platform_device_register_simple("txx9aclc-generic", -1, NULL, 0); + tx4939_sramc_init(); + tx4939_rng_init(); } static void __init rbtx4939_setup(void) @@ -346,10 +513,10 @@ static void __init rbtx4939_setup(void) rbtx4939_ebusc_setup(); /* always enable ATA0 */ txx9_set64(&tx4939_ccfgptr->pcfg, TX4939_PCFG_ATA0MODE); - rbtx4939_update_ioc_pen(); if (txx9_master_clock == 0) txx9_master_clock = 20000000; tx4939_setup(); + rbtx4939_update_ioc_pen(); #ifdef HAVE_RBTX4939_IOSWAB ioswabw = rbtx4939_ioswabw; __mem_ioswabw = rbtx4939_mem_ioswabw; @@ -375,7 +542,7 @@ static void __init rbtx4939_setup(void) } struct txx9_board_vec rbtx4939_vec __initdata = { - .system = "Tothiba RBTX4939", + .system = "Toshiba RBTX4939", .prom_init = rbtx4939_prom_init, .mem_setup = rbtx4939_setup, .irq_setup = rbtx4939_irq_setup, |
