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