--- zzzz-none-000/linux-2.4.17/arch/mips/au1000/pb1000/setup.c 2001-09-09 17:43:01.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/arch/mips/au1000/pb1000/setup.c 2004-11-24 13:22:38.000000000 +0000 @@ -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 #include #include +#include #include #include +#include #include #include #include +#include #include #include +#include #include +#include + +#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,226 @@ 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 = 0; + ioport_resource.end = 0xffffffff; + iomem_resource.start = 0; + 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; + } + + printk("Alchemy Semi Pb1000 Board\n"); + printk("Au1000/Pb1000 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +}