diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-p1852.c')
-rw-r--r-- | arch/arm/mach-tegra/board-p1852.c | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-p1852.c b/arch/arm/mach-tegra/board-p1852.c new file mode 100644 index 00000000000..ef53d405093 --- /dev/null +++ b/arch/arm/mach-tegra/board-p1852.c | |||
@@ -0,0 +1,456 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-tegra/board-p1852.c | ||
3 | * | ||
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/ctype.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/clk.h> | ||
26 | #include <linux/serial_8250.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/i2c/panjit_ts.h> | ||
29 | #include <linux/dma-mapping.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/i2c-tegra.h> | ||
32 | #include <linux/gpio.h> | ||
33 | #include <linux/input.h> | ||
34 | #include <linux/platform_data/tegra_usb.h> | ||
35 | #include <linux/platform_data/tegra_nor.h> | ||
36 | #include <linux/spi/spi.h> | ||
37 | #include <linux/mtd/partitions.h> | ||
38 | #include <mach/clk.h> | ||
39 | #include <mach/iomap.h> | ||
40 | #include <mach/irqs.h> | ||
41 | #include <mach/pinmux.h> | ||
42 | #include <mach/iomap.h> | ||
43 | #include <mach/io.h> | ||
44 | #include <mach/pci.h> | ||
45 | #include <mach/audio.h> | ||
46 | #include <mach/tegra_p1852_pdata.h> | ||
47 | #include <asm/mach/flash.h> | ||
48 | #include <asm/mach-types.h> | ||
49 | #include <asm/mach/arch.h> | ||
50 | #include <mach/usb_phy.h> | ||
51 | #include <sound/wm8903.h> | ||
52 | #include <mach/tsensor.h> | ||
53 | #include "board.h" | ||
54 | #include "clock.h" | ||
55 | #include "board-p1852.h" | ||
56 | #include "devices.h" | ||
57 | #include "gpio-names.h" | ||
58 | #include "fuse.h" | ||
59 | |||
60 | static struct tegra_utmip_config utmi_phy_config[] = { | ||
61 | [0] = { | ||
62 | .hssync_start_delay = 0, | ||
63 | .idle_wait_delay = 17, | ||
64 | .elastic_limit = 16, | ||
65 | .term_range_adj = 6, | ||
66 | .xcvr_setup = 15, | ||
67 | .xcvr_setup_offset = 0, | ||
68 | .xcvr_use_fuses = 1, | ||
69 | .xcvr_lsfslew = 2, | ||
70 | .xcvr_lsrslew = 2, | ||
71 | }, | ||
72 | [1] = { | ||
73 | .hssync_start_delay = 0, | ||
74 | .idle_wait_delay = 17, | ||
75 | .elastic_limit = 16, | ||
76 | .term_range_adj = 6, | ||
77 | .xcvr_setup = 15, | ||
78 | .xcvr_setup_offset = 0, | ||
79 | .xcvr_use_fuses = 1, | ||
80 | .xcvr_lsfslew = 2, | ||
81 | .xcvr_lsrslew = 2, | ||
82 | }, | ||
83 | [2] = { | ||
84 | .hssync_start_delay = 0, | ||
85 | .idle_wait_delay = 17, | ||
86 | .elastic_limit = 16, | ||
87 | .term_range_adj = 6, | ||
88 | .xcvr_setup = 8, | ||
89 | .xcvr_setup_offset = 0, | ||
90 | .xcvr_use_fuses = 1, | ||
91 | .xcvr_lsfslew = 2, | ||
92 | .xcvr_lsrslew = 2, | ||
93 | }, | ||
94 | }; | ||
95 | |||
96 | static __initdata struct tegra_clk_init_table p1852_clk_init_table[] = { | ||
97 | /* name parent rate enabled */ | ||
98 | { "pll_m", NULL, 0, true}, | ||
99 | { "hda", "pll_p", 108000000, false}, | ||
100 | { "hda2codec_2x", "pll_p", 48000000, false}, | ||
101 | { "pwm", "clk_32k", 32768, false}, | ||
102 | { "blink", "clk_32k", 32768, true}, | ||
103 | { "pll_a", NULL, 552960000, false}, | ||
104 | { "pll_a_out0", NULL, 12288000, false}, | ||
105 | { "d_audio", "pll_a_out0", 12288000, false}, | ||
106 | { "nor", "pll_p", 86500000, true}, | ||
107 | { "uarta", "pll_p", 480000000, true}, | ||
108 | { "uartd", "pll_p", 480000000, true}, | ||
109 | { "uarte", "pll_p", 480000000, true}, | ||
110 | { "sdmmc2", "pll_p", 52000000, true}, | ||
111 | { "sbc1", "pll_m", 100000000, true}, | ||
112 | { "sbc2", "pll_m", 100000000, true}, | ||
113 | { "sbc3", "pll_m", 100000000, true}, | ||
114 | { "sbc4", "pll_m", 100000000, true}, | ||
115 | { "sbc5", "pll_m", 100000000, true}, | ||
116 | { "sbc6", "pll_m", 100000000, true}, | ||
117 | { "cpu_g", "cclk_g", 900000000, true}, | ||
118 | { "i2s0", "pll_a_out0", 12288000, false}, | ||
119 | { "i2s1", "pll_a_out0", 12288000, false}, | ||
120 | { "i2s2", "pll_a_out0", 12288000, false}, | ||
121 | { "i2s3", "pll_a_out0", 12288000, false}, | ||
122 | { "i2s4", "pll_a_out0", 12288000, false}, | ||
123 | { "audio0", "i2s0_sync", 12288000, false}, | ||
124 | { "audio1", "i2s1_sync", 12288000, false}, | ||
125 | { "audio2", "i2s2_sync", 12288000, false}, | ||
126 | { "audio3", "i2s3_sync", 12288000, false}, | ||
127 | { "audio4", "i2s4_sync", 12288000, false}, | ||
128 | { "apbif", "clk_m", 12000000, false}, | ||
129 | { "dam0", "clk_m", 12000000, true}, | ||
130 | { "dam1", "clk_m", 12000000, true}, | ||
131 | { "dam2", "clk_m", 12000000, true}, | ||
132 | { "vi", "pll_p", 470000000, false}, | ||
133 | { "vi_sensor", "pll_p", 150000000, false}, | ||
134 | { "vde", "pll_c", 484000000, true}, | ||
135 | { "host1x", "pll_c", 242000000, true}, | ||
136 | { "mpe", "pll_c", 484000000, true}, | ||
137 | { "se", "pll_m", 625000000, true}, | ||
138 | { "i2c1", "pll_p", 3200000, true}, | ||
139 | { "i2c2", "pll_p", 3200000, true}, | ||
140 | { "i2c3", "pll_p", 3200000, true}, | ||
141 | { "i2c4", "pll_p", 3200000, true}, | ||
142 | { "i2c5", "pll_p", 3200000, true}, | ||
143 | { "sdmmc2", "pll_p", 104000000, false}, | ||
144 | { NULL, NULL, 0, 0}, | ||
145 | }; | ||
146 | |||
147 | static struct tegra_i2c_platform_data p1852_i2c1_platform_data = { | ||
148 | .adapter_nr = 0, | ||
149 | .bus_count = 1, | ||
150 | .bus_clk_rate = { 100000, 0 }, | ||
151 | }; | ||
152 | |||
153 | static struct tegra_i2c_platform_data p1852_i2c2_platform_data = { | ||
154 | .adapter_nr = 1, | ||
155 | .bus_count = 1, | ||
156 | .bus_clk_rate = { 100000, 0 }, | ||
157 | .is_clkon_always = true, | ||
158 | }; | ||
159 | |||
160 | static struct tegra_i2c_platform_data p1852_i2c4_platform_data = { | ||
161 | .adapter_nr = 3, | ||
162 | .bus_count = 1, | ||
163 | .bus_clk_rate = { 100000, 0 }, | ||
164 | }; | ||
165 | |||
166 | static struct tegra_i2c_platform_data p1852_i2c5_platform_data = { | ||
167 | .adapter_nr = 4, | ||
168 | .bus_count = 1, | ||
169 | .bus_clk_rate = { 100000, 0 }, | ||
170 | }; | ||
171 | |||
172 | static struct tegra_pci_platform_data p1852_pci_platform_data = { | ||
173 | .port_status[0] = 0, | ||
174 | .port_status[1] = 1, | ||
175 | .port_status[2] = 1, | ||
176 | .use_dock_detect = 0, | ||
177 | .gpio = 0, | ||
178 | }; | ||
179 | |||
180 | static void p1852_pcie_init(void) | ||
181 | { | ||
182 | tegra_pci_device.dev.platform_data = &p1852_pci_platform_data; | ||
183 | platform_device_register(&tegra_pci_device); | ||
184 | } | ||
185 | |||
186 | static void p1852_i2c_init(void) | ||
187 | { | ||
188 | tegra_i2c_device1.dev.platform_data = &p1852_i2c1_platform_data; | ||
189 | tegra_i2c_device2.dev.platform_data = &p1852_i2c2_platform_data; | ||
190 | tegra_i2c_device4.dev.platform_data = &p1852_i2c4_platform_data; | ||
191 | tegra_i2c_device5.dev.platform_data = &p1852_i2c5_platform_data; | ||
192 | |||
193 | platform_device_register(&tegra_i2c_device5); | ||
194 | platform_device_register(&tegra_i2c_device4); | ||
195 | platform_device_register(&tegra_i2c_device2); | ||
196 | platform_device_register(&tegra_i2c_device1); | ||
197 | } | ||
198 | |||
199 | static struct platform_device *p1852_uart_devices[] __initdata = { | ||
200 | &tegra_uarta_device, | ||
201 | &tegra_uartb_device, | ||
202 | &tegra_uartd_device, | ||
203 | &tegra_uarte_device, | ||
204 | }; | ||
205 | static struct clk *debug_uart_clk; | ||
206 | |||
207 | static void __init uart_debug_init(void) | ||
208 | { | ||
209 | /* Use skuinfo to decide debug uart */ | ||
210 | /* UARTB is the debug port. */ | ||
211 | pr_info("Selecting UARTB as the debug console\n"); | ||
212 | p1852_uart_devices[1] = &debug_uartb_device; | ||
213 | debug_uart_clk = clk_get_sys("serial8250.0", "uartb"); | ||
214 | } | ||
215 | |||
216 | static void __init p1852_uart_init(void) | ||
217 | { | ||
218 | /* Register low speed only if it is selected */ | ||
219 | if (!is_tegra_debug_uartport_hs()) { | ||
220 | uart_debug_init(); | ||
221 | /* Clock enable for the debug channel */ | ||
222 | if (!IS_ERR_OR_NULL(debug_uart_clk)) { | ||
223 | pr_info("The debug console clock name is %s\n", | ||
224 | debug_uart_clk->name); | ||
225 | clk_enable(debug_uart_clk); | ||
226 | clk_set_rate(debug_uart_clk, 408000000); | ||
227 | } else { | ||
228 | pr_err("Not getting the clock %s for debug console\n", | ||
229 | debug_uart_clk->name); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | platform_add_devices(p1852_uart_devices, | ||
234 | ARRAY_SIZE(p1852_uart_devices)); | ||
235 | } | ||
236 | |||
237 | static struct tegra_p1852_platform_data p1852_audio_pdata = { | ||
238 | .codec_info[0] = { | ||
239 | .codec_dai_name = "dit-hifi", | ||
240 | .cpu_dai_name = "tegra30-i2s.0", | ||
241 | .codec_name = "spdif-dit.0", | ||
242 | .name = "tegra-i2s-1", | ||
243 | .i2s_format = format_i2s, | ||
244 | .master = 1, | ||
245 | }, | ||
246 | .codec_info[1] = { | ||
247 | .codec_dai_name = "dit-hifi", | ||
248 | .cpu_dai_name = "tegra30-i2s.1", | ||
249 | .codec_name = "spdif-dit.1", | ||
250 | .name = "tegra-i2s-2", | ||
251 | .i2s_format = format_i2s, | ||
252 | .master = 0, | ||
253 | }, | ||
254 | |||
255 | }; | ||
256 | |||
257 | static struct platform_device generic_codec_1 = { | ||
258 | .name = "spdif-dit", | ||
259 | .id = 0, | ||
260 | }; | ||
261 | static struct platform_device generic_codec_2 = { | ||
262 | .name = "spdif-dit", | ||
263 | .id = 1, | ||
264 | }; | ||
265 | |||
266 | static struct platform_device tegra_snd_p1852 = { | ||
267 | .name = "tegra-snd-p1852", | ||
268 | .id = 0, | ||
269 | .dev = { | ||
270 | .platform_data = &p1852_audio_pdata, | ||
271 | }, | ||
272 | }; | ||
273 | |||
274 | static void p1852_i2s_audio_init(void) | ||
275 | { | ||
276 | platform_device_register(&tegra_pcm_device); | ||
277 | platform_device_register(&generic_codec_1); | ||
278 | platform_device_register(&generic_codec_2); | ||
279 | platform_device_register(&tegra_i2s_device0); | ||
280 | platform_device_register(&tegra_i2s_device1); | ||
281 | platform_device_register(&tegra_ahub_device); | ||
282 | platform_device_register(&tegra_snd_p1852); | ||
283 | } | ||
284 | |||
285 | |||
286 | #if defined(CONFIG_SPI_TEGRA) && defined(CONFIG_SPI_SPIDEV) | ||
287 | static struct spi_board_info tegra_spi_devices[] __initdata = { | ||
288 | { | ||
289 | .modalias = "spidev", | ||
290 | .bus_num = 0, | ||
291 | .chip_select = 0, | ||
292 | .mode = SPI_MODE_0, | ||
293 | .max_speed_hz = 18000000, | ||
294 | .platform_data = NULL, | ||
295 | .irq = 0, | ||
296 | }, | ||
297 | { | ||
298 | .modalias = "spidev", | ||
299 | .bus_num = 1, | ||
300 | .chip_select = 1, | ||
301 | .mode = SPI_MODE_0, | ||
302 | .max_speed_hz = 18000000, | ||
303 | .platform_data = NULL, | ||
304 | .irq = 0, | ||
305 | }, | ||
306 | { | ||
307 | .modalias = "spidev", | ||
308 | .bus_num = 3, | ||
309 | .chip_select = 1, | ||
310 | .mode = SPI_MODE_0, | ||
311 | .max_speed_hz = 18000000, | ||
312 | .platform_data = NULL, | ||
313 | .irq = 0, | ||
314 | }, | ||
315 | }; | ||
316 | |||
317 | static void __init p852_register_spidev(void) | ||
318 | { | ||
319 | spi_register_board_info(tegra_spi_devices, | ||
320 | ARRAY_SIZE(tegra_spi_devices)); | ||
321 | } | ||
322 | #else | ||
323 | #define p852_register_spidev() do {} while (0) | ||
324 | #endif | ||
325 | |||
326 | |||
327 | static void p1852_spi_init(void) | ||
328 | { | ||
329 | tegra_spi_device2.name = "spi_slave_tegra"; | ||
330 | platform_device_register(&tegra_spi_device1); | ||
331 | platform_device_register(&tegra_spi_device2); | ||
332 | p852_register_spidev(); | ||
333 | } | ||
334 | |||
335 | static struct platform_device *p1852_devices[] __initdata = { | ||
336 | #if defined(CONFIG_TEGRA_IOVMM_SMMU) | ||
337 | &tegra_smmu_device, | ||
338 | #endif | ||
339 | #if defined(CONFIG_TEGRA_AVP) | ||
340 | &tegra_avp_device, | ||
341 | #endif | ||
342 | }; | ||
343 | |||
344 | static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { | ||
345 | [0] = { | ||
346 | .instance = 0, | ||
347 | .vbus_gpio = -1, | ||
348 | .vbus_reg_supply = NULL, | ||
349 | }, | ||
350 | [1] = { | ||
351 | .instance = 1, | ||
352 | .vbus_gpio = -1, | ||
353 | }, | ||
354 | [2] = { | ||
355 | .instance = 2, | ||
356 | .vbus_gpio = -1, | ||
357 | .vbus_reg_supply = NULL, | ||
358 | }, | ||
359 | }; | ||
360 | |||
361 | static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { | ||
362 | [0] = { | ||
363 | .phy_config = &utmi_phy_config[0], | ||
364 | .operating_mode = TEGRA_USB_HOST, | ||
365 | .power_down_on_bus_suspend = 1, | ||
366 | }, | ||
367 | [1] = { | ||
368 | .phy_config = &utmi_phy_config[1], | ||
369 | .operating_mode = TEGRA_USB_HOST, | ||
370 | .power_down_on_bus_suspend = 1, | ||
371 | }, | ||
372 | [2] = { | ||
373 | .phy_config = &utmi_phy_config[2], | ||
374 | .operating_mode = TEGRA_USB_HOST, | ||
375 | .power_down_on_bus_suspend = 1, | ||
376 | }, | ||
377 | }; | ||
378 | |||
379 | static void p1852_usb_init(void) | ||
380 | { | ||
381 | /* Need to parse sku info to decide host/device mode */ | ||
382 | tegra_usb_phy_init(tegra_usb_phy_pdata, | ||
383 | ARRAY_SIZE(tegra_usb_phy_pdata)); | ||
384 | |||
385 | tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0]; | ||
386 | platform_device_register(&tegra_ehci1_device); | ||
387 | |||
388 | tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; | ||
389 | platform_device_register(&tegra_ehci2_device); | ||
390 | |||
391 | tegra_ehci3_device.dev.platform_data = &tegra_ehci_pdata[2]; | ||
392 | platform_device_register(&tegra_ehci3_device); | ||
393 | |||
394 | } | ||
395 | |||
396 | static struct tegra_nor_platform_data p1852_nor_data = { | ||
397 | .flash = { | ||
398 | .map_name = "cfi_probe", | ||
399 | .width = 2, | ||
400 | }, | ||
401 | .chip_parms = { | ||
402 | /* FIXME: Need to use characterized value */ | ||
403 | .timing_default = { | ||
404 | .timing0 = 0xA0400273, | ||
405 | .timing1 = 0x00030402, | ||
406 | }, | ||
407 | .timing_read = { | ||
408 | .timing0 = 0xA0400273, | ||
409 | .timing1 = 0x00030402, | ||
410 | }, | ||
411 | }, | ||
412 | }; | ||
413 | |||
414 | static void p1852_nor_init(void) | ||
415 | { | ||
416 | tegra_nor_device.resource[2].end = TEGRA_NOR_FLASH_BASE + SZ_64M - 1; | ||
417 | tegra_nor_device.dev.platform_data = &p1852_nor_data; | ||
418 | platform_device_register(&tegra_nor_device); | ||
419 | } | ||
420 | |||
421 | static void __init tegra_p1852_init(void) | ||
422 | { | ||
423 | tegra_init_board_info(); | ||
424 | tegra_clk_init_from_table(p1852_clk_init_table); | ||
425 | p1852_pinmux_init(); | ||
426 | p1852_i2c_init(); | ||
427 | p1852_i2s_audio_init(); | ||
428 | p1852_gpio_init(); | ||
429 | p1852_uart_init(); | ||
430 | p1852_usb_init(); | ||
431 | p1852_sdhci_init(); | ||
432 | p1852_spi_init(); | ||
433 | platform_add_devices(p1852_devices, ARRAY_SIZE(p1852_devices)); | ||
434 | p1852_panel_init(); | ||
435 | p1852_nor_init(); | ||
436 | p1852_pcie_init(); | ||
437 | } | ||
438 | |||
439 | static void __init tegra_p1852_reserve(void) | ||
440 | { | ||
441 | #if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) | ||
442 | tegra_reserve(0, SZ_8M, 0); | ||
443 | #else | ||
444 | tegra_reserve(SZ_128M, SZ_8M, 0); | ||
445 | #endif | ||
446 | } | ||
447 | |||
448 | MACHINE_START(P1852, "p1852") | ||
449 | .boot_params = 0x80000100, | ||
450 | .init_irq = tegra_init_irq, | ||
451 | .init_early = tegra_init_early, | ||
452 | .init_machine = tegra_p1852_init, | ||
453 | .map_io = tegra_map_common_io, | ||
454 | .reserve = tegra_p1852_reserve, | ||
455 | .timer = &tegra_timer, | ||
456 | MACHINE_END | ||