#include <linux/highmem.h>
#include <linux/memblock.h>
#include <linux/bitops.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/of.h>
+#include <asm/soc.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <asm/system.h>
+#include <mach/hardware.h>
#include <mach/iomap.h>
#include <mach/powergate.h>
-#include <mach/system.h>
#include <mach/tegra_smmu.h>
+#include <mach/gpio-tegra.h>
#include "apbio.h"
#include "board.h"
#include "pm.h"
#include "reset.h"
#include "devices.h"
+#include "pmc.h"
+#include "common.h"
#define MC_SECURITY_CFG2 0x7c
#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
+unsigned long tegra_avp_kernel_start;
+unsigned long tegra_avp_kernel_size;
unsigned long tegra_bootloader_fb_start;
unsigned long tegra_bootloader_fb_size;
unsigned long tegra_fb_start;
unsigned long tegra_carveout_size;
unsigned long tegra_vpr_start;
unsigned long tegra_vpr_size;
+unsigned long tegra_tsec_start;
+unsigned long tegra_tsec_size;
unsigned long tegra_lp0_vec_start;
unsigned long tegra_lp0_vec_size;
bool tegra_lp0_vec_relocate;
static int board_panel_type;
static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
+u32 tegra_uart_config[3] = {
+ /* Debug UART initialization required */
+ 1,
+ /* Debug UART physical address */
+ (u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+ /* Debug UART virtual address */
+ (u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+};
+
#ifdef CONFIG_OF
static const struct of_device_id tegra_dt_irq_match[] __initconst = {
{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init },
void tegra_assert_system_reset(char mode, const char *cmd)
{
#if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET
- printk("tegra_assert_system_reset() ignored.....");
+ pr_info("tegra_assert_system_reset() ignored.....");
do { } while (1);
#else
void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0);
#endif
}
static int modem_id;
+static int sku_override;
static int debug_uart_port_id;
static enum audio_codec_type audio_codec_name;
+static enum image_type board_image_type = system_image;
static int max_cpu_current;
/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
{ "vi", "pll_c", 0, false },
{ "2d", "pll_c", 0, false },
{ "3d", "pll_c", 0, false },
- { "sbc1.sclk", NULL, 40000000, false},
- { "sbc2.sclk", NULL, 40000000, false},
- { "sbc3.sclk", NULL, 40000000, false},
- { "sbc4.sclk", NULL, 40000000, false},
#else
{ "pll_p", NULL, 216000000, true },
{ "pll_p_out1", "pll_p", 28800000, false },
{ "sclk", "pll_p_out4", 108000000, true },
{ "hclk", "sclk", 108000000, true },
{ "pclk", "hclk", 54000000, true },
+ { "wake.sclk", NULL, 250000000, true },
#endif
+ { "sbc1.sclk", NULL, 40000000, false},
+ { "sbc2.sclk", NULL, 40000000, false},
+ { "sbc3.sclk", NULL, 40000000, false},
+ { "sbc4.sclk", NULL, 40000000, false},
#ifdef CONFIG_TEGRA_SLOW_CSITE
{ "csite", "clk_m", 1000000, true },
#else
static __initdata struct tegra_clk_init_table tegra30_clk_init_table[] = {
/* name parent rate enabled */
{ "clk_m", NULL, 0, true },
+ { "emc", NULL, 0, true },
+ { "cpu", NULL, 0, true },
+ { "kfuse", NULL, 0, true },
+ { "fuse", NULL, 0, true },
#ifdef CONFIG_TEGRA_SILICON_PLATFORM
{ "pll_p", NULL, 0, true },
{ "pll_p_out1", "pll_p", 0, false },
{ "sclk", "pll_p_out4", 102000000, true },
{ "hclk", "sclk", 102000000, true },
{ "pclk", "hclk", 51000000, true },
- { "sbc5.sclk", NULL, 40000000, false},
- { "sbc6.sclk", NULL, 40000000, false},
- { "sbc1.sclk", NULL, 40000000, false},
- { "sbc2.sclk", NULL, 40000000, false},
- { "sbc3.sclk", NULL, 40000000, false},
- { "sbc4.sclk", NULL, 40000000, false},
#else
{ "pll_p", NULL, 216000000, true },
{ "pll_p_out1", "pll_p", 28800000, false },
{ "pll_p_out2", "pll_p", 48000000, false },
{ "pll_p_out3", "pll_p", 72000000, true },
{ "pll_m_out1", "pll_m", 275000000, true },
- { "pll_c", NULL, ULONG_MAX, false },
- { "pll_c_out1", "pll_c", 208000000, false },
{ "pll_p_out4", "pll_p", 108000000, false },
{ "sclk", "pll_p_out4", 108000000, true },
{ "hclk", "sclk", 108000000, true },
{ "pclk", "hclk", 54000000, true },
#endif
#ifdef CONFIG_TEGRA_SLOW_CSITE
- { "csite", "clk_m", 1000000, true },
+ { "csite", "clk_m", 1000000, true },
#else
{ "csite", NULL, 0, true },
#endif
+ { "pll_u", NULL, 480000000, false },
+ { "sdmmc1", "pll_p", 48000000, false},
+ { "sdmmc3", "pll_p", 48000000, false},
+ { "sdmmc4", "pll_p", 48000000, 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},
+ { "wake.sclk", NULL, 40000000, true },
+ { "cbus", "pll_c", 416000000, false },
+ { "pll_c_out1", "pll_c", 208000000, false },
+ { "mselect", "pll_p", 102000000, true },
+ { NULL, NULL, 0, 0},
+};
+#endif
+#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+static __initdata struct tegra_clk_init_table tegra11x_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "clk_m", NULL, 0, true },
{ "emc", NULL, 0, true },
{ "cpu", NULL, 0, true },
{ "kfuse", NULL, 0, true },
{ "fuse", NULL, 0, true },
+ { "sclk", NULL, 0, true },
+ { "pll_p", NULL, 0, true },
+ { "pll_p_out1", "pll_p", 0, false },
+ { "pll_p_out3", "pll_p", 0, true },
+#ifdef CONFIG_TEGRA_SILICON_PLATFORM
+ { "pll_m_out1", "pll_m", 275000000, false },
+ { "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 },
+ { "wake.sclk", NULL, 40000000, 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 },
+#else
+ { "pll_m_out1", "pll_m", 275000000, true },
+ { "pll_p_out2", "pll_p", 108000000, false },
+ { "sclk", "pll_p_out2", 108000000, true },
+ { "pll_p_out4", "pll_p", 216000000, true },
+ { "hclk", "sclk", 108000000, true },
+ { "pclk", "hclk", 54000000, true },
+ { "wake.sclk", NULL, 250000000, true },
+ { "mselect", "pll_p", 108000000, true },
+ { "host1x", "pll_p", 108000000, false },
+ { "cl_dvfs_ref", "clk_m", 13000000, false },
+ { "cl_dvfs_soc", "clk_m", 13000000, false },
+#endif
+#ifdef CONFIG_TEGRA_SLOW_CSITE
+ { "csite", "clk_m", 1000000, true },
+#else
+ { "csite", NULL, 0, true },
+#endif
{ "pll_u", NULL, 480000000, false },
{ "sdmmc1", "pll_p", 48000000, false},
{ "sdmmc3", "pll_p", 48000000, false},
{ "sdmmc4", "pll_p", 48000000, false},
- { "pll_a", "pll_p_out1", 0, false},
- { "pll_a_out0", "pll_a", 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},
+#ifdef CONFIG_TEGRA_DUAL_CBUS
+ { "c2bus", "pll_c2", 300000000, false },
+ { "c3bus", "pll_c3", 300000000, false },
+#else
{ "cbus", "pll_c", 416000000, false },
{ "pll_c_out1", "pll_c", 208000000, false },
- { "mselect", "pll_p", 102000000, true },
+#endif
{ NULL, NULL, 0, 0},
};
#endif
+#ifdef CONFIG_CACHE_L2X0
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+static void tegra_cache_smc(bool enable, u32 arg)
+{
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+ bool need_affinity_switch;
+ bool can_switch_affinity;
+ bool l2x0_enabled;
+ cpumask_t local_cpu_mask;
+ cpumask_t saved_cpu_mask;
+ unsigned long flags;
+ long ret;
+
+ /*
+ * ISSUE : Some registers of PL310 controler must be written
+ * from Secure context (and from CPU0)!
+ *
+ * When called form Normal we obtain an abort or do nothing.
+ * Instructions that must be called in Secure:
+ * - Write to Control register (L2X0_CTRL==0x100)
+ * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
+ * - Invalidate all entries (L2X0_INV_WAY==0x77C),
+ * mandatory at boot time.
+ * - Tag and Data RAM Latency Control Registers
+ * (0x108 & 0x10C) must be written in Secure.
+ */
+ need_affinity_switch = (smp_processor_id() != 0);
+ can_switch_affinity = !irqs_disabled();
+
+ WARN_ON(need_affinity_switch && !can_switch_affinity);
+ if (need_affinity_switch && can_switch_affinity) {
+ cpu_set(0, local_cpu_mask);
+ sched_getaffinity(0, &saved_cpu_mask);
+ ret = sched_setaffinity(0, &local_cpu_mask);
+ WARN_ON(ret != 0);
+ }
+
+ local_irq_save(flags);
+ l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
+ if (enable && !l2x0_enabled)
+ tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
+ else if (!enable && l2x0_enabled)
+ tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
+ local_irq_restore(flags);
+
+ if (need_affinity_switch && can_switch_affinity) {
+ ret = sched_setaffinity(0, &saved_cpu_mask);
+ WARN_ON(ret != 0);
+ }
+}
+
+static void tegra_l2x0_disable(void)
+{
+ unsigned long flags;
+ static u32 l2x0_way_mask;
+
+ if (!l2x0_way_mask) {
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+ u32 aux_ctrl;
+ u32 ways;
+
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
+ l2x0_way_mask = (1 << ways) - 1;
+ }
+
+ local_irq_save(flags);
+ tegra_cache_smc(false, l2x0_way_mask);
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
void tegra_init_cache(bool init)
{
-#ifdef CONFIG_CACHE_L2X0
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
- u32 aux_ctrl, cache_type;
+ u32 aux_ctrl;
+#ifndef CONFIG_TRUSTED_FOUNDATIONS
+ u32 cache_type;
u32 tag_latency, data_latency;
- u32 speedo;
- u32 tmp;
+#endif
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+ /* issue the SMC to enable the L2 */
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ tegra_cache_smc(true, aux_ctrl);
+
+ /* after init, reread aux_ctrl and register handlers */
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
+
+ /* override outer_disable() with our disable */
+ outer_cache.disable = tegra_l2x0_disable;
+#else
#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
tag_latency = 0x331;
data_latency = 0x441;
tag_latency = 0x221;
data_latency = 0x221;
} 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 ||
#ifndef CONFIG_TEGRA_FPGA_PLATFORM
writel(7, p + L2X0_PREFETCH_CTRL);
writel(2, p + L2X0_POWER_CTRL);
-#endif
+#endif
#endif
+ writel(0x3, p + L2X0_POWER_CTRL);
cache_type = readl(p + L2X0_CACHE_TYPE);
aux_ctrl = (cache_type & 0x700) << (17-8);
aux_ctrl |= 0x7C400001;
if (init) {
l2x0_init(p, aux_ctrl, 0x8200c3fe);
} else {
+ u32 tmp;
+
tmp = aux_ctrl;
aux_ctrl = readl(p + L2X0_AUX_CTRL);
aux_ctrl &= 0x8200c3fe;
aux_ctrl |= tmp;
writel(aux_ctrl, p + L2X0_AUX_CTRL);
}
+ l2x0_enable();
#endif
}
+#endif
static void __init tegra_init_power(void)
{
#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
- tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
+ tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
#endif
#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
val &= ~MST_ID(~0);
- val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
+ val |= PREFETCH_ENB | AHBDMA_MST_ID |
+ ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
val &= ~MST_ID(~0);
- val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
+ val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) |
+ INACTIVITY_TIMEOUT(0x1000);
gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
val &= ~MST_ID(~0);
- val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
+ val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) |
+ INACTIVITY_TIMEOUT(0x1000);
gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
val &= ~MST_ID(~0);
- val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
+ val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) |
+ INACTIVITY_TIMEOUT(0x1000);
gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
}
tegra2_init_dvfs();
tegra_common_init_clock();
tegra_clk_init_from_table(tegra20_clk_init_table);
- tegra_init_power();
tegra_init_cache(true);
+ tegra_pmc_init();
+ tegra_powergate_init();
+ tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
+ tegra_gpio_resume_init();
}
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
tegra_cpu_reset_handler_init();
#endif
tegra_init_fuse();
- tegra3_init_clocks();
+ tegra30_init_clocks();
tegra3_init_dvfs();
tegra_common_init_clock();
tegra_clk_init_from_table(tegra30_clk_init_table);
+ tegra_init_cache(true);
+ tegra_pmc_init();
+ tegra_powergate_init();
tegra_init_power();
+ tegra_init_ahb_gizmo_settings();
+ tegra_init_debug_uart_rate();
+ tegra_gpio_resume_init();
+}
+#endif
+#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+void __init tegra11x_init_early(void)
+{
+#ifndef CONFIG_SMP
+ /* For SMP system, initializing the reset handler here is too
+ late. For non-SMP systems, the function that calls the reset
+ handler initializer is not called, so do it here for non-SMP. */
+ tegra_cpu_reset_handler_init();
+#endif
+ tegra_init_fuse();
+ tegra11x_init_clocks();
+ tegra11x_init_dvfs();
+ tegra_common_init_clock();
+ tegra_clk_init_from_table(tegra11x_clk_init_table);
+ tegra11x_clk_init_la();
tegra_init_cache(true);
+ tegra_pmc_init();
+ tegra_powergate_init();
+ tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
+ tegra_gpio_resume_init();
}
#endif
-
static int __init tegra_lp0_vec_arg(char *options)
{
char *p = options;
}
early_param("tegra_fbmem", tegra_bootloader_fb_arg);
+static int __init tegra_sku_override(char *id)
+{
+ char *p = id;
+
+ sku_override = memparse(p, &p);
+
+ return 0;
+}
+early_param("sku_override", tegra_sku_override);
+
+int tegra_get_sku_override(void)
+{
+ return sku_override;
+}
+
static int __init tegra_vpr_arg(char *options)
{
char *p = options;
}
early_param("vpr", tegra_vpr_arg);
+static int __init tegra_tsec_arg(char *options)
+{
+ char *p = options;
+
+ tegra_tsec_size = memparse(p, &p);
+ if (*p == '@')
+ tegra_tsec_start = memparse(p+1, &p);
+ pr_info("Found tsec, start=0x%lx size=%lx",
+ tegra_tsec_start, tegra_tsec_size);
+ return 0;
+}
+early_param("tsec", tegra_tsec_arg);
+
enum panel_type get_panel_type(void)
{
return board_panel_type;
}
__setup("debug_uartport=", tegra_debug_uartport);
+static int __init tegra_image_type(char *options)
+{
+ if (!strcmp(options, "RCK"))
+ board_image_type = rck_image;
+
+ return 0;
+}
+
+enum image_type get_tegra_image_type(void)
+{
+ return board_image_type;
+}
+
+__setup("image=", tegra_image_type);
+
static int __init tegra_audio_codec_type(char *info)
{
char *p = info;
void tegra_get_board_info(struct board_info *bi)
{
- bi->board_id = (system_serial_high >> 16) & 0xFFFF;
- bi->sku = (system_serial_high) & 0xFFFF;
- bi->fab = (system_serial_low >> 24) & 0xFF;
- bi->major_revision = (system_serial_low >> 16) & 0xFF;
- bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+ struct device_node *board_info;
+ u32 prop_val;
+ int err;
+
+ board_info = of_find_node_by_path("/chosen/board_info");
+ if (!IS_ERR_OR_NULL(board_info)) {
+ memset(bi, 0, sizeof(*bi));
+
+ err = of_property_read_u32(board_info, "id", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/id\n");
+ else
+ bi->board_id = prop_val;
+
+ err = of_property_read_u32(board_info, "sku", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/sku\n");
+ else
+ bi->sku = prop_val;
+
+ err = of_property_read_u32(board_info, "fab", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/fab\n");
+ else
+ bi->fab = prop_val;
+
+ err = of_property_read_u32(board_info, "major_revision", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/major_revision\n");
+ else
+ bi->major_revision = prop_val;
+
+ err = of_property_read_u32(board_info, "minor_revision", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/minor_revision\n");
+ else
+ bi->minor_revision = prop_val;
+ } else {
+#endif
+ bi->board_id = (system_serial_high >> 16) & 0xFFFF;
+ bi->sku = (system_serial_high) & 0xFFFF;
+ bi->fab = (system_serial_low >> 24) & 0xFF;
+ bi->major_revision = (system_serial_low >> 16) & 0xFF;
+ bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+ }
+#endif
}
static int __init tegra_pmu_board_info(char *info)
__setup("modem_id=", tegra_modem_id);
-
-
/*
* Tegra has a protected aperture that prevents access by most non-CPU
* memory masters to addresses above the aperture value. Enabling it
iounmap(to_io);
}
-#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
-#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
-#else
-#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
-#endif
-#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
- (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
-/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
- * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
- * do not need to reserve memory.
- */
-#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
-#endif
-
void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
unsigned long fb2_size)
{
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- int smmu_reserved = 0;
- struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
+ const size_t avp_kernel_reserve = SZ_32M;
+#if !defined(CONFIG_TEGRA_AVP_KERNEL_ON_MMU) /* Tegra2 with AVP MMU */ && \
+ !defined(CONFIG_TEGRA_AVP_KERNEL_ON_SMMU) /* Tegra3 & up with SMMU */
+ /* Reserve hardcoded AVP kernel load area starting at 0xXe000000*/
+ tegra_avp_kernel_size = SZ_1M;
+ tegra_avp_kernel_start = memblock_end_of_DRAM() - avp_kernel_reserve;
+ if (memblock_remove(tegra_avp_kernel_start, avp_kernel_reserve)) {
+ pr_err("Failed to remove AVP kernel load area %08lx@%08lx "
+ "from memory map\n",
+ (unsigned long)avp_kernel_reserve,
+ tegra_avp_kernel_start);
+ tegra_avp_kernel_size = 0;
+ }
#endif
if (carveout_size) {
if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
tegra_grhost_aperture = tegra_carveout_start;
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- if (!smmu_window) {
- pr_err("No SMMU resource\n");
- } else {
- size_t smmu_window_size;
-
- if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
- (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
- tegra_get_revision() == TEGRA_REVISION_A01)) {
- smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
- smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
- TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
- }
- smmu_window_size = smmu_window->end + 1 - smmu_window->start;
- if (smmu_window->start >= 0x80000000) {
- if (memblock_reserve(smmu_window->start,
- smmu_window_size))
- pr_err(
- "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
- (unsigned long)smmu_window_size,
- (unsigned long)smmu_window->start);
- else
- smmu_reserved = 1;
- }
- }
-#endif
-
if (tegra_lp0_vec_size &&
(tegra_lp0_vec_start < memblock_end_of_DRAM())) {
if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
"Framebuffer: %08lx - %08lx\n"
"2nd Framebuffer: %08lx - %08lx\n"
"Carveout: %08lx - %08lx\n"
- "Vpr: %08lx - %08lx\n",
+ "Vpr: %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_bootloader_fb_start,
tegra_bootloader_fb_size ?
- tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0,
+ tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1
+ : 0,
tegra_fb_start,
tegra_fb_size ?
tegra_fb_start + tegra_fb_size - 1 : 0,
tegra_carveout_start + tegra_carveout_size - 1 : 0,
tegra_vpr_start,
tegra_vpr_size ?
- tegra_vpr_start + tegra_vpr_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);
+
+ if (tegra_avp_kernel_size) {
+ /* Return excessive memory reserved for AVP kernel */
+ if (tegra_avp_kernel_size < avp_kernel_reserve)
+ memblock_add(
+ tegra_avp_kernel_start + tegra_avp_kernel_size,
+ avp_kernel_reserve - tegra_avp_kernel_size);
+ pr_info(
+ "AVP kernel: %08lx - %08lx\n",
+ tegra_avp_kernel_start,
+ tegra_avp_kernel_start + tegra_avp_kernel_size - 1);
+ }
+}
-#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
- if (smmu_reserved)
- pr_info("SMMU: %08lx - %08lx\n",
- smmu_window->start, smmu_window->end);
-#endif
+static struct resource ram_console_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resources),
+ .resource = ram_console_resources,
+};
+
+void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
+{
+ struct resource *res;
+ long ret;
+
+ res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
+ if (!res)
+ goto fail;
+ res->start = memblock_end_of_DRAM() - ram_console_size;
+ res->end = res->start + ram_console_size - 1;
+ ret = memblock_remove(res->start, ram_console_size);
+ if (ret)
+ goto fail;
+
+ return;
+
+fail:
+ ram_console_device.resource = NULL;
+ ram_console_device.num_resources = 0;
+ pr_err("Failed to reserve memory block for ram console\n");
+}
+
+void __init tegra_ram_console_debug_init(void)
+{
+ int err;
+
+ err = platform_device_register(&ram_console_device);
+ if (err)
+ pr_err("%s: ram console registration failed (%d)!\n",
+ __func__, err);
}
void __init tegra_release_bootloader_fb(void)
tegra_bootloader_fb_size))
pr_err("Failed to free bootloader fb.\n");
}
+
+static struct platform_device *pinmux_devices[] = {
+ &tegra_gpio_device,
+ &tegra_pinmux_device,
+};
+
+void tegra_enable_pinmux(void)
+{
+ platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
+}
+
+struct arm_soc_desc tegra_soc_desc __initdata = {
+ .name = "NVIDIA Tegra",
+ soc_smp_init_ops(tegra_soc_smp_init_ops)
+ soc_smp_ops(tegra_soc_smp_ops)
+};