Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/bcm63xx/setup.c
26424 views
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (C) 2008 Maxime Bizon <[email protected]>
7
*/
8
9
#include <linux/init.h>
10
#include <linux/kernel.h>
11
#include <linux/delay.h>
12
#include <linux/memblock.h>
13
#include <linux/ioport.h>
14
#include <linux/pm.h>
15
#include <asm/bmips.h>
16
#include <asm/bootinfo.h>
17
#include <asm/time.h>
18
#include <asm/reboot.h>
19
#include <asm/cacheflush.h>
20
#include <bcm63xx_board.h>
21
#include <bcm63xx_cpu.h>
22
#include <bcm63xx_regs.h>
23
#include <bcm63xx_io.h>
24
#include <bcm63xx_gpio.h>
25
26
/*
27
* CBR addr doesn't change and we can cache it.
28
* For broken SoC/Bootloader CBR addr might also be provided via DT
29
* with "brcm,bmips-cbr-reg" in the "cpus" node.
30
*/
31
void __iomem *bmips_cbr_addr __read_mostly;
32
33
void bcm63xx_machine_halt(void)
34
{
35
pr_info("System halted\n");
36
while (1)
37
;
38
}
39
40
static void bcm6348_a1_reboot(void)
41
{
42
u32 reg;
43
44
/* soft reset all blocks */
45
pr_info("soft-resetting all blocks ...\n");
46
reg = bcm_perf_readl(PERF_SOFTRESET_REG);
47
reg &= ~SOFTRESET_6348_ALL;
48
bcm_perf_writel(reg, PERF_SOFTRESET_REG);
49
mdelay(10);
50
51
reg = bcm_perf_readl(PERF_SOFTRESET_REG);
52
reg |= SOFTRESET_6348_ALL;
53
bcm_perf_writel(reg, PERF_SOFTRESET_REG);
54
mdelay(10);
55
56
/* Jump to the power on address. */
57
pr_info("jumping to reset vector.\n");
58
/* set high vectors (base at 0xbfc00000 */
59
set_c0_status(ST0_BEV | ST0_ERL);
60
/* run uncached in kseg0 */
61
change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
62
__flush_cache_all();
63
/* remove all wired TLB entries */
64
write_c0_wired(0);
65
__asm__ __volatile__(
66
"jr\t%0"
67
:
68
: "r" (0xbfc00000));
69
while (1)
70
;
71
}
72
73
void bcm63xx_machine_reboot(void)
74
{
75
u32 reg, perf_regs[2] = { 0, 0 };
76
unsigned int i;
77
78
/* mask and clear all external irq */
79
switch (bcm63xx_get_cpu_id()) {
80
case BCM3368_CPU_ID:
81
perf_regs[0] = PERF_EXTIRQ_CFG_REG_3368;
82
break;
83
case BCM6328_CPU_ID:
84
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
85
break;
86
case BCM6338_CPU_ID:
87
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
88
break;
89
case BCM6345_CPU_ID:
90
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
91
break;
92
case BCM6348_CPU_ID:
93
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
94
break;
95
case BCM6358_CPU_ID:
96
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358;
97
break;
98
case BCM6362_CPU_ID:
99
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6362;
100
break;
101
}
102
103
for (i = 0; i < 2; i++) {
104
if (!perf_regs[i])
105
break;
106
107
reg = bcm_perf_readl(perf_regs[i]);
108
if (BCMCPU_IS_6348()) {
109
reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
110
reg |= EXTIRQ_CFG_CLEAR_ALL_6348;
111
} else {
112
reg &= ~EXTIRQ_CFG_MASK_ALL;
113
reg |= EXTIRQ_CFG_CLEAR_ALL;
114
}
115
bcm_perf_writel(reg, perf_regs[i]);
116
}
117
118
if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
119
bcm6348_a1_reboot();
120
121
pr_info("triggering watchdog soft-reset...\n");
122
if (BCMCPU_IS_6328()) {
123
bcm_wdt_writel(1, WDT_SOFTRESET_REG);
124
} else {
125
reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
126
reg |= SYS_PLL_SOFT_RESET;
127
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
128
}
129
while (1)
130
;
131
}
132
133
static void __bcm63xx_machine_reboot(char *p)
134
{
135
bcm63xx_machine_reboot();
136
}
137
138
/*
139
* return system type in /proc/cpuinfo
140
*/
141
const char *get_system_type(void)
142
{
143
static char buf[128];
144
snprintf(buf, sizeof(buf), "bcm63xx/%s (0x%04x/0x%02X)",
145
board_get_name(),
146
bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev());
147
return buf;
148
}
149
150
void __init plat_time_init(void)
151
{
152
mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2;
153
}
154
155
void __init plat_mem_setup(void)
156
{
157
memblock_add(0, bcm63xx_get_memory_size());
158
159
_machine_halt = bcm63xx_machine_halt;
160
_machine_restart = __bcm63xx_machine_reboot;
161
pm_power_off = bcm63xx_machine_halt;
162
163
set_io_port_base(0);
164
ioport_resource.start = 0;
165
ioport_resource.end = ~0;
166
167
board_setup();
168
}
169
170
static int __init bcm63xx_register_devices(void)
171
{
172
/* register gpiochip */
173
bcm63xx_gpio_init();
174
175
return board_register_devices();
176
}
177
178
arch_initcall(bcm63xx_register_devices);
179
180