1b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/kernel.h>
2b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/init.h>
3b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/pci.h>
4b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include <linux/types.h>
5f15cbe6f1a4b4d9df59142fc8e4abb973302cf44Paul Mundt#include <cpu/irq.h>
6b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt#include "pci-sh5.h"
7b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
8d5341942d784134f2997b3ff82cd63cf71d1f932Ralf Baechleint __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
9b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt{
10b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	int result = -1;
11b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
12b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	/* The complication here is that the PCI IRQ lines from the Cayman's 2
13b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   5V slots get into the CPU via a different path from the IRQ lines
14b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   from the 3 3.3V slots.  Thus, we have to detect whether the card's
15b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
16b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   at the point where we cross from 5V to 3.3V is not the normal case.
17b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
18b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   The added complication is that we don't know that the 5V slots are
19b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   always bus 2, because a card containing a PCI-PCI bridge may be
20b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   plugged into a 3.3V slot, and this changes the bus numbering.
21b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
22b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   Also, the Cayman has an intermediate PCI bus that goes a custom
23b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   expansion board header (and to the secondary bridge).  This bus has
24b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   never been used in practice.
25b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
26b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   The 1ary onboard PCI-PCI bridge is device 3 on bus 0
27b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of
28b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   the 1ary bridge.
29b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   */
30b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
31b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	struct slot_pin {
32b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		int slot;
33b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		int pin;
34b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	} path[4];
35b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	int i=0;
36b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
37b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	while (dev->bus->number > 0) {
38b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
39b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		slot = path[i].slot = PCI_SLOT(dev->devfn);
406aa6e4981741013e4a8c7c3ee7b90c24e89fae24Bjorn Helgaas		pin = path[i].pin = pci_swizzle_interrupt_pin(dev, pin);
41b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		dev = dev->bus->self;
42b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		i++;
43b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		if (i > 3) panic("PCI path to root bus too long!\n");
44b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	}
45b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
46b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	slot = PCI_SLOT(dev->devfn);
47b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	/* This is the slot on bus 0 through which the device is eventually
48b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	   reachable. */
49b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
50b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	/* Now work back up. */
51b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	if ((slot < 3) || (i == 0)) {
52b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		/* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
53b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		   swizzle now. */
546aa6e4981741013e4a8c7c3ee7b90c24e89fae24Bjorn Helgaas		result = IRQ_INTA + pci_swizzle_interrupt_pin(dev, pin) - 1;
55b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	} else {
56b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		i--;
57b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		slot = path[i].slot;
58b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		pin  = path[i].pin;
59b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		if (slot > 0) {
60b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt			panic("PCI expansion bus device found - not handled!\n");
61b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		} else {
62b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt			if (i > 0) {
63b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				/* 5V slots */
64b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				i--;
65b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				slot = path[i].slot;
66b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				pin  = path[i].pin;
67b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				/* 'pin' was swizzled earlier wrt slot, don't do it again. */
68b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				result = IRQ_P2INTA + (pin - 1);
69b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt			} else {
70b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				/* IRQ for 2ary PCI-PCI bridge : unused */
71b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt				result = -1;
72b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt			}
73b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt		}
74b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	}
75b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt
76b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt	return result;
77b6d7b666097e79a8908e3c43fd55fd291a95e133Paul Mundt}
78