xref: /openbmc/linux/drivers/soc/bcm/brcmstb/pm/s3-mips.S (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*1802d0beSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
20e9b1141SJustin Chen/*
30e9b1141SJustin Chen * Copyright (C) 2016 Broadcom Corporation
40e9b1141SJustin Chen */
50e9b1141SJustin Chen
60e9b1141SJustin Chen#include <asm/asm.h>
70e9b1141SJustin Chen#include <asm/regdef.h>
80e9b1141SJustin Chen#include <asm/mipsregs.h>
90e9b1141SJustin Chen#include <asm/bmips.h>
100e9b1141SJustin Chen
110e9b1141SJustin Chen#include "pm.h"
120e9b1141SJustin Chen
130e9b1141SJustin Chen	.text
140e9b1141SJustin Chen	.set		noreorder
150e9b1141SJustin Chen	.align		5
160e9b1141SJustin Chen	.global		s3_reentry
170e9b1141SJustin Chen
180e9b1141SJustin Chen/*
190e9b1141SJustin Chen * a0: AON_CTRL base register
200e9b1141SJustin Chen * a1: D-Cache line size
210e9b1141SJustin Chen */
220e9b1141SJustin ChenLEAF(brcm_pm_do_s3)
230e9b1141SJustin Chen
240e9b1141SJustin Chen	/* Get the address of s3_context */
250e9b1141SJustin Chen	la	t0, gp_regs
260e9b1141SJustin Chen	sw	ra, 0(t0)
270e9b1141SJustin Chen	sw	s0, 4(t0)
280e9b1141SJustin Chen	sw	s1, 8(t0)
290e9b1141SJustin Chen	sw	s2, 12(t0)
300e9b1141SJustin Chen	sw	s3, 16(t0)
310e9b1141SJustin Chen	sw	s4, 20(t0)
320e9b1141SJustin Chen	sw	s5, 24(t0)
330e9b1141SJustin Chen	sw	s6, 28(t0)
340e9b1141SJustin Chen	sw	s7, 32(t0)
350e9b1141SJustin Chen	sw	gp, 36(t0)
360e9b1141SJustin Chen	sw	sp, 40(t0)
370e9b1141SJustin Chen	sw	fp, 44(t0)
380e9b1141SJustin Chen
390e9b1141SJustin Chen	/* Save CP0 Status */
400e9b1141SJustin Chen	mfc0	t1, CP0_STATUS
410e9b1141SJustin Chen	sw	t1, 48(t0)
420e9b1141SJustin Chen
430e9b1141SJustin Chen	/* Write-back gp registers - cache will be gone */
440e9b1141SJustin Chen	addiu	t1, a1, -1
450e9b1141SJustin Chen	not	t1
460e9b1141SJustin Chen	and	t0, t1
470e9b1141SJustin Chen
480e9b1141SJustin Chen	/* Flush at least 64 bytes */
490e9b1141SJustin Chen	addiu	t2, t0, 64
500e9b1141SJustin Chen	and	t2, t1
510e9b1141SJustin Chen
520e9b1141SJustin Chen1:	cache	0x17, 0(t0)
530e9b1141SJustin Chen	bne	t0, t2, 1b
540e9b1141SJustin Chen	addu	t0, a1
550e9b1141SJustin Chen
560e9b1141SJustin Chen	/* Drop to deep standby */
570e9b1141SJustin Chen	li	t1, PM_WARM_CONFIG
580e9b1141SJustin Chen	sw	zero, AON_CTRL_PM_CTRL(a0)
590e9b1141SJustin Chen	lw	zero, AON_CTRL_PM_CTRL(a0)
600e9b1141SJustin Chen	sw	t1, AON_CTRL_PM_CTRL(a0)
610e9b1141SJustin Chen	lw	t1, AON_CTRL_PM_CTRL(a0)
620e9b1141SJustin Chen
630e9b1141SJustin Chen	li	t1, (PM_WARM_CONFIG | PM_PWR_DOWN)
640e9b1141SJustin Chen	sw	t1, AON_CTRL_PM_CTRL(a0)
650e9b1141SJustin Chen	lw	t1, AON_CTRL_PM_CTRL(a0)
660e9b1141SJustin Chen
670e9b1141SJustin Chen	/* Enable CP0 interrupt 2 and wait for interrupt */
680e9b1141SJustin Chen	mfc0	t0, CP0_STATUS
690e9b1141SJustin Chen
700e9b1141SJustin Chen	li	t1, ~(ST0_IM | ST0_IE)
710e9b1141SJustin Chen	and	t0, t1
720e9b1141SJustin Chen	ori	t0, STATUSF_IP2
730e9b1141SJustin Chen	mtc0	t0, CP0_STATUS
740e9b1141SJustin Chen	nop
750e9b1141SJustin Chen	nop
760e9b1141SJustin Chen	nop
770e9b1141SJustin Chen	ori	t0, ST0_IE
780e9b1141SJustin Chen	mtc0	t0, CP0_STATUS
790e9b1141SJustin Chen
800e9b1141SJustin Chen        /* Wait for interrupt */
810e9b1141SJustin Chen        wait
820e9b1141SJustin Chen        nop
830e9b1141SJustin Chen
840e9b1141SJustin Chens3_reentry:
850e9b1141SJustin Chen
860e9b1141SJustin Chen	/* Clear call/return stack */
870e9b1141SJustin Chen	li	t0, (0x06 << 16)
880e9b1141SJustin Chen	mtc0	t0, $22, 2
890e9b1141SJustin Chen	ssnop
900e9b1141SJustin Chen	ssnop
910e9b1141SJustin Chen	ssnop
920e9b1141SJustin Chen
930e9b1141SJustin Chen	/* Clear jump target buffer */
940e9b1141SJustin Chen	li	t0, (0x04 << 16)
950e9b1141SJustin Chen	mtc0	t0, $22, 2
960e9b1141SJustin Chen	ssnop
970e9b1141SJustin Chen	ssnop
980e9b1141SJustin Chen	ssnop
990e9b1141SJustin Chen
1000e9b1141SJustin Chen	sync
1010e9b1141SJustin Chen	nop
1020e9b1141SJustin Chen
1030e9b1141SJustin Chen	/* Setup mmu defaults */
1040e9b1141SJustin Chen	mtc0	zero, CP0_WIRED
1050e9b1141SJustin Chen	mtc0	zero, CP0_ENTRYHI
1060e9b1141SJustin Chen	li	k0, PM_DEFAULT_MASK
1070e9b1141SJustin Chen	mtc0	k0, CP0_PAGEMASK
1080e9b1141SJustin Chen
1090e9b1141SJustin Chen	li	sp, BMIPS_WARM_RESTART_VEC
1100e9b1141SJustin Chen	la	k0, plat_wired_tlb_setup
1110e9b1141SJustin Chen	jalr	k0
1120e9b1141SJustin Chen	nop
1130e9b1141SJustin Chen
1140e9b1141SJustin Chen	/* Restore general purpose registers */
1150e9b1141SJustin Chen	la	t0, gp_regs
1160e9b1141SJustin Chen	lw	fp, 44(t0)
1170e9b1141SJustin Chen	lw	sp, 40(t0)
1180e9b1141SJustin Chen	lw	gp, 36(t0)
1190e9b1141SJustin Chen	lw	s7, 32(t0)
1200e9b1141SJustin Chen	lw	s6, 28(t0)
1210e9b1141SJustin Chen	lw	s5, 24(t0)
1220e9b1141SJustin Chen	lw	s4, 20(t0)
1230e9b1141SJustin Chen	lw	s3, 16(t0)
1240e9b1141SJustin Chen	lw	s2, 12(t0)
1250e9b1141SJustin Chen	lw	s1, 8(t0)
1260e9b1141SJustin Chen	lw	s0, 4(t0)
1270e9b1141SJustin Chen	lw	ra, 0(t0)
1280e9b1141SJustin Chen
1290e9b1141SJustin Chen	/* Restore CP0 status */
1300e9b1141SJustin Chen	lw	t1, 48(t0)
1310e9b1141SJustin Chen	mtc0	t1, CP0_STATUS
1320e9b1141SJustin Chen
1330e9b1141SJustin Chen	/* Return to caller */
1340e9b1141SJustin Chen	li	v0, 0
1350e9b1141SJustin Chen	jr      ra
1360e9b1141SJustin Chen	nop
1370e9b1141SJustin Chen
1380e9b1141SJustin ChenEND(brcm_pm_do_s3)
139