#include <linux/pstore_ram.h>
#include <linux/dma-mapping.h>
#include <linux/sys_soc.h>
+#if defined(CONFIG_SMSC911X)
+#include <linux/smsc911x.h>
+#endif
#include <linux/export.h>
#include <linux/bootmem.h>
#include <trace/events/nvsecurity.h>
-#include <asm/hardware/cache-l2x0.h>
+#ifdef CONFIG_ARM64
+#include <linux/irqchip/gic.h>
+#else
#include <asm/system.h>
+#include <asm/hardware/cache-l2x0.h>
+#endif
#include <asm/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/powergate.h>
#include <mach/tegra_smmu.h>
-#include <mach/gpio-tegra.h>
#include <mach/nct.h>
#include "apbio.h"
#define AHB_GIZMO_AHB_MEM 0xc
#define ENB_FAST_REARBITRATE BIT(2)
#define DONT_SPLIT_AHB_WR BIT(7)
+#define WR_WAIT_COMMIT_ON_1K BIT(8)
+#define EN_USB_WAIT_COMMIT_ON_1K_STALL BIT(9)
#define RECOVERY_MODE BIT(31)
#define BOOTLOADER_MODE BIT(30)
#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_bootloader_fb2_start;
-unsigned long tegra_bootloader_fb2_size;
-unsigned long tegra_fb_start;
-unsigned long tegra_fb_size;
-unsigned long tegra_fb2_start;
-unsigned long tegra_fb2_size;
-unsigned long tegra_carveout_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;
+phys_addr_t tegra_avp_kernel_start;
+phys_addr_t tegra_avp_kernel_size;
+phys_addr_t tegra_bootloader_fb_start;
+phys_addr_t tegra_bootloader_fb_size;
+phys_addr_t tegra_bootloader_fb2_start;
+phys_addr_t tegra_bootloader_fb2_size;
+phys_addr_t tegra_fb_start;
+phys_addr_t tegra_fb_size;
+phys_addr_t tegra_fb2_start;
+phys_addr_t tegra_fb2_size;
+phys_addr_t tegra_carveout_start;
+phys_addr_t tegra_carveout_size;
+phys_addr_t tegra_vpr_start;
+phys_addr_t tegra_vpr_size;
+phys_addr_t tegra_tsec_start;
+phys_addr_t tegra_tsec_size;
+phys_addr_t tegra_lp0_vec_start;
+phys_addr_t tegra_lp0_vec_size;
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+phys_addr_t tegra_wb0_params_address;
+phys_addr_t tegra_wb0_params_instances;
+phys_addr_t tegra_wb0_params_block_size;
+#endif
+
#ifdef CONFIG_TEGRA_NVDUMPER
unsigned long nvdumper_reserved;
#endif
static struct board_info display_board_info;
static int panel_id;
static struct board_info camera_board_info;
-static int touch_id;
+static int touch_vendor_id;
+static int touch_panel_id;
static struct board_info io_board_info;
static struct board_info button_board_info;
static struct board_info joystick_board_info;
static int pwr_i2c_clk = 400;
static u8 power_config;
static u8 display_config;
+
+#ifdef CONFIG_TEGRA_SIMULATION_SPLIT_MEM
+static int tegra_split_mem_set;
+#endif
+
/*
* Storage for debug-macro.S's state.
*
#define NEVER_RESET 0
+static DEFINE_SPINLOCK(ahb_lock);
void ahb_gizmo_writel(unsigned long val, void __iomem *reg)
{
/* Read and check if write is successful,
* if val doesn't match with read, retry write.
*/
+ spin_lock(&ahb_lock);
do {
writel(val, reg);
check = readl(reg);
else
pr_err("AHB register access fail for reg\n");
} while (--retry);
+ spin_unlock(&ahb_lock);
}
void tegra_assert_system_reset(char mode, const char *cmd)
{ "host1x", "pll_p", 102000000, false },
{ "cl_dvfs_ref", "pll_p", 51000000, true },
{ "cl_dvfs_soc", "pll_p", 51000000, true },
+ { "dsialp", "pll_p", 70000000, false },
+ { "dsiblp", "pll_p", 70000000, false },
#else
{ "pll_m_out1", "pll_m", 275000000, true },
{ "pll_p_out2", "pll_p", 108000000, false },
{ "csite", NULL, 0, true },
#endif
{ "pll_u", NULL, 480000000, true },
- { "pll_re_vco", NULL, 612000000, true },
+ { "pll_re_vco", NULL, 612000000, false },
{ "xusb_falcon_src", "pll_p", 204000000, false},
{ "xusb_host_src", "pll_p", 102000000, false},
- { "xusb_ss_src", "pll_re_vco", 122400000, false},
- { "xusb_hs_src", "xusb_ss_div2", 61200000, false},
+ { "xusb_ss_src", "pll_u_480M", 120000000, false},
+ { "xusb_hs_src", "pll_u_60M", 60000000, false},
{ "xusb_fs_src", "pll_u_48M", 48000000, false},
{ "sdmmc1", "pll_p", 48000000, false},
{ "sdmmc3", "pll_p", 48000000, false},
{ "sbc4.sclk", NULL, 40000000, false},
{ "sbc5.sclk", NULL, 40000000, false},
{ "sbc6.sclk", NULL, 40000000, false},
+#ifdef CONFIG_TEGRA_DUAL_CBUS
+ { "c2bus", "pll_c2", 250000000, false },
+ { "c3bus", "pll_c3", 250000000, false },
+ { "pll_c", NULL, 624000000, false },
+#else
+ { "cbus", "pll_c", 250000000, false },
+#endif
+ { "pll_c_out1", "pll_c", 150000000, false },
#ifdef CONFIG_TEGRA_PLLM_SCALED
{ "vi", "pll_p", 0, false},
#endif
#ifdef CONFIG_TEGRA_SOCTHERM
- { "soc_therm", "pll_p", 51000000, false },
+ { "soc_therm", "pll_p", 136000000, false },
{ "tsensor", "clk_m", 500000, false },
#endif
+ { "csite", NULL, 0, true },
{ NULL, NULL, 0, 0},
};
static __initdata struct tegra_clk_init_table tegra11x_cbus_init_table[] = {
{ NULL, NULL, 0, 0},
};
#endif
+#ifdef CONFIG_ARCH_TEGRA_12x_SOC
+static __initdata struct tegra_clk_init_table tegra12x_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 },
+#ifdef CONFIG_TEGRA_SILICON_PLATFORM
+ { "pll_p", NULL, 0, true },
+ { "pll_p_out1", "pll_p", 0, false },
+ { "pll_p_out3", "pll_p", 0, true },
+ { "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 },
+ { "host1x", "pll_p", 102000000, false },
+ { "cl_dvfs_ref", "pll_p", 54000000, true },
+ { "cl_dvfs_soc", "pll_p", 54000000, true },
+ { "hclk", "sclk", 102000000, true },
+ { "pclk", "hclk", 51000000, true },
+ { "wake.sclk", NULL, 40000000, true },
+ { "mselect", "pll_p", 102000000, true },
+#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 },
+ { "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, true },
+ { "pll_re_vco", NULL, 612000000, true },
+ { "xusb_falcon_src", "pll_p", 204000000, false},
+ { "xusb_host_src", "pll_p", 102000000, false},
+ { "xusb_ss_src", "pll_re_vco", 122400000, false},
+ { "xusb_hs_src", "xusb_ss_div2", 61200000, false},
+ { "xusb_fs_src", "pll_u_48M", 48000000, 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},
+#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
+#if defined(CONFIG_TEGRA_SIMULATION_PLATFORM)
+ { "vde", "pll_c3", 48400000, true},
+#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 */
{
u32 reg;
+#ifdef CONFIG_ARM64
+ asm volatile("mrs %0, PMCR_EL0" : "=r"(reg));
+ reg >>= 11;
+ reg = (1 << (reg & 0x1f))-1;
+ reg |= 0x80000000;
+ asm volatile("msr PMINTENCLR_EL1, %0" : : "r"(reg));
+ reg = 1;
+ asm volatile("msr PMUSERENR_EL0, %0" : : "r"(reg));
+#else
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(reg));
reg >>= 11;
reg = (1 << (reg & 0x1f))-1;
asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r"(reg));
reg = 1;
asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r"(reg));
+#endif
}
-#if defined(CONFIG_ARCH_TEGRA_11x_SOC) || defined(CONFIG_ARCH_TEGRA_14x_SOC)
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
static void __init tegra_ramrepair_init(void)
{
if (tegra_spare_fuse(10) | tegra_spare_fuse(11)) {
#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
#endif
-#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
+#if defined(CONFIG_ARCH_TEGRA_HAS_PCIE) && \
+ !defined(CONFIG_TEGRA_PCIE_SKIP_POWERGATING)
tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
#endif
#ifdef CONFIG_ARCH_TEGRA_11x_SOC
val = gizmo_readl(AHB_GIZMO_AHB_MEM);
val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
+
+ if (tegra_get_chipid() == TEGRA_CHIPID_TEGRA11 &&
+ tegra_revision == TEGRA_REVISION_A02)
+ val |= WR_WAIT_COMMIT_ON_1K;
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+ val |= WR_WAIT_COMMIT_ON_1K | EN_USB_WAIT_COMMIT_ON_1K_STALL;
+#endif
gizmo_writel(val, AHB_GIZMO_AHB_MEM);
val = gizmo_readl(AHB_GIZMO_USB);
val |= IMMEDIATE;
gizmo_writel(val, AHB_GIZMO_USB3);
-#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
- val = gizmo_readl(AHB_GIZMO_SE);
- val |= IMMEDIATE;
- gizmo_writel(val, AHB_GIZMO_SE);
-#endif
-
-
val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
| AHB_PRIORITY_WEIGHT(7);
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
tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
- tegra_gpio_resume_init();
tegra_ram_console_debug_reserve(SZ_1M);
init_dma_coherent_pool_size(SZ_1M);
tegra_init_power();
tegra_init_ahb_gizmo_settings();
tegra_init_debug_uart_rate();
- tegra_gpio_resume_init();
init_dma_coherent_pool_size(SZ_2M);
}
#endif
+#ifdef CONFIG_ARCH_TEGRA_12x_SOC
+void __init tegra12x_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_apb_io_init();
+ tegra_init_fuse();
+ tegra_ramrepair_init();
+ tegra12x_init_clocks();
+ tegra12x_init_dvfs();
+ tegra_common_init_clock();
+ tegra_clk_init_from_table(tegra12x_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();
+}
+#endif
#ifdef CONFIG_ARCH_TEGRA_14x_SOC
void __init tegra14x_init_early(void)
{
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
}
early_param("lp0_vec", tegra_lp0_vec_arg);
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+static int __init tegra_wb0_params_arg(char *options)
+{
+ char *p = options;
+
+ tegra_wb0_params_address = memparse(p, &p);
+ if (*p == ',')
+ tegra_wb0_params_instances = memparse(p+1, &p);
+ if (*p == ',')
+ tegra_wb0_params_block_size = memparse(p+1, &p);
+
+ return 0;
+}
+early_param("wb0_params", tegra_wb0_params_arg);
+#endif
+
#ifdef CONFIG_TEGRA_NVDUMPER
static int __init tegra_nvdumper_arg(char *options)
{
if (*p == '@')
tegra_bootloader_fb_start = memparse(p+1, &p);
- pr_info("Found tegra_fbmem: %08lx@%08lx\n",
- tegra_bootloader_fb_size, tegra_bootloader_fb_start);
+ pr_info("Found tegra_fbmem: %08llx@%08llx\n",
+ (u64)tegra_bootloader_fb_size, (u64)tegra_bootloader_fb_start);
return 0;
}
if (*p == '@')
tegra_bootloader_fb2_start = memparse(p+1, &p);
- pr_info("Found tegra_fbmem2: %08lx@%08lx\n",
- tegra_bootloader_fb2_size, tegra_bootloader_fb2_start);
+ pr_info("Found tegra_fbmem2: %08llx@%08llx\n",
+ (u64)tegra_bootloader_fb2_size,
+ (u64)tegra_bootloader_fb2_start);
return 0;
}
tegra_vpr_size = memparse(p, &p);
if (*p == '@')
tegra_vpr_start = memparse(p+1, &p);
- pr_info("Found vpr, start=0x%lx size=%lx",
- tegra_vpr_start, tegra_vpr_size);
+ pr_info("Found vpr, start=0x%llx size=%llx",
+ (u64)tegra_vpr_start, (u64)tegra_vpr_size);
return 0;
}
early_param("vpr", tegra_vpr_arg);
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);
+ pr_info("Found tsec, start=0x%llx size=%llx",
+ (u64)tegra_tsec_start, (u64)tegra_tsec_size);
return 0;
}
early_param("tsec", tegra_tsec_arg);
}
__setup("display_panel=", tegra_board_panel_id);
-int tegra_get_touch_id(void)
+int tegra_get_touch_vendor_id(void)
+{
+ return touch_vendor_id;
+}
+int tegra_get_touch_panel_id(void)
{
- return touch_id;
+ return touch_panel_id;
}
static int __init tegra_touch_id(char *options)
{
char *p = options;
- touch_id = memparse(p, &p);
- return touch_id;
+ touch_vendor_id = memparse(p, &p);
+ if (*p == '@')
+ touch_panel_id = memparse(p+1, &p);
+ return 1;
}
-__setup("touch_type=", tegra_touch_id);
-
+__setup("touch_id=", tegra_touch_id);
u8 get_power_config(void)
{
pr_err("failed to read /chosen/board_info/minor_revision\n");
else
bi->minor_revision = prop_val;
+#ifndef CONFIG_ARM64
system_serial_high = (bi->board_id << 16) | bi->sku;
system_serial_low = (bi->fab << 24) |
(bi->major_revision << 16) | (bi->minor_revision << 8);
+#endif
} else {
#endif
+#ifdef CONFIG_ARM64
+ /* FIXME:
+ * use dummy values for now as system_serial_high/low
+ * are gone in arm64.
+ */
+ bi->board_id = 0xDEAD;
+ bi->sku = 0xDEAD;
+ bi->fab = 0xDD;
+ bi->major_revision = 0xDD;
+ bi->minor_revision = 0xDD;
+#else
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;
+#endif
#ifdef CONFIG_OF
}
#endif
* the memory map.
*/
void __tegra_move_framebuffer(struct platform_device *pdev,
- unsigned long to, unsigned long from,
- unsigned long size)
+ phys_addr_t to, phys_addr_t from,
+ size_t size)
{
struct page *page;
void __iomem *to_io;
void *from_virt;
- unsigned long i, addr[] = { to, from, };
+ unsigned long i;
+ phys_addr_t addr[] = { to, from, };
BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to);
BUG_ON(PAGE_ALIGN(from) != from);
return;
}
- if (pfn_valid(page_to_pfn(phys_to_page(from)))) {
+ if (from && pfn_valid(page_to_pfn(phys_to_page(from)))) {
for (i = 0 ; i < size; i += PAGE_SIZE) {
page = phys_to_page(from + i);
from_virt = kmap(page);
memcpy(to_io + i, from_virt, PAGE_SIZE);
kunmap(page);
}
- } else {
+ } else if (from) {
void __iomem *from_io = ioremap(from, size);
if (!from_io) {
pr_err("%s: Failed to map source framebuffer\n",
if (!pdev)
goto out;
+#ifdef CONFIG_ARM64
+ BUG(); /* ARM64 doesn't support dma_map_linear yet!!! */
+#else
for (i = 0; i < ARRAY_SIZE(addr); i++)
dma_map_linear(&pdev->dev, addr[i], size, DMA_TO_DEVICE);
+#endif
out:
iounmap(to_io);
}
if (!pdev)
goto out;
+#ifndef CONFIG_ARM64 /* FIXME */
dma_map_linear(&pdev->dev, to, size, DMA_TO_DEVICE);
+#endif
out:
iounmap(to_io);
}
unsigned long fb2_size)
{
const size_t avp_kernel_reserve = SZ_32M;
+ int i = 0;
#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;
+ tegra_avp_kernel_size = SECTION_SIZE;
+
+ /*
+ * Choose a DRAM region in which to allocate the AVP kernel, using the
+ * following guidelines:
+ * - Choose a DRAM region which exists below the 4 GB physical
+ * address limit. This is necessary because AVP is a 32 bit
+ * processor and it cannot access physical addresses above 4 GB.
+ * - Out of the applicable DRAM regions (i.e. those which exist
+ * below 4 GB), choose the region with the highest starting
+ * physical address.
+ */
+ for (i = memblock.memory.cnt - 1; i >= 0; i--) {
+ if ((u64)(memblock.memory.regions[i].base) +
+ (u64)(memblock.memory.regions[i].size) <
+ (u64)(SZ_2G)*(u64)(2)) {
+ tegra_avp_kernel_start =
+ memblock.memory.regions[i].base +
+ memblock.memory.regions[i].size -
+ avp_kernel_reserve;
+ break;
+ }
+ }
+ /*
+ * If tegra_avp_kernel_start is still 0, that means we didn't find any
+ * DRAM region below the 4 GB physical address limit. This is a problem
+ * because the AVP kernel must reside below 4 GB.
+ */
+ BUG_ON(tegra_avp_kernel_start == 0);
+
if (memblock_remove(tegra_avp_kernel_start, avp_kernel_reserve)) {
- pr_err("Failed to remove AVP kernel load area %08lx@%08lx "
+ pr_err("Failed to remove AVP kernel load area %08lx@%08llx "
"from memory map\n",
(unsigned long)avp_kernel_reserve,
- tegra_avp_kernel_start);
+ (u64)tegra_avp_kernel_start);
tegra_avp_kernel_size = 0;
}
#endif
if (carveout_size) {
tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
if (memblock_remove(tegra_carveout_start, carveout_size)) {
- pr_err("Failed to remove carveout %08lx@%08lx "
+ pr_err("Failed to remove carveout %08lx@%08llx "
"from memory map\n",
- carveout_size, tegra_carveout_start);
+ carveout_size, (u64)tegra_carveout_start);
tegra_carveout_start = 0;
tegra_carveout_size = 0;
} else
tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
if (memblock_remove(tegra_fb2_start, fb2_size)) {
pr_err("Failed to remove second framebuffer "
- "%08lx@%08lx from memory map\n",
- fb2_size, tegra_fb2_start);
+ "%08lx@%08llx from memory map\n",
+ fb2_size, (u64)tegra_fb2_start);
tegra_fb2_start = 0;
tegra_fb2_size = 0;
} else
if (fb_size) {
tegra_fb_start = memblock_end_of_DRAM() - fb_size;
if (memblock_remove(tegra_fb_start, fb_size)) {
- pr_err("Failed to remove framebuffer %08lx@%08lx "
+ pr_err("Failed to remove framebuffer %08lx@%08llx "
"from memory map\n",
- fb_size, tegra_fb_start);
+ fb_size, (u64)tegra_fb_start);
tegra_fb_start = 0;
tegra_fb_size = 0;
} else
tegra_fb_size = fb_size;
}
+#ifdef CONFIG_TEGRA_SIMULATION_SPLIT_MEM
+ if (tegra_split_mem_active()) {
+ tegra_fb_start = TEGRA_ASIM_QT_FB_START;
+ tegra_fb_size = TEGRA_ASIM_QT_FB_SIZE;
+
+ if (tegra_vpr_size == 0) {
+ tegra_carveout_start =
+ TEGRA_ASIM_QT_CARVEOUT_VPR_DISABLED_START;
+ tegra_carveout_size =
+ TEGRA_ASIM_QT_CARVEOUT_VPR_DISABLED_SIZE;
+ } else if (
+ (tegra_vpr_start <
+ TEGRA_ASIM_QT_FB_START +
+ TEGRA_ASIM_QT_FB_SIZE) ||
+ (tegra_vpr_start + tegra_vpr_size - 1 >
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_START +
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_SIZE - 1)) {
+ /*
+ * On ASIM/ASIM + QT with
+ * CONFIG_TEGRA_SIMULATION_SPLIT_MEM enabled, the VPR
+ * region needs to be within the front door memory
+ * region. Moreover, the VPR region can't exist where
+ * the framebuffer resides.
+ */
+ BUG();
+ } else if (
+ (tegra_vpr_start -
+ (TEGRA_ASIM_QT_FB_START +
+ TEGRA_ASIM_QT_FB_SIZE) <
+ TEGRA_ASIM_QT_CARVEOUT_MIN_SIZE) &&
+ (TEGRA_ASIM_QT_FRONT_DOOR_MEM_START +
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_SIZE -
+ (tegra_vpr_start + tegra_vpr_size) <
+ TEGRA_ASIM_QT_CARVEOUT_MIN_SIZE)) {
+ /*
+ * The tegra ASIM/QT carveout has a min size:-
+ * TEGRA_ASIM_QT_CARVEOUT_MIN_SIZE. All free regions in
+ * front door mem are smaller than the min carveout
+ * size. Therefore, we can't fit the carveout in front
+ * door mem.
+ */
+ BUG();
+ } else if (
+ (tegra_vpr_start -
+ (TEGRA_ASIM_QT_FB_START + TEGRA_ASIM_QT_FB_SIZE)) >=
+ (TEGRA_ASIM_QT_FRONT_DOOR_MEM_START +
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_SIZE -
+ (tegra_vpr_start + tegra_vpr_size))) {
+ /*
+ * Place the tegra ASIM/QT carveout between the
+ * framebuffer and VPR.
+ */
+ tegra_carveout_start =
+ TEGRA_ASIM_QT_CARVEOUT_VPR_DISABLED_START;
+ tegra_carveout_size = tegra_vpr_start -
+ (TEGRA_ASIM_QT_FB_START +
+ TEGRA_ASIM_QT_FB_SIZE);
+ } else {
+ /*
+ * Place the tegra ASIM/QT carveout after VPR.
+ */
+ tegra_carveout_start = tegra_vpr_start + tegra_vpr_size;
+ tegra_carveout_size =
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_START +
+ TEGRA_ASIM_QT_FRONT_DOOR_MEM_SIZE -
+ (tegra_vpr_start + tegra_vpr_size);
+ }
+ } else if (tegra_vpr_size != 0) {
+ /*
+ * VPR cannot work on ASIM/ASIM + QT if split mem is not
+ * enabled.
+ */
+ BUG();
+ }
+#endif
+
if (tegra_fb_size)
tegra_grhost_aperture = tegra_fb_start;
if (tegra_lp0_vec_size &&
(tegra_lp0_vec_start < memblock_end_of_DRAM())) {
if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
- pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
- tegra_lp0_vec_size, tegra_lp0_vec_start);
+ pr_err("Failed to reserve lp0_vec %08llx@%08llx\n",
+ (u64)tegra_lp0_vec_size,
+ (u64)tegra_lp0_vec_start);
tegra_lp0_vec_start = 0;
tegra_lp0_vec_size = 0;
}
if (memblock_reserve(tegra_bootloader_fb_start,
tegra_bootloader_fb_size)) {
pr_err("Failed to reserve bootloader frame buffer "
- "%08lx@%08lx\n", tegra_bootloader_fb_size,
- tegra_bootloader_fb_start);
+ "%08llx@%08llx\n",
+ (u64)tegra_bootloader_fb_size,
+ (u64)tegra_bootloader_fb_start);
tegra_bootloader_fb_start = 0;
tegra_bootloader_fb_size = 0;
}
PAGE_ALIGN(tegra_bootloader_fb2_size);
if (memblock_reserve(tegra_bootloader_fb2_start,
tegra_bootloader_fb2_size)) {
- pr_err("Failed to reserve bootloader fb2 %08lx@%08lx\n",
- tegra_bootloader_fb2_size,
- tegra_bootloader_fb2_start);
+ pr_err("Failed to reserve bootloader fb2 %08llx@%08llx\n",
+ (u64)tegra_bootloader_fb2_size,
+ (u64)tegra_bootloader_fb2_start);
tegra_bootloader_fb2_start = 0;
tegra_bootloader_fb2_size = 0;
}
}
pr_info("Tegra reserved memory:\n"
- "LP0: %08lx - %08lx\n"
- "Bootloader framebuffer: %08lx - %08lx\n"
- "Bootloader framebuffer2: %08lx - %08lx\n"
- "Framebuffer: %08lx - %08lx\n"
- "2nd Framebuffer: %08lx - %08lx\n"
- "Carveout: %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_fb2_start,
- tegra_bootloader_fb2_size ?
- tegra_bootloader_fb2_start + tegra_bootloader_fb2_size - 1 : 0,
- tegra_fb_start,
- tegra_fb_size ?
- tegra_fb_start + tegra_fb_size - 1 : 0,
- tegra_fb2_start,
- tegra_fb2_size ?
- tegra_fb2_start + tegra_fb2_size - 1 : 0,
- tegra_carveout_start,
- tegra_carveout_size ?
- tegra_carveout_start + tegra_carveout_size - 1 : 0,
- tegra_vpr_start,
- tegra_vpr_size ?
- tegra_vpr_start + tegra_vpr_size - 1 : 0,
- tegra_tsec_start,
- tegra_tsec_size ?
- tegra_tsec_start + tegra_tsec_size - 1 : 0);
+ "LP0: %08llx - %08llx\n"
+ "Bootloader framebuffer: %08llx - %08llx\n"
+ "Bootloader framebuffer2: %08llx - %08llx\n"
+ "Framebuffer: %08llx - %08llx\n"
+ "2nd Framebuffer: %08llx - %08llx\n"
+ "Carveout: %08llx - %08llx\n"
+ "Vpr: %08llx - %08llx\n"
+ "Tsec: %08llx - %08llx\n",
+ (u64)tegra_lp0_vec_start,
+ (u64)(tegra_lp0_vec_size ?
+ tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0),
+ (u64)tegra_bootloader_fb_start,
+ (u64)(tegra_bootloader_fb_size ?
+ tegra_bootloader_fb_start +
+ tegra_bootloader_fb_size - 1 : 0),
+ (u64)tegra_bootloader_fb2_start,
+ (u64)(tegra_bootloader_fb2_size ?
+ tegra_bootloader_fb2_start +
+ tegra_bootloader_fb2_size - 1 : 0),
+ (u64)tegra_fb_start,
+ (u64)(tegra_fb_size ?
+ tegra_fb_start + tegra_fb_size - 1 : 0),
+ (u64)tegra_fb2_start,
+ (u64)(tegra_fb2_size ?
+ tegra_fb2_start + tegra_fb2_size - 1 : 0),
+ (u64)tegra_carveout_start,
+ (u64)(tegra_carveout_size ?
+ tegra_carveout_start + tegra_carveout_size - 1 : 0),
+ (u64)tegra_vpr_start,
+ (u64)(tegra_vpr_size ?
+ tegra_vpr_start + tegra_vpr_size - 1 : 0),
+ (u64)tegra_tsec_start,
+ (u64)(tegra_tsec_size ?
+ tegra_tsec_start + tegra_tsec_size - 1 : 0));
if (tegra_avp_kernel_size) {
/* Return excessive memory reserved for AVP kernel */
memblock_add(
tegra_avp_kernel_start + tegra_avp_kernel_size,
avp_kernel_reserve - tegra_avp_kernel_size);
+ /* The AVP kernel should be loaded below the 4 GB physical
+ address limit. */
+ BUG_ON((u64)(tegra_avp_kernel_start) +
+ (u64)(tegra_avp_kernel_size) - (u64)(1) >=
+ (u64)(SZ_2G)*(u64)(2));
pr_info(
- "AVP kernel: %08lx - %08lx\n",
- tegra_avp_kernel_start,
- tegra_avp_kernel_start + tegra_avp_kernel_size - 1);
+ "AVP kernel: %08llx - %08llx\n",
+ (u64)tegra_avp_kernel_start,
+ (u64)(tegra_avp_kernel_start +
+ tegra_avp_kernel_size - 1));
}
#ifdef CONFIG_TEGRA_NVDUMPER
.resource = tegra_asim_smc91x_resources,
};
-static int __init asim_enet_init(void)
+static int __init asim_enet_smc91x_init(void)
{
- if (tegra_cpu_is_asim())
+ if (tegra_cpu_is_asim() && !tegra_cpu_is_dsim())
platform_device_register(&tegra_asim_smc91x_device);
return 0;
}
-rootfs_initcall(asim_enet_init);
+rootfs_initcall(asim_enet_smc91x_init);
#endif
+#if defined(CONFIG_SMSC911X)
+static struct resource tegra_smsc911x_resources[] = {
+ [0] = {
+ .start = 0x4E000000,
+ .end = 0x4E000000 + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_ETH,
+ .end = IRQ_ETH,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config tegra_smsc911x_config = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+static struct platform_device tegra_smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .resource = tegra_smsc911x_resources,
+ .num_resources = ARRAY_SIZE(tegra_smsc911x_resources),
+ .dev.platform_data = &tegra_smsc911x_config,
+};
+
+static int __init enet_smsc911x_init(void)
+{
+ if (!tegra_cpu_is_dsim())
+ platform_device_register(&tegra_smsc911x_device);
+ return 0;
+}
+
+rootfs_initcall(enet_smsc911x_init);
+#endif
+
+#ifdef CONFIG_TEGRA_SIMULATION_SPLIT_MEM
+int tegra_split_mem_active(void)
+{
+ return tegra_split_mem_set;
+}
+
+static int __init set_tegra_split_mem(char *options)
+{
+ tegra_split_mem_set = 1;
+ return 0;
+}
+early_param("tegra_split_mem", set_tegra_split_mem);
+#endif
#endif