1/* 2 * Copyright (C) 2016 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#include <asm/asm.h> 15#include <asm/regdef.h> 16#include <asm/mipsregs.h> 17#include <asm/stackframe.h> 18 19#include "pm.h" 20 21 .text 22 .set noreorder 23 .align 5 24 25/* 26 * a0: u32 params array 27 */ 28LEAF(brcm_pm_do_s2) 29 30 subu sp, 64 31 sw ra, 0(sp) 32 sw s0, 4(sp) 33 sw s1, 8(sp) 34 sw s2, 12(sp) 35 sw s3, 16(sp) 36 sw s4, 20(sp) 37 sw s5, 24(sp) 38 sw s6, 28(sp) 39 sw s7, 32(sp) 40 41 /* 42 * Dereference the params array 43 * s0: AON_CTRL base register 44 * s1: DDR_PHY base register 45 * s2: TIMERS base register 46 * s3: I-Cache line size 47 * s4: Restart vector address 48 * s5: Restart vector size 49 */ 50 move t0, a0 51 52 lw s0, 0(t0) 53 lw s1, 4(t0) 54 lw s2, 8(t0) 55 lw s3, 12(t0) 56 lw s4, 16(t0) 57 lw s5, 20(t0) 58 59 /* Lock this asm section into the I-cache */ 60 addiu t1, s3, -1 61 not t1 62 63 la t0, brcm_pm_do_s2 64 and t0, t1 65 66 la t2, asm_end 67 and t2, t1 68 691: cache 0x1c, 0(t0) 70 bne t0, t2, 1b 71 addu t0, s3 72 73 /* Lock the interrupt vector into the I-cache */ 74 move t0, zero 75 762: move t1, s4 77 cache 0x1c, 0(t1) 78 addu t1, s3 79 addu t0, s3 80 ble t0, s5, 2b 81 nop 82 83 sync 84 85 /* Power down request */ 86 li t0, PM_S2_COMMAND 87 sw zero, AON_CTRL_PM_CTRL(s0) 88 lw zero, AON_CTRL_PM_CTRL(s0) 89 sw t0, AON_CTRL_PM_CTRL(s0) 90 lw t0, AON_CTRL_PM_CTRL(s0) 91 92 /* Enable CP0 interrupt 2 and wait for interrupt */ 93 mfc0 t0, CP0_STATUS 94 /* Save cp0 sr for restoring later */ 95 move s6, t0 96 97 li t1, ~(ST0_IM | ST0_IE) 98 and t0, t1 99 ori t0, STATUSF_IP2 100 mtc0 t0, CP0_STATUS 101 nop 102 nop 103 nop 104 ori t0, ST0_IE 105 mtc0 t0, CP0_STATUS 106 107 /* Wait for interrupt */ 108 wait 109 nop 110 111 /* Wait for memc0 */ 1121: lw t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1) 113 andi t0, 1 114 beqz t0, 1b 115 nop 116 117 /* 1ms delay needed for stable recovery */ 118 /* Use TIMER1 to count 1 ms */ 119 li t0, RESET_TIMER 120 sw t0, TIMER_TIMER1_CTRL(s2) 121 lw t0, TIMER_TIMER1_CTRL(s2) 122 123 li t0, START_TIMER 124 sw t0, TIMER_TIMER1_CTRL(s2) 125 lw t0, TIMER_TIMER1_CTRL(s2) 126 127 /* Prepare delay */ 128 li t0, TIMER_MASK 129 lw t1, TIMER_TIMER1_STAT(s2) 130 and t1, t0 131 /* 1ms delay */ 132 addi t1, 27000 133 134 /* Wait for the timer value to exceed t1 */ 1351: lw t0, TIMER_TIMER1_STAT(s2) 136 sgtu t2, t1, t0 137 bnez t2, 1b 138 nop 139 140 /* Power back up */ 141 li t1, 1 142 sw t1, AON_CTRL_HOST_MISC_CMDS(s0) 143 lw t1, AON_CTRL_HOST_MISC_CMDS(s0) 144 145 sw zero, AON_CTRL_PM_CTRL(s0) 146 lw zero, AON_CTRL_PM_CTRL(s0) 147 148 /* Unlock I-cache */ 149 addiu t1, s3, -1 150 not t1 151 152 la t0, brcm_pm_do_s2 153 and t0, t1 154 155 la t2, asm_end 156 and t2, t1 157 1581: cache 0x00, 0(t0) 159 bne t0, t2, 1b 160 addu t0, s3 161 162 /* Unlock interrupt vector */ 163 move t0, zero 164 1652: move t1, s4 166 cache 0x00, 0(t1) 167 addu t1, s3 168 addu t0, s3 169 ble t0, s5, 2b 170 nop 171 172 /* Restore cp0 sr */ 173 sync 174 nop 175 mtc0 s6, CP0_STATUS 176 nop 177 178 /* Set return value to success */ 179 li v0, 0 180 181 /* Return to caller */ 182 lw s7, 32(sp) 183 lw s6, 28(sp) 184 lw s5, 24(sp) 185 lw s4, 20(sp) 186 lw s3, 16(sp) 187 lw s2, 12(sp) 188 lw s1, 8(sp) 189 lw s0, 4(sp) 190 lw ra, 0(sp) 191 addiu sp, 64 192 193 jr ra 194 nop 195END(brcm_pm_do_s2) 196 197 .globl asm_end 198asm_end: 199 nop 200 201