1/* SPDX-License-Identifier: GPL-2.0 */
2/* Copyright (C) 2017 Andes Technology Corporation */
3
4#include <asm/memory.h>
5
6.data
7.global sp_tmp
8sp_tmp:
9.long
10
11.text
12.globl suspend2ram
13.globl cpu_resume
14
15suspend2ram:
16	pushm   $r0, $r31
17#if defined(CONFIG_HWZOL)
18	mfusr   $r0, $lc
19	mfusr   $r1, $le
20	mfusr   $r2, $lb
21#endif
22	mfsr	$r3, $mr0
23	mfsr    $r4, $mr1
24	mfsr    $r5, $mr4
25	mfsr    $r6, $mr6
26	mfsr    $r7, $mr7
27	mfsr    $r8, $mr8
28	mfsr    $r9, $ir0
29	mfsr    $r10, $ir1
30	mfsr    $r11, $ir2
31	mfsr    $r12, $ir3
32	mfsr    $r13, $ir9
33	mfsr    $r14, $ir10
34	mfsr    $r15, $ir12
35	mfsr    $r16, $ir13
36	mfsr    $r17, $ir14
37	mfsr    $r18, $ir15
38	pushm   $r0, $r19
39#if defined(CONFIG_FPU)
40	jal	store_fpu_for_suspend
41#endif
42	tlbop	FlushAll
43	isb
44
45	// transfer $sp from va to pa
46	sethi	$r0, hi20(PAGE_OFFSET)
47	ori	$r0, $r0, lo12(PAGE_OFFSET)
48	movi	$r2, PHYS_OFFSET
49	sub	$r1, $sp, $r0
50	add	$r2, $r1, $r2
51
52	// store pa($sp) to sp_tmp
53	sethi 	$r1, hi20(sp_tmp)
54	swi	$r2, [$r1 + lo12(sp_tmp)]
55
56	pushm	$r16, $r25
57	pushm	$r29, $r30
58#ifdef	CONFIG_CACHE_L2
59	jal	dcache_wb_all_level
60#else
61	jal	cpu_dcache_wb_all
62#endif
63	popm	$r29, $r30
64	popm	$r16, $r25
65
66	// get wake_mask and loop in standby
67	la	$r1, wake_mask
68	lwi	$r1, [$r1]
69self_loop:
70	standby wake_grant
71	mfsr	$r2, $ir15
72	and	$r2, $r1, $r2
73	beqz	$r2, self_loop
74
75	// set ipc to resume address
76	la	$r1, resume_addr
77	lwi	$r1, [$r1]
78	mtsr	$r1, $ipc
79	isb
80
81	// reset psw, turn off the address translation
82	li      $r2, 0x7000a
83	mtsr    $r2, $ipsw
84	isb
85
86	iret
87cpu_resume:
88	// translate the address of sp_tmp variable to pa
89	la	$r1, sp_tmp
90	sethi   $r0, hi20(PAGE_OFFSET)
91	ori     $r0, $r0, lo12(PAGE_OFFSET)
92	movi    $r2, PHYS_OFFSET
93	sub     $r1, $r1, $r0
94	add     $r1, $r1, $r2
95
96	// access the sp_tmp to get stack pointer
97	lwi	$sp, [$r1]
98
99	popm	$r0, $r19
100#if defined(CONFIG_HWZOL)
101	mtusr   $r0, $lb
102	mtusr   $r1, $lc
103	mtusr   $r2, $le
104#endif
105	mtsr	$r3, $mr0
106	mtsr    $r4, $mr1
107	mtsr    $r5, $mr4
108	mtsr    $r6, $mr6
109	mtsr    $r7, $mr7
110	mtsr    $r8, $mr8
111	// set original psw to ipsw
112	mtsr    $r9, $ir1
113
114	mtsr    $r11, $ir2
115	mtsr    $r12, $ir3
116
117	// set ipc to RR
118	la	$r13, RR
119	mtsr	$r13, $ir9
120
121	mtsr    $r14, $ir10
122	mtsr    $r15, $ir12
123	mtsr    $r16, $ir13
124	mtsr    $r17, $ir14
125	mtsr    $r18, $ir15
126	popm    $r0, $r31
127
128	isb
129	iret
130RR:
131	ret
132