Skip to content

Commit ce4f1c7

Browse files
Ley Foon Tanbjorn-helgaas
authored andcommitted
PCI: altera: Move retrain from fixup to altera_pcie_host_init()
Previously we used a PCI early fixup to initiate a link retrain on Altera devices. But Altera PCIe IP can be configured as either a Root Port or an Endpoint, and they might have same vendor ID, so the fixup would be run for both. We only want to initiate a link retrain for Altera Root Port devices, not for Endpoints, so move the link retrain functionality from the fixup to altera_pcie_host_init(). [bhelgaas: changelog] Signed-off-by: Ley Foon Tan <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]>
1 parent 31fc0ad commit ce4f1c7

File tree

1 file changed

+91
-60
lines changed

1 file changed

+91
-60
lines changed

drivers/pci/host/pcie-altera.c

Lines changed: 91 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define RP_LTSSM_MASK 0x1f
4444
#define LTSSM_L0 0xf
4545

46+
#define PCIE_CAP_OFFSET 0x80
4647
/* TLP configuration type 0 and 1 */
4748
#define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
4849
#define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
@@ -100,66 +101,6 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
100101
return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
101102
}
102103

103-
static void altera_wait_link_retrain(struct pci_dev *dev)
104-
{
105-
u16 reg16;
106-
unsigned long start_jiffies;
107-
struct altera_pcie *pcie = dev->bus->sysdata;
108-
109-
/* Wait for link training end. */
110-
start_jiffies = jiffies;
111-
for (;;) {
112-
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &reg16);
113-
if (!(reg16 & PCI_EXP_LNKSTA_LT))
114-
break;
115-
116-
if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
117-
dev_err(&pcie->pdev->dev, "link retrain timeout\n");
118-
break;
119-
}
120-
udelay(100);
121-
}
122-
123-
/* Wait for link is up */
124-
start_jiffies = jiffies;
125-
for (;;) {
126-
if (altera_pcie_link_is_up(pcie))
127-
break;
128-
129-
if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
130-
dev_err(&pcie->pdev->dev, "link up timeout\n");
131-
break;
132-
}
133-
udelay(100);
134-
}
135-
}
136-
137-
static void altera_pcie_retrain(struct pci_dev *dev)
138-
{
139-
u16 linkcap, linkstat;
140-
struct altera_pcie *pcie = dev->bus->sysdata;
141-
142-
if (!altera_pcie_link_is_up(pcie))
143-
return;
144-
145-
/*
146-
* Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
147-
* current speed is 2.5 GB/s.
148-
*/
149-
pcie_capability_read_word(dev, PCI_EXP_LNKCAP, &linkcap);
150-
151-
if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
152-
return;
153-
154-
pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &linkstat);
155-
if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
156-
pcie_capability_set_word(dev, PCI_EXP_LNKCTL,
157-
PCI_EXP_LNKCTL_RL);
158-
altera_wait_link_retrain(dev);
159-
}
160-
}
161-
DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
162-
163104
/*
164105
* Altera PCIe port uses BAR0 of RC's configuration space as the translation
165106
* from PCI bus to native BUS. Entire DDR region is mapped into PCIe space
@@ -434,6 +375,90 @@ static struct pci_ops altera_pcie_ops = {
434375
.write = altera_pcie_cfg_write,
435376
};
436377

378+
static int altera_read_cap_word(struct altera_pcie *pcie, u8 busno,
379+
unsigned int devfn, int offset, u16 *value)
380+
{
381+
u32 data;
382+
int ret;
383+
384+
ret = _altera_pcie_cfg_read(pcie, busno, devfn,
385+
PCIE_CAP_OFFSET + offset, sizeof(*value),
386+
&data);
387+
*value = data;
388+
return ret;
389+
}
390+
391+
static int altera_write_cap_word(struct altera_pcie *pcie, u8 busno,
392+
unsigned int devfn, int offset, u16 value)
393+
{
394+
return _altera_pcie_cfg_write(pcie, busno, devfn,
395+
PCIE_CAP_OFFSET + offset, sizeof(value),
396+
value);
397+
}
398+
399+
static void altera_wait_link_retrain(struct altera_pcie *pcie)
400+
{
401+
u16 reg16;
402+
unsigned long start_jiffies;
403+
404+
/* Wait for link training end. */
405+
start_jiffies = jiffies;
406+
for (;;) {
407+
altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
408+
PCI_EXP_LNKSTA, &reg16);
409+
if (!(reg16 & PCI_EXP_LNKSTA_LT))
410+
break;
411+
412+
if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) {
413+
dev_err(&pcie->pdev->dev, "link retrain timeout\n");
414+
break;
415+
}
416+
udelay(100);
417+
}
418+
419+
/* Wait for link is up */
420+
start_jiffies = jiffies;
421+
for (;;) {
422+
if (altera_pcie_link_is_up(pcie))
423+
break;
424+
425+
if (time_after(jiffies, start_jiffies + LINK_UP_TIMEOUT)) {
426+
dev_err(&pcie->pdev->dev, "link up timeout\n");
427+
break;
428+
}
429+
udelay(100);
430+
}
431+
}
432+
433+
static void altera_pcie_retrain(struct altera_pcie *pcie)
434+
{
435+
u16 linkcap, linkstat, linkctl;
436+
437+
if (!altera_pcie_link_is_up(pcie))
438+
return;
439+
440+
/*
441+
* Set the retrain bit if the PCIe rootport support > 2.5GB/s, but
442+
* current speed is 2.5 GB/s.
443+
*/
444+
altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKCAP,
445+
&linkcap);
446+
if ((linkcap & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB)
447+
return;
448+
449+
altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN, PCI_EXP_LNKSTA,
450+
&linkstat);
451+
if ((linkstat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) {
452+
altera_read_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
453+
PCI_EXP_LNKCTL, &linkctl);
454+
linkctl |= PCI_EXP_LNKCTL_RL;
455+
altera_write_cap_word(pcie, pcie->root_bus_nr, RP_DEVFN,
456+
PCI_EXP_LNKCTL, linkctl);
457+
458+
altera_wait_link_retrain(pcie);
459+
}
460+
}
461+
437462
static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
438463
irq_hw_number_t hwirq)
439464
{
@@ -555,6 +580,11 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
555580
return 0;
556581
}
557582

583+
static void altera_pcie_host_init(struct altera_pcie *pcie)
584+
{
585+
altera_pcie_retrain(pcie);
586+
}
587+
558588
static int altera_pcie_probe(struct platform_device *pdev)
559589
{
560590
struct altera_pcie *pcie;
@@ -592,6 +622,7 @@ static int altera_pcie_probe(struct platform_device *pdev)
592622
cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
593623
/* enable all interrupts */
594624
cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
625+
altera_pcie_host_init(pcie);
595626

596627
bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
597628
pcie, &pcie->resources);

0 commit comments

Comments
 (0)