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

PCI: xilinx-nwl: Add support for Xilinx NWL PCIe Host Controller

Add PCIe Root Port driver for Xilinx PCIe NWL bridge IP.

[bhelgaas: wait for link like dw_pcie_wait_for_link(), simplify bitmap
error path, typos, whitespace, fold in Dan Carpenter's PTR_ERR() fix]
Signed-off-by: Bharat Kumar Gogada <bharatku@xilinx.com>
Signed-off-by: Ravi Kiran Gummaluri <rgummal@xilinx.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Rob Herring <robh@kernel.org>

authored by

Bharat Kumar Gogada and committed by
Bjorn Helgaas
ab597d35 92e963f5

+960
+68
Documentation/devicetree/bindings/pci/xilinx-nwl-pcie.txt
··· 1 + * Xilinx NWL PCIe Root Port Bridge DT description 2 + 3 + Required properties: 4 + - compatible: Should contain "xlnx,nwl-pcie-2.11" 5 + - #address-cells: Address representation for root ports, set to <3> 6 + - #size-cells: Size representation for root ports, set to <2> 7 + - #interrupt-cells: specifies the number of cells needed to encode an 8 + interrupt source. The value must be 1. 9 + - reg: Should contain Bridge, PCIe Controller registers location, 10 + configuration space, and length 11 + - reg-names: Must include the following entries: 12 + "breg": bridge registers 13 + "pcireg": PCIe controller registers 14 + "cfg": configuration space region 15 + - device_type: must be "pci" 16 + - interrupts: Should contain NWL PCIe interrupt 17 + - interrupt-names: Must include the following entries: 18 + "msi1, msi0": interrupt asserted when MSI is received 19 + "intx": interrupt asserted when a legacy interrupt is received 20 + "misc": interrupt asserted when miscellaneous is received 21 + - interrupt-map-mask and interrupt-map: standard PCI properties to define the 22 + mapping of the PCI interface to interrupt numbers. 23 + - ranges: ranges for the PCI memory regions (I/O space region is not 24 + supported by hardware) 25 + Please refer to the standard PCI bus binding document for a more 26 + detailed explanation 27 + - msi-controller: indicates that this is MSI controller node 28 + - msi-parent: MSI parent of the root complex itself 29 + - legacy-interrupt-controller: Interrupt controller device node for Legacy interrupts 30 + - interrupt-controller: identifies the node as an interrupt controller 31 + - #interrupt-cells: should be set to 1 32 + - #address-cells: specifies the number of cells needed to encode an 33 + address. The value must be 0. 34 + 35 + 36 + Example: 37 + ++++++++ 38 + 39 + nwl_pcie: pcie@fd0e0000 { 40 + #address-cells = <3>; 41 + #size-cells = <2>; 42 + compatible = "xlnx,nwl-pcie-2.11"; 43 + #interrupt-cells = <1>; 44 + msi-controller; 45 + device_type = "pci"; 46 + interrupt-parent = <&gic>; 47 + interrupts = <0 114 4>, <0 115 4>, <0 116 4>, <0 117 4>, <0 118 4>; 48 + interrupt-names = "msi0", "msi1", "intx", "dummy", "misc"; 49 + interrupt-map-mask = <0x0 0x0 0x0 0x7>; 50 + interrupt-map = <0x0 0x0 0x0 0x1 &pcie_intc 0x1>, 51 + <0x0 0x0 0x0 0x2 &pcie_intc 0x2>, 52 + <0x0 0x0 0x0 0x3 &pcie_intc 0x3>, 53 + <0x0 0x0 0x0 0x4 &pcie_intc 0x4>; 54 + 55 + msi-parent = <&nwl_pcie>; 56 + reg = <0x0 0xfd0e0000 0x0 0x1000>, 57 + <0x0 0xfd480000 0x0 0x1000>, 58 + <0x0 0xe0000000 0x0 0x1000000>; 59 + reg-names = "breg", "pcireg", "cfg"; 60 + ranges = <0x02000000 0x00000000 0xe1000000 0x00000000 0xe1000000 0 0x0f000000>; 61 + 62 + pcie_intc: legacy-interrupt-controller { 63 + interrupt-controller; 64 + #address-cells = <0>; 65 + #interrupt-cells = <1>; 66 + }; 67 + 68 + };
+10
drivers/pci/host/Kconfig
··· 16 16 depends on ARCH_MVEBU || ARCH_DOVE 17 17 depends on OF 18 18 19 + config PCIE_XILINX_NWL 20 + bool "NWL PCIe Core" 21 + depends on ARCH_ZYNQMP 22 + select PCI_MSI_IRQ_DOMAIN if PCI_MSI 23 + help 24 + Say 'Y' here if you want kernel support for Xilinx 25 + NWL PCIe controller. The controller can act as Root Port 26 + or End Point. The current option selection will only 27 + support root port enabling. 28 + 19 29 config PCIE_DW 20 30 bool 21 31
+1
drivers/pci/host/Makefile
··· 10 10 obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o 11 11 obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o 12 12 obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o 13 + obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o 13 14 obj-$(CONFIG_PCI_XGENE) += pci-xgene.o 14 15 obj-$(CONFIG_PCI_XGENE_MSI) += pci-xgene-msi.o 15 16 obj-$(CONFIG_PCI_LAYERSCAPE) += pci-layerscape.o
+881
drivers/pci/host/pcie-xilinx-nwl.c
··· 1 + /* 2 + * PCIe host controller driver for NWL PCIe Bridge 3 + * Based on pcie-xilinx.c, pci-tegra.c 4 + * 5 + * (C) Copyright 2014 - 2015, Xilinx, Inc. 6 + * 7 + * This program is free software: you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License as published by 9 + * the Free Software Foundation, either version 2 of the License, or 10 + * (at your option) any later version. 11 + */ 12 + 13 + #include <linux/delay.h> 14 + #include <linux/interrupt.h> 15 + #include <linux/irq.h> 16 + #include <linux/irqdomain.h> 17 + #include <linux/kernel.h> 18 + #include <linux/module.h> 19 + #include <linux/msi.h> 20 + #include <linux/of_address.h> 21 + #include <linux/of_pci.h> 22 + #include <linux/of_platform.h> 23 + #include <linux/of_irq.h> 24 + #include <linux/pci.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/irqchip/chained_irq.h> 27 + 28 + /* Bridge core config registers */ 29 + #define BRCFG_PCIE_RX0 0x00000000 30 + #define BRCFG_INTERRUPT 0x00000010 31 + #define BRCFG_PCIE_RX_MSG_FILTER 0x00000020 32 + 33 + /* Egress - Bridge translation registers */ 34 + #define E_BREG_CAPABILITIES 0x00000200 35 + #define E_BREG_CONTROL 0x00000208 36 + #define E_BREG_BASE_LO 0x00000210 37 + #define E_BREG_BASE_HI 0x00000214 38 + #define E_ECAM_CAPABILITIES 0x00000220 39 + #define E_ECAM_CONTROL 0x00000228 40 + #define E_ECAM_BASE_LO 0x00000230 41 + #define E_ECAM_BASE_HI 0x00000234 42 + 43 + /* Ingress - address translations */ 44 + #define I_MSII_CAPABILITIES 0x00000300 45 + #define I_MSII_CONTROL 0x00000308 46 + #define I_MSII_BASE_LO 0x00000310 47 + #define I_MSII_BASE_HI 0x00000314 48 + 49 + #define I_ISUB_CONTROL 0x000003E8 50 + #define SET_ISUB_CONTROL BIT(0) 51 + /* Rxed msg fifo - Interrupt status registers */ 52 + #define MSGF_MISC_STATUS 0x00000400 53 + #define MSGF_MISC_MASK 0x00000404 54 + #define MSGF_LEG_STATUS 0x00000420 55 + #define MSGF_LEG_MASK 0x00000424 56 + #define MSGF_MSI_STATUS_LO 0x00000440 57 + #define MSGF_MSI_STATUS_HI 0x00000444 58 + #define MSGF_MSI_MASK_LO 0x00000448 59 + #define MSGF_MSI_MASK_HI 0x0000044C 60 + 61 + /* Msg filter mask bits */ 62 + #define CFG_ENABLE_PM_MSG_FWD BIT(1) 63 + #define CFG_ENABLE_INT_MSG_FWD BIT(2) 64 + #define CFG_ENABLE_ERR_MSG_FWD BIT(3) 65 + #define CFG_ENABLE_SLT_MSG_FWD BIT(5) 66 + #define CFG_ENABLE_VEN_MSG_FWD BIT(7) 67 + #define CFG_ENABLE_OTH_MSG_FWD BIT(13) 68 + #define CFG_ENABLE_VEN_MSG_EN BIT(14) 69 + #define CFG_ENABLE_VEN_MSG_VEN_INV BIT(15) 70 + #define CFG_ENABLE_VEN_MSG_VEN_ID GENMASK(31, 16) 71 + #define CFG_ENABLE_MSG_FILTER_MASK (CFG_ENABLE_PM_MSG_FWD | \ 72 + CFG_ENABLE_INT_MSG_FWD | \ 73 + CFG_ENABLE_ERR_MSG_FWD | \ 74 + CFG_ENABLE_SLT_MSG_FWD | \ 75 + CFG_ENABLE_VEN_MSG_FWD | \ 76 + CFG_ENABLE_OTH_MSG_FWD | \ 77 + CFG_ENABLE_VEN_MSG_EN | \ 78 + CFG_ENABLE_VEN_MSG_VEN_INV | \ 79 + CFG_ENABLE_VEN_MSG_VEN_ID) 80 + 81 + /* Misc interrupt status mask bits */ 82 + #define MSGF_MISC_SR_RXMSG_AVAIL BIT(0) 83 + #define MSGF_MISC_SR_RXMSG_OVER BIT(1) 84 + #define MSGF_MISC_SR_SLAVE_ERR BIT(4) 85 + #define MSGF_MISC_SR_MASTER_ERR BIT(5) 86 + #define MSGF_MISC_SR_I_ADDR_ERR BIT(6) 87 + #define MSGF_MISC_SR_E_ADDR_ERR BIT(7) 88 + #define MSGF_MISC_SR_UR_DETECT BIT(20) 89 + 90 + #define MSGF_MISC_SR_PCIE_CORE GENMASK(18, 16) 91 + #define MSGF_MISC_SR_PCIE_CORE_ERR GENMASK(31, 22) 92 + 93 + #define MSGF_MISC_SR_MASKALL (MSGF_MISC_SR_RXMSG_AVAIL | \ 94 + MSGF_MISC_SR_RXMSG_OVER | \ 95 + MSGF_MISC_SR_SLAVE_ERR | \ 96 + MSGF_MISC_SR_MASTER_ERR | \ 97 + MSGF_MISC_SR_I_ADDR_ERR | \ 98 + MSGF_MISC_SR_E_ADDR_ERR | \ 99 + MSGF_MISC_SR_UR_DETECT | \ 100 + MSGF_MISC_SR_PCIE_CORE | \ 101 + MSGF_MISC_SR_PCIE_CORE_ERR) 102 + 103 + /* Legacy interrupt status mask bits */ 104 + #define MSGF_LEG_SR_INTA BIT(0) 105 + #define MSGF_LEG_SR_INTB BIT(1) 106 + #define MSGF_LEG_SR_INTC BIT(2) 107 + #define MSGF_LEG_SR_INTD BIT(3) 108 + #define MSGF_LEG_SR_MASKALL (MSGF_LEG_SR_INTA | MSGF_LEG_SR_INTB | \ 109 + MSGF_LEG_SR_INTC | MSGF_LEG_SR_INTD) 110 + 111 + /* MSI interrupt status mask bits */ 112 + #define MSGF_MSI_SR_LO_MASK BIT(0) 113 + #define MSGF_MSI_SR_HI_MASK BIT(0) 114 + 115 + #define MSII_PRESENT BIT(0) 116 + #define MSII_ENABLE BIT(0) 117 + #define MSII_STATUS_ENABLE BIT(15) 118 + 119 + /* Bridge config interrupt mask */ 120 + #define BRCFG_INTERRUPT_MASK BIT(0) 121 + #define BREG_PRESENT BIT(0) 122 + #define BREG_ENABLE BIT(0) 123 + #define BREG_ENABLE_FORCE BIT(1) 124 + 125 + /* E_ECAM status mask bits */ 126 + #define E_ECAM_PRESENT BIT(0) 127 + #define E_ECAM_CR_ENABLE BIT(0) 128 + #define E_ECAM_SIZE_LOC GENMASK(20, 16) 129 + #define E_ECAM_SIZE_SHIFT 16 130 + #define ECAM_BUS_LOC_SHIFT 20 131 + #define ECAM_DEV_LOC_SHIFT 12 132 + #define NWL_ECAM_VALUE_DEFAULT 12 133 + 134 + #define CFG_DMA_REG_BAR GENMASK(2, 0) 135 + 136 + #define INT_PCI_MSI_NR (2 * 32) 137 + #define INTX_NUM 4 138 + 139 + /* Readin the PS_LINKUP */ 140 + #define PS_LINKUP_OFFSET 0x00000238 141 + #define PCIE_PHY_LINKUP_BIT BIT(0) 142 + #define PHY_RDY_LINKUP_BIT BIT(1) 143 + 144 + /* Parameters for the waiting for link up routine */ 145 + #define LINK_WAIT_MAX_RETRIES 10 146 + #define LINK_WAIT_USLEEP_MIN 90000 147 + #define LINK_WAIT_USLEEP_MAX 100000 148 + 149 + struct nwl_msi { /* MSI information */ 150 + struct irq_domain *msi_domain; 151 + unsigned long *bitmap; 152 + struct irq_domain *dev_domain; 153 + struct mutex lock; /* protect bitmap variable */ 154 + int irq_msi0; 155 + int irq_msi1; 156 + }; 157 + 158 + struct nwl_pcie { 159 + struct device *dev; 160 + void __iomem *breg_base; 161 + void __iomem *pcireg_base; 162 + void __iomem *ecam_base; 163 + phys_addr_t phys_breg_base; /* Physical Bridge Register Base */ 164 + phys_addr_t phys_pcie_reg_base; /* Physical PCIe Controller Base */ 165 + phys_addr_t phys_ecam_base; /* Physical Configuration Base */ 166 + u32 breg_size; 167 + u32 pcie_reg_size; 168 + u32 ecam_size; 169 + int irq_intx; 170 + int irq_misc; 171 + u32 ecam_value; 172 + u8 last_busno; 173 + u8 root_busno; 174 + struct nwl_msi msi; 175 + struct irq_domain *legacy_irq_domain; 176 + }; 177 + 178 + static inline u32 nwl_bridge_readl(struct nwl_pcie *pcie, u32 off) 179 + { 180 + return readl(pcie->breg_base + off); 181 + } 182 + 183 + static inline void nwl_bridge_writel(struct nwl_pcie *pcie, u32 val, u32 off) 184 + { 185 + writel(val, pcie->breg_base + off); 186 + } 187 + 188 + static bool nwl_pcie_link_up(struct nwl_pcie *pcie) 189 + { 190 + if (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) & PCIE_PHY_LINKUP_BIT) 191 + return true; 192 + return false; 193 + } 194 + 195 + static bool nwl_phy_link_up(struct nwl_pcie *pcie) 196 + { 197 + if (readl(pcie->pcireg_base + PS_LINKUP_OFFSET) & PHY_RDY_LINKUP_BIT) 198 + return true; 199 + return false; 200 + } 201 + 202 + static int nwl_wait_for_link(struct nwl_pcie *pcie) 203 + { 204 + int retries; 205 + 206 + /* check if the link is up or not */ 207 + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { 208 + if (nwl_phy_link_up(pcie)) 209 + return 0; 210 + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); 211 + } 212 + 213 + dev_err(pcie->dev, "PHY link never came up\n"); 214 + return -ETIMEDOUT; 215 + } 216 + 217 + static bool nwl_pcie_valid_device(struct pci_bus *bus, unsigned int devfn) 218 + { 219 + struct nwl_pcie *pcie = bus->sysdata; 220 + 221 + /* Check link before accessing downstream ports */ 222 + if (bus->number != pcie->root_busno) { 223 + if (!nwl_pcie_link_up(pcie)) 224 + return false; 225 + } 226 + 227 + /* Only one device down on each root port */ 228 + if (bus->number == pcie->root_busno && devfn > 0) 229 + return false; 230 + 231 + return true; 232 + } 233 + 234 + /** 235 + * nwl_pcie_map_bus - Get configuration base 236 + * 237 + * @bus: Bus structure of current bus 238 + * @devfn: Device/function 239 + * @where: Offset from base 240 + * 241 + * Return: Base address of the configuration space needed to be 242 + * accessed. 243 + */ 244 + static void __iomem *nwl_pcie_map_bus(struct pci_bus *bus, unsigned int devfn, 245 + int where) 246 + { 247 + struct nwl_pcie *pcie = bus->sysdata; 248 + int relbus; 249 + 250 + if (!nwl_pcie_valid_device(bus, devfn)) 251 + return NULL; 252 + 253 + relbus = (bus->number << ECAM_BUS_LOC_SHIFT) | 254 + (devfn << ECAM_DEV_LOC_SHIFT); 255 + 256 + return pcie->ecam_base + relbus + where; 257 + } 258 + 259 + /* PCIe operations */ 260 + static struct pci_ops nwl_pcie_ops = { 261 + .map_bus = nwl_pcie_map_bus, 262 + .read = pci_generic_config_read, 263 + .write = pci_generic_config_write, 264 + }; 265 + 266 + static irqreturn_t nwl_pcie_misc_handler(int irq, void *data) 267 + { 268 + struct nwl_pcie *pcie = data; 269 + u32 misc_stat; 270 + 271 + /* Checking for misc interrupts */ 272 + misc_stat = nwl_bridge_readl(pcie, MSGF_MISC_STATUS) & 273 + MSGF_MISC_SR_MASKALL; 274 + if (!misc_stat) 275 + return IRQ_NONE; 276 + 277 + if (misc_stat & MSGF_MISC_SR_RXMSG_OVER) 278 + dev_err(pcie->dev, "Received Message FIFO Overflow\n"); 279 + 280 + if (misc_stat & MSGF_MISC_SR_SLAVE_ERR) 281 + dev_err(pcie->dev, "Slave error\n"); 282 + 283 + if (misc_stat & MSGF_MISC_SR_MASTER_ERR) 284 + dev_err(pcie->dev, "Master error\n"); 285 + 286 + if (misc_stat & MSGF_MISC_SR_I_ADDR_ERR) 287 + dev_err(pcie->dev, 288 + "In Misc Ingress address translation error\n"); 289 + 290 + if (misc_stat & MSGF_MISC_SR_E_ADDR_ERR) 291 + dev_err(pcie->dev, 292 + "In Misc Egress address translation error\n"); 293 + 294 + if (misc_stat & MSGF_MISC_SR_PCIE_CORE_ERR) 295 + dev_err(pcie->dev, "PCIe Core error\n"); 296 + 297 + /* Clear misc interrupt status */ 298 + nwl_bridge_writel(pcie, misc_stat, MSGF_MISC_STATUS); 299 + 300 + return IRQ_HANDLED; 301 + } 302 + 303 + static void nwl_pcie_leg_handler(struct irq_desc *desc) 304 + { 305 + struct irq_chip *chip = irq_desc_get_chip(desc); 306 + struct nwl_pcie *pcie; 307 + unsigned long status; 308 + u32 bit; 309 + u32 virq; 310 + 311 + chained_irq_enter(chip, desc); 312 + pcie = irq_desc_get_handler_data(desc); 313 + 314 + while ((status = nwl_bridge_readl(pcie, MSGF_LEG_STATUS) & 315 + MSGF_LEG_SR_MASKALL) != 0) { 316 + for_each_set_bit(bit, &status, INTX_NUM) { 317 + virq = irq_find_mapping(pcie->legacy_irq_domain, 318 + bit + 1); 319 + if (virq) 320 + generic_handle_irq(virq); 321 + } 322 + } 323 + 324 + chained_irq_exit(chip, desc); 325 + } 326 + 327 + static void nwl_pcie_handle_msi_irq(struct nwl_pcie *pcie, u32 status_reg) 328 + { 329 + struct nwl_msi *msi; 330 + unsigned long status; 331 + u32 bit; 332 + u32 virq; 333 + 334 + msi = &pcie->msi; 335 + 336 + while ((status = nwl_bridge_readl(pcie, status_reg)) != 0) { 337 + for_each_set_bit(bit, &status, 32) { 338 + nwl_bridge_writel(pcie, 1 << bit, status_reg); 339 + virq = irq_find_mapping(msi->dev_domain, bit); 340 + if (virq) 341 + generic_handle_irq(virq); 342 + } 343 + } 344 + } 345 + 346 + static void nwl_pcie_msi_handler_high(struct irq_desc *desc) 347 + { 348 + struct irq_chip *chip = irq_desc_get_chip(desc); 349 + struct nwl_pcie *pcie = irq_desc_get_handler_data(desc); 350 + 351 + chained_irq_enter(chip, desc); 352 + nwl_pcie_handle_msi_irq(pcie, MSGF_MSI_STATUS_HI); 353 + chained_irq_exit(chip, desc); 354 + } 355 + 356 + static void nwl_pcie_msi_handler_low(struct irq_desc *desc) 357 + { 358 + struct irq_chip *chip = irq_desc_get_chip(desc); 359 + struct nwl_pcie *pcie = irq_desc_get_handler_data(desc); 360 + 361 + chained_irq_enter(chip, desc); 362 + nwl_pcie_handle_msi_irq(pcie, MSGF_MSI_STATUS_LO); 363 + chained_irq_exit(chip, desc); 364 + } 365 + 366 + static int nwl_legacy_map(struct irq_domain *domain, unsigned int irq, 367 + irq_hw_number_t hwirq) 368 + { 369 + irq_set_chip_and_handler(irq, &dummy_irq_chip, handle_simple_irq); 370 + irq_set_chip_data(irq, domain->host_data); 371 + 372 + return 0; 373 + } 374 + 375 + static const struct irq_domain_ops legacy_domain_ops = { 376 + .map = nwl_legacy_map, 377 + }; 378 + 379 + #ifdef CONFIG_PCI_MSI 380 + static struct irq_chip nwl_msi_irq_chip = { 381 + .name = "nwl_pcie:msi", 382 + .irq_enable = unmask_msi_irq, 383 + .irq_disable = mask_msi_irq, 384 + .irq_mask = mask_msi_irq, 385 + .irq_unmask = unmask_msi_irq, 386 + 387 + }; 388 + 389 + static struct msi_domain_info nwl_msi_domain_info = { 390 + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 391 + MSI_FLAG_MULTI_PCI_MSI), 392 + .chip = &nwl_msi_irq_chip, 393 + }; 394 + #endif 395 + 396 + static void nwl_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) 397 + { 398 + struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); 399 + phys_addr_t msi_addr = pcie->phys_pcie_reg_base; 400 + 401 + msg->address_lo = lower_32_bits(msi_addr); 402 + msg->address_hi = upper_32_bits(msi_addr); 403 + msg->data = data->hwirq; 404 + } 405 + 406 + static int nwl_msi_set_affinity(struct irq_data *irq_data, 407 + const struct cpumask *mask, bool force) 408 + { 409 + return -EINVAL; 410 + } 411 + 412 + static struct irq_chip nwl_irq_chip = { 413 + .name = "Xilinx MSI", 414 + .irq_compose_msi_msg = nwl_compose_msi_msg, 415 + .irq_set_affinity = nwl_msi_set_affinity, 416 + }; 417 + 418 + static int nwl_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, 419 + unsigned int nr_irqs, void *args) 420 + { 421 + struct nwl_pcie *pcie = domain->host_data; 422 + struct nwl_msi *msi = &pcie->msi; 423 + int bit; 424 + int i; 425 + 426 + mutex_lock(&msi->lock); 427 + bit = bitmap_find_next_zero_area(msi->bitmap, INT_PCI_MSI_NR, 0, 428 + nr_irqs, 0); 429 + if (bit >= INT_PCI_MSI_NR) { 430 + mutex_unlock(&msi->lock); 431 + return -ENOSPC; 432 + } 433 + 434 + bitmap_set(msi->bitmap, bit, nr_irqs); 435 + 436 + for (i = 0; i < nr_irqs; i++) { 437 + irq_domain_set_info(domain, virq + i, bit + i, &nwl_irq_chip, 438 + domain->host_data, handle_simple_irq, 439 + NULL, NULL); 440 + } 441 + mutex_unlock(&msi->lock); 442 + return 0; 443 + } 444 + 445 + static void nwl_irq_domain_free(struct irq_domain *domain, unsigned int virq, 446 + unsigned int nr_irqs) 447 + { 448 + struct irq_data *data = irq_domain_get_irq_data(domain, virq); 449 + struct nwl_pcie *pcie = irq_data_get_irq_chip_data(data); 450 + struct nwl_msi *msi = &pcie->msi; 451 + 452 + mutex_lock(&msi->lock); 453 + bitmap_clear(msi->bitmap, data->hwirq, nr_irqs); 454 + mutex_unlock(&msi->lock); 455 + } 456 + 457 + static const struct irq_domain_ops dev_msi_domain_ops = { 458 + .alloc = nwl_irq_domain_alloc, 459 + .free = nwl_irq_domain_free, 460 + }; 461 + 462 + static void nwl_msi_free_irq_domain(struct nwl_pcie *pcie) 463 + { 464 + struct nwl_msi *msi = &pcie->msi; 465 + 466 + if (msi->irq_msi0) 467 + irq_set_chained_handler_and_data(msi->irq_msi0, NULL, NULL); 468 + if (msi->irq_msi1) 469 + irq_set_chained_handler_and_data(msi->irq_msi1, NULL, NULL); 470 + 471 + if (msi->msi_domain) 472 + irq_domain_remove(msi->msi_domain); 473 + if (msi->dev_domain) 474 + irq_domain_remove(msi->dev_domain); 475 + 476 + kfree(msi->bitmap); 477 + msi->bitmap = NULL; 478 + } 479 + 480 + static void nwl_pcie_free_irq_domain(struct nwl_pcie *pcie) 481 + { 482 + int i; 483 + u32 irq; 484 + 485 + for (i = 0; i < INTX_NUM; i++) { 486 + irq = irq_find_mapping(pcie->legacy_irq_domain, i + 1); 487 + if (irq > 0) 488 + irq_dispose_mapping(irq); 489 + } 490 + if (pcie->legacy_irq_domain) 491 + irq_domain_remove(pcie->legacy_irq_domain); 492 + 493 + nwl_msi_free_irq_domain(pcie); 494 + } 495 + 496 + static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie) 497 + { 498 + #ifdef CONFIG_PCI_MSI 499 + struct fwnode_handle *fwnode = of_node_to_fwnode(pcie->dev->of_node); 500 + struct nwl_msi *msi = &pcie->msi; 501 + 502 + msi->dev_domain = irq_domain_add_linear(NULL, INT_PCI_MSI_NR, 503 + &dev_msi_domain_ops, pcie); 504 + if (!msi->dev_domain) { 505 + dev_err(pcie->dev, "failed to create dev IRQ domain\n"); 506 + return -ENOMEM; 507 + } 508 + msi->msi_domain = pci_msi_create_irq_domain(fwnode, 509 + &nwl_msi_domain_info, 510 + msi->dev_domain); 511 + if (!msi->msi_domain) { 512 + dev_err(pcie->dev, "failed to create msi IRQ domain\n"); 513 + irq_domain_remove(msi->dev_domain); 514 + return -ENOMEM; 515 + } 516 + #endif 517 + return 0; 518 + } 519 + 520 + static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie) 521 + { 522 + struct device_node *node = pcie->dev->of_node; 523 + struct device_node *legacy_intc_node; 524 + 525 + legacy_intc_node = of_get_next_child(node, NULL); 526 + if (!legacy_intc_node) { 527 + dev_err(pcie->dev, "No legacy intc node found\n"); 528 + return -EINVAL; 529 + } 530 + 531 + pcie->legacy_irq_domain = irq_domain_add_linear(legacy_intc_node, 532 + INTX_NUM, 533 + &legacy_domain_ops, 534 + pcie); 535 + 536 + if (!pcie->legacy_irq_domain) { 537 + dev_err(pcie->dev, "failed to create IRQ domain\n"); 538 + return -ENOMEM; 539 + } 540 + 541 + nwl_pcie_init_msi_irq_domain(pcie); 542 + return 0; 543 + } 544 + 545 + static int nwl_pcie_enable_msi(struct nwl_pcie *pcie, struct pci_bus *bus) 546 + { 547 + struct platform_device *pdev = to_platform_device(pcie->dev); 548 + struct nwl_msi *msi = &pcie->msi; 549 + unsigned long base; 550 + int ret; 551 + int size = BITS_TO_LONGS(INT_PCI_MSI_NR) * sizeof(long); 552 + 553 + mutex_init(&msi->lock); 554 + 555 + msi->bitmap = kzalloc(size, GFP_KERNEL); 556 + if (!msi->bitmap) 557 + return -ENOMEM; 558 + 559 + /* Get msi_1 IRQ number */ 560 + msi->irq_msi1 = platform_get_irq_byname(pdev, "msi1"); 561 + if (msi->irq_msi1 < 0) { 562 + dev_err(&pdev->dev, "failed to get IRQ#%d\n", msi->irq_msi1); 563 + ret = -EINVAL; 564 + goto err; 565 + } 566 + 567 + irq_set_chained_handler_and_data(msi->irq_msi1, 568 + nwl_pcie_msi_handler_high, pcie); 569 + 570 + /* Get msi_0 IRQ number */ 571 + msi->irq_msi0 = platform_get_irq_byname(pdev, "msi0"); 572 + if (msi->irq_msi0 < 0) { 573 + dev_err(&pdev->dev, "failed to get IRQ#%d\n", msi->irq_msi0); 574 + ret = -EINVAL; 575 + goto err; 576 + } 577 + 578 + irq_set_chained_handler_and_data(msi->irq_msi0, 579 + nwl_pcie_msi_handler_low, pcie); 580 + 581 + /* Check for msii_present bit */ 582 + ret = nwl_bridge_readl(pcie, I_MSII_CAPABILITIES) & MSII_PRESENT; 583 + if (!ret) { 584 + dev_err(pcie->dev, "MSI not present\n"); 585 + ret = -EIO; 586 + goto err; 587 + } 588 + 589 + /* Enable MSII */ 590 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, I_MSII_CONTROL) | 591 + MSII_ENABLE, I_MSII_CONTROL); 592 + 593 + /* Enable MSII status */ 594 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, I_MSII_CONTROL) | 595 + MSII_STATUS_ENABLE, I_MSII_CONTROL); 596 + 597 + /* setup AFI/FPCI range */ 598 + base = pcie->phys_pcie_reg_base; 599 + nwl_bridge_writel(pcie, lower_32_bits(base), I_MSII_BASE_LO); 600 + nwl_bridge_writel(pcie, upper_32_bits(base), I_MSII_BASE_HI); 601 + 602 + /* 603 + * For high range MSI interrupts: disable, clear any pending, 604 + * and enable 605 + */ 606 + nwl_bridge_writel(pcie, (u32)~MSGF_MSI_SR_HI_MASK, MSGF_MSI_MASK_HI); 607 + 608 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_MSI_STATUS_HI) & 609 + MSGF_MSI_SR_HI_MASK, MSGF_MSI_STATUS_HI); 610 + 611 + nwl_bridge_writel(pcie, MSGF_MSI_SR_HI_MASK, MSGF_MSI_MASK_HI); 612 + 613 + /* 614 + * For low range MSI interrupts: disable, clear any pending, 615 + * and enable 616 + */ 617 + nwl_bridge_writel(pcie, (u32)~MSGF_MSI_SR_LO_MASK, MSGF_MSI_MASK_LO); 618 + 619 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_MSI_STATUS_LO) & 620 + MSGF_MSI_SR_LO_MASK, MSGF_MSI_STATUS_LO); 621 + 622 + nwl_bridge_writel(pcie, MSGF_MSI_SR_LO_MASK, MSGF_MSI_MASK_LO); 623 + 624 + return 0; 625 + err: 626 + kfree(msi->bitmap); 627 + msi->bitmap = NULL; 628 + return ret; 629 + } 630 + 631 + static int nwl_pcie_bridge_init(struct nwl_pcie *pcie) 632 + { 633 + struct platform_device *pdev = to_platform_device(pcie->dev); 634 + u32 breg_val, ecam_val, first_busno = 0; 635 + int err; 636 + 637 + breg_val = nwl_bridge_readl(pcie, E_BREG_CAPABILITIES) & BREG_PRESENT; 638 + if (!breg_val) { 639 + dev_err(pcie->dev, "BREG is not present\n"); 640 + return breg_val; 641 + } 642 + 643 + /* Write bridge_off to breg base */ 644 + nwl_bridge_writel(pcie, lower_32_bits(pcie->phys_breg_base), 645 + E_BREG_BASE_LO); 646 + nwl_bridge_writel(pcie, upper_32_bits(pcie->phys_breg_base), 647 + E_BREG_BASE_HI); 648 + 649 + /* Enable BREG */ 650 + nwl_bridge_writel(pcie, ~BREG_ENABLE_FORCE & BREG_ENABLE, 651 + E_BREG_CONTROL); 652 + 653 + /* Disable DMA channel registers */ 654 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, BRCFG_PCIE_RX0) | 655 + CFG_DMA_REG_BAR, BRCFG_PCIE_RX0); 656 + 657 + /* Enable Ingress subtractive decode translation */ 658 + nwl_bridge_writel(pcie, SET_ISUB_CONTROL, I_ISUB_CONTROL); 659 + 660 + /* Enable msg filtering details */ 661 + nwl_bridge_writel(pcie, CFG_ENABLE_MSG_FILTER_MASK, 662 + BRCFG_PCIE_RX_MSG_FILTER); 663 + 664 + err = nwl_wait_for_link(pcie); 665 + if (err) 666 + return err; 667 + 668 + ecam_val = nwl_bridge_readl(pcie, E_ECAM_CAPABILITIES) & E_ECAM_PRESENT; 669 + if (!ecam_val) { 670 + dev_err(pcie->dev, "ECAM is not present\n"); 671 + return ecam_val; 672 + } 673 + 674 + /* Enable ECAM */ 675 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) | 676 + E_ECAM_CR_ENABLE, E_ECAM_CONTROL); 677 + 678 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, E_ECAM_CONTROL) | 679 + (pcie->ecam_value << E_ECAM_SIZE_SHIFT), 680 + E_ECAM_CONTROL); 681 + 682 + nwl_bridge_writel(pcie, lower_32_bits(pcie->phys_ecam_base), 683 + E_ECAM_BASE_LO); 684 + nwl_bridge_writel(pcie, upper_32_bits(pcie->phys_ecam_base), 685 + E_ECAM_BASE_HI); 686 + 687 + /* Get bus range */ 688 + ecam_val = nwl_bridge_readl(pcie, E_ECAM_CONTROL); 689 + pcie->last_busno = (ecam_val & E_ECAM_SIZE_LOC) >> E_ECAM_SIZE_SHIFT; 690 + /* Write primary, secondary and subordinate bus numbers */ 691 + ecam_val = first_busno; 692 + ecam_val |= (first_busno + 1) << 8; 693 + ecam_val |= (pcie->last_busno << E_ECAM_SIZE_SHIFT); 694 + writel(ecam_val, (pcie->ecam_base + PCI_PRIMARY_BUS)); 695 + 696 + if (nwl_pcie_link_up(pcie)) 697 + dev_info(pcie->dev, "Link is UP\n"); 698 + else 699 + dev_info(pcie->dev, "Link is DOWN\n"); 700 + 701 + /* Get misc IRQ number */ 702 + pcie->irq_misc = platform_get_irq_byname(pdev, "misc"); 703 + if (pcie->irq_misc < 0) { 704 + dev_err(&pdev->dev, "failed to get misc IRQ %d\n", 705 + pcie->irq_misc); 706 + return -EINVAL; 707 + } 708 + 709 + err = devm_request_irq(pcie->dev, pcie->irq_misc, 710 + nwl_pcie_misc_handler, IRQF_SHARED, 711 + "nwl_pcie:misc", pcie); 712 + if (err) { 713 + dev_err(pcie->dev, "fail to register misc IRQ#%d\n", 714 + pcie->irq_misc); 715 + return err; 716 + } 717 + 718 + /* Disable all misc interrupts */ 719 + nwl_bridge_writel(pcie, (u32)~MSGF_MISC_SR_MASKALL, MSGF_MISC_MASK); 720 + 721 + /* Clear pending misc interrupts */ 722 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_MISC_STATUS) & 723 + MSGF_MISC_SR_MASKALL, MSGF_MISC_STATUS); 724 + 725 + /* Enable all misc interrupts */ 726 + nwl_bridge_writel(pcie, MSGF_MISC_SR_MASKALL, MSGF_MISC_MASK); 727 + 728 + 729 + /* Disable all legacy interrupts */ 730 + nwl_bridge_writel(pcie, (u32)~MSGF_LEG_SR_MASKALL, MSGF_LEG_MASK); 731 + 732 + /* Clear pending legacy interrupts */ 733 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, MSGF_LEG_STATUS) & 734 + MSGF_LEG_SR_MASKALL, MSGF_LEG_STATUS); 735 + 736 + /* Enable all legacy interrupts */ 737 + nwl_bridge_writel(pcie, MSGF_LEG_SR_MASKALL, MSGF_LEG_MASK); 738 + 739 + /* Enable the bridge config interrupt */ 740 + nwl_bridge_writel(pcie, nwl_bridge_readl(pcie, BRCFG_INTERRUPT) | 741 + BRCFG_INTERRUPT_MASK, BRCFG_INTERRUPT); 742 + 743 + return 0; 744 + } 745 + 746 + static int nwl_pcie_parse_dt(struct nwl_pcie *pcie, 747 + struct platform_device *pdev) 748 + { 749 + struct device_node *node = pcie->dev->of_node; 750 + struct resource *res; 751 + const char *type; 752 + 753 + /* Check for device type */ 754 + type = of_get_property(node, "device_type", NULL); 755 + if (!type || strcmp(type, "pci")) { 756 + dev_err(pcie->dev, "invalid \"device_type\" %s\n", type); 757 + return -EINVAL; 758 + } 759 + 760 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "breg"); 761 + pcie->breg_base = devm_ioremap_resource(pcie->dev, res); 762 + if (IS_ERR(pcie->breg_base)) 763 + return PTR_ERR(pcie->breg_base); 764 + pcie->phys_breg_base = res->start; 765 + 766 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pcireg"); 767 + pcie->pcireg_base = devm_ioremap_resource(pcie->dev, res); 768 + if (IS_ERR(pcie->pcireg_base)) 769 + return PTR_ERR(pcie->pcireg_base); 770 + pcie->phys_pcie_reg_base = res->start; 771 + 772 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); 773 + pcie->ecam_base = devm_ioremap_resource(pcie->dev, res); 774 + if (IS_ERR(pcie->ecam_base)) 775 + return PTR_ERR(pcie->ecam_base); 776 + pcie->phys_ecam_base = res->start; 777 + 778 + /* Get intx IRQ number */ 779 + pcie->irq_intx = platform_get_irq_byname(pdev, "intx"); 780 + if (pcie->irq_intx < 0) { 781 + dev_err(&pdev->dev, "failed to get intx IRQ %d\n", 782 + pcie->irq_intx); 783 + return -EINVAL; 784 + } 785 + 786 + irq_set_chained_handler_and_data(pcie->irq_intx, 787 + nwl_pcie_leg_handler, pcie); 788 + 789 + return 0; 790 + } 791 + 792 + static const struct of_device_id nwl_pcie_of_match[] = { 793 + { .compatible = "xlnx,nwl-pcie-2.11", }, 794 + {} 795 + }; 796 + 797 + static int nwl_pcie_probe(struct platform_device *pdev) 798 + { 799 + struct device_node *node = pdev->dev.of_node; 800 + struct nwl_pcie *pcie; 801 + struct pci_bus *bus; 802 + struct pci_bus *child; 803 + int err; 804 + resource_size_t iobase = 0; 805 + LIST_HEAD(res); 806 + 807 + pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL); 808 + if (!pcie) 809 + return -ENOMEM; 810 + 811 + pcie->dev = &pdev->dev; 812 + pcie->ecam_value = NWL_ECAM_VALUE_DEFAULT; 813 + 814 + err = nwl_pcie_parse_dt(pcie, pdev); 815 + if (err) { 816 + dev_err(pcie->dev, "Parsing DT failed\n"); 817 + return err; 818 + } 819 + 820 + err = nwl_pcie_bridge_init(pcie); 821 + if (err) { 822 + dev_err(pcie->dev, "HW Initalization failed\n"); 823 + return err; 824 + } 825 + 826 + err = of_pci_get_host_bridge_resources(node, 0, 0xff, &res, &iobase); 827 + if (err) { 828 + pr_err("Getting bridge resources failed\n"); 829 + return err; 830 + } 831 + 832 + err = nwl_pcie_init_irq_domain(pcie); 833 + if (err) { 834 + dev_err(pcie->dev, "Failed creating IRQ Domain\n"); 835 + return err; 836 + } 837 + 838 + bus = pci_create_root_bus(&pdev->dev, pcie->root_busno, 839 + &nwl_pcie_ops, pcie, &res); 840 + if (!bus) 841 + return -ENOMEM; 842 + 843 + if (IS_ENABLED(CONFIG_PCI_MSI)) { 844 + err = nwl_pcie_enable_msi(pcie, bus); 845 + if (err < 0) { 846 + dev_err(&pdev->dev, 847 + "failed to enable MSI support: %d\n", err); 848 + return err; 849 + } 850 + } 851 + pci_scan_child_bus(bus); 852 + pci_assign_unassigned_bus_resources(bus); 853 + list_for_each_entry(child, &bus->children, node) 854 + pcie_bus_configure_settings(child); 855 + pci_bus_add_devices(bus); 856 + platform_set_drvdata(pdev, pcie); 857 + return 0; 858 + } 859 + 860 + static int nwl_pcie_remove(struct platform_device *pdev) 861 + { 862 + struct nwl_pcie *pcie = platform_get_drvdata(pdev); 863 + 864 + nwl_pcie_free_irq_domain(pcie); 865 + platform_set_drvdata(pdev, NULL); 866 + return 0; 867 + } 868 + 869 + static struct platform_driver nwl_pcie_driver = { 870 + .driver = { 871 + .name = "nwl-pcie", 872 + .of_match_table = nwl_pcie_of_match, 873 + }, 874 + .probe = nwl_pcie_probe, 875 + .remove = nwl_pcie_remove, 876 + }; 877 + module_platform_driver(nwl_pcie_driver); 878 + 879 + MODULE_AUTHOR("Xilinx, Inc"); 880 + MODULE_DESCRIPTION("NWL PCIe driver"); 881 + MODULE_LICENSE("GPL");