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/stackframe.h>
0010 
0011 #include "pm.h"
0012 
0013     .text
0014     .set    noreorder
0015     .align  5
0016 
0017 /*
0018  * a0: u32 params array
0019  */
0020 LEAF(brcm_pm_do_s2)
0021 
0022     subu    sp, 64
0023     sw  ra, 0(sp)
0024     sw  s0, 4(sp)
0025     sw  s1, 8(sp)
0026     sw  s2, 12(sp)
0027     sw  s3, 16(sp)
0028     sw  s4, 20(sp)
0029     sw  s5, 24(sp)
0030     sw  s6, 28(sp)
0031     sw  s7, 32(sp)
0032 
0033     /*
0034      * Dereference the params array
0035      * s0: AON_CTRL base register
0036      * s1: DDR_PHY base register
0037      * s2: TIMERS base register
0038      * s3: I-Cache line size
0039      * s4: Restart vector address
0040      * s5: Restart vector size
0041      */
0042     move    t0, a0
0043 
0044     lw  s0, 0(t0)
0045     lw  s1, 4(t0)
0046     lw  s2, 8(t0)
0047     lw  s3, 12(t0)
0048     lw  s4, 16(t0)
0049     lw  s5, 20(t0)
0050 
0051     /* Lock this asm section into the I-cache */
0052     addiu   t1, s3, -1
0053     not t1
0054 
0055     la  t0, brcm_pm_do_s2
0056     and t0, t1
0057 
0058     la  t2, asm_end
0059     and t2, t1
0060 
0061 1:  cache   0x1c, 0(t0)
0062     bne t0, t2, 1b
0063     addu    t0, s3
0064 
0065     /* Lock the interrupt vector into the I-cache */
0066     move    t0, zero
0067 
0068 2:  move    t1, s4
0069     cache   0x1c, 0(t1)
0070     addu    t1, s3
0071     addu    t0, s3
0072     ble t0, s5, 2b
0073     nop
0074 
0075     sync
0076 
0077     /* Power down request */
0078     li  t0, PM_S2_COMMAND
0079     sw  zero, AON_CTRL_PM_CTRL(s0)
0080     lw  zero, AON_CTRL_PM_CTRL(s0)
0081     sw  t0, AON_CTRL_PM_CTRL(s0)
0082     lw  t0, AON_CTRL_PM_CTRL(s0)
0083 
0084     /* Enable CP0 interrupt 2 and wait for interrupt */
0085     mfc0    t0, CP0_STATUS
0086     /* Save cp0 sr for restoring later */
0087     move    s6, t0
0088 
0089     li  t1, ~(ST0_IM | ST0_IE)
0090     and t0, t1
0091     ori t0, STATUSF_IP2
0092     mtc0    t0, CP0_STATUS
0093     nop
0094     nop
0095     nop
0096     ori t0, ST0_IE
0097     mtc0    t0, CP0_STATUS
0098 
0099     /* Wait for interrupt */
0100     wait
0101     nop
0102 
0103     /* Wait for memc0 */
0104 1:  lw  t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1)
0105     andi    t0, 1
0106     beqz    t0, 1b
0107     nop
0108 
0109     /* 1ms delay needed for stable recovery */
0110     /* Use TIMER1 to count 1 ms */
0111     li  t0, RESET_TIMER
0112     sw  t0, TIMER_TIMER1_CTRL(s2)
0113     lw  t0, TIMER_TIMER1_CTRL(s2)
0114 
0115     li  t0, START_TIMER
0116     sw  t0, TIMER_TIMER1_CTRL(s2)
0117     lw  t0, TIMER_TIMER1_CTRL(s2)
0118 
0119     /* Prepare delay */
0120     li  t0, TIMER_MASK
0121     lw  t1, TIMER_TIMER1_STAT(s2)
0122     and t1, t0
0123     /* 1ms delay */
0124     addi    t1, 27000
0125 
0126     /* Wait for the timer value to exceed t1 */
0127 1:  lw  t0, TIMER_TIMER1_STAT(s2)
0128     sgtu    t2, t1, t0
0129     bnez    t2, 1b
0130     nop
0131 
0132     /* Power back up */
0133     li  t1, 1
0134     sw  t1, AON_CTRL_HOST_MISC_CMDS(s0)
0135     lw  t1, AON_CTRL_HOST_MISC_CMDS(s0)
0136 
0137     sw  zero, AON_CTRL_PM_CTRL(s0)
0138     lw  zero, AON_CTRL_PM_CTRL(s0)
0139 
0140     /* Unlock I-cache */
0141     addiu   t1, s3, -1
0142     not t1
0143 
0144     la  t0, brcm_pm_do_s2
0145     and     t0, t1
0146 
0147     la  t2, asm_end
0148     and t2, t1
0149 
0150 1:  cache   0x00, 0(t0)
0151     bne t0, t2, 1b
0152     addu    t0, s3
0153 
0154     /* Unlock interrupt vector */
0155     move    t0, zero
0156 
0157 2:  move    t1, s4
0158     cache   0x00, 0(t1)
0159     addu    t1, s3
0160     addu    t0, s3
0161     ble t0, s5, 2b
0162     nop
0163 
0164     /* Restore cp0 sr */
0165     sync
0166     nop
0167     mtc0    s6, CP0_STATUS
0168     nop
0169 
0170     /* Set return value to success */
0171     li  v0, 0
0172 
0173     /* Return to caller */
0174     lw  s7, 32(sp)
0175     lw  s6, 28(sp)
0176     lw  s5, 24(sp)
0177     lw  s4, 20(sp)
0178     lw  s3, 16(sp)
0179     lw  s2, 12(sp)
0180     lw  s1, 8(sp)
0181     lw  s0, 4(sp)
0182     lw  ra, 0(sp)
0183     addiu   sp, 64
0184 
0185     jr ra
0186     nop
0187 END(brcm_pm_do_s2)
0188 
0189     .globl asm_end
0190 asm_end:
0191     nop
0192