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

sleep.S (4939B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * (C) Copyright 2009, Texas Instruments, Inc. https://www.ti.com/
      4 */
      5
      6/* replicated define because linux/bitops.h cannot be included in assembly */
      7#define BIT(nr)			(1 << (nr))
      8
      9#include <linux/linkage.h>
     10#include <asm/assembler.h>
     11#include "psc.h"
     12#include "ddr2.h"
     13
     14#include "clock.h"
     15
     16/* Arbitrary, hardware currently does not update PHYRDY correctly */
     17#define PHYRDY_CYCLES		0x1000
     18
     19/* Assume 25 MHz speed for the cycle conversions since PLLs are bypassed */
     20#define PLL_BYPASS_CYCLES	(PLL_BYPASS_TIME * 25)
     21#define PLL_RESET_CYCLES	(PLL_RESET_TIME	* 25)
     22#define PLL_LOCK_CYCLES		(PLL_LOCK_TIME * 25)
     23
     24#define DEEPSLEEP_SLEEPENABLE_BIT	BIT(31)
     25
     26	.text
     27	.arch	armv5te
     28/*
     29 * Move DaVinci into deep sleep state
     30 *
     31 * Note: This code is copied to internal SRAM by PM code. When the DaVinci
     32 *	 wakes up it continues execution at the point it went to sleep.
     33 * Register Usage:
     34 * 	r0: contains virtual base for DDR2 controller
     35 * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
     36 * 	r2: contains PSC number for DDR2
     37 * 	r3: contains virtual base DDR2 PLL controller
     38 * 	r4: contains virtual address of the DEEPSLEEP register
     39 */
     40ENTRY(davinci_cpu_suspend)
     41	stmfd	sp!, {r0-r12, lr}		@ save registers on stack
     42
     43	ldr 	ip, CACHE_FLUSH
     44	blx	ip
     45
     46	ldmia	r0, {r0-r4}
     47
     48	/*
     49	 * Switch DDR to self-refresh mode.
     50	 */
     51
     52	/* calculate SDRCR address */
     53	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
     54	bic	ip, ip, #DDR2_SRPD_BIT
     55	orr	ip, ip, #DDR2_LPMODEN_BIT
     56	str	ip, [r0, #DDR2_SDRCR_OFFSET]
     57
     58	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
     59	orr	ip, ip, #DDR2_MCLKSTOPEN_BIT
     60	str	ip, [r0, #DDR2_SDRCR_OFFSET]
     61
     62       mov	ip, #PHYRDY_CYCLES
     631:     subs	ip, ip, #0x1
     64       bne	1b
     65
     66       /* Disable DDR2 LPSC */
     67	mov	r7, r0
     68	mov	r0, #0x2
     69	bl davinci_ddr_psc_config
     70	mov	r0, r7
     71
     72	/* Disable clock to DDR PHY */
     73	ldr	ip, [r3, #PLLDIV1]
     74	bic	ip, ip, #PLLDIV_EN
     75	str	ip, [r3, #PLLDIV1]
     76
     77	/* Put the DDR PLL in bypass and power down */
     78	ldr	ip, [r3, #PLLCTL]
     79	bic	ip, ip, #PLLCTL_PLLENSRC
     80	bic	ip, ip, #PLLCTL_PLLEN
     81	str	ip, [r3, #PLLCTL]
     82
     83	/* Wait for PLL to switch to bypass */
     84       mov	ip, #PLL_BYPASS_CYCLES
     852:     subs	ip, ip, #0x1
     86       bne	2b
     87
     88       /* Power down the PLL */
     89	ldr	ip, [r3, #PLLCTL]
     90	orr	ip, ip, #PLLCTL_PLLPWRDN
     91	str	ip, [r3, #PLLCTL]
     92
     93	/* Go to deep sleep */
     94	ldr	ip, [r4]
     95	orr	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
     96	/* System goes to sleep beyond after this instruction */
     97	str	ip, [r4]
     98
     99	/* Wake up from sleep */
    100
    101	/* Clear sleep enable */
    102	ldr	ip, [r4]
    103	bic	ip, ip, #DEEPSLEEP_SLEEPENABLE_BIT
    104	str	ip, [r4]
    105
    106	/* initialize the DDR PLL controller */
    107
    108	/* Put PLL in reset */
    109	ldr	ip, [r3, #PLLCTL]
    110	bic	ip, ip, #PLLCTL_PLLRST
    111	str	ip, [r3, #PLLCTL]
    112
    113	/* Clear PLL power down */
    114	ldr	ip, [r3, #PLLCTL]
    115	bic	ip, ip, #PLLCTL_PLLPWRDN
    116	str	ip, [r3, #PLLCTL]
    117
    118       mov	ip, #PLL_RESET_CYCLES
    1193:     subs	ip, ip, #0x1
    120       bne	3b
    121
    122       /* Bring PLL out of reset */
    123	ldr	ip, [r3, #PLLCTL]
    124	orr	ip, ip, #PLLCTL_PLLRST
    125	str	ip, [r3, #PLLCTL]
    126
    127	/* Wait for PLL to lock (assume prediv = 1, 25MHz OSCIN) */
    128       mov	ip, #PLL_LOCK_CYCLES
    1294:     subs	ip, ip, #0x1
    130       bne	4b
    131
    132       /* Remove PLL from bypass mode */
    133	ldr	ip, [r3, #PLLCTL]
    134	bic	ip, ip, #PLLCTL_PLLENSRC
    135	orr	ip, ip, #PLLCTL_PLLEN
    136	str	ip, [r3, #PLLCTL]
    137
    138	/* Start 2x clock to DDR2 */
    139
    140	ldr	ip, [r3, #PLLDIV1]
    141	orr	ip, ip, #PLLDIV_EN
    142	str	ip, [r3, #PLLDIV1]
    143
    144	/* Enable VCLK */
    145
    146       /* Enable DDR2 LPSC */
    147	mov	r7, r0
    148	mov	r0, #0x3
    149	bl davinci_ddr_psc_config
    150	mov	r0, r7
    151
    152	/* clear  MCLKSTOPEN */
    153
    154	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
    155	bic	ip, ip, #DDR2_MCLKSTOPEN_BIT
    156	str	ip, [r0, #DDR2_SDRCR_OFFSET]
    157
    158	ldr	ip, [r0, #DDR2_SDRCR_OFFSET]
    159	bic	ip, ip, #DDR2_LPMODEN_BIT
    160	str	ip, [r0, #DDR2_SDRCR_OFFSET]
    161
    162	/* Restore registers and return */
    163	ldmfd   sp!, {r0-r12, pc}
    164
    165ENDPROC(davinci_cpu_suspend)
    166
    167/*
    168 * Disables or Enables DDR2 LPSC
    169 * Register Usage:
    170 * 	r0: Enable or Disable LPSC r0 = 0x3 => Enable, r0 = 0x2 => Disable LPSC
    171 * 	r1: contains virtual base for DDR2 Power and Sleep controller (PSC)
    172 * 	r2: contains PSC number for DDR2
    173 */
    174ENTRY(davinci_ddr_psc_config)
    175	/* Set next state in mdctl for DDR2 */
    176	mov	r6, #MDCTL
    177	add	r6, r6, r2, lsl #2
    178	ldr	ip, [r1, r6]
    179	bic	ip, ip, #MDSTAT_STATE_MASK
    180	orr	ip, ip, r0
    181	str	ip, [r1, r6]
    182
    183	/* Enable the Power Domain Transition Command */
    184	ldr	ip, [r1, #PTCMD]
    185	orr	ip, ip, #0x1
    186	str	ip, [r1, #PTCMD]
    187
    188	/* Check for Transition Complete (PTSTAT) */
    189ptstat_done:
    190	ldr	ip, [r1, #PTSTAT]
    191	and	ip, ip, #0x1
    192	cmp 	ip, #0x0
    193	bne	ptstat_done
    194
    195	/* Check for DDR2 clock disable completion; */
    196	mov	r6, #MDSTAT
    197	add	r6, r6, r2, lsl #2
    198ddr2clk_stop_done:
    199	ldr	ip, [r1, r6]
    200	and	ip, ip, #MDSTAT_STATE_MASK
    201	cmp	ip, r0
    202	bne	ddr2clk_stop_done
    203
    204	ret	lr
    205ENDPROC(davinci_ddr_psc_config)
    206
    207CACHE_FLUSH:
    208#ifdef CONFIG_CPU_V6
    209	.word	v6_flush_kern_cache_all
    210#else
    211	.word   arm926_flush_kern_cache_all
    212#endif
    213
    214ENTRY(davinci_cpu_suspend_sz)
    215	.word	. - davinci_cpu_suspend
    216ENDPROC(davinci_cpu_suspend_sz)