diff options
| -rw-r--r-- | drivers/pci/controller/dwc/Kconfig | 27 | ||||
| -rw-r--r-- | drivers/pci/controller/dwc/pci-keystone.c | 250 |
2 files changed, 240 insertions, 37 deletions
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index d1d00833e0b3..a6ce1ee51b4c 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig | |||
| @@ -103,15 +103,32 @@ config PCIE_SPEAR13XX | |||
| 103 | Say Y here if you want PCIe support on SPEAr13XX SoCs. | 103 | Say Y here if you want PCIe support on SPEAr13XX SoCs. |
| 104 | 104 | ||
| 105 | config PCI_KEYSTONE | 105 | config PCI_KEYSTONE |
| 106 | bool "TI Keystone PCIe controller" | 106 | bool |
| 107 | |||
| 108 | config PCI_KEYSTONE_HOST | ||
| 109 | bool "PCI Keystone Host Mode" | ||
| 107 | depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) | 110 | depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) |
| 108 | depends on PCI_MSI_IRQ_DOMAIN | 111 | depends on PCI_MSI_IRQ_DOMAIN |
| 109 | select PCIE_DW_HOST | 112 | select PCIE_DW_HOST |
| 113 | select PCI_KEYSTONE | ||
| 114 | default y | ||
| 110 | help | 115 | help |
| 111 | Say Y here if you want to enable PCI controller support on Keystone | 116 | Enables support for the PCIe controller in the Keystone SoC to |
| 112 | SoCs. The PCI controller on Keystone is based on DesignWare hardware | 117 | work in host mode. The PCI controller on Keystone is based on |
| 113 | and therefore the driver re-uses the DesignWare core functions to | 118 | DesignWare hardware and therefore the driver re-uses the |
| 114 | implement the driver. | 119 | DesignWare core functions to implement the driver. |
| 120 | |||
| 121 | config PCI_KEYSTONE_EP | ||
| 122 | bool "PCI Keystone Endpoint Mode" | ||
| 123 | depends on ARCH_KEYSTONE || ARCH_K3 || ((ARM || ARM64) && COMPILE_TEST) | ||
| 124 | depends on PCI_ENDPOINT | ||
| 125 | select PCIE_DW_EP | ||
| 126 | select PCI_KEYSTONE | ||
| 127 | help | ||
| 128 | Enables support for the PCIe controller in the Keystone SoC to | ||
| 129 | work in endpoint mode. The PCI controller on Keystone is based | ||
| 130 | on DesignWare hardware and therefore the driver re-uses the | ||
| 131 | DesignWare core functions to implement the driver. | ||
| 115 | 132 | ||
| 116 | config PCI_LAYERSCAPE | 133 | config PCI_LAYERSCAPE |
| 117 | bool "Freescale Layerscape PCIe controller" | 134 | bool "Freescale Layerscape PCIe controller" |
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c index 312fd0c49bbb..af677254a072 100644 --- a/drivers/pci/controller/dwc/pci-keystone.c +++ b/drivers/pci/controller/dwc/pci-keystone.c | |||
| @@ -52,6 +52,12 @@ | |||
| 52 | #define OB_ENABLEN BIT(0) | 52 | #define OB_ENABLEN BIT(0) |
| 53 | #define OB_WIN_SIZE 8 /* 8MB */ | 53 | #define OB_WIN_SIZE 8 /* 8MB */ |
| 54 | 54 | ||
| 55 | #define PCIE_LEGACY_IRQ_ENABLE_SET(n) (0x188 + (0x10 * ((n) - 1))) | ||
| 56 | #define PCIE_LEGACY_IRQ_ENABLE_CLR(n) (0x18c + (0x10 * ((n) - 1))) | ||
| 57 | #define PCIE_EP_IRQ_SET 0x64 | ||
| 58 | #define PCIE_EP_IRQ_CLR 0x68 | ||
| 59 | #define INT_ENABLE BIT(0) | ||
| 60 | |||
| 55 | /* IRQ register defines */ | 61 | /* IRQ register defines */ |
| 56 | #define IRQ_EOI 0x050 | 62 | #define IRQ_EOI 0x050 |
| 57 | 63 | ||
| @@ -95,11 +101,16 @@ | |||
| 95 | #define KS_PCIE_SYSCLOCKOUTEN BIT(0) | 101 | #define KS_PCIE_SYSCLOCKOUTEN BIT(0) |
| 96 | 102 | ||
| 97 | #define AM654_PCIE_DEV_TYPE_MASK 0x3 | 103 | #define AM654_PCIE_DEV_TYPE_MASK 0x3 |
| 104 | #define AM654_WIN_SIZE SZ_64K | ||
| 105 | |||
| 106 | #define APP_ADDR_SPACE_0 (16 * SZ_1K) | ||
| 98 | 107 | ||
| 99 | #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) | 108 | #define to_keystone_pcie(x) dev_get_drvdata((x)->dev) |
| 100 | 109 | ||
| 101 | struct ks_pcie_of_data { | 110 | struct ks_pcie_of_data { |
| 111 | enum dw_pcie_device_mode mode; | ||
| 102 | const struct dw_pcie_host_ops *host_ops; | 112 | const struct dw_pcie_host_ops *host_ops; |
| 113 | const struct dw_pcie_ep_ops *ep_ops; | ||
| 103 | unsigned int version; | 114 | unsigned int version; |
| 104 | }; | 115 | }; |
| 105 | 116 | ||
| @@ -264,13 +275,11 @@ static void ks_pcie_handle_legacy_irq(struct keystone_pcie *ks_pcie, | |||
| 264 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset); | 275 | ks_pcie_app_writel(ks_pcie, IRQ_EOI, offset); |
| 265 | } | 276 | } |
| 266 | 277 | ||
| 278 | /* | ||
| 279 | * Dummy function so that DW core doesn't configure MSI | ||
| 280 | */ | ||
| 267 | static int ks_pcie_am654_msi_host_init(struct pcie_port *pp) | 281 | static int ks_pcie_am654_msi_host_init(struct pcie_port *pp) |
| 268 | { | 282 | { |
| 269 | struct dw_pcie *pci = to_dw_pcie_from_pp(pp); | ||
| 270 | struct device *dev = pci->dev; | ||
| 271 | |||
| 272 | dev_vdbg(dev, "dummy function so that DW core doesn't configure MSI\n"); | ||
| 273 | |||
| 274 | return 0; | 283 | return 0; |
| 275 | } | 284 | } |
| 276 | 285 | ||
| @@ -877,12 +886,139 @@ static int __init ks_pcie_add_pcie_port(struct keystone_pcie *ks_pcie, | |||
| 877 | return 0; | 886 | return 0; |
| 878 | } | 887 | } |
| 879 | 888 | ||
| 889 | static u32 ks_pcie_am654_read_dbi2(struct dw_pcie *pci, void __iomem *base, | ||
| 890 | u32 reg, size_t size) | ||
| 891 | { | ||
| 892 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 893 | u32 val; | ||
| 894 | |||
| 895 | ks_pcie_set_dbi_mode(ks_pcie); | ||
| 896 | dw_pcie_read(base + reg, size, &val); | ||
| 897 | ks_pcie_clear_dbi_mode(ks_pcie); | ||
| 898 | return val; | ||
| 899 | } | ||
| 900 | |||
| 901 | static void ks_pcie_am654_write_dbi2(struct dw_pcie *pci, void __iomem *base, | ||
| 902 | u32 reg, size_t size, u32 val) | ||
| 903 | { | ||
| 904 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 905 | |||
| 906 | ks_pcie_set_dbi_mode(ks_pcie); | ||
| 907 | dw_pcie_write(base + reg, size, val); | ||
| 908 | ks_pcie_clear_dbi_mode(ks_pcie); | ||
| 909 | } | ||
| 910 | |||
| 880 | static const struct dw_pcie_ops ks_pcie_dw_pcie_ops = { | 911 | static const struct dw_pcie_ops ks_pcie_dw_pcie_ops = { |
| 881 | .start_link = ks_pcie_start_link, | 912 | .start_link = ks_pcie_start_link, |
| 882 | .stop_link = ks_pcie_stop_link, | 913 | .stop_link = ks_pcie_stop_link, |
| 883 | .link_up = ks_pcie_link_up, | 914 | .link_up = ks_pcie_link_up, |
| 915 | .read_dbi2 = ks_pcie_am654_read_dbi2, | ||
| 916 | .write_dbi2 = ks_pcie_am654_write_dbi2, | ||
| 917 | }; | ||
| 918 | |||
| 919 | static void ks_pcie_am654_ep_init(struct dw_pcie_ep *ep) | ||
| 920 | { | ||
| 921 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 922 | int flags; | ||
| 923 | |||
| 924 | ep->page_size = AM654_WIN_SIZE; | ||
| 925 | flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32; | ||
| 926 | dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, APP_ADDR_SPACE_0 - 1); | ||
| 927 | dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, flags); | ||
| 928 | } | ||
| 929 | |||
| 930 | static void ks_pcie_am654_raise_legacy_irq(struct keystone_pcie *ks_pcie) | ||
| 931 | { | ||
| 932 | struct dw_pcie *pci = ks_pcie->pci; | ||
| 933 | u8 int_pin; | ||
| 934 | |||
| 935 | int_pin = dw_pcie_readb_dbi(pci, PCI_INTERRUPT_PIN); | ||
| 936 | if (int_pin == 0 || int_pin > 4) | ||
| 937 | return; | ||
| 938 | |||
| 939 | ks_pcie_app_writel(ks_pcie, PCIE_LEGACY_IRQ_ENABLE_SET(int_pin), | ||
| 940 | INT_ENABLE); | ||
| 941 | ks_pcie_app_writel(ks_pcie, PCIE_EP_IRQ_SET, INT_ENABLE); | ||
| 942 | mdelay(1); | ||
| 943 | ks_pcie_app_writel(ks_pcie, PCIE_EP_IRQ_CLR, INT_ENABLE); | ||
| 944 | ks_pcie_app_writel(ks_pcie, PCIE_LEGACY_IRQ_ENABLE_CLR(int_pin), | ||
| 945 | INT_ENABLE); | ||
| 946 | } | ||
| 947 | |||
| 948 | static int ks_pcie_am654_raise_irq(struct dw_pcie_ep *ep, u8 func_no, | ||
| 949 | enum pci_epc_irq_type type, | ||
| 950 | u16 interrupt_num) | ||
| 951 | { | ||
| 952 | struct dw_pcie *pci = to_dw_pcie_from_ep(ep); | ||
| 953 | struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
| 954 | |||
| 955 | switch (type) { | ||
| 956 | case PCI_EPC_IRQ_LEGACY: | ||
| 957 | ks_pcie_am654_raise_legacy_irq(ks_pcie); | ||
| 958 | break; | ||
| 959 | case PCI_EPC_IRQ_MSI: | ||
| 960 | dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); | ||
| 961 | break; | ||
| 962 | default: | ||
| 963 | dev_err(pci->dev, "UNKNOWN IRQ type\n"); | ||
| 964 | return -EINVAL; | ||
| 965 | } | ||
| 966 | |||
| 967 | return 0; | ||
| 968 | } | ||
| 969 | |||
| 970 | static const struct pci_epc_features ks_pcie_am654_epc_features = { | ||
| 971 | .linkup_notifier = false, | ||
| 972 | .msi_capable = true, | ||
| 973 | .msix_capable = false, | ||
| 974 | .reserved_bar = 1 << BAR_0 | 1 << BAR_1, | ||
| 975 | .bar_fixed_64bit = 1 << BAR_0, | ||
| 976 | .bar_fixed_size[2] = SZ_1M, | ||
| 977 | .bar_fixed_size[3] = SZ_64K, | ||
| 978 | .bar_fixed_size[4] = 256, | ||
| 979 | .bar_fixed_size[5] = SZ_1M, | ||
| 980 | .align = SZ_1M, | ||
| 884 | }; | 981 | }; |
| 885 | 982 | ||
| 983 | static const struct pci_epc_features* | ||
| 984 | ks_pcie_am654_get_features(struct dw_pcie_ep *ep) | ||
| 985 | { | ||
| 986 | return &ks_pcie_am654_epc_features; | ||
| 987 | } | ||
| 988 | |||
| 989 | static const struct dw_pcie_ep_ops ks_pcie_am654_ep_ops = { | ||
| 990 | .ep_init = ks_pcie_am654_ep_init, | ||
| 991 | .raise_irq = ks_pcie_am654_raise_irq, | ||
| 992 | .get_features = &ks_pcie_am654_get_features, | ||
| 993 | }; | ||
| 994 | |||
| 995 | static int __init ks_pcie_add_pcie_ep(struct keystone_pcie *ks_pcie, | ||
| 996 | struct platform_device *pdev) | ||
| 997 | { | ||
| 998 | int ret; | ||
| 999 | struct dw_pcie_ep *ep; | ||
| 1000 | struct resource *res; | ||
| 1001 | struct device *dev = &pdev->dev; | ||
| 1002 | struct dw_pcie *pci = ks_pcie->pci; | ||
| 1003 | |||
| 1004 | ep = &pci->ep; | ||
| 1005 | |||
| 1006 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); | ||
| 1007 | if (!res) | ||
| 1008 | return -EINVAL; | ||
| 1009 | |||
| 1010 | ep->phys_base = res->start; | ||
| 1011 | ep->addr_size = resource_size(res); | ||
| 1012 | |||
| 1013 | ret = dw_pcie_ep_init(ep); | ||
| 1014 | if (ret) { | ||
| 1015 | dev_err(dev, "failed to initialize endpoint\n"); | ||
| 1016 | return ret; | ||
| 1017 | } | ||
| 1018 | |||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1021 | |||
| 886 | static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie) | 1022 | static void ks_pcie_disable_phy(struct keystone_pcie *ks_pcie) |
| 887 | { | 1023 | { |
| 888 | int num_lanes = ks_pcie->num_lanes; | 1024 | int num_lanes = ks_pcie->num_lanes; |
| @@ -950,7 +1086,8 @@ static int ks_pcie_set_mode(struct device *dev) | |||
| 950 | return 0; | 1086 | return 0; |
| 951 | } | 1087 | } |
| 952 | 1088 | ||
| 953 | static int ks_pcie_am654_set_mode(struct device *dev) | 1089 | static int ks_pcie_am654_set_mode(struct device *dev, |
| 1090 | enum dw_pcie_device_mode mode) | ||
| 954 | { | 1091 | { |
| 955 | struct device_node *np = dev->of_node; | 1092 | struct device_node *np = dev->of_node; |
| 956 | struct regmap *syscon; | 1093 | struct regmap *syscon; |
| @@ -963,7 +1100,18 @@ static int ks_pcie_am654_set_mode(struct device *dev) | |||
| 963 | return 0; | 1100 | return 0; |
| 964 | 1101 | ||
| 965 | mask = AM654_PCIE_DEV_TYPE_MASK; | 1102 | mask = AM654_PCIE_DEV_TYPE_MASK; |
| 966 | val = RC; | 1103 | |
| 1104 | switch (mode) { | ||
| 1105 | case DW_PCIE_RC_TYPE: | ||
| 1106 | val = RC; | ||
| 1107 | break; | ||
| 1108 | case DW_PCIE_EP_TYPE: | ||
| 1109 | val = EP; | ||
| 1110 | break; | ||
| 1111 | default: | ||
| 1112 | dev_err(dev, "INVALID device type %d\n", mode); | ||
| 1113 | return -EINVAL; | ||
| 1114 | } | ||
| 967 | 1115 | ||
| 968 | ret = regmap_update_bits(syscon, 0, mask, val); | 1116 | ret = regmap_update_bits(syscon, 0, mask, val); |
| 969 | if (ret) { | 1117 | if (ret) { |
| @@ -1006,6 +1154,13 @@ static const struct ks_pcie_of_data ks_pcie_rc_of_data = { | |||
| 1006 | 1154 | ||
| 1007 | static const struct ks_pcie_of_data ks_pcie_am654_rc_of_data = { | 1155 | static const struct ks_pcie_of_data ks_pcie_am654_rc_of_data = { |
| 1008 | .host_ops = &ks_pcie_am654_host_ops, | 1156 | .host_ops = &ks_pcie_am654_host_ops, |
| 1157 | .mode = DW_PCIE_RC_TYPE, | ||
| 1158 | .version = 0x490A, | ||
| 1159 | }; | ||
| 1160 | |||
| 1161 | static const struct ks_pcie_of_data ks_pcie_am654_ep_of_data = { | ||
| 1162 | .ep_ops = &ks_pcie_am654_ep_ops, | ||
| 1163 | .mode = DW_PCIE_EP_TYPE, | ||
| 1009 | .version = 0x490A, | 1164 | .version = 0x490A, |
| 1010 | }; | 1165 | }; |
| 1011 | 1166 | ||
| @@ -1019,16 +1174,22 @@ static const struct of_device_id ks_pcie_of_match[] = { | |||
| 1019 | .data = &ks_pcie_am654_rc_of_data, | 1174 | .data = &ks_pcie_am654_rc_of_data, |
| 1020 | .compatible = "ti,am654-pcie-rc", | 1175 | .compatible = "ti,am654-pcie-rc", |
| 1021 | }, | 1176 | }, |
| 1177 | { | ||
| 1178 | .data = &ks_pcie_am654_ep_of_data, | ||
| 1179 | .compatible = "ti,am654-pcie-ep", | ||
| 1180 | }, | ||
| 1022 | { }, | 1181 | { }, |
| 1023 | }; | 1182 | }; |
| 1024 | 1183 | ||
| 1025 | static int __init ks_pcie_probe(struct platform_device *pdev) | 1184 | static int __init ks_pcie_probe(struct platform_device *pdev) |
| 1026 | { | 1185 | { |
| 1027 | const struct dw_pcie_host_ops *host_ops; | 1186 | const struct dw_pcie_host_ops *host_ops; |
| 1187 | const struct dw_pcie_ep_ops *ep_ops; | ||
| 1028 | struct device *dev = &pdev->dev; | 1188 | struct device *dev = &pdev->dev; |
| 1029 | struct device_node *np = dev->of_node; | 1189 | struct device_node *np = dev->of_node; |
| 1030 | const struct ks_pcie_of_data *data; | 1190 | const struct ks_pcie_of_data *data; |
| 1031 | const struct of_device_id *match; | 1191 | const struct of_device_id *match; |
| 1192 | enum dw_pcie_device_mode mode; | ||
| 1032 | struct dw_pcie *pci; | 1193 | struct dw_pcie *pci; |
| 1033 | struct keystone_pcie *ks_pcie; | 1194 | struct keystone_pcie *ks_pcie; |
| 1034 | struct device_link **link; | 1195 | struct device_link **link; |
| @@ -1053,6 +1214,8 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 1053 | 1214 | ||
| 1054 | version = data->version; | 1215 | version = data->version; |
| 1055 | host_ops = data->host_ops; | 1216 | host_ops = data->host_ops; |
| 1217 | ep_ops = data->ep_ops; | ||
| 1218 | mode = data->mode; | ||
| 1056 | 1219 | ||
| 1057 | ks_pcie = devm_kzalloc(dev, sizeof(*ks_pcie), GFP_KERNEL); | 1220 | ks_pcie = devm_kzalloc(dev, sizeof(*ks_pcie), GFP_KERNEL); |
| 1058 | if (!ks_pcie) | 1221 | if (!ks_pcie) |
| @@ -1078,16 +1241,11 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 1078 | ks_pcie->is_am6 = true; | 1241 | ks_pcie->is_am6 = true; |
| 1079 | 1242 | ||
| 1080 | pci->dbi_base = base; | 1243 | pci->dbi_base = base; |
| 1244 | pci->dbi_base2 = base; | ||
| 1081 | pci->dev = dev; | 1245 | pci->dev = dev; |
| 1082 | pci->ops = &ks_pcie_dw_pcie_ops; | 1246 | pci->ops = &ks_pcie_dw_pcie_ops; |
| 1083 | pci->version = version; | 1247 | pci->version = version; |
| 1084 | 1248 | ||
| 1085 | ret = of_property_read_u32(np, "num-viewport", &num_viewport); | ||
| 1086 | if (ret < 0) { | ||
| 1087 | dev_err(dev, "unable to read *num-viewport* property\n"); | ||
| 1088 | return ret; | ||
| 1089 | } | ||
| 1090 | |||
| 1091 | irq = platform_get_irq(pdev, 0); | 1249 | irq = platform_get_irq(pdev, 0); |
| 1092 | if (irq < 0) { | 1250 | if (irq < 0) { |
| 1093 | dev_err(dev, "missing IRQ resource: %d\n", irq); | 1251 | dev_err(dev, "missing IRQ resource: %d\n", irq); |
| @@ -1136,7 +1294,6 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 1136 | ks_pcie->pci = pci; | 1294 | ks_pcie->pci = pci; |
| 1137 | ks_pcie->link = link; | 1295 | ks_pcie->link = link; |
| 1138 | ks_pcie->num_lanes = num_lanes; | 1296 | ks_pcie->num_lanes = num_lanes; |
| 1139 | ks_pcie->num_viewport = num_viewport; | ||
| 1140 | ks_pcie->phy = phy; | 1297 | ks_pcie->phy = phy; |
| 1141 | 1298 | ||
| 1142 | gpiod = devm_gpiod_get_optional(dev, "reset", | 1299 | gpiod = devm_gpiod_get_optional(dev, "reset", |
| @@ -1172,7 +1329,7 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 1172 | 1329 | ||
| 1173 | pci->atu_base = atu_base; | 1330 | pci->atu_base = atu_base; |
| 1174 | 1331 | ||
| 1175 | ret = ks_pcie_am654_set_mode(dev); | 1332 | ret = ks_pcie_am654_set_mode(dev, mode); |
| 1176 | if (ret < 0) | 1333 | if (ret < 0) |
| 1177 | goto err_get_sync; | 1334 | goto err_get_sync; |
| 1178 | } else { | 1335 | } else { |
| @@ -1181,29 +1338,58 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | |||
| 1181 | goto err_get_sync; | 1338 | goto err_get_sync; |
| 1182 | } | 1339 | } |
| 1183 | 1340 | ||
| 1184 | /* | ||
| 1185 | * "Power Sequencing and Reset Signal Timings" table in | ||
| 1186 | * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 2.0 | ||
| 1187 | * indicates PERST# should be deasserted after minimum of 100us | ||
| 1188 | * once REFCLK is stable. The REFCLK to the connector in RC | ||
| 1189 | * mode is selected while enabling the PHY. So deassert PERST# | ||
| 1190 | * after 100 us. | ||
| 1191 | */ | ||
| 1192 | if (gpiod) { | ||
| 1193 | usleep_range(100, 200); | ||
| 1194 | gpiod_set_value_cansleep(gpiod, 1); | ||
| 1195 | } | ||
| 1196 | |||
| 1197 | link_speed = of_pci_get_max_link_speed(np); | 1341 | link_speed = of_pci_get_max_link_speed(np); |
| 1198 | if (link_speed < 0) | 1342 | if (link_speed < 0) |
| 1199 | link_speed = 2; | 1343 | link_speed = 2; |
| 1200 | 1344 | ||
| 1201 | ks_pcie_set_link_speed(pci, link_speed); | 1345 | ks_pcie_set_link_speed(pci, link_speed); |
| 1202 | 1346 | ||
| 1203 | pci->pp.ops = host_ops; | 1347 | switch (mode) { |
| 1204 | ret = ks_pcie_add_pcie_port(ks_pcie, pdev); | 1348 | case DW_PCIE_RC_TYPE: |
| 1205 | if (ret < 0) | 1349 | if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_HOST)) { |
| 1206 | goto err_get_sync; | 1350 | ret = -ENODEV; |
| 1351 | goto err_get_sync; | ||
| 1352 | } | ||
| 1353 | |||
| 1354 | ret = of_property_read_u32(np, "num-viewport", &num_viewport); | ||
| 1355 | if (ret < 0) { | ||
| 1356 | dev_err(dev, "unable to read *num-viewport* property\n"); | ||
| 1357 | return ret; | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /* | ||
| 1361 | * "Power Sequencing and Reset Signal Timings" table in | ||
| 1362 | * PCI EXPRESS CARD ELECTROMECHANICAL SPECIFICATION, REV. 2.0 | ||
| 1363 | * indicates PERST# should be deasserted after minimum of 100us | ||
| 1364 | * once REFCLK is stable. The REFCLK to the connector in RC | ||
| 1365 | * mode is selected while enabling the PHY. So deassert PERST# | ||
| 1366 | * after 100 us. | ||
| 1367 | */ | ||
| 1368 | if (gpiod) { | ||
| 1369 | usleep_range(100, 200); | ||
| 1370 | gpiod_set_value_cansleep(gpiod, 1); | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | ks_pcie->num_viewport = num_viewport; | ||
| 1374 | pci->pp.ops = host_ops; | ||
| 1375 | ret = ks_pcie_add_pcie_port(ks_pcie, pdev); | ||
| 1376 | if (ret < 0) | ||
| 1377 | goto err_get_sync; | ||
| 1378 | break; | ||
| 1379 | case DW_PCIE_EP_TYPE: | ||
| 1380 | if (!IS_ENABLED(CONFIG_PCI_KEYSTONE_EP)) { | ||
| 1381 | ret = -ENODEV; | ||
| 1382 | goto err_get_sync; | ||
| 1383 | } | ||
| 1384 | |||
| 1385 | pci->ep.ops = ep_ops; | ||
| 1386 | ret = ks_pcie_add_pcie_ep(ks_pcie, pdev); | ||
| 1387 | if (ret < 0) | ||
| 1388 | goto err_get_sync; | ||
| 1389 | break; | ||
| 1390 | default: | ||
| 1391 | dev_err(dev, "INVALID device type %d\n", mode); | ||
| 1392 | } | ||
| 1207 | 1393 | ||
| 1208 | ks_pcie_enable_error_irq(ks_pcie); | 1394 | ks_pcie_enable_error_irq(ks_pcie); |
| 1209 | 1395 | ||
