diff options
Diffstat (limited to 'arch/mips/pci')
| -rw-r--r-- | arch/mips/pci/ops-bridge.c | 4 | ||||
| -rw-r--r-- | arch/mips/pci/ops-loongson3.c | 34 | ||||
| -rw-r--r-- | arch/mips/pci/ops-pmcmsp.c | 28 | ||||
| -rw-r--r-- | arch/mips/pci/pci-ar2315.c | 24 | ||||
| -rw-r--r-- | arch/mips/pci/pci-ar724x.c | 42 | ||||
| -rw-r--r-- | arch/mips/pci/pci-ip27.c | 25 | ||||
| -rw-r--r-- | arch/mips/pci/pci-legacy.c | 14 | ||||
| -rw-r--r-- | arch/mips/pci/pci-mt7620.c | 1 | ||||
| -rw-r--r-- | arch/mips/pci/pci-octeon.c | 4 | ||||
| -rw-r--r-- | arch/mips/pci/pci-rt2880.c | 2 | ||||
| -rw-r--r-- | arch/mips/pci/pci.c | 4 | ||||
| -rw-r--r-- | arch/mips/pci/pcie-octeon.c | 6 |
12 files changed, 123 insertions, 65 deletions
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c index 57e1463fcd02..a1d2c4ae0d1b 100644 --- a/arch/mips/pci/ops-bridge.c +++ b/arch/mips/pci/ops-bridge.c @@ -167,7 +167,7 @@ oh_my_gawd: static int pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value) { - if (bus->number > 0) + if (!pci_is_root_bus(bus)) return pci_conf1_read_config(bus, devfn, where, size, value); return pci_conf0_read_config(bus, devfn, where, size, value); @@ -310,7 +310,7 @@ oh_my_gawd: static int pci_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) { - if (bus->number > 0) + if (!pci_is_root_bus(bus)) return pci_conf1_write_config(bus, devfn, where, size, value); return pci_conf0_write_config(bus, devfn, where, size, value); diff --git a/arch/mips/pci/ops-loongson3.c b/arch/mips/pci/ops-loongson3.c index 9e118431e226..2f6ad36bdea6 100644 --- a/arch/mips/pci/ops-loongson3.c +++ b/arch/mips/pci/ops-loongson3.c @@ -18,22 +18,36 @@ static int loongson3_pci_config_access(unsigned char access_type, int where, u32 *data) { unsigned char busnum = bus->number; - u_int64_t addr, type; - void *addrp; - int device = PCI_SLOT(devfn); int function = PCI_FUNC(devfn); + int device = PCI_SLOT(devfn); int reg = where & ~3; + void *addrp; + u64 addr; + + if (where < PCI_CFG_SPACE_SIZE) { /* standard config */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + if (busnum == 0) { + if (device > 31) + return PCIBIOS_DEVICE_NOT_FOUND; + addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE | addr); + } else { + addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr); + } + } else if (where < PCI_CFG_SPACE_EXP_SIZE) { /* extended config */ + struct pci_dev *rootdev; + + rootdev = pci_get_domain_bus_and_slot(0, 0, 0); + if (!rootdev) + return PCIBIOS_DEVICE_NOT_FOUND; - addr = (busnum << 16) | (device << 11) | (function << 8) | reg; - if (busnum == 0) { - if (device > 31) + addr = pci_resource_start(rootdev, 3); + if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; - addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff)); - type = 0; + addr |= busnum << 20 | device << 15 | function << 12 | reg; + addrp = (void *)TO_UNCAC(addr); } else { - addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr)); - type = 0x10000; + return PCIBIOS_DEVICE_NOT_FOUND; } if (access_type == PCI_ACCESS_WRITE) diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index dd2d9f7e9412..7649372103af 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c @@ -83,18 +83,6 @@ static int show_msp_pci_counts(struct seq_file *m, void *v) return 0; } -static int msp_pci_rd_cnt_open(struct inode *inode, struct file *file) -{ - return single_open(file, show_msp_pci_counts, NULL); -} - -static const struct file_operations msp_pci_rd_cnt_fops = { - .open = msp_pci_rd_cnt_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /***************************************************************************** * * FUNCTION: gen_pci_cfg_wr_show @@ -160,18 +148,6 @@ static int gen_pci_cfg_wr_show(struct seq_file *m, void *v) return 0; } -static int gen_pci_cfg_wr_open(struct inode *inode, struct file *file) -{ - return single_open(file, gen_pci_cfg_wr_show, NULL); -} - -static const struct file_operations gen_pci_cfg_wr_fops = { - .open = gen_pci_cfg_wr_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /***************************************************************************** * * FUNCTION: pci_proc_init @@ -188,8 +164,8 @@ static const struct file_operations gen_pci_cfg_wr_fops = { ****************************************************************************/ static void pci_proc_init(void) { - proc_create("pmc_msp_pci_rd_cnt", 0, NULL, &msp_pci_rd_cnt_fops); - proc_create("pmc_msp_pci_cfg_wr", 0, NULL, &gen_pci_cfg_wr_fops); + proc_create_single("pmc_msp_pci_rd_cnt", 0, NULL, show_msp_pci_counts); + proc_create_single("pmc_msp_pci_cfg_wr", 0, NULL, gen_pci_cfg_wr_show); } #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c index b4fa6413c4e5..c539d0d2b0cf 100644 --- a/arch/mips/pci/pci-ar2315.c +++ b/arch/mips/pci/pci-ar2315.c @@ -149,6 +149,13 @@ #define AR2315_PCI_HOST_SLOT 3 #define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) +/* + * We need some arbitrary non-zero value to be programmed to the BAR1 register + * of PCI host controller to enable DMA. The same value should be used as the + * offset to calculate the physical address of DMA buffer for PCI devices. + */ +#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000 + /* ??? access BAR */ #define AR2315_PCI_HOST_MBAR0 0x10000000 /* RAM access BAR */ @@ -167,6 +174,23 @@ struct ar2315_pci_ctrl { struct resource io_res; }; +static inline dma_addr_t ar2315_dev_offset(struct device *dev) +{ + if (dev && dev_is_pci(dev)) + return AR2315_PCI_HOST_SDRAM_BASEADDR; + return 0; +} + +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + return paddr + ar2315_dev_offset(dev); +} + +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr - ar2315_dev_offset(dev); +} + static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) { struct pci_controller *hose = bus->sysdata; diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 1e23c8d587bd..64b58cc48a91 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -12,14 +12,18 @@ #include <linux/irq.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/delay.h> #include <linux/platform_device.h> #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> +#define AR724X_PCI_REG_APP 0x00 #define AR724X_PCI_REG_RESET 0x18 #define AR724X_PCI_REG_INT_STATUS 0x4c #define AR724X_PCI_REG_INT_MASK 0x50 +#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0) + #define AR724X_PCI_RESET_LINK_UP BIT(0) #define AR724X_PCI_INT_DEV0 BIT(14) @@ -325,6 +329,37 @@ static void ar724x_pci_irq_init(struct ar724x_pci_controller *apc, apc); } +static void ar724x_pci_hw_init(struct ar724x_pci_controller *apc) +{ + u32 ppl, app; + int wait = 0; + + /* deassert PCIe host controller and PCIe PHY reset */ + ath79_device_reset_clear(AR724X_RESET_PCIE); + ath79_device_reset_clear(AR724X_RESET_PCIE_PHY); + + /* remove the reset of the PCIE PLL */ + ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); + ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_RESET; + ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); + + /* deassert bypass for the PCIE PLL */ + ppl = ath79_pll_rr(AR724X_PLL_REG_PCIE_CONFIG); + ppl &= ~AR724X_PLL_REG_PCIE_CONFIG_PPL_BYPASS; + ath79_pll_wr(AR724X_PLL_REG_PCIE_CONFIG, ppl); + + /* set PCIE Application Control to ready */ + app = __raw_readl(apc->ctrl_base + AR724X_PCI_REG_APP); + app |= AR724X_PCI_APP_LTSSM_ENABLE; + __raw_writel(app, apc->ctrl_base + AR724X_PCI_REG_APP); + + /* wait up to 100ms for PHY link up */ + do { + mdelay(10); + wait++; + } while (wait < 10 && !ar724x_pci_check_link(apc)); +} + static int ar724x_pci_probe(struct platform_device *pdev) { struct ar724x_pci_controller *apc; @@ -383,6 +418,13 @@ static int ar724x_pci_probe(struct platform_device *pdev) apc->pci_controller.io_resource = &apc->io_res; apc->pci_controller.mem_resource = &apc->mem_res; + /* + * Do the full PCIE Root Complex Initialization Sequence if the PCIe + * host controller is in reset. + */ + if (ath79_reset_rr(AR724X_RESET_REG_RESET_MODULE) & AR724X_RESET_PCIE) + ar724x_pci_hw_init(apc); + apc->link_up = ar724x_pci_check_link(apc); if (!apc->link_up) dev_warn(&pdev->dev, "PCIe link is down\n"); diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 0f09eafa5e3a..c94a66070a60 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -11,6 +11,7 @@ #include <linux/export.h> #include <linux/pci.h> #include <linux/smp.h> +#include <linux/dma-direct.h> #include <asm/sn/arch.h> #include <asm/pci/bridge.h> #include <asm/paccess.h> @@ -182,6 +183,19 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus); + + return bc->baddr + paddr; +} + +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr & ~(0xffUL << 56); +} + /* * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses * to find the slot number in sense of the bridge device register. @@ -200,17 +214,6 @@ static inline void pci_disable_swapping(struct pci_dev *dev) bridge->b_widget.w_tflush; /* Flush */ } -static inline void pci_enable_swapping(struct pci_dev *dev) -{ - struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); - bridge_t *bridge = bc->base; - int slot = PCI_SLOT(dev->devfn); - - /* Turn on byte swapping */ - bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; - bridge->b_widget.w_tflush; /* Flush */ -} - static void pci_fixup_ioc3(struct pci_dev *d) { pci_disable_swapping(d); diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c index 0c65c38e05d6..687513880fbf 100644 --- a/arch/mips/pci/pci-legacy.c +++ b/arch/mips/pci/pci-legacy.c @@ -11,7 +11,7 @@ #include <linux/bug.h> #include <linux/kernel.h> #include <linux/mm.h> -#include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/export.h> #include <linux/init.h> #include <linux/types.h> @@ -127,8 +127,12 @@ static void pcibios_scanbus(struct pci_controller *hose) if (pci_has_flag(PCI_PROBE_ONLY)) { pci_bus_claim_resources(bus); } else { + struct pci_bus *child; + pci_bus_size_bridges(bus); pci_bus_assign_resources(bus); + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); } pci_bus_add_devices(bus); } @@ -263,9 +267,8 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) (!(r->flags & IORESOURCE_ROM_ENABLE))) continue; if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); + pci_err(dev, + "can't enable device: resource collisions\n"); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -274,8 +277,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); + pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 407f155f0bb6..f6b77788124a 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -315,6 +315,7 @@ static int mt7620_pci_probe(struct platform_device *pdev) break; case MT762X_SOC_MT7628AN: + case MT762X_SOC_MT7688: if (mt7628_pci_hw_init(pdev)) return -1; break; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index 3e92a06fa772..5017d5843c5a 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -21,8 +21,6 @@ #include <asm/octeon/cvmx-pci-defs.h> #include <asm/octeon/pci-octeon.h> -#include <dma-coherence.h> - #define USE_OCTEON_INTERNAL_ARBITER /* @@ -166,8 +164,6 @@ int pcibios_plat_dev_init(struct pci_dev *dev) pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig); } - dev->dev.dma_ops = octeon_pci_dma_map_ops; - return 0; } diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index 711cdccdf65b..f376a1df326a 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c @@ -246,6 +246,8 @@ static int rt288x_pci_probe(struct platform_device *pdev) rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); + rt2880_pci_controller.of_node = pdev->dev.of_node; + register_pci_controller(&rt2880_pci_controller); return 0; } diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 9632436d74d7..e68b44b27c0d 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -11,7 +11,7 @@ #include <linux/bug.h> #include <linux/kernel.h> #include <linux/mm.h> -#include <linux/bootmem.h> +#include <linux/memblock.h> #include <linux/export.h> #include <linux/init.h> #include <linux/types.h> @@ -54,5 +54,5 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, phys_addr_t size = resource_size(rsrc); *start = fixup_bigphys_addr(rsrc->start, size); - *end = rsrc->start + size; + *end = rsrc->start + size - 1; } diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 87ba86bd8696..d919a0d813a1 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -94,8 +94,6 @@ union cvmx_pcie_address { static int cvmx_pcie_rc_initialize(int pcie_port); -#include <dma-coherence.h> - /** * Return the Core virtual base address for PCIe IO access. IOs are * read/written as an offset from this address. @@ -1239,14 +1237,14 @@ static int __cvmx_pcie_rc_initialize_gen2(int pcie_port) /* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0)) { if (pcie_port) { - union cvmx_ciu_qlm1 ciu_qlm; + union cvmx_ciu_qlm ciu_qlm; ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1); ciu_qlm.s.txbypass = 1; ciu_qlm.s.txdeemph = 5; ciu_qlm.s.txmargin = 0x17; cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64); } else { - union cvmx_ciu_qlm0 ciu_qlm; + union cvmx_ciu_qlm ciu_qlm; ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0); ciu_qlm.s.txbypass = 1; ciu_qlm.s.txdeemph = 5; |

