Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/sibyte/sb1250/setup.c
26481 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
4
*/
5
#include <linux/export.h>
6
#include <linux/init.h>
7
#include <linux/kernel.h>
8
#include <linux/reboot.h>
9
#include <linux/string.h>
10
11
#include <asm/bootinfo.h>
12
#include <asm/cpu.h>
13
#include <asm/mipsregs.h>
14
#include <asm/io.h>
15
#include <asm/sibyte/sb1250.h>
16
#include <asm/sibyte/sb1250_regs.h>
17
#include <asm/sibyte/sb1250_scd.h>
18
19
unsigned int sb1_pass;
20
unsigned int soc_pass;
21
unsigned int soc_type;
22
EXPORT_SYMBOL(soc_type);
23
unsigned int periph_rev;
24
EXPORT_SYMBOL_GPL(periph_rev);
25
unsigned int zbbus_mhz;
26
EXPORT_SYMBOL(zbbus_mhz);
27
28
static char *soc_str;
29
static char *pass_str;
30
static unsigned int war_pass; /* XXXKW don't overload PASS defines? */
31
32
static int __init setup_bcm1250(void)
33
{
34
int ret = 0;
35
36
switch (soc_pass) {
37
case K_SYS_REVISION_BCM1250_PASS1:
38
periph_rev = 1;
39
pass_str = "Pass 1";
40
break;
41
case K_SYS_REVISION_BCM1250_A10:
42
periph_rev = 2;
43
pass_str = "A8/A10";
44
/* XXXKW different war_pass? */
45
war_pass = K_SYS_REVISION_BCM1250_PASS2;
46
break;
47
case K_SYS_REVISION_BCM1250_PASS2_2:
48
periph_rev = 2;
49
pass_str = "B1";
50
break;
51
case K_SYS_REVISION_BCM1250_B2:
52
periph_rev = 2;
53
pass_str = "B2";
54
war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
55
break;
56
case K_SYS_REVISION_BCM1250_PASS3:
57
periph_rev = 3;
58
pass_str = "C0";
59
break;
60
case K_SYS_REVISION_BCM1250_C1:
61
periph_rev = 3;
62
pass_str = "C1";
63
break;
64
default:
65
if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
66
periph_rev = 2;
67
pass_str = "A0-A6";
68
war_pass = K_SYS_REVISION_BCM1250_PASS2;
69
} else {
70
printk("Unknown BCM1250 rev %x\n", soc_pass);
71
ret = 1;
72
}
73
break;
74
}
75
76
return ret;
77
}
78
79
int sb1250_m3_workaround_needed(void)
80
{
81
switch (soc_type) {
82
case K_SYS_SOC_TYPE_BCM1250:
83
case K_SYS_SOC_TYPE_BCM1250_ALT:
84
case K_SYS_SOC_TYPE_BCM1250_ALT2:
85
case K_SYS_SOC_TYPE_BCM1125:
86
case K_SYS_SOC_TYPE_BCM1125H:
87
return soc_pass < K_SYS_REVISION_BCM1250_C0;
88
89
default:
90
return 0;
91
}
92
}
93
94
static int __init setup_bcm112x(void)
95
{
96
int ret = 0;
97
98
switch (soc_pass) {
99
case 0:
100
/* Early build didn't have revid set */
101
periph_rev = 3;
102
pass_str = "A1";
103
war_pass = K_SYS_REVISION_BCM112x_A1;
104
break;
105
case K_SYS_REVISION_BCM112x_A1:
106
periph_rev = 3;
107
pass_str = "A1";
108
break;
109
case K_SYS_REVISION_BCM112x_A2:
110
periph_rev = 3;
111
pass_str = "A2";
112
break;
113
case K_SYS_REVISION_BCM112x_A3:
114
periph_rev = 3;
115
pass_str = "A3";
116
break;
117
case K_SYS_REVISION_BCM112x_A4:
118
periph_rev = 3;
119
pass_str = "A4";
120
break;
121
case K_SYS_REVISION_BCM112x_B0:
122
periph_rev = 3;
123
pass_str = "B0";
124
break;
125
default:
126
printk("Unknown %s rev %x\n", soc_str, soc_pass);
127
ret = 1;
128
}
129
130
return ret;
131
}
132
133
/* Setup code likely to be common to all SiByte platforms */
134
135
static int __init sys_rev_decode(void)
136
{
137
int ret = 0;
138
139
war_pass = soc_pass;
140
switch (soc_type) {
141
case K_SYS_SOC_TYPE_BCM1250:
142
case K_SYS_SOC_TYPE_BCM1250_ALT:
143
case K_SYS_SOC_TYPE_BCM1250_ALT2:
144
soc_str = "BCM1250";
145
ret = setup_bcm1250();
146
break;
147
case K_SYS_SOC_TYPE_BCM1120:
148
soc_str = "BCM1120";
149
ret = setup_bcm112x();
150
break;
151
case K_SYS_SOC_TYPE_BCM1125:
152
soc_str = "BCM1125";
153
ret = setup_bcm112x();
154
break;
155
case K_SYS_SOC_TYPE_BCM1125H:
156
soc_str = "BCM1125H";
157
ret = setup_bcm112x();
158
break;
159
default:
160
printk("Unknown SOC type %x\n", soc_type);
161
ret = 1;
162
break;
163
}
164
165
return ret;
166
}
167
168
void __init sb1250_setup(void)
169
{
170
uint64_t sys_rev;
171
int plldiv;
172
int bad_config = 0;
173
174
sb1_pass = read_c0_prid() & PRID_REV_MASK;
175
sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
176
soc_type = SYS_SOC_TYPE(sys_rev);
177
soc_pass = G_SYS_REVISION(sys_rev);
178
179
if (sys_rev_decode()) {
180
printk("Restart after failure to identify SiByte chip\n");
181
machine_restart(NULL);
182
}
183
184
plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
185
zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
186
187
printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
188
soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
189
printk("Board type: %s\n", get_system_type());
190
191
switch (war_pass) {
192
case K_SYS_REVISION_BCM1250_PASS1:
193
printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
194
"and the kernel doesn't have the proper "
195
"workarounds compiled in. @@@@\n");
196
bad_config = 1;
197
break;
198
case K_SYS_REVISION_BCM1250_PASS2:
199
/* Pass 2 - easiest as default for now - so many numbers */
200
#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
201
!defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
202
printk("@@@@ This is a BCM1250 A3-A10 board, and the "
203
"kernel doesn't have the proper workarounds "
204
"compiled in. @@@@\n");
205
bad_config = 1;
206
#endif
207
#ifdef CONFIG_CPU_HAS_PREFETCH
208
printk("@@@@ Prefetches may be enabled in this kernel, "
209
"but are buggy on this board. @@@@\n");
210
bad_config = 1;
211
#endif
212
break;
213
case K_SYS_REVISION_BCM1250_PASS2_2:
214
#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
215
printk("@@@@ This is a BCM1250 B1/B2. board, and the "
216
"kernel doesn't have the proper workarounds "
217
"compiled in. @@@@\n");
218
bad_config = 1;
219
#endif
220
#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
221
!defined(CONFIG_CPU_HAS_PREFETCH)
222
printk("@@@@ This is a BCM1250 B1/B2, but the kernel is "
223
"conservatively configured for an 'A' stepping. "
224
"@@@@\n");
225
#endif
226
break;
227
default:
228
break;
229
}
230
if (bad_config) {
231
printk("Invalid configuration for this chip.\n");
232
machine_restart(NULL);
233
}
234
}
235
236