starfive: add new target for StarFive JH7100/7110 SoC
[openwrt/staging/981213.git] / target / linux / starfive / patches-6.1 / 0008-reset-Create-subdirectory-for-StarFive-drivers.patch
1 From ea9e5879793f9743fbfe613174900ab0c431ac0e Mon Sep 17 00:00:00 2001
2 From: Emil Renner Berthing <kernel@esmil.dk>
3 Date: Sat, 1 Apr 2023 19:19:20 +0800
4 Subject: [PATCH 008/122] reset: Create subdirectory for StarFive drivers
5
6 This moves the StarFive JH7100 reset driver to a new subdirectory in
7 preparation for adding more StarFive reset drivers.
8
9 Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
10 Tested-by: Tommaso Merciai <tomm.merciai@gmail.com>
11 Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
12 Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com>
13 Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
14 Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
15 Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
16 ---
17 drivers/reset/Kconfig | 8 +-------
18 drivers/reset/Makefile | 2 +-
19 drivers/reset/starfive/Kconfig | 8 ++++++++
20 drivers/reset/starfive/Makefile | 2 ++
21 drivers/reset/{ => starfive}/reset-starfive-jh7100.c | 0
22 5 files changed, 12 insertions(+), 8 deletions(-)
23 create mode 100644 drivers/reset/starfive/Kconfig
24 create mode 100644 drivers/reset/starfive/Makefile
25 rename drivers/reset/{ => starfive}/reset-starfive-jh7100.c (100%)
26
27 --- a/drivers/reset/Kconfig
28 +++ b/drivers/reset/Kconfig
29 @@ -232,13 +232,6 @@ config RESET_SOCFPGA
30 This enables the reset driver for the SoCFPGA ARMv7 platforms. This
31 driver gets initialized early during platform init calls.
32
33 -config RESET_STARFIVE_JH7100
34 - bool "StarFive JH7100 Reset Driver"
35 - depends on ARCH_STARFIVE || COMPILE_TEST
36 - default ARCH_STARFIVE
37 - help
38 - This enables the reset controller driver for the StarFive JH7100 SoC.
39 -
40 config RESET_SUNPLUS
41 bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
42 default ARCH_SUNPLUS
43 @@ -320,6 +313,7 @@ config RESET_ZYNQ
44 help
45 This enables the reset controller driver for Xilinx Zynq SoCs.
46
47 +source "drivers/reset/starfive/Kconfig"
48 source "drivers/reset/sti/Kconfig"
49 source "drivers/reset/hisilicon/Kconfig"
50 source "drivers/reset/tegra/Kconfig"
51 --- a/drivers/reset/Makefile
52 +++ b/drivers/reset/Makefile
53 @@ -1,6 +1,7 @@
54 # SPDX-License-Identifier: GPL-2.0
55 obj-y += core.o
56 obj-y += hisilicon/
57 +obj-y += starfive/
58 obj-$(CONFIG_ARCH_STI) += sti/
59 obj-$(CONFIG_ARCH_TEGRA) += tegra/
60 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
61 @@ -30,7 +31,6 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) +=
62 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
63 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
64 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
65 -obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
66 obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
67 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
68 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
69 --- /dev/null
70 +++ b/drivers/reset/starfive/Kconfig
71 @@ -0,0 +1,8 @@
72 +# SPDX-License-Identifier: GPL-2.0-only
73 +
74 +config RESET_STARFIVE_JH7100
75 + bool "StarFive JH7100 Reset Driver"
76 + depends on ARCH_STARFIVE || COMPILE_TEST
77 + default ARCH_STARFIVE
78 + help
79 + This enables the reset controller driver for the StarFive JH7100 SoC.
80 --- /dev/null
81 +++ b/drivers/reset/starfive/Makefile
82 @@ -0,0 +1,2 @@
83 +# SPDX-License-Identifier: GPL-2.0
84 +obj-$(CONFIG_RESET_STARFIVE_JH7100) += reset-starfive-jh7100.o
85 --- a/drivers/reset/reset-starfive-jh7100.c
86 +++ /dev/null
87 @@ -1,173 +0,0 @@
88 -// SPDX-License-Identifier: GPL-2.0-or-later
89 -/*
90 - * Reset driver for the StarFive JH7100 SoC
91 - *
92 - * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
93 - */
94 -
95 -#include <linux/bitmap.h>
96 -#include <linux/io.h>
97 -#include <linux/io-64-nonatomic-lo-hi.h>
98 -#include <linux/iopoll.h>
99 -#include <linux/mod_devicetable.h>
100 -#include <linux/platform_device.h>
101 -#include <linux/reset-controller.h>
102 -#include <linux/spinlock.h>
103 -
104 -#include <dt-bindings/reset/starfive-jh7100.h>
105 -
106 -/* register offsets */
107 -#define JH7100_RESET_ASSERT0 0x00
108 -#define JH7100_RESET_ASSERT1 0x04
109 -#define JH7100_RESET_ASSERT2 0x08
110 -#define JH7100_RESET_ASSERT3 0x0c
111 -#define JH7100_RESET_STATUS0 0x10
112 -#define JH7100_RESET_STATUS1 0x14
113 -#define JH7100_RESET_STATUS2 0x18
114 -#define JH7100_RESET_STATUS3 0x1c
115 -
116 -/*
117 - * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
118 - * line 32m + n, and writing a 0 deasserts the same line.
119 - * Most reset lines have their status inverted so a 0 bit in the STATUS
120 - * register means the line is asserted and a 1 means it's deasserted. A few
121 - * lines don't though, so store the expected value of the status registers when
122 - * all lines are asserted.
123 - */
124 -static const u64 jh7100_reset_asserted[2] = {
125 - /* STATUS0 */
126 - BIT_ULL_MASK(JH7100_RST_U74) |
127 - BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
128 - BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
129 - /* STATUS1 */
130 - BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
131 - BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
132 - /* STATUS2 */
133 - BIT_ULL_MASK(JH7100_RST_E24) |
134 - /* STATUS3 */
135 - 0,
136 -};
137 -
138 -struct jh7100_reset {
139 - struct reset_controller_dev rcdev;
140 - /* protect registers against concurrent read-modify-write */
141 - spinlock_t lock;
142 - void __iomem *base;
143 -};
144 -
145 -static inline struct jh7100_reset *
146 -jh7100_reset_from(struct reset_controller_dev *rcdev)
147 -{
148 - return container_of(rcdev, struct jh7100_reset, rcdev);
149 -}
150 -
151 -static int jh7100_reset_update(struct reset_controller_dev *rcdev,
152 - unsigned long id, bool assert)
153 -{
154 - struct jh7100_reset *data = jh7100_reset_from(rcdev);
155 - unsigned long offset = BIT_ULL_WORD(id);
156 - u64 mask = BIT_ULL_MASK(id);
157 - void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
158 - void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
159 - u64 done = jh7100_reset_asserted[offset] & mask;
160 - u64 value;
161 - unsigned long flags;
162 - int ret;
163 -
164 - if (!assert)
165 - done ^= mask;
166 -
167 - spin_lock_irqsave(&data->lock, flags);
168 -
169 - value = readq(reg_assert);
170 - if (assert)
171 - value |= mask;
172 - else
173 - value &= ~mask;
174 - writeq(value, reg_assert);
175 -
176 - /* if the associated clock is gated, deasserting might otherwise hang forever */
177 - ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
178 -
179 - spin_unlock_irqrestore(&data->lock, flags);
180 - return ret;
181 -}
182 -
183 -static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
184 - unsigned long id)
185 -{
186 - return jh7100_reset_update(rcdev, id, true);
187 -}
188 -
189 -static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
190 - unsigned long id)
191 -{
192 - return jh7100_reset_update(rcdev, id, false);
193 -}
194 -
195 -static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
196 - unsigned long id)
197 -{
198 - int ret;
199 -
200 - ret = jh7100_reset_assert(rcdev, id);
201 - if (ret)
202 - return ret;
203 -
204 - return jh7100_reset_deassert(rcdev, id);
205 -}
206 -
207 -static int jh7100_reset_status(struct reset_controller_dev *rcdev,
208 - unsigned long id)
209 -{
210 - struct jh7100_reset *data = jh7100_reset_from(rcdev);
211 - unsigned long offset = BIT_ULL_WORD(id);
212 - u64 mask = BIT_ULL_MASK(id);
213 - void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
214 - u64 value = readq(reg_status);
215 -
216 - return !((value ^ jh7100_reset_asserted[offset]) & mask);
217 -}
218 -
219 -static const struct reset_control_ops jh7100_reset_ops = {
220 - .assert = jh7100_reset_assert,
221 - .deassert = jh7100_reset_deassert,
222 - .reset = jh7100_reset_reset,
223 - .status = jh7100_reset_status,
224 -};
225 -
226 -static int __init jh7100_reset_probe(struct platform_device *pdev)
227 -{
228 - struct jh7100_reset *data;
229 -
230 - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
231 - if (!data)
232 - return -ENOMEM;
233 -
234 - data->base = devm_platform_ioremap_resource(pdev, 0);
235 - if (IS_ERR(data->base))
236 - return PTR_ERR(data->base);
237 -
238 - data->rcdev.ops = &jh7100_reset_ops;
239 - data->rcdev.owner = THIS_MODULE;
240 - data->rcdev.nr_resets = JH7100_RSTN_END;
241 - data->rcdev.dev = &pdev->dev;
242 - data->rcdev.of_node = pdev->dev.of_node;
243 - spin_lock_init(&data->lock);
244 -
245 - return devm_reset_controller_register(&pdev->dev, &data->rcdev);
246 -}
247 -
248 -static const struct of_device_id jh7100_reset_dt_ids[] = {
249 - { .compatible = "starfive,jh7100-reset" },
250 - { /* sentinel */ }
251 -};
252 -
253 -static struct platform_driver jh7100_reset_driver = {
254 - .driver = {
255 - .name = "jh7100-reset",
256 - .of_match_table = jh7100_reset_dt_ids,
257 - .suppress_bind_attrs = true,
258 - },
259 -};
260 -builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
261 --- /dev/null
262 +++ b/drivers/reset/starfive/reset-starfive-jh7100.c
263 @@ -0,0 +1,173 @@
264 +// SPDX-License-Identifier: GPL-2.0-or-later
265 +/*
266 + * Reset driver for the StarFive JH7100 SoC
267 + *
268 + * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
269 + */
270 +
271 +#include <linux/bitmap.h>
272 +#include <linux/io.h>
273 +#include <linux/io-64-nonatomic-lo-hi.h>
274 +#include <linux/iopoll.h>
275 +#include <linux/mod_devicetable.h>
276 +#include <linux/platform_device.h>
277 +#include <linux/reset-controller.h>
278 +#include <linux/spinlock.h>
279 +
280 +#include <dt-bindings/reset/starfive-jh7100.h>
281 +
282 +/* register offsets */
283 +#define JH7100_RESET_ASSERT0 0x00
284 +#define JH7100_RESET_ASSERT1 0x04
285 +#define JH7100_RESET_ASSERT2 0x08
286 +#define JH7100_RESET_ASSERT3 0x0c
287 +#define JH7100_RESET_STATUS0 0x10
288 +#define JH7100_RESET_STATUS1 0x14
289 +#define JH7100_RESET_STATUS2 0x18
290 +#define JH7100_RESET_STATUS3 0x1c
291 +
292 +/*
293 + * Writing a 1 to the n'th bit of the m'th ASSERT register asserts
294 + * line 32m + n, and writing a 0 deasserts the same line.
295 + * Most reset lines have their status inverted so a 0 bit in the STATUS
296 + * register means the line is asserted and a 1 means it's deasserted. A few
297 + * lines don't though, so store the expected value of the status registers when
298 + * all lines are asserted.
299 + */
300 +static const u64 jh7100_reset_asserted[2] = {
301 + /* STATUS0 */
302 + BIT_ULL_MASK(JH7100_RST_U74) |
303 + BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
304 + BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
305 + /* STATUS1 */
306 + BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
307 + BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
308 + /* STATUS2 */
309 + BIT_ULL_MASK(JH7100_RST_E24) |
310 + /* STATUS3 */
311 + 0,
312 +};
313 +
314 +struct jh7100_reset {
315 + struct reset_controller_dev rcdev;
316 + /* protect registers against concurrent read-modify-write */
317 + spinlock_t lock;
318 + void __iomem *base;
319 +};
320 +
321 +static inline struct jh7100_reset *
322 +jh7100_reset_from(struct reset_controller_dev *rcdev)
323 +{
324 + return container_of(rcdev, struct jh7100_reset, rcdev);
325 +}
326 +
327 +static int jh7100_reset_update(struct reset_controller_dev *rcdev,
328 + unsigned long id, bool assert)
329 +{
330 + struct jh7100_reset *data = jh7100_reset_from(rcdev);
331 + unsigned long offset = BIT_ULL_WORD(id);
332 + u64 mask = BIT_ULL_MASK(id);
333 + void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + offset * sizeof(u64);
334 + void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
335 + u64 done = jh7100_reset_asserted[offset] & mask;
336 + u64 value;
337 + unsigned long flags;
338 + int ret;
339 +
340 + if (!assert)
341 + done ^= mask;
342 +
343 + spin_lock_irqsave(&data->lock, flags);
344 +
345 + value = readq(reg_assert);
346 + if (assert)
347 + value |= mask;
348 + else
349 + value &= ~mask;
350 + writeq(value, reg_assert);
351 +
352 + /* if the associated clock is gated, deasserting might otherwise hang forever */
353 + ret = readq_poll_timeout_atomic(reg_status, value, (value & mask) == done, 0, 1000);
354 +
355 + spin_unlock_irqrestore(&data->lock, flags);
356 + return ret;
357 +}
358 +
359 +static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
360 + unsigned long id)
361 +{
362 + return jh7100_reset_update(rcdev, id, true);
363 +}
364 +
365 +static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
366 + unsigned long id)
367 +{
368 + return jh7100_reset_update(rcdev, id, false);
369 +}
370 +
371 +static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
372 + unsigned long id)
373 +{
374 + int ret;
375 +
376 + ret = jh7100_reset_assert(rcdev, id);
377 + if (ret)
378 + return ret;
379 +
380 + return jh7100_reset_deassert(rcdev, id);
381 +}
382 +
383 +static int jh7100_reset_status(struct reset_controller_dev *rcdev,
384 + unsigned long id)
385 +{
386 + struct jh7100_reset *data = jh7100_reset_from(rcdev);
387 + unsigned long offset = BIT_ULL_WORD(id);
388 + u64 mask = BIT_ULL_MASK(id);
389 + void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + offset * sizeof(u64);
390 + u64 value = readq(reg_status);
391 +
392 + return !((value ^ jh7100_reset_asserted[offset]) & mask);
393 +}
394 +
395 +static const struct reset_control_ops jh7100_reset_ops = {
396 + .assert = jh7100_reset_assert,
397 + .deassert = jh7100_reset_deassert,
398 + .reset = jh7100_reset_reset,
399 + .status = jh7100_reset_status,
400 +};
401 +
402 +static int __init jh7100_reset_probe(struct platform_device *pdev)
403 +{
404 + struct jh7100_reset *data;
405 +
406 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
407 + if (!data)
408 + return -ENOMEM;
409 +
410 + data->base = devm_platform_ioremap_resource(pdev, 0);
411 + if (IS_ERR(data->base))
412 + return PTR_ERR(data->base);
413 +
414 + data->rcdev.ops = &jh7100_reset_ops;
415 + data->rcdev.owner = THIS_MODULE;
416 + data->rcdev.nr_resets = JH7100_RSTN_END;
417 + data->rcdev.dev = &pdev->dev;
418 + data->rcdev.of_node = pdev->dev.of_node;
419 + spin_lock_init(&data->lock);
420 +
421 + return devm_reset_controller_register(&pdev->dev, &data->rcdev);
422 +}
423 +
424 +static const struct of_device_id jh7100_reset_dt_ids[] = {
425 + { .compatible = "starfive,jh7100-reset" },
426 + { /* sentinel */ }
427 +};
428 +
429 +static struct platform_driver jh7100_reset_driver = {
430 + .driver = {
431 + .name = "jh7100-reset",
432 + .of_match_table = jh7100_reset_dt_ids,
433 + .suppress_bind_attrs = true,
434 + },
435 +};
436 +builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);