Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27d59a4a authored by Tero Kristo's avatar Tero Kristo Committed by Kevin Hilman
Browse files

OMAP3 PM: off-mode support for HS/EMU devices



For HS/EMU devices, some additional resources need to be
saved/restored for off-mode support.  Namely, saving the secure RAM
and a pointer to it in the scratchpad.

Signed-off-by: default avatarTero Kristo <tero.kristo@nokia.com>
Signed-off-by: default avatarKevin Hilman <khilman@deeprootsystems.com>
parent f2d11858
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ struct omap3_scratchpad_sdrc_block {
	u32 block_size;
};

void *omap3_secure_ram_storage;

/*
 * This is used to store ARM registers in SDRAM before attempting
 * an MPU OFF. The save and restore happens from the SRAM sleep code.
@@ -209,7 +211,11 @@ void omap3_save_scratchpad_contents(void)
	scratchpad_contents.boot_config_ptr = 0x0;
	scratchpad_contents.public_restore_ptr =
			 virt_to_phys(get_restore_pointer());
	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
		scratchpad_contents.secure_ram_restore_ptr = 0x0;
	else
		scratchpad_contents.secure_ram_restore_ptr =
			(u32) __pa(omap3_secure_ram_storage);
	scratchpad_contents.sdrc_module_semaphore = 0x0;
	scratchpad_contents.prcm_block_offset = 0x2C;
	scratchpad_contents.sdrc_block_offset = 0x64;
+3 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@

#include <plat/powerdomain.h>

extern void *omap3_secure_ram_storage;

extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm);
extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);

@@ -36,6 +38,7 @@ extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
					void __iomem *sdrc_power);
extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
extern void save_secure_ram_context(u32 *addr);
extern void omap3_save_scratchpad_contents(void);

extern unsigned int omap24xx_idle_loop_suspend_sz;
extern unsigned int omap34xx_suspend_sz;
+42 −1
Original line number Diff line number Diff line
@@ -63,6 +63,8 @@ static LIST_HEAD(pwrst_list);

static void (*_omap_sram_idle)(u32 *addr, int save_state);

static int (*_omap_save_secure_sram)(u32 *addr);

static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
static struct powerdomain *core_pwrdm, *per_pwrdm;

@@ -110,6 +112,33 @@ static void omap3_core_restore_context(void)
	omap_dma_global_context_restore();
}

static void omap3_save_secure_ram_context(u32 target_mpu_state)
{
	u32 ret;

	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
		/* Disable dma irq before calling secure rom code API */
		omap_dma_disable_irq(0);
		omap_dma_disable_irq(1);
		/*
		 * MPU next state must be set to POWER_ON temporarily,
		 * otherwise the WFI executed inside the ROM code
		 * will hang the system.
		 */
		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
		ret = _omap_save_secure_sram((u32 *)
				__pa(omap3_secure_ram_storage));
		pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state);
		/* Following is for error tracking, it should not happen */
		if (ret) {
			printk(KERN_ERR "save_secure_sram() returns %08x\n",
				ret);
			while (1)
				;
		}
	}
}

/*
 * PRCM Interrupt Handler Helper Function
 *
@@ -308,6 +337,7 @@ static void omap_sram_idle(void)
		if (core_next_state == PWRDM_POWER_OFF) {
			omap3_core_save_context();
			omap3_prcm_save_context();
			omap3_save_secure_ram_context(mpu_next_state);
		}
		/* Enable IO-PAD wakeup */
		prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
@@ -901,6 +931,9 @@ void omap_push_sram_idle(void)
{
	_omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
					omap34xx_cpu_suspend_sz);
	if (omap_type() != OMAP2_DEVICE_TYPE_GP)
		_omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
				save_secure_ram_context_sz);
}

static int __init omap3_pm_init(void)
@@ -916,7 +949,6 @@ static int __init omap3_pm_init(void)
	/* XXX prcm_setup_regs needs to be before enabling hw
	 * supervised mode for powerdomains */
	prcm_setup_regs();
	omap3_save_scratchpad_contents();

	ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
			  (irq_handler_t)prcm_interrupt_handler,
@@ -961,6 +993,15 @@ static int __init omap3_pm_init(void)
	*/
	pwrdm_add_wkdep(per_pwrdm, core_pwrdm);

	if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
		omap3_secure_ram_storage =
			kmalloc(0x803F, GFP_KERNEL);
		if (!omap3_secure_ram_storage)
			printk(KERN_ERR "Memory allocation failed when"
					"allocating for secure sram context\n");
	}
	omap3_save_scratchpad_contents();

err1:
	return ret;
err2:
+74 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#define PM_PREPWSTST_MPU_V	OMAP34XX_PRM_REGADDR(MPU_MOD, \
				OMAP3430_PM_PREPWSTST)
#define PM_PWSTCTRL_MPU_P	OMAP3430_PRM_BASE + MPU_MOD + PM_PWSTCTRL
#define SRAM_BASE_P		0x40200000
#define CONTROL_STAT		0x480022F0
#define SCRATCHPAD_MEM_OFFS	0x310 /* Move this as correct place is
				       * available */
#define SCRATCHPAD_BASE_P	(OMAP343X_CTRL_BASE + OMAP343X_CONTROL_MEM_WKUP\
@@ -51,6 +53,40 @@ ENTRY(get_restore_pointer)
        ldmfd   sp!, {pc}     @ restore regs and return
ENTRY(get_restore_pointer_sz)
        .word   . - get_restore_pointer_sz

/* Function to call rom code to save secure ram context */
ENTRY(save_secure_ram_context)
	stmfd	sp!, {r1-r12, lr}	@ save registers on stack
save_secure_ram_debug:
	/* b save_secure_ram_debug */	@ enable to debug save code
	adr	r3, api_params		@ r3 points to parameters
	str	r0, [r3,#0x4]		@ r0 has sdram address
	ldr	r12, high_mask
	and	r3, r3, r12
	ldr	r12, sram_phy_addr_mask
	orr	r3, r3, r12
	mov	r0, #25			@ set service ID for PPA
	mov	r12, r0			@ copy secure service ID in r12
	mov	r1, #0			@ set task id for ROM code in r1
	mov	r2, #7			@ set some flags in r2, r6
	mov	r6, #0xff
	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
	.word	0xE1600071		@ call SMI monitor (smi #1)
	nop
	nop
	nop
	nop
	ldmfd	sp!, {r1-r12, pc}
sram_phy_addr_mask:
	.word	SRAM_BASE_P
high_mask:
	.word	0xffff
api_params:
	.word	0x4, 0x0, 0x0, 0x1, 0x1
ENTRY(save_secure_ram_context_sz)
	.word	. - save_secure_ram_context

/*
 * Forces OMAP into idle state
 *
@@ -107,9 +143,44 @@ restore:
        moveq   r9, #0x3        @ MPU OFF => L1 and L2 lost
	movne	r9, #0x1	@ Only L1 and L2 lost => avoid L2 invalidation
	bne	logic_l1_restore
	ldr	r0, control_stat
	ldr	r1, [r0]
	and	r1, #0x700
	cmp	r1, #0x300
	beq	l2_inv_gp
	mov	r0, #40		@ set service ID for PPA
	mov	r12, r0		@ copy secure Service ID in r12
	mov	r1, #0		@ set task id for ROM code in r1
	mov	r2, #4		@ set some flags in r2, r6
	mov	r6, #0xff
	adr	r3, l2_inv_api_params	@ r3 points to dummy parameters
	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
	.word	0xE1600071		@ call SMI monitor (smi #1)
	/* Write to Aux control register to set some bits */
	mov	r0, #42		@ set service ID for PPA
	mov	r12, r0		@ copy secure Service ID in r12
	mov	r1, #0		@ set task id for ROM code in r1
	mov	r2, #4		@ set some flags in r2, r6
	mov	r6, #0xff
	adr	r3, write_aux_control_params	@ r3 points to parameters
	mcr	p15, 0, r0, c7, c10, 4	@ data write barrier
	mcr	p15, 0, r0, c7, c10, 5	@ data memory barrier
	.word	0xE1600071		@ call SMI monitor (smi #1)

	b	logic_l1_restore
l2_inv_api_params:
	.word   0x1, 0x00
write_aux_control_params:
	.word   0x1, 0x72
l2_inv_gp:
	/* Execute smi to invalidate L2 cache */
	mov r12, #0x1                         @ set up to invalide L2
smi:    .word 0xE1600070		@ Call SMI monitor (smieq)
	/* Write to Aux control register to set some bits */
	mov	r0, #0x72
	mov	r12, #0x3
	.word 0xE1600070	@ Call SMI monitor (smieq)
logic_l1_restore:
	mov	r1, #0
	/* Invalidate all instruction caches to PoU
@@ -429,5 +500,7 @@ table_entry:
	.word	0x00000C02
cache_pred_disable_mask:
	.word	0xFFFFE7FB
control_stat:
	.word	CONTROL_STAT
ENTRY(omap34xx_cpu_suspend_sz)
	.word	. - omap34xx_cpu_suspend