pcie-rcar: try setting PCIe speed to 5 GT/s at boot
Subsystems (2)
PATCH v2 1/1 pcie-rcar: try setting PCIe speed to 5 GT/s at boot
Initially, the PCIe link speed is set up only at 2.5 GT/s. For better performance, we're trying to increase link speed to 5 GT/s.
Based on the original patch by Grigory Kletsko
<[email protected]>.
---
The patch is against the 'next' branch of Bjorn Helgaas' 'pci.git' repo.
Changes in version 2:
- switched from the interrupt based speed change algorithm to polling with 1-second timeout, got rid of the now unneeded register/bit #define's;
- made rcar_pcie_force_speedup() *static*;
- moved the speed capability check to the start of rcar_pcie_force_speedup();
- adjusted the speed change in-progress check and the error message;
- read MACSR ony once during the speed change setup;
- print current link speed after any speed change outcome and when the speed is already 5 GT/s;
- removed the TODO comment;
- moved rcar_pcie_force_speedup() call to the start of rcar_pcie_enable();
- changed the patch authorship, updated the patch description accordingly.
drivers/pci/host/pcie-rcar.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)
drivers/pci/host/pcie-rcar.c +70 -0
@@ -84,8 +84,19 @@#define IDSETR1 0x011004#define TLCTLR 0x011048#define MACSR 0x011054 +#define SPCHG (1 << 5) +#define SPCHGFIN (1 << 4) +#define SPCHGSUC (1 << 7) +#define SPCHGFAIL (1 << 6) +#define LINK_SPEED (0xf << 16) +#define LINK_SPEED_2_5GTS (1 << 16) +#define LINK_SPEED_5_0GTS (2 << 16)#define MACCTLR 0x011058 +#define SPEED_CHANGE (1 << 24)#define SCRAMBLE_DISABLE (1 << 27) +#define MACS2R 0x011078 +#define MACCGSPSETR 0x011084 +#define SPCNGRSN (1 << 31)/* R-Car H1 PHY */ #define H1_PCIEPHYADRR 0x04000c
@@ -385,11 +396,70 @@ static int rcar_pcie_setup(struct list_hreturn 1 ; } +static void rcar_pcie_force_speedup (struct rcar_pcie *pcie) +{ +unsigned int timeout =1000 ; +u32 macsr; + +if ((rcar_pci_read_reg (pcie,MACS2R ) &LINK_SPEED ) !=LINK_SPEED_5_0GTS ) +return ; + +dev_info (pcie->dev,"Trying speed up to 5 GT/s\n" ); + +if (rcar_pci_read_reg (pcie,MACCTLR ) &SPEED_CHANGE ) { +dev_err (pcie->dev,"Speed change is in progress\n" ); +return ; + } + + macsr =rcar_pci_read_reg (pcie,MACSR ); +if ((macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ) + goto done; + +/* Set target link speed to 5.0 GT/s */ +rcar_rmw32 (pcie,EXPCAP (12 ),PCI_EXP_LNKSTA_CLS , +PCI_EXP_LNKSTA_CLS_5_0GB ); + +/* Set speed change reason as intentional factor */ +rcar_rmw32 (pcie,MACCGSPSETR ,SPCNGRSN ,0 ); + +/* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */ +if (macsr & (SPCHGFIN |SPCHGSUC |SPCHGFAIL )) +rcar_pci_write_reg (pcie, macsr,MACSR ); + +/* Start link speed change */ +rcar_rmw32 (pcie,MACCTLR ,SPEED_CHANGE ,SPEED_CHANGE ); + +while (timeout--) { + macsr =rcar_pci_read_reg (pcie,MACSR ); +if (macsr &SPCHGFIN ) { +/* Clear the interrupt bits */ +rcar_pci_write_reg (pcie, macsr,MACSR ); + +if (macsr &SPCHGFAIL ) +dev_err (pcie->dev,"Speed change failed\n" ); + + goto done; + } + +msleep (1 ); + }; + +dev_err (pcie->dev,"Speed change timed out\n" ); + +done: +/* Check speed */ +dev_info (pcie->dev,"Current link speed is %s GT/s\n" , + (macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ?"5" :"2.5" ); +} +static int rcar_pcie_enable (struct rcar_pcie *pcie) {struct pci_bus *bus, *child;LIST_HEAD (res); +/* Try setting 5 GT/s link speed */ +rcar_pcie_force_speedup (pcie); +rcar_pcie_setup (&res, pcie);pci_add_flags (PCI_REASSIGN_ALL_RSRC |PCI_REASSIGN_ALL_BUS );
Quoted 10 lines · Sergei Shtylyov
Initially, the PCIe link speed is set up only at 2.5 GT/s. For better performance, we're trying to increase link speed to 5 GT/s.
Based on the original patch by Grigory Kletsko
<[email protected]>.Signed-off-by Sergei Shtylyov <[email protected]>---
The patch is against the 'next' branch of Bjorn Helgaas' 'pci.git' repo.
Minor comment below, that not withstanding.
Quoted 44 lines
Changes in version 2:
- switched from the interrupt based speed change algorithm to polling with 1-second timeout, got rid of the now unneeded register/bit #define's;
- madercar_pcie_force_speedup()*static*;
- moved the speed capability check to the start ofrcar_pcie_force_speedup();
- adjusted the speed change in-progress check and the error message;
- read MACSR ony once during the speed change setup;
- print current link speed after any speed change outcome and when the speed is already 5 GT/s;
- removed the TODO comment;
- movedrcar_pcie_force_speedup()call to the start ofrcar_pcie_enable();
- changed the patch authorship, updated the patch description accordingly.drivers/pci/host/pcie-rcar.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)Index:
pci/drivers/pci/host/pcie-rcar.c
===================================================================drivers/pci/host/pcie-rcar.c +11
-0@@ -84,8 +84,19 @@#define IDSETR1 0x011004#define TLCTLR 0x011048#define MACSR 0x011054 +#define SPCHG (1 << 5) +#define SPCHGFIN (1 << 4) +#define SPCHGSUC (1 << 7) +#define SPCHGFAIL (1 << 6) +#define LINK_SPEED (0xf << 16) +#define LINK_SPEED_2_5GTS (1 << 16) +#define LINK_SPEED_5_0GTS (2 << 16)#define MACCTLR 0x011058 +#define SPEED_CHANGE (1 << 24)#define SCRAMBLE_DISABLE (1 << 27) +#define MACS2R 0x011078 +#define MACCGSPSETR 0x011084 +#define SPCNGRSN (1 << 31)/* R-Car H1 PHY */ #define H1_PCIEPHYADRR 0x04000c@@ -385,11 +396,70 @@ static int rcar_pcie_setup(struct list_hreturn 1 ; }
drivers/pci/host/pcie-rcar.c static int rcar_pcie_setup(struct list_h · line 407
Quoted 10 lines
drivers/pci/host/pcie-rcar.c +9
-0+static void rcar_pcie_force_speedup (struct rcar_pcie *pcie) +{ +unsigned int timeout =1000 ; +u32 macsr; + +if ((rcar_pci_read_reg (pcie,MACS2R ) &LINK_SPEED ) !=LINK_SPEED_5_0GTS ) +return ; + +dev_info (pcie->dev,"Trying speed up to 5 GT/s\n" );
The above is a little too noisy for my taste.
Quoted 59 lines
drivers/pci/host/pcie-rcar.c +50
-0+ +if (rcar_pci_read_reg (pcie,MACCTLR ) &SPEED_CHANGE ) { +dev_err (pcie->dev,"Speed change is in progress\n" ); +return ; + } + + macsr =rcar_pci_read_reg (pcie,MACSR ); +if ((macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ) + goto done; + +/* Set target link speed to 5.0 GT/s */ +rcar_rmw32 (pcie,EXPCAP (12 ),PCI_EXP_LNKSTA_CLS , +PCI_EXP_LNKSTA_CLS_5_0GB ); + +/* Set speed change reason as intentional factor */ +rcar_rmw32 (pcie,MACCGSPSETR ,SPCNGRSN ,0 ); + +/* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */ +if (macsr & (SPCHGFIN |SPCHGSUC |SPCHGFAIL )) +rcar_pci_write_reg (pcie, macsr,MACSR ); + +/* Start link speed change */ +rcar_rmw32 (pcie,MACCTLR ,SPEED_CHANGE ,SPEED_CHANGE ); + +while (timeout--) { + macsr =rcar_pci_read_reg (pcie,MACSR ); +if (macsr &SPCHGFIN ) { +/* Clear the interrupt bits */ +rcar_pci_write_reg (pcie, macsr,MACSR ); + +if (macsr &SPCHGFAIL ) +dev_err (pcie->dev,"Speed change failed\n" ); + + goto done; + } + +msleep (1 ); + }; + +dev_err (pcie->dev,"Speed change timed out\n" ); + +done: +/* Check speed */ +dev_info (pcie->dev,"Current link speed is %s GT/s\n" , + (macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ?"5" :"2.5" ); +} +static int rcar_pcie_enable (struct rcar_pcie *pcie) {struct pci_bus *bus, *child;LIST_HEAD (res); +/* Try setting 5 GT/s link speed */ +rcar_pcie_force_speedup (pcie); +rcar_pcie_setup (&res, pcie);pci_add_flags (PCI_REASSIGN_ALL_RSRC |PCI_REASSIGN_ALL_BUS );
Quoted 6 lines · Simon Horman
Quoted 6 lines
Initially, the PCIe link speed is set up only at 2.5 GT/s. For better performance, we're trying to increase link speed to 5 GT/s.
Based on the original patch by Grigory Kletsko
<[email protected]>.
Quoted 8 lines
Quoted 4 lines
Signed-off-by Sergei Shtylyov <[email protected]>---
The patch is against the 'next' branch of Bjorn Helgaas' 'pci.git' repo.Minor comment below, that not withstanding.
Acked-by Simon Horman <[email protected]>
Bjorn, we expected this to be merged to 4.9-rc1, is that still possible?
MBR, Sergei
Quoted 7 lines · Sergei Shtylyov
Initially, the PCIe link speed is set up only at 2.5 GT/s. For better performance, we're trying to increase link speed to 5 GT/s.
Based on the original patch by Grigory Kletsko
<[email protected]>.Signed-off-by Sergei Shtylyov <[email protected]>
I addressed Simon's comment for you, added his ack, and applied this to pci/host-rcar for v4.9.
Quoted 119 lines
---
The patch is against the 'next' branch of Bjorn Helgaas' 'pci.git' repo.Changes in version 2:
- switched from the interrupt based speed change algorithm to polling with 1-second timeout, got rid of the now unneeded register/bit #define's;
- madercar_pcie_force_speedup()*static*;
- moved the speed capability check to the start ofrcar_pcie_force_speedup();
- adjusted the speed change in-progress check and the error message;
- read MACSR ony once during the speed change setup;
- print current link speed after any speed change outcome and when the speed is already 5 GT/s;
- removed the TODO comment;
- movedrcar_pcie_force_speedup()call to the start ofrcar_pcie_enable();
- changed the patch authorship, updated the patch description accordingly.drivers/pci/host/pcie-rcar.c | 70 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+)Index:
pci/drivers/pci/host/pcie-rcar.c
===================================================================drivers/pci/host/pcie-rcar.c +70
-1@@ -84,8 +84,19 @@#define IDSETR1 0x011004#define TLCTLR 0x011048#define MACSR 0x011054 +#define SPCHG (1 << 5) +#define SPCHGFIN (1 << 4) +#define SPCHGSUC (1 << 7) +#define SPCHGFAIL (1 << 6) +#define LINK_SPEED (0xf << 16) +#define LINK_SPEED_2_5GTS (1 << 16) +#define LINK_SPEED_5_0GTS (2 << 16)#define MACCTLR 0x011058 +#define SPEED_CHANGE (1 << 24)#define SCRAMBLE_DISABLE (1 << 27) +#define MACS2R 0x011078 +#define MACCGSPSETR 0x011084 +#define SPCNGRSN (1 << 31)/* R-Car H1 PHY */ #define H1_PCIEPHYADRR 0x04000c@@ -385,11 +396,70 @@ static int rcar_pcie_setup(struct list_hreturn 1 ; } +static void rcar_pcie_force_speedup (struct rcar_pcie *pcie) +{ +unsigned int timeout =1000 ; +u32 macsr; + +if ((rcar_pci_read_reg (pcie,MACS2R ) &LINK_SPEED ) !=LINK_SPEED_5_0GTS ) +return ; + +dev_info (pcie->dev,"Trying speed up to 5 GT/s\n" ); + +if (rcar_pci_read_reg (pcie,MACCTLR ) &SPEED_CHANGE ) { +dev_err (pcie->dev,"Speed change is in progress\n" ); +return ; + } + + macsr =rcar_pci_read_reg (pcie,MACSR ); +if ((macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ) + goto done; + +/* Set target link speed to 5.0 GT/s */ +rcar_rmw32 (pcie,EXPCAP (12 ),PCI_EXP_LNKSTA_CLS , +PCI_EXP_LNKSTA_CLS_5_0GB ); + +/* Set speed change reason as intentional factor */ +rcar_rmw32 (pcie,MACCGSPSETR ,SPCNGRSN ,0 ); + +/* Clear SPCHGFIN, SPCHGSUC, and SPCHGFAIL */ +if (macsr & (SPCHGFIN |SPCHGSUC |SPCHGFAIL )) +rcar_pci_write_reg (pcie, macsr,MACSR ); + +/* Start link speed change */ +rcar_rmw32 (pcie,MACCTLR ,SPEED_CHANGE ,SPEED_CHANGE ); + +while (timeout--) { + macsr =rcar_pci_read_reg (pcie,MACSR ); +if (macsr &SPCHGFIN ) { +/* Clear the interrupt bits */ +rcar_pci_write_reg (pcie, macsr,MACSR ); + +if (macsr &SPCHGFAIL ) +dev_err (pcie->dev,"Speed change failed\n" ); + + goto done; + } + +msleep (1 ); + }; + +dev_err (pcie->dev,"Speed change timed out\n" ); + +done: +/* Check speed */ +dev_info (pcie->dev,"Current link speed is %s GT/s\n" , + (macsr &LINK_SPEED ) ==LINK_SPEED_5_0GTS ?"5" :"2.5" ); +} +static int rcar_pcie_enable (struct rcar_pcie *pcie) {struct pci_bus *bus, *child;LIST_HEAD (res); +/* Try setting 5 GT/s link speed */ +rcar_pcie_force_speedup (pcie); +rcar_pcie_setup (&res, pcie);pci_add_flags (PCI_REASSIGN_ALL_RSRC |PCI_REASSIGN_ALL_BUS ); --To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 10 lines · Bjorn Helgaas
Quoted 7 lines
Initially, the PCIe link speed is set up only at 2.5 GT/s. For better performance, we're trying to increase link speed to 5 GT/s.
Based on the original patch by Grigory Kletsko
<[email protected]>.Signed-off-by Sergei Shtylyov <[email protected]>I addressed Simon's comment for you, added his ack, and applied this to pci/host-rcar for v4.9.
Thank you!
MBR, Sergei