Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
arm
mach-orion5x
common.c
Go to the documentation of this file.
1
/*
2
* arch/arm/mach-orion5x/common.c
3
*
4
* Core functions for Marvell Orion 5x SoCs
5
*
6
* Maintainer: Tzachi Perelstein <
[email protected]
>
7
*
8
* This file is licensed under the terms of the GNU General Public
9
* License version 2. This program is licensed "as is" without any
10
* warranty of any kind, whether express or implied.
11
*/
12
13
#include <linux/kernel.h>
14
#include <
linux/init.h
>
15
#include <
linux/platform_device.h
>
16
#include <
linux/dma-mapping.h
>
17
#include <
linux/serial_8250.h
>
18
#include <
linux/mv643xx_i2c.h
>
19
#include <
linux/ata_platform.h
>
20
#include <
linux/delay.h
>
21
#include <
linux/clk-provider.h
>
22
#include <
net/dsa.h
>
23
#include <asm/page.h>
24
#include <asm/setup.h>
25
#include <asm/system_misc.h>
26
#include <asm/timex.h>
27
#include <
asm/mach/arch.h
>
28
#include <
asm/mach/map.h
>
29
#include <
asm/mach/time.h
>
30
#include <mach/bridge-regs.h>
31
#include <mach/hardware.h>
32
#include <
mach/orion5x.h
>
33
#include <
linux/platform_data/mtd-orion_nand.h
>
34
#include <
linux/platform_data/usb-ehci-orion.h
>
35
#include <
plat/time.h
>
36
#include <plat/common.h>
37
#include <
plat/addr-map.h
>
38
#include "
common.h
"
39
40
/*****************************************************************************
41
* I/O Address Mapping
42
****************************************************************************/
43
static
struct
map_desc
orion5x_io_desc[]
__initdata
= {
44
{
45
.virtual = (
unsigned
long
)
ORION5X_REGS_VIRT_BASE
,
46
.
pfn
=
__phys_to_pfn
(
ORION5X_REGS_PHYS_BASE
),
47
.length =
ORION5X_REGS_SIZE
,
48
.type =
MT_DEVICE
,
49
}, {
50
.virtual = (
unsigned
long
)
ORION5X_PCIE_WA_VIRT_BASE
,
51
.
pfn
=
__phys_to_pfn
(
ORION5X_PCIE_WA_PHYS_BASE
),
52
.length =
ORION5X_PCIE_WA_SIZE
,
53
.type =
MT_DEVICE
,
54
},
55
};
56
57
void
__init
orion5x_map_io
(
void
)
58
{
59
iotable_init
(orion5x_io_desc,
ARRAY_SIZE
(orion5x_io_desc));
60
}
61
62
63
/*****************************************************************************
64
* CLK tree
65
****************************************************************************/
66
static
struct
clk
*tclk;
67
68
static
void
__init
clk_init
(
void
)
69
{
70
tclk =
clk_register_fixed_rate
(
NULL
,
"tclk"
,
NULL
, CLK_IS_ROOT,
71
orion5x_tclk
);
72
73
orion_clkdev_init
(tclk);
74
}
75
76
/*****************************************************************************
77
* EHCI0
78
****************************************************************************/
79
void
__init
orion5x_ehci0_init
(
void
)
80
{
81
orion_ehci_init
(
ORION5X_USB0_PHYS_BASE
,
IRQ_ORION5X_USB0_CTRL
,
82
EHCI_PHY_ORION
);
83
}
84
85
86
/*****************************************************************************
87
* EHCI1
88
****************************************************************************/
89
void
__init
orion5x_ehci1_init
(
void
)
90
{
91
orion_ehci_1_init
(
ORION5X_USB1_PHYS_BASE
,
IRQ_ORION5X_USB1_CTRL
);
92
}
93
94
95
/*****************************************************************************
96
* GE00
97
****************************************************************************/
98
void
__init
orion5x_eth_init
(
struct
mv643xx_eth_platform_data
*eth_data)
99
{
100
orion_ge00_init
(eth_data,
101
ORION5X_ETH_PHYS_BASE
,
IRQ_ORION5X_ETH_SUM
,
102
IRQ_ORION5X_ETH_ERR
,
103
MV643XX_TX_CSUM_DEFAULT_LIMIT
);
104
}
105
106
107
/*****************************************************************************
108
* Ethernet switch
109
****************************************************************************/
110
void
__init
orion5x_eth_switch_init
(
struct
dsa_platform_data
*
d
,
int
irq)
111
{
112
orion_ge00_switch_init
(d, irq);
113
}
114
115
116
/*****************************************************************************
117
* I2C
118
****************************************************************************/
119
void
__init
orion5x_i2c_init
(
void
)
120
{
121
orion_i2c_init
(
I2C_PHYS_BASE
,
IRQ_ORION5X_I2C
, 8);
122
123
}
124
125
126
/*****************************************************************************
127
* SATA
128
****************************************************************************/
129
void
__init
orion5x_sata_init
(
struct
mv_sata_platform_data
*sata_data)
130
{
131
orion_sata_init
(sata_data,
ORION5X_SATA_PHYS_BASE
,
IRQ_ORION5X_SATA
);
132
}
133
134
135
/*****************************************************************************
136
* SPI
137
****************************************************************************/
138
void
__init
orion5x_spi_init
()
139
{
140
orion_spi_init
(
SPI_PHYS_BASE
);
141
}
142
143
144
/*****************************************************************************
145
* UART0
146
****************************************************************************/
147
void
__init
orion5x_uart0_init
(
void
)
148
{
149
orion_uart0_init
(
UART0_VIRT_BASE
,
UART0_PHYS_BASE
,
150
IRQ_ORION5X_UART0
, tclk);
151
}
152
153
/*****************************************************************************
154
* UART1
155
****************************************************************************/
156
void
__init
orion5x_uart1_init
(
void
)
157
{
158
orion_uart1_init
(
UART1_VIRT_BASE
,
UART1_PHYS_BASE
,
159
IRQ_ORION5X_UART1
, tclk);
160
}
161
162
/*****************************************************************************
163
* XOR engine
164
****************************************************************************/
165
void
__init
orion5x_xor_init
(
void
)
166
{
167
orion_xor0_init
(
ORION5X_XOR_PHYS_BASE
,
168
ORION5X_XOR_PHYS_BASE
+ 0x200,
169
IRQ_ORION5X_XOR0
,
IRQ_ORION5X_XOR1
);
170
}
171
172
/*****************************************************************************
173
* Cryptographic Engines and Security Accelerator (CESA)
174
****************************************************************************/
175
static
void
__init
orion5x_crypto_init(
void
)
176
{
177
orion5x_setup_sram_win
();
178
orion_crypto_init
(
ORION5X_CRYPTO_PHYS_BASE
,
ORION5X_SRAM_PHYS_BASE
,
179
SZ_8K
,
IRQ_ORION5X_CESA
);
180
}
181
182
/*****************************************************************************
183
* Watchdog
184
****************************************************************************/
185
void
__init
orion5x_wdt_init
(
void
)
186
{
187
orion_wdt_init
();
188
}
189
190
191
/*****************************************************************************
192
* Time handling
193
****************************************************************************/
194
void
__init
orion5x_init_early
(
void
)
195
{
196
orion_time_set_base
(
TIMER_VIRT_BASE
);
197
198
/*
199
* Some Orion5x devices allocate their coherent buffers from atomic
200
* context. Increase size of atomic coherent pool to make sure such
201
* the allocations won't fail.
202
*/
203
init_dma_coherent_pool_size(
SZ_1M
);
204
}
205
206
int
orion5x_tclk
;
207
208
int
__init
orion5x_find_tclk
(
void
)
209
{
210
u32
dev
,
rev
;
211
212
orion5x_pcie_id
(&dev, &rev);
213
if
(dev ==
MV88F6183_DEV_ID
&&
214
(
readl
(
MPP_RESET_SAMPLE
) & 0x00000200) == 0)
215
return
133333333;
216
217
return
166666667;
218
}
219
220
static
void
__init
orion5x_timer_init(
void
)
221
{
222
orion5x_tclk =
orion5x_find_tclk
();
223
224
orion_time_init
(
ORION5X_BRIDGE_VIRT_BASE
,
BRIDGE_INT_TIMER1_CLR
,
225
IRQ_ORION5X_BRIDGE
, orion5x_tclk);
226
}
227
228
struct
sys_timer
orion5x_timer
= {
229
.init = orion5x_timer_init,
230
};
231
232
233
/*****************************************************************************
234
* General
235
****************************************************************************/
236
/*
237
* Identify device ID and rev from PCIe configuration header space '0'.
238
*/
239
static
void
__init
orion5x_id(
u32
*
dev
,
u32
*
rev
,
char
**dev_name)
240
{
241
orion5x_pcie_id
(dev, rev);
242
243
if
(*dev ==
MV88F5281_DEV_ID
) {
244
if
(*rev ==
MV88F5281_REV_D2
) {
245
*dev_name =
"MV88F5281-D2"
;
246
}
else
if
(*rev ==
MV88F5281_REV_D1
) {
247
*dev_name =
"MV88F5281-D1"
;
248
}
else
if
(*rev ==
MV88F5281_REV_D0
) {
249
*dev_name =
"MV88F5281-D0"
;
250
}
else
{
251
*dev_name =
"MV88F5281-Rev-Unsupported"
;
252
}
253
}
else
if
(*dev ==
MV88F5182_DEV_ID
) {
254
if
(*rev ==
MV88F5182_REV_A2
) {
255
*dev_name =
"MV88F5182-A2"
;
256
}
else
{
257
*dev_name =
"MV88F5182-Rev-Unsupported"
;
258
}
259
}
else
if
(*dev ==
MV88F5181_DEV_ID
) {
260
if
(*rev ==
MV88F5181_REV_B1
) {
261
*dev_name =
"MV88F5181-Rev-B1"
;
262
}
else
if
(*rev ==
MV88F5181L_REV_A1
) {
263
*dev_name =
"MV88F5181L-Rev-A1"
;
264
}
else
{
265
*dev_name =
"MV88F5181(L)-Rev-Unsupported"
;
266
}
267
}
else
if
(*dev ==
MV88F6183_DEV_ID
) {
268
if
(*rev ==
MV88F6183_REV_B0
) {
269
*dev_name =
"MV88F6183-Rev-B0"
;
270
}
else
{
271
*dev_name =
"MV88F6183-Rev-Unsupported"
;
272
}
273
}
else
{
274
*dev_name =
"Device-Unknown"
;
275
}
276
}
277
278
void
__init
orion5x_init
(
void
)
279
{
280
char
*dev_name;
281
u32
dev
,
rev
;
282
283
orion5x_id(&dev, &rev, &dev_name);
284
printk
(
KERN_INFO
"Orion ID: %s. TCLK=%d.\n"
, dev_name, orion5x_tclk);
285
286
/*
287
* Setup Orion address map
288
*/
289
orion5x_setup_cpu_mbus_bridge
();
290
291
/* Setup root of clk tree */
292
clk_init
();
293
294
/*
295
* Don't issue "Wait for Interrupt" instruction if we are
296
* running on D0 5281 silicon.
297
*/
298
if
(dev ==
MV88F5281_DEV_ID
&& rev ==
MV88F5281_REV_D0
) {
299
printk
(
KERN_INFO
"Orion: Applying 5281 D0 WFI workaround.\n"
);
300
disable_hlt
();
301
}
302
303
/*
304
* The 5082/5181l/5182/6082/6082l/6183 have crypto
305
* while 5180n/5181/5281 don't have crypto.
306
*/
307
if
((dev ==
MV88F5181_DEV_ID
&& rev >=
MV88F5181L_REV_A0
) ||
308
dev ==
MV88F5182_DEV_ID
|| dev ==
MV88F6183_DEV_ID
)
309
orion5x_crypto_init();
310
311
/*
312
* Register watchdog driver
313
*/
314
orion5x_wdt_init
();
315
}
316
317
void
orion5x_restart
(
char
mode
,
const
char
*
cmd
)
318
{
319
/*
320
* Enable and issue soft reset
321
*/
322
orion5x_setbits
(
RSTOUTn_MASK
, (1 << 2));
323
orion5x_setbits
(
CPU_SOFT_RESET
, 1);
324
mdelay
(200);
325
orion5x_clrbits
(
CPU_SOFT_RESET
, 1);
326
}
327
328
/*
329
* Many orion-based systems have buggy bootloader implementations.
330
* This is a common fixup for bogus memory tags.
331
*/
332
void
__init
tag_fixup_mem32
(
struct
tag
*
t
,
char
**
from
,
333
struct
meminfo
*
meminfo
)
334
{
335
for
(; t->
hdr
.size; t =
tag_next
(t))
336
if
(t->
hdr
.tag ==
ATAG_MEM
&&
337
(!t->
u
.
mem
.size || t->
u
.
mem
.size & ~
PAGE_MASK
||
338
t->
u
.
mem
.start & ~
PAGE_MASK
)) {
339
printk
(
KERN_WARNING
340
"Clearing invalid memory bank %dKB@0x%08x\n"
,
341
t->
u
.
mem
.size / 1024, t->
u
.
mem
.start);
342
t->
hdr
.tag = 0;
343
}
344
}
Generated on Thu Jan 10 2013 12:54:29 for Linux Kernel by
1.8.2