* [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe @ 2006-11-13 17:55 Roland Dreier 2006-11-13 22:27 ` Wolfgang Denk 2006-11-13 22:31 ` [PATCH v2 -- fixed changelog] " Roland Dreier 0 siblings, 2 replies; 11+ messages in thread From: Roland Dreier @ 2006-11-13 17:55 UTC (permalink / raw) To: mporter; +Cc: linuxppc-embedded This is mostly updating the PCI Express code to work with the new core in the Rev. B chip, which unfortunately has different undocumented restrictions on the PLB addresses that can be used from the Rev. A core. Also, when adding the cputable entry for 440SPe Rev. B, we need to adjust the entry for 440SP Rev. A so that it looks at more bits of the PVR. The 440SPe Rev. B has PVR 53421891, which would have matched the old 440SP pattern of 53xxx891. Signed-off-by: Roland Dreier <rolandd@cisco.com> --- Matt, please queue for a 2.6.20 merge. arch/powerpc/kernel/cputable.c | 21 ++- arch/ppc/platforms/4xx/davinci_sc.c | 5 - arch/ppc/syslib/ppc440spe_pcie.c | 258 ++++++++++++++++++++++-------- drivers/infiniband/hw/mthca/mthca_main.c | 4 +- 4 files changed, 206 insertions(+), 82 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index bfd499e..04559be 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1073,8 +1073,8 @@ #ifdef CONFIG_44x .platform = "ppc440", }, { /* 440SP Rev. A */ - .pvr_mask = 0xff000fff, - .pvr_value = 0x53000891, + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53200891, .cpu_name = "440SP Rev. A", .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_USER_BOOKE, @@ -1083,9 +1083,20 @@ #ifdef CONFIG_44x .platform = "ppc440", }, { /* 440SPe Rev. A */ - .pvr_mask = 0xff000fff, - .pvr_value = 0x53000890, - .cpu_name = "440SPe Rev. A", + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53400890, + .cpu_name = "440SPe Rev. A", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB, + .cpu_user_features = COMMON_USER_BOOKE, + .icache_bsize = 32, + .dcache_bsize = 32, + .platform = "ppc440", + }, + { /* 440SPe Rev. B */ + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53400891, + .cpu_name = "440SPe Rev. B", .cpu_features = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, .cpu_user_features = COMMON_USER_BOOKE, diff --git a/arch/ppc/platforms/4xx/davinci_sc.c b/arch/ppc/platforms/4xx/davinci_sc.c index 623988f..3dbedda 100644 --- a/arch/ppc/platforms/4xx/davinci_sc.c +++ b/arch/ppc/platforms/4xx/davinci_sc.c @@ -172,11 +172,6 @@ davinci_sc_setup_hoses(void) char name[20]; int i; - if (0 && ppc440spe_init_pcie()) { - printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n"); - return; - } - for (i = 0; i <= 2; ++i) { if (!davinci_sc_pcie_card_present(i)) continue; diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c index dd5d4b9..7ae14d2 100644 --- a/arch/ppc/syslib/ppc440spe_pcie.c +++ b/arch/ppc/syslib/ppc440spe_pcie.c @@ -19,16 +19,23 @@ #include <asm/ibm44x.h> #include "ppc440spe_pcie.h" +static enum { + REV_A, + REV_B +} core_rev; + static int pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose = bus->sysdata; - if (PCI_SLOT(devfn) != 1) + /* 440SPE implements only one function per port */ + if (PCI_SLOT(devfn) != 1 || PCI_FUNC(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; - offset += devfn << 12; + if (core_rev == REV_A) + offset += devfn << 12; /* * Note: the caller has already checked that offset is @@ -57,10 +64,11 @@ pcie_write_config(struct pci_bus *bus, u { struct pci_controller *hose = bus->sysdata; - if (PCI_SLOT(devfn) != 1) + if (PCI_SLOT(devfn) != 1 || PCI_FUNC(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; - offset += devfn << 12; + if (core_rev == REV_A) + offset += devfn << 12; switch (len) { case 1: @@ -153,6 +161,20 @@ static void check_error(void) */ int ppc440spe_init_pcie(void) { + int i; + + switch (PVR_REV(mfspr(SPRN_PVR))) { + case 0x1890: core_rev = REV_A; break; + case 0x1891: core_rev = REV_B; break; + default: + printk(KERN_ERR "PCIE: Unknown PVR rev. %lx\n", + PVR_REV(mfspr(SPRN_PVR))); + return -1; + } + + printk(KERN_INFO "PCIE: core rev %c detected\n", + core_rev == REV_A ? 'A' : 'B'); + /* Set PLL clock receiver to LVPECL */ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28); @@ -168,21 +190,78 @@ int ppc440spe_init_pcie(void) SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24)); udelay(3); + for (i = 0; i < 100; ++i) { + if (SDR_READ(PESDR0_PLLLCT3) & 0x10000000) + goto pll_ok; + + udelay(1); + } + + printk(KERN_INFO "PCIE: VCO output not locked: %x\n", + SDR_READ(PESDR0_PLLLCT3)); + return -1; + +pll_ok: return 0; } +static void ppc440spe_setup_utl(int port) +{ + void __iomem *utl_base; + + /* + * Map UTL registers at 0xc_1000_0n00 + */ + switch (port) { + case 0: + mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800); + break; + + case 1: + mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800); + break; + + case 2: + mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800); + } + + utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100); + + /* + * Set buffer allocations and then assert VRB and TXE. + */ + out_be32(utl_base + PEUTL_OUTTR, 0x08000000); + out_be32(utl_base + PEUTL_INTR, 0x02000000); + out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000); + out_be32(utl_base + PEUTL_PBBSZ, 0x53000000); + out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000); + out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000); + out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); + out_be32(utl_base + PEUTL_PCTL, 0x80800066); + + iounmap(utl_base); +} + int ppc440spe_init_pcie_rootport(int port) { static int core_init; - void __iomem *utl_base; u32 val = 0; int i; if (!core_init) { - ++core_init; i = ppc440spe_init_pcie(); if (i) return i; + ++core_init; } /* @@ -193,13 +272,19 @@ int ppc440spe_init_pcie_rootport(int por * - Set up UTL configuration. * - Increase SERDES drive strength to levels suggested by AMCC. * - De-assert RSTPYN, RSTDL and RSTGU. + * + * For rev. B chips, we don't set PESDRn_UTLSET2, but just + * leave it with default setting 0x11310000. The register has + * new fields, PESDRn_UTLSET2[LKINE] in particular: clearing + * it leads to a PCIe core hang. */ switch (port) { case 0: SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12); SDR_WRITE(PESDR0_UTLSET1, 0x21222222); - SDR_WRITE(PESDR0_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR0_UTLSET2, 0x11000000); SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000); @@ -218,7 +303,8 @@ int ppc440spe_init_pcie_rootport(int por SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12); SDR_WRITE(PESDR1_UTLSET1, 0x21222222); - SDR_WRITE(PESDR1_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR1_UTLSET2, 0x11000000); SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000); @@ -233,7 +319,8 @@ int ppc440spe_init_pcie_rootport(int por SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12); SDR_WRITE(PESDR2_UTLSET1, 0x21222222); - SDR_WRITE(PESDR2_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR2_UTLSET2, 0x11000000); SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000); @@ -255,78 +342,81 @@ int ppc440spe_init_pcie_rootport(int por if (!(val & (1 << 20))) printk(KERN_INFO "PCIE%d: PGRST inactive\n", port); - else - printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val); - - switch (port) { - case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break; - case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break; - case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break; + else { + printk(KERN_WARNING "PCIE%d: PGRST failed %08x\n", port, val); + return -1; } - /* - * Map UTL registers at 0xc_1000_0n00 - */ switch (port) { - case 0: - mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800); - break; - - case 1: - mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800); - break; - - case 2: - mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800); + case 0: val = SDR_READ(PESDR0_LOOP); break; + case 1: val = SDR_READ(PESDR1_LOOP); break; + case 2: val = SDR_READ(PESDR2_LOOP); break; } - utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100); + if (val & 0x1000) + printk(KERN_INFO "PCIE%d: link up\n", port); + else { + printk(KERN_WARNING "PCIE%d: link down %08x\n", port, val); + return -1; + } /* - * Set buffer allocations and then assert VRB and TXE. + * Setup UTL registers - but only on rev. A! + * Just leave rev. B with default settings. */ - out_be32(utl_base + PEUTL_OUTTR, 0x08000000); - out_be32(utl_base + PEUTL_INTR, 0x02000000); - out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000); - out_be32(utl_base + PEUTL_PBBSZ, 0x53000000); - out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000); - out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000); - out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); - out_be32(utl_base + PEUTL_PCTL, 0x80800066); - - iounmap(utl_base); + if (core_rev == REV_A) + ppc440spe_setup_utl(port); /* * We map PCI Express configuration access into the 512MB regions + * + * Rev. B is very strict about PLB real addressess and ranges + * to be mapped for config space; it seems to only work with + * 0xd_nnnn_nnnn range (the core hangs on config transaction + * attempts when set otherwise), while rev. A only works with + * 0xc_nnnn_nnnn. So we use the following ranges: + * + * Rev. A: * PCIE0: 0xc_4000_0000 * PCIE1: 0xc_8000_0000 * PCIE2: 0xc_c000_0000 + * + * Rev. B: + * PCIE0: 0xd_0000_0000 + * PCIE1: 0xd_2000_0000 + * PCIE2: 0xd_4000_0000 */ switch (port) { case 0: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */ break; case 1: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */ break; case 2: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */ break; } @@ -336,18 +426,24 @@ int ppc440spe_init_pcie_rootport(int por */ switch (port) { case 0: - if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) + if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) { printk(KERN_WARNING "PCIE0: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20); break; case 1: - if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) - printk(KERN_WARNING "PCIE0: VC0 not active\n"); + if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) { + printk(KERN_WARNING "PCIE1: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20); break; case 2: - if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) - printk(KERN_WARNING "PCIE0: VC0 not active\n"); + if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) { + printk(KERN_WARNING "PCIE2: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20); break; } @@ -375,19 +471,42 @@ void ppc440spe_setup_pcie(struct pci_con { void __iomem *mbase; - /* - * Map 16MB, which is enough for 4 bits of bus # - */ - hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000, - 1 << 24); + if (core_rev == REV_A) { + /* + * Map 16MB, which is enough for 4 bits of bus # + */ + hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000, + 1 << 24); + + mbase = ioremap64(0xc50000000ull + port * 0x40000000, 0x1000); + } else { + /* + * Rev. B is very strict about PLB real addressess and + * sizes to be mapped for config space; the core hangs + * on config transaction attempt if not set to + * 0xd_0010_0000, 0xd_2010_0000, 0xd_4010_0000 + * respectively. + */ + hose->cfg_data = ioremap64(0xd00100000ull + port * 0x20000000, + 0x400); + + /* for accessing Local Config space we need to set A[35] */ + mbase = ioremap64(0xd10000000ull + port * 0x20000000, 0x400); + } + hose->ops = &pcie_pci_ops; /* * Set bus numbers on our root port */ - mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096); - out_8(mbase + PCI_PRIMARY_BUS, 0); - out_8(mbase + PCI_SECONDARY_BUS, 0); + if (core_rev == REV_A) { + out_8(mbase + PCI_PRIMARY_BUS, 0); + out_8(mbase + PCI_SECONDARY_BUS, 0); + } else { + out_8(mbase + PCI_PRIMARY_BUS, 0); + out_8(mbase + PCI_SECONDARY_BUS, 1); + out_8(mbase + PCI_SUBORDINATE_BUS, 1); + } /* * Set up outbound translation to hose->mem_space from PLB @@ -412,7 +531,6 @@ void ppc440spe_setup_pcie(struct pci_con mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff); mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1), ~(hose->mem_space.end - hose->mem_space.start) | 3); - break; case 2: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d); -- 1.4.3.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-13 17:55 [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe Roland Dreier @ 2006-11-13 22:27 ` Wolfgang Denk 2006-11-13 22:29 ` jhon scoot 2006-11-13 22:31 ` Roland Dreier 2006-11-13 22:31 ` [PATCH v2 -- fixed changelog] " Roland Dreier 1 sibling, 2 replies; 11+ messages in thread From: Wolfgang Denk @ 2006-11-13 22:27 UTC (permalink / raw) To: Roland Dreier; +Cc: linuxppc-embedded In message <adalkmf44eu.fsf@cisco.com> you wrote: > This is mostly updating the PCI Express code to work with the new core > in the Rev. B chip, which unfortunately has different undocumented > restrictions on the PLB addresses that can be used from the Rev. A core. > > Also, when adding the cputable entry for 440SPe Rev. B, we need to > adjust the entry for 440SP Rev. A so that it looks at more bits of the > PVR. The 440SPe Rev. B has PVR 53421891, which would have matched the > old 440SP pattern of 53xxx891. > > Signed-off-by: Roland Dreier <rolandd@cisco.com> Just for the record: This patch is _heavily_ borrowed on code by Rafal Jaworowski; see http://www.denx.de/cgi-bin/gitweb.cgi?p=linux-2.6-denx.git;a=commit;h=30e3e3be8863902f508af74fdc61ec9b80756bc0 Please add correct attribution. Best regards, Wolfgang Denk -- Software Engineering: Embedded and Realtime Systems, Embedded Linux Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de "In Christianity neither morality nor religion come into contact with reality at any point." - Friedrich Nietzsche ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-13 22:27 ` Wolfgang Denk @ 2006-11-13 22:29 ` jhon scoot 2006-11-13 22:31 ` Roland Dreier 1 sibling, 0 replies; 11+ messages in thread From: jhon scoot @ 2006-11-13 22:29 UTC (permalink / raw) To: wd, rdreier; +Cc: linuxppc-embedded Roland did u are working on a settop box? with PPC440 >From: Wolfgang Denk <wd@denx.de> >To: Roland Dreier <rdreier@cisco.com> >CC: linuxppc-embedded@ozlabs.org >Subject: Re: [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe >Date: Mon, 13 Nov 2006 23:27:25 +0100 > >In message <adalkmf44eu.fsf@cisco.com> you wrote: > > This is mostly updating the PCI Express code to work with the new core > > in the Rev. B chip, which unfortunately has different undocumented > > restrictions on the PLB addresses that can be used from the Rev. A core. > > > > Also, when adding the cputable entry for 440SPe Rev. B, we need to > > adjust the entry for 440SP Rev. A so that it looks at more bits of the > > PVR. The 440SPe Rev. B has PVR 53421891, which would have matched the > > old 440SP pattern of 53xxx891. > > > > Signed-off-by: Roland Dreier <rolandd@cisco.com> > >Just for the record: > >This patch is _heavily_ borrowed on code by Rafal Jaworowski; see >http://www.denx.de/cgi-bin/gitweb.cgi?p=linux-2.6-denx.git;a=commit;h=30e3e3be8863902f508af74fdc61ec9b80756bc0 > >Please add correct attribution. > >Best regards, > >Wolfgang Denk > >-- >Software Engineering: Embedded and Realtime Systems, Embedded Linux >Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de >"In Christianity neither morality nor religion come into contact with >reality at any point." - Friedrich Nietzsche >_______________________________________________ >Linuxppc-embedded mailing list >Linuxppc-embedded@ozlabs.org >https://ozlabs.org/mailman/listinfo/linuxppc-embedded _________________________________________________________________ Try Search Survival Kits: Fix up your home and better handle your cash with Live Search! http://imagine-windowslive.com/search/kits/default.aspx?kit=improve&locale=en-US&source=hmtagline ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-13 22:27 ` Wolfgang Denk 2006-11-13 22:29 ` jhon scoot @ 2006-11-13 22:31 ` Roland Dreier 1 sibling, 0 replies; 11+ messages in thread From: Roland Dreier @ 2006-11-13 22:31 UTC (permalink / raw) To: Wolfgang Denk; +Cc: linuxppc-embedded > This patch is _heavily_ borrowed on code by Rafal Jaworowski Indeed -- I meant to add that to the change log and just forgot. I will resend now. On the other hand it might have been nice for you to submit this upstream rather than letting it sit in your tree for months and months... - R. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-13 17:55 [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe Roland Dreier 2006-11-13 22:27 ` Wolfgang Denk @ 2006-11-13 22:31 ` Roland Dreier 2006-11-14 9:01 ` Eugene Surovegin 1 sibling, 1 reply; 11+ messages in thread From: Roland Dreier @ 2006-11-13 22:31 UTC (permalink / raw) To: mporter; +Cc: linuxppc-embedded This is mostly updating the PCI Express code to work with the new core in the Rev. B chip, which unfortunately has different undocumented restrictions on the PLB addresses that can be used from the Rev. A core. Also, when adding the cputable entry for 440SPe Rev. B, we need to adjust the entry for 440SP Rev. A so that it looks at more bits of the PVR. The 440SPe Rev. B has PVR 53421891, which would have matched the old 440SP pattern of 53xxx891. This is a cleaned up version of the original work done by Rafal Jaworowski <raj@semihalf.com>, who actually suffered through figuring out how to avoid the Rev. B chip locking up when using PCIe. Signed-off-by: Roland Dreier <rolandd@cisco.com> --- Matt, please apply this version, which gives proper credit for the patch. arch/powerpc/kernel/cputable.c | 21 ++- arch/ppc/platforms/4xx/davinci_sc.c | 5 - arch/ppc/syslib/ppc440spe_pcie.c | 258 ++++++++++++++++++++++-------- drivers/infiniband/hw/mthca/mthca_main.c | 4 +- 4 files changed, 206 insertions(+), 82 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index bfd499e..04559be 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1073,8 +1073,8 @@ #ifdef CONFIG_44x .platform = "ppc440", }, { /* 440SP Rev. A */ - .pvr_mask = 0xff000fff, - .pvr_value = 0x53000891, + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53200891, .cpu_name = "440SP Rev. A", .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_USER_BOOKE, @@ -1083,9 +1083,20 @@ #ifdef CONFIG_44x .platform = "ppc440", }, { /* 440SPe Rev. A */ - .pvr_mask = 0xff000fff, - .pvr_value = 0x53000890, - .cpu_name = "440SPe Rev. A", + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53400890, + .cpu_name = "440SPe Rev. A", + .cpu_features = CPU_FTR_SPLIT_ID_CACHE | + CPU_FTR_USE_TB, + .cpu_user_features = COMMON_USER_BOOKE, + .icache_bsize = 32, + .dcache_bsize = 32, + .platform = "ppc440", + }, + { /* 440SPe Rev. B */ + .pvr_mask = 0xfff00fff, + .pvr_value = 0x53400891, + .cpu_name = "440SPe Rev. B", .cpu_features = CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, .cpu_user_features = COMMON_USER_BOOKE, diff --git a/arch/ppc/platforms/4xx/davinci_sc.c b/arch/ppc/platforms/4xx/davinci_sc.c index 623988f..3dbedda 100644 --- a/arch/ppc/platforms/4xx/davinci_sc.c +++ b/arch/ppc/platforms/4xx/davinci_sc.c @@ -172,11 +172,6 @@ davinci_sc_setup_hoses(void) char name[20]; int i; - if (0 && ppc440spe_init_pcie()) { - printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n"); - return; - } - for (i = 0; i <= 2; ++i) { if (!davinci_sc_pcie_card_present(i)) continue; diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c index dd5d4b9..7ae14d2 100644 --- a/arch/ppc/syslib/ppc440spe_pcie.c +++ b/arch/ppc/syslib/ppc440spe_pcie.c @@ -19,16 +19,23 @@ #include <asm/ibm44x.h> #include "ppc440spe_pcie.h" +static enum { + REV_A, + REV_B +} core_rev; + static int pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int len, u32 *val) { struct pci_controller *hose = bus->sysdata; - if (PCI_SLOT(devfn) != 1) + /* 440SPE implements only one function per port */ + if (PCI_SLOT(devfn) != 1 || PCI_FUNC(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; - offset += devfn << 12; + if (core_rev == REV_A) + offset += devfn << 12; /* * Note: the caller has already checked that offset is @@ -57,10 +64,11 @@ pcie_write_config(struct pci_bus *bus, u { struct pci_controller *hose = bus->sysdata; - if (PCI_SLOT(devfn) != 1) + if (PCI_SLOT(devfn) != 1 || PCI_FUNC(devfn) != 0) return PCIBIOS_DEVICE_NOT_FOUND; - offset += devfn << 12; + if (core_rev == REV_A) + offset += devfn << 12; switch (len) { case 1: @@ -153,6 +161,20 @@ static void check_error(void) */ int ppc440spe_init_pcie(void) { + int i; + + switch (PVR_REV(mfspr(SPRN_PVR))) { + case 0x1890: core_rev = REV_A; break; + case 0x1891: core_rev = REV_B; break; + default: + printk(KERN_ERR "PCIE: Unknown PVR rev. %lx\n", + PVR_REV(mfspr(SPRN_PVR))); + return -1; + } + + printk(KERN_INFO "PCIE: core rev %c detected\n", + core_rev == REV_A ? 'A' : 'B'); + /* Set PLL clock receiver to LVPECL */ SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28); @@ -168,21 +190,78 @@ int ppc440spe_init_pcie(void) SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24)); udelay(3); + for (i = 0; i < 100; ++i) { + if (SDR_READ(PESDR0_PLLLCT3) & 0x10000000) + goto pll_ok; + + udelay(1); + } + + printk(KERN_INFO "PCIE: VCO output not locked: %x\n", + SDR_READ(PESDR0_PLLLCT3)); + return -1; + +pll_ok: return 0; } +static void ppc440spe_setup_utl(int port) +{ + void __iomem *utl_base; + + /* + * Map UTL registers at 0xc_1000_0n00 + */ + switch (port) { + case 0: + mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800); + break; + + case 1: + mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800); + break; + + case 2: + mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c); + mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000); + mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001); + mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800); + } + + utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100); + + /* + * Set buffer allocations and then assert VRB and TXE. + */ + out_be32(utl_base + PEUTL_OUTTR, 0x08000000); + out_be32(utl_base + PEUTL_INTR, 0x02000000); + out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000); + out_be32(utl_base + PEUTL_PBBSZ, 0x53000000); + out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000); + out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000); + out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); + out_be32(utl_base + PEUTL_PCTL, 0x80800066); + + iounmap(utl_base); +} + int ppc440spe_init_pcie_rootport(int port) { static int core_init; - void __iomem *utl_base; u32 val = 0; int i; if (!core_init) { - ++core_init; i = ppc440spe_init_pcie(); if (i) return i; + ++core_init; } /* @@ -193,13 +272,19 @@ int ppc440spe_init_pcie_rootport(int por * - Set up UTL configuration. * - Increase SERDES drive strength to levels suggested by AMCC. * - De-assert RSTPYN, RSTDL and RSTGU. + * + * For rev. B chips, we don't set PESDRn_UTLSET2, but just + * leave it with default setting 0x11310000. The register has + * new fields, PESDRn_UTLSET2[LKINE] in particular: clearing + * it leads to a PCIe core hang. */ switch (port) { case 0: SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12); SDR_WRITE(PESDR0_UTLSET1, 0x21222222); - SDR_WRITE(PESDR0_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR0_UTLSET2, 0x11000000); SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000); @@ -218,7 +303,8 @@ int ppc440spe_init_pcie_rootport(int por SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12); SDR_WRITE(PESDR1_UTLSET1, 0x21222222); - SDR_WRITE(PESDR1_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR1_UTLSET2, 0x11000000); SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000); @@ -233,7 +319,8 @@ int ppc440spe_init_pcie_rootport(int por SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12); SDR_WRITE(PESDR2_UTLSET1, 0x21222222); - SDR_WRITE(PESDR2_UTLSET2, 0x11000000); + if (core_rev == REV_A) + SDR_WRITE(PESDR2_UTLSET2, 0x11000000); SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000); SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000); @@ -255,78 +342,81 @@ int ppc440spe_init_pcie_rootport(int por if (!(val & (1 << 20))) printk(KERN_INFO "PCIE%d: PGRST inactive\n", port); - else - printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val); - - switch (port) { - case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break; - case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break; - case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break; + else { + printk(KERN_WARNING "PCIE%d: PGRST failed %08x\n", port, val); + return -1; } - /* - * Map UTL registers at 0xc_1000_0n00 - */ switch (port) { - case 0: - mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800); - break; - - case 1: - mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800); - break; - - case 2: - mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c); - mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000); - mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001); - mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800); + case 0: val = SDR_READ(PESDR0_LOOP); break; + case 1: val = SDR_READ(PESDR1_LOOP); break; + case 2: val = SDR_READ(PESDR2_LOOP); break; } - utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100); + if (val & 0x1000) + printk(KERN_INFO "PCIE%d: link up\n", port); + else { + printk(KERN_WARNING "PCIE%d: link down %08x\n", port, val); + return -1; + } /* - * Set buffer allocations and then assert VRB and TXE. + * Setup UTL registers - but only on rev. A! + * Just leave rev. B with default settings. */ - out_be32(utl_base + PEUTL_OUTTR, 0x08000000); - out_be32(utl_base + PEUTL_INTR, 0x02000000); - out_be32(utl_base + PEUTL_OPDBSZ, 0x10000000); - out_be32(utl_base + PEUTL_PBBSZ, 0x53000000); - out_be32(utl_base + PEUTL_IPHBSZ, 0x08000000); - out_be32(utl_base + PEUTL_IPDBSZ, 0x10000000); - out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000); - out_be32(utl_base + PEUTL_PCTL, 0x80800066); - - iounmap(utl_base); + if (core_rev == REV_A) + ppc440spe_setup_utl(port); /* * We map PCI Express configuration access into the 512MB regions + * + * Rev. B is very strict about PLB real addressess and ranges + * to be mapped for config space; it seems to only work with + * 0xd_nnnn_nnnn range (the core hangs on config transaction + * attempts when set otherwise), while rev. A only works with + * 0xc_nnnn_nnnn. So we use the following ranges: + * + * Rev. A: * PCIE0: 0xc_4000_0000 * PCIE1: 0xc_8000_0000 * PCIE2: 0xc_c000_0000 + * + * Rev. B: + * PCIE0: 0xd_0000_0000 + * PCIE1: 0xd_2000_0000 + * PCIE2: 0xd_4000_0000 */ switch (port) { case 0: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */ break; case 1: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */ break; case 2: - mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); - mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); + if (core_rev == REV_A) { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); + } else { + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d); + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000); + } mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */ break; } @@ -336,18 +426,24 @@ int ppc440spe_init_pcie_rootport(int por */ switch (port) { case 0: - if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) + if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16))) { printk(KERN_WARNING "PCIE0: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20); break; case 1: - if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) - printk(KERN_WARNING "PCIE0: VC0 not active\n"); + if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16))) { + printk(KERN_WARNING "PCIE1: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20); break; case 2: - if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) - printk(KERN_WARNING "PCIE0: VC0 not active\n"); + if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16))) { + printk(KERN_WARNING "PCIE2: VC0 not active\n"); + return -1; + } SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20); break; } @@ -375,19 +471,42 @@ void ppc440spe_setup_pcie(struct pci_con { void __iomem *mbase; - /* - * Map 16MB, which is enough for 4 bits of bus # - */ - hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000, - 1 << 24); + if (core_rev == REV_A) { + /* + * Map 16MB, which is enough for 4 bits of bus # + */ + hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000, + 1 << 24); + + mbase = ioremap64(0xc50000000ull + port * 0x40000000, 0x1000); + } else { + /* + * Rev. B is very strict about PLB real addressess and + * sizes to be mapped for config space; the core hangs + * on config transaction attempt if not set to + * 0xd_0010_0000, 0xd_2010_0000, 0xd_4010_0000 + * respectively. + */ + hose->cfg_data = ioremap64(0xd00100000ull + port * 0x20000000, + 0x400); + + /* for accessing Local Config space we need to set A[35] */ + mbase = ioremap64(0xd10000000ull + port * 0x20000000, 0x400); + } + hose->ops = &pcie_pci_ops; /* * Set bus numbers on our root port */ - mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096); - out_8(mbase + PCI_PRIMARY_BUS, 0); - out_8(mbase + PCI_SECONDARY_BUS, 0); + if (core_rev == REV_A) { + out_8(mbase + PCI_PRIMARY_BUS, 0); + out_8(mbase + PCI_SECONDARY_BUS, 0); + } else { + out_8(mbase + PCI_PRIMARY_BUS, 0); + out_8(mbase + PCI_SECONDARY_BUS, 1); + out_8(mbase + PCI_SUBORDINATE_BUS, 1); + } /* * Set up outbound translation to hose->mem_space from PLB @@ -412,7 +531,6 @@ void ppc440spe_setup_pcie(struct pci_con mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff); mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1), ~(hose->mem_space.end - hose->mem_space.start) | 3); - break; case 2: mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2), 0x0000000d); diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 47ea021..c499b90 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -87,9 +87,9 @@ static const char mthca_version[] __devi DRV_VERSION " (" DRV_RELDATE ")\n"; static struct mthca_profile default_profile = { - .num_qp = 1 << 16, + .num_qp = 1 << 11, .rdb_per_qp = 4, - .num_cq = 1 << 16, + .num_cq = 1 << 11, .num_mcg = 1 << 13, .num_mpt = 1 << 17, .num_mtt = 1 << 20, -- 1.4.3.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-13 22:31 ` [PATCH v2 -- fixed changelog] " Roland Dreier @ 2006-11-14 9:01 ` Eugene Surovegin 2006-11-15 22:29 ` Roland Dreier 0 siblings, 1 reply; 11+ messages in thread From: Eugene Surovegin @ 2006-11-14 9:01 UTC (permalink / raw) To: Roland Dreier; +Cc: linuxppc-embedded On Mon, Nov 13, 2006 at 02:31:51PM -0800, Roland Dreier wrote: > This is mostly updating the PCI Express code to work with the new core > in the Rev. B chip, which unfortunately has different undocumented > restrictions on the PLB addresses that can be used from the Rev. A core. > > Also, when adding the cputable entry for 440SPe Rev. B, we need to > adjust the entry for 440SP Rev. A so that it looks at more bits of the > PVR. The 440SPe Rev. B has PVR 53421891, which would have matched the > old 440SP pattern of 53xxx891. > > This is a cleaned up version of the original work done by Rafal > Jaworowski <raj@semihalf.com>, who actually suffered through figuring > out how to avoid the Rev. B chip locking up when using PCIe. > > Signed-off-by: Roland Dreier <rolandd@cisco.com> [snip] > +static void ppc440spe_setup_utl(int port) > +{ > + void __iomem *utl_base; > + > + /* > + * Map UTL registers at 0xc_1000_0n00 > + */ > + switch (port) { > + case 0: > + mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c); > + mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000); > + mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001); > + mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800); > + break; > + > + case 1: > + mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c); > + mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000); > + mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001); > + mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800); > + break; > + > + case 2: > + mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c); > + mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000); > + mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001); > + mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800); > + } Can this be collapsed into 4 writes instead of 12? DCR accessors have supported run-time specified parameters for quite some time. [snip] > + case 0: val = SDR_READ(PESDR0_LOOP); break; > + case 1: val = SDR_READ(PESDR1_LOOP); break; > + case 2: val = SDR_READ(PESDR2_LOOP); break; I'm curious, why do we need a switch here? SDR_READ() also supports run-time parameters. [snip] > switch (port) { > case 0: > - mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); > - mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); > + if (core_rev == REV_A) { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000); > + } else { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000d); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x00000000); > + } > mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */ > break; > > case 1: > - mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); > - mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); > + if (core_rev == REV_A) { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000); > + } else { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000d); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x20000000); > + } > mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */ > break; > > case 2: > - mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); > - mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); > + if (core_rev == REV_A) { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000); > + } else { > + mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000d); > + mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0x40000000); > + } > mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */ > break; > } Can we get rid of this switch as well? There are other places like this in the patch but I think you got my idea :). -- Eugene ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-14 9:01 ` Eugene Surovegin @ 2006-11-15 22:29 ` Roland Dreier 2006-11-16 1:14 ` Eugene Surovegin 0 siblings, 1 reply; 11+ messages in thread From: Roland Dreier @ 2006-11-15 22:29 UTC (permalink / raw) To: mporter; +Cc: linuxppc-embedded > Can we get rid of this switch as well? > > There are other places like this in the patch but I think you got my > idea :). Makes sense -- I'll rework the patch to cut down on the code duplication (which is already there in my code that went upstream). I think there have to be switches (or equivalently, look-up tables) since there's no regularity in where the DCRs/SDRs for the different PCIe ports are. - R. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-15 22:29 ` Roland Dreier @ 2006-11-16 1:14 ` Eugene Surovegin 2006-11-16 1:20 ` Roland Dreier 0 siblings, 1 reply; 11+ messages in thread From: Eugene Surovegin @ 2006-11-16 1:14 UTC (permalink / raw) To: Roland Dreier; +Cc: linuxppc-embedded On Wed, Nov 15, 2006 at 02:29:51PM -0800, Roland Dreier wrote: [snip] > I think there have to be switches (or equivalently, look-up tables) > since there's no regularity in where the DCRs/SDRs for the different > PCIe ports are. Uhh, I was afraid you were gonna say this. HW guys don't make our life easier :). I think look-up tables are fine. It's not a fast path, is it? -- Eugene ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-16 1:14 ` Eugene Surovegin @ 2006-11-16 1:20 ` Roland Dreier 2006-11-16 1:26 ` Eugene Surovegin 0 siblings, 1 reply; 11+ messages in thread From: Roland Dreier @ 2006-11-16 1:20 UTC (permalink / raw) To: mporter; +Cc: linuxppc-embedded > I think look-up tables are fine. It's not a fast path, is it? Nope, that would be fine. I'll definitely cut down on the code duplication -- I'm just not sure what will end up being cleanest. I don't see that much difference between a switch and a look-up table for finding the base DCR index for a particular port. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-16 1:20 ` Roland Dreier @ 2006-11-16 1:26 ` Eugene Surovegin 2006-11-16 1:36 ` Roland Dreier 0 siblings, 1 reply; 11+ messages in thread From: Eugene Surovegin @ 2006-11-16 1:26 UTC (permalink / raw) To: Roland Dreier; +Cc: linuxppc-embedded On Wed, Nov 15, 2006 at 05:20:28PM -0800, Roland Dreier wrote: > > I think look-up tables are fine. It's not a fast path, is it? > > Nope, that would be fine. I'll definitely cut down on the code > duplication -- I'm just not sure what will end up being cleanest. I > don't see that much difference between a switch and a look-up table > for finding the base DCR index for a particular port. OK, I was just wanted to make sure you were aware that mfdcr/mtdcr supported run-time specified DCR number (from that code it wasn't clear). -- Eugene ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 -- fixed changelog] [POWERPC] Add support for Rev. B of PowerPC 440SPe 2006-11-16 1:26 ` Eugene Surovegin @ 2006-11-16 1:36 ` Roland Dreier 0 siblings, 0 replies; 11+ messages in thread From: Roland Dreier @ 2006-11-16 1:36 UTC (permalink / raw) To: mporter; +Cc: linuxppc-embedded > OK, I was just wanted to make sure you were aware that mfdcr/mtdcr > supported run-time specified DCR number (from that code it wasn't > clear). I actually didn't until you pointed it out -- mfdcr looks enough like assembly to confuse my small brain, and I guess I'm way behind the times (since the support for run-time numbers predates the beginning of git history, so it's been a _long_ time). - R. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2006-11-16 1:36 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-11-13 17:55 [PATCH] [POWERPC] Add support for Rev. B of PowerPC 440SPe Roland Dreier 2006-11-13 22:27 ` Wolfgang Denk 2006-11-13 22:29 ` jhon scoot 2006-11-13 22:31 ` Roland Dreier 2006-11-13 22:31 ` [PATCH v2 -- fixed changelog] " Roland Dreier 2006-11-14 9:01 ` Eugene Surovegin 2006-11-15 22:29 ` Roland Dreier 2006-11-16 1:14 ` Eugene Surovegin 2006-11-16 1:20 ` Roland Dreier 2006-11-16 1:26 ` Eugene Surovegin 2006-11-16 1:36 ` Roland Dreier
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).