powerpc: Start merging 64-bit support into powermac files
authorPaul Mackerras <paulus@samba.org>
Mon, 10 Oct 2005 12:58:41 +0000 (22:58 +1000)
committerPaul Mackerras <paulus@samba.org>
Mon, 10 Oct 2005 12:58:41 +0000 (22:58 +1000)
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/powerpc/platforms/powermac/pci.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/pmac.h
arch/powerpc/platforms/powermac/setup.c

index 40bcd3e55afb60a6c07f29cd6897dc4cd7994cf9..afb147e6b89f301d73f247ff9c45d93219fdb52d 100644 (file)
@@ -1,8 +1,5 @@
 /*
  * Support for PCI bridges found on Power Macintoshes.
- * At present the "bandit" and "chaos" bridges are supported.
- * Fortunately you access configuration space in the same
- * way with either bridge.
  *
  * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
  * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+#ifdef CONFIG_PPC64
+#include <asm/iommu.h>
+#include <asm/ppc-pci.h>
+#endif
 
 #undef DEBUG
 
@@ -160,9 +161,13 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose,
 static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
                                      int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose;
        unsigned long addr;
 
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -187,9 +192,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
 static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
                                       int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose;
        unsigned long addr;
 
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
        if (!addr)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -221,7 +230,7 @@ static struct pci_ops macrisc_pci_ops =
 };
 
 /*
- * Verifiy that a specific (bus, dev_fn) exists on chaos
+ * Verify that a specific (bus, dev_fn) exists on chaos
  */
 static int
 chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
@@ -274,7 +283,6 @@ static struct pci_ops chaos_pci_ops =
 };
 
 #ifdef CONFIG_POWER4
-
 /*
  * These versions of U3 HyperTransport config space access ops do not
  * implement self-view of the HT host yet
@@ -342,11 +350,11 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
 static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose;
        unsigned long addr;
 
-       struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
-       if (np == NULL)
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
@@ -357,19 +365,19 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
        case 0:
                break;
        case 1:
-                       switch (len) {
-                       case 1:
-                               *val = 0xff; break;
-                       case 2:
-                               *val = 0xffff; break;
-                       default:
-                               *val = 0xfffffffful; break;
-                       }
-                       return PCIBIOS_SUCCESSFUL;
+               switch (len) {
+               case 1:
+                       *val = 0xff; break;
+               case 2:
+                       *val = 0xffff; break;
+               default:
+                       *val = 0xfffffffful; break;
+               }
+               return PCIBIOS_SUCCESSFUL;
        default:
                return PCIBIOS_DEVICE_NOT_FOUND;
-               }
-           
+       }
+
        /*
         * Note: the caller has already checked that offset is
         * suitably aligned and that len is 1, 2 or 4.
@@ -391,11 +399,11 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
 static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose;
        unsigned long addr;
 
-       struct device_node *np = pci_busdev_to_OF_node(bus, devfn);
-       if (np == NULL)
+       hose = pci_bus_to_host(bus);
+       if (hose == NULL)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
        addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
@@ -437,15 +445,13 @@ static struct pci_ops u3_ht_pci_ops =
        u3_ht_read_config,
        u3_ht_write_config
 };
-
 #endif /* CONFIG_POWER4 */
 
 /*
  * For a bandit bridge, turn on cache coherency if necessary.
  * N.B. we could clean this up using the hose ops directly.
  */
-static void __init
-init_bandit(struct pci_controller *bp)
+static void __init init_bandit(struct pci_controller *bp)
 {
        unsigned int vendev, magic;
        int rev;
@@ -485,8 +491,7 @@ init_bandit(struct pci_controller *bp)
 /*
  * Tweak the PCI-PCI bridge chip on the blue & white G3s.
  */
-static void __init
-init_p2pbridge(void)
+static void __init init_p2pbridge(void)
 {
        struct device_node *p2pbridge;
        struct pci_controller* hose;
@@ -526,8 +531,7 @@ init_p2pbridge(void)
  * EHCI part of it so it behaves like a pair of OHCI's. This fixup
  * code re-enables it ;)
  */
-static void __init
-fixup_nec_usb2(void)
+static void __init fixup_nec_usb2(void)
 {
        struct device_node *nec;
 
@@ -567,77 +571,6 @@ fixup_nec_usb2(void)
        }
 }
 
-void __init
-pmac_find_bridges(void)
-{
-       struct device_node *np, *root;
-       struct device_node *ht = NULL;
-
-       root = of_find_node_by_path("/");
-       if (root == NULL) {
-               printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
-               return;
-       }
-       for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
-               if (np->name == NULL)
-                       continue;
-               if (strcmp(np->name, "bandit") == 0
-                   || strcmp(np->name, "chaos") == 0
-                   || strcmp(np->name, "pci") == 0) {
-                       if (add_bridge(np) == 0)
-                               of_node_get(np);
-               }
-               if (strcmp(np->name, "ht") == 0) {
-                       of_node_get(np);
-                       ht = np;
-               }
-       }
-       of_node_put(root);
-
-       /* Probe HT last as it relies on the agp resources to be already
-        * setup
-        */
-       if (ht && add_bridge(ht) != 0)
-               of_node_put(ht);
-
-       init_p2pbridge();
-       fixup_nec_usb2();
-       
-       /* We are still having some issues with the Xserve G4, enabling
-        * some offset between bus number and domains for now when we
-        * assign all busses should help for now
-        */
-       if (pci_assign_all_busses)
-               pcibios_assign_bus_offset = 0x10;
-
-#ifdef CONFIG_POWER4 
-       /* There is something wrong with DMA on U3/HT. I haven't figured out
-        * the details yet, but if I set the cache line size to 128 bytes like
-        * it should, I'm getting memory corruption caused by devices like
-        * sungem (even without the MWI bit set, but maybe sungem doesn't
-        * care). Right now, it appears that setting up a 64 bytes line size
-        * works properly, 64 bytes beeing the max transfer size of HT, I
-        * suppose this is related the way HT/PCI are hooked together. I still
-        * need to dive into more specs though to be really sure of what's
-        * going on. --BenH.
-        *
-        * Ok, apparently, it's just that HT can't do more than 64 bytes
-        * transactions. MWI seem to be meaningless there as well, it may
-        * be worth nop'ing out pci_set_mwi too though I haven't done that
-        * yet.
-        *
-        * Note that it's a bit different for whatever is in the AGP slot.
-        * For now, I don't care, but this can become a real issue, we
-        * should probably hook pci_set_mwi anyway to make sure it sets
-        * the real cache line size in there.
-        */
-       if (machine_is_compatible("MacRISC4"))
-               pci_cache_line_size = 16; /* 64 bytes */
-
-       pmac_check_ht_link();
-#endif /* CONFIG_POWER4 */
-}
-
 #define GRACKLE_CFA(b, d, o)   (0x80 | ((b) << 8) | ((d) << 16) \
                                 | (((o) & ~3) << 24))
 
@@ -703,7 +636,6 @@ setup_chaos(struct pci_controller* hose, struct reg_property* addr)
 }
 
 #ifdef CONFIG_POWER4
-
 static void __init setup_u3_agp(struct pci_controller* hose)
 {
        /* On G5, we move AGP up to high bus number so we don't need
@@ -715,7 +647,7 @@ static void __init setup_u3_agp(struct pci_controller* hose)
         * the reg address cell, we shall fix that by killing struct
         * reg_property and using some accessor functions instead
         */
-               hose->first_busno = 0xf0;
+       hose->first_busno = 0xf0;
        hose->last_busno = 0xff;
        has_uninorth = 1;
        hose->ops = &macrisc_pci_ops;
@@ -748,7 +680,7 @@ static void __init setup_u3_ht(struct pci_controller* hose)
         */
        hose->io_base_phys = 0xf4000000;
        hose->io_base_virt = ioremap(hose->io_base_phys, 0x00400000);
-       isa_io_base = (unsigned long) hose->io_base_virt;
+       isa_io_base = pci_io_base = (unsigned long) hose->io_base_virt;
        hose->io_resource.name = np->full_name;
        hose->io_resource.start = 0;
        hose->io_resource.end = 0x003fffff;
@@ -794,13 +726,13 @@ static void __init setup_u3_ht(struct pci_controller* hose)
                }
                /* No, it's not the case, we need a hole */
                if (cur == 2) {
-                       /* not enough resources to make a hole, we drop part of the range */
+                       /* not enough resources for a hole, we drop part of the range */
                        printk(KERN_WARNING "Running out of resources for /ht host !\n");
                        hose->mem_resources[cur].end = res->start - 1;
                        continue;
                }               
                cur++;
-                       DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
+               DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
                    cur-1, res->start - 1, cur, res->end + 1);
                hose->mem_resources[cur].name = np->full_name;
                hose->mem_resources[cur].flags = IORESOURCE_MEM;
@@ -981,7 +913,7 @@ static int __init add_bridge(struct device_node *dev)
        if (device_is_compatible(dev, "uni-north")) {
                        primary = setup_uninorth(hose, addr);
                        disp_name = "UniNorth";
-               } else if (strcmp(dev->name, "pci") == 0) {
+       } else if (strcmp(dev->name, "pci") == 0) {
                        /* XXX assume this is a mpc106 (grackle) */
                        setup_grackle(hose);
                        disp_name = "Grackle (MPC106)";
@@ -993,7 +925,7 @@ static int __init add_bridge(struct device_node *dev)
                        disp_name = "Chaos";
                        primary = 0;
                }
-               printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n",
+               printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n",
                        disp_name, addr->address, hose->first_busno, hose->last_busno);
                DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
                        hose, hose->cfg_addr, hose->cfg_data);
@@ -1036,6 +968,50 @@ pmac_pcibios_fixup(void)
        pcibios_fixup_OF_interrupts();
 }
 
+void __init pmac_find_bridges(void)
+{
+       struct device_node *np, *root;
+       struct device_node *ht = NULL;
+
+       root = of_find_node_by_path("/");
+       if (root == NULL) {
+               printk(KERN_CRIT "pmac_find_bridges: can't find root of device tree\n");
+               return;
+       }
+       for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
+               if (np->name == NULL)
+                       continue;
+               if (strcmp(np->name, "bandit") == 0
+                   || strcmp(np->name, "chaos") == 0
+                   || strcmp(np->name, "pci") == 0) {
+                       if (add_bridge(np) == 0)
+                               of_node_get(np);
+               }
+               if (strcmp(np->name, "ht") == 0) {
+                       of_node_get(np);
+                       ht = np;
+               }
+       }
+       of_node_put(root);
+
+       /* Probe HT last as it relies on the agp resources to be already
+        * setup
+        */
+       if (ht && add_bridge(ht) != 0)
+               of_node_put(ht);
+
+       init_p2pbridge();
+       fixup_nec_usb2();
+       
+       /* We are still having some issues with the Xserve G4, enabling
+        * some offset between bus number and domains for now when we
+        * assign all busses should help for now
+        */
+       if (pci_assign_all_busses)
+               pcibios_assign_bus_offset = 0x10;
+
+}
+
 int
 pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
 {
index 7ddd5264cc6e23e672841aa914e20b6a6e9290a5..682fe8b6e02596149012c2fce0b97cef429651e4 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sysdev.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
+#include <linux/module.h>
 
 #include <asm/sections.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/time.h>
-#include <asm/open_pic.h>
 #include <asm/xmon.h>
 #include <asm/pmac_feature.h>
 #include <asm/mpic.h>
 
-#include "pmac_pic.h"
+#include "pmac.h"
 
 /*
  * XXX this should be in xmon.h, but putting it there means xmon.h
@@ -46,6 +46,7 @@
  */
 extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
 
+#ifdef CONFIG_PPC32
 struct pmac_irq_hw {
         unsigned int    event;
         unsigned int    enable;
@@ -71,6 +72,9 @@ static u32 level_mask[4];
 
 static DEFINE_SPINLOCK(pmac_pic_lock);
 
+/* XXX here for now, should move to arch/powerpc/kernel/irq.c */
+int ppc_do_canonicalize_irqs;
+EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
 
 #define GATWICK_IRQ_POOL_SIZE        10
 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE];
@@ -377,11 +381,6 @@ static int __init enable_second_ohare(void)
        return irqctrler->intrs[0].line;
 }
 
-static int pmac_u3_cascade(struct pt_regs *regs, void *data)
-{
-       return mpic_get_one_irq((struct mpic *)data, regs);
-}
-
 #ifdef CONFIG_XMON
 static struct irqaction xmon_action = {
        .handler        = xmon_irq,
@@ -397,15 +396,23 @@ static struct irqaction gatwick_cascade_action = {
        .mask           = CPU_MASK_NONE,
        .name           = "cascade",
 };
+#endif /* CONFIG_PPC32 */
+
+static int pmac_u3_cascade(struct pt_regs *regs, void *data)
+{
+       return mpic_get_one_irq((struct mpic *)data, regs);
+}
 
 void __init pmac_pic_init(void)
 {
-        int i;
         struct device_node *irqctrler  = NULL;
         struct device_node *irqctrler2 = NULL;
        struct device_node *np;
+#ifdef CONFIG_PPC32
+        int i;
         unsigned long addr;
        int irq_cascade = -1;
+#endif
        struct mpic *mpic1, *mpic2;
 
        /* We first try to detect Apple's new Core99 chipset, since mac-io
@@ -455,7 +462,7 @@ void __init pmac_pic_init(void)
                        mpic_setup_cascade(irqctrler2->intrs[0].line,
                                           pmac_u3_cascade, mpic2);
                }
-#ifdef CONFIG_XMON
+#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
                {
                        struct device_node* pswitch;
                        int nmi_irq;
@@ -463,7 +470,7 @@ void __init pmac_pic_init(void)
                        pswitch = find_devices("programmer-switch");
                        if (pswitch && pswitch->n_intrs) {
                                nmi_irq = pswitch->intrs[0].line;
-                               openpic_init_nmi_irq(nmi_irq);
+                               mpic_irq_set_priority(nmi_irq, 9);
                                setup_irq(nmi_irq, &xmon_action);
                        }
                }
@@ -472,6 +479,7 @@ void __init pmac_pic_init(void)
        }
        irqctrler = NULL;
 
+#ifdef CONFIG_PPC32
        /* Get the level/edge settings, assume if it's not
         * a Grand Central nor an OHare, then it's an Heathrow
         * (or Paddington).
@@ -570,6 +578,7 @@ void __init pmac_pic_init(void)
 #ifdef CONFIG_XMON
        setup_irq(20, &xmon_action);
 #endif /* CONFIG_XMON */
+#endif /* CONFIG_PPC32 */
 }
 
 #ifdef CONFIG_PM
@@ -659,9 +668,10 @@ static struct sysdev_driver driver_pmacpic = {
 
 static int __init init_pmacpic_sysfs(void)
 {
+#ifdef CONFIG_PPC32
        if (max_irqs == 0)
                return -ENODEV;
-
+#endif
        printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
        sysdev_class_register(&pmacpic_sysclass);
        sysdev_register(&device_pmacpic);
index 40e1c5030f7408ca5f410b24411770962a1f3ec8..81f52512b046b3efcbcb3c29075bff15519b5a38 100644 (file)
@@ -3,19 +3,31 @@
 
 #include <linux/pci.h>
 #include <linux/ide.h>
+#include <linux/irq.h>
 
 /*
  * Declaration for the various functions exported by the
  * pmac_* files. Mostly for use by pmac_setup
  */
 
-extern void pmac_get_boot_time(struct rtc_time *tm);
-extern void pmac_get_rtc_time(struct rtc_time *tm);
-extern int  pmac_set_rtc_time(struct rtc_time *tm);
+extern long pmac_time_init(void);
+extern unsigned long pmac_get_rtc_time(void);
+extern int pmac_set_rtc_time(unsigned long nowtime);
 extern void pmac_read_rtc_time(void);
 extern void pmac_calibrate_decr(void);
-
 extern void pmac_pcibios_fixup(void);
+extern void pmac_find_bridges(void);
+extern unsigned long pmac_ide_get_base(int index);
+extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
+       unsigned long data_port, unsigned long ctrl_port, int *irq);
+
+extern void pmac_nvram_update(void);
+extern unsigned char pmac_nvram_read_byte(int addr);
+extern void pmac_nvram_write_byte(int addr, unsigned char val);
+extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
+extern void pmac_pcibios_after_init(void);
+extern int of_show_percpuinfo(struct seq_file *m, int i);
+
 extern void pmac_pci_init(void);
 extern void pmac_setup_pci_dma(void);
 extern void pmac_check_ht_link(void);
@@ -28,4 +40,9 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
 
 extern void pmac_nvram_init(void);
 
+extern struct hw_interrupt_type pmac_pic;
+
+void pmac_pic_init(void);
+int pmac_get_irq(struct pt_regs *regs);
+
 #endif /* __PMAC_H__ */
index 1b12bf9956cb25dc128f4c2bba0b96f1961e2cc1..9416fcaa6daae6d811e311c8bf4e9570292f1d5b 100644 (file)
 #include <asm/of_device.h>
 #include <asm/mmu_context.h>
 
-#include "pmac_pic.h"
+#include "pmac.h"
 
 #undef SHOW_GATWICK_IRQS
 
-extern long pmac_time_init(void);
-extern unsigned long pmac_get_rtc_time(void);
-extern int pmac_set_rtc_time(unsigned long nowtime);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
-extern void pmac_find_bridges(void);
-extern unsigned long pmac_ide_get_base(int index);
-extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
-       unsigned long data_port, unsigned long ctrl_port, int *irq);
-
-extern void pmac_nvram_update(void);
-extern unsigned char pmac_nvram_read_byte(int addr);
-extern void pmac_nvram_write_byte(int addr, unsigned char val);
-extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
-extern void pmac_pcibios_after_init(void);
-extern int of_show_percpuinfo(struct seq_file *m, int i);
-
 unsigned char drive_info;
 
 int ppc_override_l2cr = 0;