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.c346
1 files changed, 321 insertions, 25 deletions
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 30e18bc6064..86e9615f785 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -20,12 +20,18 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/serial_8250.h> 21#include <linux/serial_8250.h>
22#include <linux/clk.h> 22#include <linux/clk.h>
23#include <linux/mtd/mtd.h>
24#include <linux/mtd/partitions.h>
23#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
24#include <linux/pda_power.h> 26#include <linux/pda_power.h>
27#include <linux/input.h>
25#include <linux/io.h> 28#include <linux/io.h>
26#include <linux/gpio.h> 29#include <linux/gpio.h>
30#include <linux/gpio_keys.h>
27#include <linux/i2c.h> 31#include <linux/i2c.h>
28#include <linux/i2c-tegra.h> 32#include <linux/i2c-tegra.h>
33#include <linux/memblock.h>
34#include <linux/delay.h>
29 35
30#include <sound/wm8903.h> 36#include <sound/wm8903.h>
31 37
@@ -38,35 +44,157 @@
38#include <mach/iomap.h> 44#include <mach/iomap.h>
39#include <mach/irqs.h> 45#include <mach/irqs.h>
40#include <mach/sdhci.h> 46#include <mach/sdhci.h>
47#include <mach/nand.h>
48#include <mach/clk.h>
49#include <mach/usb_phy.h>
41 50
51#include "clock.h"
42#include "board.h" 52#include "board.h"
43#include "board-harmony.h" 53#include "board-harmony.h"
44#include "clock.h" 54#include "clock.h"
45#include "devices.h" 55#include "devices.h"
46#include "gpio-names.h" 56#include "gpio-names.h"
57#include "pm.h"
47 58
48static struct plat_serial8250_port debug_uart_platform_data[] = { 59/* NVidia bootloader tags */
49 { 60#define ATAG_NVIDIA 0x41000801
50 .membase = IO_ADDRESS(TEGRA_UARTD_BASE), 61
51 .mapbase = TEGRA_UARTD_BASE, 62#define ATAG_NVIDIA_RM 0x1
52 .irq = INT_UARTD, 63#define ATAG_NVIDIA_DISPLAY 0x2
53 .flags = UPF_BOOT_AUTOCONF, 64#define ATAG_NVIDIA_FRAMEBUFFER 0x3
54 .iotype = UPIO_MEM, 65#define ATAG_NVIDIA_CHIPSHMOO 0x4
55 .regshift = 2, 66#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5
56 .uartclk = 216000000, 67#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000
57 }, { 68#define ATAG_NVIDIA_PRESERVED_MEM_N 2
58 .flags = 0 69#define ATAG_NVIDIA_FORCE_32 0x7fffffff
59 } 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 },
60}; 154};
61 155
62static struct platform_device debug_uart = { 156struct platform_device tegra_nand_device = {
63 .name = "serial8250", 157 .name = "tegra_nand",
64 .id = PLAT8250_DEV_PLATFORM, 158 .id = -1,
159 .num_resources = ARRAY_SIZE(resources_nand),
160 .resource = resources_nand,
65 .dev = { 161 .dev = {
66 .platform_data = debug_uart_platform_data, 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,
67 }, 174 },
68}; 175};
69 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
70static struct tegra_wm8903_platform_data harmony_audio_pdata = { 198static struct tegra_wm8903_platform_data harmony_audio_pdata = {
71 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN, 199 .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
72 .gpio_hp_det = TEGRA_GPIO_HP_DET, 200 .gpio_hp_det = TEGRA_GPIO_HP_DET,
@@ -84,19 +212,40 @@ static struct platform_device harmony_audio_device = {
84}; 212};
85 213
86static struct tegra_i2c_platform_data harmony_i2c1_platform_data = { 214static struct tegra_i2c_platform_data harmony_i2c1_platform_data = {
87 .bus_clk_rate = 400000, 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,
88}; 228};
89 229
90static struct tegra_i2c_platform_data harmony_i2c2_platform_data = { 230static struct tegra_i2c_platform_data harmony_i2c2_platform_data = {
91 .bus_clk_rate = 400000, 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 },
92}; 236};
93 237
94static struct tegra_i2c_platform_data harmony_i2c3_platform_data = { 238static struct tegra_i2c_platform_data harmony_i2c3_platform_data = {
95 .bus_clk_rate = 400000, 239 .adapter_nr = 3,
240 .bus_count = 1,
241 .bus_clk_rate = { 400000, 0 },
96}; 242};
97 243
98static struct tegra_i2c_platform_data harmony_dvc_platform_data = { 244static struct tegra_i2c_platform_data harmony_dvc_platform_data = {
99 .bus_clk_rate = 400000, 245 .adapter_nr = 4,
246 .bus_count = 1,
247 .bus_clk_rate = { 400000, 0 },
248 .is_dvc = true,
100}; 249};
101 250
102static struct wm8903_platform_data harmony_wm8903_pdata = { 251static struct wm8903_platform_data harmony_wm8903_pdata = {
@@ -134,15 +283,103 @@ static void __init harmony_i2c_init(void)
134 i2c_register_board_info(0, &wm8903_board_info, 1); 283 i2c_register_board_info(0, &wm8903_board_info, 1);
135} 284}
136 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
137static struct platform_device *harmony_devices[] __initdata = { 358static struct platform_device *harmony_devices[] __initdata = {
138 &debug_uart, 359 &debug_uartd_device,
139 &tegra_sdhci_device1, 360 &tegra_sdhci_device1,
140 &tegra_sdhci_device2, 361 &tegra_sdhci_device2,
141 &tegra_sdhci_device4, 362 &tegra_sdhci_device4,
142 &tegra_i2s_device1, 363 &tegra_i2s_device1,
364 &tegra_i2s_device2,
365 &tegra_spdif_device,
143 &tegra_das_device, 366 &tegra_das_device,
367 &spdif_dit_device,
368 &bluetooth_dit_device,
144 &tegra_pcm_device, 369 &tegra_pcm_device,
145 &harmony_audio_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,
146}; 383};
147 384
148static void __init tegra_harmony_fixup(struct machine_desc *desc, 385static void __init tegra_harmony_fixup(struct machine_desc *desc,
@@ -158,10 +395,13 @@ static void __init tegra_harmony_fixup(struct machine_desc *desc,
158static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = { 395static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
159 /* name parent rate enabled */ 396 /* name parent rate enabled */
160 { "uartd", "pll_p", 216000000, true }, 397 { "uartd", "pll_p", 216000000, true },
161 { "pll_a", "pll_p_out1", 56448000, true }, 398 { "i2s1", "pll_a_out0", 0, false},
162 { "pll_a_out0", "pll_a", 11289600, true }, 399 { "spdif_out", "pll_a_out0", 0, false},
163 { "cdev1", NULL, 0, true }, 400 { "sdmmc1", "clk_m", 48000000, true },
164 { "i2s1", "pll_a_out0", 11289600, false}, 401 { "sdmmc2", "clk_m", 48000000, true },
402 { "sdmmc4", "clk_m", 48000000, true },
403 { "ndflash", "pll_p", 108000000, true},
404 { "pwm", "clk_32k", 32768, false},
165 { NULL, NULL, 0, 0}, 405 { NULL, NULL, 0, 0},
166}; 406};
167 407
@@ -185,25 +425,81 @@ static struct tegra_sdhci_platform_data sdhci_pdata4 = {
185 .is_8bit = 1, 425 .is_8bit = 1,
186}; 426};
187 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
188static void __init tegra_harmony_init(void) 463static void __init tegra_harmony_init(void)
189{ 464{
190 tegra_clk_init_from_table(harmony_clk_init_table); 465 tegra_clk_init_from_table(harmony_clk_init_table);
191 466
192 harmony_pinmux_init(); 467 harmony_pinmux_init();
193 468
469 harmony_keys_init();
470
471 harmony_debug_uart_init();
472
194 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1; 473 tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
195 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2; 474 tegra_sdhci_device2.dev.platform_data = &sdhci_pdata2;
196 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4; 475 tegra_sdhci_device4.dev.platform_data = &sdhci_pdata4;
197 476
477 tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata;
478
198 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices)); 479 platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
199 harmony_i2c_init(); 480 harmony_i2c_init();
200 harmony_regulator_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);
201} 496}
202 497
203MACHINE_START(HARMONY, "harmony") 498MACHINE_START(HARMONY, "harmony")
204 .boot_params = 0x00000100, 499 .boot_params = 0x00000100,
205 .fixup = tegra_harmony_fixup, 500 .fixup = tegra_harmony_fixup,
206 .map_io = tegra_map_common_io, 501 .map_io = tegra_map_common_io,
502 .reserve = tegra_harmony_reserve,
207 .init_early = tegra_init_early, 503 .init_early = tegra_init_early,
208 .init_irq = tegra_init_irq, 504 .init_irq = tegra_init_irq,
209 .timer = &tegra_timer, 505 .timer = &tegra_timer,