On Thursday 24 February 2022 18:08:00 Bjorn Helgaas wrote: > On Tue, Feb 22, 2022 at 04:50:23PM +0100, Pali Rohár wrote: > > If x1/x4 mode is not set correctly then link with endpoint card is not > > established. > > > > Use DTS property 'num-lanes' to deteriminate x1/x4 mode. > > I know this is already merged, but if tweaking for any other reason, > s/deteriminate/determine/ > > > + * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link > > + * Capability register. This register is defined by PCIe specification > > + * as read-only but this mvebu controller has it as read-write and must > > + * be set to number of SerDes PCIe lanes (1 or 4). If this register is > > + * not set correctly then link with endpoint card is not established. > > True, everything in Link Capability is RO or HwInit, but that's for > the architected access via config space. I think a device-specific > mechanism like this is fair game as long as you do it before anybody > can read it via config space. Maybe I was not clear and explicit in above comment, but this register sets number of PCIe lanes which HW will use. Armada PCIe controllers supports only x1 and x4. Sometimes default HW value is 4 for x1 HW and sometimes default value for x4 HW is 1. First case cause that link never comes up (HW is trying to setup 4 lanes but in reality there is only one, so link training never finish) and second case cause degraded performance (x4 link is established only in x1 mode as HW is via this register instructed to ignores other 3 lanes). So basically HW designers misused this Link Capability register for configuring PCIe Link of PCIe Root Port. > > + */ > > + lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP); > > + lnkcap &= ~PCI_EXP_LNKCAP_MLW; > > + lnkcap |= (port->is_x4 ? 4 : 1) << 4; > > + mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);