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