2 * arch/arm/mach-kirkwood/pcie.c
4 * PCIe functions for Marvell Kirkwood SoCs
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
11 #include <linux/kernel.h>
12 #include <linux/pci.h>
13 #include <linux/slab.h>
14 #include <linux/mbus.h>
16 #include <asm/mach/pci.h>
17 #include <plat/pcie.h>
18 #include <mach/bridge-regs.h>
22 #define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE)
24 void __init
kirkwood_pcie_id(u32
*dev
, u32
*rev
)
26 *dev
= orion_pcie_dev_id(PCIE_BASE
);
27 *rev
= orion_pcie_rev(PCIE_BASE
);
30 static int pcie_valid_config(int bus
, int dev
)
33 * Don't go out when trying to access --
34 * 1. nonexisting device on local bus
35 * 2. where there's no device connected (no link)
37 if (bus
== 0 && dev
== 0)
40 if (!orion_pcie_link_up(PCIE_BASE
))
43 if (bus
== 0 && dev
!= 1)
51 * PCIe config cycles are done by programming the PCIE_CONF_ADDR register
52 * and then reading the PCIE_CONF_DATA register. Need to make sure these
53 * transactions are atomic.
55 static DEFINE_SPINLOCK(kirkwood_pcie_lock
);
57 static int pcie_rd_conf(struct pci_bus
*bus
, u32 devfn
, int where
,
63 if (pcie_valid_config(bus
->number
, PCI_SLOT(devfn
)) == 0) {
65 return PCIBIOS_DEVICE_NOT_FOUND
;
68 spin_lock_irqsave(&kirkwood_pcie_lock
, flags
);
69 ret
= orion_pcie_rd_conf(PCIE_BASE
, bus
, devfn
, where
, size
, val
);
70 spin_unlock_irqrestore(&kirkwood_pcie_lock
, flags
);
75 static int pcie_wr_conf(struct pci_bus
*bus
, u32 devfn
,
76 int where
, int size
, u32 val
)
81 if (pcie_valid_config(bus
->number
, PCI_SLOT(devfn
)) == 0)
82 return PCIBIOS_DEVICE_NOT_FOUND
;
84 spin_lock_irqsave(&kirkwood_pcie_lock
, flags
);
85 ret
= orion_pcie_wr_conf(PCIE_BASE
, bus
, devfn
, where
, size
, val
);
86 spin_unlock_irqrestore(&kirkwood_pcie_lock
, flags
);
91 static struct pci_ops pcie_ops
= {
93 .write
= pcie_wr_conf
,
97 static int __init
kirkwood_pcie_setup(int nr
, struct pci_sys_data
*sys
)
100 extern unsigned int kirkwood_clk_ctrl
;
103 * Generic PCIe unit setup.
105 orion_pcie_setup(PCIE_BASE
, &kirkwood_mbus_dram_info
);
110 res
= kzalloc(sizeof(struct resource
) * 2, GFP_KERNEL
);
112 panic("pcie_setup unable to alloc resources");
117 res
[0].name
= "PCIe I/O Space";
118 res
[0].flags
= IORESOURCE_IO
;
119 res
[0].start
= KIRKWOOD_PCIE_IO_BUS_BASE
;
120 res
[0].end
= res
[0].start
+ KIRKWOOD_PCIE_IO_SIZE
- 1;
121 if (request_resource(&ioport_resource
, &res
[0]))
122 panic("Request PCIe IO resource failed\n");
123 sys
->resource
[0] = &res
[0];
128 res
[1].name
= "PCIe Memory Space";
129 res
[1].flags
= IORESOURCE_MEM
;
130 res
[1].start
= KIRKWOOD_PCIE_MEM_BUS_BASE
;
131 res
[1].end
= res
[1].start
+ KIRKWOOD_PCIE_MEM_SIZE
- 1;
132 if (request_resource(&iomem_resource
, &res
[1]))
133 panic("Request PCIe Memory resource failed\n");
134 sys
->resource
[1] = &res
[1];
136 sys
->resource
[2] = NULL
;
139 kirkwood_clk_ctrl
|= CGC_PEX0
;
144 static void __devinit
rc_pci_fixup(struct pci_dev
*dev
)
147 * Prevent enumeration of root complex.
149 if (dev
->bus
->parent
== NULL
&& dev
->devfn
== 0) {
152 for (i
= 0; i
< DEVICE_COUNT_RESOURCE
; i
++) {
153 dev
->resource
[i
].start
= 0;
154 dev
->resource
[i
].end
= 0;
155 dev
->resource
[i
].flags
= 0;
159 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL
, PCI_ANY_ID
, rc_pci_fixup
);
161 static struct pci_bus __init
*
162 kirkwood_pcie_scan_bus(int nr
, struct pci_sys_data
*sys
)
167 bus
= pci_scan_bus(sys
->busnr
, &pcie_ops
, sys
);
176 static int __init
kirkwood_pcie_map_irq(struct pci_dev
*dev
, u8 slot
, u8 pin
)
178 return IRQ_KIRKWOOD_PCIE
;
181 static struct hw_pci kirkwood_pci __initdata
= {
183 .swizzle
= pci_std_swizzle
,
184 .setup
= kirkwood_pcie_setup
,
185 .scan
= kirkwood_pcie_scan_bus
,
186 .map_irq
= kirkwood_pcie_map_irq
,
189 void __init
kirkwood_pcie_init(void)
191 pci_common_init(&kirkwood_pci
);