forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
2.1 KiB
138 lines
2.1 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* Copyright (C) 2016 Broadcom Corporation |
|
*/ |
|
|
|
#include <asm/asm.h> |
|
#include <asm/regdef.h> |
|
#include <asm/mipsregs.h> |
|
#include <asm/bmips.h> |
|
|
|
#include "pm.h" |
|
|
|
.text |
|
.set noreorder |
|
.align 5 |
|
.global s3_reentry |
|
|
|
/* |
|
* a0: AON_CTRL base register |
|
* a1: D-Cache line size |
|
*/ |
|
LEAF(brcm_pm_do_s3) |
|
|
|
/* Get the address of s3_context */ |
|
la t0, gp_regs |
|
sw ra, 0(t0) |
|
sw s0, 4(t0) |
|
sw s1, 8(t0) |
|
sw s2, 12(t0) |
|
sw s3, 16(t0) |
|
sw s4, 20(t0) |
|
sw s5, 24(t0) |
|
sw s6, 28(t0) |
|
sw s7, 32(t0) |
|
sw gp, 36(t0) |
|
sw sp, 40(t0) |
|
sw fp, 44(t0) |
|
|
|
/* Save CP0 Status */ |
|
mfc0 t1, CP0_STATUS |
|
sw t1, 48(t0) |
|
|
|
/* Write-back gp registers - cache will be gone */ |
|
addiu t1, a1, -1 |
|
not t1 |
|
and t0, t1 |
|
|
|
/* Flush at least 64 bytes */ |
|
addiu t2, t0, 64 |
|
and t2, t1 |
|
|
|
1: cache 0x17, 0(t0) |
|
bne t0, t2, 1b |
|
addu t0, a1 |
|
|
|
/* Drop to deep standby */ |
|
li t1, PM_WARM_CONFIG |
|
sw zero, AON_CTRL_PM_CTRL(a0) |
|
lw zero, AON_CTRL_PM_CTRL(a0) |
|
sw t1, AON_CTRL_PM_CTRL(a0) |
|
lw t1, AON_CTRL_PM_CTRL(a0) |
|
|
|
li t1, (PM_WARM_CONFIG | PM_PWR_DOWN) |
|
sw t1, AON_CTRL_PM_CTRL(a0) |
|
lw t1, AON_CTRL_PM_CTRL(a0) |
|
|
|
/* Enable CP0 interrupt 2 and wait for interrupt */ |
|
mfc0 t0, CP0_STATUS |
|
|
|
li t1, ~(ST0_IM | ST0_IE) |
|
and t0, t1 |
|
ori t0, STATUSF_IP2 |
|
mtc0 t0, CP0_STATUS |
|
nop |
|
nop |
|
nop |
|
ori t0, ST0_IE |
|
mtc0 t0, CP0_STATUS |
|
|
|
/* Wait for interrupt */ |
|
wait |
|
nop |
|
|
|
s3_reentry: |
|
|
|
/* Clear call/return stack */ |
|
li t0, (0x06 << 16) |
|
mtc0 t0, $22, 2 |
|
ssnop |
|
ssnop |
|
ssnop |
|
|
|
/* Clear jump target buffer */ |
|
li t0, (0x04 << 16) |
|
mtc0 t0, $22, 2 |
|
ssnop |
|
ssnop |
|
ssnop |
|
|
|
sync |
|
nop |
|
|
|
/* Setup mmu defaults */ |
|
mtc0 zero, CP0_WIRED |
|
mtc0 zero, CP0_ENTRYHI |
|
li k0, PM_DEFAULT_MASK |
|
mtc0 k0, CP0_PAGEMASK |
|
|
|
li sp, BMIPS_WARM_RESTART_VEC |
|
la k0, plat_wired_tlb_setup |
|
jalr k0 |
|
nop |
|
|
|
/* Restore general purpose registers */ |
|
la t0, gp_regs |
|
lw fp, 44(t0) |
|
lw sp, 40(t0) |
|
lw gp, 36(t0) |
|
lw s7, 32(t0) |
|
lw s6, 28(t0) |
|
lw s5, 24(t0) |
|
lw s4, 20(t0) |
|
lw s3, 16(t0) |
|
lw s2, 12(t0) |
|
lw s1, 8(t0) |
|
lw s0, 4(t0) |
|
lw ra, 0(t0) |
|
|
|
/* Restore CP0 status */ |
|
lw t1, 48(t0) |
|
mtc0 t1, CP0_STATUS |
|
|
|
/* Return to caller */ |
|
li v0, 0 |
|
jr ra |
|
nop |
|
|
|
END(brcm_pm_do_s3)
|
|
|