summaryrefslogtreecommitdiffstats
path: root/target/linux/ramips/files/arch/mips/ralink/rt288x/setup.c
blob: d0258524cc74d932106764f0d8b33c66bbddbf36 (plain)
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
 * Ralink RT288x SoC specific setup
 *
 * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org>
 * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
 *
 * Parts of this file are based on Ralink's 2.6.21 BSP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/serial_8250.h>

#include <asm/bootinfo.h>
#include <asm/mips_machine.h>
#include <asm/reboot.h>
#include <asm/time.h>

#include <asm/mach-ralink/rt288x.h>
#include <asm/mach-ralink/rt288x_regs.h>

#define RT288X_MEM_SIZE_MIN (2 * 1024 * 1024)
#define RT288X_MEM_SIZE_MAX (128 * 1024 * 1024)

unsigned long rt288x_mach_type;

static void rt288x_restart(char *command)
{
	rt288x_sysc_wr(RT2880_RESET_SYSTEM, SYSC_REG_RESET_CTRL);
	while (1)
		if (cpu_wait)
			cpu_wait();
}

static void rt288x_halt(void)
{
	while (1)
		cpu_wait();
}

static void __init rt288x_detect_mem_size(void)
{
	unsigned long size;

	for (size = RT288X_MEM_SIZE_MIN; size < RT288X_MEM_SIZE_MAX;
	     size <<= 1 ) {
		if (!memcmp(rt288x_detect_mem_size,
			    rt288x_detect_mem_size + size, 1024))
			break;
	}

	add_memory_region(RT2880_SDRAM_BASE, size, BOOT_MEM_RAM);
}

static void __init rt288x_early_serial_setup(void)
{
	struct uart_port p;
	int err;

	memset(&p, 0, sizeof(p));
	p.flags		= UPF_SKIP_TEST;
	p.iotype	= UPIO_AU;
	p.uartclk	= rt288x_sys_freq;
	p.regshift	= 2;
	p.type		= PORT_16550A;

	p.mapbase	= RT2880_UART0_BASE;
	p.membase	= ioremap_nocache(p.mapbase, RT2880_UART0_SIZE);
	p.line		= 0;
	p.irq		= RT2880_INTC_IRQ_UART0;

	err = early_serial_setup(&p);
	if (err)
		printk(KERN_ERR "RT288x: early UART0 registration failed %d\n",
			err);

	p.mapbase	= RT2880_UART1_BASE;
	p.membase	= ioremap_nocache(p.mapbase, RT2880_UART1_SIZE);
	p.line		= 1;
	p.irq		= RT2880_INTC_IRQ_UART1;

	err = early_serial_setup(&p);
	if (err)
		printk(KERN_ERR "RT288x: early UART1 registration failed %d\n",
			err);
}

const char *get_system_type(void)
{
	return rt288x_sys_type;
}

unsigned int __cpuinit get_c0_compare_irq(void)
{
	return CP0_LEGACY_COMPARE_IRQ;
}

void __init plat_mem_setup(void)
{
	set_io_port_base(KSEG1);

	rt288x_sysc_base = ioremap_nocache(RT2880_SYSC_BASE, RT2880_SYSC_SIZE);
	rt288x_memc_base = ioremap_nocache(RT2880_MEMC_BASE, RT2880_MEMC_SIZE);

	rt288x_detect_mem_size();
	rt288x_detect_sys_type();
	rt288x_detect_sys_freq();

	printk(KERN_INFO "%s running at %lu.%02lu MHz\n", get_system_type(),
		rt288x_cpu_freq / 1000000,
		(rt288x_cpu_freq % 1000000) * 100 / 1000000);

	_machine_restart = rt288x_restart;
	_machine_halt = rt288x_halt;
	pm_power_off = rt288x_halt;

	rt288x_early_serial_setup();
}

void __init plat_time_init(void)
{
	mips_hpt_frequency = rt288x_cpu_freq / 2;
}

static int __init rt288x_machine_setup(void)
{
	mips_machine_setup(rt288x_mach_type);

	return 0;
}

arch_initcall(rt288x_machine_setup);