cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sleep24xx.S (2784B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * linux/arch/arm/mach-omap2/sleep.S
      4 *
      5 * (C) Copyright 2004
      6 * Texas Instruments, <www.ti.com>
      7 * Richard Woodruff <r-woodruff2@ti.com>
      8 *
      9 * (C) Copyright 2006 Nokia Corporation
     10 * Fixed idle loop sleep
     11 * Igor Stoppa <igor.stoppa@nokia.com>
     12 */
     13
     14#include <linux/linkage.h>
     15#include <asm/assembler.h>
     16
     17#include "omap24xx.h"
     18#include "sdrc.h"
     19
     20/* First address of reserved address space?  apparently valid for OMAP2 & 3 */
     21#define A_SDRC0_V		(0xC0000000)
     22
     23	.text
     24
     25/*
     26 * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing
     27 * SDRC shutdown then ARM shutdown.  Upon wake MPU is back on so just restore
     28 * SDRC.
     29 *
     30 * Input:
     31 * R0 :	DLL ctrl value pre-Sleep
     32 * R1 : SDRC_DLLA_CTRL
     33 * R2 : SDRC_POWER
     34 *
     35 * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
     36 * when we get called, but the DLL probably isn't.  We will wait a bit more in
     37 * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even
     38 * if in unlocked mode.
     39 *
     40 * For less than 242x-ES2.2 upon wake from a sleep mode where the external
     41 * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz
     42 * clock can pass into the PRCM can cause problems at DSP and IVA.
     43 * To work around this the code will switch to the 32kHz source prior to sleep.
     44 * Post sleep we will shift back to using the DPLL.  Apparently,
     45 * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait
     46 * 3x12MHz + 3x32kHz clocks for a full switch.
     47 *
     48 * The DLL load value is not kept in RETENTION or OFF.	It needs to be restored
     49 * at wake
     50 */
     51	.align	3
     52ENTRY(omap24xx_cpu_suspend)
     53	stmfd	sp!, {r0 - r12, lr}	@ save registers on stack
     54	mov	r3, #0x0		@ clear for mcr call
     55	mcr	p15, 0, r3, c7, c10, 4	@ memory barrier, hope SDR/DDR finished
     56	nop
     57	nop
     58	ldr	r4, [r2]		@ read SDRC_POWER
     59	orr	r4, r4, #0x40		@ enable self refresh on idle req
     60	mov	r5, #0x2000		@ set delay (DPLL relock + DLL relock)
     61	str	r4, [r2]		@ make it so
     62	nop
     63	mcr	p15, 0, r3, c7, c0, 4	@ wait for interrupt
     64	nop
     65loop:
     66	subs	r5, r5, #0x1		@ awake, wait just a bit
     67	bne	loop
     68
     69	/* The DPLL has to be on before we take the DDR out of self refresh */
     70	bic	r4, r4, #0x40		@ now clear self refresh bit.
     71	str	r4, [r2]		@ write to SDRC_POWER
     72	ldr	r4, A_SDRC0		@ make a clock happen
     73	ldr	r4, [r4]		@ read A_SDRC0
     74	nop				@ start auto refresh only after clk ok
     75	movs	r0, r0			@ see if DDR or SDR
     76	strne	r0, [r1]		@ rewrite DLLA to force DLL reload
     77	addne	r1, r1, #0x8		@ move to DLLB
     78	strne	r0, [r1]		@ rewrite DLLB to force DLL reload
     79
     80	mov	r5, #0x1000
     81loop2:
     82	subs	r5, r5, #0x1
     83	bne	loop2
     84	/* resume*/
     85	ldmfd	sp!, {r0 - r12, pc}	@ restore regs and return
     86
     87A_SDRC0:
     88	.word A_SDRC0_V
     89
     90ENTRY(omap24xx_cpu_suspend_sz)
     91	.word	. - omap24xx_cpu_suspend