summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2019-03-25 05:39:38 -0400
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-04-15 08:24:02 -0400
commitfbb2de891cc4d69c0c80c4116cf870a99235cfe8 (patch)
tree8350691cfa445dd87fd190f40ad52bc23a744a9b
parent40e5d614a0cdbf50dc3caa7eb10bd838edcb3ba5 (diff)
PCI: keystone: Add support to set the max link speed from DT
PCIe in TI's AM654 devices is by default configured to work in GEN3 mode. However PCIe does not work reliably in GEN3 mode because of SERDES configuration. Add support to set the link speed to GEN1, GEN2 or GEN3 based on "max-link-speed" DT property with GEN2 as the default speed if "max-link-speed" is absent. Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-rw-r--r--drivers/pci/controller/dwc/pci-keystone.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
index e4a816f53b8e..312fd0c49bbb 100644
--- a/drivers/pci/controller/dwc/pci-keystone.c
+++ b/drivers/pci/controller/dwc/pci-keystone.c
@@ -28,6 +28,7 @@
28#include <linux/resource.h> 28#include <linux/resource.h>
29#include <linux/signal.h> 29#include <linux/signal.h>
30 30
31#include "../../pci.h"
31#include "pcie-designware.h" 32#include "pcie-designware.h"
32 33
33#define PCIE_VENDORID_MASK 0xffff 34#define PCIE_VENDORID_MASK 0xffff
@@ -89,6 +90,8 @@
89#define LEG_EP 0x1 90#define LEG_EP 0x1
90#define RC 0x2 91#define RC 0x2
91 92
93#define EXP_CAP_ID_OFFSET 0x70
94
92#define KS_PCIE_SYSCLOCKOUTEN BIT(0) 95#define KS_PCIE_SYSCLOCKOUTEN BIT(0)
93 96
94#define AM654_PCIE_DEV_TYPE_MASK 0x3 97#define AM654_PCIE_DEV_TYPE_MASK 0x3
@@ -971,6 +974,31 @@ static int ks_pcie_am654_set_mode(struct device *dev)
971 return 0; 974 return 0;
972} 975}
973 976
977static void ks_pcie_set_link_speed(struct dw_pcie *pci, int link_speed)
978{
979 u32 val;
980
981 dw_pcie_dbi_ro_wr_en(pci);
982
983 val = dw_pcie_readl_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCAP);
984 if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) {
985 val &= ~((u32)PCI_EXP_LNKCAP_SLS);
986 val |= link_speed;
987 dw_pcie_writel_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCAP,
988 val);
989 }
990
991 val = dw_pcie_readl_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCTL2);
992 if ((val & PCI_EXP_LNKCAP_SLS) != link_speed) {
993 val &= ~((u32)PCI_EXP_LNKCAP_SLS);
994 val |= link_speed;
995 dw_pcie_writel_dbi(pci, EXP_CAP_ID_OFFSET + PCI_EXP_LNKCTL2,
996 val);
997 }
998
999 dw_pcie_dbi_ro_wr_dis(pci);
1000}
1001
974static const struct ks_pcie_of_data ks_pcie_rc_of_data = { 1002static const struct ks_pcie_of_data ks_pcie_rc_of_data = {
975 .host_ops = &ks_pcie_host_ops, 1003 .host_ops = &ks_pcie_host_ops,
976 .version = 0x365A, 1004 .version = 0x365A,
@@ -1011,6 +1039,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
1011 void __iomem *base; 1039 void __iomem *base;
1012 u32 num_viewport; 1040 u32 num_viewport;
1013 struct phy **phy; 1041 struct phy **phy;
1042 int link_speed;
1014 u32 num_lanes; 1043 u32 num_lanes;
1015 char name[10]; 1044 char name[10];
1016 int ret; 1045 int ret;
@@ -1165,6 +1194,12 @@ static int __init ks_pcie_probe(struct platform_device *pdev)
1165 gpiod_set_value_cansleep(gpiod, 1); 1194 gpiod_set_value_cansleep(gpiod, 1);
1166 } 1195 }
1167 1196
1197 link_speed = of_pci_get_max_link_speed(np);
1198 if (link_speed < 0)
1199 link_speed = 2;
1200
1201 ks_pcie_set_link_speed(pci, link_speed);
1202
1168 pci->pp.ops = host_ops; 1203 pci->pp.ops = host_ops;
1169 ret = ks_pcie_add_pcie_port(ks_pcie, pdev); 1204 ret = ks_pcie_add_pcie_port(ks_pcie, pdev);
1170 if (ret < 0) 1205 if (ret < 0)