645 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * PLDA PCIe XpressRich host controller driver4 *5 * Copyright (C) 2023 Microchip Co. Ltd6 * StarFive Co. Ltd7 *8 * Author: Daire McNamara <daire.mcnamara@microchip.com>9 */10 11#include <linux/irqchip/chained_irq.h>12#include <linux/irqdomain.h>13#include <linux/msi.h>14#include <linux/pci_regs.h>15#include <linux/pci-ecam.h>16 17#include "pcie-plda.h"18 19void __iomem *plda_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,20 int where)21{22 struct plda_pcie_rp *pcie = bus->sysdata;23 24 return pcie->config_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);25}26EXPORT_SYMBOL_GPL(plda_pcie_map_bus);27 28static void plda_handle_msi(struct irq_desc *desc)29{30 struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);31 struct irq_chip *chip = irq_desc_get_chip(desc);32 struct device *dev = port->dev;33 struct plda_msi *msi = &port->msi;34 void __iomem *bridge_base_addr = port->bridge_addr;35 unsigned long status;36 u32 bit;37 int ret;38 39 chained_irq_enter(chip, desc);40 41 status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);42 if (status & PM_MSI_INT_MSI_MASK) {43 writel_relaxed(status & PM_MSI_INT_MSI_MASK,44 bridge_base_addr + ISTATUS_LOCAL);45 status = readl_relaxed(bridge_base_addr + ISTATUS_MSI);46 for_each_set_bit(bit, &status, msi->num_vectors) {47 ret = generic_handle_domain_irq(msi->dev_domain, bit);48 if (ret)49 dev_err_ratelimited(dev, "bad MSI IRQ %d\n",50 bit);51 }52 }53 54 chained_irq_exit(chip, desc);55}56 57static void plda_msi_bottom_irq_ack(struct irq_data *data)58{59 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);60 void __iomem *bridge_base_addr = port->bridge_addr;61 u32 bitpos = data->hwirq;62 63 writel_relaxed(BIT(bitpos), bridge_base_addr + ISTATUS_MSI);64}65 66static void plda_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)67{68 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);69 phys_addr_t addr = port->msi.vector_phy;70 71 msg->address_lo = lower_32_bits(addr);72 msg->address_hi = upper_32_bits(addr);73 msg->data = data->hwirq;74 75 dev_dbg(port->dev, "msi#%x address_hi %#x address_lo %#x\n",76 (int)data->hwirq, msg->address_hi, msg->address_lo);77}78 79static struct irq_chip plda_msi_bottom_irq_chip = {80 .name = "PLDA MSI",81 .irq_ack = plda_msi_bottom_irq_ack,82 .irq_compose_msi_msg = plda_compose_msi_msg,83};84 85static int plda_irq_msi_domain_alloc(struct irq_domain *domain,86 unsigned int virq,87 unsigned int nr_irqs,88 void *args)89{90 struct plda_pcie_rp *port = domain->host_data;91 struct plda_msi *msi = &port->msi;92 unsigned long bit;93 94 mutex_lock(&msi->lock);95 bit = find_first_zero_bit(msi->used, msi->num_vectors);96 if (bit >= msi->num_vectors) {97 mutex_unlock(&msi->lock);98 return -ENOSPC;99 }100 101 set_bit(bit, msi->used);102 103 irq_domain_set_info(domain, virq, bit, &plda_msi_bottom_irq_chip,104 domain->host_data, handle_edge_irq, NULL, NULL);105 106 mutex_unlock(&msi->lock);107 108 return 0;109}110 111static void plda_irq_msi_domain_free(struct irq_domain *domain,112 unsigned int virq,113 unsigned int nr_irqs)114{115 struct irq_data *d = irq_domain_get_irq_data(domain, virq);116 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(d);117 struct plda_msi *msi = &port->msi;118 119 mutex_lock(&msi->lock);120 121 if (test_bit(d->hwirq, msi->used))122 __clear_bit(d->hwirq, msi->used);123 else124 dev_err(port->dev, "trying to free unused MSI%lu\n", d->hwirq);125 126 mutex_unlock(&msi->lock);127}128 129static const struct irq_domain_ops msi_domain_ops = {130 .alloc = plda_irq_msi_domain_alloc,131 .free = plda_irq_msi_domain_free,132};133 134static struct irq_chip plda_msi_irq_chip = {135 .name = "PLDA PCIe MSI",136 .irq_ack = irq_chip_ack_parent,137 .irq_mask = pci_msi_mask_irq,138 .irq_unmask = pci_msi_unmask_irq,139};140 141static struct msi_domain_info plda_msi_domain_info = {142 .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |143 MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX,144 .chip = &plda_msi_irq_chip,145};146 147static int plda_allocate_msi_domains(struct plda_pcie_rp *port)148{149 struct device *dev = port->dev;150 struct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);151 struct plda_msi *msi = &port->msi;152 153 mutex_init(&port->msi.lock);154 155 msi->dev_domain = irq_domain_add_linear(NULL, msi->num_vectors,156 &msi_domain_ops, port);157 if (!msi->dev_domain) {158 dev_err(dev, "failed to create IRQ domain\n");159 return -ENOMEM;160 }161 162 msi->msi_domain = pci_msi_create_irq_domain(fwnode,163 &plda_msi_domain_info,164 msi->dev_domain);165 if (!msi->msi_domain) {166 dev_err(dev, "failed to create MSI domain\n");167 irq_domain_remove(msi->dev_domain);168 return -ENOMEM;169 }170 171 return 0;172}173 174static void plda_handle_intx(struct irq_desc *desc)175{176 struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);177 struct irq_chip *chip = irq_desc_get_chip(desc);178 struct device *dev = port->dev;179 void __iomem *bridge_base_addr = port->bridge_addr;180 unsigned long status;181 u32 bit;182 int ret;183 184 chained_irq_enter(chip, desc);185 186 status = readl_relaxed(bridge_base_addr + ISTATUS_LOCAL);187 if (status & PM_MSI_INT_INTX_MASK) {188 status &= PM_MSI_INT_INTX_MASK;189 status >>= PM_MSI_INT_INTX_SHIFT;190 for_each_set_bit(bit, &status, PCI_NUM_INTX) {191 ret = generic_handle_domain_irq(port->intx_domain, bit);192 if (ret)193 dev_err_ratelimited(dev, "bad INTx IRQ %d\n",194 bit);195 }196 }197 198 chained_irq_exit(chip, desc);199}200 201static void plda_ack_intx_irq(struct irq_data *data)202{203 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);204 void __iomem *bridge_base_addr = port->bridge_addr;205 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);206 207 writel_relaxed(mask, bridge_base_addr + ISTATUS_LOCAL);208}209 210static void plda_mask_intx_irq(struct irq_data *data)211{212 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);213 void __iomem *bridge_base_addr = port->bridge_addr;214 unsigned long flags;215 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);216 u32 val;217 218 raw_spin_lock_irqsave(&port->lock, flags);219 val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);220 val &= ~mask;221 writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);222 raw_spin_unlock_irqrestore(&port->lock, flags);223}224 225static void plda_unmask_intx_irq(struct irq_data *data)226{227 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);228 void __iomem *bridge_base_addr = port->bridge_addr;229 unsigned long flags;230 u32 mask = BIT(data->hwirq + PM_MSI_INT_INTX_SHIFT);231 u32 val;232 233 raw_spin_lock_irqsave(&port->lock, flags);234 val = readl_relaxed(bridge_base_addr + IMASK_LOCAL);235 val |= mask;236 writel_relaxed(val, bridge_base_addr + IMASK_LOCAL);237 raw_spin_unlock_irqrestore(&port->lock, flags);238}239 240static struct irq_chip plda_intx_irq_chip = {241 .name = "PLDA PCIe INTx",242 .irq_ack = plda_ack_intx_irq,243 .irq_mask = plda_mask_intx_irq,244 .irq_unmask = plda_unmask_intx_irq,245};246 247static int plda_pcie_intx_map(struct irq_domain *domain, unsigned int irq,248 irq_hw_number_t hwirq)249{250 irq_set_chip_and_handler(irq, &plda_intx_irq_chip, handle_level_irq);251 irq_set_chip_data(irq, domain->host_data);252 253 return 0;254}255 256static const struct irq_domain_ops intx_domain_ops = {257 .map = plda_pcie_intx_map,258};259 260static u32 plda_get_events(struct plda_pcie_rp *port)261{262 u32 events, val, origin;263 264 origin = readl_relaxed(port->bridge_addr + ISTATUS_LOCAL);265 266 /* MSI event and sys events */267 val = (origin & SYS_AND_MSI_MASK) >> PM_MSI_INT_MSI_SHIFT;268 events = val << (PM_MSI_INT_MSI_SHIFT - PCI_NUM_INTX + 1);269 270 /* INTx events */271 if (origin & PM_MSI_INT_INTX_MASK)272 events |= BIT(PM_MSI_INT_INTX_SHIFT);273 274 /* remains are same with register */275 events |= origin & GENMASK(P_ATR_EVT_DOORBELL_SHIFT, 0);276 277 return events;278}279 280static irqreturn_t plda_event_handler(int irq, void *dev_id)281{282 return IRQ_HANDLED;283}284 285static void plda_handle_event(struct irq_desc *desc)286{287 struct plda_pcie_rp *port = irq_desc_get_handler_data(desc);288 unsigned long events;289 u32 bit;290 struct irq_chip *chip = irq_desc_get_chip(desc);291 292 chained_irq_enter(chip, desc);293 294 events = port->event_ops->get_events(port);295 296 events &= port->events_bitmap;297 for_each_set_bit(bit, &events, port->num_events)298 generic_handle_domain_irq(port->event_domain, bit);299 300 chained_irq_exit(chip, desc);301}302 303static u32 plda_hwirq_to_mask(int hwirq)304{305 u32 mask;306 307 /* hwirq 23 - 0 are the same with register */308 if (hwirq < EVENT_PM_MSI_INT_INTX)309 mask = BIT(hwirq);310 else if (hwirq == EVENT_PM_MSI_INT_INTX)311 mask = PM_MSI_INT_INTX_MASK;312 else313 mask = BIT(hwirq + PCI_NUM_INTX - 1);314 315 return mask;316}317 318static void plda_ack_event_irq(struct irq_data *data)319{320 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);321 322 writel_relaxed(plda_hwirq_to_mask(data->hwirq),323 port->bridge_addr + ISTATUS_LOCAL);324}325 326static void plda_mask_event_irq(struct irq_data *data)327{328 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);329 u32 mask, val;330 331 mask = plda_hwirq_to_mask(data->hwirq);332 333 raw_spin_lock(&port->lock);334 val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);335 val &= ~mask;336 writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);337 raw_spin_unlock(&port->lock);338}339 340static void plda_unmask_event_irq(struct irq_data *data)341{342 struct plda_pcie_rp *port = irq_data_get_irq_chip_data(data);343 u32 mask, val;344 345 mask = plda_hwirq_to_mask(data->hwirq);346 347 raw_spin_lock(&port->lock);348 val = readl_relaxed(port->bridge_addr + IMASK_LOCAL);349 val |= mask;350 writel_relaxed(val, port->bridge_addr + IMASK_LOCAL);351 raw_spin_unlock(&port->lock);352}353 354static struct irq_chip plda_event_irq_chip = {355 .name = "PLDA PCIe EVENT",356 .irq_ack = plda_ack_event_irq,357 .irq_mask = plda_mask_event_irq,358 .irq_unmask = plda_unmask_event_irq,359};360 361static const struct plda_event_ops plda_event_ops = {362 .get_events = plda_get_events,363};364 365static int plda_pcie_event_map(struct irq_domain *domain, unsigned int irq,366 irq_hw_number_t hwirq)367{368 struct plda_pcie_rp *port = (void *)domain->host_data;369 370 irq_set_chip_and_handler(irq, port->event_irq_chip, handle_level_irq);371 irq_set_chip_data(irq, domain->host_data);372 373 return 0;374}375 376static const struct irq_domain_ops plda_event_domain_ops = {377 .map = plda_pcie_event_map,378};379 380static int plda_pcie_init_irq_domains(struct plda_pcie_rp *port)381{382 struct device *dev = port->dev;383 struct device_node *node = dev->of_node;384 struct device_node *pcie_intc_node;385 386 /* Setup INTx */387 pcie_intc_node = of_get_next_child(node, NULL);388 if (!pcie_intc_node) {389 dev_err(dev, "failed to find PCIe Intc node\n");390 return -EINVAL;391 }392 393 port->event_domain = irq_domain_add_linear(pcie_intc_node,394 port->num_events,395 &plda_event_domain_ops,396 port);397 if (!port->event_domain) {398 dev_err(dev, "failed to get event domain\n");399 of_node_put(pcie_intc_node);400 return -ENOMEM;401 }402 403 irq_domain_update_bus_token(port->event_domain, DOMAIN_BUS_NEXUS);404 405 port->intx_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,406 &intx_domain_ops, port);407 if (!port->intx_domain) {408 dev_err(dev, "failed to get an INTx IRQ domain\n");409 of_node_put(pcie_intc_node);410 return -ENOMEM;411 }412 413 irq_domain_update_bus_token(port->intx_domain, DOMAIN_BUS_WIRED);414 415 of_node_put(pcie_intc_node);416 raw_spin_lock_init(&port->lock);417 418 return plda_allocate_msi_domains(port);419}420 421int plda_init_interrupts(struct platform_device *pdev,422 struct plda_pcie_rp *port,423 const struct plda_event *event)424{425 struct device *dev = &pdev->dev;426 int event_irq, ret;427 u32 i;428 429 if (!port->event_ops)430 port->event_ops = &plda_event_ops;431 432 if (!port->event_irq_chip)433 port->event_irq_chip = &plda_event_irq_chip;434 435 ret = plda_pcie_init_irq_domains(port);436 if (ret) {437 dev_err(dev, "failed creating IRQ domains\n");438 return ret;439 }440 441 port->irq = platform_get_irq(pdev, 0);442 if (port->irq < 0)443 return -ENODEV;444 445 for_each_set_bit(i, &port->events_bitmap, port->num_events) {446 event_irq = irq_create_mapping(port->event_domain, i);447 if (!event_irq) {448 dev_err(dev, "failed to map hwirq %d\n", i);449 return -ENXIO;450 }451 452 if (event->request_event_irq)453 ret = event->request_event_irq(port, event_irq, i);454 else455 ret = devm_request_irq(dev, event_irq,456 plda_event_handler,457 0, NULL, port);458 459 if (ret) {460 dev_err(dev, "failed to request IRQ %d\n", event_irq);461 return ret;462 }463 }464 465 port->intx_irq = irq_create_mapping(port->event_domain,466 event->intx_event);467 if (!port->intx_irq) {468 dev_err(dev, "failed to map INTx interrupt\n");469 return -ENXIO;470 }471 472 /* Plug the INTx chained handler */473 irq_set_chained_handler_and_data(port->intx_irq, plda_handle_intx, port);474 475 port->msi_irq = irq_create_mapping(port->event_domain,476 event->msi_event);477 if (!port->msi_irq)478 return -ENXIO;479 480 /* Plug the MSI chained handler */481 irq_set_chained_handler_and_data(port->msi_irq, plda_handle_msi, port);482 483 /* Plug the main event chained handler */484 irq_set_chained_handler_and_data(port->irq, plda_handle_event, port);485 486 return 0;487}488EXPORT_SYMBOL_GPL(plda_init_interrupts);489 490void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index,491 phys_addr_t axi_addr, phys_addr_t pci_addr,492 size_t size)493{494 u32 atr_sz = ilog2(size) - 1;495 u32 val;496 497 if (index == 0)498 val = PCIE_CONFIG_INTERFACE;499 else500 val = PCIE_TX_RX_INTERFACE;501 502 writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +503 ATR0_AXI4_SLV0_TRSL_PARAM);504 505 val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) |506 ATR_IMPL_ENABLE;507 writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +508 ATR0_AXI4_SLV0_SRCADDR_PARAM);509 510 val = upper_32_bits(axi_addr);511 writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +512 ATR0_AXI4_SLV0_SRC_ADDR);513 514 val = lower_32_bits(pci_addr);515 writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +516 ATR0_AXI4_SLV0_TRSL_ADDR_LSB);517 518 val = upper_32_bits(pci_addr);519 writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) +520 ATR0_AXI4_SLV0_TRSL_ADDR_UDW);521 522 val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);523 val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT);524 writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM);525 writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR);526}527EXPORT_SYMBOL_GPL(plda_pcie_setup_window);528 529int plda_pcie_setup_iomems(struct pci_host_bridge *bridge,530 struct plda_pcie_rp *port)531{532 void __iomem *bridge_base_addr = port->bridge_addr;533 struct resource_entry *entry;534 u64 pci_addr;535 u32 index = 1;536 537 resource_list_for_each_entry(entry, &bridge->windows) {538 if (resource_type(entry->res) == IORESOURCE_MEM) {539 pci_addr = entry->res->start - entry->offset;540 plda_pcie_setup_window(bridge_base_addr, index,541 entry->res->start, pci_addr,542 resource_size(entry->res));543 index++;544 }545 }546 547 return 0;548}549EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);550 551static void plda_pcie_irq_domain_deinit(struct plda_pcie_rp *pcie)552{553 irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);554 irq_set_chained_handler_and_data(pcie->msi_irq, NULL, NULL);555 irq_set_chained_handler_and_data(pcie->intx_irq, NULL, NULL);556 557 irq_domain_remove(pcie->msi.msi_domain);558 irq_domain_remove(pcie->msi.dev_domain);559 560 irq_domain_remove(pcie->intx_domain);561 irq_domain_remove(pcie->event_domain);562}563 564int plda_pcie_host_init(struct plda_pcie_rp *port, struct pci_ops *ops,565 const struct plda_event *plda_event)566{567 struct device *dev = port->dev;568 struct pci_host_bridge *bridge;569 struct platform_device *pdev = to_platform_device(dev);570 struct resource *cfg_res;571 int ret;572 573 pdev = to_platform_device(dev);574 575 port->bridge_addr =576 devm_platform_ioremap_resource_byname(pdev, "apb");577 578 if (IS_ERR(port->bridge_addr))579 return dev_err_probe(dev, PTR_ERR(port->bridge_addr),580 "failed to map reg memory\n");581 582 cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");583 if (!cfg_res)584 return dev_err_probe(dev, -ENODEV,585 "failed to get config memory\n");586 587 port->config_base = devm_ioremap_resource(dev, cfg_res);588 if (IS_ERR(port->config_base))589 return dev_err_probe(dev, PTR_ERR(port->config_base),590 "failed to map config memory\n");591 592 bridge = devm_pci_alloc_host_bridge(dev, 0);593 if (!bridge)594 return dev_err_probe(dev, -ENOMEM,595 "failed to alloc bridge\n");596 597 if (port->host_ops && port->host_ops->host_init) {598 ret = port->host_ops->host_init(port);599 if (ret)600 return ret;601 }602 603 port->bridge = bridge;604 plda_pcie_setup_window(port->bridge_addr, 0, cfg_res->start, 0,605 resource_size(cfg_res));606 plda_pcie_setup_iomems(bridge, port);607 plda_set_default_msi(&port->msi);608 ret = plda_init_interrupts(pdev, port, plda_event);609 if (ret)610 goto err_host;611 612 /* Set default bus ops */613 bridge->ops = ops;614 bridge->sysdata = port;615 616 ret = pci_host_probe(bridge);617 if (ret < 0) {618 dev_err_probe(dev, ret, "failed to probe pci host\n");619 goto err_probe;620 }621 622 return ret;623 624err_probe:625 plda_pcie_irq_domain_deinit(port);626err_host:627 if (port->host_ops && port->host_ops->host_deinit)628 port->host_ops->host_deinit(port);629 630 return ret;631}632EXPORT_SYMBOL_GPL(plda_pcie_host_init);633 634void plda_pcie_host_deinit(struct plda_pcie_rp *port)635{636 pci_stop_root_bus(port->bridge->bus);637 pci_remove_root_bus(port->bridge->bus);638 639 plda_pcie_irq_domain_deinit(port);640 641 if (port->host_ops && port->host_ops->host_deinit)642 port->host_ops->host_deinit(port);643}644EXPORT_SYMBOL_GPL(plda_pcie_host_deinit);645