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