193 lines · plain
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (C) 2016 Broadcom Corporation4 */5 6#include <asm/asm.h>7#include <asm/regdef.h>8#include <asm/mipsregs.h>9#include <asm/stackframe.h>10 11#include "pm.h"12 13 .text14 .set noreorder15 .align 516 17/*18 * a0: u32 params array19 */20LEAF(brcm_pm_do_s2)21 22 subu sp, 6423 sw ra, 0(sp)24 sw s0, 4(sp)25 sw s1, 8(sp)26 sw s2, 12(sp)27 sw s3, 16(sp)28 sw s4, 20(sp)29 sw s5, 24(sp)30 sw s6, 28(sp)31 sw s7, 32(sp)32 33 /*34 * Dereference the params array35 * s0: AON_CTRL base register36 * s1: DDR_PHY base register37 * s2: TIMERS base register38 * s3: I-Cache line size39 * s4: Restart vector address40 * s5: Restart vector size41 */42 move t0, a043 44 lw s0, 0(t0)45 lw s1, 4(t0)46 lw s2, 8(t0)47 lw s3, 12(t0)48 lw s4, 16(t0)49 lw s5, 20(t0)50 51 /* Lock this asm section into the I-cache */52 addiu t1, s3, -153 not t154 55 la t0, brcm_pm_do_s256 and t0, t157 58 la t2, asm_end59 and t2, t160 611: cache 0x1c, 0(t0)62 bne t0, t2, 1b63 addu t0, s364 65 /* Lock the interrupt vector into the I-cache */66 move t0, zero67 682: move t1, s469 cache 0x1c, 0(t1)70 addu t1, s371 addu t0, s372 ble t0, s5, 2b73 nop74 75 sync76 77 /* Power down request */78 li t0, PM_S2_COMMAND79 sw zero, AON_CTRL_PM_CTRL(s0)80 lw zero, AON_CTRL_PM_CTRL(s0)81 sw t0, AON_CTRL_PM_CTRL(s0)82 lw t0, AON_CTRL_PM_CTRL(s0)83 84 /* Enable CP0 interrupt 2 and wait for interrupt */85 mfc0 t0, CP0_STATUS86 /* Save cp0 sr for restoring later */87 move s6, t088 89 li t1, ~(ST0_IM | ST0_IE)90 and t0, t191 ori t0, STATUSF_IP292 mtc0 t0, CP0_STATUS93 nop94 nop95 nop96 ori t0, ST0_IE97 mtc0 t0, CP0_STATUS98 99 /* Wait for interrupt */100 wait101 nop102 103 /* Wait for memc0 */1041: lw t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1)105 andi t0, 1106 beqz t0, 1b107 nop108 109 /* 1ms delay needed for stable recovery */110 /* Use TIMER1 to count 1 ms */111 li t0, RESET_TIMER112 sw t0, TIMER_TIMER1_CTRL(s2)113 lw t0, TIMER_TIMER1_CTRL(s2)114 115 li t0, START_TIMER116 sw t0, TIMER_TIMER1_CTRL(s2)117 lw t0, TIMER_TIMER1_CTRL(s2)118 119 /* Prepare delay */120 li t0, TIMER_MASK121 lw t1, TIMER_TIMER1_STAT(s2)122 and t1, t0123 /* 1ms delay */124 addi t1, 27000125 126 /* Wait for the timer value to exceed t1 */1271: lw t0, TIMER_TIMER1_STAT(s2)128 sgtu t2, t1, t0129 bnez t2, 1b130 nop131 132 /* Power back up */133 li t1, 1134 sw t1, AON_CTRL_HOST_MISC_CMDS(s0)135 lw t1, AON_CTRL_HOST_MISC_CMDS(s0)136 137 sw zero, AON_CTRL_PM_CTRL(s0)138 lw zero, AON_CTRL_PM_CTRL(s0)139 140 /* Unlock I-cache */141 addiu t1, s3, -1142 not t1143 144 la t0, brcm_pm_do_s2145 and t0, t1146 147 la t2, asm_end148 and t2, t1149 1501: cache 0x00, 0(t0)151 bne t0, t2, 1b152 addu t0, s3153 154 /* Unlock interrupt vector */155 move t0, zero156 1572: move t1, s4158 cache 0x00, 0(t1)159 addu t1, s3160 addu t0, s3161 ble t0, s5, 2b162 nop163 164 /* Restore cp0 sr */165 sync166 nop167 mtc0 s6, CP0_STATUS168 nop169 170 /* Set return value to success */171 li v0, 0172 173 /* Return to caller */174 lw s7, 32(sp)175 lw s6, 28(sp)176 lw s5, 24(sp)177 lw s4, 20(sp)178 lw s3, 16(sp)179 lw s2, 12(sp)180 lw s1, 8(sp)181 lw s0, 4(sp)182 lw ra, 0(sp)183 addiu sp, 64184 185 jr ra186 nop187END(brcm_pm_do_s2)188 189 .globl asm_end190asm_end:191 nop192 193