13 #include <linux/kernel.h>
14 #include <linux/pci.h>
15 #include <linux/slab.h>
41 #define PCIE_BASE (ORION5X_PCIE_VIRT_BASE)
49 static int pcie_valid_config(
int bus,
int dev)
56 if (bus == 0 && dev == 0)
62 if (bus == 0 && dev != 1)
89 spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
94 static int pcie_rd_conf_wa(
struct pci_bus *bus,
u32 devfn,
95 int where,
int size,
u32 *val)
109 if (where >= 0x100) {
115 bus, devfn, where, size, val);
120 static int pcie_wr_conf(
struct pci_bus *bus,
u32 devfn,
121 int where,
int size,
u32 val)
131 spin_unlock_irqrestore(&orion5x_pcie_lock, flags);
136 static struct pci_ops pcie_ops = {
137 .read = pcie_rd_conf,
138 .write = pcie_wr_conf,
159 "read transaction workaround\n");
162 pcie_ops.
read = pcie_rd_conf_wa;
172 panic(
"pcie_setup unable to alloc resources");
177 res->
name =
"PCIe Memory Space";
182 panic(
"Request PCIe Memory resource failed\n");
191 #define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE + (x))
192 #define PCI_MODE ORION5X_PCI_REG(0xd00)
193 #define PCI_CMD ORION5X_PCI_REG(0xc00)
194 #define PCI_P2P_CONF ORION5X_PCI_REG(0x1d14)
195 #define PCI_CONF_ADDR ORION5X_PCI_REG(0xc78)
196 #define PCI_CONF_DATA ORION5X_PCI_REG(0xc7c)
201 #define PCI_MODE_64BIT (1 << 2)
202 #define PCI_MODE_PCIX ((1 << 4) | (1 << 5))
207 #define PCI_CMD_HOST_REORDER (1 << 29)
212 #define PCI_P2P_BUS_OFFS 16
213 #define PCI_P2P_BUS_MASK (0xff << PCI_P2P_BUS_OFFS)
214 #define PCI_P2P_DEV_OFFS 24
215 #define PCI_P2P_DEV_MASK (0x1f << PCI_P2P_DEV_OFFS)
220 #define PCI_CONF_REG(reg) ((reg) & 0xfc)
221 #define PCI_CONF_FUNC(func) (((func) & 0x3) << 8)
222 #define PCI_CONF_DEV(dev) (((dev) & 0x1f) << 11)
223 #define PCI_CONF_BUS(bus) (((bus) & 0xff) << 16)
224 #define PCI_CONF_ADDR_EN (1 << 31)
229 #define PCI_CONF_FUNC_STAT_CMD 0
230 #define PCI_CONF_REG_STAT_CMD 4
231 #define PCIX_STAT 0x64
232 #define PCIX_STAT_BUS_OFFS 8
233 #define PCIX_STAT_BUS_MASK (0xff << PCIX_STAT_BUS_OFFS)
238 #define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
239 ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
240 ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
241 ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
242 #define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
243 ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
244 ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
245 ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
246 #define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
247 #define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
252 #define PCI_CONF_FUNC_BAR_CS(n) ((n) >> 1)
253 #define PCI_CONF_REG_BAR_LO_CS(n) (((n) & 1) ? 0x18 : 0x10)
254 #define PCI_CONF_REG_BAR_HI_CS(n) (((n) & 1) ? 0x1c : 0x14)
263 static int orion5x_pci_cardbus_mode;
265 static int orion5x_pci_local_bus_nr(
void)
271 static int orion5x_pci_hw_rd_conf(
int bus,
int dev,
u32 func,
284 *val = (*val >> (8*(where & 0x3))) & 0xff;
286 *val = (*val >> (8*(where & 0x3))) & 0xffff;
288 spin_unlock_irqrestore(&orion5x_pci_lock, flags);
293 static int orion5x_pci_hw_wr_conf(
int bus,
int dev,
u32 func,
307 }
else if (size == 2) {
309 }
else if (size == 1) {
315 spin_unlock_irqrestore(&orion5x_pci_lock, flags);
320 static int orion5x_pci_valid_config(
int bus,
u32 devfn)
322 if (bus == orion5x_pci_local_bus_nr()) {
333 if (orion5x_pci_cardbus_mode &&
PCI_SLOT(devfn) > 1)
340 static int orion5x_pci_rd_conf(
struct pci_bus *bus,
u32 devfn,
341 int where,
int size,
u32 *val)
343 if (!orion5x_pci_valid_config(bus->
number, devfn)) {
352 static int orion5x_pci_wr_conf(
struct pci_bus *bus,
u32 devfn,
353 int where,
int size,
u32 val)
355 if (!orion5x_pci_valid_config(bus->
number, devfn))
363 .
read = orion5x_pci_rd_conf,
364 .write = orion5x_pci_wr_conf,
367 static void __init orion5x_pci_set_bus_nr(
int nr)
378 orion5x_pci_hw_rd_conf(bus, dev, 0,
PCIX_STAT, 4, &pcix_status);
381 orion5x_pci_hw_wr_conf(bus, dev, 0,
PCIX_STAT, 4, pcix_status);
392 static void __init orion5x_pci_master_slave_enable(
void)
397 bus_nr = orion5x_pci_local_bus_nr();
400 orion5x_pci_hw_rd_conf(bus_nr, 0, func, reg, 4, &val);
402 orion5x_pci_hw_wr_conf(bus_nr, 0, func, reg, 4, val | 0x7);
414 win_enable = 0xffffffff;
420 bus = orion5x_pci_local_bus_nr();
422 for (i = 0; i < dram->
num_cs; i++) {
423 struct mbus_dram_window *
cs = dram->
cs +
i;
432 orion5x_pci_hw_rd_conf(bus, 0, func, reg, 4, &val);
433 val = (cs->base & 0xfffff000) | (val & 0xfff);
434 orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, val);
440 orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
441 writel((cs->size - 1) & 0xfffff000,
443 writel(cs->base & 0xfffff000,
449 win_enable &= ~(1 << cs->cs_index);
475 orion5x_pci_master_slave_enable();
489 panic(
"pci_setup unable to alloc resources");
494 res->
name =
"PCI Memory Space";
499 panic(
"Request PCI Memory resource failed\n");
530 orion5x_pci_disabled = 1;
535 orion5x_pci_cardbus_mode = 1;
546 ret = pcie_setup(sys);
547 }
else if (nr == 1 && !orion5x_pci_disabled) {
548 orion5x_pci_set_bus_nr(sys->
busnr);
549 ret = pci_setup(sys);
562 }
else if (nr == 1 && !orion5x_pci_disabled) {
575 int bus = dev->
bus->number;
580 if (orion5x_pci_disabled || bus < orion5x_pci_local_bus_nr())