Based on original work by David 'Shaggy' Kliekamp.
Signed-off-by: Tony Breeds t...@bakeyournoodle.com
---
arch/powerpc/include/asm/reg.h |1 +
arch/powerpc/kernel/cputable.c | 14 +
arch/powerpc/kernel/head_44x.S |2 +
arch/powerpc/platforms/44x/Kconfig |4 ++
arch/powerpc/sysdev/ppc4xx_pci.c | 57 +++-
arch/powerpc/sysdev/ppc4xx_pci.h |7
6 files changed, 84 insertions(+), 1 deletions(-)
I wimped out on doing the mask and test opperations in head_44x.S for the
generic 476 PVR.
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 559da19..7fdc2c0 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -951,6 +951,7 @@
#define PVR_403GCX 0x00201400
#define PVR_405GP 0x4011
#define PVR_4760x11a52000
+#define PVR_476FPE 0x7ff5
#define PVR_STB03XXX 0x4031
#define PVR_NP405H 0x4141
#define PVR_NP405L 0x4161
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index edae5bb..7797ae2 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1830,6 +1830,20 @@ static struct cpu_spec __initdata cpu_specs[] = {
.machine_check = machine_check_47x,
.platform = ppc470,
},
+ { /* 476fpe */
+ .pvr_mask = 0x,
+ .pvr_value = 0x7ff5,
+ .cpu_name = 476fpe,
+ .cpu_features = CPU_FTRS_47X | CPU_FTR_476_DD2,
+ .cpu_user_features = COMMON_USER_BOOKE |
+ PPC_FEATURE_HAS_FPU,
+ .mmu_features = MMU_FTR_TYPE_47x |
+ MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
+ .icache_bsize = 32,
+ .dcache_bsize = 128,
+ .machine_check = machine_check_47x,
+ .platform = ppc470,
+ },
{ /* 476 iss */
.pvr_mask = 0x,
.pvr_value = 0x0005,
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index b725dab..bb7a9c7 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -732,6 +732,8 @@ _GLOBAL(init_cpu_state)
/* We use the PVR to differenciate 44x cores from 476 */
mfspr r3,SPRN_PVR
srwir3,r3,16
+ cmplwi cr0,r3,PVR_476FPE@h
+ beq head_start_47x
cmplwi cr0,r3,PVR_476@h
beq head_start_47x
cmplwi cr0,r3,PVR_476_ISS@h
diff --git a/arch/powerpc/platforms/44x/Kconfig
b/arch/powerpc/platforms/44x/Kconfig
index 762322c..f0be6e0 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -308,6 +308,10 @@ config 460SX
select IBM_EMAC_ZMII
select IBM_EMAC_TAH
+config 476FPE
+ bool
+ select PPC_FPU
+
config APM821xx
bool
select PPC_FPU
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 45148ef..ae15e6f 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -1296,6 +1296,52 @@ static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops
__initdata =
#endif /* CONFIG_40x */
+#ifdef CONFIG_476FPE
+static int __init ppc_476fpe_pciex_core_init(struct device_node *np)
+{
+ return 4;
+}
+
+static void __init ppc_476fpe_pciex_check_link(struct ppc4xx_pciex_port *port)
+{
+ u32 timeout_ms = 20;
+ u32 val = 0, mask = (PECFG_TLDLP_LNKUP|PECFG_TLDLP_PRESENT);
+ void __iomem *mbase = ioremap(port-cfg_space.start + 0x1000,
+ 0x1000);
+
+ printk(KERN_INFO PCIE%d: Checking link...\n, port-index);
+
+ if (mbase == NULL) {
+ printk(KERN_WARNING PCIE%d: failed to get cfg space\n,
+ port-index);
+ return;
+ }
+
+ while (timeout_ms--) {
+ val = in_le32(mbase + PECFG_TLDLP);
+
+ if ((val mask) == mask)
+ break;
+ msleep(10);
+ }
+
+ if (val PECFG_TLDLP_PRESENT) {
+ printk(KERN_INFO PCIE%d: link is up !\n, port-index);
+ port-link = 1;
+ } else
+ printk(KERN_WARNING PCIE%d: Link up failed\n, port-index);
+
+ iounmap(mbase);
+ return;
+}
+
+static struct ppc4xx_pciex_hwops ppc_476fpe_pcie_hwops __initdata =
+{
+ .core_init = ppc_476fpe_pciex_core_init,
+ .check_link = ppc_476fpe_pciex_check_link,
+};
+#endif /* CONFIG_476FPE */
+
/* Check that the core has been initied and if not, do it */
static int __init ppc4xx_pciex_check_core_init(struct device_node *np)
{
@@ -1321,6 +1367,10