aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLey Foon Tan <lftan@altera.com>2016-08-25 21:47:25 -0400
committerBjorn Helgaas <bhelgaas@google.com>2016-09-12 17:49:13 -0400
commitce4f1c7ad490aa7129bde5632d6e53943f8a866c (patch)
tree983786b7b3a1a332c0d20497f5cb23ff07ba10f0
parent31fc0ad47e2e0b8417616aa0f1ddcc67edf1e109 (diff)
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 <lftan@altera.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/pci/host/pcie-altera.c151
1 files changed, 91 insertions, 60 deletions
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index 34e6258992c1..4ca50a28af82 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -43,6 +43,7 @@
43#define RP_LTSSM_MASK 0x1f 43#define RP_LTSSM_MASK 0x1f
44#define LTSSM_L0 0xf 44#define LTSSM_L0 0xf
45 45
46#define PCIE_CAP_OFFSET 0x80
46/* TLP configuration type 0 and 1 */ 47/* TLP configuration type 0 and 1 */
47#define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ 48#define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
48#define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */ 49#define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
@@ -100,66 +101,6 @@ static bool altera_pcie_link_is_up(struct altera_pcie *pcie)
100 return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); 101 return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0);
101} 102}
102 103
103static 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
137static 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}
161DECLARE_PCI_FIXUP_EARLY(0x1172, PCI_ANY_ID, altera_pcie_retrain);
162
163/* 104/*
164 * Altera PCIe port uses BAR0 of RC's configuration space as the translation 105 * Altera PCIe port uses BAR0 of RC's configuration space as the translation
165 * from PCI bus to native BUS. Entire DDR region is mapped into PCIe space 106 * 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 = {
434 .write = altera_pcie_cfg_write, 375 .write = altera_pcie_cfg_write,
435}; 376};
436 377
378static 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
391static 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
399static 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
433static 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
437static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq, 462static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
438 irq_hw_number_t hwirq) 463 irq_hw_number_t hwirq)
439{ 464{
@@ -555,6 +580,11 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
555 return 0; 580 return 0;
556} 581}
557 582
583static void altera_pcie_host_init(struct altera_pcie *pcie)
584{
585 altera_pcie_retrain(pcie);
586}
587
558static int altera_pcie_probe(struct platform_device *pdev) 588static int altera_pcie_probe(struct platform_device *pdev)
559{ 589{
560 struct altera_pcie *pcie; 590 struct altera_pcie *pcie;
@@ -592,6 +622,7 @@ static int altera_pcie_probe(struct platform_device *pdev)
592 cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS); 622 cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
593 /* enable all interrupts */ 623 /* enable all interrupts */
594 cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE); 624 cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
625 altera_pcie_host_init(pcie);
595 626
596 bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops, 627 bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops,
597 pcie, &pcie->resources); 628 pcie, &pcie->resources);