aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c220
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.h2
2 files changed, 133 insertions, 89 deletions
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index b986eff09f6b..0538980ef89c 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -16,6 +16,8 @@
16 * 16 *
17 */ 17 */
18 18
19#undef DEBUG
20
19#include <linux/kernel.h> 21#include <linux/kernel.h>
20#include <linux/pci.h> 22#include <linux/pci.h>
21#include <linux/init.h> 23#include <linux/init.h>
@@ -531,10 +533,13 @@ struct ppc4xx_pciex_port
531 struct device_node *node; 533 struct device_node *node;
532 unsigned int index; 534 unsigned int index;
533 int endpoint; 535 int endpoint;
536 int link;
537 int has_ibpre;
534 unsigned int sdr_base; 538 unsigned int sdr_base;
535 dcr_host_t dcrs; 539 dcr_host_t dcrs;
536 struct resource cfg_space; 540 struct resource cfg_space;
537 struct resource utl_regs; 541 struct resource utl_regs;
542 void __iomem *utl_base;
538}; 543};
539 544
540static struct ppc4xx_pciex_port *ppc4xx_pciex_ports; 545static struct ppc4xx_pciex_port *ppc4xx_pciex_ports;
@@ -706,29 +711,44 @@ static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
706 return 0; 711 return 0;
707} 712}
708 713
709static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port) 714static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
715{
716 return ppc440spe_pciex_init_port_hw(port);
717}
718
719static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
710{ 720{
711 void __iomem *utl_base; 721 int rc = ppc440spe_pciex_init_port_hw(port);
722
723 port->has_ibpre = 1;
724
725 return rc;
726}
712 727
728static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port)
729{
713 /* XXX Check what that value means... I hate magic */ 730 /* XXX Check what that value means... I hate magic */
714 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800); 731 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800);
715 732
716 utl_base = ioremap(port->utl_regs.start, 0x100);
717 BUG_ON(utl_base == NULL);
718
719 /* 733 /*
720 * Set buffer allocations and then assert VRB and TXE. 734 * Set buffer allocations and then assert VRB and TXE.
721 */ 735 */
722 out_be32(utl_base + PEUTL_OUTTR, 0x08000000); 736 out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000);
723 out_be32(utl_base + PEUTL_INTR, 0x02000000); 737 out_be32(port->utl_base + PEUTL_INTR, 0x02000000);
724 out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000); 738 out_be32(port->utl_base + PEUTL_OPDBSZ, 0x10000000);
725 out_be32(utl_base + PEUTL_PBBSZ, 0x53000000); 739 out_be32(port->utl_base + PEUTL_PBBSZ, 0x53000000);
726 out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000); 740 out_be32(port->utl_base + PEUTL_IPHBSZ, 0x08000000);
727 out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000); 741 out_be32(port->utl_base + PEUTL_IPDBSZ, 0x10000000);
728 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); 742 out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000);
729 out_be32(utl_base + PEUTL_PCTL, 0x80800066); 743 out_be32(port->utl_base + PEUTL_PCTL, 0x80800066);
730 744
731 iounmap(utl_base); 745 return 0;
746}
747
748static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port)
749{
750 /* Report CRS to the operating system */
751 out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000);
732 752
733 return 0; 753 return 0;
734} 754}
@@ -736,14 +756,15 @@ static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port)
736static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = 756static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata =
737{ 757{
738 .core_init = ppc440spe_pciex_core_init, 758 .core_init = ppc440spe_pciex_core_init,
739 .port_init_hw = ppc440spe_pciex_init_port_hw, 759 .port_init_hw = ppc440speA_pciex_init_port_hw,
740 .setup_utl = ppc440speA_pciex_init_utl, 760 .setup_utl = ppc440speA_pciex_init_utl,
741}; 761};
742 762
743static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = 763static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata =
744{ 764{
745 .core_init = ppc440spe_pciex_core_init, 765 .core_init = ppc440spe_pciex_core_init,
746 .port_init_hw = ppc440spe_pciex_init_port_hw, 766 .port_init_hw = ppc440speB_pciex_init_port_hw,
767 .setup_utl = ppc440speB_pciex_init_utl,
747}; 768};
748 769
749 770
@@ -821,30 +842,21 @@ static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port)
821 842
822static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) 843static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port)
823{ 844{
824 void __iomem *utl_base;
825
826 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); 845 dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0);
827 846
828 utl_base = ioremap(port->utl_regs.start, 0x100);
829 BUG_ON(utl_base == NULL);
830
831 /* 847 /*
832 * Set buffer allocations and then assert VRB and TXE. 848 * Set buffer allocations and then assert VRB and TXE.
833 */ 849 */
834 out_be32(utl_base + PEUTL_OUTTR, 0x02000000); 850 out_be32(port->utl_base + PEUTL_OUTTR, 0x02000000);
835 out_be32(utl_base + PEUTL_INTR, 0x02000000); 851 out_be32(port->utl_base + PEUTL_INTR, 0x02000000);
836 out_be32(utl_base + PEUTL_OPDBSZ, 0x04000000); 852 out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000);
837 out_be32(utl_base + PEUTL_PBBSZ, 0x21000000); 853 out_be32(port->utl_base + PEUTL_PBBSZ, 0x21000000);
838 out_be32(utl_base + PEUTL_IPHBSZ, 0x02000000); 854 out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000);
839 out_be32(utl_base + PEUTL_IPDBSZ, 0x04000000); 855 out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000);
840 out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); 856 out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000);
841 out_be32(utl_base + PEUTL_PCTL, 0x80800066); 857 out_be32(port->utl_base + PEUTL_PCTL, 0x80800066);
842 858
843 out_be32(utl_base + PEUTL_PBCTL, 0x0800000c); 859 out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000);
844 out_be32(utl_base + PEUTL_RCSTA,
845 in_be32(utl_base + PEUTL_RCSTA) | 0x000040000);
846
847 iounmap(utl_base);
848 860
849 return 0; 861 return 0;
850} 862}
@@ -926,17 +938,29 @@ static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port
926 dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0); 938 dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0);
927} 939}
928 940
929static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) 941static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port,
942 unsigned int sdr_offset,
943 unsigned int mask,
944 unsigned int value,
945 int timeout_ms)
930{ 946{
931 int attempts, rc = 0;
932 u32 val; 947 u32 val;
933 948
934 /* Check if it's endpoint or root complex 949 while(timeout_ms--) {
935 * 950 val = mfdcri(SDR0, port->sdr_base + sdr_offset);
936 * XXX Do we want to use the device-tree instead ? --BenH. 951 if ((val & mask) == value) {
937 */ 952 pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n",
938 val = mfdcri(SDR0, port->sdr_base + PESDRn_DLPSET); 953 port->index, sdr_offset, timeout_ms, val);
939 port->endpoint = (((val >> 20) & 0xf) != PTYPE_ROOT_PORT); 954 return 0;
955 }
956 msleep(1);
957 }
958 return -1;
959}
960
961static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
962{
963 int rc = 0;
940 964
941 /* Init HW */ 965 /* Init HW */
942 if (ppc4xx_pciex_hwops->port_init_hw) 966 if (ppc4xx_pciex_hwops->port_init_hw)
@@ -944,44 +968,40 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
944 if (rc != 0) 968 if (rc != 0)
945 return rc; 969 return rc;
946 970
947 /* 971 printk(KERN_INFO "PCIE%d: Checking link...\n",
948 * Notice: the following delay has critical impact on device
949 * initialization - if too short (<50ms) the link doesn't get up.
950 *
951 * XXX FIXME: There are various issues with that link up thingy,
952 * we could just wait for the link with a timeout but Stefan says
953 * some cards need more time even after the link is up. I'll
954 * investigate. For now, we keep a fixed 1s delay.
955 *
956 * Ultimately, it should be made asynchronous so all ports are
957 * brought up simultaneously though.
958 */
959 printk(KERN_INFO "PCIE%d: Waiting for link to go up...\n",
960 port->index); 972 port->index);
961 msleep(1000);
962 973
963 /* 974 /* Wait for reset to complete */
964 * Check that we exited the reset state properly 975 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) {
965 */ 976 printk(KERN_WARNING "PCIE%d: PGRST failed\n",
966 val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSTS); 977 port->index);
967 if (val & (1 << 20)) {
968 printk(KERN_WARNING "PCIE%d: PGRST failed %08x\n",
969 port->index, val);
970 return -1; 978 return -1;
971 } 979 }
972 980
973 /* 981 /* Check for card presence detect if supported, if not, just wait for
974 * Verify link is up 982 * link unconditionally.
983 *
984 * note that we don't fail if there is no link, we just filter out
985 * config space accesses. That way, it will be easier to implement
986 * hotplug later on.
975 */ 987 */
976 val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP); 988 if (!port->has_ibpre ||
977 if (!(val & 0x00001000)) { 989 !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
978 printk(KERN_INFO "PCIE%d: link is not up !\n", 990 1 << 28, 1 << 28, 100)) {
991 printk(KERN_INFO
992 "PCIE%d: Device detected, waiting for link...\n",
979 port->index); 993 port->index);
980 return -1; 994 if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP,
981 } 995 0x1000, 0x1000, 2000))
982 996 printk(KERN_WARNING
983 printk(KERN_INFO "PCIE%d: link is up !\n", 997 "PCIE%d: Link up failed\n", port->index);
984 port->index); 998 else {
999 printk(KERN_INFO
1000 "PCIE%d: link is up !\n", port->index);
1001 port->link = 1;
1002 }
1003 } else
1004 printk(KERN_INFO "PCIE%d: No device detected.\n", port->index);
985 1005
986 /* 1006 /*
987 * Initialize mapping: disable all regions and configure 1007 * Initialize mapping: disable all regions and configure
@@ -990,12 +1010,13 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
990 ppc4xx_pciex_port_init_mapping(port); 1010 ppc4xx_pciex_port_init_mapping(port);
991 1011
992 /* 1012 /*
993 * Setup UTL registers - but only on revA! 1013 * Map UTL
994 * We use default settings for revB chip. 1014 */
995 * 1015 port->utl_base = ioremap(port->utl_regs.start, 0x100);
996 * To be reworked. We may also be able to move that to 1016 BUG_ON(port->utl_base == NULL);
997 * before the link wait 1017
998 * --BenH. 1018 /*
1019 * Setup UTL registers --BenH.
999 */ 1020 */
1000 if (ppc4xx_pciex_hwops->setup_utl) 1021 if (ppc4xx_pciex_hwops->setup_utl)
1001 ppc4xx_pciex_hwops->setup_utl(port); 1022 ppc4xx_pciex_hwops->setup_utl(port);
@@ -1003,15 +1024,13 @@ static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port)
1003 /* 1024 /*
1004 * Check for VC0 active and assert RDY. 1025 * Check for VC0 active and assert RDY.
1005 */ 1026 */
1006 attempts = 10; 1027 if (port->link &&
1007 while (!(mfdcri(SDR0, port->sdr_base + PESDRn_RCSSTS) & (1 << 16))) { 1028 ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS,
1008 if (!(attempts--)) { 1029 1 << 16, 1 << 16, 5000)) {
1009 printk(KERN_INFO "PCIE%d: VC0 not active\n", 1030 printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index);
1010 port->index); 1031 port->link = 0;
1011 return -1;
1012 }
1013 msleep(1000);
1014 } 1032 }
1033
1015 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 1034 mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET,
1016 mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20); 1035 mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20);
1017 msleep(100); 1036 msleep(100);
@@ -1048,6 +1067,10 @@ static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port,
1048 PCI_SLOT(devfn) != 0) 1067 PCI_SLOT(devfn) != 0)
1049 return PCIBIOS_DEVICE_NOT_FOUND; 1068 return PCIBIOS_DEVICE_NOT_FOUND;
1050 1069
1070 /* Check if we have a link */
1071 if ((bus->number != port->hose->first_busno) && !port->link)
1072 return PCIBIOS_DEVICE_NOT_FOUND;
1073
1051 return 0; 1074 return 0;
1052} 1075}
1053 1076
@@ -1092,6 +1115,9 @@ static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
1092 gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); 1115 gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG);
1093 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); 1116 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA);
1094 1117
1118 /* Make sure no CRS is recorded */
1119 out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000);
1120
1095 switch (len) { 1121 switch (len) {
1096 case 1: 1122 case 1:
1097 *val = in_8((u8 *)(addr + offset)); 1123 *val = in_8((u8 *)(addr + offset));
@@ -1109,6 +1135,14 @@ static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
1109 bus->number, hose->first_busno, hose->last_busno, 1135 bus->number, hose->first_busno, hose->last_busno,
1110 devfn, offset, len, addr + offset, *val); 1136 devfn, offset, len, addr + offset, *val);
1111 1137
1138 /* Check for CRS (440SPe rev B does that for us but heh ..) */
1139 if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) {
1140 pr_debug("Got CRS !\n");
1141 if (len != 4 || offset != 0)
1142 return PCIBIOS_DEVICE_NOT_FOUND;
1143 *val = 0xffff0001;
1144 }
1145
1112 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); 1146 dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg);
1113 1147
1114 return PCIBIOS_SUCCESSFUL; 1148 return PCIBIOS_SUCCESSFUL;
@@ -1278,8 +1312,11 @@ static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port)
1278 void __iomem *mbase = NULL, *cfg_data = NULL; 1312 void __iomem *mbase = NULL, *cfg_data = NULL;
1279 1313
1280 /* XXX FIXME: Handle endpoint mode properly */ 1314 /* XXX FIXME: Handle endpoint mode properly */
1281 if (port->endpoint) 1315 if (port->endpoint) {
1316 printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n",
1317 port->index);
1282 return; 1318 return;
1319 }
1283 1320
1284 /* Check if primary bridge */ 1321 /* Check if primary bridge */
1285 if (of_get_property(port->node, "primary", NULL)) 1322 if (of_get_property(port->node, "primary", NULL))
@@ -1424,6 +1461,9 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
1424 } 1461 }
1425 port->sdr_base = *pval; 1462 port->sdr_base = *pval;
1426 1463
1464 /* XXX Currently, we only support root complex mode */
1465 port->endpoint = 0;
1466
1427 /* Fetch config space registers address */ 1467 /* Fetch config space registers address */
1428 if (of_address_to_resource(np, 0, &port->cfg_space)) { 1468 if (of_address_to_resource(np, 0, &port->cfg_space)) {
1429 printk(KERN_ERR "%s: Can't get PCI-E config space !", 1469 printk(KERN_ERR "%s: Can't get PCI-E config space !",
@@ -1447,8 +1487,10 @@ static void __init ppc4xx_probe_pciex_bridge(struct device_node *np)
1447 port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); 1487 port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
1448 1488
1449 /* Initialize the port specific registers */ 1489 /* Initialize the port specific registers */
1450 if (ppc4xx_pciex_port_init(port)) 1490 if (ppc4xx_pciex_port_init(port)) {
1491 printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index);
1451 return; 1492 return;
1493 }
1452 1494
1453 /* Setup the linux hose data structure */ 1495 /* Setup the linux hose data structure */
1454 ppc4xx_pciex_port_setup_hose(port); 1496 ppc4xx_pciex_port_setup_hose(port);
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.h b/arch/powerpc/sysdev/ppc4xx_pci.h
index 43e51ce5c477..1c07908dc6ef 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.h
+++ b/arch/powerpc/sysdev/ppc4xx_pci.h
@@ -330,6 +330,8 @@
330/* 330/*
331 * Config space register offsets 331 * Config space register offsets
332 */ 332 */
333#define PECFG_ECRTCTL 0x074
334
333#define PECFG_BAR0LMPA 0x210 335#define PECFG_BAR0LMPA 0x210
334#define PECFG_BAR0HMPA 0x214 336#define PECFG_BAR0HMPA 0x214
335#define PECFG_BAR1MPA 0x218 337#define PECFG_BAR1MPA 0x218