0008-reset-Create-subdirectory-for-StarFive-drivers.patch 13 KB

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