|
43 | 43 | #define RP_LTSSM_MASK 0x1f |
44 | 44 | #define LTSSM_L0 0xf |
45 | 45 |
|
| 46 | +#define PCIE_CAP_OFFSET 0x80 |
46 | 47 | /* TLP configuration type 0 and 1 */ |
47 | 48 | #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */ |
48 | 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 | 101 | return !!((cra_readl(pcie, RP_LTSSM) & RP_LTSSM_MASK) == LTSSM_L0); |
101 | 102 | } |
102 | 103 |
|
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, ®16); |
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 | | - |
163 | 104 | /* |
164 | 105 | * Altera PCIe port uses BAR0 of RC's configuration space as the translation |
165 | 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 | 375 | .write = altera_pcie_cfg_write, |
435 | 376 | }; |
436 | 377 |
|
| 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, ®16); |
| 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 | + |
437 | 462 | static int altera_pcie_intx_map(struct irq_domain *domain, unsigned int irq, |
438 | 463 | irq_hw_number_t hwirq) |
439 | 464 | { |
@@ -555,6 +580,11 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie) |
555 | 580 | return 0; |
556 | 581 | } |
557 | 582 |
|
| 583 | +static void altera_pcie_host_init(struct altera_pcie *pcie) |
| 584 | +{ |
| 585 | + altera_pcie_retrain(pcie); |
| 586 | +} |
| 587 | + |
558 | 588 | static int altera_pcie_probe(struct platform_device *pdev) |
559 | 589 | { |
560 | 590 | struct altera_pcie *pcie; |
@@ -592,6 +622,7 @@ static int altera_pcie_probe(struct platform_device *pdev) |
592 | 622 | cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS); |
593 | 623 | /* enable all interrupts */ |
594 | 624 | cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE); |
| 625 | + altera_pcie_host_init(pcie); |
595 | 626 |
|
596 | 627 | bus = pci_scan_root_bus(&pdev->dev, pcie->root_bus_nr, &altera_pcie_ops, |
597 | 628 | pcie, &pcie->resources); |
|
0 commit comments