Pull bugzilla-5452 into release branch
[pandora-kernel.git] / arch / mips / mips-boards / generic / init.c
index 311155d..df4e947 100644 (file)
@@ -1,6 +1,8 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
+ *     All rights reserved.
+ *     Authors: Carsten Langgaard <carstenl@mips.com>
+ *              Maciej W. Rozycki <macro@mips.com>
  *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-#include <asm/io.h>
 #include <asm/bootinfo.h>
+#include <asm/gt64120.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
 #include <asm/mips-boards/prom.h>
 #include <asm/mips-boards/generic.h>
-#ifdef CONFIG_MIPS_GT64120
-#include <asm/gt64120.h>
-#endif
-#include <asm/mips-boards/msc01_pci.h>
 #include <asm/mips-boards/bonito64.h>
-#ifdef CONFIG_MIPS_MALTA
+#include <asm/mips-boards/msc01_pci.h>
+
 #include <asm/mips-boards/malta.h>
-#endif
 
 #ifdef CONFIG_KGDB
 extern int rs_kgdb_hook(int, int);
@@ -217,14 +220,39 @@ void __init kgdb_config (void)
                                generic_putDebugChar (*s++);
                }
 
-               kgdb_enabled = 1;
                /* Breakpoint is invoked after interrupts are initialised */
        }
 }
 #endif
 
+void __init mips_nmi_setup (void)
+{
+       void *base;
+       extern char except_vec_nmi;
+
+       base = cpu_has_veic ?
+               (void *)(CAC_BASE + 0xa80) :
+               (void *)(CAC_BASE + 0x380);
+       memcpy(base, &except_vec_nmi, 0x80);
+       flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init mips_ejtag_setup (void)
+{
+       void *base;
+       extern char except_vec_ejtag_debug;
+
+       base = cpu_has_veic ?
+               (void *)(CAC_BASE + 0xa00) :
+               (void *)(CAC_BASE + 0x300);
+       memcpy(base, &except_vec_ejtag_debug, 0x80);
+       flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
 void __init prom_init(void)
 {
+       u32 start, map, mask, data;
+
        prom_argc = fw_arg0;
        _prom_argv = (int *) fw_arg1;
        _prom_envp = (int *) fw_arg2;
@@ -266,12 +294,15 @@ void __init prom_init(void)
 #else
                GT_WRITE(GT_PCI0_CMD_OFS, 0);
 #endif
+               /* Fix up PCI I/O mapping if necessary (for Atlas).  */
+               start = GT_READ(GT_PCI0IOLD_OFS);
+               map = GT_READ(GT_PCI0IOREMAP_OFS);
+               if ((start & map) != 0) {
+                       map &= ~start;
+                       GT_WRITE(GT_PCI0IOREMAP_OFS, map);
+               }
 
-#ifdef CONFIG_MIPS_MALTA
                set_io_port_base(MALTA_GT_PORT_BASE);
-#else
-               set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
                break;
 
        case MIPS_REVISION_CORID_CORE_EMUL_BON:
@@ -300,18 +331,22 @@ void __init prom_init(void)
                        BONITO_BONGENCFG_BYTESWAP;
 #endif
 
-#ifdef CONFIG_MIPS_MALTA
                set_io_port_base(MALTA_BONITO_PORT_BASE);
-#else
-               set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
                break;
 
        case MIPS_REVISION_CORID_CORE_MSC:
        case MIPS_REVISION_CORID_CORE_FPGA2:
+       case MIPS_REVISION_CORID_CORE_FPGA3:
+       case MIPS_REVISION_CORID_CORE_24K:
        case MIPS_REVISION_CORID_CORE_EMUL_MSC:
                _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
 
+               mb();
+               MSC_READ(MSC01_PCI_CFG, data);
+               MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
+               wmb();
+
+               /* Fix up lane swapping.  */
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
                MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
 #else
@@ -320,12 +355,23 @@ void __init prom_init(void)
                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
 #endif
+               /* Fix up target memory mapping.  */
+               MSC_READ(MSC01_PCI_BAR0, mask);
+               MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
+
+               /* Don't handle target retries indefinitely.  */
+               if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
+                   MSC01_PCI_CFG_MAXRTRY_MSK)
+                       data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
+                                        MSC01_PCI_CFG_MAXRTRY_SHF)) |
+                              ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
+                               MSC01_PCI_CFG_MAXRTRY_SHF);
+
+               wmb();
+               MSC_WRITE(MSC01_PCI_CFG, data);
+               mb();
 
-#ifdef CONFIG_MIPS_MALTA
                set_io_port_base(MALTA_MSC_PORT_BASE);
-#else
-               set_io_port_base((unsigned long)ioremap(0, 0x20000000));
-#endif
                break;
 
        default:
@@ -334,6 +380,9 @@ void __init prom_init(void)
                while(1);   /* We die here... */
        }
 #endif
+       board_nmi_handler_setup = mips_nmi_setup;
+       board_ejtag_handler_setup = mips_ejtag_setup;
+
        prom_printf("\nLINUX started...\n");
        prom_init_cmdline();
        prom_meminit();