From: Tom Rini Adrian Cox has modified the Sandpoint code to once again work on the older X2 version of the board. The older version has a number of are on the older version. Signed-off-by: Adrian Cox Signed-off-by: Tom Rini Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc/platforms/sandpoint.c | 96 ++++++++++++++++++++++++++++---- 25-akpm/arch/ppc/syslib/mpc10x_common.c | 13 ++-- 25-akpm/arch/ppc/syslib/open_pic.c | 9 ++- 25-akpm/include/asm-ppc/open_pic.h | 1 4 files changed, 100 insertions(+), 19 deletions(-) diff -puN arch/ppc/platforms/sandpoint.c~ppc32-add-support-for-sandpoint-x2 arch/ppc/platforms/sandpoint.c --- 25/arch/ppc/platforms/sandpoint.c~ppc32-add-support-for-sandpoint-x2 Thu Nov 4 14:36:30 2004 +++ 25-akpm/arch/ppc/platforms/sandpoint.c Thu Nov 4 14:36:30 2004 @@ -60,11 +60,6 @@ * of the amount of memory in the system. Once a method of determining * what version of DINK initializes the system for us, if applicable, is * found, we can hopefully stop hardcoding 32MB of RAM. - * - * It is important to note that this code only supports the Sandpoint X3 - * (all flavors) platform, and it does not support the X2 anymore. Code - * that at one time worked on the X2 can be found at: - * ftp://source.mvista.com/pub/linuxppc/obsolete/sandpoint/ */ #include @@ -107,9 +102,13 @@ #include "sandpoint.h" +/* Set non-zero if an X2 Sandpoint detected. */ +static int sandpoint_is_x2; + unsigned char __res[sizeof(bd_t)]; static void sandpoint_halt(void); +static void sandpoint_probe_type(void); /* * Define all of the IRQ senses and polarities. Taken from the @@ -129,7 +128,7 @@ static u_char sandpoint_openpic_initsens * Motorola SPS Sandpoint interrupt routing. */ static inline int -sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) { static char pci_irq_table[][4] = /* @@ -149,6 +148,27 @@ sandpoint_map_irq(struct pci_dev *dev, u return PCI_IRQ_TABLE_LOOKUP; } +static inline int +x2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 11 - i8259 on Windbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 16, 17, 18, 19 }, /* IDSEL 13 - PCI slot 1 */ + { 17, 18, 19, 16 }, /* IDSEL 14 - PCI slot 2 */ + { 18, 19, 16, 17 }, /* IDSEL 15 - PCI slot 3 */ + { 19, 16, 17, 18 }, /* IDSEL 16 - PCI slot 4 */ + }; + + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + static void __init sandpoint_setup_winbond_83553(struct pci_controller *hose) { @@ -216,6 +236,18 @@ sandpoint_setup_winbond_83553(struct pci return; } +/* On the sandpoint X2, we must avoid sending configuration cycles to + * device #12 (IDSEL addr = AD12). + */ +static int +x2_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL)) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + static void __init sandpoint_find_bridges(void) { @@ -241,7 +273,11 @@ sandpoint_find_bridges(void) ppc_md.pcibios_fixup = NULL; ppc_md.pcibios_fixup_bus = NULL; ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = sandpoint_map_irq; + if (sandpoint_is_x2) { + ppc_md.pci_map_irq = x2_map_irq; + ppc_md.pci_exclude_device = x2_exclude_device; + } else + ppc_md.pci_map_irq = x3_map_irq; } else { if (ppc_md.progress) @@ -255,6 +291,11 @@ sandpoint_find_bridges(void) static void __init sandpoint_setup_arch(void) { + /* Probe for Sandpoint model */ + sandpoint_probe_type(); + if (sandpoint_is_x2) + epic_serial_mode = 0; + loops_per_jiffy = 100000000 / HZ; #ifdef CONFIG_BLK_DEV_INITRD @@ -319,13 +360,48 @@ sandpoint_setup_arch(void) } /* + * To probe the Sandpoint type, we need to check for a connection between GPIO + * pins 6 and 7 on the NS87308 SuperIO. + */ +static void __init sandpoint_probe_type(void) +{ + u8 x; + /* First, ensure that the GPIO pins are enabled. */ + SANDPOINT_87308_SELECT_DEV(0x07); /* Select GPIO logical device */ + SANDPOINT_87308_CFG_OUTB(0x60, 0x07); /* Base address 0x700 */ + SANDPOINT_87308_CFG_OUTB(0x61, 0x00); + SANDPOINT_87308_CFG_OUTB(0x30, 0x01); /* Enable */ + + /* Now, set pin 7 to output and pin 6 to input. */ + outb((inb(0x701) | 0x80) & 0xbf, 0x701); + /* Set push-pull output */ + outb(inb(0x702) | 0x80, 0x702); + /* Set pull-up on input */ + outb(inb(0x703) | 0x40, 0x703); + /* Set output high and check */ + x = inb(0x700); + outb(x | 0x80, 0x700); + x = inb(0x700); + sandpoint_is_x2 = ! (x & 0x40); + if (ppc_md.progress && sandpoint_is_x2) + ppc_md.progress("High output says X2", 0); + /* Set output low and check */ + outb(x & 0x7f, 0x700); + sandpoint_is_x2 |= inb(0x700) & 0x40; + if (ppc_md.progress && sandpoint_is_x2) + ppc_md.progress("Low output says X2", 0); + if (ppc_md.progress && ! sandpoint_is_x2) + ppc_md.progress("Sandpoint is X3", 0); +} + +/* * Fix IDE interrupts. */ static int __init sandpoint_fix_winbond_83553(void) { - /* Make all 8259 interrupt level sensitive */ - outb(0xf8, 0x4d0); + /* Make some 8259 interrupt level sensitive */ + outb(0xe0, 0x4d0); outb(0xde, 0x4d1); return 0; @@ -398,7 +474,7 @@ sandpoint_init_IRQ(void) OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses); mpc10x_set_openpic(); - openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", + openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade", i8259_irq); /* diff -puN arch/ppc/syslib/mpc10x_common.c~ppc32-add-support-for-sandpoint-x2 arch/ppc/syslib/mpc10x_common.c --- 25/arch/ppc/syslib/mpc10x_common.c~ppc32-add-support-for-sandpoint-x2 Thu Nov 4 14:36:30 2004 +++ 25-akpm/arch/ppc/syslib/mpc10x_common.c Thu Nov 4 14:36:30 2004 @@ -43,7 +43,7 @@ #ifdef CONFIG_MPC10X_OPENPIC #ifdef CONFIG_EPIC_SERIAL_MODE -#define EPIC_IRQ_BASE 16 +#define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5) #else #define EPIC_IRQ_BASE 5 #endif @@ -69,20 +69,16 @@ static struct ocp_def mpc10x_i2c_ocp = { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_IIC, .index = 0, - .irq = MPC10X_I2C_IRQ, .additions = &mpc10x_i2c_data }; static struct ocp_def mpc10x_dma_ocp[2] = { { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_DMA, - .index = 0, - .irq = MPC10X_DMA0_IRQ -}, + .index = 0 }, { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_DMA, - .index = 1, - .irq = MPC10X_DMA1_IRQ } + .index = 1 } }; /* Set resources to match bridge memory map */ @@ -292,12 +288,15 @@ mpc10x_bridge_init(struct pci_controller MPC10X_EUMB_EPIC_SIZE); #endif mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET; + mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ; ocp_add_one_device(&mpc10x_i2c_ocp); mpc10x_dma_ocp[0].paddr = phys_eumb_base + MPC10X_EUMB_DMA_OFFSET + 0x100; + mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ; ocp_add_one_device(&mpc10x_dma_ocp[0]); mpc10x_dma_ocp[1].paddr = phys_eumb_base + MPC10X_EUMB_DMA_OFFSET + 0x200; + mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ; ocp_add_one_device(&mpc10x_dma_ocp[1]); } diff -puN arch/ppc/syslib/open_pic.c~ppc32-add-support-for-sandpoint-x2 arch/ppc/syslib/open_pic.c --- 25/arch/ppc/syslib/open_pic.c~ppc32-add-support-for-sandpoint-x2 Thu Nov 4 14:36:30 2004 +++ 25-akpm/arch/ppc/syslib/open_pic.c Thu Nov 4 14:36:30 2004 @@ -261,6 +261,9 @@ static void openpic_safe_writefield_IPI( #endif /* CONFIG_SMP */ #ifdef CONFIG_EPIC_SERIAL_MODE +/* On platforms that may use EPIC serial mode, the default is enabled. */ +int epic_serial_mode = 1; + static void __init openpic_eicr_set_clk(u_int clkval) { openpic_writefield(&OpenPIC->Global.Global_Configuration1, @@ -415,8 +418,10 @@ void __init openpic_init(int offset) openpic_set_spurious(OPENPIC_VEC_SPURIOUS); openpic_disable_8259_pass_through(); #ifdef CONFIG_EPIC_SERIAL_MODE - openpic_eicr_set_clk(7); /* Slowest value until we know better */ - openpic_enable_sie(); + if (epic_serial_mode) { + openpic_eicr_set_clk(7); /* Slowest value until we know better */ + openpic_enable_sie(); + } #endif openpic_set_priority(0); diff -puN include/asm-ppc/open_pic.h~ppc32-add-support-for-sandpoint-x2 include/asm-ppc/open_pic.h --- 25/include/asm-ppc/open_pic.h~ppc32-add-support-for-sandpoint-x2 Thu Nov 4 14:36:30 2004 +++ 25-akpm/include/asm-ppc/open_pic.h Thu Nov 4 14:36:30 2004 @@ -36,6 +36,7 @@ extern struct hw_interrupt_type open_pic extern u_int OpenPIC_NumInitSenses; extern u_char *OpenPIC_InitSenses; extern void* OpenPIC_Addr; +extern int epic_serial_mode; /* Exported functions */ extern void openpic_set_sources(int first_irq, int num_irqs, void *isr); _