/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 2002 Embedded Edge , LLC
* Author : dan @ embeddededge . com
*
* Sleep helper for Au1xxx sleep mode .
*/
#include <asm/asm.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>
.extern __flush_cache_all
.text
.set noreorder
.set noat
.align 5
/* preparatory stuff */
.macro SETUP_SLEEP
subu sp, PT_SIZE
sw $1 , PT_R1(sp)
sw $2 , PT_R2(sp)
sw $3 , PT_R3(sp)
sw $4 , PT_R4(sp)
sw $5 , PT_R5(sp)
sw $6 , PT_R6(sp)
sw $7 , PT_R7(sp)
sw $16 , PT_R16(sp)
sw $17 , PT_R17(sp)
sw $18 , PT_R18(sp)
sw $19 , PT_R19(sp)
sw $20 , PT_R20(sp)
sw $21 , PT_R21(sp)
sw $22 , PT_R22(sp)
sw $23 , PT_R23(sp)
sw $26 , PT_R26(sp)
sw $27 , PT_R27(sp)
sw $28 , PT_R28(sp)
sw $30 , PT_R30(sp)
sw $31 , PT_R31(sp)
mfc0 k0, CP0_STATUS
sw k0, 0 x20(sp)
mfc0 k0, CP0_CONTEXT
sw k0, 0 x1c(sp)
mfc0 k0, CP0_PAGEMASK
sw k0, 0 x18(sp)
mfc0 k0, CP0_CONFIG
sw k0, 0 x14(sp)
/* flush caches to make sure context is in memory */
la t1, __flush_cache_all
lw t0, 0 (t1)
jalr t0
nop
/* Now set up the scratch registers so the boot rom will
* return to this point upon wakeup .
* sys_scratch0 : SP
* sys_scratch1 : RA
*/
lui t3, 0 xb190 /* sys_xxx */
sw sp, 0 x0018(t3)
la k0, alchemy_sleep_wakeup /* resume path */
sw k0, 0 x001c(t3)
.endm
.macro DO_SLEEP
/* put power supply and processor to sleep */
sw zero, 0 x0078(t3) /* sys_slppwr */
sync
sw zero, 0 x007c(t3) /* sys_sleep */
sync
nop
nop
nop
nop
nop
nop
nop
nop
.endm
/* sleep code for Au1000/Au1100/Au1500 memory controller type */
LEAF(alchemy_sleep_au1000)
SETUP_SLEEP
/* cache following instructions, as memory gets put to sleep */
la t0, 1 f
.set arch=r4000
cache 0 x14, 0 (t0)
cache 0 x14, 32 (t0)
cache 0 x14, 64 (t0)
cache 0 x14, 96 (t0)
.set mips0
1 : lui a0, 0 xb400 /* mem_xxx */
sw zero, 0 x001c(a0) /* Precharge */
sync
sw zero, 0 x0020(a0) /* Auto Refresh */
sync
sw zero, 0 x0030(a0) /* Sleep */
sync
DO_SLEEP
END(alchemy_sleep_au1000)
/* sleep code for Au1550/Au1200 memory controller type */
LEAF(alchemy_sleep_au1550)
SETUP_SLEEP
/* cache following instructions, as memory gets put to sleep */
la t0, 1 f
.set arch=r4000
cache 0 x14, 0 (t0)
cache 0 x14, 32 (t0)
cache 0 x14, 64 (t0)
cache 0 x14, 96 (t0)
.set mips0
1 : lui a0, 0 xb400 /* mem_xxx */
sw zero, 0 x08c0(a0) /* Precharge */
sync
sw zero, 0 x08d0(a0) /* Self Refresh */
sync
/* wait for sdram to enter self-refresh mode */
lui t0, 0 x0100
2 : lw t1, 0 x0850(a0) /* mem_sdstat */
and t2, t1, t0
beq t2, zero, 2 b
nop
/* disable SDRAM clocks */
lui t0, 0 xcfff
ori t0, t0, 0 xffff
lw t1, 0 x0840(a0) /* mem_sdconfiga */
and t1, t0, t1 /* clear CE[1:0] */
sw t1, 0 x0840(a0) /* mem_sdconfiga */
sync
DO_SLEEP
END(alchemy_sleep_au1550)
/* sleepcode for Au1300 memory controller type */
LEAF(alchemy_sleep_au1300)
SETUP_SLEEP
/* cache following instructions, as memory gets put to sleep */
la t0, 2 f
la t1, 4 f
subu t2, t1, t0
.set arch=r4000
1 : cache 0 x14, 0 (t0)
subu t2, t2, 32
bgez t2, 1 b
addu t0, t0, 32
.set mips0
2 : lui a0, 0 xb400 /* mem_xxx */
/* disable all ports in mem_sdportcfga */
sw zero, 0 x868(a0) /* mem_sdportcfga */
sync
/* disable ODT */
li t0, 0 x03010000
sw t0, 0 x08d8(a0) /* mem_sdcmd0 */
sw t0, 0 x08dc(a0) /* mem_sdcmd1 */
sync
/* precharge */
li t0, 0 x23000400
sw t0, 0 x08dc(a0) /* mem_sdcmd1 */
sw t0, 0 x08d8(a0) /* mem_sdcmd0 */
sync
/* auto refresh */
sw zero, 0 x08c8(a0) /* mem_sdautoref */
sync
/* block access to the DDR */
lw t0, 0 x0848(a0) /* mem_sdconfigb */
li t1, (1 << 7 | 0 x3F)
or t0, t0, t1
sw t0, 0 x0848(a0) /* mem_sdconfigb */
sync
/* issue the Self Refresh command */
li t0, 0 x10000000
sw t0, 0 x08dc(a0) /* mem_sdcmd1 */
sw t0, 0 x08d8(a0) /* mem_sdcmd0 */
sync
/* wait for sdram to enter self-refresh mode */
lui t0, 0 x0300
3 : lw t1, 0 x0850(a0) /* mem_sdstat */
and t2, t1, t0
bne t2, t0, 3 b
nop
/* disable SDRAM clocks */
li t0, ~(3 <<28 )
lw t1, 0 x0840(a0) /* mem_sdconfiga */
and t1, t1, t0 /* clear CE[1:0] */
sw t1, 0 x0840(a0) /* mem_sdconfiga */
sync
DO_SLEEP
4 :
END(alchemy_sleep_au1300)
/* This is where we return upon wakeup.
* Reload all of the registers and return .
*/
LEAF(alchemy_sleep_wakeup)
lw k0, 0 x20(sp)
mtc0 k0, CP0_STATUS
lw k0, 0 x1c(sp)
mtc0 k0, CP0_CONTEXT
lw k0, 0 x18(sp)
mtc0 k0, CP0_PAGEMASK
lw k0, 0 x14(sp)
mtc0 k0, CP0_CONFIG
/* We need to catch the early Alchemy SOCs with
* the write - only Config [ OD ] bit and set it back to one . . .
*/
jal au1x00_fixup_config_od
nop
lw $1 , PT_R1(sp)
lw $2 , PT_R2(sp)
lw $3 , PT_R3(sp)
lw $4 , PT_R4(sp)
lw $5 , PT_R5(sp)
lw $6 , PT_R6(sp)
lw $7 , PT_R7(sp)
lw $16 , PT_R16(sp)
lw $17 , PT_R17(sp)
lw $18 , PT_R18(sp)
lw $19 , PT_R19(sp)
lw $20 , PT_R20(sp)
lw $21 , PT_R21(sp)
lw $22 , PT_R22(sp)
lw $23 , PT_R23(sp)
lw $26 , PT_R26(sp)
lw $27 , PT_R27(sp)
lw $28 , PT_R28(sp)
lw $30 , PT_R30(sp)
lw $31 , PT_R31(sp)
jr ra
addiu sp, PT_SIZE
END(alchemy_sleep_wakeup)
Messung V0.5 in Prozent C=79 H=99 G=89
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland