Skip to content

Commit

Permalink
PCI: apple: Configure link speeds properly
Browse files Browse the repository at this point in the history
This sets the maximum link speed from the devicetree. Otherwise, by
default the controller will always attempt to train at Gen4.

Signed-off-by: Hector Martin <marcan@marcan.st>
  • Loading branch information
marcan committed Dec 2, 2021
1 parent ec9e016 commit 1dcce99
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions drivers/pci/controller/pcie-apple.c
Expand Up @@ -30,6 +30,8 @@
#include <linux/of_irq.h>
#include <linux/pci-ecam.h>

#include "../pci.h"

#define CORE_RC_PHYIF_CTL 0x00024
#define CORE_RC_PHYIF_CTL_RUN BIT(0)
#define CORE_RC_PHYIF_STAT 0x00028
Expand Down Expand Up @@ -130,9 +132,13 @@
*/
#define DOORBELL_ADDR CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR

/* The offset of the PCIe capabilities structure in bridge config space */
#define PCIE_CAP_BASE 0x70

struct apple_pcie {
struct mutex lock;
struct device *dev;
struct pci_config_window *cfg;
void __iomem *base;
struct irq_domain *domain;
unsigned long *bitmap;
Expand Down Expand Up @@ -507,6 +513,33 @@ static u32 apple_pcie_rid2sid_write(struct apple_pcie_port *port,
return readl_relaxed(port->base + PORT_RID2SID(idx));
}

static inline void __iomem *bridge_reg(struct apple_pcie_port *port,
int where)
{
struct pci_config_window *cfg = port->pcie->cfg;

return cfg->win + PCIE_ECAM_OFFSET(0, PCI_DEVFN(port->idx, 0), where);
}

static int apple_pcie_link_configure_max_speed(struct apple_pcie_port *port)
{
int max_gen;
u32 ctrl2;

max_gen = of_pci_get_max_link_speed(port->np);
if (max_gen < 0) {
dev_err(port->pcie->dev, "max link speed not specified\n");
return max_gen;
}

ctrl2 = readw_relaxed(bridge_reg(port, PCIE_CAP_BASE + PCI_EXP_LNKCTL2));
ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
ctrl2 |= FIELD_PREP(PCI_EXP_LNKCTL2_TLS, max_gen);
writew_relaxed(ctrl2, bridge_reg(port, PCIE_CAP_BASE + PCI_EXP_LNKCTL2));

return 0;
}

static int apple_pcie_setup_port(struct apple_pcie *pcie,
struct device_node *np)
{
Expand Down Expand Up @@ -588,6 +621,8 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie,
ret = apple_pcie_port_register_irqs(port);
WARN_ON(ret);

apple_pcie_link_configure_max_speed(port);

writel_relaxed(PORT_LTSSMCTL_START, port->base + PORT_LTSSMCTL);

if (!wait_for_completion_timeout(&pcie->event, HZ / 10))
Expand Down Expand Up @@ -773,6 +808,7 @@ static int apple_pcie_init(struct pci_config_window *cfg)
return -ENOMEM;

pcie->dev = dev;
pcie->cfg = cfg;

mutex_init(&pcie->lock);

Expand Down

0 comments on commit 1dcce99

Please sign in to comment.