From 40711ccb22bb3f851291fa4b9d59a5a4ec6f7949 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Tue, 17 Apr 2012 15:33:13 +1000 Subject: m68knommu: move the 5272 platform code into the common ColdFire code directory All these separate directories for each ColdFire CPU SoC varient seems like overkill. The majority of them only contain a single small config file. Move these into the common ColdFire code directory. Signed-off-by: Greg Ungerer --- arch/m68k/platform/5272/Makefile | 18 ---- arch/m68k/platform/5272/config.c | 121 --------------------- arch/m68k/platform/5272/intc.c | 185 -------------------------------- arch/m68k/platform/coldfire/Makefile | 2 +- arch/m68k/platform/coldfire/intc-5272.c | 185 ++++++++++++++++++++++++++++++++ arch/m68k/platform/coldfire/m5272.c | 121 +++++++++++++++++++++ 6 files changed, 307 insertions(+), 325 deletions(-) delete mode 100644 arch/m68k/platform/5272/Makefile delete mode 100644 arch/m68k/platform/5272/config.c delete mode 100644 arch/m68k/platform/5272/intc.c create mode 100644 arch/m68k/platform/coldfire/intc-5272.c create mode 100644 arch/m68k/platform/coldfire/m5272.c (limited to 'arch/m68k/platform') diff --git a/arch/m68k/platform/5272/Makefile b/arch/m68k/platform/5272/Makefile deleted file mode 100644 index 932ddabdfe8a..000000000000 --- a/arch/m68k/platform/5272/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Makefile for the linux 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 intc.o - diff --git a/arch/m68k/platform/5272/config.c b/arch/m68k/platform/5272/config.c deleted file mode 100644 index 43e36060da18..000000000000 --- a/arch/m68k/platform/5272/config.c +++ /dev/null @@ -1,121 +0,0 @@ -/***************************************************************************/ - -/* - * linux/arch/m68knommu/platform/5272/config.c - * - * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) - * Copyright (C) 2001-2002, SnapGear Inc. (www.snapgear.com) - */ - -/***************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/***************************************************************************/ - -/* - * Some platforms need software versions of the GPIO data registers. - */ -unsigned short ppdata; -unsigned char ledbank = 0xff; - -/***************************************************************************/ - -struct mcf_gpio_chip mcf_gpio_chips[] = { - MCFGPS(PA, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), - MCFGPS(PB, 16, 16, MCFSIM_PBDDR, MCFSIM_PBDAT, MCFSIM_PBDAT), - MCFGPS(Pc, 32, 16, MCFSIM_PCDDR, MCFSIM_PCDAT, MCFSIM_PCDAT), -}; - -unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); - -/***************************************************************************/ - -static void __init m5272_uarts_init(void) -{ - u32 v; - - /* Enable the output lines for the serial ports */ - v = readl(MCF_MBAR + MCFSIM_PBCNT); - v = (v & ~0x000000ff) | 0x00000055; - writel(v, MCF_MBAR + MCFSIM_PBCNT); - - v = readl(MCF_MBAR + MCFSIM_PDCNT); - v = (v & ~0x000003fc) | 0x000002a8; - writel(v, MCF_MBAR + MCFSIM_PDCNT); -} - -/***************************************************************************/ - -static void m5272_cpu_reset(void) -{ - local_irq_disable(); - /* Set watchdog to reset, and enabled */ - __raw_writew(0, MCF_MBAR + MCFSIM_WIRR); - __raw_writew(1, MCF_MBAR + MCFSIM_WRRR); - __raw_writew(0, MCF_MBAR + MCFSIM_WCR); - for (;;) - /* wait for watchdog to timeout */; -} - -/***************************************************************************/ - -void __init config_BSP(char *commandp, int size) -{ -#if defined (CONFIG_MOD5272) - volatile unsigned char *pivrp; - - /* Set base of device vectors to be 64 */ - pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR); - *pivrp = 0x40; -#endif - -#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES) - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0004000, size); - commandp[size-1] = 0; -#elif defined(CONFIG_CANCam) - /* Copy command line from FLASH to local buffer... */ - memcpy(commandp, (char *) 0xf0010000, size); - commandp[size-1] = 0; -#endif - - mach_reset = m5272_cpu_reset; - mach_sched_init = hw_timer_init; -} - -/***************************************************************************/ - -/* - * Some 5272 based boards have the FEC ethernet diectly connected to - * an ethernet switch. In this case we need to use the fixed phy type, - * and we need to declare it early in boot. - */ -static struct fixed_phy_status nettel_fixed_phy_status __initdata = { - .link = 1, - .speed = 100, - .duplex = 0, -}; - -/***************************************************************************/ - -static int __init init_BSP(void) -{ - m5272_uarts_init(); - fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status); - return 0; -} - -arch_initcall(init_BSP); - -/***************************************************************************/ diff --git a/arch/m68k/platform/5272/intc.c b/arch/m68k/platform/5272/intc.c deleted file mode 100644 index 7160e618b0a9..000000000000 --- a/arch/m68k/platform/5272/intc.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * intc.c -- interrupt controller or ColdFire 5272 SoC - * - * (C) Copyright 2009, Greg Ungerer - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * The 5272 ColdFire interrupt controller is nothing like any other - * ColdFire interrupt controller - it truly is completely different. - * Given its age it is unlikely to be used on any other ColdFire CPU. - */ - -/* - * The masking and priproty setting of interrupts on the 5272 is done - * via a set of 4 "Interrupt Controller Registers" (ICR). There is a - * loose mapping of vector number to register and internal bits, but - * a table is the easiest and quickest way to map them. - * - * Note that the external interrupts are edge triggered (unlike the - * internal interrupt sources which are level triggered). Which means - * they also need acknowledging via acknowledge bits. - */ -struct irqmap { - unsigned char icr; - unsigned char index; - unsigned char ack; -}; - -static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = { - /*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, }, - /*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, }, - /*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, }, - /*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, }, - /*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, }, - /*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, }, - /*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, }, - /*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, }, - /*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, }, - /*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, }, - /*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, }, - /*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, }, - /*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, }, - /*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, }, - /*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, }, - /*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, }, - /*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, }, - /*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, }, - /*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, }, - /*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, }, - /*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, }, - /*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, }, - /*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, }, - /*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, }, - /*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, }, - /*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, }, - /*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, }, - /*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, }, - /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, }, -}; - -/* - * The act of masking the interrupt also has a side effect of 'ack'ing - * an interrupt on this irq (for the external irqs). So this mask function - * is also an ack_mask function. - */ -static void intc_irq_mask(struct irq_data *d) -{ - unsigned int irq = d->irq; - - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { - u32 v; - irq -= MCFINT_VECBASE; - v = 0x8 << intc_irqmap[irq].index; - writel(v, MCF_MBAR + intc_irqmap[irq].icr); - } -} - -static void intc_irq_unmask(struct irq_data *d) -{ - unsigned int irq = d->irq; - - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { - u32 v; - irq -= MCFINT_VECBASE; - v = 0xd << intc_irqmap[irq].index; - writel(v, MCF_MBAR + intc_irqmap[irq].icr); - } -} - -static void intc_irq_ack(struct irq_data *d) -{ - unsigned int irq = d->irq; - - /* Only external interrupts are acked */ - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { - irq -= MCFINT_VECBASE; - if (intc_irqmap[irq].ack) { - u32 v; - v = readl(MCF_MBAR + intc_irqmap[irq].icr); - v &= (0x7 << intc_irqmap[irq].index); - v |= (0x8 << intc_irqmap[irq].index); - writel(v, MCF_MBAR + intc_irqmap[irq].icr); - } - } -} - -static int intc_irq_set_type(struct irq_data *d, unsigned int type) -{ - unsigned int irq = d->irq; - - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { - irq -= MCFINT_VECBASE; - if (intc_irqmap[irq].ack) { - u32 v; - v = readl(MCF_MBAR + MCFSIM_PITR); - if (type == IRQ_TYPE_EDGE_FALLING) - v &= ~(0x1 << (32 - irq)); - else - v |= (0x1 << (32 - irq)); - writel(v, MCF_MBAR + MCFSIM_PITR); - } - } - return 0; -} - -/* - * Simple flow handler to deal with the external edge triggered interrupts. - * We need to be careful with the masking/acking due to the side effects - * of masking an interrupt. - */ -static void intc_external_irq(unsigned int irq, struct irq_desc *desc) -{ - irq_desc_get_chip(desc)->irq_ack(&desc->irq_data); - handle_simple_irq(irq, desc); -} - -static struct irq_chip intc_irq_chip = { - .name = "CF-INTC", - .irq_mask = intc_irq_mask, - .irq_unmask = intc_irq_unmask, - .irq_mask_ack = intc_irq_mask, - .irq_ack = intc_irq_ack, - .irq_set_type = intc_irq_set_type, -}; - -void __init init_IRQ(void) -{ - int irq, edge; - - /* Mask all interrupt sources */ - writel(0x88888888, MCF_MBAR + MCFSIM_ICR1); - writel(0x88888888, MCF_MBAR + MCFSIM_ICR2); - writel(0x88888888, MCF_MBAR + MCFSIM_ICR3); - writel(0x88888888, MCF_MBAR + MCFSIM_ICR4); - - for (irq = 0; (irq < NR_IRQS); irq++) { - irq_set_chip(irq, &intc_irq_chip); - edge = 0; - if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) - edge = intc_irqmap[irq - MCFINT_VECBASE].ack; - if (edge) { - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); - irq_set_handler(irq, intc_external_irq); - } else { - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); - irq_set_handler(irq, handle_level_irq); - } - } -} - diff --git a/arch/m68k/platform/coldfire/Makefile b/arch/m68k/platform/coldfire/Makefile index 87ffd2ce374c..ec81d0545592 100644 --- a/arch/m68k/platform/coldfire/Makefile +++ b/arch/m68k/platform/coldfire/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_M520x) += m520x.o pit.o intc-simr.o reset.o obj-$(CONFIG_M523x) += m523x.o pit.o dma_timer.o intc-2.o reset.o obj-$(CONFIG_M5249) += m5249.o timers.o intc.o intc-5249.o reset.o obj-$(CONFIG_M527x) += pit.o intc-2.o reset.o -obj-$(CONFIG_M5272) += timers.o +obj-$(CONFIG_M5272) += m5272.o intc-5272.o timers.o obj-$(CONFIG_M528x) += pit.o intc-2.o reset.o obj-$(CONFIG_M5307) += timers.o intc.o reset.o obj-$(CONFIG_M532x) += timers.o intc-simr.o reset.o diff --git a/arch/m68k/platform/coldfire/intc-5272.c b/arch/m68k/platform/coldfire/intc-5272.c new file mode 100644 index 000000000000..7160e618b0a9 --- /dev/null +++ b/arch/m68k/platform/coldfire/intc-5272.c @@ -0,0 +1,185 @@ +/* + * intc.c -- interrupt controller or ColdFire 5272 SoC + * + * (C) Copyright 2009, Greg Ungerer + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The 5272 ColdFire interrupt controller is nothing like any other + * ColdFire interrupt controller - it truly is completely different. + * Given its age it is unlikely to be used on any other ColdFire CPU. + */ + +/* + * The masking and priproty setting of interrupts on the 5272 is done + * via a set of 4 "Interrupt Controller Registers" (ICR). There is a + * loose mapping of vector number to register and internal bits, but + * a table is the easiest and quickest way to map them. + * + * Note that the external interrupts are edge triggered (unlike the + * internal interrupt sources which are level triggered). Which means + * they also need acknowledging via acknowledge bits. + */ +struct irqmap { + unsigned char icr; + unsigned char index; + unsigned char ack; +}; + +static struct irqmap intc_irqmap[MCFINT_VECMAX - MCFINT_VECBASE] = { + /*MCF_IRQ_SPURIOUS*/ { .icr = 0, .index = 0, .ack = 0, }, + /*MCF_IRQ_EINT1*/ { .icr = MCFSIM_ICR1, .index = 28, .ack = 1, }, + /*MCF_IRQ_EINT2*/ { .icr = MCFSIM_ICR1, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT3*/ { .icr = MCFSIM_ICR1, .index = 20, .ack = 1, }, + /*MCF_IRQ_EINT4*/ { .icr = MCFSIM_ICR1, .index = 16, .ack = 1, }, + /*MCF_IRQ_TIMER1*/ { .icr = MCFSIM_ICR1, .index = 12, .ack = 0, }, + /*MCF_IRQ_TIMER2*/ { .icr = MCFSIM_ICR1, .index = 8, .ack = 0, }, + /*MCF_IRQ_TIMER3*/ { .icr = MCFSIM_ICR1, .index = 4, .ack = 0, }, + /*MCF_IRQ_TIMER4*/ { .icr = MCFSIM_ICR1, .index = 0, .ack = 0, }, + /*MCF_IRQ_UART1*/ { .icr = MCFSIM_ICR2, .index = 28, .ack = 0, }, + /*MCF_IRQ_UART2*/ { .icr = MCFSIM_ICR2, .index = 24, .ack = 0, }, + /*MCF_IRQ_PLIP*/ { .icr = MCFSIM_ICR2, .index = 20, .ack = 0, }, + /*MCF_IRQ_PLIA*/ { .icr = MCFSIM_ICR2, .index = 16, .ack = 0, }, + /*MCF_IRQ_USB0*/ { .icr = MCFSIM_ICR2, .index = 12, .ack = 0, }, + /*MCF_IRQ_USB1*/ { .icr = MCFSIM_ICR2, .index = 8, .ack = 0, }, + /*MCF_IRQ_USB2*/ { .icr = MCFSIM_ICR2, .index = 4, .ack = 0, }, + /*MCF_IRQ_USB3*/ { .icr = MCFSIM_ICR2, .index = 0, .ack = 0, }, + /*MCF_IRQ_USB4*/ { .icr = MCFSIM_ICR3, .index = 28, .ack = 0, }, + /*MCF_IRQ_USB5*/ { .icr = MCFSIM_ICR3, .index = 24, .ack = 0, }, + /*MCF_IRQ_USB6*/ { .icr = MCFSIM_ICR3, .index = 20, .ack = 0, }, + /*MCF_IRQ_USB7*/ { .icr = MCFSIM_ICR3, .index = 16, .ack = 0, }, + /*MCF_IRQ_DMA*/ { .icr = MCFSIM_ICR3, .index = 12, .ack = 0, }, + /*MCF_IRQ_ERX*/ { .icr = MCFSIM_ICR3, .index = 8, .ack = 0, }, + /*MCF_IRQ_ETX*/ { .icr = MCFSIM_ICR3, .index = 4, .ack = 0, }, + /*MCF_IRQ_ENTC*/ { .icr = MCFSIM_ICR3, .index = 0, .ack = 0, }, + /*MCF_IRQ_QSPI*/ { .icr = MCFSIM_ICR4, .index = 28, .ack = 0, }, + /*MCF_IRQ_EINT5*/ { .icr = MCFSIM_ICR4, .index = 24, .ack = 1, }, + /*MCF_IRQ_EINT6*/ { .icr = MCFSIM_ICR4, .index = 20, .ack = 1, }, + /*MCF_IRQ_SWTO*/ { .icr = MCFSIM_ICR4, .index = 16, .ack = 0, }, +}; + +/* + * The act of masking the interrupt also has a side effect of 'ack'ing + * an interrupt on this irq (for the external irqs). So this mask function + * is also an ack_mask function. + */ +static void intc_irq_mask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0x8 << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_unmask(struct irq_data *d) +{ + unsigned int irq = d->irq; + + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + u32 v; + irq -= MCFINT_VECBASE; + v = 0xd << intc_irqmap[irq].index; + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } +} + +static void intc_irq_ack(struct irq_data *d) +{ + unsigned int irq = d->irq; + + /* Only external interrupts are acked */ + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + irq -= MCFINT_VECBASE; + if (intc_irqmap[irq].ack) { + u32 v; + v = readl(MCF_MBAR + intc_irqmap[irq].icr); + v &= (0x7 << intc_irqmap[irq].index); + v |= (0x8 << intc_irqmap[irq].index); + writel(v, MCF_MBAR + intc_irqmap[irq].icr); + } + } +} + +static int intc_irq_set_type(struct irq_data *d, unsigned int type) +{ + unsigned int irq = d->irq; + + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) { + irq -= MCFINT_VECBASE; + if (intc_irqmap[irq].ack) { + u32 v; + v = readl(MCF_MBAR + MCFSIM_PITR); + if (type == IRQ_TYPE_EDGE_FALLING) + v &= ~(0x1 << (32 - irq)); + else + v |= (0x1 << (32 - irq)); + writel(v, MCF_MBAR + MCFSIM_PITR); + } + } + return 0; +} + +/* + * Simple flow handler to deal with the external edge triggered interrupts. + * We need to be careful with the masking/acking due to the side effects + * of masking an interrupt. + */ +static void intc_external_irq(unsigned int irq, struct irq_desc *desc) +{ + irq_desc_get_chip(desc)->irq_ack(&desc->irq_data); + handle_simple_irq(irq, desc); +} + +static struct irq_chip intc_irq_chip = { + .name = "CF-INTC", + .irq_mask = intc_irq_mask, + .irq_unmask = intc_irq_unmask, + .irq_mask_ack = intc_irq_mask, + .irq_ack = intc_irq_ack, + .irq_set_type = intc_irq_set_type, +}; + +void __init init_IRQ(void) +{ + int irq, edge; + + /* Mask all interrupt sources */ + writel(0x88888888, MCF_MBAR + MCFSIM_ICR1); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR2); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR3); + writel(0x88888888, MCF_MBAR + MCFSIM_ICR4); + + for (irq = 0; (irq < NR_IRQS); irq++) { + irq_set_chip(irq, &intc_irq_chip); + edge = 0; + if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX)) + edge = intc_irqmap[irq - MCFINT_VECBASE].ack; + if (edge) { + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + irq_set_handler(irq, intc_external_irq); + } else { + irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH); + irq_set_handler(irq, handle_level_irq); + } + } +} + diff --git a/arch/m68k/platform/coldfire/m5272.c b/arch/m68k/platform/coldfire/m5272.c new file mode 100644 index 000000000000..43e36060da18 --- /dev/null +++ b/arch/m68k/platform/coldfire/m5272.c @@ -0,0 +1,121 @@ +/***************************************************************************/ + +/* + * linux/arch/m68knommu/platform/5272/config.c + * + * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 2001-2002, SnapGear Inc. (www.snapgear.com) + */ + +/***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/***************************************************************************/ + +/* + * Some platforms need software versions of the GPIO data registers. + */ +unsigned short ppdata; +unsigned char ledbank = 0xff; + +/***************************************************************************/ + +struct mcf_gpio_chip mcf_gpio_chips[] = { + MCFGPS(PA, 0, 16, MCFSIM_PADDR, MCFSIM_PADAT, MCFSIM_PADAT), + MCFGPS(PB, 16, 16, MCFSIM_PBDDR, MCFSIM_PBDAT, MCFSIM_PBDAT), + MCFGPS(Pc, 32, 16, MCFSIM_PCDDR, MCFSIM_PCDAT, MCFSIM_PCDAT), +}; + +unsigned int mcf_gpio_chips_size = ARRAY_SIZE(mcf_gpio_chips); + +/***************************************************************************/ + +static void __init m5272_uarts_init(void) +{ + u32 v; + + /* Enable the output lines for the serial ports */ + v = readl(MCF_MBAR + MCFSIM_PBCNT); + v = (v & ~0x000000ff) | 0x00000055; + writel(v, MCF_MBAR + MCFSIM_PBCNT); + + v = readl(MCF_MBAR + MCFSIM_PDCNT); + v = (v & ~0x000003fc) | 0x000002a8; + writel(v, MCF_MBAR + MCFSIM_PDCNT); +} + +/***************************************************************************/ + +static void m5272_cpu_reset(void) +{ + local_irq_disable(); + /* Set watchdog to reset, and enabled */ + __raw_writew(0, MCF_MBAR + MCFSIM_WIRR); + __raw_writew(1, MCF_MBAR + MCFSIM_WRRR); + __raw_writew(0, MCF_MBAR + MCFSIM_WCR); + for (;;) + /* wait for watchdog to timeout */; +} + +/***************************************************************************/ + +void __init config_BSP(char *commandp, int size) +{ +#if defined (CONFIG_MOD5272) + volatile unsigned char *pivrp; + + /* Set base of device vectors to be 64 */ + pivrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_PIVR); + *pivrp = 0x40; +#endif + +#if defined(CONFIG_NETtel) || defined(CONFIG_SCALES) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0004000, size); + commandp[size-1] = 0; +#elif defined(CONFIG_CANCam) + /* Copy command line from FLASH to local buffer... */ + memcpy(commandp, (char *) 0xf0010000, size); + commandp[size-1] = 0; +#endif + + mach_reset = m5272_cpu_reset; + mach_sched_init = hw_timer_init; +} + +/***************************************************************************/ + +/* + * Some 5272 based boards have the FEC ethernet diectly connected to + * an ethernet switch. In this case we need to use the fixed phy type, + * and we need to declare it early in boot. + */ +static struct fixed_phy_status nettel_fixed_phy_status __initdata = { + .link = 1, + .speed = 100, + .duplex = 0, +}; + +/***************************************************************************/ + +static int __init init_BSP(void) +{ + m5272_uarts_init(); + fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status); + return 0; +} + +arch_initcall(init_BSP); + +/***************************************************************************/ -- cgit v1.2.1