Skip to content

Commit

Permalink
Merge branch 'pull/v3.18/for-omap-soc' of https://github.com/nmenon/l…
Browse files Browse the repository at this point in the history
…inux-2.6-playground into omap-for-v3.18/soc
  • Loading branch information
Tony Lindgren committed Sep 8, 2014
2 parents d7eb67f + 628ed47 commit 887782e
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 64 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-omap2/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static inline int omap3_pm_init(void)
}
#endif

#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
int omap4_pm_init(void);
int omap4_pm_init_early(void);
#else
Expand Down
3 changes: 3 additions & 0 deletions arch/arm/mach-omap2/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ void __init omap5_init_early(void)
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE));
omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
omap4_pm_init_early();
omap_prm_base_init();
omap_cm_base_init();
omap44xx_prm_init();
Expand All @@ -682,6 +683,8 @@ void __init omap5_init_early(void)
void __init omap5_init_late(void)
{
omap_common_late_init();
omap4_pm_init();
omap2_clk_enable_autoidle_all();
}
#endif

Expand Down
102 changes: 71 additions & 31 deletions arch/arm/mach-omap2/omap-mpuss-lowpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include "omap4-sar-layout.h"
#include "pm.h"
#include "prcm_mpu44xx.h"
#include "prcm_mpu54xx.h"
#include "prminst44xx.h"
#include "prcm44xx.h"
#include "prm44xx.h"
Expand All @@ -68,14 +69,14 @@ struct omap4_cpu_pm_info {
void __iomem *scu_sar_addr;
void __iomem *wkup_sar_addr;
void __iomem *l2x0_sar_addr;
void (*secondary_startup)(void);
};

/**
* struct cpu_pm_ops - CPU pm operations
* @finish_suspend: CPU suspend finisher function pointer
* @resume: CPU resume function pointer
* @scu_prepare: CPU Snoop Control program function pointer
* @hotplug_restart: CPU restart function pointer
*
* Structure holds functions pointer for CPU low power operations like
* suspend, resume and scu programming.
Expand All @@ -84,11 +85,13 @@ struct cpu_pm_ops {
int (*finish_suspend)(unsigned long cpu_state);
void (*resume)(void);
void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
void (*hotplug_restart)(void);
};

static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
static struct powerdomain *mpuss_pd;
static void __iomem *sar_base;
static u32 cpu_context_offset;

static int default_finish_suspend(unsigned long cpu_state)
{
Expand All @@ -106,6 +109,7 @@ struct cpu_pm_ops omap_pm_ops = {
.finish_suspend = default_finish_suspend,
.resume = dummy_cpu_resume,
.scu_prepare = dummy_scu_prepare,
.hotplug_restart = dummy_cpu_resume,
};

/*
Expand All @@ -116,7 +120,8 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
{
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);

writel_relaxed(addr, pm_info->wkup_sar_addr);
if (pm_info->wkup_sar_addr)
writel_relaxed(addr, pm_info->wkup_sar_addr);
}

/*
Expand All @@ -141,7 +146,8 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
break;
}

writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr);
if (pm_info->scu_sar_addr)
writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr);
}

/* Helper functions for MPUSS OSWR */
Expand All @@ -161,14 +167,14 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)

if (cpu_id) {
reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
cpu_context_offset);
omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
cpu_context_offset);
} else {
reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
cpu_context_offset);
omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
cpu_context_offset);
}
}

Expand All @@ -179,7 +185,8 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
{
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);

writel_relaxed(save_state, pm_info->l2x0_sar_addr);
if (pm_info->l2x0_sar_addr)
writel_relaxed(save_state, pm_info->l2x0_sar_addr);
}

/*
Expand All @@ -189,10 +196,14 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
#ifdef CONFIG_CACHE_L2X0
static void __init save_l2x0_context(void)
{
writel_relaxed(l2x0_saved_regs.aux_ctrl,
sar_base + L2X0_AUXCTRL_OFFSET);
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
sar_base + L2X0_PREFETCH_CTRL_OFFSET);
void __iomem *l2x0_base = omap4_get_l2cache_base();

if (l2x0_base && sar_base) {
writel_relaxed(l2x0_saved_regs.aux_ctrl,
sar_base + L2X0_AUXCTRL_OFFSET);
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
sar_base + L2X0_PREFETCH_CTRL_OFFSET);
}
}
#else
static void __init save_l2x0_context(void)
Expand Down Expand Up @@ -231,6 +242,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
save_state = 1;
break;
case PWRDM_POWER_RET:
if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
save_state = 0;
break;
}
default:
/*
* CPUx CSWR is invalid hardware state. Also CPUx OSWR
Expand Down Expand Up @@ -307,7 +322,7 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)

pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
omap_pm_ops.scu_prepare(cpu, power_state);

/*
Expand All @@ -322,6 +337,21 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
}


/*
* Enable Mercury Fast HG retention mode by default.
*/
static void enable_mercury_retention_mode(void)
{
u32 reg;

reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
/* Enable HG_EN, HG_RAMPUP = fast mode */
reg |= BIT(24) | BIT(25);
omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
}

/*
* Initialise OMAP4 MPUSS
*/
Expand All @@ -334,13 +364,17 @@ int __init omap4_mpuss_init(void)
return -ENODEV;
}

sar_base = omap4_get_sar_ram_base();
if (cpu_is_omap44xx())
sar_base = omap4_get_sar_ram_base();

/* Initilaise per CPU PM information */
pm_info = &per_cpu(omap4_pm_info, 0x0);
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
if (sar_base) {
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
pm_info->wkup_sar_addr = sar_base +
CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
}
pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
if (!pm_info->pwrdm) {
pr_err("Lookup failed for CPU0 pwrdm\n");
Expand All @@ -355,13 +389,12 @@ int __init omap4_mpuss_init(void)
pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);

pm_info = &per_cpu(omap4_pm_info, 0x1);
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
if (cpu_is_omap446x())
pm_info->secondary_startup = omap4460_secondary_startup;
else
pm_info->secondary_startup = omap4_secondary_startup;
if (sar_base) {
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
pm_info->wkup_sar_addr = sar_base +
CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
}

pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
if (!pm_info->pwrdm) {
Expand All @@ -384,20 +417,27 @@ int __init omap4_mpuss_init(void)
pwrdm_clear_all_prev_pwrst(mpuss_pd);
mpuss_clear_prev_logic_pwrst();

/* Save device type on scratchpad for low level code to use */
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
writel_relaxed(1, sar_base + OMAP_TYPE_OFFSET);
else
writel_relaxed(0, sar_base + OMAP_TYPE_OFFSET);

save_l2x0_context();
if (sar_base) {
/* Save device type on scratchpad for low level code to use */
writel_relaxed((omap_type() != OMAP2_DEVICE_TYPE_GP) ? 1 : 0,
sar_base + OMAP_TYPE_OFFSET);
save_l2x0_context();
}

if (cpu_is_omap44xx()) {
omap_pm_ops.finish_suspend = omap4_finish_suspend;
omap_pm_ops.resume = omap4_cpu_resume;
omap_pm_ops.scu_prepare = scu_pwrst_prepare;
omap_pm_ops.hotplug_restart = omap4_secondary_startup;
cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
enable_mercury_retention_mode();
}

if (cpu_is_omap446x())
omap_pm_ops.hotplug_restart = omap4460_secondary_startup;

return 0;
}

Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-omap2/omap-secure.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113

#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109
#define OMAP5_MON_AMBA_IF_INDEX 0x108

/* Secure PPA(Primary Protected Application) APIs */
#define OMAP4_PPA_L2_POR_INDEX 0x23
Expand Down
20 changes: 19 additions & 1 deletion arch/arm/mach-omap2/omap-wakeupgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "soc.h"
#include "omap4-sar-layout.h"
#include "common.h"
#include "pm.h"

#define AM43XX_NR_REG_BANKS 7
#define AM43XX_IRQS 224
Expand Down Expand Up @@ -381,7 +382,7 @@ static struct notifier_block irq_notifier_block = {
static void __init irq_pm_init(void)
{
/* FIXME: Remove this when MPU OSWR support is added */
if (!soc_is_omap54xx())
if (!IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
cpu_pm_register_notifier(&irq_notifier_block);
}
#else
Expand All @@ -406,6 +407,7 @@ int __init omap_wakeupgen_init(void)
{
int i;
unsigned int boot_cpu = smp_processor_id();
u32 val;

/* Not supported on OMAP4 ES1.0 silicon */
if (omap_rev() == OMAP4430_REV_ES1_0) {
Expand Down Expand Up @@ -451,6 +453,22 @@ int __init omap_wakeupgen_init(void)
for (i = 0; i < max_irqs; i++)
irq_target_cpu[i] = boot_cpu;

/*
* Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
* 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together.
* 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode
* independently.
* This needs to be set one time thanks to always ON domain.
*
* We do not support ES1 behavior anymore. OMAP5 is assumed to be
* ES2.0, and the same is applicable for DRA7.
*/
if (soc_is_omap54xx() || soc_is_dra7xx()) {
val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
val |= BIT(5);
omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
}

irq_hotplug_init();
irq_pm_init();

Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-omap2/omap-wakeupgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define OMAP_WKG_ENB_E_1 0x420
#define OMAP_AUX_CORE_BOOT_0 0x800
#define OMAP_AUX_CORE_BOOT_1 0x804
#define OMAP_AMBA_IF_MODE 0x80c
#define OMAP_PTMSYNCREQ_MASK 0xc00
#define OMAP_PTMSYNCREQ_EN 0xc04
#define OMAP_TIMESTAMPCYCLELO 0xc08
Expand Down
10 changes: 10 additions & 0 deletions arch/arm/mach-omap2/pdata-quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,16 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
#endif
#ifdef CONFIG_SOC_OMAP5
OF_DEV_AUXDATA("ti,omap5-padconf", 0x4a002840, "4a002840.pinmux", &pcs_pdata),
OF_DEV_AUXDATA("ti,omap5-padconf", 0x4ae0c840, "4ae0c840.pinmux", &pcs_pdata),
#endif
#ifdef CONFIG_SOC_DRA7XX
OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata),
#endif
#ifdef CONFIG_SOC_AM43XX
OF_DEV_AUXDATA("ti,am437-padconf", 0x44e10800, "44e10800.pinmux", &pcs_pdata),
#endif
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
&omap4_iommu_pdata),
Expand Down
1 change: 1 addition & 0 deletions arch/arm/mach-omap2/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */

#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0)
#define PM_OMAP4_CPU_OSWR_DISABLE (1 << 1)

#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
extern u16 pm44xx_errata;
Expand Down
Loading

0 comments on commit 887782e

Please sign in to comment.