aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-harmony.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-harmony.c')
-rw-r--r--arch/arm/mach-tegra/board-harmony.c507
1 files changed, 507 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 00000000000..86e9615f785
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,507 @@
1/*
2 * arch/arm/mach-tegra/board-harmony.c
3 *
4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (C) 2011 NVIDIA, Inc.
6 *
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21#include <linux/serial_8250.h>
22#include <linux/clk.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
25#include <linux/dma-mapping.h>
26#include <linux/pda_power.h>
27#include <linux/input.h>
28#include <linux/io.h>
29#include <linux/gpio.h>
30#include <linux/gpio_keys.h>
31#include <linux/i2c.h>
32#include <linux/i2c-tegra.h>
33#include <linux/memblock.h>
34#include <linux/delay.h>
35
36#include <sound/wm8903.h>
37
38#include <asm/mach-types.h>
39#include <asm/mach/arch.h>
40#include <asm/mach/time.h>
41#include <asm/setup.h>
42
43#include <mach/tegra_wm8903_pdata.h>
44#include <mach/iomap.h>
45#include <mach/irqs.h>
46#include <mach/sdhci.h>
47#include <mach/nand.h>
48#include <mach/clk.h>
49#include <mach/usb_phy.h>
50
51#include "clock.h"
52#include "board.h"
53#include "board-harmony.h"
54#include "clock.h"
55#include "devices.h"
56#include "gpio-names.h"
57#include "pm.h"
58
59/* NVidia bootloader tags */
60#define ATAG_NVIDIA 0x41000801
61
62#define ATAG_NVIDIA_RM 0x1
63#define ATAG_NVIDIA_DISPLAY 0x2
64#define ATAG_NVIDIA_FRAMEBUFFER 0x3
65#define ATAG_NVIDIA_CHIPSHMOO 0x4
66#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5
67#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000
68#define ATAG_NVIDIA_PRESERVED_MEM_N 2
69#define ATAG_NVIDIA_FORCE_32 0x7fffffff
70
71struct tag_tegra {
72 __u32 bootarg_key;
73 __u32 bootarg_len;
74 char bootarg[1];
75};
76
77static int __init parse_tag_nvidia(const struct tag *tag)
78{
79
80 return 0;
81}
82__tagtable(ATAG_NVIDIA, parse_tag_nvidia);
83
84static struct tegra_utmip_config utmi_phy_config = {
85 .hssync_start_delay = 0,
86 .idle_wait_delay = 17,
87 .elastic_limit = 16,
88 .term_range_adj = 6,
89 .xcvr_setup = 9,
90 .xcvr_lsfslew = 2,
91 .xcvr_lsrslew = 2,
92};
93
94static struct tegra_ehci_platform_data tegra_ehci_pdata = {
95 .phy_config = &utmi_phy_config,
96 .operating_mode = TEGRA_USB_HOST,
97 .power_down_on_bus_suspend = 1,
98};
99
100static struct tegra_nand_chip_parms nand_chip_parms[] = {
101 /* Samsung K5E2G1GACM */
102 [0] = {
103 .vendor_id = 0xEC,
104 .device_id = 0xAA,
105 .read_id_fourth_byte = 0x15,
106 .capacity = 256,
107 .timing = {
108 .trp = 21,
109 .trh = 15,
110 .twp = 21,
111 .twh = 15,
112 .tcs = 31,
113 .twhr = 60,
114 .tcr_tar_trr = 20,
115 .twb = 100,
116 .trp_resp = 30,
117 .tadl = 100,
118 },
119 },
120 /* Hynix H5PS1GB3EFR */
121 [1] = {
122 .vendor_id = 0xAD,
123 .device_id = 0xDC,
124 .read_id_fourth_byte = 0x95,
125 .capacity = 512,
126 .timing = {
127 .trp = 12,
128 .trh = 10,
129 .twp = 12,
130 .twh = 10,
131 .tcs = 20,
132 .twhr = 80,
133 .tcr_tar_trr = 20,
134 .twb = 100,
135 .trp_resp = 20,
136 .tadl = 70,
137 },
138 },
139};
140
141struct tegra_nand_platform harmony_nand_data = {
142 .max_chips = 8,
143 .chip_parms = nand_chip_parms,
144 .nr_chip_parms = ARRAY_SIZE(nand_chip_parms),
145 .wp_gpio = TEGRA_GPIO_PC7,
146};
147
148static struct resource resources_nand[] = {
149 [0] = {
150 .start = INT_NANDFLASH,
151 .end = INT_NANDFLASH,
152 .flags = IORESOURCE_IRQ,
153 },
154};
155
156struct platform_device tegra_nand_device = {
157 .name = "tegra_nand",
158 .id = -1,
159 .num_resources = ARRAY_SIZE(resources_nand),
160 .resource = resources_nand,
161 .dev = {
162 .platform_data = &harmony_nand_data,
163 },
164};
165
166static struct gpio_keys_button harmony_gpio_keys_buttons[] = {
167 {
168 .code = KEY_POWER,
169 .gpio = TEGRA_GPIO_POWERKEY,
170 .active_low = 1,
171 .desc = "Power",
172 .type = EV_KEY,
173 .wakeup = 1,
174 },
175};
176
177static struct gpio_keys_platform_data harmony_gpio_keys = {
178 .buttons = harmony_gpio_keys_buttons,
179 .nbuttons = ARRAY_SIZE(harmony_gpio_keys_buttons),
180};
181
182static struct platform_device harmony_gpio_keys_device = {
183 .name = "gpio-keys",
184 .id = -1,
185 .dev = {
186 .platform_data = &harmony_gpio_keys,
187 }
188};
189
190static void harmony_keys_init(void)
191{
192 int i;
193
194 for (i = 0; i < ARRAY_SIZE(harmony_gpio_keys_buttons); i++)
195 tegra_gpio_enable(harmony_gpio_keys_buttons[i].gpio);
196}
197
198static struct tegra_wm8903_platform_data harmony_audio_pdata = {
199 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
200 .gpio_hp_det = TEGRA_GPIO_HP_DET,
201 .gpio_hp_mute = -1,
202 .gpio_int_mic_en = TEGRA_GPIO_INT_MIC_EN,
203 .gpio_ext_mic_en = TEGRA_GPIO_EXT_MIC_EN,
204};
205
206static struct platform_device harmony_audio_device = {
207 .name = "tegra-snd-wm8903",
208 .id = 0,
209 .dev = {
210 .platform_data = &harmony_audio_pdata,
211 },
212};
213
214static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
215 .adapter_nr = 0,
216 .bus_count = 1,
217 .bus_clk_rate = { 400000, 0 },
218};
219
220static const struct tegra_pingroup_config i2c2_ddc = {
221 .pingroup = TEGRA_PINGROUP_DDC,
222 .func = TEGRA_MUX_I2C2,
223};
224
225static const struct tegra_pingroup_config i2c2_gen2 = {
226 .pingroup = TEGRA_PINGROUP_PTA,
227 .func = TEGRA_MUX_I2C2,
228};
229
230static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
231 .adapter_nr = 1,
232 .bus_count = 2,
233 .bus_clk_rate = { 100000, 100000 },
234 .bus_mux = { &i2c2_ddc, &i2c2_gen2 },
235 .bus_mux_len = { 1, 1 },
236};
237
238static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
239 .adapter_nr = 3,
240 .bus_count = 1,
241 .bus_clk_rate = { 400000, 0 },
242};
243
244static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
245 .adapter_nr = 4,
246 .bus_count = 1,
247 .bus_clk_rate = { 400000, 0 },
248 .is_dvc = true,
249};
250
251static struct wm8903_platform_data harmony_wm8903_pdata = {
252 .irq_active_low = 0,
253 .micdet_cfg = 0,
254 .micdet_delay = 100,
255 .gpio_base = HARMONY_GPIO_WM8903(0),
256 .gpio_cfg = {
257 WM8903_GPIO_NO_CONFIG,
258 WM8903_GPIO_NO_CONFIG,
259 0,
260 WM8903_GPIO_NO_CONFIG,
261 WM8903_GPIO_NO_CONFIG,
262 },
263};
264
265static struct i2c_board_info __initdata wm8903_board_info = {
266 I2C_BOARD_INFO("wm8903", 0x1a),
267 .platform_data = &harmony_wm8903_pdata,
268 .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
269};
270
271static void __init harmony_i2c_init(void)
272{
273 tegra_i2c_device1.dev.platform_data = &harmony_i2c1_platform_data;
274 tegra_i2c_device2.dev.platform_data = &harmony_i2c2_platform_data;
275 tegra_i2c_device3.dev.platform_data = &harmony_i2c3_platform_data;
276 tegra_i2c_device4.dev.platform_data = &harmony_dvc_platform_data;
277
278 platform_device_register(&tegra_i2c_device1);
279 platform_device_register(&tegra_i2c_device2);
280 platform_device_register(&tegra_i2c_device3);
281 platform_device_register(&tegra_i2c_device4);
282
283 i2c_register_board_info(0, &wm8903_board_info, 1);
284}
285
286/* OTG gadget device */
287/*static u64 tegra_otg_dmamask = DMA_BIT_MASK(32);
288
289
290static struct resource tegra_otg_resources[] = {
291 [0] = {
292 .start = TEGRA_USB_BASE,
293 .end = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
294 .flags = IORESOURCE_MEM,
295 },
296 [1] = {
297 .start = INT_USB,
298 .end = INT_USB,
299 .flags = IORESOURCE_IRQ,
300 },
301};
302
303static struct fsl_usb2_platform_data tegra_otg_pdata = {
304 .operating_mode = FSL_USB2_DR_DEVICE,
305 .phy_mode = FSL_USB2_PHY_UTMI,
306};
307
308static struct platform_device tegra_otg = {
309 .name = "fsl-tegra-udc",
310 .id = -1,
311 .dev = {
312 .dma_mask = &tegra_otg_dmamask,
313 .coherent_dma_mask = 0xffffffff,
314 .platform_data = &tegra_otg_pdata,
315 },
316 .resource = tegra_otg_resources,
317 .num_resources = ARRAY_SIZE(tegra_otg_resources),
318};*/
319
320/* PDA power */
321static struct pda_power_pdata pda_power_pdata = {
322};
323
324static struct platform_device pda_power_device = {
325 .name = "pda_power",
326 .id = -1,
327 .dev = {
328 .platform_data = &pda_power_pdata,
329 },
330};
331
332static void harmony_debug_uart_init(void)
333{
334 struct clk *c;
335
336 debug_uart_clk = clk_get_sys("serial8250.0", "uartd");
337 debug_uart_port_base = ((struct plat_serial8250_port *)(
338 debug_uartd_device.dev.platform_data))->mapbase;
339
340 if (!IS_ERR_OR_NULL(debug_uart_clk)) {
341 pr_info("The debug console clock name is %s\n",
342 debug_uart_clk->name);
343 c = tegra_get_clock_by_name("pll_p");
344 if (IS_ERR_OR_NULL(c))
345 pr_err("Not getting the parent clock pll_p\n");
346 else
347 clk_set_parent(debug_uart_clk, c);
348
349 clk_enable(debug_uart_clk);
350 clk_set_rate(debug_uart_clk, clk_get_rate(c));
351 } else {
352 pr_err("Not getting the clock %s for debug console\n",
353 debug_uart_clk->name);
354 }
355 return;
356}
357
358static struct platform_device *harmony_devices[] __initdata = {
359 &debug_uartd_device,
360 &tegra_sdhci_device1,
361 &tegra_sdhci_device2,
362 &tegra_sdhci_device4,
363 &tegra_i2s_device1,
364 &tegra_i2s_device2,
365 &tegra_spdif_device,
366 &tegra_das_device,
367 &spdif_dit_device,
368 &bluetooth_dit_device,
369 &tegra_pcm_device,
370 &harmony_audio_device,
371 &tegra_pmu_device,
372 &tegra_nand_device,
373 &tegra_udc_device,
374 &harmony_gpio_keys_device,
375 &pda_power_device,
376 &tegra_ehci3_device,
377 &tegra_spi_device1,
378 &tegra_spi_device2,
379 &tegra_spi_device3,
380 &tegra_spi_device4,
381 &tegra_gart_device,
382 &tegra_avp_device,
383};
384
385static void __init tegra_harmony_fixup(struct machine_desc *desc,
386 struct tag *tags, char **cmdline, struct meminfo *mi)
387{
388 mi->nr_banks = 2;
389 mi->bank[0].start = PHYS_OFFSET;
390 mi->bank[0].size = 448 * SZ_1M;
391 mi->bank[1].start = SZ_512M;
392 mi->bank[1].size = SZ_512M;
393}
394
395static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
396 /* name parent rate enabled */
397 { "uartd", "pll_p", 216000000, true },
398 { "i2s1", "pll_a_out0", 0, false},
399 { "spdif_out", "pll_a_out0", 0, false},
400 { "sdmmc1", "clk_m", 48000000, true },
401 { "sdmmc2", "clk_m", 48000000, true },
402 { "sdmmc4", "clk_m", 48000000, true },
403 { "ndflash", "pll_p", 108000000, true},
404 { "pwm", "clk_32k", 32768, false},
405 { NULL, NULL, 0, 0},
406};
407
408
409static struct tegra_sdhci_platform_data sdhci_pdata1 = {
410 .cd_gpio = -1,
411 .wp_gpio = -1,
412 .power_gpio = -1,
413};
414
415static struct tegra_sdhci_platform_data sdhci_pdata2 = {
416 .cd_gpio = TEGRA_GPIO_SD2_CD,
417 .wp_gpio = TEGRA_GPIO_SD2_WP,
418 .power_gpio = TEGRA_GPIO_SD2_POWER,
419};
420
421static struct tegra_sdhci_platform_data sdhci_pdata4 = {
422 .cd_gpio = TEGRA_GPIO_SD4_CD,
423 .wp_gpio = TEGRA_GPIO_SD4_WP,
424 .power_gpio = TEGRA_GPIO_SD4_POWER,
425 .is_8bit = 1,
426};
427
428static int __init harmony_wifi_init(void)
429{
430 int gpio_pwr, gpio_rst;
431
432 if (!machine_is_harmony())
433 return 0;
434
435 /* WLAN - Power up (low) and Reset (low) */
436 gpio_pwr = gpio_request(TEGRA_GPIO_WLAN_PWR_LOW, "wlan_pwr");
437 gpio_rst = gpio_request(TEGRA_GPIO_WLAN_RST_LOW, "wlan_rst");
438 if (gpio_pwr < 0 || gpio_rst < 0)
439 pr_warning("Unable to get gpio for WLAN Power and Reset\n");
440 else {
441
442 tegra_gpio_enable(TEGRA_GPIO_WLAN_PWR_LOW);
443 tegra_gpio_enable(TEGRA_GPIO_WLAN_RST_LOW);
444 /* toggle in this order as per spec */
445 gpio_direction_output(TEGRA_GPIO_WLAN_PWR_LOW, 0);
446 gpio_direction_output(TEGRA_GPIO_WLAN_RST_LOW, 0);
447 udelay(5);
448 gpio_direction_output(TEGRA_GPIO_WLAN_PWR_LOW, 1);
449 gpio_direction_output(TEGRA_GPIO_WLAN_RST_LOW, 1);
450 }
451
452 return 0;
453}
454
455/*
456 * subsys_initcall_sync is good synch point to call harmony_wifi_init
457 * This makes sure that the required regulators (LDO3
458 * supply of external PMU and 1.2V regulator) are properly enabled,
459 * and mmc driver has not yet probed for a device on SDIO bus.
460 */
461subsys_initcall_sync(harmony_wifi_init);
462
463static void __init tegra_harmony_init(void)
464{
465 tegra_clk_init_from_table(harmony_clk_init_table);
466
467 harmony_pinmux_init();
468
469 harmony_keys_init();
470
471 harmony_debug_uart_init();
472
473 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
474 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
475 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
476
477 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata;
478
479 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
480 harmony_i2c_init();
481 harmony_regulator_init();
482 harmony_suspend_init();
483 harmony_panel_init();
484#ifdef CONFIG_KEYBOARD_TEGRA
485 harmony_kbc_init();
486#endif
487 harmony_pcie_init();
488}
489
490void __init tegra_harmony_reserve(void)
491{
492 if (memblock_reserve(0x0, 4096) < 0)
493 pr_warn("Cannot reserve first 4K of memory for safety\n");
494
495 tegra_reserve(SZ_128M, SZ_8M, SZ_16M);
496}
497
498MACHINE_START(HARMONY, "harmony")
499 .boot_params = 0x00000100,
500 .fixup = tegra_harmony_fixup,
501 .map_io = tegra_map_common_io,
502 .reserve = tegra_harmony_reserve,
503 .init_early = tegra_init_early,
504 .init_irq = tegra_init_irq,
505 .timer = &tegra_timer,
506 .init_machine = tegra_harmony_init,
507MACHINE_END