[PATCH] Add support for Freescale MEDIA5200 MPC5200 based platform
John Rigby
jcrigby at gmail.com
Wed Apr 5 08:08:45 EST 2006
Sylvain,
This adds support for the Media5200 platform. A couple ugly things are 1)
A new file arch/ppc/platforms/media5200.c duplicates alot of code in
..../lite5200.c and 2) the patch adds some platform specific interrupt
code to arch/ppc/syslib/mpc52xx_pic.c. The platform has an FPGA that
cascades the 4 PCI interrupts off of MPC52xx_IRQ0. I suppose a
cleaner solution would be to add some generic cascade code to
mpc52xx_pic.c and add a new file to arch/ppc/platforms/media5200_pic.c
or some thing like that. Let me know what you think.
John
-------------- next part --------------
>From nobody Mon Sep 17 00:00:00 2001
From: John Rigby <jrigby at freescale.com>
Date: Tue Apr 4 14:59:18 2006 -0600
Subject: [PATCH] Add support for Freescale MEDIA5200 MPC5200 based platform.
Signed-off-by: John Rigby <jrigby at freescale.com>
---
arch/ppc/Kconfig | 6 +
arch/ppc/platforms/Makefile | 1
arch/ppc/platforms/media5200.c | 218 ++++++++++++++++++++++++++++++++++++++++
arch/ppc/platforms/media5200.h | 21 ++++
arch/ppc/syslib/mpc52xx_pic.c | 49 +++++++++
include/asm-ppc/mpc52xx.h | 17 +++
6 files changed, 312 insertions(+), 0 deletions(-)
create mode 100644 arch/ppc/platforms/media5200.c
create mode 100644 arch/ppc/platforms/media5200.h
03370dab9b10e5354b49734161bbd9e28c076b87
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 776f5a9..7a7c14d 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -671,6 +671,12 @@ config LITE5200B
Support for the LITE5200B dev board for the MPC5200 from Freescale.
This is the new board with 2 PCI slots.
+config MEDIA5200
+ bool "Freescale MEDIA5200"
+ select PPC_MPC52xx
+ help
+ Support for the MEDIA5200 dev platform for the MPC5200 from Freescale.
+
config MPC834x_SYS
bool "Freescale MPC834x SYS"
help
diff --git a/arch/ppc/platforms/Makefile b/arch/ppc/platforms/Makefile
index 51430e2..b2bd70f 100644
--- a/arch/ppc/platforms/Makefile
+++ b/arch/ppc/platforms/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_SANDPOINT) += sandpoint.o
obj-$(CONFIG_SBC82xx) += sbc82xx.o
obj-$(CONFIG_SPRUCE) += spruce.o
obj-$(CONFIG_LITE5200) += lite5200.o
+obj-$(CONFIG_MEDIA5200) += media5200.o
obj-$(CONFIG_EV64360) += ev64360.o
ifeq ($(CONFIG_SMP),y)
diff --git a/arch/ppc/platforms/media5200.c b/arch/ppc/platforms/media5200.c
new file mode 100644
index 0000000..52fcc66
--- /dev/null
+++ b/arch/ppc/platforms/media5200.c
@@ -0,0 +1,218 @@
+/*
+ * Platform support file for the Freescale MEDIA5200 based on MPC52xx.
+ *
+ * Copyright 2005,2006 Freescale, Bernhard Kuhn, John Rigby
+ *
+ * This file originally based on lite5200.c
+ *
+ * Maintainer : Sylvain Munaut <tnt at 246tNt.com>
+ *
+ * Based on the 2.4 code written by Kent Borg,
+ * Dale Farnsworth <dale.farnsworth at mvista.com> and
+ * Wolfgang Denk <wd at denx.de>
+ *
+ * Copyright 2004 Sylvain Munaut <tnt at 246tNt.com>
+ * Copyright 2003 Motorola Inc.
+ * Copyright 2003 MontaVista Software Inc.
+ * Copyright 2003 DENX Software Engineering (wd at denx.de)
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+#include <linux/initrd.h>
+#include <linux/seq_file.h>
+#include <linux/kdev_t.h>
+#include <linux/root_dev.h>
+#include <linux/console.h>
+#include <linux/module.h>
+
+#include <asm/bootinfo.h>
+#include <asm/io.h>
+#include <asm/mpc52xx.h>
+#include <asm/ppc_sys.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+
+
+extern int powersave_nap;
+
+/* Board data given by U-Boot */
+bd_t __res;
+EXPORT_SYMBOL(__res); /* For modules */
+
+
+/* ======================================================================== */
+/* Platform specific code */
+/* ======================================================================== */
+
+/* Supported PSC function in "preference" order */
+struct mpc52xx_psc_func mpc52xx_psc_functions[] = {
+ { .id = 5,
+ .func = "uart",
+ },
+ { .id = -1, /* End entry */
+ .func = NULL,
+ }
+ };
+
+
+static int
+media5200_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "machine\t\t: Freescale MEDIA5200\n");
+ return 0;
+}
+
+#ifdef CONFIG_PCI
+
+static int
+mpc5200_map_irq_mapping[4][6] = {
+ // Connector 1 Connector 2 Mini-PCI SIU CoralPA MPC5200
+ { MEDIA5200_PCI0_IRQ, MEDIA5200_PCI1_IRQ, MEDIA5200_PCI2_IRQ, -1, MEDIA5200_PCI3_IRQ, -1 }, // Pin A
+ { MEDIA5200_PCI1_IRQ, MEDIA5200_PCI2_IRQ, MEDIA5200_PCI3_IRQ, -1, -1, -1 }, // Pin B
+ { MEDIA5200_PCI2_IRQ, MEDIA5200_PCI3_IRQ, -1, -1, -1, -1 }, // Pin C
+ { MEDIA5200_PCI3_IRQ, MEDIA5200_PCI0_IRQ, -1, -1, -1, -1 } // Pin D
+};
+
+static int
+media5200_map_irq(struct pci_dev *dev, unsigned char idsel,
+ unsigned char pin) {
+ return mpc5200_map_irq_mapping[pin-1][idsel-24];
+}
+#endif
+
+static void __init
+media5200_setup_cpu(void)
+{
+ struct mpc52xx_gpio __iomem *gpio;
+ struct mpc52xx_intr __iomem *intr;
+
+ u32 port_config;
+ u32 intr_ctrl;
+
+ /* Map zones */
+ gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE);
+ intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
+
+ if (!gpio || !intr) {
+ printk(KERN_ERR __FILE__ ": "
+ "Error while mapping GPIO/INTR during "
+ "media5200_setup_cpu\n");
+ goto unmap_regs;
+ }
+
+ // FIXME
+ port_config = 0x11551c20;
+ out_be32(&gpio->port_config, port_config);
+
+ /* IRQ[0-3] setup : IRQ0 - Level Active Low */
+ /* IRQ[1-3] - Level Active High */
+ intr_ctrl = in_be32(&intr->ctrl);
+ intr_ctrl &= ~0x00ff0000;
+ intr_ctrl |= 0x00c00000;
+ out_be32(&intr->ctrl, intr_ctrl);
+
+ /* Unmap reg zone */
+unmap_regs:
+ if (gpio) iounmap(gpio);
+ if (intr) iounmap(intr);
+}
+
+static void __init
+media5200_setup_arch(void)
+{
+ /* CPU & Port mux setup */
+ mpc52xx_setup_cpu(); /* Generic */
+ media5200_setup_cpu(); /* Platform specific */
+
+#ifdef CONFIG_PCI
+ /* PCI Bridge setup */
+ mpc52xx_find_bridges();
+#endif
+}
+
+// TODO CONFIG_ARCH_IRQ_PRIO
+void __init
+platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+ /* Generic MPC52xx platform initialization */
+ /* TODO Create one and move a max of stuff in it.
+ Put this init in the syslib */
+
+ struct bi_record *bootinfo = find_bootinfo();
+
+ if (bootinfo)
+ parse_bootinfo(bootinfo);
+ else {
+ /* Load the bd_t board info structure */
+ if (r3)
+ memcpy((void*)&__res,(void*)(r3+KERNELBASE),
+ sizeof(bd_t));
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* Load the initrd */
+ if (r4) {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;
+ }
+#endif
+
+ /* Load the command line */
+ if (r6) {
+ *(char *)(r7+KERNELBASE) = 0;
+ strcpy(cmd_line, (char *)(r6+KERNELBASE));
+ }
+ }
+
+ /* PPC Sys identification */
+ identify_ppc_sys_by_id(mfspr(SPRN_SVR));
+
+ /* BAT setup */
+ mpc52xx_set_bat();
+
+ /* No ISA bus by default */
+#ifdef CONFIG_PCI
+ isa_io_base = 0;
+ isa_mem_base = 0;
+#endif
+
+ /* Powersave */
+ /* This is provided as an example on how to do it. But you
+ need to be aware that NAP disable bus snoop and that may
+ be required for some devices to work properly, like USB ... */
+ /* powersave_nap = 1; */
+
+
+ /* Setup the ppc_md struct */
+ ppc_md.setup_arch = media5200_setup_arch;
+ ppc_md.show_cpuinfo = media5200_show_cpuinfo;
+ ppc_md.show_percpuinfo = NULL;
+ ppc_md.init_IRQ = mpc52xx_init_irq;
+ ppc_md.get_irq = mpc52xx_get_irq;
+
+#ifdef CONFIG_PCI
+ ppc_md.pci_map_irq = media5200_map_irq;
+#endif
+
+ ppc_md.find_end_of_memory = mpc52xx_find_end_of_memory;
+ ppc_md.setup_io_mappings = mpc52xx_map_io;
+
+ ppc_md.restart = mpc52xx_restart;
+ ppc_md.power_off = mpc52xx_power_off;
+ ppc_md.halt = mpc52xx_halt;
+
+ /* No time keeper on the MEDIA5200 */
+ ppc_md.time_init = NULL;
+ ppc_md.get_rtc_time = NULL;
+ ppc_md.set_rtc_time = NULL;
+
+ ppc_md.calibrate_decr = mpc52xx_calibrate_decr;
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ ppc_md.progress = mpc52xx_progress;
+#endif
+}
+
diff --git a/arch/ppc/platforms/media5200.h b/arch/ppc/platforms/media5200.h
new file mode 100644
index 0000000..b72d6c5
--- /dev/null
+++ b/arch/ppc/platforms/media5200.h
@@ -0,0 +1,21 @@
+/*
+ * Definitions for Freescale MEDIA5200 : MPC52xx Standard Development
+ * Platform board support
+ *
+ * Maintainer : Sylvain Munaut <tnt at 246tNt.com>
+ *
+ * Copyright (C) 2004 Sylvain Munaut <tnt at 246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef __PLATFORMS_MEDIA5200_H__
+#define __PLATFORMS_MEDIA5200_H__
+
+/* Serial port used for low-level debug */
+#define MPC52xx_PF_CONSOLE_PORT 6 /* PSC6 */
+
+
+#endif /* __PLATFORMS_MEDIA5200_H__ */
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
index 4c4497e..b9e2cdb 100644
--- a/arch/ppc/syslib/mpc52xx_pic.c
+++ b/arch/ppc/syslib/mpc52xx_pic.c
@@ -36,15 +36,23 @@
static struct mpc52xx_intr __iomem *intr;
static struct mpc52xx_sdma __iomem *sdma;
+// FIXME ioremap these
+#ifdef CONFIG_MEDIA5200
+#define MEDIA5200_FPGA_INT_MASK ((u32*)0xf001040c)
+#define MEDIA5200_FPGA_INT_STAT ((u32*)0xf0010410)
+#endif
+
static void
mpc52xx_ic_disable(unsigned int irq)
{
u32 val;
if (irq == MPC52xx_IRQ0) {
+#ifndef CONFIG_MEDIA5200
val = in_be32(&intr->ctrl);
val &= ~(1 << 11);
out_be32(&intr->ctrl, val);
+#endif
}
else if (irq < MPC52xx_IRQ1) {
BUG();
@@ -64,11 +72,22 @@ mpc52xx_ic_disable(unsigned int irq)
val |= 1 << (irq - MPC52xx_SDMA_IRQ_BASE);
out_be32(&sdma->IntMask, val);
}
+#ifdef CONFIG_MEDIA5200
+ else if (irq < MEDIA5200_FPGA_IRQ_BASE) {
+#else
else {
+#endif
val = in_be32(&intr->per_mask);
val |= 1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE));
out_be32(&intr->per_mask, val);
}
+#ifdef CONFIG_MEDIA5200
+ else {
+ val = in_be32(MEDIA5200_FPGA_INT_MASK);
+ val &= ~(1 << (irq - MEDIA5200_FPGA_IRQ_BASE + 28));
+ out_be32(MEDIA5200_FPGA_INT_MASK, val);
+ }
+#endif
}
static void
@@ -77,9 +96,11 @@ mpc52xx_ic_enable(unsigned int irq)
u32 val;
if (irq == MPC52xx_IRQ0) {
+#ifndef CONFIG_MEDIA5200
val = in_be32(&intr->ctrl);
val |= 1 << 11;
out_be32(&intr->ctrl, val);
+#endif
}
else if (irq < MPC52xx_IRQ1) {
BUG();
@@ -99,11 +120,22 @@ mpc52xx_ic_enable(unsigned int irq)
val &= ~(1 << (irq - MPC52xx_SDMA_IRQ_BASE));
out_be32(&sdma->IntMask, val);
}
+#ifdef CONFIG_MEDIA5200
+ else if (irq < MEDIA5200_FPGA_IRQ_BASE) {
+#else
else {
+#endif
val = in_be32(&intr->per_mask);
val &= ~(1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE)));
out_be32(&intr->per_mask, val);
}
+#ifdef CONFIG_MEDIA5200
+ else {
+ val = in_be32(MEDIA5200_FPGA_INT_MASK);
+ val |= (1 << (irq - MEDIA5200_FPGA_IRQ_BASE + 28));
+ out_be32(MEDIA5200_FPGA_INT_MASK, val);
+ }
+#endif
}
static void
@@ -117,9 +149,11 @@ mpc52xx_ic_ack(unsigned int irq)
switch (irq) {
case MPC52xx_IRQ0:
+#ifndef CONFIG_MEDIA5200
val = in_be32(&intr->ctrl);
val |= 0x08000000;
out_be32(&intr->ctrl, val);
+#endif
break;
case MPC52xx_CCS_IRQ:
val = in_be32(&intr->enc_status);
@@ -187,6 +221,9 @@ mpc52xx_init_irq(void)
panic("Can't ioremap PIC/SDMA register for init_irq !");
/* Disable all interrupt sources. */
+#ifdef CONFIG_MEDIA5200
+ out_be32(MEDIA5200_FPGA_INT_MASK,0x00000000);
+#endif
out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
@@ -195,6 +232,10 @@ mpc52xx_init_irq(void)
intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
0x00001000 | /* MEE master external enable */
+#ifdef CONFIG_MEDIA5200
+ 0x00c00000 | /* IRQ0: level-sensitive, active low */
+ 0x00000800 | /* enable IRQ 0, disable IRQ 1,2,3 */
+#endif
0x00000000 | /* 0 means disable IRQ 0-3 */
0x00000001; /* CEb route critical normally */
out_be32(&intr->ctrl, intr_ctrl);
@@ -227,6 +268,14 @@ mpc52xx_get_irq(struct pt_regs *regs)
u32 status;
int irq = -1;
+#ifdef CONFIG_MEDIA5200
+ status = in_be32(MEDIA5200_FPGA_INT_STAT) & in_be32(MEDIA5200_FPGA_INT_MASK);
+ if(status & 0xffff0000) {
+ irq = ffs(status) - 1 + MEDIA5200_FPGA_IRQ_BASE - 28;
+ // printk("IRQ=%i\n",irq);
+ return irq;
+ }
+#endif
status = in_be32(&intr->enc_status);
if (status & 0x00000400) { /* critical */
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index bd953b9..0b8edaf 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -119,11 +119,17 @@ enum ppc_sys_devices {
#define MPC52xx_MAIN_IRQ_NUM 17
#define MPC52xx_SDMA_IRQ_NUM 17
#define MPC52xx_PERP_IRQ_NUM 23
+#ifdef CONFIG_MEDIA5200
+#define MEDIA5200_FPGA_IRQ_NUM 6
+#endif
#define MPC52xx_CRIT_IRQ_BASE 1
#define MPC52xx_MAIN_IRQ_BASE (MPC52xx_CRIT_IRQ_BASE + MPC52xx_CRIT_IRQ_NUM)
#define MPC52xx_SDMA_IRQ_BASE (MPC52xx_MAIN_IRQ_BASE + MPC52xx_MAIN_IRQ_NUM)
#define MPC52xx_PERP_IRQ_BASE (MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)
+#ifdef CONFIG_MEDIA5200
+#define MEDIA5200_FPGA_IRQ_BASE (MPC52xx_PERP_IRQ_BASE + MPC52xx_PERP_IRQ_NUM)
+#endif
#define MPC52xx_IRQ0 (MPC52xx_CRIT_IRQ_BASE + 0)
#define MPC52xx_SLICE_TIMER_0_IRQ (MPC52xx_CRIT_IRQ_BASE + 1)
@@ -159,6 +165,14 @@ enum ppc_sys_devices {
#define MPC52xx_XLB_ARB_IRQ (MPC52xx_PERP_IRQ_BASE + 21)
#define MPC52xx_BDLC_IRQ (MPC52xx_PERP_IRQ_BASE + 22)
+#ifdef CONFIG_MEDIA5200
+#define MEDIA5200_PCI0_IRQ (MEDIA5200_FPGA_IRQ_BASE + 0)
+#define MEDIA5200_PCI1_IRQ (MEDIA5200_FPGA_IRQ_BASE + 1)
+#define MEDIA5200_PCI2_IRQ (MEDIA5200_FPGA_IRQ_BASE + 2)
+#define MEDIA5200_PCI3_IRQ (MEDIA5200_FPGA_IRQ_BASE + 3)
+#define MEDIA5200_EU0_IRQ (MEDIA5200_FPGA_IRQ_BASE + 4)
+#define MEDIA5200_EU1_IRQ (MEDIA5200_FPGA_IRQ_BASE + 5)
+#endif
/* ======================================================================== */
@@ -457,6 +471,9 @@ extern bd_t __res;
#if defined(CONFIG_LITE5200)
#include <platforms/lite5200.h>
#endif
+#if defined(CONFIG_MEDIA5200)
+#include <platforms/media5200.h>
+#endif
#endif /* __ASM_MPC52xx_H__ */
--
1.2.4
More information about the Linuxppc-embedded
mailing list