Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / drivers / soc / bcm / brcmstb / pm / s3-mips.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2016 Broadcom Corporation
4  */
5
6 #include <asm/asm.h>
7 #include <asm/regdef.h>
8 #include <asm/mipsregs.h>
9 #include <asm/bmips.h>
10
11 #include "pm.h"
12
13         .text
14         .set            noreorder
15         .align          5
16         .global         s3_reentry
17
18 /*
19  * a0: AON_CTRL base register
20  * a1: D-Cache line size
21  */
22 LEAF(brcm_pm_do_s3)
23
24         /* Get the address of s3_context */
25         la      t0, gp_regs
26         sw      ra, 0(t0)
27         sw      s0, 4(t0)
28         sw      s1, 8(t0)
29         sw      s2, 12(t0)
30         sw      s3, 16(t0)
31         sw      s4, 20(t0)
32         sw      s5, 24(t0)
33         sw      s6, 28(t0)
34         sw      s7, 32(t0)
35         sw      gp, 36(t0)
36         sw      sp, 40(t0)
37         sw      fp, 44(t0)
38
39         /* Save CP0 Status */
40         mfc0    t1, CP0_STATUS
41         sw      t1, 48(t0)
42
43         /* Write-back gp registers - cache will be gone */
44         addiu   t1, a1, -1
45         not     t1
46         and     t0, t1
47
48         /* Flush at least 64 bytes */
49         addiu   t2, t0, 64
50         and     t2, t1
51
52 1:      cache   0x17, 0(t0)
53         bne     t0, t2, 1b
54         addu    t0, a1
55
56         /* Drop to deep standby */
57         li      t1, PM_WARM_CONFIG
58         sw      zero, AON_CTRL_PM_CTRL(a0)
59         lw      zero, AON_CTRL_PM_CTRL(a0)
60         sw      t1, AON_CTRL_PM_CTRL(a0)
61         lw      t1, AON_CTRL_PM_CTRL(a0)
62
63         li      t1, (PM_WARM_CONFIG | PM_PWR_DOWN)
64         sw      t1, AON_CTRL_PM_CTRL(a0)
65         lw      t1, AON_CTRL_PM_CTRL(a0)
66
67         /* Enable CP0 interrupt 2 and wait for interrupt */
68         mfc0    t0, CP0_STATUS
69
70         li      t1, ~(ST0_IM | ST0_IE)
71         and     t0, t1
72         ori     t0, STATUSF_IP2
73         mtc0    t0, CP0_STATUS
74         nop
75         nop
76         nop
77         ori     t0, ST0_IE
78         mtc0    t0, CP0_STATUS
79
80         /* Wait for interrupt */
81         wait
82         nop
83
84 s3_reentry:
85
86         /* Clear call/return stack */
87         li      t0, (0x06 << 16)
88         mtc0    t0, $22, 2
89         ssnop
90         ssnop
91         ssnop
92
93         /* Clear jump target buffer */
94         li      t0, (0x04 << 16)
95         mtc0    t0, $22, 2
96         ssnop
97         ssnop
98         ssnop
99
100         sync
101         nop
102
103         /* Setup mmu defaults */
104         mtc0    zero, CP0_WIRED
105         mtc0    zero, CP0_ENTRYHI
106         li      k0, PM_DEFAULT_MASK
107         mtc0    k0, CP0_PAGEMASK
108
109         li      sp, BMIPS_WARM_RESTART_VEC
110         la      k0, plat_wired_tlb_setup
111         jalr    k0
112         nop
113
114         /* Restore general purpose registers */
115         la      t0, gp_regs
116         lw      fp, 44(t0)
117         lw      sp, 40(t0)
118         lw      gp, 36(t0)
119         lw      s7, 32(t0)
120         lw      s6, 28(t0)
121         lw      s5, 24(t0)
122         lw      s4, 20(t0)
123         lw      s3, 16(t0)
124         lw      s2, 12(t0)
125         lw      s1, 8(t0)
126         lw      s0, 4(t0)
127         lw      ra, 0(t0)
128
129         /* Restore CP0 status */
130         lw      t1, 48(t0)
131         mtc0    t1, CP0_STATUS
132
133         /* Return to caller */
134         li      v0, 0
135         jr      ra
136         nop
137
138 END(brcm_pm_do_s3)