1/* 2 * 3 * BRIEF MODULE DESCRIPTION 4 * Alchemy Pb1000 board setup. 5 * 6 * Copyright 2000 MontaVista Software Inc. 7 * Author: MontaVista Software, Inc. 8 * ppopov@mvista.com or source@mvista.com 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the 12 * Free Software Foundation; either version 2 of the License, or (at your 13 * option) any later version. 14 * 15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 18 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 21 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * You should have received a copy of the GNU General Public License along 27 * with this program; if not, write to the Free Software Foundation, Inc., 28 * 675 Mass Ave, Cambridge, MA 02139, USA. 29 */ 30#include <linux/config.h> 31#include <linux/init.h> 32#include <linux/sched.h> 33#include <linux/ioport.h> 34#include <linux/mm.h> 35#include <linux/console.h> 36#include <linux/mc146818rtc.h> 37#include <linux/delay.h> 38 39#include <asm/cpu.h> 40#include <asm/bootinfo.h> 41#include <asm/irq.h> 42#include <asm/keyboard.h> 43#include <asm/mipsregs.h> 44#include <asm/reboot.h> 45#include <asm/pgtable.h> 46#include <asm/wbflush.h> 47#include <asm/au1000.h> 48#include <asm/pb1500.h> 49 50#ifdef CONFIG_USB_OHCI 51// Enable the workaround for the OHCI DoneHead 52// register corruption problem. 53#define CONFIG_AU1000_OHCI_FIX 54#endif 55 56#if defined(CONFIG_AU1X00_SERIAL_CONSOLE) 57extern void console_setup(char *, int *); 58char serial_console[20]; 59#endif 60 61#ifdef CONFIG_BLK_DEV_INITRD 62extern unsigned long initrd_start, initrd_end; 63extern void * __rd_start, * __rd_end; 64#endif 65 66#ifdef CONFIG_BLK_DEV_IDE 67extern struct ide_ops std_ide_ops; 68extern struct ide_ops *ide_ops; 69#endif 70 71#ifdef CONFIG_RTC 72extern struct rtc_ops pb1500_rtc_ops; 73#endif 74 75void (*__wbflush) (void); 76extern char * __init prom_getcmdline(void); 77extern void au1000_restart(char *); 78extern void au1000_halt(void); 79extern void au1000_power_off(void); 80extern struct resource ioport_resource; 81extern struct resource iomem_resource; 82#ifdef CONFIG_64BIT_PHYS_ADDR 83extern phys_t (*fixup_bigphys_addr)(phys_t phys_addr, phys_t size); 84static phys_t pb1500_fixup_bigphys_addr(phys_t phys_addr, phys_t size); 85#endif 86 87 88void __init bus_error_init(void) { /* nothing */ } 89 90void au1500_wbflush(void) 91{ 92 __asm__ volatile ("sync"); 93} 94 95void __init au1x00_setup(void) 96{ 97 char *argptr; 98 u32 pin_func, static_cfg0; 99 u32 sys_freqctrl, sys_clksrc; 100 101 argptr = prom_getcmdline(); 102 103 /* NOTE: The memory map is established by YAMON 2.08+ */ 104 105 /* Various early Au1500 Errata corrected by this */ 106 set_c0_config(1<<19); /* Config[OD] */ 107 108#ifdef CONFIG_AU1X00_SERIAL_CONSOLE 109 if ((argptr = strstr(argptr, "console=")) == NULL) { 110 argptr = prom_getcmdline(); 111 strcat(argptr, " console=ttyS0,115200"); 112 } 113#endif 114 115#ifdef CONFIG_SOUND_AU1X00 116 strcat(argptr, " au1000_audio=vra"); 117 argptr = prom_getcmdline(); 118#endif 119 120 __wbflush = au1500_wbflush; 121 _machine_restart = au1000_restart; 122 _machine_halt = au1000_halt; 123 _machine_power_off = au1000_power_off; 124#ifdef CONFIG_64BIT_PHYS_ADDR 125 fixup_bigphys_addr = pb1500_fixup_bigphys_addr; 126#endif 127 128 // IO/MEM resources. 129 set_io_port_base(0); 130 ioport_resource.start = 0x00000000; 131 ioport_resource.end = 0xffffffff; 132 iomem_resource.start = 0x10000000; 133 iomem_resource.end = 0xffffffff; 134 135#ifdef CONFIG_BLK_DEV_INITRD 136 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); 137 initrd_start = (unsigned long)&__rd_start; 138 initrd_end = (unsigned long)&__rd_end; 139#endif 140 141 // set AUX clock to 12MHz * 8 = 96 MHz 142 au_writel(8, SYS_AUXPLL); 143 au_writel(0, SYS_PINSTATERD); 144 udelay(100); 145 146#if defined(CONFIG_USB_OHCI) || defined(CONFIG_AU1X00_USB_DEVICE) 147#ifdef CONFIG_USB_OHCI 148 if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) { 149 char usb_args[80]; 150 argptr = prom_getcmdline(); 151 memset(usb_args, 0, sizeof(usb_args)); 152 sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d", 153 USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT); 154 strcat(argptr, usb_args); 155 } 156#endif 157 158 /* zero and disable FREQ2 */ 159 sys_freqctrl = au_readl(SYS_FREQCTRL0); 160 sys_freqctrl &= ~0xFFF00000; 161 au_writel(sys_freqctrl, SYS_FREQCTRL0); 162 163 /* zero and disable USBH/USBD clocks */ 164 sys_clksrc = au_readl(SYS_CLKSRC); 165 sys_clksrc &= ~0x00007FE0; 166 au_writel(sys_clksrc, SYS_CLKSRC); 167 168 sys_freqctrl = au_readl(SYS_FREQCTRL0); 169 sys_freqctrl &= ~0xFFF00000; 170 171 sys_clksrc = au_readl(SYS_CLKSRC); 172 sys_clksrc &= ~0x00007FE0; 173 174 // FREQ2 = aux/2 = 48 MHz 175 sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20)); 176 au_writel(sys_freqctrl, SYS_FREQCTRL0); 177 178 /* 179 * Route 48MHz FREQ2 into USB Host and/or Device 180 */ 181#ifdef CONFIG_USB_OHCI 182 sys_clksrc |= ((4<<12) | (0<<11) | (0<<10)); 183#endif 184#ifdef CONFIG_AU1000_USB_DEVICE 185 sys_clksrc |= ((4<<7) | (0<<6) | (0<<5)); 186#endif 187 au_writel(sys_clksrc, SYS_CLKSRC); 188 189 190 pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000); 191#ifndef CONFIG_AU1000_USB_DEVICE 192 // 2nd USB port is USB host 193 pin_func |= 0x8000; 194#endif 195 au_writel(pin_func, SYS_PINFUNC); 196#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE) 197 198 199#ifdef CONFIG_USB_OHCI 200 // enable host controller and wait for reset done 201 au_writel(0x08, USB_HOST_CONFIG); 202 udelay(1000); 203 au_writel(0x0c, USB_HOST_CONFIG); 204 udelay(1000); 205 au_readl(USB_HOST_CONFIG); 206 while (!(au_readl(USB_HOST_CONFIG) & 0x10)) 207 ; 208 au_readl(USB_HOST_CONFIG); 209#endif 210 211#ifdef CONFIG_FB 212 conswitchp = &dummy_con; 213#endif 214 215#ifdef CONFIG_FB_E1356 216 if ((argptr = strstr(argptr, "video=")) == NULL) { 217 argptr = prom_getcmdline(); 218 strcat(argptr, " video=e1356fb:system:pb1500"); 219 } 220#elif defined(CONFIG_FB_XPERT98) 221 if ((argptr = strstr(argptr, "video=")) == NULL) { 222 argptr = prom_getcmdline(); 223 strcat(argptr, " video=atyfb:1024x768-8@70"); 224 } 225#endif // CONFIG_FB_E1356 226 227#ifndef CONFIG_SERIAL_NONSTANDARD 228 /* don't touch the default serial console */ 229 au_writel(0, UART0_ADDR + UART_CLK); 230#endif 231 au_writel(0, UART3_ADDR + UART_CLK); 232 233#ifdef CONFIG_BLK_DEV_IDE 234 ide_ops = &std_ide_ops; 235#endif 236 237#ifdef CONFIG_PCI 238 // Setup PCI bus controller 239 au_writel(0, Au1500_PCI_CMEM); 240 au_writel(0x00003fff, Au1500_CFG_BASE); 241#if defined(__MIPSEB__) 242 au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG); 243#else 244 au_writel(0xf, Au1500_PCI_CFG); 245#endif 246 au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); 247 au_writel(0, Au1500_PCI_MWBASE_REV_CCL); 248 au_writel(0x02a00356, Au1500_PCI_STATCMD); 249 au_writel(0x00003c04, Au1500_PCI_HDRTYPE); 250 au_writel(0x00000008, Au1500_PCI_MBAR); 251 au_sync(); 252#endif 253 254 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); 255 au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); 256 au_sync(); 257 while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); 258 au_writel(0, SYS_TOYTRIM); 259 260 /* Enable BCLK switching */ 261 au_writel(0x00000060, 0xb190003c); 262 263#ifdef CONFIG_RTC 264 rtc_ops = &pb1500_rtc_ops; 265 // Enable the RTC if not already enabled 266 if (!(au_readl(0xac000028) & 0x20)) { 267 printk("enabling clock ...\n"); 268 au_writel((au_readl(0xac000028) | 0x20), 0xac000028); 269 } 270 // Put the clock in BCD mode 271 if (readl(0xac00002C) & 0x4) { /* reg B */ 272 au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c); 273 au_sync(); 274 } 275#endif 276} 277 278#ifdef CONFIG_64BIT_PHYS_ADDR 279static phys_t pb1500_fixup_bigphys_addr(phys_t phys_addr, 280 phys_t size) 281{ 282 u32 pci_start = (u32)Au1500_PCI_MEM_START; 283 u32 pci_end = (u32)Au1500_PCI_MEM_END; 284 285 /* Don't fixup 36 bit addresses */ 286 if ((phys_addr >> 32) != 0) return phys_addr; 287 288 /* check for pci memory window */ 289 if ((phys_addr >= pci_start) && ((phys_addr + size) < pci_end)) { 290 return (phys_t)((phys_addr - pci_start) + 291 Au1500_PCI_MEM_START); 292 } 293 else 294 return phys_addr; 295} 296#endif 297