• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/arch/mips/momentum/ocelot_3/
1/*
2 * setup.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Momentum Computer Ocelot-3 board dependent boot routines
6 *
7 * Copyright (C) 1996, 1997, 01, 05 - 06  Ralf Baechle
8 * Copyright (C) 2000 RidgeRun, Inc.
9 * Copyright (C) 2001 Red Hat, Inc.
10 * Copyright (C) 2002 Momentum Computer
11 *
12 * Author: Matthew Dharm, Momentum Computer
13 *   mdharm@momenco.com
14 *
15 * Louis Hamilton, Red Hat, Inc.
16 *   hamilton@redhat.com  [MIPS64 modifications]
17 *
18 * Author: RidgeRun, Inc.
19 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
20 *
21 * Copyright 2001 MontaVista Software Inc.
22 * Author: jsun@mvista.com or jsun@junsun.net
23 *
24 * Copyright 2004 PMC-Sierra
25 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
26 *
27 * Copyright (C) 2004 MontaVista Software Inc.
28 * Author: Manish Lachwani, mlachwani@mvista.com
29 *
30 *  This program is free software; you can redistribute  it and/or modify it
31 *  under  the terms of  the GNU General  Public License as published by the
32 *  Free Software Foundation;  either version 2 of the  License, or (at your
33 *  option) any later version.
34 *
35 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
36 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
37 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
38 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
39 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
40 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
41 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
42 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
43 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
44 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45 *
46 *  You should have received a copy of the  GNU General Public License along
47 *  with this program; if not, write  to the Free Software Foundation, Inc.,
48 *  675 Mass Ave, Cambridge, MA 02139, USA.
49 */
50#include <linux/init.h>
51#include <linux/kernel.h>
52#include <linux/types.h>
53#include <linux/mc146818rtc.h>
54#include <linux/ioport.h>
55#include <linux/interrupt.h>
56#include <linux/pci.h>
57#include <linux/timex.h>
58#include <linux/bootmem.h>
59#include <linux/mv643xx.h>
60#include <linux/pm.h>
61#include <linux/bcd.h>
62
63#include <asm/time.h>
64#include <asm/page.h>
65#include <asm/bootinfo.h>
66#include <asm/io.h>
67#include <asm/irq.h>
68#include <asm/pci.h>
69#include <asm/processor.h>
70#include <asm/reboot.h>
71#include <asm/mc146818rtc.h>
72#include <asm/tlbflush.h>
73#include "ocelot_3_fpga.h"
74
75/* Marvell Discovery Register Base */
76unsigned long marvell_base = (signed)0xf4000000;
77
78/* CPU clock */
79unsigned long cpu_clock;
80
81/* RTC/NVRAM */
82unsigned char* rtc_base = (unsigned char*)(signed)0xfc800000;
83
84/* FPGA Base */
85unsigned long ocelot_fpga_base = (signed)0xfc000000;
86
87/* Serial base */
88unsigned long uart_base = (signed)0xfd000000;
89
90/*
91 * Marvell Discovery SRAM. This is one place where Ethernet
92 * Tx and Rx descriptors can be placed to improve performance
93 */
94extern unsigned long mv64340_sram_base;
95
96/* These functions are used for rebooting or halting the machine*/
97extern void momenco_ocelot_restart(char *command);
98extern void momenco_ocelot_halt(void);
99extern void momenco_ocelot_power_off(void);
100
101void momenco_time_init(void);
102static char reset_reason;
103
104void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
105		     unsigned long entryhi, unsigned long pagemask);
106
107static inline unsigned long ENTRYLO(unsigned long paddr)
108{
109	return ((paddr & PAGE_MASK) |
110		(_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
111		_CACHE_UNCACHED)) >> 6;
112}
113
114void __init bus_error_init(void)
115{
116	/* nothing */
117}
118
119/*
120 * setup code for a handoff from a version 2 PMON 2000 PROM
121 */
122void setup_wired_tlb_entries(void)
123{
124	write_c0_wired(0);
125	local_flush_tlb_all();
126
127	/* marvell and extra space */
128	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), (signed)0xf4000000, PM_64K);
129
130	/* fpga, rtc, and uart */
131	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000), (signed)0xfc000000, PM_16M);
132}
133
134unsigned long m48t37y_get_time(void)
135{
136	unsigned int year, month, day, hour, min, sec;
137	unsigned long flags;
138
139	spin_lock_irqsave(&rtc_lock, flags);
140	/* stop the update */
141	rtc_base[0x7ff8] = 0x40;
142
143	year = BCD2BIN(rtc_base[0x7fff]);
144	year += BCD2BIN(rtc_base[0x7ff1]) * 100;
145
146	month = BCD2BIN(rtc_base[0x7ffe]);
147
148	day = BCD2BIN(rtc_base[0x7ffd]);
149
150	hour = BCD2BIN(rtc_base[0x7ffb]);
151	min = BCD2BIN(rtc_base[0x7ffa]);
152	sec = BCD2BIN(rtc_base[0x7ff9]);
153
154	/* start the update */
155	rtc_base[0x7ff8] = 0x00;
156	spin_unlock_irqrestore(&rtc_lock, flags);
157
158	return mktime(year, month, day, hour, min, sec);
159}
160
161int m48t37y_set_time(unsigned long sec)
162{
163	struct rtc_time tm;
164	unsigned long flags;
165
166	/* convert to a more useful format -- note months count from 0 */
167	to_tm(sec, &tm);
168	tm.tm_mon += 1;
169
170	spin_lock_irqsave(&rtc_lock, flags);
171	/* enable writing */
172	rtc_base[0x7ff8] = 0x80;
173
174	/* year */
175	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
176	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
177
178	/* month */
179	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
180
181	/* day */
182	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
183
184	/* hour/min/sec */
185	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
186	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
187	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
188
189	/* day of week -- not really used, but let's keep it up-to-date */
190	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
191
192	/* disable writing */
193	rtc_base[0x7ff8] = 0x00;
194	spin_unlock_irqrestore(&rtc_lock, flags);
195
196	return 0;
197}
198
199void __init plat_timer_setup(struct irqaction *irq)
200{
201	setup_irq(7, irq);	/* Timer interrupt, unmask status IM7 */
202}
203
204void momenco_time_init(void)
205{
206	setup_wired_tlb_entries();
207
208	/*
209	 * Ocelot-3 board has been built with both
210	 * the Rm7900 and the Rm7065C
211	 */
212	mips_hpt_frequency = cpu_clock / 2;
213
214	rtc_mips_get_time = m48t37y_get_time;
215	rtc_mips_set_time = m48t37y_set_time;
216}
217
218/*
219 * PCI Support for Ocelot-3
220 */
221
222/* Bus #0 IO and MEM space */
223#define	OCELOT_3_PCI_IO_0_START		0xe0000000
224#define	OCELOT_3_PCI_IO_0_SIZE		0x08000000
225#define	OCELOT_3_PCI_MEM_0_START	0xc0000000
226#define	OCELOT_3_PCI_MEM_0_SIZE		0x10000000
227
228/* Bus #1 IO and MEM space */
229#define	OCELOT_3_PCI_IO_1_START		0xe8000000
230#define	OCELOT_3_PCI_IO_1_SIZE		0x08000000
231#define	OCELOT_3_PCI_MEM_1_START	0xd0000000
232#define	OCELOT_3_PCI_MEM_1_SIZE		0x10000000
233
234static struct resource mv_pci_io_mem0_resource = {
235	.name	= "MV64340 PCI0 IO MEM",
236	.start	= OCELOT_3_PCI_IO_0_START,
237	.end	= OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE - 1,
238	.flags  = IORESOURCE_IO,
239};
240
241static struct resource mv_pci_io_mem1_resource = {
242	.name	= "MV64340 PCI1 IO MEM",
243	.start	= OCELOT_3_PCI_IO_1_START,
244	.end	= OCELOT_3_PCI_IO_1_START + OCELOT_3_PCI_IO_1_SIZE - 1,
245	.flags	= IORESOURCE_IO,
246};
247
248static struct resource mv_pci_mem0_resource = {
249	.name	= "MV64340 PCI0 MEM",
250	.start	= OCELOT_3_PCI_MEM_0_START,
251	.end	= OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE - 1,
252	.flags	= IORESOURCE_MEM,
253};
254
255static struct resource mv_pci_mem1_resource = {
256	.name	= "MV64340 PCI1 MEM",
257	.start	= OCELOT_3_PCI_MEM_1_START,
258	.end	= OCELOT_3_PCI_MEM_1_START + OCELOT_3_PCI_MEM_1_SIZE - 1,
259	.flags	= IORESOURCE_MEM,
260};
261
262static struct mv_pci_controller mv_bus0_controller = {
263	.pcic = {
264		 .pci_ops	= &mv_pci_ops,
265		 .mem_resource	= &mv_pci_mem0_resource,
266		 .io_resource	= &mv_pci_io_mem0_resource,
267	},
268	.config_addr	= MV64340_PCI_0_CONFIG_ADDR,
269	.config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
270};
271
272static struct mv_pci_controller mv_bus1_controller = {
273	.pcic = {
274		 .pci_ops	= &mv_pci_ops,
275		 .mem_resource	= &mv_pci_mem1_resource,
276		 .io_resource	= &mv_pci_io_mem1_resource,
277	},
278	.config_addr	= MV64340_PCI_1_CONFIG_ADDR,
279	.config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
280};
281
282static __init int __init ja_pci_init(void)
283{
284	uint32_t enable;
285	extern int pci_probe_only;
286
287	/* PMON will assign PCI resources */
288	pci_probe_only = 1;
289
290	enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
291	/*
292	 * We require at least one enabled I/O or PCI memory window or we
293	 * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
294	 */
295	if (enable & (0x01 <<  9) || enable & (0x01 << 10))
296		register_pci_controller(&mv_bus0_controller.pcic);
297
298	if (enable & (0x01 << 14) || enable & (0x01 << 15))
299		register_pci_controller(&mv_bus1_controller.pcic);
300
301	ioport_resource.end = OCELOT_3_PCI_IO_0_START + OCELOT_3_PCI_IO_0_SIZE +
302					OCELOT_3_PCI_IO_1_SIZE - 1;
303
304	iomem_resource.end = OCELOT_3_PCI_MEM_0_START + OCELOT_3_PCI_MEM_0_SIZE +
305					OCELOT_3_PCI_MEM_1_SIZE - 1;
306
307	set_io_port_base(OCELOT_3_PCI_IO_0_START); /* mips_io_port_base */
308
309	return 0;
310}
311
312arch_initcall(ja_pci_init);
313
314void __init plat_mem_setup(void)
315{
316	unsigned int tmpword;
317
318	board_time_init = momenco_time_init;
319
320	_machine_restart = momenco_ocelot_restart;
321	_machine_halt = momenco_ocelot_halt;
322	pm_power_off = momenco_ocelot_power_off;
323
324	/* Wired TLB entries */
325	setup_wired_tlb_entries();
326
327	/* shut down ethernet ports, just to be sure our memory doesn't get
328	 * corrupted by random ethernet traffic.
329	 */
330	MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
331	MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
332	MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
333	MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
334	do {}
335	  while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
336	do {}
337	  while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
338	do {}
339	  while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
340	do {}
341	  while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
342	MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0),
343		 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
344	MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1),
345		 MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
346
347	/* Turn off the Bit-Error LED */
348	OCELOT_FPGA_WRITE(0x80, CLR);
349
350	tmpword = OCELOT_FPGA_READ(BOARDREV);
351	if (tmpword < 26)
352		printk("Momenco Ocelot-3: Board Assembly Rev. %c\n",
353			'A'+tmpword);
354	else
355		printk("Momenco Ocelot-3: Board Assembly Revision #0x%x\n",
356			tmpword);
357
358	tmpword = OCELOT_FPGA_READ(FPGA_REV);
359	printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
360	tmpword = OCELOT_FPGA_READ(RESET_STATUS);
361	printk("Reset reason: 0x%x\n", tmpword);
362	switch (tmpword) {
363		case 0x1:
364			printk("  - Power-up reset\n");
365			break;
366		case 0x2:
367			printk("  - Push-button reset\n");
368			break;
369		case 0x4:
370			printk("  - cPCI bus reset\n");
371			break;
372		case 0x8:
373			printk("  - Watchdog reset\n");
374			break;
375		case 0x10:
376			printk("  - Software reset\n");
377			break;
378		default:
379			printk("  - Unknown reset cause\n");
380	}
381	reset_reason = tmpword;
382	OCELOT_FPGA_WRITE(0xff, RESET_STATUS);
383
384	tmpword = OCELOT_FPGA_READ(CPCI_ID);
385	printk("cPCI ID register: 0x%02x\n", tmpword);
386	printk("  - Slot number: %d\n", tmpword & 0x1f);
387	printk("  - PCI bus present: %s\n", tmpword & 0x40 ? "yes" : "no");
388	printk("  - System Slot: %s\n", tmpword & 0x20 ? "yes" : "no");
389
390	tmpword = OCELOT_FPGA_READ(BOARD_STATUS);
391	printk("Board Status register: 0x%02x\n", tmpword);
392	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
393	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
394	printk("  - L3 cache size: %d MB\n", (1<<((tmpword&12) >> 2))&~1);
395
396	/* Support for 128 MB memory */
397	add_memory_region(0x0, 0x08000000, BOOT_MEM_RAM);
398}
399