/*
- * arch/ppc/platforms/sandpoint_setup.c
- *
* Board setup routines for the Motorola SPS Sandpoint Test Platform.
*
* Author: Mark A. Greer
* 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 <linux/config.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/delay.h>
-#include <linux/irq.h>
#include <linux/ide.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/serial.h>
#include <linux/tty.h> /* for linux/serial_core.h */
#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/mpc10x.h>
#include <asm/pci-bridge.h>
#include <asm/kgdb.h>
+#include <asm/ppc_sys.h>
#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
* 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] =
/*
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)
{
0x48, /* ISA-to-PCI Addr Decoder Control */
0xf0);
- /* Enable RTC and Keyboard address locations. */
- early_write_config_byte(hose,
- 0,
- devfn,
- 0x4d, /* Chip Select Control Register */
- 0x00);
-
/* Enable Port 92. */
early_write_config_byte(hose,
0,
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)
{
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)
return;
}
-#if defined(CONFIG_SERIAL_8250) && \
- (defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
-static void __init
-sandpoint_early_serial_map(void)
-{
- struct uart_port serial_req;
-
- /* Setup serial port access */
- memset(&serial_req, 0, sizeof(serial_req));
- serial_req.uartclk = UART_CLK;
- serial_req.irq = 4;
- serial_req.flags = STD_COM_FLAGS;
- serial_req.iotype = SERIAL_IO_MEM;
- serial_req.membase = (u_char *)SANDPOINT_SERIAL_0;
-
- gen550_init(0, &serial_req);
-
- if (early_serial_setup(&serial_req) != 0)
- printk(KERN_ERR "Early serial init of port 0 failed\n");
-
- /* Assume early_serial_setup() doesn't modify serial_req */
- serial_req.line = 1;
- serial_req.irq = 3; /* XXXX */
- serial_req.membase = (u_char *)SANDPOINT_SERIAL_1;
-
- gen550_init(1, &serial_req);
-
- if (early_serial_setup(&serial_req) != 0)
- printk(KERN_ERR "Early serial init of port 1 failed\n");
-}
-#endif
-
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
/* Lookup PCI host bridges */
sandpoint_find_bridges();
-#ifdef CONFIG_DUMMY_CONSOLE
- conswitchp = &dummy_con;
+ if (strncmp (cur_ppc_sys_spec->ppc_sys_name, "8245", 4) == 0)
+ {
+ bd_t *bp = (bd_t *)__res;
+ struct plat_serial8250_port *pdata;
+
+ pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC10X_UART0);
+ if (pdata)
+ {
+ pdata[0].uartclk = bp->bi_busfreq;
+ }
+
+#ifdef CONFIG_SANDPOINT_ENABLE_UART1
+ pdata = (struct plat_serial8250_port *) ppc_sys_get_pdata(MPC10X_UART1);
+ if (pdata)
+ {
+ pdata[0].uartclk = bp->bi_busfreq;
+ }
+#else
+ ppc_sys_device_remove(MPC10X_UART1);
#endif
+ }
printk(KERN_INFO "Motorola SPS Sandpoint Test Platform\n");
printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n");
* We will do this now with good known values. Future versions
* of DINK32 are supposed to get this correct.
*/
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPEC7450)
+ if (cpu_has_feature(CPU_FTR_SPEC7450))
/* 745x is different. We only want to pass along enable. */
_set_L2CR(L2CR_L2E);
- else if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)
+ else if (cpu_has_feature(CPU_FTR_L2CR))
/* All modules have 1MB of L2. We also assume that an
* L2 divisor of 3 will work.
*/
| L2CR_L2RAM_PIPE | L2CR_L2OH_1_0 | L2CR_L2DF);
#if 0
/* Untested right now. */
- if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR) {
+ if (cpu_has_feature(CPU_FTR_L3CR)) {
/* Magic value. */
_set_L3CR(0x8f032000);
}
SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \
}
+/*
+ * 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;
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);
- /*
- * openpic_init() has set up irq_desc[16-31] to be openpic
- * interrupts. We need to set irq_desc[0-15] to be i8259
- * interrupts.
- */
- for(i=0; i < NUM_8259_INTERRUPTS; i++)
- irq_desc[i].handler = &i8259_pic;
-
/*
* The EPIC allows for a read in the range of 0xFEF00000 ->
* 0xFEFFFFFF to generate a PCI interrupt-acknowledge transaction.
*/
- i8259_init(0xfef00000);
-}
-
-static u32
-sandpoint_irq_canonicalize(u32 irq)
-{
- if (irq == 2)
- return 9;
- else
- return irq;
+ i8259_init(0xfef00000, 0);
}
static unsigned long __init
static void
sandpoint_ide_probe(void)
{
- struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND,
+ struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_WINBOND,
PCI_DEVICE_ID_WINBOND_82C105, NULL);
if (pdev) {
sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start;
sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start;
sandpoint_idedma_regbase=pdev->resource[4].start;
+ pci_dev_put(pdev);
}
sandpoint_ide_ports_known = 1;
ISA_DMA_THRESHOLD = 0x00ffffff;
DMA_MODE_READ = 0x44;
DMA_MODE_WRITE = 0x48;
+ ppc_do_canonicalize_irqs = 1;
ppc_md.setup_arch = sandpoint_setup_arch;
ppc_md.show_cpuinfo = sandpoint_show_cpuinfo;
- ppc_md.irq_canonicalize = sandpoint_irq_canonicalize;
ppc_md.init_IRQ = sandpoint_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
ppc_md.nvram_read_val = todc_mc146818_read_val;
ppc_md.nvram_write_val = todc_mc146818_write_val;
-#if defined(CONFIG_SERIAL_8250) && \
- (defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG))
- sandpoint_early_serial_map();
#ifdef CONFIG_KGDB
ppc_md.kgdb_map_scc = gen550_kgdb_map_scc;
#endif
#ifdef CONFIG_SERIAL_TEXT_DEBUG
ppc_md.progress = gen550_progress;
#endif
-#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ppc_ide_md.default_irq = sandpoint_ide_default_irq;