* arch/arm/mach-tegra/common.c
*
* Copyright (C) 2010 Google, Inc.
- * Copyright (C) 2010-2013 NVIDIA Corporation
+ * Copyright (C) 2010-2013 NVIDIA Corporation. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
#include <linux/dma-mapping.h>
#include <linux/sys_soc.h>
+#include <linux/export.h>
+#include <linux/bootmem.h>
#include <trace/events/nvsecurity.h>
#include <asm/hardware/cache-l2x0.h>
unsigned long tegra_tsec_size;
unsigned long tegra_lp0_vec_start;
unsigned long tegra_lp0_vec_size;
-unsigned long tegra_bb_priv_start;
-unsigned long tegra_bb_ipc_start;
#ifdef CONFIG_TEGRA_NVDUMPER
unsigned long nvdumper_reserved;
#endif
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
+unsigned long tegra_tzram_start;
+unsigned long tegra_tzram_size;
+#endif
bool tegra_lp0_vec_relocate;
unsigned long tegra_grhost_aperture = ~0ul;
static bool is_tegra_debug_uart_hsport;
static struct board_info display_board_info;
static int panel_id;
static struct board_info camera_board_info;
+static int touch_id;
static int pmu_core_edp;
static int board_panel_type;
static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
static int pwr_i2c_clk = 400;
+static u8 power_config;
/*
* Storage for debug-macro.S's state.
*
0,
};
-static unsigned long tegra_bb_priv_size;
-static unsigned long tegra_bb_ipc_size;
#define NEVER_RESET 0
{ "csite", NULL, 0, true },
#endif
{ "pll_u", NULL, 480000000, true },
- { "pll_re_vco", NULL, 312000000, false },
+ { "pll_re_vco", NULL, 672000000, false },
+ { "xusb_falcon_src", "pll_re_vco", 224000000, false},
+ { "xusb_host_src", "pll_re_vco", 112000000, false},
+ { "xusb_ss_src", "pll_u_480M", 120000000, false},
+ { "xusb_hs_src", "xusb_ss_div2", 60000000, false},
+ { "xusb_fs_src", "pll_u_48M", 48000000, false},
{ "sdmmc1", "pll_p", 48000000, false},
{ "sdmmc3", "pll_p", 48000000, false},
{ "sdmmc4", "pll_p", 48000000, false},
{ "sbc4.sclk", NULL, 40000000, false},
{ "sbc5.sclk", NULL, 40000000, false},
{ "sbc6.sclk", NULL, 40000000, false},
+#ifdef CONFIG_TEGRA_PLLM_SCALED
+ { "vi", "pll_p", 0, false},
+#endif
+#ifdef CONFIG_TEGRA_SOCTHERM
+ { "soc_therm", "pll_p", 51000000, false },
+ { "tsensor", "clk_m", 500000, false },
+#endif
+ { NULL, NULL, 0, 0},
+};
+static __initdata struct tegra_clk_init_table tegra11x_cbus_init_table[] = {
#ifdef CONFIG_TEGRA_DUAL_CBUS
{ "c2bus", "pll_c2", 250000000, false },
{ "c3bus", "pll_c3", 250000000, false },
{ "cbus", "pll_c", 250000000, false },
#endif
{ "pll_c_out1", "pll_c", 150000000, false },
-#ifdef CONFIG_TEGRA_PLLM_SCALED
- { "vi", "pll_p", 0, false},
-#endif
{ NULL, NULL, 0, 0},
};
#endif
#ifdef CONFIG_ARCH_TEGRA_14x_SOC
static __initdata struct tegra_clk_init_table tegra14x_clk_init_table[] = {
/* name parent rate enabled */
- { "clk_m", NULL, 0, true },
+ { "osc", NULL, 0, true },
+ { "clk_m", "osc", 0, true },
{ "emc", NULL, 0, true },
{ "cpu", NULL, 0, true },
{ "kfuse", NULL, 0, true },
{ "pll_p_out2", "pll_p", 102000000, false },
{ "sclk", "pll_p_out2", 102000000, true },
{ "pll_p_out4", "pll_p", 204000000, true },
+ { "hclk", "sclk", 102000000, true },
+ { "pclk", "hclk", 51000000, true },
+ { "mselect", "pll_p", 102000000, true },
{ "host1x", "pll_p", 102000000, false },
- { "cl_dvfs_ref", "pll_p", 54000000, false },
- { "cl_dvfs_soc", "pll_p", 54000000, false },
+ { "cl_dvfs_ref", "pll_p", 51000000, true },
+ { "cl_dvfs_soc", "pll_p", 51000000, true },
#else
{ "pll_p", NULL, 0, true },
{ "pll_p_out1", "pll_p", 0, false },
{ "sbc1.sclk", NULL, 40000000, false},
{ "sbc2.sclk", NULL, 40000000, false},
{ "sbc3.sclk", NULL, 40000000, false},
- { "sbc4.sclk", NULL, 40000000, false},
- { "sbc5.sclk", NULL, 40000000, false},
- { "sbc6.sclk", NULL, 40000000, false},
+ { "msenc", "pll_p", 108000000, false },
+ { "tsec", "pll_p", 108000000, false },
+ { "mc_capa", "emc", 0, true },
+ { "mc_cbpa", "emc", 0, true },
+#ifdef CONFIG_TEGRA_SOCTHERM
+ { "soc_therm", "pll_p", 51000000, false },
+ { "tsensor", "clk_m", 400000, false },
+#endif
+ { NULL, NULL, 0, 0},
+};
+static __initdata struct tegra_clk_init_table tegra14x_cbus_init_table[] = {
+ /* Initialize c2bus, c3bus, or cbus at the end of the list
+ * after all the clocks are moved under the proper parents.
+ */
#ifdef CONFIG_TEGRA_DUAL_CBUS
- { "c2bus", "pll_c2", 300000000, false },
- { "c3bus", "pll_c3", 300000000, false },
+ { "c2bus", "pll_c2", 200000000, false },
+ { "c3bus", "pll_c3", 200000000, false },
+ { "pll_c", NULL, 768000000, false },
#else
- { "cbus", "pll_c", 416000000, false },
- { "pll_c_out1", "pll_c", 208000000, false },
+ { "cbus", "pll_c", 200000000, false },
#endif
+ { "pll_c_out1", "pll_c", 100000000, false },
{ NULL, NULL, 0, 0},
};
#endif
#ifdef CONFIG_CACHE_L2X0
-#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
static void tegra_cache_smc(bool enable, u32 arg)
{
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PL310_BASE);
tegra_cache_smc(false, l2x0_way_mask);
local_irq_restore(flags);
}
-#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+#endif /* CONFIG_TEGRA_USE_SECURE_KERNEL */
void tegra_init_cache(bool init)
{
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PL310_BASE);
u32 aux_ctrl;
-#ifndef CONFIG_TRUSTED_FOUNDATIONS
+#ifndef CONFIG_TEGRA_USE_SECURE_KERNEL
u32 cache_type;
u32 tag_latency, data_latency;
#endif
-#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
/* issue the SMC to enable the L2 */
aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
trace_smc_init_cache(NVSEC_SMC_START);
#else
#ifdef CONFIG_TEGRA_SILICON_PLATFORM
if (is_lp_cluster()) {
- tag_latency = 0x221;
- data_latency = 0x221;
+ tag_latency = tegra_cpu_c1_l2_tag_latency;
+ data_latency = tegra_cpu_c1_l2_data_latency;
} else {
- u32 speedo;
-
- /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
- speedo = tegra_cpu_speedo_id();
- if (speedo == 4 || speedo == 5 || speedo == 6 ||
- speedo == 12 || speedo == 13) {
- tag_latency = 0x442;
- data_latency = 0x552;
- } else {
- tag_latency = 0x441;
- data_latency = 0x551;
- }
+ tag_latency = tegra_cpu_c0_l2_tag_latency;
+ data_latency = tegra_cpu_c0_l2_data_latency;
}
#else
tag_latency = 0x770;
#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
#ifndef CONFIG_TEGRA_FPGA_PLATFORM
- writel(7, p + L2X0_PREFETCH_CTRL);
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+ /* Enable double line fill */
+ writel(0x40000007, p + L2X0_PREFETCH_CTRL);
+#else
+ writel(0x7, p + L2X0_PREFETCH_CTRL);
+#endif
writel(0x3, p + L2X0_POWER_CTRL);
#endif
#endif
asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r"(reg));
}
-#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
static void __init tegra_ramrepair_init(void)
{
- if (tegra_spare_fuse(10) & tegra_spare_fuse(11) & 1) {
+ if (tegra_spare_fuse(10) | tegra_spare_fuse(11)) {
u32 reg;
reg = readl(FLOW_CTRL_RAM_REPAIR);
reg &= ~FLOW_CTRL_RAM_REPAIR_BYPASS_EN;
val &= ~MST_ID(~0);
val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) |
INACTIVITY_TIMEOUT(0x1000);
+#if !defined(CONFIG_ANDROID)
+ val &= ~USB_MST_ID;
+#endif
ahb_gizmo_writel(val,
IO_ADDRESS(TEGRA_AHB_GIZMO_BASE + AHB_MEM_PREFETCH_CFG2));
val &= ~MST_ID(~0);
val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) |
INACTIVITY_TIMEOUT(0x1000);
+#if !defined(CONFIG_ANDROID)
+ val &= ~USB3_MST_ID;
+#endif
ahb_gizmo_writel(val,
IO_ADDRESS(TEGRA_AHB_GIZMO_BASE + AHB_MEM_PREFETCH_CFG3));
val &= ~MST_ID(~0);
val |= PREFETCH_ENB | SDMMC4_MST_ID | ADDR_BNDRY(0xc) |
INACTIVITY_TIMEOUT(0x1000);
+ val &= ~SDMMC4_MST_ID;
ahb_gizmo_writel(val,
IO_ADDRESS(TEGRA_AHB_GIZMO_BASE + AHB_MEM_PREFETCH_CFG5));
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
void __init tegra30_init_early(void)
{
+ u32 speedo;
+ u32 tag_latency, data_latency;
+
#ifndef CONFIG_SMP
/* For SMP system, initializing the reset handler here is too
late. For non-SMP systems, the function that calls the reset
tegra_apb_io_init();
tegra_perf_init();
tegra_init_fuse();
+ /*
+ * Store G/LP cluster L2 latencies to IRAM and DRAM
+ */
+ tegra_cpu_c1_l2_tag_latency = 0x221;
+ tegra_cpu_c1_l2_data_latency = 0x221;
+ writel_relaxed(0x221, tegra_cpu_c1_l2_tag_latency_iram);
+ writel_relaxed(0x221, tegra_cpu_c1_l2_data_latency_iram);
+ /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
+ speedo = tegra_cpu_speedo_id();
+ if (speedo == 4 || speedo == 5 || speedo == 6 ||
+ speedo == 12 || speedo == 13) {
+ tag_latency = 0x442;
+ data_latency = 0x552;
+ } else {
+ tag_latency = 0x441;
+ data_latency = 0x551;
+ }
+ tegra_cpu_c0_l2_tag_latency = tag_latency;
+ tegra_cpu_c0_l2_data_latency = data_latency;
+ writel_relaxed(tag_latency, tegra_cpu_c0_l2_tag_latency_iram);
+ writel_relaxed(data_latency, tegra_cpu_c0_l2_data_latency_iram);
tegra_init_cache(true);
tegra_pmc_init();
tegra_powergate_init();
tegra11x_init_dvfs();
tegra_common_init_clock();
tegra_clk_init_from_table(tegra11x_clk_init_table);
+ tegra_clk_init_cbus_plls_from_table(tegra11x_cbus_init_table);
tegra11x_clk_init_la();
tegra_pmc_init();
tegra_powergate_init();
+ tegra30_hotplug_init();
tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
tegra_gpio_resume_init();
- init_dma_coherent_pool_size(SZ_1M);
+ init_dma_coherent_pool_size(SZ_2M);
}
#endif
#ifdef CONFIG_ARCH_TEGRA_14x_SOC
handler initializer is not called, so do it here for non-SMP. */
tegra_cpu_reset_handler_init();
#endif
+ tegra_apb_io_init();
+ tegra_perf_init();
tegra_init_fuse();
+ tegra_ramrepair_init();
tegra14x_init_clocks();
tegra14x_init_dvfs();
tegra_common_init_clock();
tegra_clk_init_from_table(tegra14x_clk_init_table);
+ tegra_clk_init_cbus_plls_from_table(tegra14x_cbus_init_table);
+ tegra_cpu_c1_l2_tag_latency = 0x110;
+ tegra_cpu_c1_l2_data_latency = 0x331;
+ writel_relaxed(0x110, tegra_cpu_c1_l2_tag_latency_iram);
+ writel_relaxed(0x331, tegra_cpu_c1_l2_data_latency_iram);
+ tegra_cpu_c0_l2_tag_latency = 0x111;
+ tegra_cpu_c0_l2_data_latency = 0x441;
+ writel_relaxed(0x111, tegra_cpu_c0_l2_tag_latency_iram);
+ writel_relaxed(0x441, tegra_cpu_c0_l2_data_latency_iram);
tegra_init_cache(true);
tegra_pmc_init();
tegra_powergate_init();
+ tegra30_hotplug_init();
tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
tegra_gpio_resume_init();
+ tegra_ram_console_debug_reserve(SZ_1M);
}
#endif
static int __init tegra_lp0_vec_arg(char *options)
}
early_param("tsec", tegra_tsec_arg);
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
+static int __init tegra_tzram_arg(char *options)
+{
+ char *p = options;
+
+ tegra_tzram_size = memparse(p, &p);
+ if (*p == '@')
+ tegra_tzram_start = memparse(p + 1, &p);
+ return 0;
+}
+early_param("tzram", tegra_tzram_arg);
+#endif
+
enum panel_type get_panel_type(void)
{
return board_panel_type;
}
__setup("display_panel=", tegra_board_panel_id);
+int tegra_get_touch_id(void)
+{
+ return touch_id;
+}
+static int __init tegra_touch_id(char *options)
+{
+ char *p = options;
+ touch_id = memparse(p, &p);
+ return touch_id;
+}
+__setup("touch_type=", tegra_touch_id);
+
+
+u8 get_power_config(void)
+{
+ return power_config;
+}
+static int __init tegra_board_power_config(char *options)
+{
+ char *p = options;
+ power_config = memparse(p, &p);
+ return 1;
+}
+__setup("power-config=", tegra_board_power_config);
+
enum power_supply_type get_power_supply_type(void)
{
return pow_supply_type;
for (i = 0; i < size; i += 4)
writel(0, to_io + i);
}
+
+ if (!pdev)
+ goto out;
+
+ dma_map_linear(&pdev->dev, to, size, DMA_TO_DEVICE);
+out:
iounmap(to_io);
}
"2nd Framebuffer: %08lx - %08lx\n"
"Carveout: %08lx - %08lx\n"
"Vpr: %08lx - %08lx\n"
- "Tsec: %08lx - %08lx\n"
- "Baseband Private: %08lx - %08lx\n"
- "Baseband IPC: %08lx - %08lx\n",
+ "Tsec: %08lx - %08lx\n",
tegra_lp0_vec_start,
tegra_lp0_vec_size ?
tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
tegra_vpr_start + tegra_vpr_size - 1 : 0,
tegra_tsec_start,
tegra_tsec_size ?
- tegra_tsec_start + tegra_tsec_size - 1 : 0,
- tegra_bb_ipc_start,
- tegra_bb_ipc_size ?
- tegra_bb_ipc_start + tegra_bb_ipc_size - 1 : 0,
- tegra_bb_priv_start,
- tegra_bb_priv_size ?
- tegra_bb_priv_start + tegra_bb_priv_size - 1 : 0);
+ tegra_tsec_start + tegra_tsec_size - 1 : 0);
if (tegra_avp_kernel_size) {
/* Return excessive memory reserved for AVP kernel */
nvdumper_reserved + NVDUMPER_RESERVED_SIZE - 1);
}
#endif
+
+#ifdef CONFIG_TEGRA_USE_SECURE_KERNEL
+ pr_info("Tzram: %08lx - %08lx\n",
+ tegra_tzram_start,
+ tegra_tzram_size ?
+ tegra_tzram_start + tegra_tzram_size - 1 : 0);
+#endif
}
#ifdef CONFIG_PSTORE_RAM
void __init tegra_release_bootloader_fb(void)
{
/* Since bootloader fb is reserved in common.c, it is freed here. */
- if (tegra_bootloader_fb_size)
+ if (tegra_bootloader_fb_size) {
if (memblock_free(tegra_bootloader_fb_start,
tegra_bootloader_fb_size))
pr_err("Failed to free bootloader fb.\n");
- if (tegra_bootloader_fb2_size)
+ else
+ free_bootmem_late(tegra_bootloader_fb_start,
+ tegra_bootloader_fb_size);
+ }
+ if (tegra_bootloader_fb2_size) {
if (memblock_free(tegra_bootloader_fb2_start,
tegra_bootloader_fb2_size))
pr_err("Failed to free bootloader fb2.\n");
-}
-
-#if defined(CONFIG_TEGRA_BASEBAND)
-void __init tegra_reserve_shmem(unsigned long priv_size, unsigned long ipc_size)
-{
-
- if (ipc_size) {
- tegra_bb_ipc_size = ipc_size;
- tegra_bb_ipc_start = memblock_end_of_DRAM() - ipc_size;
- if (memblock_remove(tegra_bb_ipc_start, ipc_size)) {
- pr_err("Failed to remove carveout %08lx@%08lx\n",
- ipc_size, tegra_bb_ipc_start);
- tegra_bb_ipc_start = 0;
- tegra_bb_ipc_size = 0;
- }
- }
-
- if (priv_size) {
- tegra_bb_priv_size = priv_size;
- tegra_bb_priv_start = memblock_end_of_DRAM() - priv_size;
- if (memblock_remove(tegra_bb_priv_start, priv_size)) {
- pr_err("Failed to remove carveout %08lx@%08lx\n",
- priv_size, tegra_bb_priv_start);
- tegra_bb_priv_start = 0;
- tegra_bb_priv_size = 0;
- }
+ else
+ free_bootmem_late(tegra_bootloader_fb2_start,
+ tegra_bootloader_fb2_size);
}
}
-#endif
static struct platform_device *pinmux_devices[] = {
&tegra_gpio_device,
#endif
tegra_powergate_debugfs_init();
}
+
+#ifdef CONFIG_TEGRA_PRE_SILICON_SUPPORT
+#define ASIM_SHUTDOWN_REG 0x538f0ffc
+
+static void asim_power_off(void)
+{
+ pr_err("ASIM Powering off the device\n");
+ writel(1, IO_ADDRESS(ASIM_SHUTDOWN_REG));
+ while (1)
+ ;
+}
+
+static int __init asim_power_off_init(void)
+{
+ if (tegra_cpu_is_asim())
+ pm_power_off = asim_power_off;
+ return 0;
+}
+
+arch_initcall(asim_power_off_init);
+
+#if defined(CONFIG_SMC91X)
+static struct resource tegra_asim_smc91x_resources[] = {
+ [0] = {
+ .start = TEGRA_SIM_ETH_BASE,
+ .end = TEGRA_SIM_ETH_BASE + TEGRA_SIM_ETH_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ETH,
+ .end = IRQ_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device tegra_asim_smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(tegra_asim_smc91x_resources),
+ .resource = tegra_asim_smc91x_resources,
+};
+
+static int __init asim_enet_init(void)
+{
+ if (tegra_cpu_is_asim())
+ platform_device_register(&tegra_asim_smc91x_device);
+ return 0;
+}
+
+rootfs_initcall(asim_enet_init);
+#endif
+
+#endif