Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1/*
  2 * linux/arch/arm/mach-omap2/board-apollon.c
  3 *
  4 * Copyright (C) 2005,2006 Samsung Electronics
  5 * Author: Kyungmin Park <kyungmin.park@samsung.com>
  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 "common.h"
 41#include <plat/gpmc.h>
 42
 43#include <video/omapdss.h>
 44#include <video/omap-panel-generic-dpi.h>
 45
 46#include "mux.h"
 47#include "control.h"
 48
 49/* LED & Switch macros */
 50#define LED0_GPIO13		13
 51#define LED1_GPIO14		14
 52#define LED2_GPIO15		15
 53#define SW_ENTER_GPIO16		16
 54#define SW_UP_GPIO17		17
 55#define SW_DOWN_GPIO58		58
 56
 57#define APOLLON_FLASH_CS	0
 58#define APOLLON_ETH_CS		1
 59#define APOLLON_ETHR_GPIO_IRQ	74
 60
 61static struct mtd_partition apollon_partitions[] = {
 62	{
 63		.name		= "X-Loader + U-Boot",
 64		.offset		= 0,
 65		.size		= SZ_128K,
 66		.mask_flags	= MTD_WRITEABLE,
 67	},
 68	{
 69		.name		= "params",
 70		.offset		= MTDPART_OFS_APPEND,
 71		.size		= SZ_128K,
 72	},
 73	{
 74		.name		= "kernel",
 75		.offset		= MTDPART_OFS_APPEND,
 76		.size		= SZ_2M,
 77	},
 78	{
 79		.name		= "rootfs",
 80		.offset		= MTDPART_OFS_APPEND,
 81		.size		= SZ_16M,
 82	},
 83	{
 84		.name		= "filesystem00",
 85		.offset		= MTDPART_OFS_APPEND,
 86		.size		= SZ_32M,
 87	},
 88	{
 89		.name		= "filesystem01",
 90		.offset		= MTDPART_OFS_APPEND,
 91		.size		= MTDPART_SIZ_FULL,
 92	},
 93};
 94
 95static struct onenand_platform_data apollon_flash_data = {
 96	.parts		= apollon_partitions,
 97	.nr_parts	= ARRAY_SIZE(apollon_partitions),
 98};
 99
100static struct resource apollon_flash_resource[] = {
101	[0] = {
102		.flags		= IORESOURCE_MEM,
103	},
104};
105
106static struct platform_device apollon_onenand_device = {
107	.name		= "onenand-flash",
108	.id		= -1,
109	.dev		= {
110		.platform_data	= &apollon_flash_data,
111	},
112	.num_resources	= ARRAY_SIZE(apollon_flash_resource),
113	.resource	= apollon_flash_resource,
114};
115
116static void __init apollon_flash_init(void)
117{
118	unsigned long base;
119
120	if (gpmc_cs_request(APOLLON_FLASH_CS, SZ_128K, &base) < 0) {
121		printk(KERN_ERR "Cannot request OneNAND GPMC CS\n");
122		return;
123	}
124	apollon_flash_resource[0].start = base;
125	apollon_flash_resource[0].end   = base + SZ_128K - 1;
126}
127
128static struct smc91x_platdata appolon_smc91x_info = {
129	.flags	= SMC91X_USE_16BIT | SMC91X_NOWAIT,
130	.leda	= RPC_LED_100_10,
131	.ledb	= RPC_LED_TX_RX,
132};
133
134static struct resource apollon_smc91x_resources[] = {
135	[0] = {
136		.flags  = IORESOURCE_MEM,
137	},
138	[1] = {
139		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
140	},
141};
142
143static struct platform_device apollon_smc91x_device = {
144	.name		= "smc91x",
145	.id		= -1,
146	.dev	= {
147		.platform_data	= &appolon_smc91x_info,
148	},
149	.num_resources	= ARRAY_SIZE(apollon_smc91x_resources),
150	.resource	= apollon_smc91x_resources,
151};
152
153static struct omap_led_config apollon_led_config[] = {
154	{
155		.cdev	= {
156			.name	= "apollon:led0",
157		},
158		.gpio	= LED0_GPIO13,
159	},
160	{
161		.cdev	= {
162			.name	= "apollon:led1",
163		},
164		.gpio	= LED1_GPIO14,
165	},
166	{
167		.cdev	= {
168			.name	= "apollon:led2",
169		},
170		.gpio	= LED2_GPIO15,
171	},
172};
173
174static struct omap_led_platform_data apollon_led_data = {
175	.nr_leds	= ARRAY_SIZE(apollon_led_config),
176	.leds		= apollon_led_config,
177};
178
179static struct platform_device apollon_led_device = {
180	.name		= "omap-led",
181	.id		= -1,
182	.dev		= {
183		.platform_data	= &apollon_led_data,
184	},
185};
186
187static struct platform_device *apollon_devices[] __initdata = {
188	&apollon_onenand_device,
189	&apollon_smc91x_device,
190	&apollon_led_device,
191};
192
193static inline void __init apollon_init_smc91x(void)
194{
195	unsigned long base;
196
197	unsigned int rate;
198	struct clk *gpmc_fck;
199	int eth_cs;
200	int err;
201
202	gpmc_fck = clk_get(NULL, "gpmc_fck");	/* Always on ENABLE_ON_INIT */
203	if (IS_ERR(gpmc_fck)) {
204		WARN_ON(1);
205		return;
206	}
207
208	clk_enable(gpmc_fck);
209	rate = clk_get_rate(gpmc_fck);
210
211	eth_cs = APOLLON_ETH_CS;
212
213	/* Make sure CS1 timings are correct */
214	gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG1, 0x00011200);
215
216	if (rate >= 160000000) {
217		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f01);
218		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080803);
219		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1c0b1c0a);
220		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
221		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
222	} else if (rate >= 130000000) {
223		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
224		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
225		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
226		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x041f1F1F);
227		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000004C4);
228	} else {/* rate = 100000000 */
229		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG2, 0x001f1f00);
230		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG3, 0x00080802);
231		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG4, 0x1C091C09);
232		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG5, 0x031A1F1F);
233		gpmc_cs_write_reg(eth_cs, GPMC_CS_CONFIG6, 0x000003C2);
234	}
235
236	if (gpmc_cs_request(APOLLON_ETH_CS, SZ_16M, &base) < 0) {
237		printk(KERN_ERR "Failed to request GPMC CS for smc91x\n");
238		goto out;
239	}
240	apollon_smc91x_resources[0].start = base + 0x300;
241	apollon_smc91x_resources[0].end   = base + 0x30f;
242	udelay(100);
243
244	omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
245	err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
246	if (err) {
247		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
248			APOLLON_ETHR_GPIO_IRQ);
249		gpmc_cs_free(APOLLON_ETH_CS);
250	}
251out:
252	clk_disable(gpmc_fck);
253	clk_put(gpmc_fck);
254}
255
256static struct omap_usb_config apollon_usb_config __initdata = {
257	.register_dev	= 1,
258	.hmc_mode	= 0x14,	/* 0:dev 1:host1 2:disable */
259
260	.pins[0]	= 6,
261};
262
263static struct panel_generic_dpi_data apollon_panel_data = {
264	.name			= "apollon",
265};
266
267static struct omap_dss_device apollon_lcd_device = {
268	.name			= "lcd",
269	.driver_name		= "generic_dpi_panel",
270	.type			= OMAP_DISPLAY_TYPE_DPI,
271	.phy.dpi.data_lines	= 18,
272	.data			= &apollon_panel_data,
273};
274
275static struct omap_dss_device *apollon_dss_devices[] = {
276	&apollon_lcd_device,
277};
278
279static struct omap_dss_board_info apollon_dss_data = {
280	.num_devices	= ARRAY_SIZE(apollon_dss_devices),
281	.devices	= apollon_dss_devices,
282	.default_device	= &apollon_lcd_device,
283};
284
285static struct gpio apollon_gpio_leds[] __initdata = {
286	{ LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
287	{ LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6  */
288	{ LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4  */
289};
290
291static void __init apollon_led_init(void)
292{
293	omap_mux_init_signal("vlynq_clk.gpio_13", 0);
294	omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
295	omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
296
297	gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
298}
299
300static void __init apollon_usb_init(void)
301{
302	/* USB device */
303	/* DEVICE_SUSPEND */
304	omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
305	gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
306	omap2_usbfs_init(&apollon_usb_config);
307}
308
309#ifdef CONFIG_OMAP_MUX
310static struct omap_board_mux board_mux[] __initdata = {
311	{ .reg_offset = OMAP_MUX_TERMINATOR },
312};
313#endif
314
315static void __init omap_apollon_init(void)
316{
317	u32 v;
318
319	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
320
321	apollon_init_smc91x();
322	apollon_led_init();
323	apollon_flash_init();
324	apollon_usb_init();
325
326	/* REVISIT: where's the correct place */
327	omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
328
329	/* LCD PWR_EN */
330	omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
331
332	/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
333	v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
334	v |= (1 << 24);
335	omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
336
337	/*
338 	 * Make sure the serial ports are muxed on at this point.
339	 * You have to mux them off in device drivers later on
340	 * if not needed.
341	 */
342	apollon_smc91x_resources[1].start = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ);
343	apollon_smc91x_resources[1].end = gpio_to_irq(APOLLON_ETHR_GPIO_IRQ);
344	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
345	omap_serial_init();
346	omap_sdrc_init(NULL, NULL);
347	omap_display_init(&apollon_dss_data);
348}
349
350MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
351	/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
352	.atag_offset	= 0x100,
353	.reserve	= omap_reserve,
354	.map_io		= omap242x_map_io,
355	.init_early	= omap2420_init_early,
356	.init_irq	= omap2_init_irq,
357	.handle_irq	= omap2_intc_handle_irq,
358	.init_machine	= omap_apollon_init,
359	.init_late	= omap2420_init_late,
360	.timer		= &omap2_timer,
361	.restart	= omap_prcm_restart,
362MACHINE_END