diff options
Diffstat (limited to 'arch/m68k/platform/5307')
-rw-r--r-- | arch/m68k/platform/5307/Makefile | 20 | ||||
-rw-r--r-- | arch/m68k/platform/5307/config.c | 147 | ||||
-rw-r--r-- | arch/m68k/platform/5307/gpio.c | 49 | ||||
-rw-r--r-- | arch/m68k/platform/5307/nettel.c | 153 |
4 files changed, 369 insertions, 0 deletions
diff --git a/arch/m68k/platform/5307/Makefile b/arch/m68k/platform/5307/Makefile new file mode 100644 index 00000000000..d4293b791f2 --- /dev/null +++ b/arch/m68k/platform/5307/Makefile @@ -0,0 +1,20 @@ +# +# Makefile for the m68knommu kernel. +# + +# +# If you want to play with the HW breakpoints then you will +# need to add define this, which will give you a stack backtrace +# on the console port whenever a DBG interrupt occurs. You have to +# set up you HW breakpoints to trigger a DBG interrupt: +# +# ccflags-y := -DTRAP_DBG_INTERRUPT +# asflags-y := -DTRAP_DBG_INTERRUPT +# + +asflags-$(CONFIG_FULLDEBUG) := -DDEBUGGER_COMPATIBLE_CACHE=1 + +obj-y += config.o gpio.o +obj-$(CONFIG_NETtel) += nettel.o +obj-$(CONFIG_CLEOPATRA) += nettel.o + diff --git a/arch/m68k/platform/5307/config.c b/arch/m68k/platform/5307/config.c new file mode 100644 index 00000000000..00900ac06a9 --- /dev/null +++ b/arch/m68k/platform/5307/config.c @@ -0,0 +1,147 @@ +/***************************************************************************/ + +/* + * linux/arch/m68knommu/platform/5307/config.c + * + * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2000, Lineo (www.lineo.com) + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/init.h> +#include <linux/io.h> +#include <asm/machdep.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfuart.h> +#include <asm/mcfwdebug.h> + +/***************************************************************************/ + +/* + * Some platforms need software versions of the GPIO data registers. + */ +unsigned short ppdata; +unsigned char ledbank = 0xff; + +/***************************************************************************/ + +static struct mcf_platform_uart m5307_uart_platform[] = { + { + .mapbase = MCF_MBAR + MCFUART_BASE1, + .irq = 73, + }, + { + .mapbase = MCF_MBAR + MCFUART_BASE2, + .irq = 74, + }, + { }, +}; + +static struct platform_device m5307_uart = { + .name = "mcfuart", + .id = 0, + .dev.platform_data = m5307_uart_platform, +}; + +static struct platform_device *m5307_devices[] __initdata = { + &m5307_uart, +}; + +/***************************************************************************/ + +static void __init m5307_uart_init_line(int line, int irq) +{ + if (line == 0) { + writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR); + writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR); + mcf_mapirq2imr(irq, MCFINTC_UART0); + } else if (line == 1) { + writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR); + writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR); + mcf_mapirq2imr(irq, MCFINTC_UART1); + } +} + +static void __init m5307_uarts_init(void) +{ + const int nrlines = ARRAY_SIZE(m5307_uart_platform); + int line; + + for (line = 0; (line < nrlines); line++) + m5307_uart_init_line(line, m5307_uart_platform[line].irq); +} + +/***************************************************************************/ + +static void __init m5307_timers_init(void) +{ + /* Timer1 is always used as system timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER1ICR); + mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1); + +#ifdef CONFIG_HIGHPROFILE + /* Timer2 is to be used as a high speed profile timer */ + writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3, + MCF_MBAR + MCFSIM_TIMER2ICR); + mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2); +#endif +} + +/***************************************************************************/ + +void m5307_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to soft reset, and enabled */ + __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + +void __init config_BSP(char *commandp, int size) +{ +#if defined(CONFIG_NETtel) || \ + defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0004000, size); + commandp[size-1] = 0; +#endif + + mach_reset = m5307_cpu_reset; + m5307_timers_init(); + m5307_uarts_init(); + + /* Only support the external interrupts on their primary level */ + mcf_mapirq2imr(25, MCFINTC_EINT1); + mcf_mapirq2imr(27, MCFINTC_EINT3); + mcf_mapirq2imr(29, MCFINTC_EINT5); + mcf_mapirq2imr(31, MCFINTC_EINT7); + +#ifdef CONFIG_BDM_DISABLE + /* + * Disable the BDM clocking. This also turns off most of the rest of + * the BDM device. This is good for EMC reasons. This option is not + * incompatible with the memory protection option. + */ + wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK); +#endif +} + +/***************************************************************************/ + +static int __init init_BSP(void) +{ + platform_add_devices(m5307_devices, ARRAY_SIZE(m5307_devices)); + return 0; +} + +arch_initcall(init_BSP); + +/***************************************************************************/ diff --git a/arch/m68k/platform/5307/gpio.c b/arch/m68k/platform/5307/gpio.c new file mode 100644 index 00000000000..5850612b4a3 --- /dev/null +++ b/arch/m68k/platform/5307/gpio.c @@ -0,0 +1,49 @@ +/* + * Coldfire generic GPIO support + * + * (C) Copyright 2009, Steven King <sfking@fdwdc.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +*/ + +#include <linux/kernel.h> +#include <linux/init.h> + +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/mcfgpio.h> + +static struct mcf_gpio_chip mcf_gpio_chips[] = { + { + .gpio_chip = { + .label = "PP", + .request = mcf_gpio_request, + .free = mcf_gpio_free, + .direction_input = mcf_gpio_direction_input, + .direction_output = mcf_gpio_direction_output, + .get = mcf_gpio_get_value, + .set = mcf_gpio_set_value, + .ngpio = 16, + }, + .pddr = (void __iomem *) MCFSIM_PADDR, + .podr = (void __iomem *) MCFSIM_PADAT, + .ppdr = (void __iomem *) MCFSIM_PADAT, + }, +}; + +static int __init mcf_gpio_init(void) +{ + unsigned i = 0; + while (i < ARRAY_SIZE(mcf_gpio_chips)) + (void)gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); + return 0; +} + +core_initcall(mcf_gpio_init); diff --git a/arch/m68k/platform/5307/nettel.c b/arch/m68k/platform/5307/nettel.c new file mode 100644 index 00000000000..e925ea4602f --- /dev/null +++ b/arch/m68k/platform/5307/nettel.c @@ -0,0 +1,153 @@ +/***************************************************************************/ + +/* + * nettel.c -- startup code support for the NETtel boards + * + * Copyright (C) 2009, Greg Ungerer (gerg@snapgear.com) + */ + +/***************************************************************************/ + +#include <linux/kernel.h> +#include <linux/param.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <asm/coldfire.h> +#include <asm/mcfsim.h> +#include <asm/nettel.h> + +/***************************************************************************/ + +/* + * Define the IO and interrupt resources of the 2 SMC9196 interfaces. + */ +#define NETTEL_SMC0_ADDR 0x30600300 +#define NETTEL_SMC0_IRQ 29 + +#define NETTEL_SMC1_ADDR 0x30600000 +#define NETTEL_SMC1_IRQ 27 + +/* + * We need some access into the SMC9196 registers. Define those registers + * we will need here (including the smc91x.h doesn't seem to give us these + * in a simple form). + */ +#define SMC91xx_BANKSELECT 14 +#define SMC91xx_BASEADDR 2 +#define SMC91xx_BASEMAC 4 + +/***************************************************************************/ + +static struct resource nettel_smc91x_0_resources[] = { + { + .start = NETTEL_SMC0_ADDR, + .end = NETTEL_SMC0_ADDR + 0x20, + .flags = IORESOURCE_MEM, + }, + { + .start = NETTEL_SMC0_IRQ, + .end = NETTEL_SMC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource nettel_smc91x_1_resources[] = { + { + .start = NETTEL_SMC1_ADDR, + .end = NETTEL_SMC1_ADDR + 0x20, + .flags = IORESOURCE_MEM, + }, + { + .start = NETTEL_SMC1_IRQ, + .end = NETTEL_SMC1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device nettel_smc91x[] = { + { + .name = "smc91x", + .id = 0, + .num_resources = ARRAY_SIZE(nettel_smc91x_0_resources), + .resource = nettel_smc91x_0_resources, + }, + { + .name = "smc91x", + .id = 1, + .num_resources = ARRAY_SIZE(nettel_smc91x_1_resources), + .resource = nettel_smc91x_1_resources, + }, +}; + +static struct platform_device *nettel_devices[] __initdata = { + &nettel_smc91x[0], + &nettel_smc91x[1], +}; + +/***************************************************************************/ + +static u8 nettel_macdefault[] __initdata = { + 0x00, 0xd0, 0xcf, 0x00, 0x00, 0x01, +}; + +/* + * Set flash contained MAC address into SMC9196 core. Make sure the flash + * MAC address is sane, and not an empty flash. If no good use the Moreton + * Bay default MAC address instead. + */ + +static void __init nettel_smc91x_setmac(unsigned int ioaddr, unsigned int flashaddr) +{ + u16 *macp; + + macp = (u16 *) flashaddr; + if ((macp[0] == 0xffff) && (macp[1] == 0xffff) && (macp[2] == 0xffff)) + macp = (u16 *) &nettel_macdefault[0]; + + writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); + writew(macp[0], ioaddr + SMC91xx_BASEMAC); + writew(macp[1], ioaddr + SMC91xx_BASEMAC + 2); + writew(macp[2], ioaddr + SMC91xx_BASEMAC + 4); +} + +/***************************************************************************/ + +/* + * Re-map the address space of at least one of the SMC ethernet + * parts. Both parts power up decoding the same address, so we + * need to move one of them first, before doing anything else. + */ + +static void __init nettel_smc91x_init(void) +{ + writew(0x00ec, MCF_MBAR + MCFSIM_PADDR); + mcf_setppdata(0, 0x0080); + writew(1, NETTEL_SMC0_ADDR + SMC91xx_BANKSELECT); + writew(0x0067, NETTEL_SMC0_ADDR + SMC91xx_BASEADDR); + mcf_setppdata(0x0080, 0); + + /* Set correct chip select timing for SMC9196 accesses */ + writew(0x1180, MCF_MBAR + MCFSIM_CSCR3); + + /* Set the SMC interrupts to be auto-vectored */ + mcf_autovector(NETTEL_SMC0_IRQ); + mcf_autovector(NETTEL_SMC1_IRQ); + + /* Set MAC addresses from flash for both interfaces */ + nettel_smc91x_setmac(NETTEL_SMC0_ADDR, 0xf0006000); + nettel_smc91x_setmac(NETTEL_SMC1_ADDR, 0xf0006006); +} + +/***************************************************************************/ + +static int __init init_nettel(void) +{ + nettel_smc91x_init(); + platform_add_devices(nettel_devices, ARRAY_SIZE(nettel_devices)); + return 0; +} + +arch_initcall(init_nettel); + +/***************************************************************************/ |