linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / platforms / 83xx / mpc834x_sys.c
index 32df239..2098dd0 100644 (file)
@@ -11,6 +11,7 @@
  * option) any later version.
  */
 
+#include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
+#include <linux/module.h>
+#include <linux/fsl_devices.h>
 
 #include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
 #include <asm/atomic.h>
 #include <asm/time.h>
 #include <asm/io.h>
 #include <asm/machdep.h>
 #include <asm/ipic.h>
 #include <asm/bootinfo.h>
+#include <asm/pci-bridge.h>
+#include <asm/mpc83xx.h>
 #include <asm/irq.h>
+#include <mm/mmu_decl.h>
 #include <asm/prom.h>
 #include <asm/udbg.h>
 #include <sysdev/fsl_soc.h>
@@ -43,12 +51,53 @@ unsigned long isa_io_base = 0;
 unsigned long isa_mem_base = 0;
 #endif
 
+#ifdef CONFIG_PCI
+extern int mpc83xx_pci2_busno;
+
+static int
+mpc83xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+       static char pci_irq_table[][4] =
+           /*
+            *      PCI IDSEL/INTPIN->INTLINE
+            *       A      B      C      D
+            */
+       {
+               {PIRQA, PIRQB, PIRQC, PIRQD},   /* idsel 0x11 */
+               {PIRQC, PIRQD, PIRQA, PIRQB},   /* idsel 0x12 */
+               {PIRQD, PIRQA, PIRQB, PIRQC},   /* idsel 0x13 */
+               {0, 0, 0, 0},
+               {PIRQA, PIRQB, PIRQC, PIRQD},   /* idsel 0x15 */
+               {PIRQD, PIRQA, PIRQB, PIRQC},   /* idsel 0x16 */
+               {PIRQC, PIRQD, PIRQA, PIRQB},   /* idsel 0x17 */
+               {PIRQB, PIRQC, PIRQD, PIRQA},   /* idsel 0x18 */
+               {0, 0, 0, 0},                   /* idsel 0x19 */
+               {0, 0, 0, 0},                   /* idsel 0x20 */
+       };
+
+       const long min_idsel = 0x11, max_idsel = 0x20, irqs_per_slot = 4;
+       return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static int
+mpc83xx_exclude_device(u_char bus, u_char devfn)
+{
+       if (bus == 0 && PCI_SLOT(devfn) == 0)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (mpc83xx_pci2_busno)
+               if (bus == (mpc83xx_pci2_busno) && PCI_SLOT(devfn) == 0)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+       return PCIBIOS_SUCCESSFUL;
+}
+#endif /* CONFIG_PCI */
+
 /* ************************************************************************
  *
  * Setup the architecture
  *
  */
-static void __init mpc834x_sys_setup_arch(void)
+static void __init
+mpc834x_sys_setup_arch(void)
 {
        struct device_node *np;
 
@@ -57,37 +106,52 @@ static void __init mpc834x_sys_setup_arch(void)
 
        np = of_find_node_by_type(NULL, "cpu");
        if (np != 0) {
-               unsigned int *fp =
-                   (int *)get_property(np, "clock-frequency", NULL);
+               unsigned int *fp = (int *) get_property(np, "clock-frequency", NULL);
                if (fp != 0)
                        loops_per_jiffy = *fp / HZ;
                else
                        loops_per_jiffy = 50000000 / HZ;
                of_node_put(np);
        }
+
 #ifdef CONFIG_PCI
        for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
                add_bridge(np);
 
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_map_irq = mpc83xx_map_irq;
        ppc_md.pci_exclude_device = mpc83xx_exclude_device;
 #endif
 
 #ifdef  CONFIG_ROOT_NFS
-       ROOT_DEV = Root_NFS;
+               ROOT_DEV = Root_NFS;
 #else
-       ROOT_DEV = Root_HDA1;
+               ROOT_DEV = Root_HDA1;
 #endif
 }
 
-void __init mpc834x_sys_init_IRQ(void)
+void __init
+mpc834x_sys_init_IRQ(void)
 {
-       struct device_node *np;
-
-       np = of_find_node_by_type(NULL, "ipic");
-       if (!np)
-               return;
+       u8 senses[8] = {
+               0,                      /* EXT 0 */
+               IRQ_SENSE_LEVEL,        /* EXT 1 */
+               IRQ_SENSE_LEVEL,        /* EXT 2 */
+               0,                      /* EXT 3 */
+#ifdef CONFIG_PCI
+               IRQ_SENSE_LEVEL,        /* EXT 4 */
+               IRQ_SENSE_LEVEL,        /* EXT 5 */
+               IRQ_SENSE_LEVEL,        /* EXT 6 */
+               IRQ_SENSE_LEVEL,        /* EXT 7 */
+#else
+               0,                      /* EXT 4 */
+               0,                      /* EXT 5 */
+               0,                      /* EXT 6 */
+               0,                      /* EXT 7 */
+#endif
+       };
 
-       ipic_init(np, 0);
+       ipic_init(get_immrbase() + 0x00700, 0, 0, senses, 8);
 
        /* Initialize the default interrupt mapping priorities,
         * in case the boot rom changed something on us.
@@ -96,48 +160,84 @@ void __init mpc834x_sys_init_IRQ(void)
 }
 
 #if defined(CONFIG_I2C_MPC) && defined(CONFIG_SENSORS_DS1374)
-extern ulong ds1374_get_rtc_time(void);
-extern int ds1374_set_rtc_time(ulong);
+extern ulong   ds1374_get_rtc_time(void);
+extern int     ds1374_set_rtc_time(ulong);
 
-static int __init mpc834x_rtc_hookup(void)
+static int __init
+mpc834x_rtc_hookup(void)
 {
-       struct timespec tv;
+       struct timespec tv;
 
        ppc_md.get_rtc_time = ds1374_get_rtc_time;
        ppc_md.set_rtc_time = ds1374_set_rtc_time;
 
        tv.tv_nsec = 0;
-       tv.tv_sec = (ppc_md.get_rtc_time) ();
+       tv.tv_sec = (ppc_md.get_rtc_time)();
        do_settimeofday(&tv);
 
        return 0;
 }
-
 late_initcall(mpc834x_rtc_hookup);
 #endif
 
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init mpc834x_sys_probe(void)
+static void
+mpc83xx_restart(char *cmd)
+{
+#define RST_OFFSET     0x00000900
+#define RST_PROT_REG   0x00000018
+#define RST_CTRL_REG   0x0000001c
+       __be32 __iomem *reg;
+
+       // map reset register space
+       reg = ioremap(get_immrbase() + 0x900, 0xff);
+
+       local_irq_disable();
+
+       /* enable software reset "RSTE" */
+       out_be32(reg + (RST_PROT_REG >> 2), 0x52535445);
+
+       /* set software hard reset */
+       out_be32(reg + (RST_CTRL_REG >> 2), 0x52535445);
+       for(;;);
+}
+
+static long __init
+mpc83xx_time_init(void)
 {
-       /* We always match for now, eventually we should look at the flat
-          dev tree to ensure this is the board we are suppose to run on
-       */
-       return 1;
+#define SPCR_OFFSET    0x00000110
+#define SPCR_TBEN      0x00400000
+       __be32 __iomem *spcr = ioremap(get_immrbase() + SPCR_OFFSET, 4);
+       __be32 tmp;
+
+       tmp = in_be32(spcr);
+       out_be32(spcr, tmp|SPCR_TBEN);
+
+       iounmap(spcr);
+
+       return 0;
 }
+void __init
+platform_init(void)
+{
+       /* setup the PowerPC module struct */
+       ppc_md.setup_arch = mpc834x_sys_setup_arch;
+
+       ppc_md.init_IRQ = mpc834x_sys_init_IRQ;
+       ppc_md.get_irq = ipic_get_irq;
+
+       ppc_md.restart = mpc83xx_restart;
+
+       ppc_md.time_init = mpc83xx_time_init;
+       ppc_md.set_rtc_time = NULL;
+       ppc_md.get_rtc_time = NULL;
+       ppc_md.calibrate_decr = generic_calibrate_decr;
+
+       ppc_md.progress = udbg_progress;
+
+       if (ppc_md.progress)
+               ppc_md.progress("mpc834x_sys_init(): exit", 0);
+
+       return;
+}
+
 
-define_machine(mpc834x_sys) {
-       .name                   = "MPC834x SYS",
-       .probe                  = mpc834x_sys_probe,
-       .setup_arch             = mpc834x_sys_setup_arch,
-       .init_IRQ               = mpc834x_sys_init_IRQ,
-       .get_irq                = ipic_get_irq,
-       .restart                = mpc83xx_restart,
-       .time_init              = mpc83xx_time_init,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-#ifdef CONFIG_PCI
-       .pcibios_fixup          = mpc83xx_pcibios_fixup,
-#endif
-};