diff options
author | Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> | 2016-09-22 16:20:18 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-10-04 12:42:39 -0400 |
commit | b3327f7fae66daf918ce72214eb464e434193523 (patch) | |
tree | 473ae479ace16651fad8c8205fa5c0e7cda56ba9 | |
parent | f7bc63802d53139f7e6b62b222f2b26dca3f5e89 (diff) |
PCI: rcar: Try increasing PCIe link speed to 5 GT/s at boot
The PCIe link speed is initially set to 2.5 GT/s. Try to increase the link
speed to 5 GT/s.
Based on original patch by Grigory Kletsko
<grigory.kletsko@cogentembedded.com>.
[bhelgaas: remove "Trying speed up" message, remove unused SPCHG]
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 35aee9cf531f..6db53267dfbd 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -84,8 +84,18 @@ | |||
84 | #define IDSETR1 0x011004 | 84 | #define IDSETR1 0x011004 |
85 | #define TLCTLR 0x011048 | 85 | #define TLCTLR 0x011048 |
86 | #define MACSR 0x011054 | 86 | #define MACSR 0x011054 |
87 | #define SPCHGFIN (1 << 4) | ||
88 | #define SPCHGFAIL (1 << 6) | ||
89 | #define SPCHGSUC (1 << 7) | ||
90 | #define LINK_SPEED (0xf << 16) | ||
91 | #define LINK_SPEED_2_5GTS (1 << 16) | ||
92 | #define LINK_SPEED_5_0GTS (2 << 16) | ||
87 | #define MACCTLR 0x011058 | 93 | #define MACCTLR 0x011058 |
94 | #define SPEED_CHANGE (1 << 24) | ||
88 | #define SCRAMBLE_DISABLE (1 << 27) | 95 | #define SCRAMBLE_DISABLE (1 << 27) |
96 | #define MACS2R 0x011078 | ||
97 | #define MACCGSPSETR 0x011084 | ||
98 | #define SPCNGRSN (1 << 31) | ||
89 | 99 | ||
90 | /* R-Car H1 PHY */ | 100 | /* R-Car H1 PHY */ |
91 | #define H1_PCIEPHYADRR 0x04000c | 101 | #define H1_PCIEPHYADRR 0x04000c |
@@ -385,11 +395,67 @@ static int rcar_pcie_setup(struct list_head *resource, struct rcar_pcie *pci) | |||
385 | return 1; | 395 | return 1; |
386 | } | 396 | } |
387 | 397 | ||
398 | static void rcar_pcie_force_speedup(struct rcar_pcie *pcie) | ||
399 | { | ||
400 | unsigned int timeout = 1000; | ||
401 | u32 macsr; | ||
402 | |||
403 | if ((rcar_pci_read_reg(pcie, MACS2R) & LINK_SPEED) != LINK_SPEED_5_0GTS) | ||
404 | return; | ||
405 | |||
406 | if (rcar_pci_read_reg(pcie, MACCTLR) & SPEED_CHANGE) { | ||
407 | dev_err(pcie->dev, "Speed change already in progress\n"); | ||
408 | return; | ||
409 | } | ||
410 | |||
411 | macsr = rcar_pci_read_reg(pcie, MACSR); | ||
412 | if ((macsr & LINK_SPEED) == LINK_SPEED_5_0GTS) | ||
413 | goto done; | ||
414 | |||
415 | /* Set target link speed to 5.0 GT/s */ | ||
416 | rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS, | ||
417 | PCI_EXP_LNKSTA_CLS_5_0GB); | ||
418 | |||
419 | /* Set speed change reason as intentional factor */ | ||
420 | rcar_rmw32(pcie, MACCGSPSETR, SPCNGRSN, 0); | ||
421 | |||
422 | /* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */ | ||
423 | if (macsr & (SPCHGFIN | SPCHGSUC | SPCHGFAIL)) | ||
424 | rcar_pci_write_reg(pcie, macsr, MACSR); | ||
425 | |||
426 | /* Start link speed change */ | ||
427 | rcar_rmw32(pcie, MACCTLR, SPEED_CHANGE, SPEED_CHANGE); | ||
428 | |||
429 | while (timeout--) { | ||
430 | macsr = rcar_pci_read_reg(pcie, MACSR); | ||
431 | if (macsr & SPCHGFIN) { | ||
432 | /* Clear the interrupt bits */ | ||
433 | rcar_pci_write_reg(pcie, macsr, MACSR); | ||
434 | |||
435 | if (macsr & SPCHGFAIL) | ||
436 | dev_err(pcie->dev, "Speed change failed\n"); | ||
437 | |||
438 | goto done; | ||
439 | } | ||
440 | |||
441 | msleep(1); | ||
442 | }; | ||
443 | |||
444 | dev_err(pcie->dev, "Speed change timed out\n"); | ||
445 | |||
446 | done: | ||
447 | dev_info(pcie->dev, "Current link speed is %s GT/s\n", | ||
448 | (macsr & LINK_SPEED) == LINK_SPEED_5_0GTS ? "5" : "2.5"); | ||
449 | } | ||
450 | |||
388 | static int rcar_pcie_enable(struct rcar_pcie *pcie) | 451 | static int rcar_pcie_enable(struct rcar_pcie *pcie) |
389 | { | 452 | { |
390 | struct pci_bus *bus, *child; | 453 | struct pci_bus *bus, *child; |
391 | LIST_HEAD(res); | 454 | LIST_HEAD(res); |
392 | 455 | ||
456 | /* Try setting 5 GT/s link speed */ | ||
457 | rcar_pcie_force_speedup(pcie); | ||
458 | |||
393 | rcar_pcie_setup(&res, pcie); | 459 | rcar_pcie_setup(&res, pcie); |
394 | 460 | ||
395 | pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); | 461 | pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS); |