Skip to content

Commit 9cda279

Browse files
committed
PCI: apple: Skip controller port setup for online links
U-boot gained recently support for PCIe controller on Apple silicon devices. It is currently unkown how to reset / retrain already brought up ports. Redoing the controller level setup breaks the links. Check the link status before performing controller level port/link setup. Link: https://lore.kernel.org/u-boot/20230121192800.82428-1-kettenis@openbsd.org/ Signed-off-by: Janne Grunau <j@jannau.net>
1 parent fb2de8b commit 9cda279

1 file changed

Lines changed: 55 additions & 33 deletions

File tree

drivers/pci/controller/pcie-apple.c

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -605,15 +605,13 @@ static int apple_pcie_probe_port(struct device_node *np)
605605
return 0;
606606
}
607607

608-
static int apple_pcie_setup_port(struct apple_pcie *pcie,
608+
static int apple_pcie_setup_link(struct apple_pcie *pcie,
609+
struct apple_pcie_port *port,
609610
struct device_node *np)
610611
{
611-
struct platform_device *platform = to_platform_device(pcie->dev);
612-
struct apple_pcie_port *port;
613-
struct gpio_desc *reset, *pwren = NULL;
614-
u32 stat, idx;
615-
int ret, i;
616-
char name[16];
612+
struct gpio_desc *reset, *pwren;
613+
u32 stat;
614+
int ret;
617615

618616
reset = devm_fwnode_gpiod_get(pcie->dev, of_fwnode_handle(np), "reset",
619617
GPIOD_OUT_LOW, "PERST#");
@@ -629,32 +627,6 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
629627
return PTR_ERR(pwren);
630628
}
631629

632-
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
633-
if (!port)
634-
return -ENOMEM;
635-
636-
ret = of_property_read_u32_index(np, "reg", 0, &idx);
637-
if (ret)
638-
return ret;
639-
640-
/* Use the first reg entry to work out the port index */
641-
port->idx = idx >> 11;
642-
port->pcie = pcie;
643-
port->np = np;
644-
645-
snprintf(name, sizeof(name), "port%d", port->idx);
646-
port->base = devm_platform_ioremap_resource_byname(platform, name);
647-
if (IS_ERR(port->base))
648-
port->base = devm_platform_ioremap_resource(platform, port->idx + 2);
649-
if (IS_ERR(port->base)) {
650-
return PTR_ERR(port->base);
651-
}
652-
653-
snprintf(name, sizeof(name), "phy%d", port->idx);
654-
port->phy = devm_platform_ioremap_resource_byname(platform, name);
655-
if (IS_ERR(port->phy))
656-
port->phy = pcie->base + CORE_PHY_DEFAULT_BASE(port->idx);
657-
658630
rmw_set(PORT_APPCLK_EN, port->base + PORT_APPCLK);
659631

660632
/* Assert PERST# before setting up the clock */
@@ -690,6 +662,52 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
690662
return ret;
691663
}
692664

665+
return 0;
666+
}
667+
668+
static int apple_pcie_setup_port(struct apple_pcie *pcie,
669+
struct device_node *np)
670+
{
671+
struct platform_device *platform = to_platform_device(pcie->dev);
672+
struct apple_pcie_port *port;
673+
u32 link_stat, idx;
674+
int ret, i;
675+
char name[16];
676+
677+
port = devm_kzalloc(pcie->dev, sizeof(*port), GFP_KERNEL);
678+
if (!port)
679+
return -ENOMEM;
680+
681+
ret = of_property_read_u32_index(np, "reg", 0, &idx);
682+
if (ret)
683+
return ret;
684+
685+
/* Use the first reg entry to work out the port index */
686+
port->idx = idx >> 11;
687+
port->pcie = pcie;
688+
port->np = np;
689+
690+
snprintf(name, sizeof(name), "port%d", port->idx);
691+
port->base = devm_platform_ioremap_resource_byname(platform, name);
692+
if (IS_ERR(port->base))
693+
port->base = devm_platform_ioremap_resource(platform, port->idx + 2);
694+
if (IS_ERR(port->base)) {
695+
return PTR_ERR(port->base);
696+
}
697+
698+
snprintf(name, sizeof(name), "phy%d", port->idx);
699+
port->phy = devm_platform_ioremap_resource_byname(platform, name);
700+
if (IS_ERR(port->phy))
701+
port->phy = pcie->base + CORE_PHY_DEFAULT_BASE(port->idx);
702+
703+
/* link might be already brought up by u-boot, skip setup then */
704+
link_stat = readl_relaxed(port->base + PORT_LINKSTS);
705+
if (!(link_stat & PORT_LINKSTS_UP)) {
706+
ret = apple_pcie_setup_link(pcie, port, np);
707+
if (ret)
708+
return ret;
709+
}
710+
693711
ret = apple_pcie_port_setup_irq(port);
694712
if (ret)
695713
return ret;
@@ -714,6 +732,10 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
714732
ret = apple_pcie_port_register_irqs(port);
715733
WARN_ON(ret);
716734

735+
if (link_stat & PORT_LINKSTS_UP)
736+
return 0;
737+
738+
/* start link training */
717739
writel_relaxed(PORT_LTSSMCTL_START, port->base + PORT_LTSSMCTL);
718740

719741
if (!wait_for_completion_timeout(&pcie->event, HZ / 10))

0 commit comments

Comments
 (0)