1 /*
2 * Renesas SCP/MCP Software
3 * Copyright (c) 2020-2021, Renesas Electronics Corporation. All rights
4 * reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include <mmio.h>
10 #include <rcar_common.h>
11 #include <rcar_iic_dvfs.h>
12 #include <rcar_mmap.h>
13 #include <rcar_pwc.h>
14
15 #include <fwk_attributes.h>
16
17 #include <arch_helpers.h>
18
19 #include <stdint.h>
20 #include <stdlib.h>
21
22 /* Suspend to ram */
23 #define DBSC4_REG_BASE (0xE6790000U)
24 #define DBSC4_REG_DBSYSCNT0 (DBSC4_REG_BASE + 0x0100U)
25 #define DBSC4_REG_DBACEN (DBSC4_REG_BASE + 0x0200U)
26 #define DBSC4_REG_DBCMD (DBSC4_REG_BASE + 0x0208U)
27 #define DBSC4_REG_DBWAIT (DBSC4_REG_BASE + 0x0210U)
28 #define DBSC4_REG_DBRFEN (DBSC4_REG_BASE + 0x0204U)
29
30 #define DBSC4_REG_DBCALCNF (DBSC4_REG_BASE + 0x0424U)
31 #define DBSC4_REG_DBDFIPMSTRCNF (DBSC4_REG_BASE + 0x0520U)
32
33 #define DBSC4_REG_DBCAM0CTRL0 (DBSC4_REG_BASE + 0x0940U)
34 #define DBSC4_REG_DBCAM0STAT0 (DBSC4_REG_BASE + 0x0980U)
35 #define DBSC4_REG_DBCAM1STAT0 (DBSC4_REG_BASE + 0x0990U)
36 #define DBSC4_REG_DBCAM2STAT0 (DBSC4_REG_BASE + 0x09A0U)
37 #define DBSC4_REG_DBCAM3STAT0 (DBSC4_REG_BASE + 0x09B0U)
38
39 #define DBSC4_BIT_DBCAMxSTAT0 (0x00000001U)
40 #define DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN (0x00000001U)
41 #define DBSC4_SET_DBCMD_OPC_PRE (0x04000000U)
42 #define DBSC4_SET_DBCMD_OPC_SR (0x0A000000U)
43 #define DBSC4_SET_DBCMD_OPC_PD (0x08000000U)
44 #define DBSC4_SET_DBCMD_OPC_MRW (0x0E000000U)
45 #define DBSC4_SET_DBCMD_ARG_ENTER (0x00000000U)
46 #define DBSC4_SET_DBCMD_ARG_MRW_ODTC (0x00000B00U)
47 #define DBSC4_SET_DBCMD_CH_ALL (0x00800000U)
48 #define DBSC4_SET_DBCMD_RANK_ALL (0x00040000U)
49 #define DBSC4_SET_DBCMD_ARG_ALL (0x00000010U)
50 #define DBSC4_SET_DBSYSCNT0_WRITE_ENABLE (0x00001234U)
51 #define DBSC4_SET_DBSYSCNT0_WRITE_DISABLE (0x00000000U)
52
53 #define BIT_BKUP_CTRL_OUT ((uint8_t)(1U << 4))
54 #define PMIC_RETRY_MAX (100U)
55 #define PMIC_BKUP_MODE_CNT (0x20U)
56 #define PMIC_QLLM_CNT (0x27U)
57 #define DVFS_SET_VID_0V (0x00)
58 #define P_ALL_OFF (0x80)
59
60 #define SRESCR_CODE (0x5AA5U << 16)
61 #define BIT_SOFTRESET (1U << 15)
62 #define SCTLR_EL3_M_BIT ((uint32_t)1U << 0)
63 #define RCAR_CONV_MICROSEC (1000000U)
64
65 #define DBCAM_FLUSH(__bit) \
66 do { \
67 ; \
68 } while (!( \
69 mmio_read_32(DBSC4_REG_DBCAM##__bit##STAT0) & DBSC4_BIT_DBCAMxSTAT0))
70
71 extern uint32_t rcar_pwrc_switch_stack(
72 uintptr_t jump,
73 uintptr_t stack,
74 void *arg);
75
76 extern void panic(void);
77
rcar_pwrc_set_self_refresh(void)78 static void FWK_SECTION(".system_ram") rcar_pwrc_set_self_refresh(void)
79 {
80 uint32_t reg = mmio_read_32(RCAR_PRR);
81 uint32_t cut, product;
82
83 product = reg & RCAR_PRODUCT_MASK;
84 cut = reg & RCAR_CUT_MASK;
85
86 if (!((product == RCAR_PRODUCT_M3 && cut < RCAR_CUT_VER30) ||
87 (product == RCAR_PRODUCT_H3 && cut < RCAR_CUT_VER20)))
88 mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE);
89
90 /* DFI_PHYMSTR_ACK setting */
91 mmio_write_32(
92 DBSC4_REG_DBDFIPMSTRCNF,
93 mmio_read_32(DBSC4_REG_DBDFIPMSTRCNF) &
94 (~DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN));
95
96 /* Set the Self-Refresh mode */
97 mmio_write_32(DBSC4_REG_DBACEN, 0);
98
99 if (product == RCAR_PRODUCT_H3 && cut < RCAR_CUT_VER20)
100 udelay(100);
101 else if (product == RCAR_PRODUCT_H3) {
102 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
103 DBCAM_FLUSH(0);
104 DBCAM_FLUSH(1);
105 DBCAM_FLUSH(2);
106 DBCAM_FLUSH(3);
107 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
108 } else if (product == RCAR_PRODUCT_M3) {
109 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
110 DBCAM_FLUSH(0);
111 DBCAM_FLUSH(1);
112 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
113 } else {
114 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
115 DBCAM_FLUSH(0);
116 mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
117 }
118
119 /* Set the SDRAM calibration configuration register */
120 mmio_write_32(DBSC4_REG_DBCALCNF, 0);
121
122 reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL |
123 DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL;
124 mmio_write_32(DBSC4_REG_DBCMD, reg);
125 while (mmio_read_32(DBSC4_REG_DBWAIT))
126 continue;
127
128 /* Self-Refresh entry command */
129 reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL |
130 DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
131 mmio_write_32(DBSC4_REG_DBCMD, reg);
132 while (mmio_read_32(DBSC4_REG_DBWAIT))
133 continue;
134
135 /* Mode Register Write command. (ODT disabled) */
136 reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL |
137 DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC;
138 mmio_write_32(DBSC4_REG_DBCMD, reg);
139 while (mmio_read_32(DBSC4_REG_DBWAIT))
140 continue;
141
142 /* Power Down entry command */
143 reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL |
144 DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
145 mmio_write_32(DBSC4_REG_DBCMD, reg);
146 while (mmio_read_32(DBSC4_REG_DBWAIT))
147 continue;
148
149 /* Set the auto-refresh enable register */
150 mmio_write_32(DBSC4_REG_DBRFEN, 0U);
151 udelay(1);
152
153 if (product == RCAR_PRODUCT_M3 && cut < RCAR_CUT_VER30)
154 return;
155
156 if (product == RCAR_PRODUCT_H3 && cut < RCAR_CUT_VER20)
157 return;
158
159 mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE);
160 }
161
rcar_pwrc_go_suspend_to_ram(void)162 void FWK_SECTION(".system_ram") FWK_NOINLINE rcar_pwrc_go_suspend_to_ram(void)
163 {
164 int32_t rc = -1, qllm = -1;
165 uint8_t mode;
166 uint32_t i;
167
168 rcar_pwrc_set_self_refresh();
169
170 /* Set QLLM Cnt Disable */
171 for (i = 0; (i < PMIC_RETRY_MAX) && (qllm != 0); i++)
172 qllm = rcar_iic_dvfs_send(PMIC, PMIC_QLLM_CNT, 0);
173
174 /* Set trigger of power down to PMIV */
175 for (i = 0; (i < PMIC_RETRY_MAX) && (rc != 0) && (qllm == 0); i++) {
176 rc = rcar_iic_dvfs_receive(PMIC, PMIC_BKUP_MODE_CNT, &mode);
177 if (rc == 0) {
178 mode |= BIT_BKUP_CTRL_OUT;
179 rc = rcar_iic_dvfs_send(PMIC, PMIC_BKUP_MODE_CNT, mode);
180 }
181 }
182
183 wfi();
184
185 while (1)
186 continue;
187 }
188
rcar_pwrc_set_suspend_to_ram(void)189 void rcar_pwrc_set_suspend_to_ram(void)
190 {
191 uintptr_t jump = (uintptr_t)&rcar_pwrc_go_suspend_to_ram;
192 uintptr_t stack = (uintptr_t)(SCP_SRAM_STACK_BASE + SCP_SRAM_STACK_SIZE);
193 uint32_t sctlr;
194
195 /* disable MMU */
196 sctlr = (uint32_t)read_sctlr_el3();
197 sctlr &= (uint32_t)~SCTLR_EL3_M_BIT;
198 write_sctlr_el3((uint64_t)sctlr);
199
200 rcar_pwrc_switch_stack(jump, stack, NULL);
201 }
202
rcar_system_off(void)203 void rcar_system_off(void)
204 {
205 if (rcar_iic_dvfs_send(PMIC, DVFS_SET_VID, DVFS_SET_VID_0V))
206 panic();
207 }
208
rcar_system_reset(void)209 void rcar_system_reset(void)
210 {
211 #if RCAR_SOFTWARE_RESET
212 mmio_write_32(RCAR_SRESCR, SRESCR_CODE | BIT_SOFTRESET);
213 #else
214 if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF))
215 panic();
216 #endif /* RCAR_SOFTWARE_RESET */
217 }
218