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