mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-11 05:17:10 +09:00
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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user