Lines Matching +full:port +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0
5 * Author: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
24 #include "../pci-bridge-emul.h"
36 #define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
89 u32 port; member
108 static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg) in mvebu_writel() argument
110 writel(val, port->base + reg); in mvebu_writel()
113 static inline u32 mvebu_readl(struct mvebu_pcie_port *port, u32 reg) in mvebu_readl() argument
115 return readl(port->base + reg); in mvebu_readl()
118 static inline bool mvebu_has_ioport(struct mvebu_pcie_port *port) in mvebu_has_ioport() argument
120 return port->io_target != -1 && port->io_attr != -1; in mvebu_has_ioport()
123 static bool mvebu_pcie_link_up(struct mvebu_pcie_port *port) in mvebu_pcie_link_up() argument
125 return !(mvebu_readl(port, PCIE_STAT_OFF) & PCIE_STAT_LINK_DOWN); in mvebu_pcie_link_up()
128 static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie_port *port, int nr) in mvebu_pcie_set_local_bus_nr() argument
132 stat = mvebu_readl(port, PCIE_STAT_OFF); in mvebu_pcie_set_local_bus_nr()
135 mvebu_writel(port, stat, PCIE_STAT_OFF); in mvebu_pcie_set_local_bus_nr()
138 static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr) in mvebu_pcie_set_local_dev_nr() argument
142 stat = mvebu_readl(port, PCIE_STAT_OFF); in mvebu_pcie_set_local_dev_nr()
145 mvebu_writel(port, stat, PCIE_STAT_OFF); in mvebu_pcie_set_local_dev_nr()
150 * BAR[0] -> internal registers (needed for MSI)
151 * BAR[1] -> covers all DRAM banks
152 * BAR[2] -> Disabled
153 * WIN[0-3] -> DRAM bank[0-3]
155 static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) in mvebu_pcie_setup_wins() argument
164 for (i = 1; i < 3; i++) { in mvebu_pcie_setup_wins()
165 mvebu_writel(port, 0, PCIE_BAR_CTRL_OFF(i)); in mvebu_pcie_setup_wins()
166 mvebu_writel(port, 0, PCIE_BAR_LO_OFF(i)); in mvebu_pcie_setup_wins()
167 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(i)); in mvebu_pcie_setup_wins()
171 mvebu_writel(port, 0, PCIE_WIN04_CTRL_OFF(i)); in mvebu_pcie_setup_wins()
172 mvebu_writel(port, 0, PCIE_WIN04_BASE_OFF(i)); in mvebu_pcie_setup_wins()
173 mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i)); in mvebu_pcie_setup_wins()
176 mvebu_writel(port, 0, PCIE_WIN5_CTRL_OFF); in mvebu_pcie_setup_wins()
177 mvebu_writel(port, 0, PCIE_WIN5_BASE_OFF); in mvebu_pcie_setup_wins()
178 mvebu_writel(port, 0, PCIE_WIN5_REMAP_OFF); in mvebu_pcie_setup_wins()
182 for (i = 0; i < dram->num_cs; i++) { in mvebu_pcie_setup_wins()
183 const struct mbus_dram_window *cs = dram->cs + i; in mvebu_pcie_setup_wins()
185 mvebu_writel(port, cs->base & 0xffff0000, in mvebu_pcie_setup_wins()
187 mvebu_writel(port, 0, PCIE_WIN04_REMAP_OFF(i)); in mvebu_pcie_setup_wins()
188 mvebu_writel(port, in mvebu_pcie_setup_wins()
189 ((cs->size - 1) & 0xffff0000) | in mvebu_pcie_setup_wins()
190 (cs->mbus_attr << 8) | in mvebu_pcie_setup_wins()
191 (dram->mbus_dram_target_id << 4) | 1, in mvebu_pcie_setup_wins()
194 size += cs->size; in mvebu_pcie_setup_wins()
198 if ((size & (size - 1)) != 0) in mvebu_pcie_setup_wins()
199 size = 1 << fls(size); in mvebu_pcie_setup_wins()
201 /* Setup BAR[1] to all DRAM banks. */ in mvebu_pcie_setup_wins()
202 mvebu_writel(port, dram->cs[0].base, PCIE_BAR_LO_OFF(1)); in mvebu_pcie_setup_wins()
203 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(1)); in mvebu_pcie_setup_wins()
204 mvebu_writel(port, ((size - 1) & 0xffff0000) | 1, in mvebu_pcie_setup_wins()
205 PCIE_BAR_CTRL_OFF(1)); in mvebu_pcie_setup_wins()
210 mvebu_writel(port, round_down(port->regs.start, SZ_1M), PCIE_BAR_LO_OFF(0)); in mvebu_pcie_setup_wins()
211 mvebu_writel(port, 0, PCIE_BAR_HI_OFF(0)); in mvebu_pcie_setup_wins()
214 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port) in mvebu_pcie_setup_hw() argument
219 mvebu_pcie_setup_wins(port); in mvebu_pcie_setup_hw()
222 cmd = mvebu_readl(port, PCIE_CMD_OFF); in mvebu_pcie_setup_hw()
226 mvebu_writel(port, cmd, PCIE_CMD_OFF); in mvebu_pcie_setup_hw()
228 /* Enable interrupt lines A-D. */ in mvebu_pcie_setup_hw()
229 mask = mvebu_readl(port, PCIE_MASK_OFF); in mvebu_pcie_setup_hw()
231 mvebu_writel(port, mask, PCIE_MASK_OFF); in mvebu_pcie_setup_hw()
234 static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port, in mvebu_pcie_hw_rd_conf() argument
238 void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF; in mvebu_pcie_hw_rd_conf()
240 mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where), in mvebu_pcie_hw_rd_conf()
244 case 1: in mvebu_pcie_hw_rd_conf()
258 static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port, in mvebu_pcie_hw_wr_conf() argument
262 void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF; in mvebu_pcie_hw_wr_conf()
264 mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where), in mvebu_pcie_hw_wr_conf()
268 case 1: in mvebu_pcie_hw_wr_conf()
288 static void mvebu_pcie_del_windows(struct mvebu_pcie_port *port, in mvebu_pcie_del_windows() argument
292 size_t sz = 1 << (fls(size) - 1); in mvebu_pcie_del_windows()
296 size -= sz; in mvebu_pcie_del_windows()
306 static void mvebu_pcie_add_windows(struct mvebu_pcie_port *port, in mvebu_pcie_add_windows() argument
314 size_t sz = 1 << (fls(size) - 1); in mvebu_pcie_add_windows()
320 phys_addr_t end = base + sz - 1; in mvebu_pcie_add_windows()
322 dev_err(&port->pcie->pdev->dev, in mvebu_pcie_add_windows()
323 "Could not create MBus window at [mem %pa-%pa]: %d\n", in mvebu_pcie_add_windows()
325 mvebu_pcie_del_windows(port, base - size_mapped, in mvebu_pcie_add_windows()
330 size -= sz; in mvebu_pcie_add_windows()
338 static void mvebu_pcie_set_window(struct mvebu_pcie_port *port, in mvebu_pcie_set_window() argument
343 if (desired->base == cur->base && desired->remap == cur->remap && in mvebu_pcie_set_window()
344 desired->size == cur->size) in mvebu_pcie_set_window()
347 if (cur->size != 0) { in mvebu_pcie_set_window()
348 mvebu_pcie_del_windows(port, cur->base, cur->size); in mvebu_pcie_set_window()
349 cur->size = 0; in mvebu_pcie_set_window()
350 cur->base = 0; in mvebu_pcie_set_window()
359 if (desired->size == 0) in mvebu_pcie_set_window()
362 mvebu_pcie_add_windows(port, target, attribute, desired->base, in mvebu_pcie_set_window()
363 desired->size, desired->remap); in mvebu_pcie_set_window()
367 static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) in mvebu_pcie_handle_iobase_change() argument
370 struct pci_bridge_emul_conf *conf = &port->bridge.conf; in mvebu_pcie_handle_iobase_change()
373 if (conf->iolimit < conf->iobase || in mvebu_pcie_handle_iobase_change()
374 conf->iolimitupper < conf->iobaseupper || in mvebu_pcie_handle_iobase_change()
375 !(conf->command & PCI_COMMAND_IO)) { in mvebu_pcie_handle_iobase_change()
376 mvebu_pcie_set_window(port, port->io_target, port->io_attr, in mvebu_pcie_handle_iobase_change()
377 &desired, &port->iowin); in mvebu_pcie_handle_iobase_change()
381 if (!mvebu_has_ioport(port)) { in mvebu_pcie_handle_iobase_change()
382 dev_WARN(&port->pcie->pdev->dev, in mvebu_pcie_handle_iobase_change()
388 * We read the PCI-to-PCI bridge emulated registers, and in mvebu_pcie_handle_iobase_change()
390 * window to setup, according to the PCI-to-PCI bridge in mvebu_pcie_handle_iobase_change()
391 * specifications. iobase is the bus address, port->iowin_base in mvebu_pcie_handle_iobase_change()
394 desired.remap = ((conf->iobase & 0xF0) << 8) | in mvebu_pcie_handle_iobase_change()
395 (conf->iobaseupper << 16); in mvebu_pcie_handle_iobase_change()
396 desired.base = port->pcie->io.start + desired.remap; in mvebu_pcie_handle_iobase_change()
397 desired.size = ((0xFFF | ((conf->iolimit & 0xF0) << 8) | in mvebu_pcie_handle_iobase_change()
398 (conf->iolimitupper << 16)) - in mvebu_pcie_handle_iobase_change()
400 1; in mvebu_pcie_handle_iobase_change()
402 mvebu_pcie_set_window(port, port->io_target, port->io_attr, &desired, in mvebu_pcie_handle_iobase_change()
403 &port->iowin); in mvebu_pcie_handle_iobase_change()
406 static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) in mvebu_pcie_handle_membase_change() argument
409 struct pci_bridge_emul_conf *conf = &port->bridge.conf; in mvebu_pcie_handle_membase_change()
412 if (conf->memlimit < conf->membase || in mvebu_pcie_handle_membase_change()
413 !(conf->command & PCI_COMMAND_MEMORY)) { in mvebu_pcie_handle_membase_change()
414 mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, in mvebu_pcie_handle_membase_change()
415 &desired, &port->memwin); in mvebu_pcie_handle_membase_change()
420 * We read the PCI-to-PCI bridge emulated registers, and in mvebu_pcie_handle_membase_change()
422 * window to setup, according to the PCI-to-PCI bridge in mvebu_pcie_handle_membase_change()
425 desired.base = ((conf->membase & 0xFFF0) << 16); in mvebu_pcie_handle_membase_change()
426 desired.size = (((conf->memlimit & 0xFFF0) << 16) | 0xFFFFF) - in mvebu_pcie_handle_membase_change()
427 desired.base + 1; in mvebu_pcie_handle_membase_change()
429 mvebu_pcie_set_window(port, port->mem_target, port->mem_attr, &desired, in mvebu_pcie_handle_membase_change()
430 &port->memwin); in mvebu_pcie_handle_membase_change()
437 struct mvebu_pcie_port *port = bridge->data; in mvebu_pci_bridge_emul_pcie_conf_read() local
441 *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCAP); in mvebu_pci_bridge_emul_pcie_conf_read()
445 *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL) & in mvebu_pci_bridge_emul_pcie_conf_read()
453 * hard-wired to zero for downstream ports in mvebu_pci_bridge_emul_pcie_conf_read()
455 *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP) & in mvebu_pci_bridge_emul_pcie_conf_read()
460 *value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); in mvebu_pci_bridge_emul_pcie_conf_read()
468 *value = mvebu_readl(port, PCIE_RC_RTSTA); in mvebu_pci_bridge_emul_pcie_conf_read()
482 struct mvebu_pcie_port *port = bridge->data; in mvebu_pci_bridge_emul_base_conf_write() local
483 struct pci_bridge_emul_conf *conf = &bridge->conf; in mvebu_pci_bridge_emul_base_conf_write()
488 if (!mvebu_has_ioport(port)) in mvebu_pci_bridge_emul_base_conf_write()
489 conf->command &= ~PCI_COMMAND_IO; in mvebu_pci_bridge_emul_base_conf_write()
492 mvebu_pcie_handle_iobase_change(port); in mvebu_pci_bridge_emul_base_conf_write()
494 mvebu_pcie_handle_membase_change(port); in mvebu_pci_bridge_emul_base_conf_write()
501 * We keep bit 1 set, it is a read-only bit that in mvebu_pci_bridge_emul_base_conf_write()
505 conf->iobase |= PCI_IO_RANGE_TYPE_32; in mvebu_pci_bridge_emul_base_conf_write()
506 conf->iolimit |= PCI_IO_RANGE_TYPE_32; in mvebu_pci_bridge_emul_base_conf_write()
507 mvebu_pcie_handle_iobase_change(port); in mvebu_pci_bridge_emul_base_conf_write()
511 mvebu_pcie_handle_membase_change(port); in mvebu_pci_bridge_emul_base_conf_write()
515 mvebu_pcie_handle_iobase_change(port); in mvebu_pci_bridge_emul_base_conf_write()
519 mvebu_pcie_set_local_bus_nr(port, conf->secondary_bus); in mvebu_pci_bridge_emul_base_conf_write()
531 struct mvebu_pcie_port *port = bridge->data; in mvebu_pci_bridge_emul_pcie_conf_write() local
542 mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_DEVCTL); in mvebu_pci_bridge_emul_pcie_conf_write()
554 mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL); in mvebu_pci_bridge_emul_pcie_conf_write()
558 mvebu_writel(port, new, PCIE_RC_RTSTA); in mvebu_pci_bridge_emul_pcie_conf_write()
570 * Initialize the configuration space of the PCI-to-PCI bridge
573 static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) in mvebu_pci_bridge_emul_init() argument
575 struct pci_bridge_emul *bridge = &port->bridge; in mvebu_pci_bridge_emul_init()
577 bridge->conf.vendor = PCI_VENDOR_ID_MARVELL; in mvebu_pci_bridge_emul_init()
578 bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; in mvebu_pci_bridge_emul_init()
579 bridge->conf.class_revision = in mvebu_pci_bridge_emul_init()
580 mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff; in mvebu_pci_bridge_emul_init()
582 if (mvebu_has_ioport(port)) { in mvebu_pci_bridge_emul_init()
584 bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; in mvebu_pci_bridge_emul_init()
585 bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; in mvebu_pci_bridge_emul_init()
588 bridge->has_pcie = true; in mvebu_pci_bridge_emul_init()
589 bridge->data = port; in mvebu_pci_bridge_emul_init()
590 bridge->ops = &mvebu_pci_bridge_emul_ops; in mvebu_pci_bridge_emul_init()
597 return sys->private_data; in sys_to_pcie()
606 for (i = 0; i < pcie->nports; i++) { in mvebu_pcie_find_port()
607 struct mvebu_pcie_port *port = &pcie->ports[i]; in mvebu_pcie_find_port() local
609 if (bus->number == 0 && port->devfn == devfn) in mvebu_pcie_find_port()
610 return port; in mvebu_pcie_find_port()
611 if (bus->number != 0 && in mvebu_pcie_find_port()
612 bus->number >= port->bridge.conf.secondary_bus && in mvebu_pcie_find_port()
613 bus->number <= port->bridge.conf.subordinate_bus) in mvebu_pcie_find_port()
614 return port; in mvebu_pcie_find_port()
624 struct mvebu_pcie *pcie = bus->sysdata; in mvebu_pcie_wr_conf()
625 struct mvebu_pcie_port *port; in mvebu_pcie_wr_conf() local
628 port = mvebu_pcie_find_port(pcie, bus, devfn); in mvebu_pcie_wr_conf()
629 if (!port) in mvebu_pcie_wr_conf()
632 /* Access the emulated PCI-to-PCI bridge */ in mvebu_pcie_wr_conf()
633 if (bus->number == 0) in mvebu_pcie_wr_conf()
634 return pci_bridge_emul_conf_write(&port->bridge, where, in mvebu_pcie_wr_conf()
637 if (!mvebu_pcie_link_up(port)) in mvebu_pcie_wr_conf()
641 ret = mvebu_pcie_hw_wr_conf(port, bus, devfn, in mvebu_pcie_wr_conf()
651 struct mvebu_pcie *pcie = bus->sysdata; in mvebu_pcie_rd_conf()
652 struct mvebu_pcie_port *port; in mvebu_pcie_rd_conf() local
655 port = mvebu_pcie_find_port(pcie, bus, devfn); in mvebu_pcie_rd_conf()
656 if (!port) { in mvebu_pcie_rd_conf()
661 /* Access the emulated PCI-to-PCI bridge */ in mvebu_pcie_rd_conf()
662 if (bus->number == 0) in mvebu_pcie_rd_conf()
663 return pci_bridge_emul_conf_read(&port->bridge, where, in mvebu_pcie_rd_conf()
666 if (!mvebu_pcie_link_up(port)) { in mvebu_pcie_rd_conf()
672 ret = mvebu_pcie_hw_rd_conf(port, bus, devfn, in mvebu_pcie_rd_conf()
689 if (dev->bus->number != 0) in mvebu_pcie_align_resource()
693 * On the PCI-to-PCI bridge side, the I/O windows must have at in mvebu_pcie_align_resource()
695 * least a 1 MB size. Moreover, MBus windows need to have a in mvebu_pcie_align_resource()
703 if (res->flags & IORESOURCE_IO) in mvebu_pcie_align_resource()
706 else if (res->flags & IORESOURCE_MEM) in mvebu_pcie_align_resource()
715 struct mvebu_pcie_port *port) in mvebu_pcie_map_registers() argument
719 ret = of_address_to_resource(np, 0, &port->regs); in mvebu_pcie_map_registers()
723 return devm_ioremap_resource(&pdev->dev, &port->regs); in mvebu_pcie_map_registers()
741 *tgt = -1; in mvebu_get_tgt_attr()
742 *attr = -1; in mvebu_get_tgt_attr()
746 return -EINVAL; in mvebu_get_tgt_attr()
753 u32 flags = of_read_number(range, 1); in mvebu_get_tgt_attr()
754 u32 slot = of_read_number(range + 1, 1); in mvebu_get_tgt_attr()
772 return -ENOENT; in mvebu_get_tgt_attr()
782 for (i = 0; i < pcie->nports; i++) { in mvebu_pcie_suspend()
783 struct mvebu_pcie_port *port = pcie->ports + i; in mvebu_pcie_suspend() local
784 port->saved_pcie_stat = mvebu_readl(port, PCIE_STAT_OFF); in mvebu_pcie_suspend()
796 for (i = 0; i < pcie->nports; i++) { in mvebu_pcie_resume()
797 struct mvebu_pcie_port *port = pcie->ports + i; in mvebu_pcie_resume() local
798 mvebu_writel(port, port->saved_pcie_stat, PCIE_STAT_OFF); in mvebu_pcie_resume()
799 mvebu_pcie_setup_hw(port); in mvebu_pcie_resume()
808 struct mvebu_pcie_port *port = data; in mvebu_pcie_port_clk_put() local
810 clk_put(port->clk); in mvebu_pcie_port_clk_put()
814 struct mvebu_pcie_port *port, struct device_node *child) in mvebu_pcie_parse_port() argument
816 struct device *dev = &pcie->pdev->dev; in mvebu_pcie_parse_port()
820 port->pcie = pcie; in mvebu_pcie_parse_port()
822 if (of_property_read_u32(child, "marvell,pcie-port", &port->port)) { in mvebu_pcie_parse_port()
823 dev_warn(dev, "ignoring %pOF, missing pcie-port property\n", in mvebu_pcie_parse_port()
828 if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane)) in mvebu_pcie_parse_port()
829 port->lane = 0; in mvebu_pcie_parse_port()
831 port->name = devm_kasprintf(dev, GFP_KERNEL, "pcie%d.%d", port->port, in mvebu_pcie_parse_port()
832 port->lane); in mvebu_pcie_parse_port()
833 if (!port->name) { in mvebu_pcie_parse_port()
834 ret = -ENOMEM; in mvebu_pcie_parse_port()
838 port->devfn = of_pci_get_devfn(child); in mvebu_pcie_parse_port()
839 if (port->devfn < 0) in mvebu_pcie_parse_port()
842 ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM, in mvebu_pcie_parse_port()
843 &port->mem_target, &port->mem_attr); in mvebu_pcie_parse_port()
846 port->name); in mvebu_pcie_parse_port()
850 if (resource_size(&pcie->io) != 0) { in mvebu_pcie_parse_port()
851 mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_IO, in mvebu_pcie_parse_port()
852 &port->io_target, &port->io_attr); in mvebu_pcie_parse_port()
854 port->io_target = -1; in mvebu_pcie_parse_port()
855 port->io_attr = -1; in mvebu_pcie_parse_port()
858 reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags); in mvebu_pcie_parse_port()
859 if (reset_gpio == -EPROBE_DEFER) { in mvebu_pcie_parse_port()
867 port->reset_name = devm_kasprintf(dev, GFP_KERNEL, "%s-reset", in mvebu_pcie_parse_port()
868 port->name); in mvebu_pcie_parse_port()
869 if (!port->reset_name) { in mvebu_pcie_parse_port()
870 ret = -ENOMEM; in mvebu_pcie_parse_port()
884 port->reset_name); in mvebu_pcie_parse_port()
886 if (ret == -EPROBE_DEFER) in mvebu_pcie_parse_port()
891 port->reset_gpio = gpio_to_desc(reset_gpio); in mvebu_pcie_parse_port()
894 port->clk = of_clk_get_by_name(child, NULL); in mvebu_pcie_parse_port()
895 if (IS_ERR(port->clk)) { in mvebu_pcie_parse_port()
896 dev_err(dev, "%s: cannot get clock\n", port->name); in mvebu_pcie_parse_port()
900 ret = devm_add_action(dev, mvebu_pcie_port_clk_put, port); in mvebu_pcie_parse_port()
902 clk_put(port->clk); in mvebu_pcie_parse_port()
906 return 1; in mvebu_pcie_parse_port()
912 devm_kfree(dev, port->reset_name); in mvebu_pcie_parse_port()
913 port->reset_name = NULL; in mvebu_pcie_parse_port()
914 devm_kfree(dev, port->name); in mvebu_pcie_parse_port()
915 port->name = NULL; in mvebu_pcie_parse_port()
922 * Power up a PCIe port. PCIe requires the refclk to be stable for 100µs
923 * prior to releasing PERST. See table 2-4 in section 2.6.2 AC Specifications
926 static int mvebu_pcie_powerup(struct mvebu_pcie_port *port) in mvebu_pcie_powerup() argument
930 ret = clk_prepare_enable(port->clk); in mvebu_pcie_powerup()
934 if (port->reset_gpio) { in mvebu_pcie_powerup()
937 of_property_read_u32(port->dn, "reset-delay-us", in mvebu_pcie_powerup()
942 gpiod_set_value_cansleep(port->reset_gpio, 0); in mvebu_pcie_powerup()
950 * Power down a PCIe port. Strictly, PCIe requires us to place the card
953 static void mvebu_pcie_powerdown(struct mvebu_pcie_port *port) in mvebu_pcie_powerdown() argument
955 gpiod_set_value_cansleep(port->reset_gpio, 1); in mvebu_pcie_powerdown()
957 clk_disable_unprepare(port->clk); in mvebu_pcie_powerdown()
967 struct device *dev = &pcie->pdev->dev; in mvebu_pcie_parse_request_resources()
972 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem); in mvebu_pcie_parse_request_resources()
973 if (resource_size(&pcie->mem) == 0) { in mvebu_pcie_parse_request_resources()
975 return -EINVAL; in mvebu_pcie_parse_request_resources()
978 pcie->mem.name = "PCI MEM"; in mvebu_pcie_parse_request_resources()
979 pci_add_resource(&bridge->windows, &pcie->mem); in mvebu_pcie_parse_request_resources()
980 ret = devm_request_resource(dev, &iomem_resource, &pcie->mem); in mvebu_pcie_parse_request_resources()
985 mvebu_mbus_get_pcie_io_aperture(&pcie->io); in mvebu_pcie_parse_request_resources()
987 if (resource_size(&pcie->io) != 0) { in mvebu_pcie_parse_request_resources()
988 pcie->realio.flags = pcie->io.flags; in mvebu_pcie_parse_request_resources()
989 pcie->realio.start = PCIBIOS_MIN_IO; in mvebu_pcie_parse_request_resources()
990 pcie->realio.end = min_t(resource_size_t, in mvebu_pcie_parse_request_resources()
991 IO_SPACE_LIMIT - SZ_64K, in mvebu_pcie_parse_request_resources()
992 resource_size(&pcie->io) - 1); in mvebu_pcie_parse_request_resources()
993 pcie->realio.name = "PCI I/O"; in mvebu_pcie_parse_request_resources()
995 pci_add_resource(&bridge->windows, &pcie->realio); in mvebu_pcie_parse_request_resources()
996 ret = devm_request_resource(dev, &ioport_resource, &pcie->realio); in mvebu_pcie_parse_request_resources()
1019 dev_err(bridge->dev.parent, "Scanning root bridge failed"); in mvebu_pci_host_probe()
1024 if (resource_size(&pcie->io) != 0) { in mvebu_pci_host_probe()
1027 for (i = 0; i < resource_size(&pcie->realio); i += SZ_64K) in mvebu_pci_host_probe()
1028 pci_ioremap_io(i, pcie->io.start + i); in mvebu_pci_host_probe()
1031 bus = bridge->bus; in mvebu_pci_host_probe()
1044 list_for_each_entry(child, &bus->children, node) in mvebu_pci_host_probe()
1054 struct device *dev = &pdev->dev; in mvebu_pcie_probe()
1057 struct device_node *np = dev->of_node; in mvebu_pcie_probe()
1063 return -ENOMEM; in mvebu_pcie_probe()
1066 pcie->pdev = pdev; in mvebu_pcie_probe()
1075 pcie->ports = devm_kcalloc(dev, num, sizeof(*pcie->ports), GFP_KERNEL); in mvebu_pcie_probe()
1076 if (!pcie->ports) in mvebu_pcie_probe()
1077 return -ENOMEM; in mvebu_pcie_probe()
1081 struct mvebu_pcie_port *port = &pcie->ports[i]; in mvebu_pcie_probe() local
1083 ret = mvebu_pcie_parse_port(pcie, port, child); in mvebu_pcie_probe()
1091 port->dn = child; in mvebu_pcie_probe()
1094 pcie->nports = i; in mvebu_pcie_probe()
1096 for (i = 0; i < pcie->nports; i++) { in mvebu_pcie_probe()
1097 struct mvebu_pcie_port *port = &pcie->ports[i]; in mvebu_pcie_probe() local
1099 child = port->dn; in mvebu_pcie_probe()
1103 ret = mvebu_pcie_powerup(port); in mvebu_pcie_probe()
1107 port->base = mvebu_pcie_map_registers(pdev, child, port); in mvebu_pcie_probe()
1108 if (IS_ERR(port->base)) { in mvebu_pcie_probe()
1109 dev_err(dev, "%s: cannot map registers\n", port->name); in mvebu_pcie_probe()
1110 port->base = NULL; in mvebu_pcie_probe()
1111 mvebu_pcie_powerdown(port); in mvebu_pcie_probe()
1115 mvebu_pcie_setup_hw(port); in mvebu_pcie_probe()
1116 mvebu_pcie_set_local_dev_nr(port, 1); in mvebu_pcie_probe()
1117 mvebu_pci_bridge_emul_init(port); in mvebu_pcie_probe()
1120 pcie->nports = i; in mvebu_pcie_probe()
1122 bridge->sysdata = pcie; in mvebu_pcie_probe()
1123 bridge->ops = &mvebu_pcie_ops; in mvebu_pcie_probe()
1124 bridge->align_resource = mvebu_pcie_align_resource; in mvebu_pcie_probe()
1130 { .compatible = "marvell,armada-xp-pcie", },
1131 { .compatible = "marvell,armada-370-pcie", },
1132 { .compatible = "marvell,dove-pcie", },
1133 { .compatible = "marvell,kirkwood-pcie", },
1143 .name = "mvebu-pcie",