Skip to content

Commit d3575a3

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 e48287a commit d3575a3

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
@@ -606,15 +606,13 @@ static int apple_pcie_probe_port(struct device_node *np)
606606
return 0;
607607
}
608608

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

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

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

661633
/* Assert PERST# before setting up the clock */
@@ -691,6 +663,52 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
691663
return ret;
692664
}
693665

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

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

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

0 commit comments

Comments
 (0)