From 6bfeccdc110a4f92e44d51d67b274977392cbf46 Mon Sep 17 00:00:00 2001 From: Zang Roy-r61911 Date: Thu, 15 Mar 2007 10:37:56 +1100 Subject: [POWERPC] kernel: Remove loops_per_jiffy code for 7448HPC2 platforms Remove loops_per_jiffy early initialization code for 7448HPC2 platforms. Since udelay no longer uses loops_per_jiffy it is not necessary to initialize it early. Signed-off-by: Roy Zang Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'arch/powerpc/platforms/embedded6xx') diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index c3f64ddb0be6..366702e8c038 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -72,22 +72,10 @@ int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) static void __init mpc7448_hpc2_setup_arch(void) { - struct device_node *cpu; struct device_node *np; if (ppc_md.progress) ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu != 0) { - const unsigned int *fp; - - fp = of_get_property(cpu, "clock-frequency", NULL); - if (fp != 0) - loops_per_jiffy = *fp / HZ; - else - loops_per_jiffy = 50000000 / HZ; - of_node_put(cpu); - } tsi108_csr_vir_base = get_vir_csrbase(); /* setup PCI host bridge */ -- cgit v1.2.3 From 08390db07a012b972189629a30eb695cdcb0ec14 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 8 May 2007 07:25:22 +1000 Subject: [POWERPC] Add tsi108_pci.h for common PCI functions Add a header file for the common PCI routines used for the TSI bridge Signed-off-by: Josh Boyer Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 5 +-- arch/powerpc/sysdev/tsi108_pci.c | 1 + include/asm-powerpc/tsi108_pci.h | 45 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 include/asm-powerpc/tsi108_pci.h (limited to 'arch/powerpc/platforms/embedded6xx') diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 366702e8c038..06c86a1b4fb0 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -41,6 +41,7 @@ #include #include #include "mpc7448_hpc2.h" +#include #include #include @@ -57,10 +58,7 @@ isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; #endif -extern int tsi108_setup_pci(struct device_node *dev); extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); -extern void tsi108_pci_int_init(struct device_node *node); -extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) { @@ -210,7 +208,6 @@ static int __init mpc7448_hpc2_probe(void) static int mpc7448_machine_check_exception(struct pt_regs *regs) { - extern void tsi108_clear_pci_cfg_error(void); const struct exception_table_entry *entry; /* Are we prepared to handle this fault */ diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 58b9e7f8abf2..76c32be4a6b0 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/include/asm-powerpc/tsi108_pci.h b/include/asm-powerpc/tsi108_pci.h new file mode 100644 index 000000000000..f3be7d90d267 --- /dev/null +++ b/include/asm-powerpc/tsi108_pci.h @@ -0,0 +1,45 @@ +/* + * Copyright 2007 IBM Corp + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_PPC_TSI108_PCI_H +#define _ASM_PPC_TSI108_PCI_H + +#include + +/* Register definitions */ +#define TSI108_PCI_P2O_BAR0 (TSI108_PCI_OFFSET + 0x10) +#define TSI108_PCI_P2O_BAR0_UPPER (TSI108_PCI_OFFSET + 0x14) +#define TSI108_PCI_P2O_BAR2 (TSI108_PCI_OFFSET + 0x18) +#define TSI108_PCI_P2O_BAR2_UPPER (TSI108_PCI_OFFSET + 0x1c) +#define TSI108_PCI_P2O_PAGE_SIZES (TSI108_PCI_OFFSET + 0x4c) +#define TSI108_PCI_PFAB_BAR0 (TSI108_PCI_OFFSET + 0x204) +#define TSI108_PCI_PFAB_BAR0_UPPER (TSI108_PCI_OFFSET + 0x208) +#define TSI108_PCI_PFAB_IO (TSI108_PCI_OFFSET + 0x20c) +#define TSI108_PCI_PFAB_IO_UPPER (TSI108_PCI_OFFSET + 0x210) +#define TSI108_PCI_PFAB_MEM32 (TSI108_PCI_OFFSET + 0x214) +#define TSI108_PCI_PFAB_PFM3 (TSI108_PCI_OFFSET + 0x220) +#define TSI108_PCI_PFAB_PFM4 (TSI108_PCI_OFFSET + 0x230) + +extern int tsi108_setup_pci(struct device_node *dev); +extern void tsi108_pci_int_init(struct device_node *node); +extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); +extern void tsi108_clear_pci_cfg_error(void); + +#endif /* _ASM_PPC_TSI108_PCI_H */ -- cgit v1.2.3 From 05ad6a9159401804c9bcec8922a9c4a1cb2bfb59 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 8 May 2007 07:27:15 +1000 Subject: [POWERPC] Generalize tsi108 PCI setup Generalize tsi108_setup_pci to take the config space physical address and primary bus designator as a parameter. Signed-off-by: Josh Boyer Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 4 +++- arch/powerpc/sysdev/tsi108_pci.c | 11 ++++++----- include/asm-powerpc/tsi108.h | 1 - include/asm-powerpc/tsi108_pci.h | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'arch/powerpc/platforms/embedded6xx') diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index 06c86a1b4fb0..4542e0c837c0 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -52,6 +52,8 @@ #define DBG(fmt...) do { } while(0) #endif +#define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000 + #ifndef CONFIG_PCI isa_io_base = MPC7448_HPC2_ISA_IO_BASE; isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; @@ -79,7 +81,7 @@ static void __init mpc7448_hpc2_setup_arch(void) /* setup PCI host bridge */ #ifdef CONFIG_PCI for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) - tsi108_setup_pci(np); + tsi108_setup_pci(np, MPC7448HPC2_PCI_CFG_PHYS, 0); ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; if (ppc_md.progress) diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 76c32be4a6b0..2153163fa593 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -50,6 +50,7 @@ ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) u32 tsi108_pci_cfg_base; +static u32 tsi108_pci_cfg_phys; u32 tsi108_csr_vir_base; static struct device_node *pci_irq_node; static struct irq_host *pci_irq_host; @@ -186,7 +187,7 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, void tsi108_clear_pci_cfg_error(void) { - tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); + tsi108_clear_pci_error(tsi108_pci_cfg_phys); } static struct pci_ops tsi108_direct_pci_ops = { @@ -194,17 +195,17 @@ static struct pci_ops tsi108_direct_pci_ops = { tsi108_direct_write_config }; -int __init tsi108_setup_pci(struct device_node *dev) +int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; - int primary = 0, has_address = 0; + int has_address = 0; /* PCI Config mapping */ - tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, - TSI108_PCI_CFG_SIZE); + tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE); + tsi108_pci_cfg_phys = cfg_phys; DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, tsi108_pci_cfg_base); diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h index 20cb072d45ae..f8b60793b7a9 100644 --- a/include/asm-powerpc/tsi108.h +++ b/include/asm-powerpc/tsi108.h @@ -68,7 +68,6 @@ #define TSI108_PB_ERRCS_ES (1 << 1) #define TSI108_PB_ISR_PBS_RD_ERR (1 << 8) -#define TSI108_PCI_CFG_BASE_PHYS (0xfb000000) #define TSI108_PCI_CFG_SIZE (0x01000000) /* diff --git a/include/asm-powerpc/tsi108_pci.h b/include/asm-powerpc/tsi108_pci.h index f3be7d90d267..a9f92f73232c 100644 --- a/include/asm-powerpc/tsi108_pci.h +++ b/include/asm-powerpc/tsi108_pci.h @@ -37,7 +37,7 @@ #define TSI108_PCI_PFAB_PFM3 (TSI108_PCI_OFFSET + 0x220) #define TSI108_PCI_PFAB_PFM4 (TSI108_PCI_OFFSET + 0x230) -extern int tsi108_setup_pci(struct device_node *dev); +extern int tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary); extern void tsi108_pci_int_init(struct device_node *node); extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); extern void tsi108_clear_pci_cfg_error(void); -- cgit v1.2.3 From cb9e4d10c448a388babd9dfbfa2b8bb1c5bbf84f Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 8 May 2007 07:28:38 +1000 Subject: [POWERPC] Add support for 750CL Holly board Add PowerPC 750 Holly/Hickory platform support Signed-off-by: Stephen Winiecki Signed-off-by: Josh Boyer Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 2 +- arch/powerpc/platforms/embedded6xx/Kconfig | 14 +- arch/powerpc/platforms/embedded6xx/Makefile | 1 + arch/powerpc/platforms/embedded6xx/holly.c | 317 ++++++++++++++++++++++++++++ 4 files changed, 330 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/platforms/embedded6xx/holly.c (limited to 'arch/powerpc/platforms/embedded6xx') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 49b1ea275eba..5ada5b45cbb1 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -664,7 +664,7 @@ config MCA config PCI bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ - || MPC7448HPC2 || PPC_PS3 + || MPC7448HPC2 || PPC_PS3 || PPC_HOLLY default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ && !PPC_85xx && !PPC_86xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 9557908ef545..8f3c2a73e165 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -20,16 +20,24 @@ config MPC7448HPC2 select TSI108_BRIDGE select DEFAULT_UIMAGE select PPC_UDBG_16550 - select MPIC - select MPIC_WEIRD help Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) platform + +config PPC_HOLLY + bool "PPC750GX/CL with TSI10x bridge (Hickory/Holly)" + select TSI108_BRIDGE + select PPC_UDBG_16550 + help + Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval + Board with TSI108/9 bridge (Hickory/Holly) endchoice config TSI108_BRIDGE bool - depends on MPC7448HPC2 + depends on MPC7448HPC2 || PPC_HOLLY + select MPIC + select MPIC_WEIRD default y config MPC10X_BRIDGE diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index d3d11a3cd656..b39fe4f470d5 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o +obj-$(CONFIG_PPC_HOLLY) += holly.o diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c new file mode 100644 index 000000000000..3a0b4a01401c --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/holly.c @@ -0,0 +1,317 @@ +/* + * Board setup routines for the IBM 750GX/CL platform w/ TSI10x bridge + * + * Copyright 2007 IBM Corporation + * + * Stephen Winiecki + * Josh Boyer + * + * Based on code from mpc7448_hpc2.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#define HOLLY_PCI_CFG_PHYS 0x7c000000 + +int holly_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +static void holly_remap_bridge(void) +{ + u32 lut_val, lut_addr; + int i; + + printk(KERN_INFO "Remapping PCI bridge\n"); + + /* Re-init the PCI bridge and LUT registers to have mappings that don't + * rely on PIBS + */ + lut_addr = 0x900; + for (i = 0; i < 31; i++) { + tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000201); + lut_addr += 4; + tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0); + lut_addr += 4; + } + + /* Reserve the last LUT entry for PCI I/O space */ + tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x00000241); + lut_addr += 4; + tsi108_write_reg(TSI108_PB_OFFSET + lut_addr, 0x0); + + /* Map PCI I/O space */ + tsi108_write_reg(TSI108_PCI_PFAB_IO_UPPER, 0x0); + tsi108_write_reg(TSI108_PCI_PFAB_IO, 0x1); + + /* Map PCI CFG space */ + tsi108_write_reg(TSI108_PCI_PFAB_BAR0_UPPER, 0x0); + tsi108_write_reg(TSI108_PCI_PFAB_BAR0, 0x7c000000 | 0x01); + + /* We don't need MEM32 and PRM remapping so disable them */ + tsi108_write_reg(TSI108_PCI_PFAB_MEM32, 0x0); + tsi108_write_reg(TSI108_PCI_PFAB_PFM3, 0x0); + tsi108_write_reg(TSI108_PCI_PFAB_PFM4, 0x0); + + /* Set P2O_BAR0 */ + tsi108_write_reg(TSI108_PCI_P2O_BAR0_UPPER, 0x0); + tsi108_write_reg(TSI108_PCI_P2O_BAR0, 0xc0000000); + + /* Init the PCI LUTs to do no remapping */ + lut_addr = 0x500; + lut_val = 0x00000002; + + for (i = 0; i < 32; i++) { + tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, lut_val); + lut_addr += 4; + tsi108_write_reg(TSI108_PCI_OFFSET + lut_addr, 0x40000000); + lut_addr += 4; + lut_val += 0x02000000; + } + tsi108_write_reg(TSI108_PCI_P2O_PAGE_SIZES, 0x00007900); + + /* Set 64-bit PCI bus address for system memory */ + tsi108_write_reg(TSI108_PCI_P2O_BAR2_UPPER, 0x0); + tsi108_write_reg(TSI108_PCI_P2O_BAR2, 0x0); +} + +static void __init holly_setup_arch(void) +{ + struct device_node *cpu; + struct device_node *np; + + if (ppc_md.progress) + ppc_md.progress("holly_setup_arch():set_bridge", 0); + + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu) { + const unsigned int *fp; + + fp = of_get_property(cpu, "clock-frequency", NULL); + if (fp) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(cpu); + } + tsi108_csr_vir_base = get_vir_csrbase(); + + /* setup PCI host bridge */ + holly_remap_bridge(); + + np = of_find_node_by_type(NULL, "pci"); + if (np) + tsi108_setup_pci(np, HOLLY_PCI_CFG_PHYS, 1); + + ppc_md.pci_exclude_device = holly_exclude_device; + if (ppc_md.progress) + ppc_md.progress("tsi108: resources set", 0x100); + + printk(KERN_INFO "PPC750GX/CL Platform\n"); +} + +/* + * Interrupt setup and service. Interrrupts on the holly come + * from the four external INT pins, PCI interrupts are routed via + * PCI interrupt control registers, it generates internal IRQ23 + * + * Interrupt routing on the Holly Board: + * TSI108:PB_INT[0] -> CPU0:INT# + * TSI108:PB_INT[1] -> CPU0:MCP# + * TSI108:PB_INT[2] -> N/C + * TSI108:PB_INT[3] -> N/C + */ +static void __init holly_init_IRQ(void) +{ + struct mpic *mpic; + phys_addr_t mpic_paddr = 0; + struct device_node *tsi_pic; +#ifdef CONFIG_PCI + unsigned int cascade_pci_irq; + struct device_node *tsi_pci; + struct device_node *cascade_node = NULL; +#endif + + tsi_pic = of_find_node_by_type(NULL, "open-pic"); + if (tsi_pic) { + unsigned int size; + const void *prop = of_get_property(tsi_pic, "reg", &size); + mpic_paddr = of_translate_address(tsi_pic, prop); + } + + if (mpic_paddr == 0) { + printk(KERN_ERR "%s: No tsi108 PIC found !\n", __func__); + return; + } + + pr_debug("%s: tsi108 pic phys_addr = 0x%x\n", __func__, (u32) mpic_paddr); + + mpic = mpic_alloc(tsi_pic, mpic_paddr, + MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, + 24, + NR_IRQS-4, /* num_sources used */ + "Tsi108_PIC"); + + BUG_ON(mpic == NULL); + + mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); + + mpic_init(mpic); + +#ifdef CONFIG_PCI + tsi_pci = of_find_node_by_type(NULL, "pci"); + if (tsi_pci == NULL) { + printk(KERN_ERR "%s: No tsi108 pci node found !\n", __func__); + return; + } + + cascade_node = of_find_node_by_type(NULL, "pic-router"); + if (cascade_node == NULL) { + printk(KERN_ERR "%s: No tsi108 pci cascade node found !\n", __func__); + return; + } + + cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); + pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq); + tsi108_pci_int_init(cascade_node); + set_irq_data(cascade_pci_irq, mpic); + set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); +#endif + /* Configure MPIC outputs to CPU0 */ + tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); + of_node_put(tsi_pic); +} + +void holly_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: PPC750 GX/CL\n"); +} + +void holly_restart(char *cmd) +{ + __be32 __iomem *ocn_bar1 = NULL; + unsigned long bar; + struct device_node *bridge = NULL; + const void *prop; + int size; + phys_addr_t addr = 0xc0000000; + + local_irq_disable(); + + bridge = of_find_node_by_type(NULL, "tsi-bridge"); + if (bridge) { + prop = of_get_property(bridge, "reg", &size); + addr = of_translate_address(bridge, prop); + } + addr += (TSI108_PB_OFFSET + 0x414); + + ocn_bar1 = ioremap(addr, 0x4); + + /* Turn on the BOOT bit so the addresses are correctly + * routed to the HLP interface */ + bar = ioread32be(ocn_bar1); + bar |= 2; + iowrite32be(bar, ocn_bar1); + iosync(); + + /* Set SRR0 to the reset vector and turn on MSR_IP */ + mtspr(SPRN_SRR0, 0xfff00100); + mtspr(SPRN_SRR1, MSR_IP); + + /* Do an rfi to jump back to firmware. Somewhat evil, + * but it works + */ + __asm__ __volatile__("rfi" : : : "memory"); + + /* Spin until reset happens. Shouldn't really get here */ + for (;;) ; +} + +void holly_power_off(void) +{ + local_irq_disable(); + /* No way to shut power off with software */ + for (;;) ; +} + +void holly_halt(void) +{ + holly_power_off(); +} + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init holly_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "ibm,holly")) + return 0; + return 1; +} + +static int ppc750_machine_check_exception(struct pt_regs *regs) +{ + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + tsi108_clear_pci_cfg_error(); + regs->msr |= MSR_RI; + regs->nip = entry->fixup; + return 1; + } + return 0; +} + +define_machine(holly){ + .name = "PPC750 GX/CL TSI", + .probe = holly_probe, + .setup_arch = holly_setup_arch, + .init_IRQ = holly_init_IRQ, + .show_cpuinfo = holly_show_cpuinfo, + .get_irq = mpic_get_irq, + .restart = holly_restart, + .calibrate_decr = generic_calibrate_decr, + .machine_check_exception = ppc750_machine_check_exception, + .progress = udbg_progress, +}; -- cgit v1.2.3