xref: /openbmc/linux/drivers/soc/bcm/brcmstb/pm/s2-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/stackframe.h>
100e9b1141SJustin Chen
110e9b1141SJustin Chen#include "pm.h"
120e9b1141SJustin Chen
130e9b1141SJustin Chen	.text
140e9b1141SJustin Chen	.set	noreorder
150e9b1141SJustin Chen	.align	5
160e9b1141SJustin Chen
170e9b1141SJustin Chen/*
180e9b1141SJustin Chen * a0: u32 params array
190e9b1141SJustin Chen */
200e9b1141SJustin ChenLEAF(brcm_pm_do_s2)
210e9b1141SJustin Chen
220e9b1141SJustin Chen	subu	sp, 64
230e9b1141SJustin Chen	sw	ra, 0(sp)
240e9b1141SJustin Chen	sw	s0, 4(sp)
250e9b1141SJustin Chen	sw	s1, 8(sp)
260e9b1141SJustin Chen	sw	s2, 12(sp)
270e9b1141SJustin Chen	sw	s3, 16(sp)
280e9b1141SJustin Chen	sw	s4, 20(sp)
290e9b1141SJustin Chen	sw	s5, 24(sp)
300e9b1141SJustin Chen	sw	s6, 28(sp)
310e9b1141SJustin Chen	sw	s7, 32(sp)
320e9b1141SJustin Chen
330e9b1141SJustin Chen	/*
340e9b1141SJustin Chen	 * Dereference the params array
350e9b1141SJustin Chen	 * s0: AON_CTRL base register
360e9b1141SJustin Chen	 * s1: DDR_PHY base register
370e9b1141SJustin Chen	 * s2: TIMERS base register
380e9b1141SJustin Chen	 * s3: I-Cache line size
390e9b1141SJustin Chen	 * s4: Restart vector address
400e9b1141SJustin Chen	 * s5: Restart vector size
410e9b1141SJustin Chen	 */
420e9b1141SJustin Chen	move	t0, a0
430e9b1141SJustin Chen
440e9b1141SJustin Chen	lw	s0, 0(t0)
450e9b1141SJustin Chen	lw	s1, 4(t0)
460e9b1141SJustin Chen	lw	s2, 8(t0)
470e9b1141SJustin Chen	lw	s3, 12(t0)
480e9b1141SJustin Chen	lw	s4, 16(t0)
490e9b1141SJustin Chen	lw	s5, 20(t0)
500e9b1141SJustin Chen
510e9b1141SJustin Chen	/* Lock this asm section into the I-cache */
520e9b1141SJustin Chen	addiu	t1, s3, -1
530e9b1141SJustin Chen	not	t1
540e9b1141SJustin Chen
550e9b1141SJustin Chen	la	t0, brcm_pm_do_s2
560e9b1141SJustin Chen	and	t0, t1
570e9b1141SJustin Chen
580e9b1141SJustin Chen	la	t2, asm_end
590e9b1141SJustin Chen	and	t2, t1
600e9b1141SJustin Chen
610e9b1141SJustin Chen1:	cache	0x1c, 0(t0)
620e9b1141SJustin Chen	bne	t0, t2, 1b
630e9b1141SJustin Chen	addu	t0, s3
640e9b1141SJustin Chen
650e9b1141SJustin Chen	/* Lock the interrupt vector into the I-cache */
660e9b1141SJustin Chen	move	t0, zero
670e9b1141SJustin Chen
680e9b1141SJustin Chen2:	move	t1, s4
690e9b1141SJustin Chen	cache 	0x1c, 0(t1)
700e9b1141SJustin Chen	addu	t1, s3
710e9b1141SJustin Chen	addu	t0, s3
720e9b1141SJustin Chen	ble	t0, s5, 2b
730e9b1141SJustin Chen	nop
740e9b1141SJustin Chen
750e9b1141SJustin Chen	sync
760e9b1141SJustin Chen
770e9b1141SJustin Chen	/* Power down request */
780e9b1141SJustin Chen	li	t0, PM_S2_COMMAND
790e9b1141SJustin Chen	sw	zero, AON_CTRL_PM_CTRL(s0)
800e9b1141SJustin Chen	lw	zero, AON_CTRL_PM_CTRL(s0)
810e9b1141SJustin Chen	sw	t0, AON_CTRL_PM_CTRL(s0)
820e9b1141SJustin Chen	lw	t0, AON_CTRL_PM_CTRL(s0)
830e9b1141SJustin Chen
840e9b1141SJustin Chen	/* Enable CP0 interrupt 2 and wait for interrupt */
850e9b1141SJustin Chen	mfc0	t0, CP0_STATUS
860e9b1141SJustin Chen	/* Save cp0 sr for restoring later */
870e9b1141SJustin Chen	move	s6, t0
880e9b1141SJustin Chen
890e9b1141SJustin Chen	li	t1, ~(ST0_IM | ST0_IE)
900e9b1141SJustin Chen	and	t0, t1
910e9b1141SJustin Chen	ori	t0, STATUSF_IP2
920e9b1141SJustin Chen	mtc0	t0, CP0_STATUS
930e9b1141SJustin Chen	nop
940e9b1141SJustin Chen	nop
950e9b1141SJustin Chen	nop
960e9b1141SJustin Chen	ori	t0, ST0_IE
970e9b1141SJustin Chen	mtc0	t0, CP0_STATUS
980e9b1141SJustin Chen
990e9b1141SJustin Chen	/* Wait for interrupt */
1000e9b1141SJustin Chen	wait
1010e9b1141SJustin Chen	nop
1020e9b1141SJustin Chen
1030e9b1141SJustin Chen	/* Wait for memc0 */
1040e9b1141SJustin Chen1:	lw	t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1)
1050e9b1141SJustin Chen	andi	t0, 1
1060e9b1141SJustin Chen	beqz	t0, 1b
1070e9b1141SJustin Chen	nop
1080e9b1141SJustin Chen
1090e9b1141SJustin Chen	/* 1ms delay needed for stable recovery */
1100e9b1141SJustin Chen	/* Use TIMER1 to count 1 ms */
1110e9b1141SJustin Chen	li	t0, RESET_TIMER
1120e9b1141SJustin Chen	sw	t0, TIMER_TIMER1_CTRL(s2)
1130e9b1141SJustin Chen	lw	t0, TIMER_TIMER1_CTRL(s2)
1140e9b1141SJustin Chen
1150e9b1141SJustin Chen	li	t0, START_TIMER
1160e9b1141SJustin Chen	sw	t0, TIMER_TIMER1_CTRL(s2)
1170e9b1141SJustin Chen	lw	t0, TIMER_TIMER1_CTRL(s2)
1180e9b1141SJustin Chen
1190e9b1141SJustin Chen	/* Prepare delay */
1200e9b1141SJustin Chen	li	t0, TIMER_MASK
1210e9b1141SJustin Chen	lw	t1, TIMER_TIMER1_STAT(s2)
1220e9b1141SJustin Chen	and	t1, t0
1230e9b1141SJustin Chen	/* 1ms delay */
1240e9b1141SJustin Chen	addi	t1, 27000
1250e9b1141SJustin Chen
1260e9b1141SJustin Chen	/* Wait for the timer value to exceed t1 */
1270e9b1141SJustin Chen1:	lw	t0, TIMER_TIMER1_STAT(s2)
1280e9b1141SJustin Chen	sgtu	t2, t1, t0
1290e9b1141SJustin Chen	bnez	t2, 1b
1300e9b1141SJustin Chen	nop
1310e9b1141SJustin Chen
1320e9b1141SJustin Chen	/* Power back up */
1330e9b1141SJustin Chen	li	t1, 1
1340e9b1141SJustin Chen	sw	t1, AON_CTRL_HOST_MISC_CMDS(s0)
1350e9b1141SJustin Chen	lw	t1, AON_CTRL_HOST_MISC_CMDS(s0)
1360e9b1141SJustin Chen
1370e9b1141SJustin Chen	sw	zero, AON_CTRL_PM_CTRL(s0)
1380e9b1141SJustin Chen	lw	zero, AON_CTRL_PM_CTRL(s0)
1390e9b1141SJustin Chen
1400e9b1141SJustin Chen	/* Unlock I-cache */
1410e9b1141SJustin Chen	addiu	t1, s3, -1
1420e9b1141SJustin Chen	not	t1
1430e9b1141SJustin Chen
1440e9b1141SJustin Chen	la	t0, brcm_pm_do_s2
1450e9b1141SJustin Chen	and 	t0, t1
1460e9b1141SJustin Chen
1470e9b1141SJustin Chen	la	t2, asm_end
1480e9b1141SJustin Chen	and	t2, t1
1490e9b1141SJustin Chen
1500e9b1141SJustin Chen1:	cache	0x00, 0(t0)
1510e9b1141SJustin Chen	bne	t0, t2, 1b
1520e9b1141SJustin Chen	addu	t0, s3
1530e9b1141SJustin Chen
1540e9b1141SJustin Chen	/* Unlock interrupt vector */
1550e9b1141SJustin Chen	move	t0, zero
1560e9b1141SJustin Chen
1570e9b1141SJustin Chen2:	move	t1, s4
1580e9b1141SJustin Chen	cache 	0x00, 0(t1)
1590e9b1141SJustin Chen	addu	t1, s3
1600e9b1141SJustin Chen	addu	t0, s3
1610e9b1141SJustin Chen	ble	t0, s5, 2b
1620e9b1141SJustin Chen	nop
1630e9b1141SJustin Chen
1640e9b1141SJustin Chen	/* Restore cp0 sr */
1650e9b1141SJustin Chen	sync
1660e9b1141SJustin Chen	nop
1670e9b1141SJustin Chen	mtc0	s6, CP0_STATUS
1680e9b1141SJustin Chen	nop
1690e9b1141SJustin Chen
1700e9b1141SJustin Chen	/* Set return value to success */
1710e9b1141SJustin Chen	li	v0, 0
1720e9b1141SJustin Chen
1730e9b1141SJustin Chen	/* Return to caller */
1740e9b1141SJustin Chen	lw	s7, 32(sp)
1750e9b1141SJustin Chen	lw	s6, 28(sp)
1760e9b1141SJustin Chen	lw	s5, 24(sp)
1770e9b1141SJustin Chen	lw	s4, 20(sp)
1780e9b1141SJustin Chen	lw	s3, 16(sp)
1790e9b1141SJustin Chen	lw	s2, 12(sp)
1800e9b1141SJustin Chen	lw	s1, 8(sp)
1810e9b1141SJustin Chen	lw	s0, 4(sp)
1820e9b1141SJustin Chen	lw	ra, 0(sp)
1830e9b1141SJustin Chen	addiu	sp, 64
1840e9b1141SJustin Chen
1850e9b1141SJustin Chen	jr ra
1860e9b1141SJustin Chen	nop
1870e9b1141SJustin ChenEND(brcm_pm_do_s2)
1880e9b1141SJustin Chen
1890e9b1141SJustin Chen	.globl asm_end
1900e9b1141SJustin Chenasm_end:
1910e9b1141SJustin Chen	nop
1920e9b1141SJustin Chen
193