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