Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2016 Broadcom Corporation
0004  */
0005 
0006 #include <asm/asm.h>
0007 #include <asm/regdef.h>
0008 #include <asm/mipsregs.h>
0009 #include <asm/bmips.h>
0010 
0011 #include "pm.h"
0012 
0013     .text
0014     .set        noreorder
0015     .align      5
0016     .global     s3_reentry
0017 
0018 /*
0019  * a0: AON_CTRL base register
0020  * a1: D-Cache line size
0021  */
0022 LEAF(brcm_pm_do_s3)
0023 
0024     /* Get the address of s3_context */
0025     la  t0, gp_regs
0026     sw  ra, 0(t0)
0027     sw  s0, 4(t0)
0028     sw  s1, 8(t0)
0029     sw  s2, 12(t0)
0030     sw  s3, 16(t0)
0031     sw  s4, 20(t0)
0032     sw  s5, 24(t0)
0033     sw  s6, 28(t0)
0034     sw  s7, 32(t0)
0035     sw  gp, 36(t0)
0036     sw  sp, 40(t0)
0037     sw  fp, 44(t0)
0038 
0039     /* Save CP0 Status */
0040     mfc0    t1, CP0_STATUS
0041     sw  t1, 48(t0)
0042 
0043     /* Write-back gp registers - cache will be gone */
0044     addiu   t1, a1, -1
0045     not t1
0046     and t0, t1
0047 
0048     /* Flush at least 64 bytes */
0049     addiu   t2, t0, 64
0050     and t2, t1
0051 
0052 1:  cache   0x17, 0(t0)
0053     bne t0, t2, 1b
0054     addu    t0, a1
0055 
0056     /* Drop to deep standby */
0057     li  t1, PM_WARM_CONFIG
0058     sw  zero, AON_CTRL_PM_CTRL(a0)
0059     lw  zero, AON_CTRL_PM_CTRL(a0)
0060     sw  t1, AON_CTRL_PM_CTRL(a0)
0061     lw  t1, AON_CTRL_PM_CTRL(a0)
0062 
0063     li  t1, (PM_WARM_CONFIG | PM_PWR_DOWN)
0064     sw  t1, AON_CTRL_PM_CTRL(a0)
0065     lw  t1, AON_CTRL_PM_CTRL(a0)
0066 
0067     /* Enable CP0 interrupt 2 and wait for interrupt */
0068     mfc0    t0, CP0_STATUS
0069 
0070     li  t1, ~(ST0_IM | ST0_IE)
0071     and t0, t1
0072     ori t0, STATUSF_IP2
0073     mtc0    t0, CP0_STATUS
0074     nop
0075     nop
0076     nop
0077     ori t0, ST0_IE
0078     mtc0    t0, CP0_STATUS
0079 
0080         /* Wait for interrupt */
0081         wait
0082         nop
0083 
0084 s3_reentry:
0085 
0086     /* Clear call/return stack */
0087     li  t0, (0x06 << 16)
0088     mtc0    t0, $22, 2
0089     ssnop
0090     ssnop
0091     ssnop
0092 
0093     /* Clear jump target buffer */
0094     li  t0, (0x04 << 16)
0095     mtc0    t0, $22, 2
0096     ssnop
0097     ssnop
0098     ssnop
0099 
0100     sync
0101     nop
0102 
0103     /* Setup mmu defaults */
0104     mtc0    zero, CP0_WIRED
0105     mtc0    zero, CP0_ENTRYHI
0106     li  k0, PM_DEFAULT_MASK
0107     mtc0    k0, CP0_PAGEMASK
0108 
0109     li  sp, BMIPS_WARM_RESTART_VEC
0110     la  k0, plat_wired_tlb_setup
0111     jalr    k0
0112     nop
0113 
0114     /* Restore general purpose registers */
0115     la  t0, gp_regs
0116     lw  fp, 44(t0)
0117     lw  sp, 40(t0)
0118     lw  gp, 36(t0)
0119     lw  s7, 32(t0)
0120     lw  s6, 28(t0)
0121     lw  s5, 24(t0)
0122     lw  s4, 20(t0)
0123     lw  s3, 16(t0)
0124     lw  s2, 12(t0)
0125     lw  s1, 8(t0)
0126     lw  s0, 4(t0)
0127     lw  ra, 0(t0)
0128 
0129     /* Restore CP0 status */
0130     lw  t1, 48(t0)
0131     mtc0    t1, CP0_STATUS
0132 
0133     /* Return to caller */
0134     li  v0, 0
0135     jr      ra
0136     nop
0137 
0138 END(brcm_pm_do_s3)