diff options
author | Tirumala Marri <tmarri@amcc.com> | 2009-12-21 17:49:41 -0500 |
---|---|---|
committer | Josh Boyer <jwboyer@linux.vnet.ibm.com> | 2010-05-07 15:07:19 -0400 |
commit | e2efc09e52680cecb0ca624e379cb4b4c56157c3 (patch) | |
tree | b32c902a33371e88aea9b62d4159bfa4998a12c6 /arch | |
parent | 1ed31d6db90d51010545921e59d369d2f92b7ac2 (diff) |
powerpc/44x: Adding PCI-E support for PowerPC 460SX based SOC.
Add support for PCI-e on the AMCC 460SX boards
Signed-off-by: Tirumala Marri <tmarri@amcc.com>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com
Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/boot/dts/redwood.dts | 122 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.c | 119 | ||||
-rw-r--r-- | arch/powerpc/sysdev/ppc4xx_pci.h | 58 |
3 files changed, 299 insertions, 0 deletions
diff --git a/arch/powerpc/boot/dts/redwood.dts b/arch/powerpc/boot/dts/redwood.dts index d2af32e2bf7a..81636c01d906 100644 --- a/arch/powerpc/boot/dts/redwood.dts +++ b/arch/powerpc/boot/dts/redwood.dts | |||
@@ -234,10 +234,132 @@ | |||
234 | has-inverted-stacr-oc; | 234 | has-inverted-stacr-oc; |
235 | has-new-stacr-staopc; | 235 | has-new-stacr-staopc; |
236 | }; | 236 | }; |
237 | }; | ||
238 | PCIE0: pciex@d00000000 { | ||
239 | device_type = "pci"; | ||
240 | #interrupt-cells = <1>; | ||
241 | #size-cells = <2>; | ||
242 | #address-cells = <3>; | ||
243 | compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | ||
244 | primary; | ||
245 | port = <0x0>; /* port number */ | ||
246 | reg = <0x0000000d 0x00000000 0x20000000 /* Config space access */ | ||
247 | 0x0000000c 0x10000000 0x00001000>; /* Registers */ | ||
248 | dcr-reg = <0x100 0x020>; | ||
249 | sdr-base = <0x300>; | ||
250 | |||
251 | /* Outbound ranges, one memory and one IO, | ||
252 | * later cannot be changed | ||
253 | */ | ||
254 | ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x00000000 0x00000000 0x80000000 | ||
255 | 0x01000000 0x00000000 0x00000000 0x0000000f 0x80000000 0x00000000 0x00010000>; | ||
256 | |||
257 | /* Inbound 2GB range starting at 0 */ | ||
258 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | ||
237 | 259 | ||
260 | /* This drives busses 10 to 0x1f */ | ||
261 | bus-range = <0x10 0x1f>; | ||
262 | |||
263 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
264 | * to invert PCIe legacy interrupts). | ||
265 | * We are de-swizzling here because the numbers are actually for | ||
266 | * port of the root complex virtual P2P bridge. But I want | ||
267 | * to avoid putting a node for it in the tree, so the numbers | ||
268 | * below are basically de-swizzled numbers. | ||
269 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
270 | */ | ||
271 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
272 | interrupt-map = < | ||
273 | 0x0 0x0 0x0 0x1 &UIC3 0x0 0x4 /* swizzled int A */ | ||
274 | 0x0 0x0 0x0 0x2 &UIC3 0x1 0x4 /* swizzled int B */ | ||
275 | 0x0 0x0 0x0 0x3 &UIC3 0x2 0x4 /* swizzled int C */ | ||
276 | 0x0 0x0 0x0 0x4 &UIC3 0x3 0x4 /* swizzled int D */>; | ||
277 | }; | ||
278 | |||
279 | PCIE1: pciex@d20000000 { | ||
280 | device_type = "pci"; | ||
281 | #interrupt-cells = <1>; | ||
282 | #size-cells = <2>; | ||
283 | #address-cells = <3>; | ||
284 | compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | ||
285 | primary; | ||
286 | port = <0x1>; /* port number */ | ||
287 | reg = <0x0000000d 0x20000000 0x20000000 /* Config space access */ | ||
288 | 0x0000000c 0x10001000 0x00001000>; /* Registers */ | ||
289 | dcr-reg = <0x120 0x020>; | ||
290 | sdr-base = <0x340>; | ||
291 | |||
292 | /* Outbound ranges, one memory and one IO, | ||
293 | * later cannot be changed | ||
294 | */ | ||
295 | ranges = <0x02000000 0x00000000 0x80000000 0x0000000e 0x80000000 0x00000000 0x80000000 | ||
296 | 0x01000000 0x00000000 0x00000000 0x0000000f 0x80010000 0x00000000 0x00010000>; | ||
297 | |||
298 | /* Inbound 2GB range starting at 0 */ | ||
299 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | ||
300 | |||
301 | /* This drives busses 10 to 0x1f */ | ||
302 | bus-range = <0x20 0x2f>; | ||
303 | |||
304 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
305 | * to invert PCIe legacy interrupts). | ||
306 | * We are de-swizzling here because the numbers are actually for | ||
307 | * port of the root complex virtual P2P bridge. But I want | ||
308 | * to avoid putting a node for it in the tree, so the numbers | ||
309 | * below are basically de-swizzled numbers. | ||
310 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
311 | */ | ||
312 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
313 | interrupt-map = < | ||
314 | 0x0 0x0 0x0 0x1 &UIC3 0x4 0x4 /* swizzled int A */ | ||
315 | 0x0 0x0 0x0 0x2 &UIC3 0x5 0x4 /* swizzled int B */ | ||
316 | 0x0 0x0 0x0 0x3 &UIC3 0x6 0x4 /* swizzled int C */ | ||
317 | 0x0 0x0 0x0 0x4 &UIC3 0x7 0x4 /* swizzled int D */>; | ||
318 | }; | ||
319 | |||
320 | PCIE2: pciex@d40000000 { | ||
321 | device_type = "pci"; | ||
322 | #interrupt-cells = <1>; | ||
323 | #size-cells = <2>; | ||
324 | #address-cells = <3>; | ||
325 | compatible = "ibm,plb-pciex-460sx", "ibm,plb-pciex"; | ||
326 | primary; | ||
327 | port = <0x2>; /* port number */ | ||
328 | reg = <0x0000000d 0x40000000 0x20000000 /* Config space access */ | ||
329 | 0x0000000c 0x10002000 0x00001000>; /* Registers */ | ||
330 | dcr-reg = <0x140 0x020>; | ||
331 | sdr-base = <0x370>; | ||
332 | |||
333 | /* Outbound ranges, one memory and one IO, | ||
334 | * later cannot be changed | ||
335 | */ | ||
336 | ranges = <0x02000000 0x00000000 0x80000000 0x0000000f 0x00000000 0x00000000 0x80000000 | ||
337 | 0x01000000 0x00000000 0x00000000 0x0000000f 0x80020000 0x00000000 0x00010000>; | ||
338 | |||
339 | /* Inbound 2GB range starting at 0 */ | ||
340 | dma-ranges = <0x42000000 0x0 0x0 0x0 0x0 0x0 0x80000000>; | ||
341 | |||
342 | /* This drives busses 10 to 0x1f */ | ||
343 | bus-range = <0x30 0x3f>; | ||
344 | |||
345 | /* Legacy interrupts (note the weird polarity, the bridge seems | ||
346 | * to invert PCIe legacy interrupts). | ||
347 | * We are de-swizzling here because the numbers are actually for | ||
348 | * port of the root complex virtual P2P bridge. But I want | ||
349 | * to avoid putting a node for it in the tree, so the numbers | ||
350 | * below are basically de-swizzled numbers. | ||
351 | * The real slot is on idsel 0, so the swizzling is 1:1 | ||
352 | */ | ||
353 | interrupt-map-mask = <0x0 0x0 0x0 0x7>; | ||
354 | interrupt-map = < | ||
355 | 0x0 0x0 0x0 0x1 &UIC3 0x8 0x4 /* swizzled int A */ | ||
356 | 0x0 0x0 0x0 0x2 &UIC3 0x9 0x4 /* swizzled int B */ | ||
357 | 0x0 0x0 0x0 0x3 &UIC3 0xa 0x4 /* swizzled int C */ | ||
358 | 0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>; | ||
238 | }; | 359 | }; |
239 | 360 | ||
240 | }; | 361 | }; |
362 | |||
241 | chosen { | 363 | chosen { |
242 | linux,stdout-path = "/plb/opb/serial@ef600200"; | 364 | linux,stdout-path = "/plb/opb/serial@ef600200"; |
243 | }; | 365 | }; |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 106d767bf65b..156aa7d36258 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c | |||
@@ -974,6 +974,123 @@ static struct ppc4xx_pciex_hwops ppc460ex_pcie_hwops __initdata = | |||
974 | .setup_utl = ppc460ex_pciex_init_utl, | 974 | .setup_utl = ppc460ex_pciex_init_utl, |
975 | }; | 975 | }; |
976 | 976 | ||
977 | static int __init ppc460sx_pciex_core_init(struct device_node *np) | ||
978 | { | ||
979 | /* HSS drive amplitude */ | ||
980 | mtdcri(SDR0, PESDR0_460SX_HSSL0DAMP, 0xB9843211); | ||
981 | mtdcri(SDR0, PESDR0_460SX_HSSL1DAMP, 0xB9843211); | ||
982 | mtdcri(SDR0, PESDR0_460SX_HSSL2DAMP, 0xB9843211); | ||
983 | mtdcri(SDR0, PESDR0_460SX_HSSL3DAMP, 0xB9843211); | ||
984 | mtdcri(SDR0, PESDR0_460SX_HSSL4DAMP, 0xB9843211); | ||
985 | mtdcri(SDR0, PESDR0_460SX_HSSL5DAMP, 0xB9843211); | ||
986 | mtdcri(SDR0, PESDR0_460SX_HSSL6DAMP, 0xB9843211); | ||
987 | mtdcri(SDR0, PESDR0_460SX_HSSL7DAMP, 0xB9843211); | ||
988 | |||
989 | mtdcri(SDR0, PESDR1_460SX_HSSL0DAMP, 0xB9843211); | ||
990 | mtdcri(SDR0, PESDR1_460SX_HSSL1DAMP, 0xB9843211); | ||
991 | mtdcri(SDR0, PESDR1_460SX_HSSL2DAMP, 0xB9843211); | ||
992 | mtdcri(SDR0, PESDR1_460SX_HSSL3DAMP, 0xB9843211); | ||
993 | |||
994 | mtdcri(SDR0, PESDR2_460SX_HSSL0DAMP, 0xB9843211); | ||
995 | mtdcri(SDR0, PESDR2_460SX_HSSL1DAMP, 0xB9843211); | ||
996 | mtdcri(SDR0, PESDR2_460SX_HSSL2DAMP, 0xB9843211); | ||
997 | mtdcri(SDR0, PESDR2_460SX_HSSL3DAMP, 0xB9843211); | ||
998 | |||
999 | /* HSS TX pre-emphasis */ | ||
1000 | mtdcri(SDR0, PESDR0_460SX_HSSL0COEFA, 0xDCB98987); | ||
1001 | mtdcri(SDR0, PESDR0_460SX_HSSL1COEFA, 0xDCB98987); | ||
1002 | mtdcri(SDR0, PESDR0_460SX_HSSL2COEFA, 0xDCB98987); | ||
1003 | mtdcri(SDR0, PESDR0_460SX_HSSL3COEFA, 0xDCB98987); | ||
1004 | mtdcri(SDR0, PESDR0_460SX_HSSL4COEFA, 0xDCB98987); | ||
1005 | mtdcri(SDR0, PESDR0_460SX_HSSL5COEFA, 0xDCB98987); | ||
1006 | mtdcri(SDR0, PESDR0_460SX_HSSL6COEFA, 0xDCB98987); | ||
1007 | mtdcri(SDR0, PESDR0_460SX_HSSL7COEFA, 0xDCB98987); | ||
1008 | |||
1009 | mtdcri(SDR0, PESDR1_460SX_HSSL0COEFA, 0xDCB98987); | ||
1010 | mtdcri(SDR0, PESDR1_460SX_HSSL1COEFA, 0xDCB98987); | ||
1011 | mtdcri(SDR0, PESDR1_460SX_HSSL2COEFA, 0xDCB98987); | ||
1012 | mtdcri(SDR0, PESDR1_460SX_HSSL3COEFA, 0xDCB98987); | ||
1013 | |||
1014 | mtdcri(SDR0, PESDR2_460SX_HSSL0COEFA, 0xDCB98987); | ||
1015 | mtdcri(SDR0, PESDR2_460SX_HSSL1COEFA, 0xDCB98987); | ||
1016 | mtdcri(SDR0, PESDR2_460SX_HSSL2COEFA, 0xDCB98987); | ||
1017 | mtdcri(SDR0, PESDR2_460SX_HSSL3COEFA, 0xDCB98987); | ||
1018 | |||
1019 | /* HSS TX calibration control */ | ||
1020 | mtdcri(SDR0, PESDR0_460SX_HSSL1CALDRV, 0x22222222); | ||
1021 | mtdcri(SDR0, PESDR1_460SX_HSSL1CALDRV, 0x22220000); | ||
1022 | mtdcri(SDR0, PESDR2_460SX_HSSL1CALDRV, 0x22220000); | ||
1023 | |||
1024 | /* HSS TX slew control */ | ||
1025 | mtdcri(SDR0, PESDR0_460SX_HSSSLEW, 0xFFFFFFFF); | ||
1026 | mtdcri(SDR0, PESDR1_460SX_HSSSLEW, 0xFFFF0000); | ||
1027 | mtdcri(SDR0, PESDR2_460SX_HSSSLEW, 0xFFFF0000); | ||
1028 | |||
1029 | udelay(100); | ||
1030 | |||
1031 | /* De-assert PLLRESET */ | ||
1032 | dcri_clrset(SDR0, PESDR0_PLLLCT2, 0x00000100, 0); | ||
1033 | |||
1034 | /* Reset DL, UTL, GPL before configuration */ | ||
1035 | mtdcri(SDR0, PESDR0_460SX_RCSSET, | ||
1036 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
1037 | mtdcri(SDR0, PESDR1_460SX_RCSSET, | ||
1038 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
1039 | mtdcri(SDR0, PESDR2_460SX_RCSSET, | ||
1040 | PESDRx_RCSSET_RSTDL | PESDRx_RCSSET_RSTGU); | ||
1041 | |||
1042 | udelay(100); | ||
1043 | |||
1044 | /* | ||
1045 | * If bifurcation is not enabled, u-boot would have disabled the | ||
1046 | * third PCIe port | ||
1047 | */ | ||
1048 | if (((mfdcri(SDR0, PESDR1_460SX_HSSCTLSET) & 0x00000001) == | ||
1049 | 0x00000001)) { | ||
1050 | printk(KERN_INFO "PCI: PCIE bifurcation setup successfully.\n"); | ||
1051 | printk(KERN_INFO "PCI: Total 3 PCIE ports are present\n"); | ||
1052 | return 3; | ||
1053 | } | ||
1054 | |||
1055 | printk(KERN_INFO "PCI: Total 2 PCIE ports are present\n"); | ||
1056 | return 2; | ||
1057 | } | ||
1058 | |||
1059 | static int ppc460sx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) | ||
1060 | { | ||
1061 | |||
1062 | if (port->endpoint) | ||
1063 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | ||
1064 | 0x01000000, 0); | ||
1065 | else | ||
1066 | dcri_clrset(SDR0, port->sdr_base + PESDRn_UTLSET2, | ||
1067 | 0, 0x01000000); | ||
1068 | |||
1069 | /*Gen-1*/ | ||
1070 | mtdcri(SDR0, port->sdr_base + PESDRn_460SX_RCEI, 0x08000000); | ||
1071 | |||
1072 | dcri_clrset(SDR0, port->sdr_base + PESDRn_RCSSET, | ||
1073 | (PESDRx_RCSSET_RSTGU | PESDRx_RCSSET_RSTDL), | ||
1074 | PESDRx_RCSSET_RSTPYN); | ||
1075 | |||
1076 | port->has_ibpre = 1; | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static int ppc460sx_pciex_init_utl(struct ppc4xx_pciex_port *port) | ||
1082 | { | ||
1083 | /* Max 128 Bytes */ | ||
1084 | out_be32 (port->utl_base + PEUTL_PBBSZ, 0x00000000); | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | static struct ppc4xx_pciex_hwops ppc460sx_pcie_hwops __initdata = { | ||
1089 | .core_init = ppc460sx_pciex_core_init, | ||
1090 | .port_init_hw = ppc460sx_pciex_init_port_hw, | ||
1091 | .setup_utl = ppc460sx_pciex_init_utl, | ||
1092 | }; | ||
1093 | |||
977 | #endif /* CONFIG_44x */ | 1094 | #endif /* CONFIG_44x */ |
978 | 1095 | ||
979 | #ifdef CONFIG_40x | 1096 | #ifdef CONFIG_40x |
@@ -1089,6 +1206,8 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) | |||
1089 | } | 1206 | } |
1090 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) | 1207 | if (of_device_is_compatible(np, "ibm,plb-pciex-460ex")) |
1091 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; | 1208 | ppc4xx_pciex_hwops = &ppc460ex_pcie_hwops; |
1209 | if (of_device_is_compatible(np, "ibm,plb-pciex-460sx")) | ||
1210 | ppc4xx_pciex_hwops = &ppc460sx_pcie_hwops; | ||
1092 | #endif /* CONFIG_44x */ | 1211 | #endif /* CONFIG_44x */ |
1093 | #ifdef CONFIG_40x | 1212 | #ifdef CONFIG_40x |
1094 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) | 1213 | if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) |
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h index d04e40b306fb..56d9e5deccbf 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.h +++ b/arch/powerpc/sysdev/ppc4xx_pci.h | |||
@@ -324,6 +324,64 @@ | |||
324 | #define PESDR0_460EX_IHS2 0x036D | 324 | #define PESDR0_460EX_IHS2 0x036D |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * 460SX addtional DCRs | ||
328 | */ | ||
329 | #define PESDRn_460SX_RCEI 0x02 | ||
330 | |||
331 | #define PESDR0_460SX_HSSL0DAMP 0x320 | ||
332 | #define PESDR0_460SX_HSSL1DAMP 0x321 | ||
333 | #define PESDR0_460SX_HSSL2DAMP 0x322 | ||
334 | #define PESDR0_460SX_HSSL3DAMP 0x323 | ||
335 | #define PESDR0_460SX_HSSL4DAMP 0x324 | ||
336 | #define PESDR0_460SX_HSSL5DAMP 0x325 | ||
337 | #define PESDR0_460SX_HSSL6DAMP 0x326 | ||
338 | #define PESDR0_460SX_HSSL7DAMP 0x327 | ||
339 | |||
340 | #define PESDR1_460SX_HSSL0DAMP 0x354 | ||
341 | #define PESDR1_460SX_HSSL1DAMP 0x355 | ||
342 | #define PESDR1_460SX_HSSL2DAMP 0x356 | ||
343 | #define PESDR1_460SX_HSSL3DAMP 0x357 | ||
344 | |||
345 | #define PESDR2_460SX_HSSL0DAMP 0x384 | ||
346 | #define PESDR2_460SX_HSSL1DAMP 0x385 | ||
347 | #define PESDR2_460SX_HSSL2DAMP 0x386 | ||
348 | #define PESDR2_460SX_HSSL3DAMP 0x387 | ||
349 | |||
350 | #define PESDR0_460SX_HSSL0COEFA 0x328 | ||
351 | #define PESDR0_460SX_HSSL1COEFA 0x329 | ||
352 | #define PESDR0_460SX_HSSL2COEFA 0x32A | ||
353 | #define PESDR0_460SX_HSSL3COEFA 0x32B | ||
354 | #define PESDR0_460SX_HSSL4COEFA 0x32C | ||
355 | #define PESDR0_460SX_HSSL5COEFA 0x32D | ||
356 | #define PESDR0_460SX_HSSL6COEFA 0x32E | ||
357 | #define PESDR0_460SX_HSSL7COEFA 0x32F | ||
358 | |||
359 | #define PESDR1_460SX_HSSL0COEFA 0x358 | ||
360 | #define PESDR1_460SX_HSSL1COEFA 0x359 | ||
361 | #define PESDR1_460SX_HSSL2COEFA 0x35A | ||
362 | #define PESDR1_460SX_HSSL3COEFA 0x35B | ||
363 | |||
364 | #define PESDR2_460SX_HSSL0COEFA 0x388 | ||
365 | #define PESDR2_460SX_HSSL1COEFA 0x389 | ||
366 | #define PESDR2_460SX_HSSL2COEFA 0x38A | ||
367 | #define PESDR2_460SX_HSSL3COEFA 0x38B | ||
368 | |||
369 | #define PESDR0_460SX_HSSL1CALDRV 0x339 | ||
370 | #define PESDR1_460SX_HSSL1CALDRV 0x361 | ||
371 | #define PESDR2_460SX_HSSL1CALDRV 0x391 | ||
372 | |||
373 | #define PESDR0_460SX_HSSSLEW 0x338 | ||
374 | #define PESDR1_460SX_HSSSLEW 0x360 | ||
375 | #define PESDR2_460SX_HSSSLEW 0x390 | ||
376 | |||
377 | #define PESDR0_460SX_HSSCTLSET 0x31E | ||
378 | #define PESDR1_460SX_HSSCTLSET 0x352 | ||
379 | #define PESDR2_460SX_HSSCTLSET 0x382 | ||
380 | |||
381 | #define PESDR0_460SX_RCSSET 0x304 | ||
382 | #define PESDR1_460SX_RCSSET 0x344 | ||
383 | #define PESDR2_460SX_RCSSET 0x374 | ||
384 | /* | ||
327 | * Of the above, some are common offsets from the base | 385 | * Of the above, some are common offsets from the base |
328 | */ | 386 | */ |
329 | #define PESDRn_UTLSET1 0x00 | 387 | #define PESDRn_UTLSET1 0x00 |