ARM: tegra: suspend: Fix compile issues with CONFIG_SMP=n

Move suspend pagetable creation to suspend.c
Always compile headsmp-t2.S, it's needed for LP2 resume

Change-Id: I9e23c6bf72fff3e98e0549edf1f85bec823a3a38
Signed-off-by: Colin Cross <ccross@android.com>
This commit is contained in:
Colin Cross
2010-10-23 15:01:35 -07:00
parent 1d583e43c3
commit 1c83ad292d
5 changed files with 87 additions and 75 deletions

View File

@@ -24,10 +24,9 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_save.o
obj-$(CONFIG_CPU_V7) += cortex-a9.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-t2-tables.o
ifeq ($(CONFIG_SMP),y)
obj-y += platsmp.o localtimer.o
obj-$(CONFIG_SMP) += localtimer.o
obj-$(CONFIG_SMP) += platsmp.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += headsmp-t2.o
endif
obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o

View File

@@ -48,6 +48,7 @@
str \val, [\tmp]
.endm
#ifdef CONFIG_SMP
/*
* tegra_secondary_startup
*
@@ -62,6 +63,7 @@ ENTRY(tegra_secondary_startup)
poke_ev r0, r1
b secondary_startup
ENDPROC(tegra_secondary_startup)
#endif
/*
* __restart_pllx
@@ -194,4 +196,4 @@ __tegra_hotplug_data:
.long tegra_pgd_phys
.long __cortex_a9_restore
.size __tegra_hotplug_data, . - __tegra_hotplug_data
#endif
#endif

View File

@@ -33,7 +33,6 @@
#include <asm/smp_scu.h>
#include <asm/cpu.h>
#include <asm/mmu_context.h>
#include <asm/pgalloc.h>
#include <mach/iomap.h>
@@ -43,8 +42,6 @@ extern void tegra_secondary_startup(void);
static DEFINE_SPINLOCK(boot_lock);
static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
extern void __cortex_a9_restore(void);
extern void __shut_off_mmu(void);
#ifdef CONFIG_HOTPLUG_CPU
static DEFINE_PER_CPU(struct completion, cpu_killed);
@@ -64,10 +61,6 @@ const struct cpumask *const cpu_init_mask = to_cpumask(cpu_init_bits);
#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
(IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
unsigned long tegra_pgd_phys; /* pgd used by hotplug & LP2 bootup */
static pgd_t *tegra_pgd;
void *tegra_context_area = NULL;
void __cpuinit platform_secondary_init(unsigned int cpu)
{
trace_hardirqs_off();
@@ -150,61 +143,6 @@ void __init smp_init_cpus(void)
cpu_set(i, cpu_possible_map);
}
static int create_suspend_pgtable(void)
{
int i;
pmd_t *pmd;
/* arrays of virtual-to-physical mappings which must be
* present to safely boot hotplugged / LP2-idled CPUs.
* tegra_hotplug_startup (hotplug reset vector) is mapped
* VA=PA so that the translation post-MMU is the same as
* pre-MMU, IRAM is mapped VA=PA so that SDRAM self-refresh
* can safely disable the MMU */
unsigned long addr_v[] = {
PHYS_OFFSET,
IO_IRAM_PHYS,
(unsigned long)tegra_context_area,
(unsigned long)virt_to_phys(tegra_hotplug_startup),
(unsigned long)__cortex_a9_restore,
(unsigned long)virt_to_phys(__shut_off_mmu),
};
unsigned long addr_p[] = {
PHYS_OFFSET,
IO_IRAM_PHYS,
(unsigned long)virt_to_phys(tegra_context_area),
(unsigned long)virt_to_phys(tegra_hotplug_startup),
(unsigned long)virt_to_phys(__cortex_a9_restore),
(unsigned long)virt_to_phys(__shut_off_mmu),
};
unsigned int flags = PMD_TYPE_SECT | PMD_SECT_AP_WRITE |
PMD_SECT_WBWA | PMD_SECT_S;
tegra_pgd = pgd_alloc(&init_mm);
if (!tegra_pgd)
return -ENOMEM;
for (i=0; i<ARRAY_SIZE(addr_p); i++) {
unsigned long v = addr_v[i];
pmd = pmd_offset(tegra_pgd + pgd_index(v), v);
*pmd = __pmd((addr_p[i] & PGDIR_MASK) | flags);
flush_pmd_entry(pmd);
outer_clean_range(__pa(pmd), __pa(pmd + 1));
}
tegra_pgd_phys = virt_to_phys(tegra_pgd);
__cpuc_flush_dcache_area(&tegra_pgd_phys,
sizeof(tegra_pgd_phys));
outer_clean_range(__pa(&tegra_pgd_phys),
__pa(&tegra_pgd_phys+1));
__cpuc_flush_dcache_area(&tegra_context_area,
sizeof(tegra_context_area));
outer_clean_range(__pa(&tegra_context_area),
__pa(&tegra_context_area+1));
return 0;
}
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int ncores = scu_get_core_count(scu_base);
@@ -219,13 +157,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
if (max_cpus > ncores)
max_cpus = ncores;
tegra_context_area = kzalloc(CONTEXT_SIZE_BYTES * ncores, GFP_KERNEL);
if (tegra_context_area && create_suspend_pgtable()) {
kfree(tegra_context_area);
tegra_context_area = NULL;
}
/*
* Initialise the present map, which describes the set of CPUs
* actually populated at the present time.

View File

@@ -47,9 +47,13 @@
#define TEGRA_IRAM_CODE_SIZE SZ_4K
#ifndef __ASSEMBLY__
extern void *tegra_context_area;
void tegra_lp2_set_trigger(unsigned long cycles);
unsigned long tegra_lp2_timer_remain(void);
void __cortex_a9_save(unsigned int mode);
void __cortex_a9_restore(void);
void __shut_off_mmu(void);
void tegra_lp2_startup(void);
unsigned int tegra_suspend_lp2(unsigned int us);
void tegra_hotplug_startup(void);

View File

@@ -41,6 +41,7 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/hardware/gic.h>
#include <asm/localtimer.h>
#include <asm/pgalloc.h>
#include <asm/tlbflush.h>
#include <mach/iomap.h>
@@ -68,13 +69,11 @@ struct suspend_context
volatile struct suspend_context tegra_sctx;
#ifdef CONFIG_HOTPLUG_CPU
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
static void __iomem *flow_ctrl = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE);
static void __iomem *evp_reset = IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE)+0x100;
static void __iomem *tmrus = IO_ADDRESS(TEGRA_TMRUS_BASE);
#endif
#define PMC_CTRL 0x0
#define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
@@ -112,6 +111,10 @@ static void __iomem *tmrus = IO_ADDRESS(TEGRA_TMRUS_BASE);
#define FLOW_CTRL_CPU_CSR 0x8
#define FLOW_CTRL_CPU1_CSR 0x18
unsigned long tegra_pgd_phys; /* pgd used by hotplug & LP2 bootup */
static pgd_t *tegra_pgd;
void *tegra_context_area = NULL;
static struct clk *tegra_pclk = NULL;
static const struct tegra_suspend_platform_data *pdata = NULL;
static unsigned long wb0_restore = 0;
@@ -166,6 +169,67 @@ static void set_power_timers(unsigned long us_on, unsigned long us_off,
last_pclk = pclk;
}
static int create_suspend_pgtable(void)
{
int i;
pmd_t *pmd;
/* arrays of virtual-to-physical mappings which must be
* present to safely boot hotplugged / LP2-idled CPUs.
* tegra_hotplug_startup (hotplug reset vector) is mapped
* VA=PA so that the translation post-MMU is the same as
* pre-MMU, IRAM is mapped VA=PA so that SDRAM self-refresh
* can safely disable the MMU */
unsigned long addr_v[] = {
PHYS_OFFSET,
IO_IRAM_PHYS,
(unsigned long)tegra_context_area,
#ifdef CONFIG_HOTPLUG_CPU
(unsigned long)virt_to_phys(tegra_hotplug_startup),
#endif
(unsigned long)__cortex_a9_restore,
(unsigned long)virt_to_phys(__shut_off_mmu),
};
unsigned long addr_p[] = {
PHYS_OFFSET,
IO_IRAM_PHYS,
(unsigned long)virt_to_phys(tegra_context_area),
#ifdef CONFIG_HOTPLUG_CPU
(unsigned long)virt_to_phys(tegra_hotplug_startup),
#endif
(unsigned long)virt_to_phys(__cortex_a9_restore),
(unsigned long)virt_to_phys(__shut_off_mmu),
};
unsigned int flags = PMD_TYPE_SECT | PMD_SECT_AP_WRITE |
PMD_SECT_WBWA | PMD_SECT_S;
tegra_pgd = pgd_alloc(&init_mm);
if (!tegra_pgd)
return -ENOMEM;
for (i=0; i<ARRAY_SIZE(addr_p); i++) {
unsigned long v = addr_v[i];
pmd = pmd_offset(tegra_pgd + pgd_index(v), v);
*pmd = __pmd((addr_p[i] & PGDIR_MASK) | flags);
flush_pmd_entry(pmd);
outer_clean_range(__pa(pmd), __pa(pmd + 1));
}
tegra_pgd_phys = virt_to_phys(tegra_pgd);
__cpuc_flush_dcache_area(&tegra_pgd_phys,
sizeof(tegra_pgd_phys));
outer_clean_range(__pa(&tegra_pgd_phys),
__pa(&tegra_pgd_phys+1));
__cpuc_flush_dcache_area(&tegra_context_area,
sizeof(tegra_context_area));
outer_clean_range(__pa(&tegra_context_area),
__pa(&tegra_context_area+1));
return 0;
}
/*
* suspend_cpu_complex
*
@@ -199,8 +263,10 @@ static noinline void restore_cpu_complex(void)
writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR);
wmb();
#ifdef CONFIG_HAVE_ARM_TWD
writel(tegra_sctx.twd_ctrl, twd_base + 0x8);
writel(tegra_sctx.twd_load, twd_base + 0);
#endif
gic_dist_restore(0);
get_irq_chip(IRQ_LOCALTIMER)->unmask(IRQ_LOCALTIMER);
@@ -224,9 +290,11 @@ static noinline void suspend_cpu_complex(void)
tegra_sctx.pllx_misc = readl(clk_rst + CLK_RESET_PLLX_MISC);
tegra_sctx.cclk_divider = readl(clk_rst + CLK_RESET_CCLK_DIVIDER);
#ifdef CONFIG_HAVE_ARM_TWD
tegra_sctx.twd_ctrl = readl(twd_base + 0x8);
tegra_sctx.twd_load = readl(twd_base + 0);
local_timer_stop();
#endif
reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR);
/* clear any pending events, set the WFE bitmap to specify just
@@ -565,6 +633,14 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
plat->suspend_mode = TEGRA_SUSPEND_LP1;
}
tegra_context_area = kzalloc(CONTEXT_SIZE_BYTES * NR_CPUS, GFP_KERNEL);
pr_info("%s: %p\n", __func__, tegra_context_area);
if (tegra_context_area && create_suspend_pgtable()) {
kfree(tegra_context_area);
tegra_context_area = NULL;
}
#ifdef CONFIG_PM
iram_save_size = (unsigned long)__tegra_iram_end;
iram_save_size -= (unsigned long)__tegra_lp1_reset;