On Sun, 15 Aug 2021 08:42:50 +0100, Marc Zyngier <maz@xxxxxxxxxx> wrote: > > On Sun, 15 Aug 2021 05:25:25 +0100, > Alyssa Rosenzweig <alyssa@xxxxxxxxxxxxx> wrote: > > > > Add a driver for the PCIe controller found in Apple system-on-chips, > > particularly the Apple M1. This driver exposes the internal bus used for > > the USB type-A ports, Ethernet, Wi-Fi, and Bluetooth. This patch brings > > up the USB type-A ports and Ethernet. Bringing up the radios requires > > interfacing with the System Management Coprocessor via Apple's > > mailboxes, so that's left to a future patch. > > > > In this state, the driver consists of two major parts: hardware > > initialization and MSI handling. The hardware initialization is derived > > from Mark Kettenis's U-Boot patches which in turn is derived from > > Corellium's patches for the hardware. The rest of the driver is derived > > from Marc Zyngier's driver for the hardware. > > This really needs to be split into multiple patches: > > - PCI probing > - Clock management > - MSI implementation > > A couple of comments below: > > > > > Co-developed-by: Stan Skowronek <stan@xxxxxxxxxxxxx> > > Signed-off-by: Stan Skowronek <stan@xxxxxxxxxxxxx> > > Co-developed-by: Marc Zyngier <maz@xxxxxxxxxx> > > Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx> > > Signed-off-by: Alyssa Rosenzweig <alyssa@xxxxxxxxxxxxx> > > --- > > MAINTAINERS | 1 + > > drivers/pci/controller/Kconfig | 13 + > > drivers/pci/controller/Makefile | 1 + > > drivers/pci/controller/pcie-apple.c | 466 ++++++++++++++++++++++++++++ > > 4 files changed, 481 insertions(+) > > create mode 100644 drivers/pci/controller/pcie-apple.c > > [...] One last comment before I put the laptop away and go hiking for the day: > > +static int apple_pcie_setup_refclk(void __iomem *rc, > > + void __iomem *port, > > + unsigned int idx) > > +{ > > + u32 stat; > > + int res; > > + > > + res = readl_poll_timeout(rc + CORE_RC_PHYIF_STAT, stat, > > + stat & CORE_RC_PHYIF_STAT_REFCLK, 100, 50000); > > + if (res < 0) > > + return res; > > + > > + rmwl(0, CORE_LANE_CTL_CFGACC, rc + CORE_LANE_CTL(idx)); > > + rmwl(0, CORE_LANE_CFG_REFCLK0REQ, rc + CORE_LANE_CFG(idx)); > > + > > + res = readl_poll_timeout(rc + CORE_LANE_CFG(idx), stat, > > + stat & CORE_LANE_CFG_REFCLK0ACK, 100, 50000); > > + if (res < 0) > > + return res; > > + > > + rmwl(0, CORE_LANE_CFG_REFCLK1, rc + CORE_LANE_CFG(idx)); > > + res = readl_poll_timeout(rc + CORE_LANE_CFG(idx), stat, > > + stat & CORE_LANE_CFG_REFCLK1, 100, 50000); > > + > > + if (res < 0) > > + return res; > > + > > + rmwl(CORE_LANE_CTL_CFGACC, 0, rc + CORE_LANE_CTL(idx)); > > + udelay(1); > > + rmwl(0, CORE_LANE_CFG_REFCLKEN, rc + CORE_LANE_CFG(idx)); > > + > > + rmwl(0, PORT_REFCLK_EN, port + PORT_REFCLK); > > + > > + return 0; > > +} This really wants to be moved to its own clock driver, unless there is a strong guarantee that the clock tree isn't shared with anything else. I expect that parts of that clock tree will need to be refcounted, and that's where having a real clock driver will help. I also have the strong feeling that the clock hierarchy will need to be described in DT one way or another, if only to be able to cope with future revisions of this block. Thanks, M. -- Without deviation from the norm, progress is not possible.