162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Sleep helper for Loongson-3 sleep mode.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Author: Huacai Chen <chenhuacai@loongson.cn>
662306a36Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/asm.h>
1062306a36Sopenharmony_ci#include <asm/asmmacro.h>
1162306a36Sopenharmony_ci#include <asm/addrspace.h>
1262306a36Sopenharmony_ci#include <asm/loongarch.h>
1362306a36Sopenharmony_ci#include <asm/stackframe.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/* preparatory stuff */
1662306a36Sopenharmony_ci.macro	SETUP_SLEEP
1762306a36Sopenharmony_ci	addi.d		sp, sp, -PT_SIZE
1862306a36Sopenharmony_ci	st.d		$r1, sp, PT_R1
1962306a36Sopenharmony_ci	st.d		$r2, sp, PT_R2
2062306a36Sopenharmony_ci	st.d		$r3, sp, PT_R3
2162306a36Sopenharmony_ci	st.d		$r4, sp, PT_R4
2262306a36Sopenharmony_ci	st.d		$r21, sp, PT_R21
2362306a36Sopenharmony_ci	st.d		$r22, sp, PT_R22
2462306a36Sopenharmony_ci	st.d		$r23, sp, PT_R23
2562306a36Sopenharmony_ci	st.d		$r24, sp, PT_R24
2662306a36Sopenharmony_ci	st.d		$r25, sp, PT_R25
2762306a36Sopenharmony_ci	st.d		$r26, sp, PT_R26
2862306a36Sopenharmony_ci	st.d		$r27, sp, PT_R27
2962306a36Sopenharmony_ci	st.d		$r28, sp, PT_R28
3062306a36Sopenharmony_ci	st.d		$r29, sp, PT_R29
3162306a36Sopenharmony_ci	st.d		$r30, sp, PT_R30
3262306a36Sopenharmony_ci	st.d		$r31, sp, PT_R31
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	la.pcrel	t0, acpi_saved_sp
3562306a36Sopenharmony_ci	st.d		sp, t0, 0
3662306a36Sopenharmony_ci.endm
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci.macro SETUP_WAKEUP
3962306a36Sopenharmony_ci	ld.d		$r1, sp, PT_R1
4062306a36Sopenharmony_ci	ld.d		$r2, sp, PT_R2
4162306a36Sopenharmony_ci	ld.d		$r3, sp, PT_R3
4262306a36Sopenharmony_ci	ld.d		$r4, sp, PT_R4
4362306a36Sopenharmony_ci	ld.d		$r21, sp, PT_R21
4462306a36Sopenharmony_ci	ld.d		$r22, sp, PT_R22
4562306a36Sopenharmony_ci	ld.d		$r23, sp, PT_R23
4662306a36Sopenharmony_ci	ld.d		$r24, sp, PT_R24
4762306a36Sopenharmony_ci	ld.d		$r25, sp, PT_R25
4862306a36Sopenharmony_ci	ld.d		$r26, sp, PT_R26
4962306a36Sopenharmony_ci	ld.d		$r27, sp, PT_R27
5062306a36Sopenharmony_ci	ld.d		$r28, sp, PT_R28
5162306a36Sopenharmony_ci	ld.d		$r29, sp, PT_R29
5262306a36Sopenharmony_ci	ld.d		$r30, sp, PT_R30
5362306a36Sopenharmony_ci	ld.d		$r31, sp, PT_R31
5462306a36Sopenharmony_ci.endm
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	.text
5762306a36Sopenharmony_ci	.align 12
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* Sleep/wakeup code for Loongson-3 */
6062306a36Sopenharmony_ciSYM_FUNC_START(loongarch_suspend_enter)
6162306a36Sopenharmony_ci	SETUP_SLEEP
6262306a36Sopenharmony_ci	bl		__flush_cache_all
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	/* Pass RA and SP to BIOS */
6562306a36Sopenharmony_ci	addi.d		a1, sp, 0
6662306a36Sopenharmony_ci	la.pcrel	a0, loongarch_wakeup_start
6762306a36Sopenharmony_ci	la.pcrel	t0, loongarch_suspend_addr
6862306a36Sopenharmony_ci	ld.d		t0, t0, 0
6962306a36Sopenharmony_ci	jirl		a0, t0, 0 /* Call BIOS's STR sleep routine */
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	/*
7262306a36Sopenharmony_ci	 * This is where we return upon wakeup.
7362306a36Sopenharmony_ci	 * Reload all of the registers and return.
7462306a36Sopenharmony_ci	 */
7562306a36Sopenharmony_ciSYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
7662306a36Sopenharmony_ci	li.d		t0, CSR_DMW0_INIT	# UC, PLV0
7762306a36Sopenharmony_ci	csrwr		t0, LOONGARCH_CSR_DMWIN0
7862306a36Sopenharmony_ci	li.d		t0, CSR_DMW1_INIT	# CA, PLV0
7962306a36Sopenharmony_ci	csrwr		t0, LOONGARCH_CSR_DMWIN1
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	JUMP_VIRT_ADDR	t0, t1
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* Enable PG */
8462306a36Sopenharmony_ci	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
8562306a36Sopenharmony_ci	csrwr		t0, LOONGARCH_CSR_CRMD
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	la.pcrel	t0, acpi_saved_sp
8862306a36Sopenharmony_ci	ld.d		sp, t0, 0
8962306a36Sopenharmony_ci	SETUP_WAKEUP
9062306a36Sopenharmony_ci	addi.d		sp, sp, PT_SIZE
9162306a36Sopenharmony_ci	jr		ra
9262306a36Sopenharmony_ciSYM_FUNC_END(loongarch_suspend_enter)
93