Lines Matching +full:pcie +full:- +full:phy

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for the Aardvark PCIe controller, used on Marvell Armada
20 #include <linux/phy/phy.h>
28 #include "../pci-bridge-emul.h"
30 /* PCIe core registers */
128 /* PCIe core controller registers */
136 /* PCIe Central Interrupts Registers */
202 struct phy *phy; member
205 static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) in advk_writel() argument
207 writel(val, pcie->base + reg); in advk_writel()
210 static inline u32 advk_readl(struct advk_pcie *pcie, u64 reg) in advk_readl() argument
212 return readl(pcie->base + reg); in advk_readl()
215 static inline u16 advk_read16(struct advk_pcie *pcie, u64 reg) in advk_read16() argument
217 return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); in advk_read16()
220 static int advk_pcie_link_up(struct advk_pcie *pcie) in advk_pcie_link_up() argument
224 val = advk_readl(pcie, CFG_REG); in advk_pcie_link_up()
229 static int advk_pcie_wait_for_link(struct advk_pcie *pcie) in advk_pcie_wait_for_link() argument
235 if (advk_pcie_link_up(pcie)) in advk_pcie_wait_for_link()
241 return -ETIMEDOUT; in advk_pcie_wait_for_link()
244 static void advk_pcie_wait_for_retrain(struct advk_pcie *pcie) in advk_pcie_wait_for_retrain() argument
249 if (!advk_pcie_link_up(pcie)) in advk_pcie_wait_for_retrain()
255 static void advk_pcie_issue_perst(struct advk_pcie *pcie) in advk_pcie_issue_perst() argument
259 if (!pcie->reset_gpio) in advk_pcie_issue_perst()
263 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_issue_perst()
265 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_issue_perst()
268 dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); in advk_pcie_issue_perst()
269 gpiod_set_value_cansleep(pcie->reset_gpio, 1); in advk_pcie_issue_perst()
271 gpiod_set_value_cansleep(pcie->reset_gpio, 0); in advk_pcie_issue_perst()
274 static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) in advk_pcie_train_at_gen() argument
280 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_train_at_gen()
288 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_train_at_gen()
294 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_train_at_gen()
296 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_train_at_gen()
302 reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); in advk_pcie_train_at_gen()
304 advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); in advk_pcie_train_at_gen()
306 ret = advk_pcie_wait_for_link(pcie); in advk_pcie_train_at_gen()
310 reg = advk_read16(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKSTA); in advk_pcie_train_at_gen()
316 static void advk_pcie_train_link(struct advk_pcie *pcie) in advk_pcie_train_link() argument
318 struct device *dev = &pcie->pdev->dev; in advk_pcie_train_link()
319 int neg_gen = -1, gen; in advk_pcie_train_link()
322 * Reset PCIe card via PERST# signal. Some cards are not detected in advk_pcie_train_link()
323 * during link training when they are in some non-initial state. in advk_pcie_train_link()
325 advk_pcie_issue_perst(pcie); in advk_pcie_train_link()
338 * 'max-link-speed'. If this fails, iteratively train at lower gen. in advk_pcie_train_link()
340 for (gen = pcie->link_gen; gen > 0; --gen) { in advk_pcie_train_link()
341 neg_gen = advk_pcie_train_at_gen(pcie, gen); in advk_pcie_train_link()
356 neg_gen = advk_pcie_train_at_gen(pcie, gen); in advk_pcie_train_link()
368 static void advk_pcie_setup_hw(struct advk_pcie *pcie) in advk_pcie_setup_hw() argument
373 reg = advk_readl(pcie, PCIE_CORE_REF_CLK_REG); in advk_pcie_setup_hw()
375 advk_writel(pcie, reg, PCIE_CORE_REF_CLK_REG); in advk_pcie_setup_hw()
378 reg = advk_readl(pcie, CTRL_CONFIG_REG); in advk_pcie_setup_hw()
381 advk_writel(pcie, reg, CTRL_CONFIG_REG); in advk_pcie_setup_hw()
384 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
386 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
393 advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); in advk_pcie_setup_hw()
395 /* Set PCIe Device Control register */ in advk_pcie_setup_hw()
396 reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); in advk_pcie_setup_hw()
402 advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); in advk_pcie_setup_hw()
404 /* Program PCIe Control 2 to disable strict ordering */ in advk_pcie_setup_hw()
407 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
410 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
413 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
416 reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
418 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
421 advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); in advk_pcie_setup_hw()
422 advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); in advk_pcie_setup_hw()
423 advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); in advk_pcie_setup_hw()
428 advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); in advk_pcie_setup_hw()
430 advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); in advk_pcie_setup_hw()
433 advk_writel(pcie, 0, PCIE_MSI_MASK_REG); in advk_pcie_setup_hw()
437 advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); in advk_pcie_setup_hw()
439 reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
441 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
444 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_setup_hw()
446 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_setup_hw()
448 advk_pcie_train_link(pcie); in advk_pcie_setup_hw()
457 reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); in advk_pcie_setup_hw()
461 advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); in advk_pcie_setup_hw()
464 static void advk_pcie_check_pio_status(struct advk_pcie *pcie) in advk_pcie_check_pio_status() argument
466 struct device *dev = &pcie->pdev->dev; in advk_pcie_check_pio_status()
471 reg = advk_readl(pcie, PIO_STAT); in advk_pcie_check_pio_status()
494 str_posted = "Non-posted"; in advk_pcie_check_pio_status()
499 str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); in advk_pcie_check_pio_status()
502 static int advk_pcie_wait_pio(struct advk_pcie *pcie) in advk_pcie_wait_pio() argument
504 struct device *dev = &pcie->pdev->dev; in advk_pcie_wait_pio()
510 start = advk_readl(pcie, PIO_START); in advk_pcie_wait_pio()
511 isr = advk_readl(pcie, PIO_ISR); in advk_pcie_wait_pio()
518 return -ETIMEDOUT; in advk_pcie_wait_pio()
526 struct advk_pcie *pcie = bridge->data; in advk_pci_bridge_emul_pcie_conf_read() local
535 u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG); in advk_pci_bridge_emul_pcie_conf_read()
541 u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG); in advk_pci_bridge_emul_pcie_conf_read()
542 u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG); in advk_pci_bridge_emul_pcie_conf_read()
549 u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) & in advk_pci_bridge_emul_pcie_conf_read()
551 if (!advk_pcie_link_up(pcie)) in advk_pci_bridge_emul_pcie_conf_read()
561 *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); in advk_pci_bridge_emul_pcie_conf_read()
573 struct advk_pcie *pcie = bridge->data; in advk_pci_bridge_emul_pcie_conf_write() local
577 advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg); in advk_pci_bridge_emul_pcie_conf_write()
581 advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg); in advk_pci_bridge_emul_pcie_conf_write()
583 advk_pcie_wait_for_retrain(pcie); in advk_pci_bridge_emul_pcie_conf_write()
588 u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) & in advk_pci_bridge_emul_pcie_conf_write()
592 advk_writel(pcie, val, PCIE_ISR0_MASK_REG); in advk_pci_bridge_emul_pcie_conf_write()
598 advk_writel(pcie, new, PCIE_ISR0_REG); in advk_pci_bridge_emul_pcie_conf_write()
612 * Initialize the configuration space of the PCI-to-PCI bridge
613 * associated with the given PCIe interface.
615 static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) in advk_sw_pci_bridge_init() argument
617 struct pci_bridge_emul *bridge = &pcie->bridge; in advk_sw_pci_bridge_init()
619 bridge->conf.vendor = in advk_sw_pci_bridge_init()
620 cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); in advk_sw_pci_bridge_init()
621 bridge->conf.device = in advk_sw_pci_bridge_init()
622 cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16); in advk_sw_pci_bridge_init()
623 bridge->conf.class_revision = in advk_sw_pci_bridge_init()
624 cpu_to_le32(advk_readl(pcie, PCIE_CORE_DEV_REV_REG) & 0xff); in advk_sw_pci_bridge_init()
627 bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; in advk_sw_pci_bridge_init()
628 bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; in advk_sw_pci_bridge_init()
631 bridge->conf.pref_mem_base = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); in advk_sw_pci_bridge_init()
632 bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); in advk_sw_pci_bridge_init()
635 bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; in advk_sw_pci_bridge_init()
637 bridge->has_pcie = true; in advk_sw_pci_bridge_init()
638 bridge->data = pcie; in advk_sw_pci_bridge_init()
639 bridge->ops = &advk_pci_bridge_emul_ops; in advk_sw_pci_bridge_init()
644 static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, in advk_pcie_valid_device() argument
651 * If the link goes down after we check for link-up, nothing bad in advk_pcie_valid_device()
654 if (!pci_is_root_bus(bus) && !advk_pcie_link_up(pcie)) in advk_pcie_valid_device()
663 struct advk_pcie *pcie = bus->sysdata; in advk_pcie_rd_conf() local
667 if (!advk_pcie_valid_device(pcie, bus, devfn)) { in advk_pcie_rd_conf()
673 return pci_bridge_emul_conf_read(&pcie->bridge, where, in advk_pcie_rd_conf()
677 advk_writel(pcie, 0, PIO_START); in advk_pcie_rd_conf()
678 advk_writel(pcie, 1, PIO_ISR); in advk_pcie_rd_conf()
681 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_rd_conf()
683 if (pci_is_root_bus(bus->parent)) in advk_pcie_rd_conf()
687 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_rd_conf()
690 reg = PCIE_CONF_ADDR(bus->number, devfn, where); in advk_pcie_rd_conf()
691 advk_writel(pcie, reg, PIO_ADDR_LS); in advk_pcie_rd_conf()
692 advk_writel(pcie, 0, PIO_ADDR_MS); in advk_pcie_rd_conf()
695 advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); in advk_pcie_rd_conf()
698 advk_writel(pcie, 1, PIO_START); in advk_pcie_rd_conf()
700 ret = advk_pcie_wait_pio(pcie); in advk_pcie_rd_conf()
706 advk_pcie_check_pio_status(pcie); in advk_pcie_rd_conf()
709 *val = advk_readl(pcie, PIO_RD_DATA); in advk_pcie_rd_conf()
721 struct advk_pcie *pcie = bus->sysdata; in advk_pcie_wr_conf() local
727 if (!advk_pcie_valid_device(pcie, bus, devfn)) in advk_pcie_wr_conf()
731 return pci_bridge_emul_conf_write(&pcie->bridge, where, in advk_pcie_wr_conf()
738 advk_writel(pcie, 0, PIO_START); in advk_pcie_wr_conf()
739 advk_writel(pcie, 1, PIO_ISR); in advk_pcie_wr_conf()
742 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_wr_conf()
744 if (pci_is_root_bus(bus->parent)) in advk_pcie_wr_conf()
748 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_wr_conf()
751 reg = PCIE_CONF_ADDR(bus->number, devfn, where); in advk_pcie_wr_conf()
752 advk_writel(pcie, reg, PIO_ADDR_LS); in advk_pcie_wr_conf()
753 advk_writel(pcie, 0, PIO_ADDR_MS); in advk_pcie_wr_conf()
758 data_strobe = GENMASK(size - 1, 0) << offset; in advk_pcie_wr_conf()
761 advk_writel(pcie, reg, PIO_WR_DATA); in advk_pcie_wr_conf()
764 advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); in advk_pcie_wr_conf()
767 advk_writel(pcie, 1, PIO_START); in advk_pcie_wr_conf()
769 ret = advk_pcie_wait_pio(pcie); in advk_pcie_wr_conf()
773 advk_pcie_check_pio_status(pcie); in advk_pcie_wr_conf()
786 struct advk_pcie *pcie = irq_data_get_irq_chip_data(data); in advk_msi_irq_compose_msi_msg() local
787 phys_addr_t msi_msg = virt_to_phys(&pcie->msi_msg); in advk_msi_irq_compose_msi_msg()
789 msg->address_lo = lower_32_bits(msi_msg); in advk_msi_irq_compose_msi_msg()
790 msg->address_hi = upper_32_bits(msi_msg); in advk_msi_irq_compose_msi_msg()
791 msg->data = data->irq; in advk_msi_irq_compose_msi_msg()
797 return -EINVAL; in advk_msi_set_affinity()
804 struct advk_pcie *pcie = domain->host_data; in advk_msi_irq_domain_alloc() local
807 mutex_lock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
808 hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM, in advk_msi_irq_domain_alloc()
811 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
812 return -ENOSPC; in advk_msi_irq_domain_alloc()
815 bitmap_set(pcie->msi_used, hwirq, nr_irqs); in advk_msi_irq_domain_alloc()
816 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
820 &pcie->msi_bottom_irq_chip, in advk_msi_irq_domain_alloc()
821 domain->host_data, handle_simple_irq, in advk_msi_irq_domain_alloc()
831 struct advk_pcie *pcie = domain->host_data; in advk_msi_irq_domain_free() local
833 mutex_lock(&pcie->msi_used_lock); in advk_msi_irq_domain_free()
834 bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs); in advk_msi_irq_domain_free()
835 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_free()
845 struct advk_pcie *pcie = d->domain->host_data; in advk_pcie_irq_mask() local
849 mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_irq_mask()
851 advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); in advk_pcie_irq_mask()
856 struct advk_pcie *pcie = d->domain->host_data; in advk_pcie_irq_unmask() local
860 mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_irq_unmask()
862 advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); in advk_pcie_irq_unmask()
868 struct advk_pcie *pcie = h->host_data; in advk_pcie_irq_map() local
872 irq_set_chip_and_handler(virq, &pcie->irq_chip, in advk_pcie_irq_map()
874 irq_set_chip_data(virq, pcie); in advk_pcie_irq_map()
884 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) in advk_pcie_init_msi_irq_domain() argument
886 struct device *dev = &pcie->pdev->dev; in advk_pcie_init_msi_irq_domain()
887 struct device_node *node = dev->of_node; in advk_pcie_init_msi_irq_domain()
892 mutex_init(&pcie->msi_used_lock); in advk_pcie_init_msi_irq_domain()
894 bottom_ic = &pcie->msi_bottom_irq_chip; in advk_pcie_init_msi_irq_domain()
896 bottom_ic->name = "MSI"; in advk_pcie_init_msi_irq_domain()
897 bottom_ic->irq_compose_msi_msg = advk_msi_irq_compose_msi_msg; in advk_pcie_init_msi_irq_domain()
898 bottom_ic->irq_set_affinity = advk_msi_set_affinity; in advk_pcie_init_msi_irq_domain()
900 msi_ic = &pcie->msi_irq_chip; in advk_pcie_init_msi_irq_domain()
901 msi_ic->name = "advk-MSI"; in advk_pcie_init_msi_irq_domain()
903 msi_di = &pcie->msi_domain_info; in advk_pcie_init_msi_irq_domain()
904 msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | in advk_pcie_init_msi_irq_domain()
906 msi_di->chip = msi_ic; in advk_pcie_init_msi_irq_domain()
908 msi_msg_phys = virt_to_phys(&pcie->msi_msg); in advk_pcie_init_msi_irq_domain()
910 advk_writel(pcie, lower_32_bits(msi_msg_phys), in advk_pcie_init_msi_irq_domain()
912 advk_writel(pcie, upper_32_bits(msi_msg_phys), in advk_pcie_init_msi_irq_domain()
915 pcie->msi_inner_domain = in advk_pcie_init_msi_irq_domain()
917 &advk_msi_domain_ops, pcie); in advk_pcie_init_msi_irq_domain()
918 if (!pcie->msi_inner_domain) in advk_pcie_init_msi_irq_domain()
919 return -ENOMEM; in advk_pcie_init_msi_irq_domain()
921 pcie->msi_domain = in advk_pcie_init_msi_irq_domain()
923 msi_di, pcie->msi_inner_domain); in advk_pcie_init_msi_irq_domain()
924 if (!pcie->msi_domain) { in advk_pcie_init_msi_irq_domain()
925 irq_domain_remove(pcie->msi_inner_domain); in advk_pcie_init_msi_irq_domain()
926 return -ENOMEM; in advk_pcie_init_msi_irq_domain()
932 static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie) in advk_pcie_remove_msi_irq_domain() argument
934 irq_domain_remove(pcie->msi_domain); in advk_pcie_remove_msi_irq_domain()
935 irq_domain_remove(pcie->msi_inner_domain); in advk_pcie_remove_msi_irq_domain()
938 static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) in advk_pcie_init_irq_domain() argument
940 struct device *dev = &pcie->pdev->dev; in advk_pcie_init_irq_domain()
941 struct device_node *node = dev->of_node; in advk_pcie_init_irq_domain()
948 dev_err(dev, "No PCIe Intc node found\n"); in advk_pcie_init_irq_domain()
949 return -ENODEV; in advk_pcie_init_irq_domain()
952 irq_chip = &pcie->irq_chip; in advk_pcie_init_irq_domain()
954 irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq", in advk_pcie_init_irq_domain()
956 if (!irq_chip->name) { in advk_pcie_init_irq_domain()
957 ret = -ENOMEM; in advk_pcie_init_irq_domain()
961 irq_chip->irq_mask = advk_pcie_irq_mask; in advk_pcie_init_irq_domain()
962 irq_chip->irq_mask_ack = advk_pcie_irq_mask; in advk_pcie_init_irq_domain()
963 irq_chip->irq_unmask = advk_pcie_irq_unmask; in advk_pcie_init_irq_domain()
965 pcie->irq_domain = in advk_pcie_init_irq_domain()
967 &advk_pcie_irq_domain_ops, pcie); in advk_pcie_init_irq_domain()
968 if (!pcie->irq_domain) { in advk_pcie_init_irq_domain()
970 ret = -ENOMEM; in advk_pcie_init_irq_domain()
979 static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) in advk_pcie_remove_irq_domain() argument
981 irq_domain_remove(pcie->irq_domain); in advk_pcie_remove_irq_domain()
984 static void advk_pcie_handle_msi(struct advk_pcie *pcie) in advk_pcie_handle_msi() argument
989 msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG); in advk_pcie_handle_msi()
990 msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG); in advk_pcie_handle_msi()
997 advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); in advk_pcie_handle_msi()
998 msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; in advk_pcie_handle_msi()
1002 advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, in advk_pcie_handle_msi()
1006 static void advk_pcie_handle_int(struct advk_pcie *pcie) in advk_pcie_handle_int() argument
1012 isr0_val = advk_readl(pcie, PCIE_ISR0_REG); in advk_pcie_handle_int()
1013 isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); in advk_pcie_handle_int()
1016 isr1_val = advk_readl(pcie, PCIE_ISR1_REG); in advk_pcie_handle_int()
1017 isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_handle_int()
1021 advk_writel(pcie, isr0_val, PCIE_ISR0_REG); in advk_pcie_handle_int()
1022 advk_writel(pcie, isr1_val, PCIE_ISR1_REG); in advk_pcie_handle_int()
1028 advk_pcie_handle_msi(pcie); in advk_pcie_handle_int()
1035 advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), in advk_pcie_handle_int()
1038 virq = irq_find_mapping(pcie->irq_domain, i); in advk_pcie_handle_int()
1045 struct advk_pcie *pcie = arg; in advk_pcie_irq_handler() local
1048 status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); in advk_pcie_irq_handler()
1052 advk_pcie_handle_int(pcie); in advk_pcie_irq_handler()
1055 advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); in advk_pcie_irq_handler()
1060 static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie) in advk_pcie_disable_phy() argument
1062 phy_power_off(pcie->phy); in advk_pcie_disable_phy()
1063 phy_exit(pcie->phy); in advk_pcie_disable_phy()
1066 static int advk_pcie_enable_phy(struct advk_pcie *pcie) in advk_pcie_enable_phy() argument
1070 if (!pcie->phy) in advk_pcie_enable_phy()
1073 ret = phy_init(pcie->phy); in advk_pcie_enable_phy()
1077 ret = phy_set_mode(pcie->phy, PHY_MODE_PCIE); in advk_pcie_enable_phy()
1079 phy_exit(pcie->phy); in advk_pcie_enable_phy()
1083 ret = phy_power_on(pcie->phy); in advk_pcie_enable_phy()
1084 if (ret == -EOPNOTSUPP) { in advk_pcie_enable_phy()
1085 dev_warn(&pcie->pdev->dev, "PHY unsupported by firmware\n"); in advk_pcie_enable_phy()
1087 phy_exit(pcie->phy); in advk_pcie_enable_phy()
1094 static int advk_pcie_setup_phy(struct advk_pcie *pcie) in advk_pcie_setup_phy() argument
1096 struct device *dev = &pcie->pdev->dev; in advk_pcie_setup_phy()
1097 struct device_node *node = dev->of_node; in advk_pcie_setup_phy()
1100 pcie->phy = devm_of_phy_get(dev, node, NULL); in advk_pcie_setup_phy()
1101 if (IS_ERR(pcie->phy) && (PTR_ERR(pcie->phy) == -EPROBE_DEFER)) in advk_pcie_setup_phy()
1102 return PTR_ERR(pcie->phy); in advk_pcie_setup_phy()
1104 /* Old bindings miss the PHY handle */ in advk_pcie_setup_phy()
1105 if (IS_ERR(pcie->phy)) { in advk_pcie_setup_phy()
1106 dev_warn(dev, "PHY unavailable (%ld)\n", PTR_ERR(pcie->phy)); in advk_pcie_setup_phy()
1107 pcie->phy = NULL; in advk_pcie_setup_phy()
1111 ret = advk_pcie_enable_phy(pcie); in advk_pcie_setup_phy()
1113 dev_err(dev, "Failed to initialize PHY (%d)\n", ret); in advk_pcie_setup_phy()
1120 struct device *dev = &pdev->dev; in advk_pcie_probe()
1121 struct advk_pcie *pcie; in advk_pcie_probe() local
1127 return -ENOMEM; in advk_pcie_probe()
1129 pcie = pci_host_bridge_priv(bridge); in advk_pcie_probe()
1130 pcie->pdev = pdev; in advk_pcie_probe()
1131 platform_set_drvdata(pdev, pcie); in advk_pcie_probe()
1133 pcie->base = devm_platform_ioremap_resource(pdev, 0); in advk_pcie_probe()
1134 if (IS_ERR(pcie->base)) in advk_pcie_probe()
1135 return PTR_ERR(pcie->base); in advk_pcie_probe()
1142 IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie", in advk_pcie_probe()
1143 pcie); in advk_pcie_probe()
1149 pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, in advk_pcie_probe()
1150 "reset-gpios", 0, in advk_pcie_probe()
1152 "pcie1-reset"); in advk_pcie_probe()
1153 ret = PTR_ERR_OR_ZERO(pcie->reset_gpio); in advk_pcie_probe()
1155 if (ret == -ENOENT) { in advk_pcie_probe()
1156 pcie->reset_gpio = NULL; in advk_pcie_probe()
1158 if (ret != -EPROBE_DEFER) in advk_pcie_probe()
1159 dev_err(dev, "Failed to get reset-gpio: %i\n", in advk_pcie_probe()
1165 ret = of_pci_get_max_link_speed(dev->of_node); in advk_pcie_probe()
1167 pcie->link_gen = 3; in advk_pcie_probe()
1169 pcie->link_gen = ret; in advk_pcie_probe()
1171 ret = advk_pcie_setup_phy(pcie); in advk_pcie_probe()
1175 advk_pcie_setup_hw(pcie); in advk_pcie_probe()
1177 ret = advk_sw_pci_bridge_init(pcie); in advk_pcie_probe()
1183 ret = advk_pcie_init_irq_domain(pcie); in advk_pcie_probe()
1189 ret = advk_pcie_init_msi_irq_domain(pcie); in advk_pcie_probe()
1192 advk_pcie_remove_irq_domain(pcie); in advk_pcie_probe()
1196 bridge->sysdata = pcie; in advk_pcie_probe()
1197 bridge->ops = &advk_pcie_ops; in advk_pcie_probe()
1201 advk_pcie_remove_msi_irq_domain(pcie); in advk_pcie_probe()
1202 advk_pcie_remove_irq_domain(pcie); in advk_pcie_probe()
1211 struct advk_pcie *pcie = platform_get_drvdata(pdev); in advk_pcie_remove() local
1212 struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); in advk_pcie_remove()
1215 pci_stop_root_bus(bridge->bus); in advk_pcie_remove()
1216 pci_remove_root_bus(bridge->bus); in advk_pcie_remove()
1219 advk_pcie_remove_msi_irq_domain(pcie); in advk_pcie_remove()
1220 advk_pcie_remove_irq_domain(pcie); in advk_pcie_remove()
1226 { .compatible = "marvell,armada-3700-pcie", },
1233 .name = "advk-pcie",
1241 MODULE_DESCRIPTION("Aardvark PCIe controller");