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
6 This moves the StarFive JH7100 reset driver to a new subdirectory in
7 preparation for adding more StarFive reset drivers.
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>
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%)
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.
33 -config RESET_STARFIVE_JH7100
34 - bool "StarFive JH7100 Reset Driver"
35 - depends on ARCH_STARFIVE || COMPILE_TEST
36 - default ARCH_STARFIVE
38 - This enables the reset controller driver for the StarFive JH7100 SoC.
41 bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
43 @@ -320,6 +313,7 @@ config RESET_ZYNQ
45 This enables the reset controller driver for Xilinx Zynq SoCs.
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
54 # SPDX-License-Identifier: GPL-2.0
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
70 +++ b/drivers/reset/starfive/Kconfig
72 +# SPDX-License-Identifier: GPL-2.0-only
74 +config RESET_STARFIVE_JH7100
75 + bool "StarFive JH7100 Reset Driver"
76 + depends on ARCH_STARFIVE || COMPILE_TEST
77 + default ARCH_STARFIVE
79 + This enables the reset controller driver for the StarFive JH7100 SoC.
81 +++ b/drivers/reset/starfive/Makefile
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
88 -// SPDX-License-Identifier: GPL-2.0-or-later
90 - * Reset driver for the StarFive JH7100 SoC
92 - * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
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>
104 -#include <dt-bindings/reset/starfive-jh7100.h>
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
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.
124 -static const u64 jh7100_reset_asserted[2] = {
126 - BIT_ULL_MASK(JH7100_RST_U74) |
127 - BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
128 - BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
130 - BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
131 - BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
133 - BIT_ULL_MASK(JH7100_RST_E24) |
138 -struct jh7100_reset {
139 - struct reset_controller_dev rcdev;
140 - /* protect registers against concurrent read-modify-write */
142 - void __iomem *base;
145 -static inline struct jh7100_reset *
146 -jh7100_reset_from(struct reset_controller_dev *rcdev)
148 - return container_of(rcdev, struct jh7100_reset, rcdev);
151 -static int jh7100_reset_update(struct reset_controller_dev *rcdev,
152 - unsigned long id, bool assert)
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;
161 - unsigned long flags;
167 - spin_lock_irqsave(&data->lock, flags);
169 - value = readq(reg_assert);
174 - writeq(value, reg_assert);
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);
179 - spin_unlock_irqrestore(&data->lock, flags);
183 -static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
186 - return jh7100_reset_update(rcdev, id, true);
189 -static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
192 - return jh7100_reset_update(rcdev, id, false);
195 -static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
200 - ret = jh7100_reset_assert(rcdev, id);
204 - return jh7100_reset_deassert(rcdev, id);
207 -static int jh7100_reset_status(struct reset_controller_dev *rcdev,
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);
216 - return !((value ^ jh7100_reset_asserted[offset]) & mask);
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,
226 -static int __init jh7100_reset_probe(struct platform_device *pdev)
228 - struct jh7100_reset *data;
230 - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
234 - data->base = devm_platform_ioremap_resource(pdev, 0);
235 - if (IS_ERR(data->base))
236 - return PTR_ERR(data->base);
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);
245 - return devm_reset_controller_register(&pdev->dev, &data->rcdev);
248 -static const struct of_device_id jh7100_reset_dt_ids[] = {
249 - { .compatible = "starfive,jh7100-reset" },
253 -static struct platform_driver jh7100_reset_driver = {
255 - .name = "jh7100-reset",
256 - .of_match_table = jh7100_reset_dt_ids,
257 - .suppress_bind_attrs = true,
260 -builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);
262 +++ b/drivers/reset/starfive/reset-starfive-jh7100.c
264 +// SPDX-License-Identifier: GPL-2.0-or-later
266 + * Reset driver for the StarFive JH7100 SoC
268 + * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk>
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>
280 +#include <dt-bindings/reset/starfive-jh7100.h>
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
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.
300 +static const u64 jh7100_reset_asserted[2] = {
302 + BIT_ULL_MASK(JH7100_RST_U74) |
303 + BIT_ULL_MASK(JH7100_RST_VP6_DRESET) |
304 + BIT_ULL_MASK(JH7100_RST_VP6_BRESET) |
306 + BIT_ULL_MASK(JH7100_RST_HIFI4_DRESET) |
307 + BIT_ULL_MASK(JH7100_RST_HIFI4_BRESET),
309 + BIT_ULL_MASK(JH7100_RST_E24) |
314 +struct jh7100_reset {
315 + struct reset_controller_dev rcdev;
316 + /* protect registers against concurrent read-modify-write */
318 + void __iomem *base;
321 +static inline struct jh7100_reset *
322 +jh7100_reset_from(struct reset_controller_dev *rcdev)
324 + return container_of(rcdev, struct jh7100_reset, rcdev);
327 +static int jh7100_reset_update(struct reset_controller_dev *rcdev,
328 + unsigned long id, bool assert)
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;
337 + unsigned long flags;
343 + spin_lock_irqsave(&data->lock, flags);
345 + value = readq(reg_assert);
350 + writeq(value, reg_assert);
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);
355 + spin_unlock_irqrestore(&data->lock, flags);
359 +static int jh7100_reset_assert(struct reset_controller_dev *rcdev,
362 + return jh7100_reset_update(rcdev, id, true);
365 +static int jh7100_reset_deassert(struct reset_controller_dev *rcdev,
368 + return jh7100_reset_update(rcdev, id, false);
371 +static int jh7100_reset_reset(struct reset_controller_dev *rcdev,
376 + ret = jh7100_reset_assert(rcdev, id);
380 + return jh7100_reset_deassert(rcdev, id);
383 +static int jh7100_reset_status(struct reset_controller_dev *rcdev,
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);
392 + return !((value ^ jh7100_reset_asserted[offset]) & mask);
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,
402 +static int __init jh7100_reset_probe(struct platform_device *pdev)
404 + struct jh7100_reset *data;
406 + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
410 + data->base = devm_platform_ioremap_resource(pdev, 0);
411 + if (IS_ERR(data->base))
412 + return PTR_ERR(data->base);
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);
421 + return devm_reset_controller_register(&pdev->dev, &data->rcdev);
424 +static const struct of_device_id jh7100_reset_dt_ids[] = {
425 + { .compatible = "starfive,jh7100-reset" },
429 +static struct platform_driver jh7100_reset_driver = {
431 + .name = "jh7100-reset",
432 + .of_match_table = jh7100_reset_dt_ids,
433 + .suppress_bind_attrs = true,
436 +builtin_platform_driver_probe(jh7100_reset_driver, jh7100_reset_probe);