setup.c 12.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/*
 * Toshiba rbtx4927 specific setup
 *
 * Author: MontaVista Software, Inc.
 *         source@mvista.com
 *
 * Copyright 2001-2002 MontaVista Software Inc.
 *
 * Copyright (C) 1996, 97, 2001, 04  Ralf Baechle (ralf@linux-mips.org)
 * Copyright (C) 2000 RidgeRun, Inc.
 * Author: RidgeRun, Inc.
 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: jsun@mvista.com or jsun@junsun.net
 *
 * Copyright 2002 MontaVista Software Inc.
 * Author: Michael Pruznick, michael_pruznick@mvista.com
 *
 * Copyright (C) 2000-2001 Toshiba Corporation
 *
 * Copyright (C) 2004 MontaVista Software Inc.
 * Author: Manish Lachwani, mlachwani@mvista.com
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the
 *  Free Software Foundation; either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
50
#include <linux/pm.h>
51
#include <linux/platform_device.h>
52
#include <linux/delay.h>
53

L
Linus Torvalds 已提交
54 55 56 57 58
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/time.h>
59
#include <asm/txx9tmr.h>
60 61
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
A
Atsushi Nemoto 已提交
62
#include <asm/txx9/rbtx4927.h>
63
#include <asm/txx9/tx4938.h>	/* for TX4937 */
R
Ralf Baechle 已提交
64 65 66
#ifdef CONFIG_SERIAL_TXX9
#include <linux/serial_core.h>
#endif
L
Linus Torvalds 已提交
67 68 69 70 71 72 73

/* These functions are used for rebooting or halting the machine*/
extern void toshiba_rbtx4927_restart(char *command);
extern void toshiba_rbtx4927_halt(void);
extern void toshiba_rbtx4927_power_off(void);
extern void toshiba_rbtx4927_irq_setup(void);

74 75
char *prom_getcmdline(void);

L
Linus Torvalds 已提交
76 77 78
static int tx4927_ccfg_toeon = 1;

#ifdef CONFIG_PCI
79
static void __init tx4927_pci_setup(void)
L
Linus Torvalds 已提交
80
{
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
	int extarb = !(__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCIARB);
	struct pci_controller *c = &txx9_primary_pcic;

	register_pci_controller(c);

	if (__raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_PCI66)
		txx9_pci_option =
			(txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
			TXX9_PCI_OPT_CLK_66; /* already configured */

	/* Reset PCI Bus */
	writeb(1, rbtx4927_pcireset_addr);
	/* Reset PCIC */
	txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
	if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
	    TXX9_PCI_OPT_CLK_66)
		tx4927_pciclk66_setup();
	mdelay(10);
	/* clear PCIC reset */
	txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
	writeb(0, rbtx4927_pcireset_addr);
	iob();

	tx4927_report_pciclk();
	tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
	if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
	    TXX9_PCI_OPT_CLK_AUTO &&
	    txx9_pci66_check(c, 0, 0)) {
		/* Reset PCI Bus */
		writeb(1, rbtx4927_pcireset_addr);
		/* Reset PCIC */
		txx9_set64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
		tx4927_pciclk66_setup();
		mdelay(10);
		/* clear PCIC reset */
		txx9_clear64(&tx4927_ccfgptr->clkctr, TX4927_CLKCTR_PCIRST);
		writeb(0, rbtx4927_pcireset_addr);
		iob();
		/* Reinitialize PCIC */
		tx4927_report_pciclk();
		tx4927_pcic_setup(tx4927_pcicptr, c, extarb);
	}
L
Linus Torvalds 已提交
123 124
}

125
static void __init tx4937_pci_setup(void)
L
Linus Torvalds 已提交
126
{
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
	int extarb = !(__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCIARB);
	struct pci_controller *c = &txx9_primary_pcic;

	register_pci_controller(c);

	if (__raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_PCI66)
		txx9_pci_option =
			(txx9_pci_option & ~TXX9_PCI_OPT_CLK_MASK) |
			TXX9_PCI_OPT_CLK_66; /* already configured */

	/* Reset PCI Bus */
	writeb(1, rbtx4927_pcireset_addr);
	/* Reset PCIC */
	txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
	if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
	    TXX9_PCI_OPT_CLK_66)
		tx4938_pciclk66_setup();
	mdelay(10);
	/* clear PCIC reset */
	txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
	writeb(0, rbtx4927_pcireset_addr);
	iob();

	tx4938_report_pciclk();
	tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
	if ((txx9_pci_option & TXX9_PCI_OPT_CLK_MASK) ==
	    TXX9_PCI_OPT_CLK_AUTO &&
	    txx9_pci66_check(c, 0, 0)) {
		/* Reset PCI Bus */
		writeb(1, rbtx4927_pcireset_addr);
		/* Reset PCIC */
		txx9_set64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
		tx4938_pciclk66_setup();
		mdelay(10);
		/* clear PCIC reset */
		txx9_clear64(&tx4938_ccfgptr->clkctr, TX4938_CLKCTR_PCIRST);
		writeb(0, rbtx4927_pcireset_addr);
		iob();
		/* Reinitialize PCIC */
		tx4938_report_pciclk();
		tx4927_pcic_setup(tx4938_pcicptr, c, extarb);
L
Linus Torvalds 已提交
168 169 170
	}
}

171
static void __init rbtx4927_arch_init(void)
L
Linus Torvalds 已提交
172
{
173 174 175 176
	if (mips_machtype == MACH_TOSHIBA_RBTX4937)
		tx4937_pci_setup();
	else
		tx4927_pci_setup();
L
Linus Torvalds 已提交
177
}
178 179
#else
#define rbtx4927_arch_init NULL
L
Linus Torvalds 已提交
180 181
#endif /* CONFIG_PCI */

182 183 184 185 186 187 188
static void __noreturn wait_forever(void)
{
	while (1)
		if (cpu_wait)
			(*cpu_wait)();
}

L
Linus Torvalds 已提交
189 190 191 192 193
void toshiba_rbtx4927_restart(char *command)
{
	printk(KERN_NOTICE "System Rebooting...\n");

	/* enable the s/w reset register */
194
	writeb(RBTX4927_SW_RESET_ENABLE_SET, RBTX4927_SW_RESET_ENABLE);
L
Linus Torvalds 已提交
195 196

	/* wait for enable to be seen */
197
	while ((readb(RBTX4927_SW_RESET_ENABLE) &
L
Linus Torvalds 已提交
198 199 200
		RBTX4927_SW_RESET_ENABLE_SET) == 0x00);

	/* do a s/w reset */
201
	writeb(RBTX4927_SW_RESET_DO_SET, RBTX4927_SW_RESET_DO);
L
Linus Torvalds 已提交
202 203 204

	/* do something passive while waiting for reset */
	local_irq_disable();
205
	wait_forever();
L
Linus Torvalds 已提交
206 207 208 209 210 211 212
	/* no return */
}

void toshiba_rbtx4927_halt(void)
{
	printk(KERN_NOTICE "System Halted\n");
	local_irq_disable();
213
	wait_forever();
L
Linus Torvalds 已提交
214 215 216 217 218 219 220 221 222
	/* no return */
}

void toshiba_rbtx4927_power_off(void)
{
	toshiba_rbtx4927_halt();
	/* no return */
}

223
static void __init rbtx4927_mem_setup(void)
L
Linus Torvalds 已提交
224
{
225
	int i;
226
	u32 cp0_config;
L
Linus Torvalds 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
	char *argptr;

	/* f/w leaves this on at startup */
	clear_c0_status(ST0_ERL);

	/* enable caches -- HCP5 does this, pmon does not */
	cp0_config = read_c0_config();
	cp0_config = cp0_config & ~(TX49_CONF_IC | TX49_CONF_DC);
	write_c0_config(cp0_config);

	ioport_resource.end = 0xffffffff;
	iomem_resource.end = 0xffffffff;

	_machine_restart = toshiba_rbtx4927_restart;
	_machine_halt = toshiba_rbtx4927_halt;
242
	pm_power_off = toshiba_rbtx4927_power_off;
L
Linus Torvalds 已提交
243

244 245 246
	for (i = 0; i < TX4927_NR_TMR; i++)
		txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL);

L
Linus Torvalds 已提交
247
#ifdef CONFIG_PCI
248 249 250 251 252 253
	txx9_alloc_pci_controller(&txx9_primary_pcic,
				  RBTX4927_PCIMEM, RBTX4927_PCIMEM_SIZE,
				  RBTX4927_PCIIO, RBTX4927_PCIIO_SIZE);
#else
	set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET);
#endif
L
Linus Torvalds 已提交
254 255 256

	/*
	   * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz.
257 258 259
	   *
	   * For TX4927:
	   * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1).
L
Linus Torvalds 已提交
260 261 262 263 264
	   * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5)
	   * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3)
	   * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5)
	   * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6)
	   * i.e. S9[3]: ON (83MHz), OFF (100MHz)
265 266 267 268 269 270 271 272 273 274 275
	   *
	   * For TX4937:
	   * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1)
	   * PCIDIVMODE[10] is 0.
	   * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8)
	   * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4)
	   * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9)
	   * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5)
	   * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10)
	   * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5)
	   *
L
Linus Torvalds 已提交
276
	 */
277
	if (mips_machtype == MACH_TOSHIBA_RBTX4937)
278 279 280 281 282
		switch ((unsigned long)__raw_readq(&tx4938_ccfgptr->ccfg) &
			TX4938_CCFG_PCIDIVMODE_MASK) {
		case TX4938_CCFG_PCIDIVMODE_8:
		case TX4938_CCFG_PCIDIVMODE_4:
			txx9_cpu_clock = 266666666;	/* 266MHz */
283
			break;
284 285 286
		case TX4938_CCFG_PCIDIVMODE_9:
		case TX4938_CCFG_PCIDIVMODE_4_5:
			txx9_cpu_clock = 300000000;	/* 300MHz */
287 288
			break;
		default:
289
			txx9_cpu_clock = 333333333;	/* 333MHz */
290 291
		}
	else
292 293
		switch ((unsigned long)__raw_readq(&tx4927_ccfgptr->ccfg) &
			TX4927_CCFG_PCIDIVMODE_MASK) {
294 295
		case TX4927_CCFG_PCIDIVMODE_2_5:
		case TX4927_CCFG_PCIDIVMODE_5:
296
			txx9_cpu_clock = 166666666;	/* 166MHz */
297 298
			break;
		default:
299
			txx9_cpu_clock = 200000000;	/* 200MHz */
300
		}
301 302
	/* change default value to udelay/mdelay take reasonable time */
	loops_per_jiffy = txx9_cpu_clock / HZ / 2;
L
Linus Torvalds 已提交
303 304

	/* CCFG */
305
	/* do reset on watchdog */
306
	tx4927_ccfg_set(TX4927_CCFG_WR);
L
Linus Torvalds 已提交
307 308
	/* enable Timeout BusError */
	if (tx4927_ccfg_toeon)
309
		tx4927_ccfg_set(TX4927_CCFG_TOE);
L
Linus Torvalds 已提交
310

R
Ralf Baechle 已提交
311 312 313 314 315 316 317 318 319 320
#ifdef CONFIG_SERIAL_TXX9
	{
		extern int early_serial_txx9_setup(struct uart_port *port);
		struct uart_port req;
		for(i = 0; i < 2; i++) {
			memset(&req, 0, sizeof(req));
			req.line = i;
			req.iotype = UPIO_MEM;
			req.membase = (char *)(0xff1ff300 + i * 0x100);
			req.mapbase = 0xff1ff300 + i * 0x100;
321
			req.irq = TXX9_IRQ_BASE + TX4927_IR_SIO(i);
R
Ralf Baechle 已提交
322 323 324 325 326
			req.flags |= UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
			req.uartclk = 50000000;
			early_serial_txx9_setup(&req);
		}
	}
L
Linus Torvalds 已提交
327 328 329 330 331 332
#ifdef CONFIG_SERIAL_TXX9_CONSOLE
        argptr = prom_getcmdline();
        if (strstr(argptr, "console=") == NULL) {
                strcat(argptr, " console=ttyS0,38400");
        }
#endif
R
Ralf Baechle 已提交
333
#endif
L
Linus Torvalds 已提交
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349

#ifdef CONFIG_ROOT_NFS
        argptr = prom_getcmdline();
        if (strstr(argptr, "root=") == NULL) {
                strcat(argptr, " root=/dev/nfs rw");
        }
#endif

#ifdef CONFIG_IP_PNP
        argptr = prom_getcmdline();
        if (strstr(argptr, "ip=") == NULL) {
                strcat(argptr, " ip=any");
        }
#endif
}

350
static void __init rbtx4927_time_init(void)
L
Linus Torvalds 已提交
351
{
352 353
	mips_hpt_frequency = txx9_cpu_clock / 2;
	if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_TINTDIS)
354 355 356
		txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
				     TXX9_IRQ_BASE + 17,
				     50000000);
L
Linus Torvalds 已提交
357 358
}

359 360
static int __init toshiba_rbtx4927_rtc_init(void)
{
361
	static struct resource __initdata res = {
362 363 364 365 366
		.start	= 0x1c010000,
		.end	= 0x1c010000 + 0x800 - 1,
		.flags	= IORESOURCE_MEM,
	};
	struct platform_device *dev =
367
		platform_device_register_simple("rtc-ds1742", -1, &res, 1);
368 369
	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387

static int __init rbtx4927_ne_init(void)
{
	static struct resource __initdata res[] = {
		{
			.start	= RBTX4927_RTL_8019_BASE,
			.end	= RBTX4927_RTL_8019_BASE + 0x20 - 1,
			.flags	= IORESOURCE_IO,
		}, {
			.start	= RBTX4927_RTL_8019_IRQ,
			.flags	= IORESOURCE_IRQ,
		}
	};
	struct platform_device *dev =
		platform_device_register_simple("ne", -1,
						res, ARRAY_SIZE(res));
	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407

/* Watchdog support */

static int __init txx9_wdt_init(unsigned long base)
{
	struct resource res = {
		.start	= base,
		.end	= base + 0x100 - 1,
		.flags	= IORESOURCE_MEM,
	};
	struct platform_device *dev =
		platform_device_register_simple("txx9wdt", -1, &res, 1);
	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}

static int __init rbtx4927_wdt_init(void)
{
	return txx9_wdt_init(TX4927_TMR_REG(2) & 0xfffffffffULL);
}

408
static void __init rbtx4927_device_init(void)
409
{
410 411 412
	toshiba_rbtx4927_rtc_init();
	rbtx4927_ne_init();
	rbtx4927_wdt_init();
413 414
}

415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
struct txx9_board_vec rbtx4927_vec __initdata = {
	.type = MACH_TOSHIBA_RBTX4927,
	.system = "Toshiba RBTX4927",
	.prom_init = rbtx4927_prom_init,
	.mem_setup = rbtx4927_mem_setup,
	.irq_setup = rbtx4927_irq_setup,
	.time_init = rbtx4927_time_init,
	.device_init = rbtx4927_device_init,
	.arch_init = rbtx4927_arch_init,
#ifdef CONFIG_PCI
	.pci_map_irq = rbtx4927_pci_map_irq,
#endif
};
struct txx9_board_vec rbtx4937_vec __initdata = {
	.type = MACH_TOSHIBA_RBTX4937,
	.system = "Toshiba RBTX4937",
	.prom_init = rbtx4927_prom_init,
	.mem_setup = rbtx4927_mem_setup,
	.irq_setup = rbtx4927_irq_setup,
	.time_init = rbtx4927_time_init,
	.device_init = rbtx4927_device_init,
	.arch_init = rbtx4927_arch_init,
#ifdef CONFIG_PCI
	.pci_map_irq = rbtx4927_pci_map_irq,
#endif
};