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