PageRenderTime 68ms CodeModel.GetById 15ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/mips/momentum/jaguar_atx/setup.c

https://bitbucket.org/evzijst/gittest
C | 474 lines | 289 code | 81 blank | 104 comment | 14 complexity | ed8983f6c8400c70d6f154e8782c98b9 MD5 | raw file
  1/*
  2 * BRIEF MODULE DESCRIPTION
  3 * Momentum Computer Jaguar-ATX board dependent boot routines
  4 *
  5 * Copyright (C) 1996, 1997, 2001, 2004  Ralf Baechle (ralf@linux-mips.org)
  6 * Copyright (C) 2000 RidgeRun, Inc.
  7 * Copyright (C) 2001 Red Hat, Inc.
  8 * Copyright (C) 2002 Momentum Computer
  9 *
 10 * Author: Matthew Dharm, Momentum Computer
 11 *   mdharm@momenco.com
 12 *
 13 * Louis Hamilton, Red Hat, Inc.
 14 *   hamilton@redhat.com  [MIPS64 modifications]
 15 *
 16 * Author: RidgeRun, Inc.
 17 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
 18 *
 19 * Copyright 2001 MontaVista Software Inc.
 20 * Author: jsun@mvista.com or jsun@junsun.net
 21 *
 22 *  This program is free software; you can redistribute  it and/or modify it
 23 *  under  the terms of  the GNU General  Public License as published by the
 24 *  Free Software Foundation;  either version 2 of the  License, or (at your
 25 *  option) any later version.
 26 *
 27 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 28 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 29 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 30 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 31 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 32 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 33 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 34 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 35 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 36 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 37 *
 38 *  You should have received a copy of the  GNU General Public License along
 39 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 40 *  675 Mass Ave, Cambridge, MA 02139, USA.
 41 */
 42#include <linux/config.h>
 43#include <linux/bcd.h>
 44#include <linux/init.h>
 45#include <linux/kernel.h>
 46#include <linux/types.h>
 47#include <linux/mm.h>
 48#include <linux/bootmem.h>
 49#include <linux/module.h>
 50#include <linux/pci.h>
 51#include <linux/swap.h>
 52#include <linux/ioport.h>
 53#include <linux/sched.h>
 54#include <linux/interrupt.h>
 55#include <linux/timex.h>
 56#include <linux/vmalloc.h>
 57#include <asm/time.h>
 58#include <asm/bootinfo.h>
 59#include <asm/page.h>
 60#include <asm/io.h>
 61#include <asm/irq.h>
 62#include <asm/processor.h>
 63#include <asm/ptrace.h>
 64#include <asm/reboot.h>
 65#include <asm/tlbflush.h>
 66#include <asm/mv64340.h>
 67
 68#include "jaguar_atx_fpga.h"
 69
 70extern unsigned long mv64340_sram_base;
 71unsigned long cpu_clock;
 72
 73/* These functions are used for rebooting or halting the machine*/
 74extern void momenco_jaguar_restart(char *command);
 75extern void momenco_jaguar_halt(void);
 76extern void momenco_jaguar_power_off(void);
 77
 78void momenco_time_init(void);
 79
 80static char reset_reason;
 81
 82static inline unsigned long ENTRYLO(unsigned long paddr)
 83{
 84	return ((paddr & PAGE_MASK) |
 85	       (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
 86		_CACHE_UNCACHED)) >> 6;
 87}
 88
 89void __init bus_error_init(void) { /* nothing */ }
 90
 91/*
 92 * Load a few TLB entries for the MV64340 and perhiperals. The MV64340 is going
 93 * to be hit on every IRQ anyway - there's absolutely no point in letting it be
 94 * a random TLB entry, as it'll just cause needless churning of the TLB. And we
 95 * use the other half for the serial port, which is just a PITA otherwise :)
 96 *
 97 *	Device			Physical	Virtual
 98 *	MV64340 Internal Regs	0xf4000000	0xf4000000
 99 *	Ocelot-C[S] PLD (CS0)	0xfc000000	0xfc000000
100 *	NVRAM (CS1)		0xfc800000	0xfc800000
101 *	UARTs (CS2)		0xfd000000	0xfd000000
102 *	Internal SRAM		0xfe000000	0xfe000000
103 *	M-Systems DOC (CS3)	0xff000000	0xff000000
104 */
105
106static __init void wire_stupidity_into_tlb(void)
107{
108#ifdef CONFIG_MIPS32
109	write_c0_wired(0);
110	local_flush_tlb_all();
111
112	/* marvell and extra space */
113	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
114	                0xf4000000UL, PM_64K);
115	/* fpga, rtc, and uart */
116	add_wired_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfd000000),
117	                0xfc000000UL, PM_16M);
118//	/* m-sys and internal SRAM */
119//	add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000),
120//	                0xfe000000UL, PM_16M);
121
122	marvell_base = 0xf4000000;
123	//mv64340_sram_base = 0xfe000000;	/* Currently unused */
124#endif
125}
126
127unsigned long marvell_base	= 0xf4000000L;
128unsigned long ja_fpga_base	= JAGUAR_ATX_CS0_ADDR;
129unsigned long uart_base		= 0xfd000000L;
130static unsigned char *rtc_base	= (unsigned char*) 0xfc800000L;
131
132EXPORT_SYMBOL(marvell_base);
133
134static __init int per_cpu_mappings(void)
135{
136	marvell_base	= (unsigned long) ioremap(0xf4000000, 0x10000);
137	ja_fpga_base	= (unsigned long) ioremap(JAGUAR_ATX_CS0_ADDR,  0x1000);
138	uart_base	= (unsigned long) ioremap(0xfd000000UL, 0x1000);
139	rtc_base	= ioremap(0xfc000000UL, 0x8000);
140	// ioremap(0xfe000000,  32 << 20);
141	write_c0_wired(0);
142	local_flush_tlb_all();
143	ja_setup_console();
144
145	return 0;
146}
147arch_initcall(per_cpu_mappings);
148
149unsigned long m48t37y_get_time(void)
150{
151	unsigned int year, month, day, hour, min, sec;
152
153	/* stop the update */
154	rtc_base[0x7ff8] = 0x40;
155
156	year = BCD2BIN(rtc_base[0x7fff]);
157	year += BCD2BIN(rtc_base[0x7ff1]) * 100;
158
159	month = BCD2BIN(rtc_base[0x7ffe]);
160
161	day = BCD2BIN(rtc_base[0x7ffd]);
162
163	hour = BCD2BIN(rtc_base[0x7ffb]);
164	min = BCD2BIN(rtc_base[0x7ffa]);
165	sec = BCD2BIN(rtc_base[0x7ff9]);
166
167	/* start the update */
168	rtc_base[0x7ff8] = 0x00;
169
170	return mktime(year, month, day, hour, min, sec);
171}
172
173int m48t37y_set_time(unsigned long sec)
174{
175	struct rtc_time tm;
176
177	/* convert to a more useful format -- note months count from 0 */
178	to_tm(sec, &tm);
179	tm.tm_mon += 1;
180
181	/* enable writing */
182	rtc_base[0x7ff8] = 0x80;
183
184	/* year */
185	rtc_base[0x7fff] = BIN2BCD(tm.tm_year % 100);
186	rtc_base[0x7ff1] = BIN2BCD(tm.tm_year / 100);
187
188	/* month */
189	rtc_base[0x7ffe] = BIN2BCD(tm.tm_mon);
190
191	/* day */
192	rtc_base[0x7ffd] = BIN2BCD(tm.tm_mday);
193
194	/* hour/min/sec */
195	rtc_base[0x7ffb] = BIN2BCD(tm.tm_hour);
196	rtc_base[0x7ffa] = BIN2BCD(tm.tm_min);
197	rtc_base[0x7ff9] = BIN2BCD(tm.tm_sec);
198
199	/* day of week -- not really used, but let's keep it up-to-date */
200	rtc_base[0x7ffc] = BIN2BCD(tm.tm_wday + 1);
201
202	/* disable writing */
203	rtc_base[0x7ff8] = 0x00;
204
205	return 0;
206}
207
208void momenco_timer_setup(struct irqaction *irq)
209{
210	setup_irq(8, irq);
211}
212
213/*
214 * Ugly but the least of all evils.  TLB initialization did flush the TLB so
215 * We need to setup mappings again before we can touch the RTC.
216 */
217void momenco_time_init(void)
218{
219	wire_stupidity_into_tlb();
220
221	mips_hpt_frequency = cpu_clock / 2;
222	board_timer_setup = momenco_timer_setup;
223
224	rtc_get_time = m48t37y_get_time;
225	rtc_set_time = m48t37y_set_time;
226}
227
228static struct resource mv_pci_io_mem0_resource = {
229	.name	= "MV64340 PCI0 IO MEM",
230	.flags	= IORESOURCE_IO
231};
232
233static struct resource mv_pci_mem0_resource = {
234	.name	= "MV64340 PCI0 MEM",
235	.flags	= IORESOURCE_MEM
236};
237
238static struct mv_pci_controller mv_bus0_controller = {
239	.pcic = {
240		.pci_ops	= &mv_pci_ops,
241		.mem_resource	= &mv_pci_mem0_resource,
242		.io_resource	= &mv_pci_io_mem0_resource,
243	},
244	.config_addr	= MV64340_PCI_0_CONFIG_ADDR,
245	.config_vreg	= MV64340_PCI_0_CONFIG_DATA_VIRTUAL_REG,
246};
247
248static uint32_t mv_io_base, mv_io_size;
249
250static void ja_pci0_init(void)
251{
252	uint32_t mem0_base, mem0_size;
253	uint32_t io_base, io_size;
254
255	io_base = MV_READ(MV64340_PCI_0_IO_BASE_ADDR) << 16;
256	io_size = (MV_READ(MV64340_PCI_0_IO_SIZE) + 1) << 16;
257	mem0_base = MV_READ(MV64340_PCI_0_MEMORY0_BASE_ADDR) << 16;
258	mem0_size = (MV_READ(MV64340_PCI_0_MEMORY0_SIZE) + 1) << 16;
259
260	mv_pci_io_mem0_resource.start		= 0;
261	mv_pci_io_mem0_resource.end		= io_size - 1;
262	mv_pci_mem0_resource.start		= mem0_base;
263	mv_pci_mem0_resource.end		= mem0_base + mem0_size - 1;
264	mv_bus0_controller.pcic.mem_offset	= mem0_base;
265	mv_bus0_controller.pcic.io_offset	= 0;
266
267	ioport_resource.end		= io_size - 1;
268
269	register_pci_controller(&mv_bus0_controller.pcic);
270
271	mv_io_base = io_base;
272	mv_io_size = io_size;
273}
274
275static struct resource mv_pci_io_mem1_resource = {
276	.name	= "MV64340 PCI1 IO MEM",
277	.flags	= IORESOURCE_IO
278};
279
280static struct resource mv_pci_mem1_resource = {
281	.name	= "MV64340 PCI1 MEM",
282	.flags	= IORESOURCE_MEM
283};
284
285static struct mv_pci_controller mv_bus1_controller = {
286	.pcic = {
287		.pci_ops	= &mv_pci_ops,
288		.mem_resource	= &mv_pci_mem1_resource,
289		.io_resource	= &mv_pci_io_mem1_resource,
290	},
291	.config_addr	= MV64340_PCI_1_CONFIG_ADDR,
292	.config_vreg	= MV64340_PCI_1_CONFIG_DATA_VIRTUAL_REG,
293};
294
295static __init void ja_pci1_init(void)
296{
297	uint32_t mem0_base, mem0_size;
298	uint32_t io_base, io_size;
299
300	io_base = MV_READ(MV64340_PCI_1_IO_BASE_ADDR) << 16;
301	io_size = (MV_READ(MV64340_PCI_1_IO_SIZE) + 1) << 16;
302	mem0_base = MV_READ(MV64340_PCI_1_MEMORY0_BASE_ADDR) << 16;
303	mem0_size = (MV_READ(MV64340_PCI_1_MEMORY0_SIZE) + 1) << 16;
304
305	/*
306	 * Here we assume the I/O window of second bus to be contiguous with
307	 * the first.  A gap is no problem but would waste address space for
308	 * remapping the port space.
309	 */
310	mv_pci_io_mem1_resource.start		= mv_io_size;
311	mv_pci_io_mem1_resource.end		= mv_io_size + io_size - 1;
312	mv_pci_mem1_resource.start		= mem0_base;
313	mv_pci_mem1_resource.end		= mem0_base + mem0_size - 1;
314	mv_bus1_controller.pcic.mem_offset	= mem0_base;
315	mv_bus1_controller.pcic.io_offset	= 0;
316
317	ioport_resource.end		= io_base + io_size -mv_io_base - 1;
318
319	register_pci_controller(&mv_bus1_controller.pcic);
320
321	mv_io_size = io_base + io_size - mv_io_base;
322}
323
324static __init int __init ja_pci_init(void)
325{
326	unsigned long io_v_base;
327	uint32_t enable;
328
329	enable = ~MV_READ(MV64340_BASE_ADDR_ENABLE);
330
331	/*
332	 * We require at least one enabled I/O or PCI memory window or we
333	 * will ignore this PCI bus.  We ignore PCI windows 1, 2 and 3.
334	 */
335	if (enable & (0x01 <<  9) || enable & (0x01 << 10))
336		ja_pci0_init();
337
338	if (enable & (0x01 << 14) || enable & (0x01 << 15))
339		ja_pci1_init();
340
341	if (mv_io_size) {
342		io_v_base = (unsigned long) ioremap(mv_io_base, mv_io_size);
343		if (!io_v_base)
344			panic("Could not ioremap I/O port range");
345
346		set_io_port_base(io_v_base);
347	}
348
349	return 0;
350}
351
352arch_initcall(ja_pci_init);
353
354static int  __init momenco_jaguar_atx_setup(void)
355{
356	unsigned int tmpword;
357
358	board_time_init = momenco_time_init;
359
360	_machine_restart = momenco_jaguar_restart;
361	_machine_halt = momenco_jaguar_halt;
362	_machine_power_off = momenco_jaguar_power_off;
363
364	/*
365	 * initrd_start = (ulong)jaguar_initrd_start;
366	 * initrd_end = (ulong)jaguar_initrd_start + (ulong)jaguar_initrd_size;
367	 * initrd_below_start_ok = 1;
368	 */
369
370	wire_stupidity_into_tlb();
371
372	/*
373	 * shut down ethernet ports, just to be sure our memory doesn't get
374	 * corrupted by random ethernet traffic.
375	 */
376	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8);
377	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8);
378	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8);
379	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8);
380	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8);
381	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8);
382	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff);
383	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff);
384	while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff);
385	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff);
386	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff);
387	while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff);
388	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0),
389	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1);
390	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1),
391	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1);
392	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2),
393	         MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1);
394
395	/* Turn off the Bit-Error LED */
396	JAGUAR_FPGA_WRITE(0x80, CLR);
397
398	tmpword = JAGUAR_FPGA_READ(BOARDREV);
399	if (tmpword < 26)
400		printk("Momentum Jaguar-ATX: Board Assembly Rev. %c\n",
401			'A'+tmpword);
402	else
403		printk("Momentum Jaguar-ATX: Board Assembly Revision #0x%x\n",
404			tmpword);
405
406	tmpword = JAGUAR_FPGA_READ(FPGA_REV);
407	printk("FPGA Rev: %d.%d\n", tmpword>>4, tmpword&15);
408	tmpword = JAGUAR_FPGA_READ(RESET_STATUS);
409	printk("Reset reason: 0x%x\n", tmpword);
410	switch (tmpword) {
411	case 0x1:
412		printk("  - Power-up reset\n");
413		break;
414	case 0x2:
415		printk("  - Push-button reset\n");
416		break;
417	case 0x8:
418		printk("  - Watchdog reset\n");
419		break;
420	case 0x10:
421		printk("  - JTAG reset\n");
422		break;
423	default:
424		printk("  - Unknown reset cause\n");
425	}
426	reset_reason = tmpword;
427	JAGUAR_FPGA_WRITE(0xff, RESET_STATUS);
428
429	tmpword = JAGUAR_FPGA_READ(BOARD_STATUS);
430	printk("Board Status register: 0x%02x\n", tmpword);
431	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
432	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
433
434	/* 256MiB of RM9000x2 DDR */
435//	add_memory_region(0x0, 0x100<<20, BOOT_MEM_RAM);
436
437	/* 128MiB of MV-64340 DDR */
438//	add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
439
440	/* XXX Memory configuration should be picked up from PMON2k */
441#ifdef CONFIG_JAGUAR_DMALOW
442	printk("Jaguar ATX DMA-low mode set\n");
443	add_memory_region(0x00000000, 0x08000000, BOOT_MEM_RAM);
444	add_memory_region(0x08000000, 0x10000000, BOOT_MEM_RAM);
445#else
446	/* 128MiB of MV-64340 DDR RAM */
447	printk("Jaguar ATX DMA-low mode is not set\n");
448	add_memory_region(0x100<<20, 0x80<<20, BOOT_MEM_RAM);
449#endif
450
451#ifdef GEMDEBUG_TRACEBUFFER
452	{
453	  unsigned int tbControl;
454	  tbControl = 
455	    0 << 26 |  /* post trigger delay 0 */
456	    	    0x2 << 16 |		/* sequential trace mode */
457	    //	    0x0 << 16 |		/* non-sequential trace mode */
458	    //	    0xf << 4 |		/* watchpoints disabled */
459	    2 << 2 |		/* armed */
460	    2 ;			/* interrupt disabled  */
461	  printk ("setting     tbControl = %08lx\n", tbControl);
462	  write_32bit_cp0_set1_register($22, tbControl);
463	  __asm__ __volatile__(".set noreorder\n\t" \
464			       "nop; nop; nop; nop; nop; nop;\n\t" \
465			       "nop; nop; nop; nop; nop; nop;\n\t" \
466			       ".set reorder\n\t");
467
468	}
469#endif
470
471	return 0;
472}
473
474early_initcall(momenco_jaguar_atx_setup);