Lines Matching +full:host +full:- +full:port
1 // SPDX-License-Identifier: GPL-2.0+
35 /* MediaTek-specific configuration registers */
40 /* Host-PCI bridge registers */
67 * struct mt7621_pcie_port - PCIe port information
69 * @list: port list
70 * @pcie: pointer to PCIe host info
71 * @clk: pointer to the port clock gate
73 * @pcie_rst: pointer to port reset control
75 * @slot: port slot
76 * @enabled: indicates if port is enabled
91 * struct mt7621_pcie - PCIe host information
94 * @ports: pointer to PCIe port information
107 return readl_relaxed(pcie->base + reg); in pcie_read()
112 writel_relaxed(val, pcie->base + reg); in pcie_write()
115 static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) in pcie_port_read() argument
117 return readl_relaxed(port->base + reg); in pcie_port_read()
120 static inline void pcie_port_write(struct mt7621_pcie_port *port, in pcie_port_write() argument
123 writel_relaxed(val, port->base + reg); in pcie_port_write()
129 struct mt7621_pcie *pcie = bus->sysdata; in mt7621_pcie_map_bus()
130 u32 address = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn), in mt7621_pcie_map_bus()
133 writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); in mt7621_pcie_map_bus()
135 return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); in mt7621_pcie_map_bus()
161 static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) in mt7621_rst_gpio_pcie_assert() argument
163 if (port->gpio_rst) in mt7621_rst_gpio_pcie_assert()
164 gpiod_set_value(port->gpio_rst, 1); in mt7621_rst_gpio_pcie_assert()
167 static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) in mt7621_rst_gpio_pcie_deassert() argument
169 if (port->gpio_rst) in mt7621_rst_gpio_pcie_deassert()
170 gpiod_set_value(port->gpio_rst, 0); in mt7621_rst_gpio_pcie_deassert()
173 static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) in mt7621_pcie_port_is_linkup() argument
175 return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; in mt7621_pcie_port_is_linkup()
178 static inline void mt7621_control_assert(struct mt7621_pcie_port *port) in mt7621_control_assert() argument
180 struct mt7621_pcie *pcie = port->pcie; in mt7621_control_assert()
182 if (pcie->resets_inverted) in mt7621_control_assert()
183 reset_control_assert(port->pcie_rst); in mt7621_control_assert()
185 reset_control_deassert(port->pcie_rst); in mt7621_control_assert()
188 static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) in mt7621_control_deassert() argument
190 struct mt7621_pcie *pcie = port->pcie; in mt7621_control_deassert()
192 if (pcie->resets_inverted) in mt7621_control_deassert()
193 reset_control_deassert(port->pcie_rst); in mt7621_control_deassert()
195 reset_control_assert(port->pcie_rst); in mt7621_control_deassert()
202 struct mt7621_pcie_port *port; in mt7621_pcie_parse_port() local
203 struct device *dev = pcie->dev; in mt7621_pcie_parse_port()
208 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); in mt7621_pcie_parse_port()
209 if (!port) in mt7621_pcie_parse_port()
210 return -ENOMEM; in mt7621_pcie_parse_port()
212 port->base = devm_platform_ioremap_resource(pdev, slot + 1); in mt7621_pcie_parse_port()
213 if (IS_ERR(port->base)) in mt7621_pcie_parse_port()
214 return PTR_ERR(port->base); in mt7621_pcie_parse_port()
216 port->clk = devm_get_clk_from_child(dev, node, NULL); in mt7621_pcie_parse_port()
217 if (IS_ERR(port->clk)) { in mt7621_pcie_parse_port()
219 return PTR_ERR(port->clk); in mt7621_pcie_parse_port()
222 port->pcie_rst = of_reset_control_get_exclusive(node, NULL); in mt7621_pcie_parse_port()
223 if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { in mt7621_pcie_parse_port()
225 return PTR_ERR(port->pcie_rst); in mt7621_pcie_parse_port()
228 snprintf(name, sizeof(name), "pcie-phy%d", slot); in mt7621_pcie_parse_port()
229 port->phy = devm_of_phy_get(dev, node, name); in mt7621_pcie_parse_port()
230 if (IS_ERR(port->phy)) { in mt7621_pcie_parse_port()
231 dev_err(dev, "failed to get pcie-phy%d\n", slot); in mt7621_pcie_parse_port()
232 err = PTR_ERR(port->phy); in mt7621_pcie_parse_port()
236 port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, in mt7621_pcie_parse_port()
238 if (IS_ERR(port->gpio_rst)) { in mt7621_pcie_parse_port()
240 err = PTR_ERR(port->gpio_rst); in mt7621_pcie_parse_port()
244 port->slot = slot; in mt7621_pcie_parse_port()
245 port->pcie = pcie; in mt7621_pcie_parse_port()
247 INIT_LIST_HEAD(&port->list); in mt7621_pcie_parse_port()
248 list_add_tail(&port->list, &pcie->ports); in mt7621_pcie_parse_port()
253 reset_control_put(port->pcie_rst); in mt7621_pcie_parse_port()
259 struct device *dev = pcie->dev; in mt7621_pcie_parse_dt()
261 struct device_node *node = dev->of_node, *child; in mt7621_pcie_parse_dt()
264 pcie->base = devm_platform_ioremap_resource(pdev, 0); in mt7621_pcie_parse_dt()
265 if (IS_ERR(pcie->base)) in mt7621_pcie_parse_dt()
266 return PTR_ERR(pcie->base); in mt7621_pcie_parse_dt()
290 static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) in mt7621_pcie_init_port() argument
292 struct mt7621_pcie *pcie = port->pcie; in mt7621_pcie_init_port()
293 struct device *dev = pcie->dev; in mt7621_pcie_init_port()
294 u32 slot = port->slot; in mt7621_pcie_init_port()
297 err = phy_init(port->phy); in mt7621_pcie_init_port()
299 dev_err(dev, "failed to initialize port%d phy\n", slot); in mt7621_pcie_init_port()
303 err = phy_power_on(port->phy); in mt7621_pcie_init_port()
305 dev_err(dev, "failed to power on port%d phy\n", slot); in mt7621_pcie_init_port()
306 phy_exit(port->phy); in mt7621_pcie_init_port()
310 port->enabled = true; in mt7621_pcie_init_port()
317 struct mt7621_pcie_port *port; in mt7621_pcie_reset_assert() local
319 list_for_each_entry(port, &pcie->ports, list) { in mt7621_pcie_reset_assert()
321 mt7621_control_assert(port); in mt7621_pcie_reset_assert()
324 mt7621_rst_gpio_pcie_assert(port); in mt7621_pcie_reset_assert()
332 struct mt7621_pcie_port *port; in mt7621_pcie_reset_rc_deassert() local
334 list_for_each_entry(port, &pcie->ports, list) in mt7621_pcie_reset_rc_deassert()
335 mt7621_control_deassert(port); in mt7621_pcie_reset_rc_deassert()
340 struct mt7621_pcie_port *port; in mt7621_pcie_reset_ep_deassert() local
342 list_for_each_entry(port, &pcie->ports, list) in mt7621_pcie_reset_ep_deassert()
343 mt7621_rst_gpio_pcie_deassert(port); in mt7621_pcie_reset_ep_deassert()
350 struct device *dev = pcie->dev; in mt7621_pcie_init_ports()
351 struct mt7621_pcie_port *port, *tmp; in mt7621_pcie_init_ports() local
358 list_for_each_entry_safe(port, tmp, &pcie->ports, list) { in mt7621_pcie_init_ports()
359 u32 slot = port->slot; in mt7621_pcie_init_ports()
362 port->enabled = true; in mt7621_pcie_init_ports()
366 err = mt7621_pcie_init_port(port); in mt7621_pcie_init_ports()
368 dev_err(dev, "initializing port %d failed\n", slot); in mt7621_pcie_init_ports()
369 list_del(&port->list); in mt7621_pcie_init_ports()
377 list_for_each_entry(port, &pcie->ports, list) { in mt7621_pcie_init_ports()
378 u32 slot = port->slot; in mt7621_pcie_init_ports()
380 if (!mt7621_pcie_port_is_linkup(port)) { in mt7621_pcie_init_ports()
383 mt7621_control_assert(port); in mt7621_pcie_init_ports()
384 port->enabled = false; in mt7621_pcie_init_ports()
388 tmp = port; in mt7621_pcie_init_ports()
392 if (slot == 1 && tmp && !tmp->enabled) in mt7621_pcie_init_ports()
393 phy_power_off(tmp->phy); in mt7621_pcie_init_ports()
397 return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; in mt7621_pcie_init_ports()
400 static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) in mt7621_pcie_enable_port() argument
402 struct mt7621_pcie *pcie = port->pcie; in mt7621_pcie_enable_port()
403 u32 slot = port->slot; in mt7621_pcie_enable_port()
412 pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, in mt7621_pcie_enable_port()
416 pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, in mt7621_pcie_enable_port()
426 static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) in mt7621_pcie_enable_ports() argument
428 struct mt7621_pcie *pcie = pci_host_bridge_priv(host); in mt7621_pcie_enable_ports()
429 struct device *dev = pcie->dev; in mt7621_pcie_enable_ports()
430 struct mt7621_pcie_port *port; in mt7621_pcie_enable_ports() local
434 entry = resource_list_first_type(&host->windows, IORESOURCE_IO); in mt7621_pcie_enable_ports()
437 return -EINVAL; in mt7621_pcie_enable_ports()
442 pcie_write(pcie, entry->res->start - entry->offset, RALINK_PCI_IOBASE); in mt7621_pcie_enable_ports()
444 list_for_each_entry(port, &pcie->ports, list) { in mt7621_pcie_enable_ports()
445 if (port->enabled) { in mt7621_pcie_enable_ports()
446 err = clk_prepare_enable(port->clk); in mt7621_pcie_enable_ports()
449 port->slot); in mt7621_pcie_enable_ports()
453 mt7621_pcie_enable_port(port); in mt7621_pcie_enable_ports()
454 dev_info(dev, "PCIE%d enabled\n", port->slot); in mt7621_pcie_enable_ports()
461 static int mt7621_pcie_register_host(struct pci_host_bridge *host) in mt7621_pcie_register_host() argument
463 struct mt7621_pcie *pcie = pci_host_bridge_priv(host); in mt7621_pcie_register_host()
465 host->ops = &mt7621_pcie_ops; in mt7621_pcie_register_host()
466 host->sysdata = pcie; in mt7621_pcie_register_host()
467 return pci_host_probe(host); in mt7621_pcie_register_host()
477 struct device *dev = &pdev->dev; in mt7621_pcie_probe()
479 struct mt7621_pcie_port *port; in mt7621_pcie_probe() local
484 if (!dev->of_node) in mt7621_pcie_probe()
485 return -ENODEV; in mt7621_pcie_probe()
489 return -ENOMEM; in mt7621_pcie_probe()
492 pcie->dev = dev; in mt7621_pcie_probe()
494 INIT_LIST_HEAD(&pcie->ports); in mt7621_pcie_probe()
498 pcie->resets_inverted = true; in mt7621_pcie_probe()
521 list_for_each_entry(port, &pcie->ports, list) in mt7621_pcie_probe()
522 reset_control_put(port->pcie_rst); in mt7621_pcie_probe()
530 struct mt7621_pcie_port *port; in mt7621_pcie_remove() local
532 list_for_each_entry(port, &pcie->ports, list) in mt7621_pcie_remove()
533 reset_control_put(port->pcie_rst); in mt7621_pcie_remove()
537 { .compatible = "mediatek,mt7621-pci" },
546 .name = "mt7621-pci",
552 MODULE_DESCRIPTION("MediaTek MT7621 PCIe host controller driver");