Lines Matching full:pcie
3 * Driver for the Aardvark PCIe controller, used on Marvell Armada
24 /* PCIe core registers */
122 /* PCIe core controller registers */
130 /* PCIe Central Interrupts Registers */
194 static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) in advk_writel() argument
196 writel(val, pcie->base + reg); in advk_writel()
199 static inline u32 advk_readl(struct advk_pcie *pcie, u64 reg) in advk_readl() argument
201 return readl(pcie->base + reg); in advk_readl()
204 static int advk_pcie_link_up(struct advk_pcie *pcie) in advk_pcie_link_up() argument
208 val = advk_readl(pcie, CFG_REG); in advk_pcie_link_up()
213 static int advk_pcie_wait_for_link(struct advk_pcie *pcie) in advk_pcie_wait_for_link() argument
215 struct device *dev = &pcie->pdev->dev; in advk_pcie_wait_for_link()
220 if (advk_pcie_link_up(pcie)) { in advk_pcie_wait_for_link()
232 static void advk_pcie_setup_hw(struct advk_pcie *pcie) in advk_pcie_setup_hw() argument
237 reg = advk_readl(pcie, CTRL_CONFIG_REG); in advk_pcie_setup_hw()
240 advk_writel(pcie, reg, CTRL_CONFIG_REG); in advk_pcie_setup_hw()
243 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
245 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
252 advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); in advk_pcie_setup_hw()
254 /* Set PCIe Device Control and Status 1 PF0 register */ in advk_pcie_setup_hw()
260 advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); in advk_pcie_setup_hw()
262 /* Program PCIe Control 2 to disable strict ordering */ in advk_pcie_setup_hw()
265 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
268 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
271 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
274 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
277 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
280 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
282 advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); in advk_pcie_setup_hw()
285 reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
287 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
290 advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); in advk_pcie_setup_hw()
291 advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); in advk_pcie_setup_hw()
292 advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); in advk_pcie_setup_hw()
297 advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); in advk_pcie_setup_hw()
299 advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); in advk_pcie_setup_hw()
302 advk_writel(pcie, 0, PCIE_MSI_MASK_REG); in advk_pcie_setup_hw()
306 advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); in advk_pcie_setup_hw()
308 reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
310 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); in advk_pcie_setup_hw()
313 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_setup_hw()
315 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_setup_hw()
318 reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); in advk_pcie_setup_hw()
320 advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); in advk_pcie_setup_hw()
322 advk_pcie_wait_for_link(pcie); in advk_pcie_setup_hw()
324 reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); in advk_pcie_setup_hw()
328 advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); in advk_pcie_setup_hw()
331 static void advk_pcie_check_pio_status(struct advk_pcie *pcie) in advk_pcie_check_pio_status() argument
333 struct device *dev = &pcie->pdev->dev; in advk_pcie_check_pio_status()
338 reg = advk_readl(pcie, PIO_STAT); in advk_pcie_check_pio_status()
366 str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); in advk_pcie_check_pio_status()
369 static int advk_pcie_wait_pio(struct advk_pcie *pcie) in advk_pcie_wait_pio() argument
371 struct device *dev = &pcie->pdev->dev; in advk_pcie_wait_pio()
379 start = advk_readl(pcie, PIO_START); in advk_pcie_wait_pio()
380 isr = advk_readl(pcie, PIO_ISR); in advk_pcie_wait_pio()
389 static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, in advk_pcie_valid_device() argument
392 if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) in advk_pcie_valid_device()
401 struct advk_pcie *pcie = bus->sysdata; in advk_pcie_rd_conf() local
405 if (!advk_pcie_valid_device(pcie, bus, devfn)) { in advk_pcie_rd_conf()
411 advk_writel(pcie, 0, PIO_START); in advk_pcie_rd_conf()
412 advk_writel(pcie, 1, PIO_ISR); in advk_pcie_rd_conf()
415 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_rd_conf()
417 if (bus->number == pcie->root_bus_nr) in advk_pcie_rd_conf()
421 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_rd_conf()
425 advk_writel(pcie, reg, PIO_ADDR_LS); in advk_pcie_rd_conf()
426 advk_writel(pcie, 0, PIO_ADDR_MS); in advk_pcie_rd_conf()
429 advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); in advk_pcie_rd_conf()
432 advk_writel(pcie, 1, PIO_START); in advk_pcie_rd_conf()
434 ret = advk_pcie_wait_pio(pcie); in advk_pcie_rd_conf()
438 advk_pcie_check_pio_status(pcie); in advk_pcie_rd_conf()
441 *val = advk_readl(pcie, PIO_RD_DATA); in advk_pcie_rd_conf()
453 struct advk_pcie *pcie = bus->sysdata; in advk_pcie_wr_conf() local
459 if (!advk_pcie_valid_device(pcie, bus, devfn)) in advk_pcie_wr_conf()
466 advk_writel(pcie, 0, PIO_START); in advk_pcie_wr_conf()
467 advk_writel(pcie, 1, PIO_ISR); in advk_pcie_wr_conf()
470 reg = advk_readl(pcie, PIO_CTRL); in advk_pcie_wr_conf()
472 if (bus->number == pcie->root_bus_nr) in advk_pcie_wr_conf()
476 advk_writel(pcie, reg, PIO_CTRL); in advk_pcie_wr_conf()
480 advk_writel(pcie, reg, PIO_ADDR_LS); in advk_pcie_wr_conf()
481 advk_writel(pcie, 0, PIO_ADDR_MS); in advk_pcie_wr_conf()
489 advk_writel(pcie, reg, PIO_WR_DATA); in advk_pcie_wr_conf()
492 advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); in advk_pcie_wr_conf()
495 advk_writel(pcie, 1, PIO_START); in advk_pcie_wr_conf()
497 ret = advk_pcie_wait_pio(pcie); in advk_pcie_wr_conf()
501 advk_pcie_check_pio_status(pcie); in advk_pcie_wr_conf()
514 struct advk_pcie *pcie = irq_data_get_irq_chip_data(data); in advk_msi_irq_compose_msi_msg() local
515 phys_addr_t msi_msg = virt_to_phys(&pcie->msi_msg); in advk_msi_irq_compose_msi_msg()
532 struct advk_pcie *pcie = domain->host_data; in advk_msi_irq_domain_alloc() local
535 mutex_lock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
536 hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM, in advk_msi_irq_domain_alloc()
539 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
543 bitmap_set(pcie->msi_used, hwirq, nr_irqs); in advk_msi_irq_domain_alloc()
544 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_alloc()
548 &pcie->msi_bottom_irq_chip, in advk_msi_irq_domain_alloc()
559 struct advk_pcie *pcie = domain->host_data; in advk_msi_irq_domain_free() local
561 mutex_lock(&pcie->msi_used_lock); in advk_msi_irq_domain_free()
562 bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs); in advk_msi_irq_domain_free()
563 mutex_unlock(&pcie->msi_used_lock); in advk_msi_irq_domain_free()
573 struct advk_pcie *pcie = d->domain->host_data; in advk_pcie_irq_mask() local
577 mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_irq_mask()
579 advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); in advk_pcie_irq_mask()
584 struct advk_pcie *pcie = d->domain->host_data; in advk_pcie_irq_unmask() local
588 mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_irq_unmask()
590 advk_writel(pcie, mask, PCIE_ISR1_MASK_REG); in advk_pcie_irq_unmask()
596 struct advk_pcie *pcie = h->host_data; in advk_pcie_irq_map() local
600 irq_set_chip_and_handler(virq, &pcie->irq_chip, in advk_pcie_irq_map()
602 irq_set_chip_data(virq, pcie); in advk_pcie_irq_map()
612 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie) in advk_pcie_init_msi_irq_domain() argument
614 struct device *dev = &pcie->pdev->dev; in advk_pcie_init_msi_irq_domain()
620 mutex_init(&pcie->msi_used_lock); in advk_pcie_init_msi_irq_domain()
622 bottom_ic = &pcie->msi_bottom_irq_chip; in advk_pcie_init_msi_irq_domain()
628 msi_ic = &pcie->msi_irq_chip; in advk_pcie_init_msi_irq_domain()
631 msi_di = &pcie->msi_domain_info; in advk_pcie_init_msi_irq_domain()
636 msi_msg_phys = virt_to_phys(&pcie->msi_msg); in advk_pcie_init_msi_irq_domain()
638 advk_writel(pcie, lower_32_bits(msi_msg_phys), in advk_pcie_init_msi_irq_domain()
640 advk_writel(pcie, upper_32_bits(msi_msg_phys), in advk_pcie_init_msi_irq_domain()
643 pcie->msi_inner_domain = in advk_pcie_init_msi_irq_domain()
645 &advk_msi_domain_ops, pcie); in advk_pcie_init_msi_irq_domain()
646 if (!pcie->msi_inner_domain) in advk_pcie_init_msi_irq_domain()
649 pcie->msi_domain = in advk_pcie_init_msi_irq_domain()
651 msi_di, pcie->msi_inner_domain); in advk_pcie_init_msi_irq_domain()
652 if (!pcie->msi_domain) { in advk_pcie_init_msi_irq_domain()
653 irq_domain_remove(pcie->msi_inner_domain); in advk_pcie_init_msi_irq_domain()
660 static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie) in advk_pcie_remove_msi_irq_domain() argument
662 irq_domain_remove(pcie->msi_domain); in advk_pcie_remove_msi_irq_domain()
663 irq_domain_remove(pcie->msi_inner_domain); in advk_pcie_remove_msi_irq_domain()
666 static int advk_pcie_init_irq_domain(struct advk_pcie *pcie) in advk_pcie_init_irq_domain() argument
668 struct device *dev = &pcie->pdev->dev; in advk_pcie_init_irq_domain()
675 dev_err(dev, "No PCIe Intc node found\n"); in advk_pcie_init_irq_domain()
679 irq_chip = &pcie->irq_chip; in advk_pcie_init_irq_domain()
692 pcie->irq_domain = in advk_pcie_init_irq_domain()
694 &advk_pcie_irq_domain_ops, pcie); in advk_pcie_init_irq_domain()
695 if (!pcie->irq_domain) { in advk_pcie_init_irq_domain()
704 static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie) in advk_pcie_remove_irq_domain() argument
706 irq_domain_remove(pcie->irq_domain); in advk_pcie_remove_irq_domain()
709 static void advk_pcie_handle_msi(struct advk_pcie *pcie) in advk_pcie_handle_msi() argument
714 msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG); in advk_pcie_handle_msi()
715 msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG); in advk_pcie_handle_msi()
722 advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG); in advk_pcie_handle_msi()
723 msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & 0xFF; in advk_pcie_handle_msi()
727 advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, in advk_pcie_handle_msi()
731 static void advk_pcie_handle_int(struct advk_pcie *pcie) in advk_pcie_handle_int() argument
737 isr0_val = advk_readl(pcie, PCIE_ISR0_REG); in advk_pcie_handle_int()
738 isr0_mask = advk_readl(pcie, PCIE_ISR0_MASK_REG); in advk_pcie_handle_int()
741 isr1_val = advk_readl(pcie, PCIE_ISR1_REG); in advk_pcie_handle_int()
742 isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG); in advk_pcie_handle_int()
746 advk_writel(pcie, isr0_val, PCIE_ISR0_REG); in advk_pcie_handle_int()
747 advk_writel(pcie, isr1_val, PCIE_ISR1_REG); in advk_pcie_handle_int()
753 advk_pcie_handle_msi(pcie); in advk_pcie_handle_int()
760 advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i), in advk_pcie_handle_int()
763 virq = irq_find_mapping(pcie->irq_domain, i); in advk_pcie_handle_int()
770 struct advk_pcie *pcie = arg; in advk_pcie_irq_handler() local
773 status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG); in advk_pcie_irq_handler()
777 advk_pcie_handle_int(pcie); in advk_pcie_irq_handler()
780 advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG); in advk_pcie_irq_handler()
785 static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) in advk_pcie_parse_request_of_pci_ranges() argument
788 struct device *dev = &pcie->pdev->dev; in advk_pcie_parse_request_of_pci_ranges()
792 INIT_LIST_HEAD(&pcie->resources); in advk_pcie_parse_request_of_pci_ranges()
795 &pcie->resources, &iobase); in advk_pcie_parse_request_of_pci_ranges()
799 err = devm_request_pci_bus_resources(dev, &pcie->resources); in advk_pcie_parse_request_of_pci_ranges()
803 resource_list_for_each_entry_safe(win, tmp, &pcie->resources) { in advk_pcie_parse_request_of_pci_ranges()
819 pcie->root_bus_nr = res->start; in advk_pcie_parse_request_of_pci_ranges()
833 pci_free_resource_list(&pcie->resources); in advk_pcie_parse_request_of_pci_ranges()
840 struct advk_pcie *pcie; in advk_pcie_probe() local
849 pcie = pci_host_bridge_priv(bridge); in advk_pcie_probe()
850 pcie->pdev = pdev; in advk_pcie_probe()
853 pcie->base = devm_ioremap_resource(dev, res); in advk_pcie_probe()
854 if (IS_ERR(pcie->base)) in advk_pcie_probe()
855 return PTR_ERR(pcie->base); in advk_pcie_probe()
859 IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie", in advk_pcie_probe()
860 pcie); in advk_pcie_probe()
866 ret = advk_pcie_parse_request_of_pci_ranges(pcie); in advk_pcie_probe()
872 advk_pcie_setup_hw(pcie); in advk_pcie_probe()
874 ret = advk_pcie_init_irq_domain(pcie); in advk_pcie_probe()
880 ret = advk_pcie_init_msi_irq_domain(pcie); in advk_pcie_probe()
883 advk_pcie_remove_irq_domain(pcie); in advk_pcie_probe()
887 list_splice_init(&pcie->resources, &bridge->windows); in advk_pcie_probe()
889 bridge->sysdata = pcie; in advk_pcie_probe()
897 advk_pcie_remove_msi_irq_domain(pcie); in advk_pcie_probe()
898 advk_pcie_remove_irq_domain(pcie); in advk_pcie_probe()
906 { .compatible = "marvell,armada-3700-pcie", },
912 .name = "advk-pcie",