Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-omap2/board-apollon.c
10817 views
1
/*
2
* linux/arch/arm/mach-omap2/board-apollon.c
3
*
4
* Copyright (C) 2005,2006 Samsung Electronics
5
* Author: Kyungmin Park <[email protected]>
6
*
7
* Modified from mach-omap/omap2/board-h4.c
8
*
9
* Code for apollon OMAP2 board. Should work on many OMAP2 systems where
10
* the bootloader passes the board-specific data to the kernel.
11
* Do not put any board specific code to this file; create a new machine
12
* type if you need custom low-level initializations.
13
*
14
* This program is free software; you can redistribute it and/or modify
15
* it under the terms of the GNU General Public License version 2 as
16
* published by the Free Software Foundation.
17
*/
18
19
#include <linux/kernel.h>
20
#include <linux/init.h>
21
#include <linux/platform_device.h>
22
#include <linux/mtd/mtd.h>
23
#include <linux/mtd/partitions.h>
24
#include <linux/mtd/onenand.h>
25
#include <linux/delay.h>
26
#include <linux/leds.h>
27
#include <linux/err.h>
28
#include <linux/clk.h>
29
#include <linux/smc91x.h>
30
#include <linux/gpio.h>
31
32
#include <mach/hardware.h>
33
#include <asm/mach-types.h>
34
#include <asm/mach/arch.h>
35
#include <asm/mach/flash.h>
36
37
#include <plat/led.h>
38
#include <plat/usb.h>
39
#include <plat/board.h>
40
#include <plat/common.h>
41
#include <plat/gpmc.h>
42
43
#include "mux.h"
44
#include "control.h"
45
46
/* LED & Switch macros */
47
#define LED0_GPIO13 13
48
#define LED1_GPIO14 14
49
#define LED2_GPIO15 15
50
#define SW_ENTER_GPIO16 16
51
#define SW_UP_GPIO17 17
52
#define SW_DOWN_GPIO58 58
53
54
#define APOLLON_FLASH_CS 0
55
#define APOLLON_ETH_CS 1
56
#define APOLLON_ETHR_GPIO_IRQ 74
57
58
static struct mtd_partition apollon_partitions[] = {
59
{
60
.name = "X-Loader + U-Boot",
61
.offset = 0,
62
.size = SZ_128K,
63
.mask_flags = MTD_WRITEABLE,
64
},
65
{
66
.name = "params",
67
.offset = MTDPART_OFS_APPEND,
68
.size = SZ_128K,
69
},
70
{
71
.name = "kernel",
72
.offset = MTDPART_OFS_APPEND,
73
.size = SZ_2M,
74
},
75
{
76
.name = "rootfs",
77
.offset = MTDPART_OFS_APPEND,
78
.size = SZ_16M,
79
},
80
{
81
.name = "filesystem00",
82
.offset = MTDPART_OFS_APPEND,
83
.size = SZ_32M,
84
},
85
{
86
.name = "filesystem01",
87
.offset = MTDPART_OFS_APPEND,
88
.size = MTDPART_SIZ_FULL,
89
},
90
};
91
92
static struct onenand_platform_data apollon_flash_data = {
93
.parts = apollon_partitions,
94
.nr_parts = ARRAY_SIZE(apollon_partitions),
95
};
96
97
static struct resource apollon_flash_resource[] = {
98
[0] = {
99
.flags = IORESOURCE_MEM,
100
},
101
};
102
103
static struct platform_device apollon_onenand_device = {
104
.name = "onenand-flash",
105
.id = -1,
106
.dev = {
107
.platform_data = &apollon_flash_data,
108
},
109
.num_resources = ARRAY_SIZE(apollon_flash_resource),
110
.resource = apollon_flash_resource,
111
};
112
113
static void __init apollon_flash_init(void)
114
{
115
unsigned long base;
116
117
if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
118
printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
119
return;
120
}
121
apollon_flash_resource[0].start = base;
122
apollon_flash_resource[0].end = base + SZ_128K - 1;
123
}
124
125
static struct smc91x_platdata appolon_smc91x_info = {
126
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
127
.leda = RPC_LED_100_10,
128
.ledb = RPC_LED_TX_RX,
129
};
130
131
static struct resource apollon_smc91x_resources[] = {
132
[0] = {
133
.flags = IORESOURCE_MEM,
134
},
135
[1] = {
136
.start = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
137
.end = OMAP_GPIO_IRQ(APOLLON_ETHR_GPIO_IRQ),
138
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
139
},
140
};
141
142
static struct platform_device apollon_smc91x_device = {
143
.name = "smc91x",
144
.id = -1,
145
.dev = {
146
.platform_data = &appolon_smc91x_info,
147
},
148
.num_resources = ARRAY_SIZE(apollon_smc91x_resources),
149
.resource = apollon_smc91x_resources,
150
};
151
152
static struct platform_device apollon_lcd_device = {
153
.name = "apollon_lcd",
154
.id = -1,
155
};
156
157
static struct omap_led_config apollon_led_config[] = {
158
{
159
.cdev = {
160
.name = "apollon:led0",
161
},
162
.gpio = LED0_GPIO13,
163
},
164
{
165
.cdev = {
166
.name = "apollon:led1",
167
},
168
.gpio = LED1_GPIO14,
169
},
170
{
171
.cdev = {
172
.name = "apollon:led2",
173
},
174
.gpio = LED2_GPIO15,
175
},
176
};
177
178
static struct omap_led_platform_data apollon_led_data = {
179
.nr_leds = ARRAY_SIZE(apollon_led_config),
180
.leds = apollon_led_config,
181
};
182
183
static struct platform_device apollon_led_device = {
184
.name = "omap-led",
185
.id = -1,
186
.dev = {
187
.platform_data = &apollon_led_data,
188
},
189
};
190
191
static struct platform_device *apollon_devices[] __initdata = {
192
&apollon_onenand_device,
193
&apollon_smc91x_device,
194
&apollon_lcd_device,
195
&apollon_led_device,
196
};
197
198
static inline void __init apollon_init_smc91x(void)
199
{
200
unsigned long base;
201
202
unsigned int rate;
203
struct clk *gpmc_fck;
204
int eth_cs;
205
int err;
206
207
gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
208
if (IS_ERR(gpmc_fck)) {
209
WARN_ON(1);
210
return;
211
}
212
213
clk_enable(gpmc_fck);
214
rate = clk_get_rate(gpmc_fck);
215
216
eth_cs = APOLLON_ETH_CS;
217
218
/* Make sure CS1 timings are correct */
219
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
220
221
if (rate >= 160000000) {
222
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
223
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
224
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
225
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
226
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
227
} else if (rate >= 130000000) {
228
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
229
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
230
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
231
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
232
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
233
} else {/* rate = 100000000 */
234
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
235
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
236
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
237
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
238
gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
239
}
240
241
if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
242
printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
243
goto out;
244
}
245
apollon_smc91x_resources[0].start = base + 0x300;
246
apollon_smc91x_resources[0].end = base + 0x30f;
247
udelay(100);
248
249
omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
250
err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
251
if (err) {
252
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
253
APOLLON_ETHR_GPIO_IRQ);
254
gpmc_cs_free(APOLLON_ETH_CS);
255
}
256
out:
257
clk_disable(gpmc_fck);
258
clk_put(gpmc_fck);
259
}
260
261
static struct omap_usb_config apollon_usb_config __initdata = {
262
.register_dev = 1,
263
.hmc_mode = 0x14, /* 0:dev 1:host1 2:disable */
264
265
.pins[0] = 6,
266
};
267
268
static struct omap_lcd_config apollon_lcd_config __initdata = {
269
.ctrl_name = "internal",
270
};
271
272
static struct omap_board_config_kernel apollon_config[] __initdata = {
273
{ OMAP_TAG_LCD, &apollon_lcd_config },
274
};
275
276
static void __init omap_apollon_init_early(void)
277
{
278
omap2_init_common_infrastructure();
279
omap2_init_common_devices(NULL, NULL);
280
}
281
282
static struct gpio apollon_gpio_leds[] __initdata = {
283
{ LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
284
{ LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */
285
{ LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4 */
286
};
287
288
static void __init apollon_led_init(void)
289
{
290
omap_mux_init_signal("vlynq_clk.gpio_13", 0);
291
omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
292
omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
293
294
gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
295
}
296
297
static void __init apollon_usb_init(void)
298
{
299
/* USB device */
300
/* DEVICE_SUSPEND */
301
omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
302
gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
303
omap2_usbfs_init(&apollon_usb_config);
304
}
305
306
#ifdef CONFIG_OMAP_MUX
307
static struct omap_board_mux board_mux[] __initdata = {
308
{ .reg_offset = OMAP_MUX_TERMINATOR },
309
};
310
#endif
311
312
static void __init omap_apollon_init(void)
313
{
314
u32 v;
315
316
omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
317
omap_board_config = apollon_config;
318
omap_board_config_size = ARRAY_SIZE(apollon_config);
319
320
apollon_init_smc91x();
321
apollon_led_init();
322
apollon_flash_init();
323
apollon_usb_init();
324
325
/* REVISIT: where's the correct place */
326
omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
327
328
/* LCD PWR_EN */
329
omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
330
331
/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
332
v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
333
v |= (1 << 24);
334
omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
335
336
/*
337
* Make sure the serial ports are muxed on at this point.
338
* You have to mux them off in device drivers later on
339
* if not needed.
340
*/
341
platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
342
omap_serial_init();
343
}
344
345
static void __init omap_apollon_map_io(void)
346
{
347
omap2_set_globals_242x();
348
omap242x_map_common_io();
349
}
350
351
MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
352
/* Maintainer: Kyungmin Park <[email protected]> */
353
.boot_params = 0x80000100,
354
.reserve = omap_reserve,
355
.map_io = omap_apollon_map_io,
356
.init_early = omap_apollon_init_early,
357
.init_irq = omap_init_irq,
358
.init_machine = omap_apollon_init,
359
.timer = &omap_timer,
360
MACHINE_END
361
362