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/bmips.h> 18 19#include "pm.h" 20 21 .text 22 .set noreorder 23 .align 5 24 .global s3_reentry 25 26/* 27 * a0: AON_CTRL base register 28 * a1: D-Cache line size 29 */ 30LEAF(brcm_pm_do_s3) 31 32 /* Get the address of s3_context */ 33 la t0, gp_regs 34 sw ra, 0(t0) 35 sw s0, 4(t0) 36 sw s1, 8(t0) 37 sw s2, 12(t0) 38 sw s3, 16(t0) 39 sw s4, 20(t0) 40 sw s5, 24(t0) 41 sw s6, 28(t0) 42 sw s7, 32(t0) 43 sw gp, 36(t0) 44 sw sp, 40(t0) 45 sw fp, 44(t0) 46 47 /* Save CP0 Status */ 48 mfc0 t1, CP0_STATUS 49 sw t1, 48(t0) 50 51 /* Write-back gp registers - cache will be gone */ 52 addiu t1, a1, -1 53 not t1 54 and t0, t1 55 56 /* Flush at least 64 bytes */ 57 addiu t2, t0, 64 58 and t2, t1 59 601: cache 0x17, 0(t0) 61 bne t0, t2, 1b 62 addu t0, a1 63 64 /* Drop to deep standby */ 65 li t1, PM_WARM_CONFIG 66 sw zero, AON_CTRL_PM_CTRL(a0) 67 lw zero, AON_CTRL_PM_CTRL(a0) 68 sw t1, AON_CTRL_PM_CTRL(a0) 69 lw t1, AON_CTRL_PM_CTRL(a0) 70 71 li t1, (PM_WARM_CONFIG | PM_PWR_DOWN) 72 sw t1, AON_CTRL_PM_CTRL(a0) 73 lw t1, AON_CTRL_PM_CTRL(a0) 74 75 /* Enable CP0 interrupt 2 and wait for interrupt */ 76 mfc0 t0, CP0_STATUS 77 78 li t1, ~(ST0_IM | ST0_IE) 79 and t0, t1 80 ori t0, STATUSF_IP2 81 mtc0 t0, CP0_STATUS 82 nop 83 nop 84 nop 85 ori t0, ST0_IE 86 mtc0 t0, CP0_STATUS 87 88 /* Wait for interrupt */ 89 wait 90 nop 91 92s3_reentry: 93 94 /* Clear call/return stack */ 95 li t0, (0x06 << 16) 96 mtc0 t0, $22, 2 97 ssnop 98 ssnop 99 ssnop 100 101 /* Clear jump target buffer */ 102 li t0, (0x04 << 16) 103 mtc0 t0, $22, 2 104 ssnop 105 ssnop 106 ssnop 107 108 sync 109 nop 110 111 /* Setup mmu defaults */ 112 mtc0 zero, CP0_WIRED 113 mtc0 zero, CP0_ENTRYHI 114 li k0, PM_DEFAULT_MASK 115 mtc0 k0, CP0_PAGEMASK 116 117 li sp, BMIPS_WARM_RESTART_VEC 118 la k0, plat_wired_tlb_setup 119 jalr k0 120 nop 121 122 /* Restore general purpose registers */ 123 la t0, gp_regs 124 lw fp, 44(t0) 125 lw sp, 40(t0) 126 lw gp, 36(t0) 127 lw s7, 32(t0) 128 lw s6, 28(t0) 129 lw s5, 24(t0) 130 lw s4, 20(t0) 131 lw s3, 16(t0) 132 lw s2, 12(t0) 133 lw s1, 8(t0) 134 lw s0, 4(t0) 135 lw ra, 0(t0) 136 137 /* Restore CP0 status */ 138 lw t1, 48(t0) 139 mtc0 t1, CP0_STATUS 140 141 /* Return to caller */ 142 li v0, 0 143 jr ra 144 nop 145 146END(brcm_pm_do_s3) 147