Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

plat-orion: share PCIe handling code

Split off Orion PCIe handling code into plat-orion/.

Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Reviewed-by: Tzachi Perelstein <tzachi@marvell.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Nicolas Pitre <nico@marvell.com>

authored by

Lennert Buytenhek and committed by
Nicolas Pitre
abc0197d 01eb5698

+387 -282
+2 -2
arch/arm/mach-orion/common.h
··· 43 43 struct pci_bus; 44 44 45 45 void orion_pcie_id(u32 *dev, u32 *rev); 46 - u32 orion_pcie_local_bus_nr(void); 47 - u32 orion_pci_local_bus_nr(void); 46 + int orion_pcie_local_bus_nr(void); 47 + int orion_pci_local_bus_nr(void); 48 48 int orion_pci_sys_setup(int nr, struct pci_sys_data *sys); 49 49 struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys); 50 50
+108 -279
arch/arm/mach-orion/pci.c
··· 14 14 #include <linux/pci.h> 15 15 #include <linux/mbus.h> 16 16 #include <asm/mach/pci.h> 17 + #include <asm/plat-orion/pcie.h> 17 18 #include "common.h" 18 19 19 20 /***************************************************************************** ··· 33 32 /***************************************************************************** 34 33 * PCIE controller 35 34 ****************************************************************************/ 36 - #define PCIE_CTRL ORION_PCIE_REG(0x1a00) 37 - #define PCIE_STAT ORION_PCIE_REG(0x1a04) 38 - #define PCIE_DEV_ID ORION_PCIE_REG(0x0000) 39 - #define PCIE_CMD_STAT ORION_PCIE_REG(0x0004) 40 - #define PCIE_DEV_REV ORION_PCIE_REG(0x0008) 41 - #define PCIE_MASK ORION_PCIE_REG(0x1910) 42 - #define PCIE_CONF_ADDR ORION_PCIE_REG(0x18f8) 43 - #define PCIE_CONF_DATA ORION_PCIE_REG(0x18fc) 35 + #define PCIE_BASE ((void __iomem *)ORION_PCIE_VIRT_BASE) 44 36 45 - /* 46 - * PCIE_STAT bits 47 - */ 48 - #define PCIE_STAT_LINK_DOWN 1 49 - #define PCIE_STAT_BUS_OFFS 8 50 - #define PCIE_STAT_BUS_MASK (0xff << PCIE_STAT_BUS_OFFS) 51 - #define PCIE_STAT_DEV_OFFS 20 52 - #define PCIE_STAT_DEV_MASK (0x1f << PCIE_STAT_DEV_OFFS) 37 + void orion_pcie_id(u32 *dev, u32 *rev) 38 + { 39 + *dev = orion_pcie_dev_id(PCIE_BASE); 40 + *rev = orion_pcie_rev(PCIE_BASE); 41 + } 53 42 54 - /* 55 - * PCIE_CONF_ADDR bits 56 - */ 57 - #define PCIE_CONF_REG(r) ((((r) & 0xf00) << 24) | ((r) & 0xfc)) 58 - #define PCIE_CONF_FUNC(f) (((f) & 0x3) << 8) 59 - #define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) 60 - #define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) 61 - #define PCIE_CONF_ADDR_EN (1 << 31) 43 + int orion_pcie_local_bus_nr(void) 44 + { 45 + return orion_pcie_get_local_bus_nr(PCIE_BASE); 46 + } 62 47 63 - /* 64 - * PCIE Address Decode Windows registers 65 - */ 66 - #define PCIE_BAR_CTRL(n) ORION_PCIE_REG(0x1804 + ((n - 1) * 4)) 67 - #define PCIE_BAR_LO(n) ORION_PCIE_REG(0x0010 + ((n) * 8)) 68 - #define PCIE_BAR_HI(n) ORION_PCIE_REG(0x0014 + ((n) * 8)) 69 - #define PCIE_WIN_CTRL(n) (((n) < 5) ? \ 70 - ORION_PCIE_REG(0x1820 + ((n) << 4)) : \ 71 - ORION_PCIE_REG(0x1880)) 72 - #define PCIE_WIN_BASE(n) (((n) < 5) ? \ 73 - ORION_PCIE_REG(0x1824 + ((n) << 4)) : \ 74 - ORION_PCIE_REG(0x1884)) 75 - #define PCIE_WIN_REMAP(n) (((n) < 5) ? \ 76 - ORION_PCIE_REG(0x182c + ((n) << 4)) : \ 77 - ORION_PCIE_REG(0x188c)) 78 - #define PCIE_MAX_BARS 3 79 - #define PCIE_MAX_WINS 6 48 + static int pcie_valid_config(int bus, int dev) 49 + { 50 + /* 51 + * Don't go out when trying to access -- 52 + * 1. our own device / nonexisting device on local bus 53 + * 2. where there's no device connected (no link) 54 + */ 55 + if (bus == 0 && dev != 1) 56 + return 0; 80 57 81 - /* 82 - * Use PCIE BAR '1' for all DDR banks 83 - */ 84 - #define PCIE_DRAM_BAR 1 58 + if (!orion_pcie_link_up(PCIE_BASE)) 59 + return 0; 60 + 61 + return 1; 62 + } 63 + 85 64 86 65 /* 87 66 * PCIE config cycles are done by programming the PCIE_CONF_ADDR register ··· 70 89 */ 71 90 static DEFINE_SPINLOCK(orion_pcie_lock); 72 91 73 - void orion_pcie_id(u32 *dev, u32 *rev) 74 - { 75 - *dev = orion_read(PCIE_DEV_ID) >> 16; 76 - *rev = orion_read(PCIE_DEV_REV) & 0xff; 77 - } 78 - 79 - u32 orion_pcie_local_bus_nr(void) 80 - { 81 - u32 stat = orion_read(PCIE_STAT); 82 - return((stat & PCIE_STAT_BUS_MASK) >> PCIE_STAT_BUS_OFFS); 83 - } 84 - 85 - static u32 orion_pcie_local_dev_nr(void) 86 - { 87 - u32 stat = orion_read(PCIE_STAT); 88 - return((stat & PCIE_STAT_DEV_MASK) >> PCIE_STAT_DEV_OFFS); 89 - } 90 - 91 - static u32 orion_pcie_no_link(void) 92 - { 93 - u32 stat = orion_read(PCIE_STAT); 94 - return(stat & PCIE_STAT_LINK_DOWN); 95 - } 96 - 97 - static void orion_pcie_set_bus_nr(int nr) 98 - { 99 - orion_clrbits(PCIE_STAT, PCIE_STAT_BUS_MASK); 100 - orion_setbits(PCIE_STAT, nr << PCIE_STAT_BUS_OFFS); 101 - } 102 - 103 - /* 104 - * Setup PCIE BARs and Address Decode Wins: 105 - * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks 106 - * WIN[0-3] -> DRAM bank[0-3] 107 - */ 108 - static void orion_setup_pcie_wins(struct mbus_dram_target_info *dram) 109 - { 110 - u32 size; 111 - int i; 112 - 113 - /* 114 - * First, disable and clear BARs and windows 115 - */ 116 - for (i = 1; i < PCIE_MAX_BARS; i++) { 117 - writel(0, PCIE_BAR_CTRL(i)); 118 - writel(0, PCIE_BAR_LO(i)); 119 - writel(0, PCIE_BAR_HI(i)); 120 - } 121 - 122 - for (i = 0; i < PCIE_MAX_WINS; i++) { 123 - writel(0, PCIE_WIN_CTRL(i)); 124 - writel(0, PCIE_WIN_BASE(i)); 125 - writel(0, PCIE_WIN_REMAP(i)); 126 - } 127 - 128 - /* 129 - * Setup windows for DDR banks. Count total DDR size on the fly. 130 - */ 131 - size = 0; 132 - for (i = 0; i < dram->num_cs; i++) { 133 - struct mbus_dram_window *cs = dram->cs + i; 134 - 135 - writel(cs->base & 0xffff0000, PCIE_WIN_BASE(i)); 136 - writel(0, PCIE_WIN_REMAP(i)); 137 - writel(((cs->size - 1) & 0xffff0000) | 138 - (cs->mbus_attr << 8) | 139 - (dram->mbus_dram_target_id << 4) | 140 - (PCIE_DRAM_BAR << 1) | 1, PCIE_WIN_CTRL(i)); 141 - 142 - size += cs->size; 143 - } 144 - 145 - /* 146 - * Setup BAR[1] to all DRAM banks 147 - */ 148 - writel(dram->cs[0].base, PCIE_BAR_LO(PCIE_DRAM_BAR)); 149 - writel(0, PCIE_BAR_HI(PCIE_DRAM_BAR)); 150 - writel(((size - 1) & 0xffff0000) | 1, PCIE_BAR_CTRL(PCIE_DRAM_BAR)); 151 - } 152 - 153 - static void orion_pcie_master_slave_enable(void) 154 - { 155 - orion_setbits(PCIE_CMD_STAT, PCI_COMMAND_MASTER | 156 - PCI_COMMAND_IO | 157 - PCI_COMMAND_MEMORY); 158 - } 159 - 160 - static void orion_pcie_enable_interrupts(void) 161 - { 162 - /* 163 - * Enable interrupts lines 164 - * INTA[24] INTB[25] INTC[26] INTD[27] 165 - */ 166 - orion_setbits(PCIE_MASK, 0xf<<24); 167 - } 168 - 169 - static int orion_pcie_valid_config(u32 bus, u32 dev) 170 - { 171 - /* 172 - * Don't go out when trying to access -- 173 - * 1. our own device 174 - * 2. where there's no device connected (no link) 175 - * 3. nonexisting devices on local bus 176 - */ 177 - 178 - if ((orion_pcie_local_bus_nr() == bus) && 179 - (orion_pcie_local_dev_nr() == dev)) 180 - return 0; 181 - 182 - if (orion_pcie_no_link()) 183 - return 0; 184 - 185 - if (bus == orion_pcie_local_bus_nr()) 186 - if (((orion_pcie_local_dev_nr() == 0) && (dev != 1)) || 187 - ((orion_pcie_local_dev_nr() != 0) && (dev != 0))) 188 - return 0; 189 - 190 - return 1; 191 - } 192 - 193 - static int orion_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 194 - int size, u32 *val) 92 + static int pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, 93 + int size, u32 *val) 195 94 { 196 95 unsigned long flags; 197 - unsigned int dev, rev, pcie_addr; 96 + int ret; 198 97 199 - if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { 98 + if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { 200 99 *val = 0xffffffff; 201 100 return PCIBIOS_DEVICE_NOT_FOUND; 202 101 } 203 102 204 103 spin_lock_irqsave(&orion_pcie_lock, flags); 205 - 206 - orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) | 207 - PCIE_CONF_DEV(PCI_SLOT(devfn)) | 208 - PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 209 - PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN); 210 - 211 - orion_pcie_id(&dev, &rev); 212 - if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { 213 - /* extended register space */ 214 - pcie_addr = ORION_PCIE_WA_VIRT_BASE; 215 - pcie_addr |= PCIE_CONF_BUS(bus->number) | 216 - PCIE_CONF_DEV(PCI_SLOT(devfn)) | 217 - PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 218 - PCIE_CONF_REG(where); 219 - *val = orion_read(pcie_addr); 220 - } else 221 - *val = orion_read(PCIE_CONF_DATA); 222 - 223 - if (size == 1) 224 - *val = (*val >> (8*(where & 0x3))) & 0xff; 225 - else if (size == 2) 226 - *val = (*val >> (8*(where & 0x3))) & 0xffff; 227 - 228 - spin_unlock_irqrestore(&orion_pcie_lock, flags); 229 - 230 - return PCIBIOS_SUCCESSFUL; 231 - } 232 - 233 - 234 - static int orion_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, 235 - int size, u32 val) 236 - { 237 - unsigned long flags; 238 - int ret; 239 - 240 - if (orion_pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) 241 - return PCIBIOS_DEVICE_NOT_FOUND; 242 - 243 - spin_lock_irqsave(&orion_pcie_lock, flags); 244 - 245 - ret = PCIBIOS_SUCCESSFUL; 246 - 247 - orion_write(PCIE_CONF_ADDR, PCIE_CONF_BUS(bus->number) | 248 - PCIE_CONF_DEV(PCI_SLOT(devfn)) | 249 - PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 250 - PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN); 251 - 252 - if (size == 4) { 253 - __raw_writel(val, PCIE_CONF_DATA); 254 - } else if (size == 2) { 255 - __raw_writew(val, PCIE_CONF_DATA + (where & 0x3)); 256 - } else if (size == 1) { 257 - __raw_writeb(val, PCIE_CONF_DATA + (where & 0x3)); 258 - } else { 259 - ret = PCIBIOS_BAD_REGISTER_NUMBER; 260 - } 261 - 104 + ret = orion_pcie_rd_conf(PCIE_BASE, bus, devfn, where, size, val); 262 105 spin_unlock_irqrestore(&orion_pcie_lock, flags); 263 106 264 107 return ret; 265 108 } 266 109 267 - struct pci_ops orion_pcie_ops = { 268 - .read = orion_pcie_rd_conf, 269 - .write = orion_pcie_wr_conf, 110 + static int pcie_rd_conf_wa(struct pci_bus *bus, u32 devfn, 111 + int where, int size, u32 *val) 112 + { 113 + int ret; 114 + 115 + if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) { 116 + *val = 0xffffffff; 117 + return PCIBIOS_DEVICE_NOT_FOUND; 118 + } 119 + 120 + /* 121 + * We only support access to the non-extended configuration 122 + * space when using the WA access method (or we would have to 123 + * sacrifice 256M of CPU virtual address space.) 124 + */ 125 + if (where >= 0x100) { 126 + *val = 0xffffffff; 127 + return PCIBIOS_DEVICE_NOT_FOUND; 128 + } 129 + 130 + ret = orion_pcie_rd_conf_wa((void __iomem *)ORION_PCIE_WA_VIRT_BASE, 131 + bus, devfn, where, size, val); 132 + 133 + return ret; 134 + } 135 + 136 + static int pcie_wr_conf(struct pci_bus *bus, u32 devfn, 137 + int where, int size, u32 val) 138 + { 139 + unsigned long flags; 140 + int ret; 141 + 142 + if (pcie_valid_config(bus->number, PCI_SLOT(devfn)) == 0) 143 + return PCIBIOS_DEVICE_NOT_FOUND; 144 + 145 + spin_lock_irqsave(&orion_pcie_lock, flags); 146 + ret = orion_pcie_wr_conf(PCIE_BASE, bus, devfn, where, size, val); 147 + spin_unlock_irqrestore(&orion_pcie_lock, flags); 148 + 149 + return ret; 150 + } 151 + 152 + struct pci_ops pcie_ops = { 153 + .read = pcie_rd_conf, 154 + .write = pcie_wr_conf, 270 155 }; 271 156 272 157 273 - static int orion_pcie_setup(struct pci_sys_data *sys) 158 + static int pcie_setup(struct pci_sys_data *sys) 274 159 { 275 160 struct resource *res; 161 + int dev; 276 162 277 163 /* 278 - * Point PCIe unit MBUS decode windows to DRAM space. 164 + * Generic PCIe unit setup. 279 165 */ 280 - orion_setup_pcie_wins(&orion_mbus_dram_info); 166 + orion_pcie_setup(PCIE_BASE, &orion_mbus_dram_info); 281 167 282 168 /* 283 - * Master + Slave enable 169 + * Check whether to apply Orion-1/Orion-NAS PCIe config 170 + * read transaction workaround. 284 171 */ 285 - orion_pcie_master_slave_enable(); 172 + dev = orion_pcie_dev_id(PCIE_BASE); 173 + if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) { 174 + printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config " 175 + "read transaction workaround\n"); 176 + pcie_ops.read = pcie_rd_conf_wa; 177 + } 286 178 287 179 /* 288 - * Enable interrupts lines A-D 289 - */ 290 - orion_pcie_enable_interrupts(); 291 - 292 - /* 293 - * Request resource 180 + * Request resources. 294 181 */ 295 182 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); 296 183 if (!res) 297 - panic("orion_pci_setup unable to alloc resources"); 184 + panic("pcie_setup unable to alloc resources"); 298 185 299 186 /* 300 187 * IORESOURCE_IO ··· 266 417 */ 267 418 static DEFINE_SPINLOCK(orion_pci_lock); 268 419 269 - u32 orion_pci_local_bus_nr(void) 420 + int orion_pci_local_bus_nr(void) 270 421 { 271 422 u32 conf = orion_read(PCI_P2P_CONF); 272 423 return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS); 273 424 } 274 425 275 - static u32 orion_pci_local_dev_nr(void) 426 + static int orion_pci_local_dev_nr(void) 276 427 { 277 428 u32 conf = orion_read(PCI_P2P_CONF); 278 429 return((conf & PCI_P2P_DEV_MASK) >> PCI_P2P_DEV_OFFS); 279 430 } 280 431 281 - static int orion_pci_hw_rd_conf(u32 bus, u32 dev, u32 func, 432 + static int orion_pci_hw_rd_conf(int bus, int dev, u32 func, 282 433 u32 where, u32 size, u32 *val) 283 434 { 284 435 unsigned long flags; ··· 300 451 return PCIBIOS_SUCCESSFUL; 301 452 } 302 453 303 - static int orion_pci_hw_wr_conf(u32 bus, u32 dev, u32 func, 454 + static int orion_pci_hw_wr_conf(int bus, int dev, u32 func, 304 455 u32 where, u32 size, u32 val) 305 456 { 306 457 unsigned long flags; ··· 357 508 PCI_FUNC(devfn), where, size, val); 358 509 } 359 510 360 - struct pci_ops orion_pci_ops = { 511 + struct pci_ops pci_ops = { 361 512 .read = orion_pci_rd_conf, 362 513 .write = orion_pci_wr_conf, 363 514 }; ··· 389 540 390 541 static void orion_pci_master_slave_enable(void) 391 542 { 392 - u32 bus_nr, dev_nr, func, reg, val; 543 + int bus_nr, dev_nr, func, reg; 544 + u32 val; 393 545 394 546 bus_nr = orion_pci_local_bus_nr(); 395 547 dev_nr = orion_pci_local_dev_nr(); ··· 404 554 static void orion_setup_pci_wins(struct mbus_dram_target_info *dram) 405 555 { 406 556 u32 win_enable; 407 - u32 bus; 408 - u32 dev; 557 + int bus; 558 + int dev; 409 559 int i; 410 560 411 561 /* ··· 461 611 orion_setbits(PCI_ADDR_DECODE_CTRL, 1); 462 612 } 463 613 464 - static int orion_pci_setup(struct pci_sys_data *sys) 614 + static int pci_setup(struct pci_sys_data *sys) 465 615 { 466 616 struct resource *res; 467 617 ··· 485 635 */ 486 636 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); 487 637 if (!res) 488 - panic("orion_pci_setup unable to alloc resources"); 638 + panic("pci_setup unable to alloc resources"); 489 639 490 640 /* 491 641 * IORESOURCE_IO ··· 524 674 int ret = 0; 525 675 526 676 if (nr == 0) { 527 - /* 528 - * PCIE setup 529 - */ 530 - orion_pcie_set_bus_nr(0); 531 - ret = orion_pcie_setup(sys); 677 + orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr); 678 + ret = pcie_setup(sys); 532 679 } else if (nr == 1) { 533 - /* 534 - * PCI setup 535 - */ 536 - ret = orion_pci_setup(sys); 680 + orion_pci_set_bus_nr(sys->busnr); 681 + ret = pci_setup(sys); 537 682 } 538 683 539 684 return ret; ··· 536 691 537 692 struct pci_bus *orion_pci_sys_scan_bus(int nr, struct pci_sys_data *sys) 538 693 { 539 - struct pci_ops *ops; 540 694 struct pci_bus *bus; 541 695 542 - 543 696 if (nr == 0) { 544 - u32 pci_bus; 545 - /* 546 - * PCIE scan 547 - */ 548 - ops = &orion_pcie_ops; 549 - bus = pci_scan_bus(sys->busnr, ops, sys); 550 - /* 551 - * Set local PCI bus number to follow PCIE bridges (if any) 552 - */ 553 - pci_bus = bus->number + bus->subordinate - bus->secondary + 1; 554 - orion_pci_set_bus_nr(pci_bus); 697 + bus = pci_scan_bus(sys->busnr, &pcie_ops, sys); 555 698 } else if (nr == 1) { 556 - /* 557 - * PCI scan 558 - */ 559 - ops = &orion_pci_ops; 560 - bus = pci_scan_bus(sys->busnr, ops, sys); 699 + bus = pci_scan_bus(sys->busnr, &pci_ops, sys); 561 700 } else { 562 - BUG(); 563 701 bus = NULL; 702 + BUG(); 564 703 } 565 704 566 705 return bus;
+1 -1
arch/arm/plat-orion/Makefile
··· 2 2 # Makefile for the linux kernel. 3 3 # 4 4 5 - obj-y := irq.o 5 + obj-y := irq.o pcie.o 6 6 obj-m := 7 7 obj-n := 8 8 obj- :=
+245
arch/arm/plat-orion/pcie.c
··· 1 + /* 2 + * arch/arm/plat-orion/pcie.c 3 + * 4 + * Marvell Orion SoC PCIe handling. 5 + * 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. 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/pci.h> 13 + #include <linux/mbus.h> 14 + #include <asm/mach/pci.h> 15 + #include <asm/plat-orion/pcie.h> 16 + 17 + /* 18 + * PCIe unit register offsets. 19 + */ 20 + #define PCIE_DEV_ID_OFF 0x0000 21 + #define PCIE_CMD_OFF 0x0004 22 + #define PCIE_DEV_REV_OFF 0x0008 23 + #define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3)) 24 + #define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3)) 25 + #define PCIE_HEADER_LOG_4_OFF 0x0128 26 + #define PCIE_BAR_CTRL_OFF(n) (0x1804 + ((n - 1) * 4)) 27 + #define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4)) 28 + #define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4)) 29 + #define PCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4)) 30 + #define PCIE_WIN5_CTRL_OFF 0x1880 31 + #define PCIE_WIN5_BASE_OFF 0x1884 32 + #define PCIE_WIN5_REMAP_OFF 0x188c 33 + #define PCIE_CONF_ADDR_OFF 0x18f8 34 + #define PCIE_CONF_ADDR_EN 0x80000000 35 + #define PCIE_CONF_REG(r) ((((r) & 0xf00) << 16) | ((r) & 0xfc)) 36 + #define PCIE_CONF_BUS(b) (((b) & 0xff) << 16) 37 + #define PCIE_CONF_DEV(d) (((d) & 0x1f) << 11) 38 + #define PCIE_CONF_FUNC(f) (((f) & 0x3) << 8) 39 + #define PCIE_CONF_DATA_OFF 0x18fc 40 + #define PCIE_MASK_OFF 0x1910 41 + #define PCIE_CTRL_OFF 0x1a00 42 + #define PCIE_STAT_OFF 0x1a04 43 + #define PCIE_STAT_DEV_OFFS 20 44 + #define PCIE_STAT_DEV_MASK 0x1f 45 + #define PCIE_STAT_BUS_OFFS 8 46 + #define PCIE_STAT_BUS_MASK 0xff 47 + #define PCIE_STAT_LINK_DOWN 1 48 + 49 + 50 + u32 __init orion_pcie_dev_id(void __iomem *base) 51 + { 52 + return readl(base + PCIE_DEV_ID_OFF) >> 16; 53 + } 54 + 55 + u32 __init orion_pcie_rev(void __iomem *base) 56 + { 57 + return readl(base + PCIE_DEV_REV_OFF) & 0xff; 58 + } 59 + 60 + int __init orion_pcie_link_up(void __iomem *base) 61 + { 62 + return !(readl(base + PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN); 63 + } 64 + 65 + int __init orion_pcie_get_local_bus_nr(void __iomem *base) 66 + { 67 + u32 stat = readl(base + PCIE_STAT_OFF); 68 + 69 + return (stat >> PCIE_STAT_BUS_OFFS) & PCIE_STAT_BUS_MASK; 70 + } 71 + 72 + void __init orion_pcie_set_local_bus_nr(void __iomem *base, int nr) 73 + { 74 + u32 stat; 75 + 76 + stat = readl(base + PCIE_STAT_OFF); 77 + stat &= ~(PCIE_STAT_BUS_MASK << PCIE_STAT_BUS_OFFS); 78 + stat |= nr << PCIE_STAT_BUS_OFFS; 79 + writel(stat, base + PCIE_STAT_OFF); 80 + } 81 + 82 + /* 83 + * Setup PCIE BARs and Address Decode Wins: 84 + * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks 85 + * WIN[0-3] -> DRAM bank[0-3] 86 + */ 87 + static void __init orion_pcie_setup_wins(void __iomem *base, 88 + struct mbus_dram_target_info *dram) 89 + { 90 + u32 size; 91 + int i; 92 + 93 + /* 94 + * First, disable and clear BARs and windows. 95 + */ 96 + for (i = 1; i <= 2; i++) { 97 + writel(0, base + PCIE_BAR_CTRL_OFF(i)); 98 + writel(0, base + PCIE_BAR_LO_OFF(i)); 99 + writel(0, base + PCIE_BAR_HI_OFF(i)); 100 + } 101 + 102 + for (i = 0; i < 5; i++) { 103 + writel(0, base + PCIE_WIN04_CTRL_OFF(i)); 104 + writel(0, base + PCIE_WIN04_BASE_OFF(i)); 105 + writel(0, base + PCIE_WIN04_REMAP_OFF(i)); 106 + } 107 + 108 + writel(0, base + PCIE_WIN5_CTRL_OFF); 109 + writel(0, base + PCIE_WIN5_BASE_OFF); 110 + writel(0, base + PCIE_WIN5_REMAP_OFF); 111 + 112 + /* 113 + * Setup windows for DDR banks. Count total DDR size on the fly. 114 + */ 115 + size = 0; 116 + for (i = 0; i < dram->num_cs; i++) { 117 + struct mbus_dram_window *cs = dram->cs + i; 118 + 119 + writel(cs->base & 0xffff0000, base + PCIE_WIN04_BASE_OFF(i)); 120 + writel(0, base + PCIE_WIN04_REMAP_OFF(i)); 121 + writel(((cs->size - 1) & 0xffff0000) | 122 + (cs->mbus_attr << 8) | 123 + (dram->mbus_dram_target_id << 4) | 1, 124 + base + PCIE_WIN04_CTRL_OFF(i)); 125 + 126 + size += cs->size; 127 + } 128 + 129 + /* 130 + * Setup BAR[1] to all DRAM banks. 131 + */ 132 + writel(dram->cs[0].base, base + PCIE_BAR_LO_OFF(1)); 133 + writel(0, base + PCIE_BAR_HI_OFF(1)); 134 + writel(((size - 1) & 0xffff0000) | 1, base + PCIE_BAR_CTRL_OFF(1)); 135 + } 136 + 137 + void __init orion_pcie_setup(void __iomem *base, 138 + struct mbus_dram_target_info *dram) 139 + { 140 + u16 cmd; 141 + u32 mask; 142 + 143 + /* 144 + * Point PCIe unit MBUS decode windows to DRAM space. 145 + */ 146 + orion_pcie_setup_wins(base, dram); 147 + 148 + /* 149 + * Master + slave enable. 150 + */ 151 + cmd = readw(base + PCIE_CMD_OFF); 152 + cmd |= PCI_COMMAND_IO; 153 + cmd |= PCI_COMMAND_MEMORY; 154 + cmd |= PCI_COMMAND_MASTER; 155 + writew(cmd, base + PCIE_CMD_OFF); 156 + 157 + /* 158 + * Enable interrupt lines A-D. 159 + */ 160 + mask = readl(base + PCIE_MASK_OFF); 161 + mask |= 0x0f000000; 162 + writel(mask, base + PCIE_MASK_OFF); 163 + } 164 + 165 + int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, 166 + u32 devfn, int where, int size, u32 *val) 167 + { 168 + writel(PCIE_CONF_BUS(bus->number) | 169 + PCIE_CONF_DEV(PCI_SLOT(devfn)) | 170 + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 171 + PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN, 172 + base + PCIE_CONF_ADDR_OFF); 173 + 174 + *val = readl(base + PCIE_CONF_DATA_OFF); 175 + 176 + if (size == 1) 177 + *val = (*val >> (8 * (where & 3))) & 0xff; 178 + else if (size == 2) 179 + *val = (*val >> (8 * (where & 3))) & 0xffff; 180 + 181 + return PCIBIOS_SUCCESSFUL; 182 + } 183 + 184 + int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus, 185 + u32 devfn, int where, int size, u32 *val) 186 + { 187 + writel(PCIE_CONF_BUS(bus->number) | 188 + PCIE_CONF_DEV(PCI_SLOT(devfn)) | 189 + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 190 + PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN, 191 + base + PCIE_CONF_ADDR_OFF); 192 + 193 + *val = readl(base + PCIE_CONF_DATA_OFF); 194 + 195 + if (bus->number != orion_pcie_get_local_bus_nr(base) || 196 + PCI_FUNC(devfn) != 0) 197 + *val = readl(base + PCIE_HEADER_LOG_4_OFF); 198 + 199 + if (size == 1) 200 + *val = (*val >> (8 * (where & 3))) & 0xff; 201 + else if (size == 2) 202 + *val = (*val >> (8 * (where & 3))) & 0xffff; 203 + 204 + return PCIBIOS_SUCCESSFUL; 205 + } 206 + 207 + int orion_pcie_rd_conf_wa(void __iomem *wa_base, struct pci_bus *bus, 208 + u32 devfn, int where, int size, u32 *val) 209 + { 210 + *val = readl(wa_base + (PCIE_CONF_BUS(bus->number) | 211 + PCIE_CONF_DEV(PCI_SLOT(devfn)) | 212 + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 213 + PCIE_CONF_REG(where))); 214 + 215 + if (size == 1) 216 + *val = (*val >> (8 * (where & 3))) & 0xff; 217 + else if (size == 2) 218 + *val = (*val >> (8 * (where & 3))) & 0xffff; 219 + 220 + return PCIBIOS_SUCCESSFUL; 221 + } 222 + 223 + int orion_pcie_wr_conf(void __iomem *base, struct pci_bus *bus, 224 + u32 devfn, int where, int size, u32 val) 225 + { 226 + int ret = PCIBIOS_SUCCESSFUL; 227 + 228 + writel(PCIE_CONF_BUS(bus->number) | 229 + PCIE_CONF_DEV(PCI_SLOT(devfn)) | 230 + PCIE_CONF_FUNC(PCI_FUNC(devfn)) | 231 + PCIE_CONF_REG(where) | PCIE_CONF_ADDR_EN, 232 + base + PCIE_CONF_ADDR_OFF); 233 + 234 + if (size == 4) { 235 + writel(val, base + PCIE_CONF_DATA_OFF); 236 + } else if (size == 2) { 237 + writew(val, base + PCIE_CONF_DATA_OFF + (where & 3)); 238 + } else if (size == 1) { 239 + writeb(val, base + PCIE_CONF_DATA_OFF + (where & 3)); 240 + } else { 241 + ret = PCIBIOS_BAD_REGISTER_NUMBER; 242 + } 243 + 244 + return ret; 245 + }
+31
include/asm-arm/plat-orion/pcie.h
··· 1 + /* 2 + * include/asm-arm/plat-orion/pcie.h 3 + * 4 + * Marvell Orion SoC PCIe handling. 5 + * 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. 9 + */ 10 + 11 + #ifndef __ASM_PLAT_ORION_PCIE_H 12 + #define __ASM_PLAT_ORION_PCIE_H 13 + 14 + u32 orion_pcie_dev_id(void __iomem *base); 15 + u32 orion_pcie_rev(void __iomem *base); 16 + int orion_pcie_link_up(void __iomem *base); 17 + int orion_pcie_get_local_bus_nr(void __iomem *base); 18 + void orion_pcie_set_local_bus_nr(void __iomem *base, int nr); 19 + void orion_pcie_setup(void __iomem *base, 20 + struct mbus_dram_target_info *dram); 21 + int orion_pcie_rd_conf(void __iomem *base, struct pci_bus *bus, 22 + u32 devfn, int where, int size, u32 *val); 23 + int orion_pcie_rd_conf_tlp(void __iomem *base, struct pci_bus *bus, 24 + u32 devfn, int where, int size, u32 *val); 25 + int orion_pcie_rd_conf_wa(void __iomem *wa_base, struct pci_bus *bus, 26 + u32 devfn, int where, int size, u32 *val); 27 + int orion_pcie_wr_conf(void __iomem *base, struct pci_bus *bus, 28 + u32 devfn, int where, int size, u32 val); 29 + 30 + 31 + #endif