Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright 2002 Embedded Edge, LLC
0004  * Author: dan@embeddededge.com
0005  *
0006  * Sleep helper for Au1xxx sleep mode.
0007  */
0008 
0009 #include <asm/asm.h>
0010 #include <asm/mipsregs.h>
0011 #include <asm/regdef.h>
0012 #include <asm/stackframe.h>
0013 
0014     .extern __flush_cache_all
0015 
0016     .text
0017     .set noreorder
0018     .set noat
0019     .align  5
0020 
0021 
0022 /* preparatory stuff */
0023 .macro  SETUP_SLEEP
0024     subu    sp, PT_SIZE
0025     sw  $1, PT_R1(sp)
0026     sw  $2, PT_R2(sp)
0027     sw  $3, PT_R3(sp)
0028     sw  $4, PT_R4(sp)
0029     sw  $5, PT_R5(sp)
0030     sw  $6, PT_R6(sp)
0031     sw  $7, PT_R7(sp)
0032     sw  $16, PT_R16(sp)
0033     sw  $17, PT_R17(sp)
0034     sw  $18, PT_R18(sp)
0035     sw  $19, PT_R19(sp)
0036     sw  $20, PT_R20(sp)
0037     sw  $21, PT_R21(sp)
0038     sw  $22, PT_R22(sp)
0039     sw  $23, PT_R23(sp)
0040     sw  $26, PT_R26(sp)
0041     sw  $27, PT_R27(sp)
0042     sw  $28, PT_R28(sp)
0043     sw  $30, PT_R30(sp)
0044     sw  $31, PT_R31(sp)
0045     mfc0    k0, CP0_STATUS
0046     sw  k0, 0x20(sp)
0047     mfc0    k0, CP0_CONTEXT
0048     sw  k0, 0x1c(sp)
0049     mfc0    k0, CP0_PAGEMASK
0050     sw  k0, 0x18(sp)
0051     mfc0    k0, CP0_CONFIG
0052     sw  k0, 0x14(sp)
0053 
0054     /* flush caches to make sure context is in memory */
0055     la  t1, __flush_cache_all
0056     lw  t0, 0(t1)
0057     jalr    t0
0058      nop
0059 
0060     /* Now set up the scratch registers so the boot rom will
0061      * return to this point upon wakeup.
0062      * sys_scratch0 : SP
0063      * sys_scratch1 : RA
0064      */
0065     lui t3, 0xb190      /* sys_xxx */
0066     sw  sp, 0x0018(t3)
0067     la  k0, alchemy_sleep_wakeup    /* resume path */
0068     sw  k0, 0x001c(t3)
0069 .endm
0070 
0071 .macro  DO_SLEEP
0072     /* put power supply and processor to sleep */
0073     sw  zero, 0x0078(t3)    /* sys_slppwr */
0074     sync
0075     sw  zero, 0x007c(t3)    /* sys_sleep */
0076     sync
0077     nop
0078     nop
0079     nop
0080     nop
0081     nop
0082     nop
0083     nop
0084     nop
0085 .endm
0086 
0087 /* sleep code for Au1000/Au1100/Au1500 memory controller type */
0088 LEAF(alchemy_sleep_au1000)
0089 
0090     SETUP_SLEEP
0091 
0092     /* cache following instructions, as memory gets put to sleep */
0093     la  t0, 1f
0094     .set    arch=r4000
0095     cache   0x14, 0(t0)
0096     cache   0x14, 32(t0)
0097     cache   0x14, 64(t0)
0098     cache   0x14, 96(t0)
0099     .set    mips0
0100 
0101 1:  lui a0, 0xb400      /* mem_xxx */
0102     sw  zero, 0x001c(a0)    /* Precharge */
0103     sync
0104     sw  zero, 0x0020(a0)    /* Auto Refresh */
0105     sync
0106     sw  zero, 0x0030(a0)    /* Sleep */
0107     sync
0108 
0109     DO_SLEEP
0110 
0111 END(alchemy_sleep_au1000)
0112 
0113 /* sleep code for Au1550/Au1200 memory controller type */
0114 LEAF(alchemy_sleep_au1550)
0115 
0116     SETUP_SLEEP
0117 
0118     /* cache following instructions, as memory gets put to sleep */
0119     la  t0, 1f
0120     .set    arch=r4000
0121     cache   0x14, 0(t0)
0122     cache   0x14, 32(t0)
0123     cache   0x14, 64(t0)
0124     cache   0x14, 96(t0)
0125     .set    mips0
0126 
0127 1:  lui a0, 0xb400      /* mem_xxx */
0128     sw  zero, 0x08c0(a0)    /* Precharge */
0129     sync
0130     sw  zero, 0x08d0(a0)    /* Self Refresh */
0131     sync
0132 
0133     /* wait for sdram to enter self-refresh mode */
0134     lui t0, 0x0100
0135 2:  lw  t1, 0x0850(a0)      /* mem_sdstat */
0136     and t2, t1, t0
0137     beq t2, zero, 2b
0138      nop
0139 
0140     /* disable SDRAM clocks */
0141     lui t0, 0xcfff
0142     ori t0, t0, 0xffff
0143     lw  t1, 0x0840(a0)      /* mem_sdconfiga */
0144     and t1, t0, t1      /* clear CE[1:0] */
0145     sw  t1, 0x0840(a0)      /* mem_sdconfiga */
0146     sync
0147 
0148     DO_SLEEP
0149 
0150 END(alchemy_sleep_au1550)
0151 
0152 /* sleepcode for Au1300 memory controller type */
0153 LEAF(alchemy_sleep_au1300)
0154 
0155     SETUP_SLEEP
0156 
0157     /* cache following instructions, as memory gets put to sleep */
0158     la  t0, 2f
0159     la  t1, 4f
0160     subu    t2, t1, t0
0161 
0162     .set    arch=r4000
0163 
0164 1:  cache   0x14, 0(t0)
0165     subu    t2, t2, 32
0166     bgez    t2, 1b
0167      addu   t0, t0, 32
0168 
0169     .set    mips0
0170 
0171 2:  lui a0, 0xb400      /* mem_xxx */
0172 
0173     /* disable all ports in mem_sdportcfga */
0174     sw  zero, 0x868(a0)     /* mem_sdportcfga */
0175     sync
0176 
0177     /* disable ODT */
0178     li  t0, 0x03010000
0179     sw  t0, 0x08d8(a0)      /* mem_sdcmd0 */
0180     sw  t0, 0x08dc(a0)      /* mem_sdcmd1 */
0181     sync
0182 
0183     /* precharge */
0184     li  t0, 0x23000400
0185     sw  t0, 0x08dc(a0)      /* mem_sdcmd1 */
0186     sw  t0, 0x08d8(a0)      /* mem_sdcmd0 */
0187     sync
0188 
0189     /* auto refresh */
0190     sw  zero, 0x08c8(a0)    /* mem_sdautoref */
0191     sync
0192 
0193     /* block access to the DDR */
0194     lw  t0, 0x0848(a0)      /* mem_sdconfigb */
0195     li  t1, (1 << 7 | 0x3F)
0196     or  t0, t0, t1
0197     sw  t0, 0x0848(a0)      /* mem_sdconfigb */
0198     sync
0199 
0200     /* issue the Self Refresh command */
0201     li  t0, 0x10000000
0202     sw  t0, 0x08dc(a0)      /* mem_sdcmd1 */
0203     sw  t0, 0x08d8(a0)      /* mem_sdcmd0 */
0204     sync
0205 
0206     /* wait for sdram to enter self-refresh mode */
0207     lui t0, 0x0300
0208 3:  lw  t1, 0x0850(a0)      /* mem_sdstat */
0209     and t2, t1, t0
0210     bne t2, t0, 3b
0211      nop
0212 
0213     /* disable SDRAM clocks */
0214     li  t0, ~(3<<28)
0215     lw  t1, 0x0840(a0)      /* mem_sdconfiga */
0216     and t1, t1, t0      /* clear CE[1:0] */
0217     sw  t1, 0x0840(a0)      /* mem_sdconfiga */
0218     sync
0219 
0220     DO_SLEEP
0221 4:
0222 
0223 END(alchemy_sleep_au1300)
0224 
0225 
0226     /* This is where we return upon wakeup.
0227      * Reload all of the registers and return.
0228      */
0229 LEAF(alchemy_sleep_wakeup)
0230     lw  k0, 0x20(sp)
0231     mtc0    k0, CP0_STATUS
0232     lw  k0, 0x1c(sp)
0233     mtc0    k0, CP0_CONTEXT
0234     lw  k0, 0x18(sp)
0235     mtc0    k0, CP0_PAGEMASK
0236     lw  k0, 0x14(sp)
0237     mtc0    k0, CP0_CONFIG
0238 
0239     /* We need to catch the early Alchemy SOCs with
0240      * the write-only Config[OD] bit and set it back to one...
0241      */
0242     jal au1x00_fixup_config_od
0243      nop
0244     lw  $1, PT_R1(sp)
0245     lw  $2, PT_R2(sp)
0246     lw  $3, PT_R3(sp)
0247     lw  $4, PT_R4(sp)
0248     lw  $5, PT_R5(sp)
0249     lw  $6, PT_R6(sp)
0250     lw  $7, PT_R7(sp)
0251     lw  $16, PT_R16(sp)
0252     lw  $17, PT_R17(sp)
0253     lw  $18, PT_R18(sp)
0254     lw  $19, PT_R19(sp)
0255     lw  $20, PT_R20(sp)
0256     lw  $21, PT_R21(sp)
0257     lw  $22, PT_R22(sp)
0258     lw  $23, PT_R23(sp)
0259     lw  $26, PT_R26(sp)
0260     lw  $27, PT_R27(sp)
0261     lw  $28, PT_R28(sp)
0262     lw  $30, PT_R30(sp)
0263     lw  $31, PT_R31(sp)
0264     jr  ra
0265      addiu  sp, PT_SIZE
0266 END(alchemy_sleep_wakeup)