2
0

0009-reset-starfive-Factor-out-common-JH71X0-reset-code.patch 12 KB

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