forked from Minki/linux
2874c5fd28
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license as published by the free software foundation either version 2 of the license or at your option any later version extracted by the scancode license scanner the SPDX license identifier GPL-2.0-or-later has been chosen to replace the boilerplate/reference in 3029 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
267 lines
4.9 KiB
ArmAsm
267 lines
4.9 KiB
ArmAsm
/* 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, 0x20(sp)
|
|
mfc0 k0, CP0_CONTEXT
|
|
sw k0, 0x1c(sp)
|
|
mfc0 k0, CP0_PAGEMASK
|
|
sw k0, 0x18(sp)
|
|
mfc0 k0, CP0_CONFIG
|
|
sw k0, 0x14(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, 0xb190 /* sys_xxx */
|
|
sw sp, 0x0018(t3)
|
|
la k0, alchemy_sleep_wakeup /* resume path */
|
|
sw k0, 0x001c(t3)
|
|
.endm
|
|
|
|
.macro DO_SLEEP
|
|
/* put power supply and processor to sleep */
|
|
sw zero, 0x0078(t3) /* sys_slppwr */
|
|
sync
|
|
sw zero, 0x007c(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, 1f
|
|
.set arch=r4000
|
|
cache 0x14, 0(t0)
|
|
cache 0x14, 32(t0)
|
|
cache 0x14, 64(t0)
|
|
cache 0x14, 96(t0)
|
|
.set mips0
|
|
|
|
1: lui a0, 0xb400 /* mem_xxx */
|
|
sw zero, 0x001c(a0) /* Precharge */
|
|
sync
|
|
sw zero, 0x0020(a0) /* Auto Refresh */
|
|
sync
|
|
sw zero, 0x0030(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, 1f
|
|
.set arch=r4000
|
|
cache 0x14, 0(t0)
|
|
cache 0x14, 32(t0)
|
|
cache 0x14, 64(t0)
|
|
cache 0x14, 96(t0)
|
|
.set mips0
|
|
|
|
1: lui a0, 0xb400 /* mem_xxx */
|
|
sw zero, 0x08c0(a0) /* Precharge */
|
|
sync
|
|
sw zero, 0x08d0(a0) /* Self Refresh */
|
|
sync
|
|
|
|
/* wait for sdram to enter self-refresh mode */
|
|
lui t0, 0x0100
|
|
2: lw t1, 0x0850(a0) /* mem_sdstat */
|
|
and t2, t1, t0
|
|
beq t2, zero, 2b
|
|
nop
|
|
|
|
/* disable SDRAM clocks */
|
|
lui t0, 0xcfff
|
|
ori t0, t0, 0xffff
|
|
lw t1, 0x0840(a0) /* mem_sdconfiga */
|
|
and t1, t0, t1 /* clear CE[1:0] */
|
|
sw t1, 0x0840(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, 2f
|
|
la t1, 4f
|
|
subu t2, t1, t0
|
|
|
|
.set arch=r4000
|
|
|
|
1: cache 0x14, 0(t0)
|
|
subu t2, t2, 32
|
|
bgez t2, 1b
|
|
addu t0, t0, 32
|
|
|
|
.set mips0
|
|
|
|
2: lui a0, 0xb400 /* mem_xxx */
|
|
|
|
/* disable all ports in mem_sdportcfga */
|
|
sw zero, 0x868(a0) /* mem_sdportcfga */
|
|
sync
|
|
|
|
/* disable ODT */
|
|
li t0, 0x03010000
|
|
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
|
|
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
|
|
sync
|
|
|
|
/* precharge */
|
|
li t0, 0x23000400
|
|
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
|
|
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
|
|
sync
|
|
|
|
/* auto refresh */
|
|
sw zero, 0x08c8(a0) /* mem_sdautoref */
|
|
sync
|
|
|
|
/* block access to the DDR */
|
|
lw t0, 0x0848(a0) /* mem_sdconfigb */
|
|
li t1, (1 << 7 | 0x3F)
|
|
or t0, t0, t1
|
|
sw t0, 0x0848(a0) /* mem_sdconfigb */
|
|
sync
|
|
|
|
/* issue the Self Refresh command */
|
|
li t0, 0x10000000
|
|
sw t0, 0x08dc(a0) /* mem_sdcmd1 */
|
|
sw t0, 0x08d8(a0) /* mem_sdcmd0 */
|
|
sync
|
|
|
|
/* wait for sdram to enter self-refresh mode */
|
|
lui t0, 0x0300
|
|
3: lw t1, 0x0850(a0) /* mem_sdstat */
|
|
and t2, t1, t0
|
|
bne t2, t0, 3b
|
|
nop
|
|
|
|
/* disable SDRAM clocks */
|
|
li t0, ~(3<<28)
|
|
lw t1, 0x0840(a0) /* mem_sdconfiga */
|
|
and t1, t1, t0 /* clear CE[1:0] */
|
|
sw t1, 0x0840(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, 0x20(sp)
|
|
mtc0 k0, CP0_STATUS
|
|
lw k0, 0x1c(sp)
|
|
mtc0 k0, CP0_CONTEXT
|
|
lw k0, 0x18(sp)
|
|
mtc0 k0, CP0_PAGEMASK
|
|
lw k0, 0x14(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)
|