diff options
author | Johnny Qiu <joqiu@nvidia.com> | 2012-01-10 12:40:05 -0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-01-30 11:46:19 -0800 |
commit | 00ce1168fe25fa398a758c1b05dc3fc40d4fb497 (patch) | |
tree | 3e3d34c276d5e177016956bef18c1e0af7e16b16 /arch/arm/mach-tegra/board-kai.c | |
parent | e818b6ec2c0ab3bf142291983eb0f2840f62570c (diff) |
arm: tegra: kai: create board files
Create initial board files and config files for Kai.
Reviewed-on: http://git-master/r/74441
Change-Id: I4b07607da85fe4bcb00e5fce2ddbc2a83471b1de
Signed-off-by: Johnny Qiu <joqiu@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/77296
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'arch/arm/mach-tegra/board-kai.c')
-rw-r--r-- | arch/arm/mach-tegra/board-kai.c | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-kai.c b/arch/arm/mach-tegra/board-kai.c new file mode 100644 index 000000000000..2adb7eeb9d90 --- /dev/null +++ b/arch/arm/mach-tegra/board-kai.c @@ -0,0 +1,537 @@ +/* + * arch/arm/mach-tegra/board-kai.c + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/ctype.h> +#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/serial_8250.h> +#include <linux/i2c.h> +#include <linux/dma-mapping.h> +#include <linux/delay.h> +#include <linux/i2c-tegra.h> +#include <linux/gpio.h> +#include <linux/input.h> +#include <linux/platform_data/tegra_usb.h> +#include <linux/spi/spi.h> +#include <linux/tegra_uart.h> +#include <linux/memblock.h> +#include <linux/spi-tegra.h> + +#include <mach/clk.h> +#include <mach/iomap.h> +#include <mach/irqs.h> +#include <mach/pinmux.h> +#include <mach/iomap.h> +#include <mach/io.h> +#include <mach/i2s.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <mach/usb_phy.h> +#include <mach/thermal.h> + +#include "board.h" +#include "clock.h" +#include "board-kai.h" +#include "devices.h" +#include "gpio-names.h" +#include "fuse.h" +#include "pm.h" +#include "wdt-recovery.h" + +/* All units are in millicelsius */ +static struct tegra_thermal_data thermal_data = { + .temp_throttle = 85000, + .temp_shutdown = 90000, + .temp_offset = TDIODE_OFFSET, /* temps based on tdiode */ +#ifdef CONFIG_TEGRA_EDP_LIMITS + .edp_offset = TDIODE_OFFSET, /* edp based on tdiode */ + .hysteresis_edp = 3000, +#endif +#ifdef CONFIG_TEGRA_THERMAL_SYSFS + .tc1 = 0, + .tc2 = 1, + .passive_delay = 2000, +#else + .hysteresis_throttle = 1000, +#endif +}; + +/* !!!TODO: Change for kai (Taken from Ventana) */ +static struct tegra_utmip_config utmi_phy_config[] = { + [0] = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, + [1] = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 15, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, + [2] = { + .hssync_start_delay = 0, + .idle_wait_delay = 17, + .elastic_limit = 16, + .term_range_adj = 6, + .xcvr_setup = 8, + .xcvr_setup_offset = 0, + .xcvr_use_fuses = 1, + .xcvr_lsfslew = 2, + .xcvr_lsrslew = 2, + }, +}; + +static __initdata struct tegra_clk_init_table kai_clk_init_table[] = { + /* name parent rate enabled */ + { "pll_m", NULL, 0, false}, + { "hda", "pll_p", 108000000, false}, + { "hda2codec_2x", "pll_p", 48000000, false}, + { "pwm", "pll_p", 3187500, false}, + { "blink", "clk_32k", 32768, true}, + { "i2s1", "pll_a_out0", 0, false}, + { "i2s3", "pll_a_out0", 0, false}, + { "spdif_out", "pll_a_out0", 0, false}, + { "d_audio", "pll_a_out0", 0, false}, + { "dam0", "pll_a_out0", 0, false}, + { "dam1", "pll_a_out0", 0, false}, + { "dam2", "pll_a_out0", 0, false}, + { "audio1", "i2s1_sync", 0, false}, + { "audio3", "i2s3_sync", 0, false}, + { "vi_sensor", "pll_p", 150000000, false}, + { "i2c1", "pll_p", 3200000, false}, + { "i2c2", "pll_p", 3200000, false}, + { "i2c3", "pll_p", 3200000, false}, + { "i2c4", "pll_p", 3200000, false}, + { "i2c5", "pll_p", 3200000, false}, + { NULL, NULL, 0, 0}, +}; + +static struct tegra_i2c_platform_data kai_i2c1_platform_data = { + .adapter_nr = 0, + .bus_count = 1, + .bus_clk_rate = { 100000, 0 }, + .scl_gpio = {TEGRA_GPIO_PC4, 0}, + .sda_gpio = {TEGRA_GPIO_PC5, 0}, + .arb_recovery = arb_lost_recovery, +}; + +static struct tegra_i2c_platform_data kai_i2c2_platform_data = { + .adapter_nr = 1, + .bus_count = 1, + .bus_clk_rate = { 100000, 0 }, + .is_clkon_always = true, + .scl_gpio = {TEGRA_GPIO_PT5, 0}, + .sda_gpio = {TEGRA_GPIO_PT6, 0}, + .arb_recovery = arb_lost_recovery, +}; + +static struct tegra_i2c_platform_data kai_i2c3_platform_data = { + .adapter_nr = 2, + .bus_count = 1, + .bus_clk_rate = { 100000, 0 }, + .scl_gpio = {TEGRA_GPIO_PBB1, 0}, + .sda_gpio = {TEGRA_GPIO_PBB2, 0}, + .arb_recovery = arb_lost_recovery, +}; + +static struct tegra_i2c_platform_data kai_i2c4_platform_data = { + .adapter_nr = 3, + .bus_count = 1, + .bus_clk_rate = { 100000, 0 }, + .scl_gpio = {TEGRA_GPIO_PV4, 0}, + .sda_gpio = {TEGRA_GPIO_PV5, 0}, + .arb_recovery = arb_lost_recovery, +}; + +static struct tegra_i2c_platform_data kai_i2c5_platform_data = { + .adapter_nr = 4, + .bus_count = 1, + .bus_clk_rate = { 400000, 0 }, + .scl_gpio = {TEGRA_GPIO_PZ6, 0}, + .sda_gpio = {TEGRA_GPIO_PZ7, 0}, + .arb_recovery = arb_lost_recovery, +}; + +static void kai_i2c_init(void) +{ + tegra_i2c_device1.dev.platform_data = &kai_i2c1_platform_data; + tegra_i2c_device2.dev.platform_data = &kai_i2c2_platform_data; + tegra_i2c_device3.dev.platform_data = &kai_i2c3_platform_data; + tegra_i2c_device4.dev.platform_data = &kai_i2c4_platform_data; + tegra_i2c_device5.dev.platform_data = &kai_i2c5_platform_data; + + platform_device_register(&tegra_i2c_device5); + platform_device_register(&tegra_i2c_device4); + platform_device_register(&tegra_i2c_device3); + platform_device_register(&tegra_i2c_device2); + platform_device_register(&tegra_i2c_device1); +} + +static struct platform_device *kai_uart_devices[] __initdata = { + &tegra_uarta_device, + &tegra_uartb_device, + &tegra_uartc_device, + &tegra_uartd_device, + &tegra_uarte_device, +}; +static struct uart_clk_parent uart_parent_clk[] = { + [0] = {.name = "clk_m"}, + [1] = {.name = "pll_p"}, +#ifndef CONFIG_TEGRA_PLLM_RESTRICTED + [2] = {.name = "pll_m"}, +#endif +}; + +static struct tegra_uart_platform_data kai_uart_pdata; +static struct tegra_uart_platform_data kai_loopback_uart_pdata; + +static void __init uart_debug_init(void) +{ + int debug_port_id; + + debug_port_id = get_tegra_uart_debug_port_id(); + if (debug_port_id < 0) + debug_port_id = 3; + + switch (debug_port_id) { + case 0: + /* UARTA is the debug port. */ + pr_info("Selecting UARTA as the debug console\n"); + kai_uart_devices[0] = &debug_uarta_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uarta_device.dev.platform_data))->mapbase; + break; + + case 1: + /* UARTB is the debug port. */ + pr_info("Selecting UARTB as the debug console\n"); + kai_uart_devices[1] = &debug_uartb_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uartb"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uartb_device.dev.platform_data))->mapbase; + break; + + case 2: + /* UARTC is the debug port. */ + pr_info("Selecting UARTC as the debug console\n"); + kai_uart_devices[2] = &debug_uartc_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uartc"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uartc_device.dev.platform_data))->mapbase; + break; + + case 3: + /* UARTD is the debug port. */ + pr_info("Selecting UARTD as the debug console\n"); + kai_uart_devices[3] = &debug_uartd_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uartd"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uartd_device.dev.platform_data))->mapbase; + break; + + case 4: + /* UARTE is the debug port. */ + pr_info("Selecting UARTE as the debug console\n"); + kai_uart_devices[4] = &debug_uarte_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uarte"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uarte_device.dev.platform_data))->mapbase; + break; + + default: + pr_info("The debug console id %d is invalid, Assuming UARTA", + debug_port_id); + kai_uart_devices[0] = &debug_uarta_device; + debug_uart_clk = clk_get_sys("serial8250.0", "uarta"); + debug_uart_port_base = ((struct plat_serial8250_port *)( + debug_uarta_device.dev.platform_data))->mapbase; + break; + } + return; +} + +static void __init kai_uart_init(void) +{ + struct clk *c; + int i; + + for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) { + c = tegra_get_clock_by_name(uart_parent_clk[i].name); + if (IS_ERR_OR_NULL(c)) { + pr_err("Not able to get the clock for %s\n", + uart_parent_clk[i].name); + continue; + } + uart_parent_clk[i].parent_clk = c; + uart_parent_clk[i].fixed_clk_rate = clk_get_rate(c); + } + kai_uart_pdata.parent_clk_list = uart_parent_clk; + kai_uart_pdata.parent_clk_count = ARRAY_SIZE(uart_parent_clk); + kai_loopback_uart_pdata.parent_clk_list = uart_parent_clk; + kai_loopback_uart_pdata.parent_clk_count = + ARRAY_SIZE(uart_parent_clk); + kai_loopback_uart_pdata.is_loopback = true; + tegra_uarta_device.dev.platform_data = &kai_uart_pdata; + tegra_uartb_device.dev.platform_data = &kai_uart_pdata; + tegra_uartc_device.dev.platform_data = &kai_uart_pdata; + tegra_uartd_device.dev.platform_data = &kai_uart_pdata; + /* UARTE is used for loopback test purpose */ + tegra_uarte_device.dev.platform_data = &kai_loopback_uart_pdata; + + /* Register low speed only if it is selected */ + if (!is_tegra_debug_uartport_hs()) { + uart_debug_init(); + /* Clock enable for the debug channel */ + if (!IS_ERR_OR_NULL(debug_uart_clk)) { + pr_info("The debug console clock name is %s\n", + debug_uart_clk->name); + c = tegra_get_clock_by_name("pll_p"); + if (IS_ERR_OR_NULL(c)) + pr_err("Not getting the parent clock pll_p\n"); + else + clk_set_parent(debug_uart_clk, c); + + clk_enable(debug_uart_clk); + clk_set_rate(debug_uart_clk, clk_get_rate(c)); + } else { + pr_err("Not getting the clock %s for debug console\n", + debug_uart_clk->name); + } + } + + platform_add_devices(kai_uart_devices, + ARRAY_SIZE(kai_uart_devices)); +} + +static struct platform_device tegra_camera = { + .name = "tegra_camera", + .id = -1, +}; + +static struct platform_device *kai_spi_devices[] __initdata = { + &tegra_spi_device4, + &tegra_spi_device1, +}; + +static struct spi_clk_parent spi_parent_clk[] = { + [0] = {.name = "pll_p"}, +#ifndef CONFIG_TEGRA_PLLM_RESTRICTED + [1] = {.name = "pll_m"}, + [2] = {.name = "clk_m"}, +#else + [1] = {.name = "clk_m"}, +#endif +}; + +static struct tegra_spi_platform_data kai_spi_pdata = { + .is_dma_based = true, + .max_dma_buffer = (16 * 1024), + .is_clkon_always = false, + .max_rate = 100000000, +}; + +static void __init kai_spi_init(void) +{ + int i; + struct clk *c; + + for (i = 0; i < ARRAY_SIZE(spi_parent_clk); ++i) { + c = tegra_get_clock_by_name(spi_parent_clk[i].name); + if (IS_ERR_OR_NULL(c)) { + pr_err("Not able to get the clock for %s\n", + spi_parent_clk[i].name); + continue; + } + spi_parent_clk[i].parent_clk = c; + spi_parent_clk[i].fixed_clk_rate = clk_get_rate(c); + } + kai_spi_pdata.parent_clk_list = spi_parent_clk; + kai_spi_pdata.parent_clk_count = ARRAY_SIZE(spi_parent_clk); + tegra_spi_device4.dev.platform_data = &kai_spi_pdata; + platform_add_devices(kai_spi_devices, + ARRAY_SIZE(kai_spi_devices)); + +} + +static struct resource tegra_rtc_resources[] = { + [0] = { + .start = TEGRA_RTC_BASE, + .end = TEGRA_RTC_BASE + TEGRA_RTC_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = INT_RTC, + .end = INT_RTC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device tegra_rtc_device = { + .name = "tegra_rtc", + .id = -1, + .resource = tegra_rtc_resources, + .num_resources = ARRAY_SIZE(tegra_rtc_resources), +}; + +static struct platform_device *kai_devices[] __initdata = { + &tegra_pmu_device, + &tegra_rtc_device, + &tegra_udc_device, +#if defined(CONFIG_TEGRA_IOVMM_SMMU) + &tegra_smmu_device, +#endif + &tegra_wdt_device, +#if defined(CONFIG_TEGRA_AVP) + &tegra_avp_device, +#endif + &tegra_camera, +#if defined(CONFIG_CRYPTO_DEV_TEGRA_SE) + &tegra_se_device, +#endif + &tegra_ahub_device, + &tegra_dam_device0, + &tegra_dam_device1, + &tegra_dam_device2, + &tegra_i2s_device1, + &tegra_i2s_device3, + &tegra_spdif_device, + &spdif_dit_device, + &bluetooth_dit_device, + &tegra_pcm_device, + &tegra_hda_device, +#if defined(CONFIG_CRYPTO_DEV_TEGRA_AES) + &tegra_aes_device, +#endif +}; + +static struct tegra_ehci_platform_data tegra_ehci_pdata[] = { + [0] = { + .phy_config = &utmi_phy_config[0], + .operating_mode = TEGRA_USB_HOST, + .power_down_on_bus_suspend = 1, + }, + [1] = { + .phy_config = &utmi_phy_config[1], + .operating_mode = TEGRA_USB_HOST, + .power_down_on_bus_suspend = 1, + }, +}; + +static struct tegra_otg_platform_data tegra_otg_pdata = { + .ehci_device = &tegra_ehci1_device, + .ehci_pdata = &tegra_ehci_pdata[0], +}; + +#ifdef CONFIG_USB_SUPPORT +static struct usb_phy_plat_data tegra_usb_phy_pdata[] = { + [0] = { + .instance = 0, + .vbus_gpio = -1, + .vbus_reg_supply = "vdd_vbus_micro_usb", + }, + [1] = { + .instance = 1, + .vbus_gpio = -1, + }, +}; + +static void kai_usb_init(void) +{ + tegra_usb_phy_init(tegra_usb_phy_pdata, + ARRAY_SIZE(tegra_usb_phy_pdata)); + + tegra_otg_device.dev.platform_data = &tegra_otg_pdata; + platform_device_register(&tegra_otg_device); + + tegra_ehci2_device.dev.platform_data = &tegra_ehci_pdata[1]; + platform_device_register(&tegra_ehci2_device); +} +#else +static void kai_usb_init(void) { } +#endif + +static void __init tegra_kai_init(void) +{ + tegra_thermal_init(&thermal_data); + tegra_clk_init_from_table(kai_clk_init_table); + kai_pinmux_init(); + kai_i2c_init(); + kai_spi_init(); + kai_usb_init(); +#ifdef CONFIG_TEGRA_EDP_LIMITS + kai_edp_init(); +#endif + kai_uart_init(); + kai_tsensor_init(); + platform_add_devices(kai_devices, ARRAY_SIZE(kai_devices)); + tegra_ram_console_debug_init(); + kai_sdhci_init(); + kai_regulator_init(); + kai_suspend_init(); + kai_power_off_init(); + kai_keys_init(); + kai_panel_init(); + kai_pins_state_init(); + tegra_release_bootloader_fb(); +#ifdef CONFIG_TEGRA_WDT_RECOVERY + tegra_wdt_recovery_init(); +#endif +} + +static void __init kai_ramconsole_reserve(unsigned long size) +{ + tegra_ram_console_debug_reserve(SZ_1M); +} + +static void __init tegra_kai_reserve(void) +{ +#if defined(CONFIG_NVMAP_CONVERT_CARVEOUT_TO_IOVMM) + /* support 1920X1200 with 24bpp */ + tegra_reserve(0, SZ_8M + SZ_1M, SZ_8M + SZ_1M); +#else + tegra_reserve(SZ_128M, SZ_8M, SZ_8M); +#endif + kai_ramconsole_reserve(SZ_1M); +} + +MACHINE_START(KAI, "kai") + .boot_params = 0x80000100, + .map_io = tegra_map_common_io, + .reserve = tegra_kai_reserve, + .init_early = tegra_init_early, + .init_irq = tegra_init_irq, + .timer = &tegra_timer, + .init_machine = tegra_kai_init, +MACHINE_END |