1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (C) 2016 Broadcom Corporation 4 */ 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 .text 14 .set noreorder 15 .align 5 16 17/* 18 * a0: u32 params array 19 */ 20LEAF(brcm_pm_do_s2) 21 22 subu sp, 64 23 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 array 35 * s0: AON_CTRL base register 36 * s1: DDR_PHY base register 37 * s2: TIMERS base register 38 * s3: I-Cache line size 39 * s4: Restart vector address 40 * s5: Restart vector size 41 */ 42 move t0, a0 43 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, -1 53 not t1 54 55 la t0, brcm_pm_do_s2 56 and t0, t1 57 58 la t2, asm_end 59 and t2, t1 60 611: cache 0x1c, 0(t0) 62 bne t0, t2, 1b 63 addu t0, s3 64 65 /* Lock the interrupt vector into the I-cache */ 66 move t0, zero 67 682: move t1, s4 69 cache 0x1c, 0(t1) 70 addu t1, s3 71 addu t0, s3 72 ble t0, s5, 2b 73 nop 74 75 sync 76 77 /* Power down request */ 78 li t0, PM_S2_COMMAND 79 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_STATUS 86 /* Save cp0 sr for restoring later */ 87 move s6, t0 88 89 li t1, ~(ST0_IM | ST0_IE) 90 and t0, t1 91 ori t0, STATUSF_IP2 92 mtc0 t0, CP0_STATUS 93 nop 94 nop 95 nop 96 ori t0, ST0_IE 97 mtc0 t0, CP0_STATUS 98 99 /* Wait for interrupt */ 100 wait 101 nop 102 103 /* Wait for memc0 */ 1041: lw t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1) 105 andi t0, 1 106 beqz t0, 1b 107 nop 108 109 /* 1ms delay needed for stable recovery */ 110 /* Use TIMER1 to count 1 ms */ 111 li t0, RESET_TIMER 112 sw t0, TIMER_TIMER1_CTRL(s2) 113 lw t0, TIMER_TIMER1_CTRL(s2) 114 115 li t0, START_TIMER 116 sw t0, TIMER_TIMER1_CTRL(s2) 117 lw t0, TIMER_TIMER1_CTRL(s2) 118 119 /* Prepare delay */ 120 li t0, TIMER_MASK 121 lw t1, TIMER_TIMER1_STAT(s2) 122 and t1, t0 123 /* 1ms delay */ 124 addi t1, 27000 125 126 /* Wait for the timer value to exceed t1 */ 1271: lw t0, TIMER_TIMER1_STAT(s2) 128 sgtu t2, t1, t0 129 bnez t2, 1b 130 nop 131 132 /* Power back up */ 133 li t1, 1 134 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, -1 142 not t1 143 144 la t0, brcm_pm_do_s2 145 and t0, t1 146 147 la t2, asm_end 148 and t2, t1 149 1501: cache 0x00, 0(t0) 151 bne t0, t2, 1b 152 addu t0, s3 153 154 /* Unlock interrupt vector */ 155 move t0, zero 156 1572: move t1, s4 158 cache 0x00, 0(t1) 159 addu t1, s3 160 addu t0, s3 161 ble t0, s5, 2b 162 nop 163 164 /* Restore cp0 sr */ 165 sync 166 nop 167 mtc0 s6, CP0_STATUS 168 nop 169 170 /* Set return value to success */ 171 li v0, 0 172 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, 64 184 185 jr ra 186 nop 187END(brcm_pm_do_s2) 188 189 .globl asm_end 190asm_end: 191 nop 192 193