test: stabilize test_efi_secboot
[platform/kernel/u-boot.git] / drivers / reset / reset-imx7.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2017, Impinj, Inc.
4  */
5
6 #include <malloc.h>
7 #include <asm/io.h>
8 #include <common.h>
9 #include <dm.h>
10 #include <dt-bindings/reset/imx7-reset.h>
11 #include <dt-bindings/reset/imx8mq-reset.h>
12 #include <reset-uclass.h>
13
14 struct imx7_reset_priv {
15         void __iomem *base;
16         struct reset_ops ops;
17 };
18
19 struct imx7_src_signal {
20         unsigned int offset, bit;
21 };
22
23 enum imx7_src_registers {
24         SRC_A7RCR0              = 0x0004,
25         SRC_M4RCR               = 0x000c,
26         SRC_ERCR                = 0x0014,
27         SRC_HSICPHY_RCR         = 0x001c,
28         SRC_USBOPHY1_RCR        = 0x0020,
29         SRC_USBOPHY2_RCR        = 0x0024,
30         SRC_MIPIPHY_RCR         = 0x0028,
31         SRC_PCIEPHY_RCR         = 0x002c,
32         SRC_DDRC_RCR            = 0x1000,
33 };
34
35 static const struct imx7_src_signal imx7_src_signals[IMX7_RESET_NUM] = {
36         [IMX7_RESET_A7_CORE_POR_RESET0] = { SRC_A7RCR0, BIT(0) },
37         [IMX7_RESET_A7_CORE_POR_RESET1] = { SRC_A7RCR0, BIT(1) },
38         [IMX7_RESET_A7_CORE_RESET0]     = { SRC_A7RCR0, BIT(4) },
39         [IMX7_RESET_A7_CORE_RESET1]     = { SRC_A7RCR0, BIT(5) },
40         [IMX7_RESET_A7_DBG_RESET0]      = { SRC_A7RCR0, BIT(8) },
41         [IMX7_RESET_A7_DBG_RESET1]      = { SRC_A7RCR0, BIT(9) },
42         [IMX7_RESET_A7_ETM_RESET0]      = { SRC_A7RCR0, BIT(12) },
43         [IMX7_RESET_A7_ETM_RESET1]      = { SRC_A7RCR0, BIT(13) },
44         [IMX7_RESET_A7_SOC_DBG_RESET]   = { SRC_A7RCR0, BIT(20) },
45         [IMX7_RESET_A7_L2RESET]         = { SRC_A7RCR0, BIT(21) },
46         [IMX7_RESET_SW_M4C_RST]         = { SRC_M4RCR, BIT(1) },
47         [IMX7_RESET_SW_M4P_RST]         = { SRC_M4RCR, BIT(2) },
48         [IMX7_RESET_EIM_RST]            = { SRC_ERCR, BIT(0) },
49         [IMX7_RESET_HSICPHY_PORT_RST]   = { SRC_HSICPHY_RCR, BIT(1) },
50         [IMX7_RESET_USBPHY1_POR]        = { SRC_USBOPHY1_RCR, BIT(0) },
51         [IMX7_RESET_USBPHY1_PORT_RST]   = { SRC_USBOPHY1_RCR, BIT(1) },
52         [IMX7_RESET_USBPHY2_POR]        = { SRC_USBOPHY2_RCR, BIT(0) },
53         [IMX7_RESET_USBPHY2_PORT_RST]   = { SRC_USBOPHY2_RCR, BIT(1) },
54         [IMX7_RESET_MIPI_PHY_MRST]      = { SRC_MIPIPHY_RCR, BIT(1) },
55         [IMX7_RESET_MIPI_PHY_SRST]      = { SRC_MIPIPHY_RCR, BIT(2) },
56         [IMX7_RESET_PCIEPHY]            = { SRC_PCIEPHY_RCR, BIT(2) | BIT(1) },
57         [IMX7_RESET_PCIEPHY_PERST]      = { SRC_PCIEPHY_RCR, BIT(3) },
58         [IMX7_RESET_PCIE_CTRL_APPS_EN]  = { SRC_PCIEPHY_RCR, BIT(6) },
59         [IMX7_RESET_PCIE_CTRL_APPS_TURNOFF] = { SRC_PCIEPHY_RCR, BIT(11) },
60         [IMX7_RESET_DDRC_PRST]          = { SRC_DDRC_RCR, BIT(0) },
61         [IMX7_RESET_DDRC_CORE_RST]      = { SRC_DDRC_RCR, BIT(1) },
62 };
63
64 static int imx7_reset_deassert_imx7(struct reset_ctl *rst)
65 {
66         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
67         const struct imx7_src_signal *sig = imx7_src_signals;
68         u32 val;
69
70         if (rst->id >= IMX7_RESET_NUM)
71                 return -EINVAL;
72
73         if (rst->id == IMX7_RESET_PCIEPHY) {
74                 /*
75                  * wait for more than 10us to release phy g_rst and
76                  * btnrst
77                  */
78                 udelay(10);
79         }
80
81         val = readl(priv->base + sig[rst->id].offset);
82         switch (rst->id) {
83         case IMX7_RESET_PCIE_CTRL_APPS_EN:
84                 val |= sig[rst->id].bit;
85                 break;
86         default:
87                 val &= ~sig[rst->id].bit;
88                 break;
89         }
90         writel(val, priv->base + sig[rst->id].offset);
91
92         return 0;
93 }
94
95 static int imx7_reset_assert_imx7(struct reset_ctl *rst)
96 {
97         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
98         const struct imx7_src_signal *sig = imx7_src_signals;
99         u32 val;
100
101         if (rst->id >= IMX7_RESET_NUM)
102                 return -EINVAL;
103
104         val = readl(priv->base + sig[rst->id].offset);
105         switch (rst->id) {
106         case IMX7_RESET_PCIE_CTRL_APPS_EN:
107                 val &= ~sig[rst->id].bit;
108                 break;
109         default:
110                 val |= sig[rst->id].bit;
111                 break;
112         }
113         writel(val, priv->base + sig[rst->id].offset);
114
115         return 0;
116 }
117
118 enum imx8mq_src_registers {
119         SRC_A53RCR0             = 0x0004,
120         SRC_HDMI_RCR            = 0x0030,
121         SRC_DISP_RCR            = 0x0034,
122         SRC_GPU_RCR             = 0x0040,
123         SRC_VPU_RCR             = 0x0044,
124         SRC_PCIE2_RCR           = 0x0048,
125         SRC_MIPIPHY1_RCR        = 0x004c,
126         SRC_MIPIPHY2_RCR        = 0x0050,
127         SRC_DDRC2_RCR           = 0x1004,
128 };
129
130 static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
131         [IMX8MQ_RESET_A53_CORE_POR_RESET0]      = { SRC_A53RCR0, BIT(0) },
132         [IMX8MQ_RESET_A53_CORE_POR_RESET1]      = { SRC_A53RCR0, BIT(1) },
133         [IMX8MQ_RESET_A53_CORE_POR_RESET2]      = { SRC_A53RCR0, BIT(2) },
134         [IMX8MQ_RESET_A53_CORE_POR_RESET3]      = { SRC_A53RCR0, BIT(3) },
135         [IMX8MQ_RESET_A53_CORE_RESET0]          = { SRC_A53RCR0, BIT(4) },
136         [IMX8MQ_RESET_A53_CORE_RESET1]          = { SRC_A53RCR0, BIT(5) },
137         [IMX8MQ_RESET_A53_CORE_RESET2]          = { SRC_A53RCR0, BIT(6) },
138         [IMX8MQ_RESET_A53_CORE_RESET3]          = { SRC_A53RCR0, BIT(7) },
139         [IMX8MQ_RESET_A53_DBG_RESET0]           = { SRC_A53RCR0, BIT(8) },
140         [IMX8MQ_RESET_A53_DBG_RESET1]           = { SRC_A53RCR0, BIT(9) },
141         [IMX8MQ_RESET_A53_DBG_RESET2]           = { SRC_A53RCR0, BIT(10) },
142         [IMX8MQ_RESET_A53_DBG_RESET3]           = { SRC_A53RCR0, BIT(11) },
143         [IMX8MQ_RESET_A53_ETM_RESET0]           = { SRC_A53RCR0, BIT(12) },
144         [IMX8MQ_RESET_A53_ETM_RESET1]           = { SRC_A53RCR0, BIT(13) },
145         [IMX8MQ_RESET_A53_ETM_RESET2]           = { SRC_A53RCR0, BIT(14) },
146         [IMX8MQ_RESET_A53_ETM_RESET3]           = { SRC_A53RCR0, BIT(15) },
147         [IMX8MQ_RESET_A53_SOC_DBG_RESET]        = { SRC_A53RCR0, BIT(20) },
148         [IMX8MQ_RESET_A53_L2RESET]              = { SRC_A53RCR0, BIT(21) },
149         [IMX8MQ_RESET_SW_NON_SCLR_M4C_RST]      = { SRC_M4RCR, BIT(0) },
150         [IMX8MQ_RESET_OTG1_PHY_RESET]           = { SRC_USBOPHY1_RCR, BIT(0) },
151         [IMX8MQ_RESET_OTG2_PHY_RESET]           = { SRC_USBOPHY2_RCR, BIT(0) },
152         [IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N]    = { SRC_MIPIPHY_RCR, BIT(1) },
153         [IMX8MQ_RESET_MIPI_DSI_RESET_N]         = { SRC_MIPIPHY_RCR, BIT(2) },
154         [IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(3) },
155         [IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(4) },
156         [IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N]    = { SRC_MIPIPHY_RCR, BIT(5) },
157         [IMX8MQ_RESET_PCIEPHY]                  = { SRC_PCIEPHY_RCR,
158                                                     BIT(2) | BIT(1) },
159         [IMX8MQ_RESET_PCIEPHY_PERST]            = { SRC_PCIEPHY_RCR, BIT(3) },
160         [IMX8MQ_RESET_PCIE_CTRL_APPS_EN]        = { SRC_PCIEPHY_RCR, BIT(6) },
161         [IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF]   = { SRC_PCIEPHY_RCR, BIT(11) },
162         [IMX8MQ_RESET_HDMI_PHY_APB_RESET]       = { SRC_HDMI_RCR, BIT(0) },
163         [IMX8MQ_RESET_DISP_RESET]               = { SRC_DISP_RCR, BIT(0) },
164         [IMX8MQ_RESET_GPU_RESET]                = { SRC_GPU_RCR, BIT(0) },
165         [IMX8MQ_RESET_VPU_RESET]                = { SRC_VPU_RCR, BIT(0) },
166         [IMX8MQ_RESET_PCIEPHY2]                 = { SRC_PCIE2_RCR,
167                                                     BIT(2) | BIT(1) },
168         [IMX8MQ_RESET_PCIEPHY2_PERST]           = { SRC_PCIE2_RCR, BIT(3) },
169         [IMX8MQ_RESET_PCIE2_CTRL_APPS_EN]       = { SRC_PCIE2_RCR, BIT(6) },
170         [IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF]  = { SRC_PCIE2_RCR, BIT(11) },
171         [IMX8MQ_RESET_MIPI_CSI1_CORE_RESET]     = { SRC_MIPIPHY1_RCR, BIT(0) },
172         [IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET]  = { SRC_MIPIPHY1_RCR, BIT(1) },
173         [IMX8MQ_RESET_MIPI_CSI1_ESC_RESET]      = { SRC_MIPIPHY1_RCR, BIT(2) },
174         [IMX8MQ_RESET_MIPI_CSI2_CORE_RESET]     = { SRC_MIPIPHY2_RCR, BIT(0) },
175         [IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET]  = { SRC_MIPIPHY2_RCR, BIT(1) },
176         [IMX8MQ_RESET_MIPI_CSI2_ESC_RESET]      = { SRC_MIPIPHY2_RCR, BIT(2) },
177         [IMX8MQ_RESET_DDRC1_PRST]               = { SRC_DDRC_RCR, BIT(0) },
178         [IMX8MQ_RESET_DDRC1_CORE_RESET]         = { SRC_DDRC_RCR, BIT(1) },
179         [IMX8MQ_RESET_DDRC1_PHY_RESET]          = { SRC_DDRC_RCR, BIT(2) },
180         [IMX8MQ_RESET_DDRC2_PHY_RESET]          = { SRC_DDRC2_RCR, BIT(0) },
181         [IMX8MQ_RESET_DDRC2_CORE_RESET]         = { SRC_DDRC2_RCR, BIT(1) },
182         [IMX8MQ_RESET_DDRC2_PRST]               = { SRC_DDRC2_RCR, BIT(2) },
183 };
184
185 static int imx7_reset_deassert_imx8mq(struct reset_ctl *rst)
186 {
187         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
188         const struct imx7_src_signal *sig = imx8mq_src_signals;
189         u32 val;
190
191         if (rst->id >= IMX8MQ_RESET_NUM)
192                 return -EINVAL;
193
194         if (rst->id == IMX8MQ_RESET_PCIEPHY ||
195             rst->id == IMX8MQ_RESET_PCIEPHY2) {
196                 /*
197                  * wait for more than 10us to release phy g_rst and
198                  * btnrst
199                  */
200                 udelay(10);
201         }
202
203         val = readl(priv->base + sig[rst->id].offset);
204         switch (rst->id) {
205         case IMX8MQ_RESET_PCIE_CTRL_APPS_EN:
206         case IMX8MQ_RESET_PCIE2_CTRL_APPS_EN:   /* fallthrough */
207         case IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N:        /* fallthrough */
208         case IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N: /* fallthrough */
209         case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N: /* fallthrough */
210         case IMX8MQ_RESET_MIPI_DSI_RESET_N:     /* fallthrough */
211         case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N:        /* fallthrough */
212                 val |= sig[rst->id].bit;
213                 break;
214         default:
215                 val &= ~sig[rst->id].bit;
216                 break;
217         }
218         writel(val, priv->base + sig[rst->id].offset);
219
220         return 0;
221 }
222
223 static int imx7_reset_assert_imx8mq(struct reset_ctl *rst)
224 {
225         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
226         const struct imx7_src_signal *sig = imx8mq_src_signals;
227         u32 val;
228
229         if (rst->id >= IMX8MQ_RESET_NUM)
230                 return -EINVAL;
231
232         val = readl(priv->base + sig[rst->id].offset);
233         switch (rst->id) {
234         case IMX8MQ_RESET_PCIE_CTRL_APPS_EN:
235         case IMX8MQ_RESET_PCIE2_CTRL_APPS_EN:   /* fallthrough */
236         case IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N:        /* fallthrough */
237         case IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N: /* fallthrough */
238         case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N: /* fallthrough */
239         case IMX8MQ_RESET_MIPI_DSI_RESET_N:     /* fallthrough */
240         case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N:        /* fallthrough */
241                 val &= ~sig[rst->id].bit;
242                 break;
243         default:
244                 val |= sig[rst->id].bit;
245                 break;
246         }
247         writel(val, priv->base + sig[rst->id].offset);
248
249         return 0;
250 }
251
252 static int imx7_reset_assert(struct reset_ctl *rst)
253 {
254         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
255         return priv->ops.rst_assert(rst);
256 }
257
258 static int imx7_reset_deassert(struct reset_ctl *rst)
259 {
260         struct imx7_reset_priv *priv = dev_get_priv(rst->dev);
261         return priv->ops.rst_deassert(rst);
262 }
263
264 static int imx7_reset_free(struct reset_ctl *rst)
265 {
266         return 0;
267 }
268
269 static int imx7_reset_request(struct reset_ctl *rst)
270 {
271         return 0;
272 }
273
274 static const struct reset_ops imx7_reset_reset_ops = {
275         .request = imx7_reset_request,
276         .rfree = imx7_reset_free,
277         .rst_assert = imx7_reset_assert,
278         .rst_deassert = imx7_reset_deassert,
279 };
280
281 static const struct udevice_id imx7_reset_ids[] = {
282         { .compatible = "fsl,imx7d-src" },
283         { .compatible = "fsl,imx8mq-src" },
284         { }
285 };
286
287 static int imx7_reset_probe(struct udevice *dev)
288 {
289         struct imx7_reset_priv *priv = dev_get_priv(dev);
290
291         priv->base = dev_remap_addr(dev);
292         if (!priv->base)
293                 return -ENOMEM;
294
295         if (device_is_compatible(dev, "fsl,imx8mq-src")) {
296                 priv->ops.rst_assert = imx7_reset_assert_imx8mq;
297                 priv->ops.rst_deassert = imx7_reset_deassert_imx8mq;
298         } else if (device_is_compatible(dev, "fsl,imx7d-src")) {
299                 priv->ops.rst_assert = imx7_reset_assert_imx7;
300                 priv->ops.rst_deassert = imx7_reset_deassert_imx7;
301         }
302
303         return 0;
304 }
305
306 U_BOOT_DRIVER(imx7_reset) = {
307         .name = "imx7_reset",
308         .id = UCLASS_RESET,
309         .of_match = imx7_reset_ids,
310         .ops = &imx7_reset_reset_ops,
311         .probe = imx7_reset_probe,
312         .priv_auto_alloc_size = sizeof(struct imx7_reset_priv),
313 };