hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* 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)