patch-2.4.19 linux-2.4.19/arch/mips/au1000/pb1000/setup.c

Next file: linux-2.4.19/arch/mips/au1000/pb1500/Makefile
Previous file: linux-2.4.19/arch/mips/au1000/pb1000/pci_ops.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/arch/mips/au1000/pb1000/setup.c linux-2.4.19/arch/mips/au1000/pb1000/setup.c
@@ -1,7 +1,7 @@
 /*
  *
  * BRIEF MODULE DESCRIPTION
- *	Au1000-based board setup.
+ *	Alchemy Pb1000 board setup.
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
@@ -31,45 +31,51 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ioport.h>
+#include <linux/mm.h>
 #include <linux/console.h>
 #include <linux/mc146818rtc.h>
+#include <linux/delay.h>
 
 #include <asm/cpu.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
+#include <asm/keyboard.h>
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
+#include <asm/pgtable.h>
 #include <asm/au1000.h>
+#include <asm/pb1000.h>
+
+#ifdef CONFIG_USB_OHCI
+// Enable the workaround for the OHCI DoneHead
+// register corruption problem.
+#define CONFIG_AU1000_OHCI_FIX
+#endif
 
 #if defined(CONFIG_AU1000_SERIAL_CONSOLE)
 extern void console_setup(char *, int *);
 char serial_console[20];
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+extern unsigned long initrd_start, initrd_end;
+extern void * __rd_start, * __rd_end;
+#endif
+
+#ifdef CONFIG_BLK_DEV_IDE
+extern struct ide_ops std_ide_ops;
+extern struct ide_ops *ide_ops;
+#endif
+
 void (*__wbflush) (void);
 extern struct rtc_ops no_rtc_ops;
 extern char * __init prom_getcmdline(void);
-extern void au1000_restart(void);
+extern void au1000_restart(char *);
 extern void au1000_halt(void);
 extern void au1000_power_off(void);
+extern struct resource ioport_resource;
+extern struct resource iomem_resource;
 
-struct {
-    struct resource ram;
-    struct resource io;
-    struct resource sram;
-    struct resource flash;
-    struct resource boot;
-    struct resource pcmcia;
-    struct resource lcd;
-} au1000_resources = {
-    { "RAM",           0,          0x3FFFFFF,  IORESOURCE_MEM },
-    { "I/O",           0x10000000, 0x119FFFFF                 },
-    { "SRAM",          0x1e000000, 0x1E03FFFF                 },
-    { "System Flash",  0x1F800000, 0x1FBFFFFF                 },
-    { "Boot ROM",      0x1FC00000, 0x1FFFFFFF                 },
-    { "PCMCIA",        0x20000000, 0x27FFFFFF                 },
-    { "LCD",           0x60000000, 0x603FFFFF                 },
-};
 
 void au1000_wbflush(void)
 {
@@ -79,39 +85,223 @@
 void __init au1000_setup(void)
 {
 	char *argptr;
-
+	u32 pin_func, static_cfg0;
+	u32 sys_freqctrl, sys_clksrc;
+	u32 prid = read_32bit_cp0_register(CP0_PRID);
+	
 	argptr = prom_getcmdline();
 
+	/* Various early Au1000 Errata corrected by this */
+	set_cp0_config(1<<19); /* Config[OD] */
+
 #ifdef CONFIG_AU1000_SERIAL_CONSOLE
-	if ((argptr = strstr(argptr, "console=ttyS0")) == NULL) {
+	if ((argptr = strstr(argptr, "console=")) == NULL) {
 		argptr = prom_getcmdline();
 		strcat(argptr, " console=ttyS0,115200");
 	}
 #endif	  
 
-	//set_cp0_status(ST0_FR,0);
 	rtc_ops = &no_rtc_ops;
         __wbflush = au1000_wbflush;
 	_machine_restart = au1000_restart;
 	_machine_halt = au1000_halt;
 	_machine_power_off = au1000_power_off;
 
-	/*
-	 * IO/MEM resources. 
-	 */
-	mips_io_port_base = KSEG1;
-	ioport_resource.start = au1000_resources.io.start;
-	ioport_resource.end = au1000_resources.lcd.end;
+	// IO/MEM resources. 
+	set_io_port_base(0);
+	ioport_resource.start = 0x10000000;
+	ioport_resource.end = 0xffffffff;
+	iomem_resource.start = 0x10000000;
+	iomem_resource.end = 0xffffffff;
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+	initrd_start = (unsigned long)&__rd_start;
+	initrd_end = (unsigned long)&__rd_end;
 #endif
 
-	outl(PC_CNTRL_E0 | PC_CNTRL_EN0 | PC_CNTRL_EN0, PC_COUNTER_CNTRL);
-	while (inl(PC_COUNTER_CNTRL) & PC_CNTRL_T0S);
-	outl(0x8000-1, PC0_TRIM);
+	// set AUX clock to 12MHz * 8 = 96 MHz
+	outl(8, SYS_AUXPLL);
+	outl(0, SYS_PINSTATERD);
+	udelay(100);
+
+#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+#ifdef CONFIG_USB_OHCI
+	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
+	        char usb_args[80];
+		argptr = prom_getcmdline();
+		memset(usb_args, 0, sizeof(usb_args));
+		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
+			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
+		strcat(argptr, usb_args);
+	}
+#endif
 
-	printk("Alchemy Semi PB1000 Board\n");
-	printk("Au1000/PB1000 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n");
-}
+	/* zero and disable FREQ2 */
+	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* zero and disable USBH/USBD clocks */
+	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+	outl(sys_clksrc, SYS_CLKSRC);
+
+	sys_freqctrl = inl(SYS_FREQCTRL0);
+	sys_freqctrl &= ~0xFFF00000;
+
+	sys_clksrc = inl(SYS_CLKSRC);
+	sys_clksrc &= ~0x00007FE0;
+
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+	/* CPU core freq to 48MHz to slow it way down... */
+	outl(4, SYS_CPUPLL);
+
+	/*
+	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
+	 */
+	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
+	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+
+	/* CPU core freq to 384MHz */
+	outl(0x20, SYS_CPUPLL);
+
+	printk("Au1000: 48MHz OHCI workaround enabled\n");
+		break;
+
+	default:  /* HC and newer */
+	// FREQ2 = aux/2 = 48 MHz
+	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
+	outl(sys_freqctrl, SYS_FREQCTRL0);
+		break;
+	}
 
+	/*
+	 * Route 48MHz FREQ2 into USB Host and/or Device
+	 */
+#ifdef CONFIG_USB_OHCI
+	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
+#endif
+#ifdef CONFIG_AU1000_USB_DEVICE
+	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
+#endif
+	outl(sys_clksrc, SYS_CLKSRC);
+
+#ifdef CONFIG_USB_OHCI
+	// enable host controller and wait for reset done
+	outl(0x08, USB_HOST_CONFIG);
+	udelay(1000);
+	outl(0x0E, USB_HOST_CONFIG);
+	udelay(1000);
+	inl(USB_HOST_CONFIG); // throw away first read
+	while (!(inl(USB_HOST_CONFIG) & 0x10))
+		inl(USB_HOST_CONFIG);
+#endif
+	
+	// configure pins GPIO[14:9] as GPIO
+	pin_func = inl(SYS_PINFUNC) & (u32)(~0x8080);
+
+#ifndef CONFIG_AU1000_USB_DEVICE
+	// 2nd USB port is USB host
+	pin_func |= 0x8000;
+#endif
+	outl(pin_func, SYS_PINFUNC);
+	outl(0x2800, SYS_TRIOUTCLR);
+	outl(0x0030, SYS_OUTPUTCLR);
+#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
+
+	// make gpio 15 an input (for interrupt line) 
+	pin_func = inl(SYS_PINFUNC) & (u32)(~0x100);
+	// we don't need I2S, so make it available for GPIO[31:29] 
+	pin_func |= (1<<5);
+	outl(pin_func, SYS_PINFUNC);
+
+	outl(0x8000, SYS_TRIOUTCLR);
+	
+#ifdef CONFIG_FB
+	conswitchp = &dummy_con;
+#endif
+
+	static_cfg0 = inl(MEM_STCFG0) & (u32)(~0xc00);
+	outl(static_cfg0, MEM_STCFG0);
+
+	// configure RCE2* for LCD
+	outl(0x00000004, MEM_STCFG2);
+
+	// MEM_STTIME2
+	outl(0x09000000, MEM_STTIME2);
+
+	// Set 32-bit base address decoding for RCE2*
+	outl(0x10003ff0, MEM_STADDR2);
+
+	// PCI CPLD setup
+	// expand CE0 to cover PCI
+	outl(0x11803e40, MEM_STADDR1);
+
+	// burst visibility on 
+	outl(inl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
+
+	outl(0x83, MEM_STCFG1);         // ewait enabled, flash timing
+	outl(0x33030a10, MEM_STTIME1);   // slower timing for FPGA
+
+#ifdef CONFIG_FB_E1356
+	if ((argptr = strstr(argptr, "video=")) == NULL) {
+		argptr = prom_getcmdline();
+		strcat(argptr, " video=e1356fb:system:pb1000,mmunalign:1");
+	}
+#endif // CONFIG_FB_E1356
+
+
+#ifdef CONFIG_PCI
+	outl(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
+	outl(0, SDRAM_MBAR);        // set mbar to 0
+	outl(0x2, SDRAM_CMD);       // enable memory accesses
+	au_sync_delay(1);
+#endif
+
+#ifndef CONFIG_SERIAL_NONSTANDARD
+	/* don't touch the default serial console */
+	outl(0, UART0_ADDR + UART_CLK);
+#endif
+	outl(0, UART1_ADDR + UART_CLK);
+	outl(0, UART2_ADDR + UART_CLK);
+	outl(0, UART3_ADDR + UART_CLK);
+
+#ifdef CONFIG_BLK_DEV_IDE
+	{
+		argptr = prom_getcmdline();
+		strcat(argptr, " ide0=noprobe");
+	}
+	ide_ops = &std_ide_ops;
+#endif
+
+	// setup irda clocks
+	// aux clock, divide by 2, clock from 2/4 divider
+	writel(readl(SYS_CLKSRC) | 0x7, SYS_CLKSRC);
+	pin_func = inl(SYS_PINFUNC) & (u32)(~(1<<2)); // clear IRTXD
+	outl(pin_func, SYS_PINFUNC);
+
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
+	outl(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
+	au_sync();
+	while (inl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
+	outl(0, SYS_TOYTRIM);
+
+	/* Enable Au1000 BCLK switching - note: sed1356 must not use
+	 * its BCLK (Au1000 LCLK) for any timings */
+	switch (prid & 0x000000FF)
+	{
+	case 0x00: /* DA */
+	case 0x01: /* HA */
+	case 0x02: /* HB */
+		break;
+	default:  /* HC and newer */
+		outl(0x00000060, 0xb190003c);
+		break;
+	}
+}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)