The driver never reads the standard "num-lanes" property, so a board cannot set the width of a port: the OrangePi RV2's M.2 slot on port B is wired for two lanes, and other boards may use only one of the two.
Linux's DesignWare core reads "num-lanes" and, when it is set, programs the port link mode, the link width and speed control register and the Maximum Link Width in Link Capabilities from it, leaving the hardware default otherwise. dw_pcie_link_set_max_link_width() in pcie_dw_common does exactly that; call it before link training. Signed-off-by: Dave Klotz <[email protected]> --- drivers/pci/pcie_dw_spacemit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/pcie_dw_spacemit.c b/drivers/pci/pcie_dw_spacemit.c index 3b5c2dc4e0..9b299ca17a 100644 --- a/drivers/pci/pcie_dw_spacemit.c +++ b/drivers/pci/pcie_dw_spacemit.c @@ -41,6 +41,7 @@ struct pcie_dw_spacemit { struct reset_ctl_bulk rsts; struct udevice *vpcie3v3; /* slot supply, if described */ u32 max_link_speed; /* 0: hardware default */ + u32 num_lanes; /* 0: hardware default */ }; static inline u32 spacemit_pcie_readl(struct pcie_dw_spacemit *pcie, u32 offset) @@ -93,6 +94,9 @@ static void pcie_dw_configure(struct pcie_dw_spacemit *pci) writew(lnkctl2, cap + PCI_EXP_LNKCTL2); } + /* Link width from "num-lanes"; without it, keep the hardware's */ + dw_pcie_link_set_max_link_width(&pci->dw, pci->num_lanes); + dw_pcie_dbi_write_enable(&pci->dw, false); } @@ -406,6 +410,8 @@ static int pcie_dw_spacemit_of_to_plat(struct udevice *dev) pcie->max_link_speed = 0; } + pcie->num_lanes = dev_read_u32_default(dev, "num-lanes", 0); + /* Derive port ID from DBI base address */ pcie->port_id = (dbi_addr - SPACEMIT_PCIE_DBI_BASE) / SPACEMIT_PCIE_DBI_STRIDE; -- 2.55.0
