0028-pinctrl-starfive-Add-StarFive-JH7110-sys-controller-.patch 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581
  1. From 4dba3156173e59131d234d702388ee7283bac8a9 Mon Sep 17 00:00:00 2001
  2. From: Jianlong Huang <[email protected]>
  3. Date: Thu, 9 Feb 2023 22:37:01 +0800
  4. Subject: [PATCH 028/122] pinctrl: starfive: Add StarFive JH7110 sys controller
  5. driver
  6. Add pinctrl driver for StarFive JH7110 SoC sys pinctrl controller.
  7. Co-developed-by: Emil Renner Berthing <[email protected]>
  8. Signed-off-by: Emil Renner Berthing <[email protected]>
  9. Signed-off-by: Jianlong Huang <[email protected]>
  10. Signed-off-by: Hal Feng <[email protected]>
  11. ---
  12. MAINTAINERS | 2 +-
  13. drivers/pinctrl/starfive/Kconfig | 21 +
  14. drivers/pinctrl/starfive/Makefile | 3 +
  15. .../starfive/pinctrl-starfive-jh7110-sys.c | 449 ++++++++
  16. .../starfive/pinctrl-starfive-jh7110.c | 982 ++++++++++++++++++
  17. .../starfive/pinctrl-starfive-jh7110.h | 70 ++
  18. 6 files changed, 1526 insertions(+), 1 deletion(-)
  19. create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
  20. create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
  21. create mode 100644 drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
  22. --- a/MAINTAINERS
  23. +++ b/MAINTAINERS
  24. @@ -19664,7 +19664,7 @@ M: Jianlong Huang <jianlong.huang@starfi
  25. L: [email protected]
  26. S: Maintained
  27. F: Documentation/devicetree/bindings/pinctrl/starfive,jh71*.yaml
  28. -F: drivers/pinctrl/starfive/
  29. +F: drivers/pinctrl/starfive/pinctrl-starfive-jh71*
  30. F: include/dt-bindings/pinctrl/pinctrl-starfive-jh7100.h
  31. F: include/dt-bindings/pinctrl/starfive,jh7110-pinctrl.h
  32. --- a/drivers/pinctrl/starfive/Kconfig
  33. +++ b/drivers/pinctrl/starfive/Kconfig
  34. @@ -16,3 +16,24 @@ config PINCTRL_STARFIVE_JH7100
  35. This also provides an interface to the GPIO pins not used by other
  36. peripherals supporting inputs, outputs, configuring pull-up/pull-down
  37. and interrupts on input changes.
  38. +
  39. +config PINCTRL_STARFIVE_JH7110
  40. + bool
  41. + select GENERIC_PINCTRL_GROUPS
  42. + select GENERIC_PINMUX_FUNCTIONS
  43. + select GENERIC_PINCONF
  44. + select GPIOLIB
  45. + select GPIOLIB_IRQCHIP
  46. + select OF_GPIO
  47. +
  48. +config PINCTRL_STARFIVE_JH7110_SYS
  49. + tristate "System pinctrl and GPIO driver for the StarFive JH7110 SoC"
  50. + depends on SOC_STARFIVE || COMPILE_TEST
  51. + depends on OF
  52. + select PINCTRL_STARFIVE_JH7110
  53. + default SOC_STARFIVE
  54. + help
  55. + Say yes here to support system pin control on the StarFive JH7110 SoC.
  56. + This also provides an interface to the GPIO pins not used by other
  57. + peripherals supporting inputs, outputs, configuring pull-up/pull-down
  58. + and interrupts on input changes.
  59. --- a/drivers/pinctrl/starfive/Makefile
  60. +++ b/drivers/pinctrl/starfive/Makefile
  61. @@ -1,3 +1,6 @@
  62. # SPDX-License-Identifier: GPL-2.0
  63. obj-$(CONFIG_PINCTRL_STARFIVE_JH7100) += pinctrl-starfive-jh7100.o
  64. +
  65. +obj-$(CONFIG_PINCTRL_STARFIVE_JH7110) += pinctrl-starfive-jh7110.o
  66. +obj-$(CONFIG_PINCTRL_STARFIVE_JH7110_SYS) += pinctrl-starfive-jh7110-sys.o
  67. --- /dev/null
  68. +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c
  69. @@ -0,0 +1,449 @@
  70. +// SPDX-License-Identifier: GPL-2.0
  71. +/*
  72. + * Pinctrl / GPIO driver for StarFive JH7110 SoC sys controller
  73. + *
  74. + * Copyright (C) 2022 Emil Renner Berthing <[email protected]>
  75. + * Copyright (C) 2022 StarFive Technology Co., Ltd.
  76. + */
  77. +
  78. +#include <linux/bits.h>
  79. +#include <linux/clk.h>
  80. +#include <linux/gpio/driver.h>
  81. +#include <linux/io.h>
  82. +#include <linux/mod_devicetable.h>
  83. +#include <linux/module.h>
  84. +#include <linux/mutex.h>
  85. +#include <linux/of.h>
  86. +#include <linux/of_device.h>
  87. +#include <linux/platform_device.h>
  88. +#include <linux/reset.h>
  89. +#include <linux/spinlock.h>
  90. +
  91. +#include <linux/pinctrl/pinctrl.h>
  92. +#include <linux/pinctrl/pinmux.h>
  93. +
  94. +#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
  95. +
  96. +#include "../core.h"
  97. +#include "../pinctrl-utils.h"
  98. +#include "../pinmux.h"
  99. +#include "../pinconf.h"
  100. +#include "pinctrl-starfive-jh7110.h"
  101. +
  102. +#define JH7110_SYS_NGPIO 64
  103. +#define JH7110_SYS_GC_BASE 0
  104. +
  105. +/* registers */
  106. +#define JH7110_SYS_DOEN 0x000
  107. +#define JH7110_SYS_DOUT 0x040
  108. +#define JH7110_SYS_GPI 0x080
  109. +#define JH7110_SYS_GPIOIN 0x118
  110. +
  111. +#define JH7110_SYS_GPIOEN 0x0dc
  112. +#define JH7110_SYS_GPIOIS0 0x0e0
  113. +#define JH7110_SYS_GPIOIS1 0x0e4
  114. +#define JH7110_SYS_GPIOIC0 0x0e8
  115. +#define JH7110_SYS_GPIOIC1 0x0ec
  116. +#define JH7110_SYS_GPIOIBE0 0x0f0
  117. +#define JH7110_SYS_GPIOIBE1 0x0f4
  118. +#define JH7110_SYS_GPIOIEV0 0x0f8
  119. +#define JH7110_SYS_GPIOIEV1 0x0fc
  120. +#define JH7110_SYS_GPIOIE0 0x100
  121. +#define JH7110_SYS_GPIOIE1 0x104
  122. +#define JH7110_SYS_GPIORIS0 0x108
  123. +#define JH7110_SYS_GPIORIS1 0x10c
  124. +#define JH7110_SYS_GPIOMIS0 0x110
  125. +#define JH7110_SYS_GPIOMIS1 0x114
  126. +
  127. +#define JH7110_SYS_GPO_PDA_0_74_CFG 0x120
  128. +#define JH7110_SYS_GPO_PDA_89_94_CFG 0x284
  129. +
  130. +static const struct pinctrl_pin_desc jh7110_sys_pins[] = {
  131. + PINCTRL_PIN(PAD_GPIO0, "GPIO0"),
  132. + PINCTRL_PIN(PAD_GPIO1, "GPIO1"),
  133. + PINCTRL_PIN(PAD_GPIO2, "GPIO2"),
  134. + PINCTRL_PIN(PAD_GPIO3, "GPIO3"),
  135. + PINCTRL_PIN(PAD_GPIO4, "GPIO4"),
  136. + PINCTRL_PIN(PAD_GPIO5, "GPIO5"),
  137. + PINCTRL_PIN(PAD_GPIO6, "GPIO6"),
  138. + PINCTRL_PIN(PAD_GPIO7, "GPIO7"),
  139. + PINCTRL_PIN(PAD_GPIO8, "GPIO8"),
  140. + PINCTRL_PIN(PAD_GPIO9, "GPIO9"),
  141. + PINCTRL_PIN(PAD_GPIO10, "GPIO10"),
  142. + PINCTRL_PIN(PAD_GPIO11, "GPIO11"),
  143. + PINCTRL_PIN(PAD_GPIO12, "GPIO12"),
  144. + PINCTRL_PIN(PAD_GPIO13, "GPIO13"),
  145. + PINCTRL_PIN(PAD_GPIO14, "GPIO14"),
  146. + PINCTRL_PIN(PAD_GPIO15, "GPIO15"),
  147. + PINCTRL_PIN(PAD_GPIO16, "GPIO16"),
  148. + PINCTRL_PIN(PAD_GPIO17, "GPIO17"),
  149. + PINCTRL_PIN(PAD_GPIO18, "GPIO18"),
  150. + PINCTRL_PIN(PAD_GPIO19, "GPIO19"),
  151. + PINCTRL_PIN(PAD_GPIO20, "GPIO20"),
  152. + PINCTRL_PIN(PAD_GPIO21, "GPIO21"),
  153. + PINCTRL_PIN(PAD_GPIO22, "GPIO22"),
  154. + PINCTRL_PIN(PAD_GPIO23, "GPIO23"),
  155. + PINCTRL_PIN(PAD_GPIO24, "GPIO24"),
  156. + PINCTRL_PIN(PAD_GPIO25, "GPIO25"),
  157. + PINCTRL_PIN(PAD_GPIO26, "GPIO26"),
  158. + PINCTRL_PIN(PAD_GPIO27, "GPIO27"),
  159. + PINCTRL_PIN(PAD_GPIO28, "GPIO28"),
  160. + PINCTRL_PIN(PAD_GPIO29, "GPIO29"),
  161. + PINCTRL_PIN(PAD_GPIO30, "GPIO30"),
  162. + PINCTRL_PIN(PAD_GPIO31, "GPIO31"),
  163. + PINCTRL_PIN(PAD_GPIO32, "GPIO32"),
  164. + PINCTRL_PIN(PAD_GPIO33, "GPIO33"),
  165. + PINCTRL_PIN(PAD_GPIO34, "GPIO34"),
  166. + PINCTRL_PIN(PAD_GPIO35, "GPIO35"),
  167. + PINCTRL_PIN(PAD_GPIO36, "GPIO36"),
  168. + PINCTRL_PIN(PAD_GPIO37, "GPIO37"),
  169. + PINCTRL_PIN(PAD_GPIO38, "GPIO38"),
  170. + PINCTRL_PIN(PAD_GPIO39, "GPIO39"),
  171. + PINCTRL_PIN(PAD_GPIO40, "GPIO40"),
  172. + PINCTRL_PIN(PAD_GPIO41, "GPIO41"),
  173. + PINCTRL_PIN(PAD_GPIO42, "GPIO42"),
  174. + PINCTRL_PIN(PAD_GPIO43, "GPIO43"),
  175. + PINCTRL_PIN(PAD_GPIO44, "GPIO44"),
  176. + PINCTRL_PIN(PAD_GPIO45, "GPIO45"),
  177. + PINCTRL_PIN(PAD_GPIO46, "GPIO46"),
  178. + PINCTRL_PIN(PAD_GPIO47, "GPIO47"),
  179. + PINCTRL_PIN(PAD_GPIO48, "GPIO48"),
  180. + PINCTRL_PIN(PAD_GPIO49, "GPIO49"),
  181. + PINCTRL_PIN(PAD_GPIO50, "GPIO50"),
  182. + PINCTRL_PIN(PAD_GPIO51, "GPIO51"),
  183. + PINCTRL_PIN(PAD_GPIO52, "GPIO52"),
  184. + PINCTRL_PIN(PAD_GPIO53, "GPIO53"),
  185. + PINCTRL_PIN(PAD_GPIO54, "GPIO54"),
  186. + PINCTRL_PIN(PAD_GPIO55, "GPIO55"),
  187. + PINCTRL_PIN(PAD_GPIO56, "GPIO56"),
  188. + PINCTRL_PIN(PAD_GPIO57, "GPIO57"),
  189. + PINCTRL_PIN(PAD_GPIO58, "GPIO58"),
  190. + PINCTRL_PIN(PAD_GPIO59, "GPIO59"),
  191. + PINCTRL_PIN(PAD_GPIO60, "GPIO60"),
  192. + PINCTRL_PIN(PAD_GPIO61, "GPIO61"),
  193. + PINCTRL_PIN(PAD_GPIO62, "GPIO62"),
  194. + PINCTRL_PIN(PAD_GPIO63, "GPIO63"),
  195. + PINCTRL_PIN(PAD_SD0_CLK, "SD0_CLK"),
  196. + PINCTRL_PIN(PAD_SD0_CMD, "SD0_CMD"),
  197. + PINCTRL_PIN(PAD_SD0_DATA0, "SD0_DATA0"),
  198. + PINCTRL_PIN(PAD_SD0_DATA1, "SD0_DATA1"),
  199. + PINCTRL_PIN(PAD_SD0_DATA2, "SD0_DATA2"),
  200. + PINCTRL_PIN(PAD_SD0_DATA3, "SD0_DATA3"),
  201. + PINCTRL_PIN(PAD_SD0_DATA4, "SD0_DATA4"),
  202. + PINCTRL_PIN(PAD_SD0_DATA5, "SD0_DATA5"),
  203. + PINCTRL_PIN(PAD_SD0_DATA6, "SD0_DATA6"),
  204. + PINCTRL_PIN(PAD_SD0_DATA7, "SD0_DATA7"),
  205. + PINCTRL_PIN(PAD_SD0_STRB, "SD0_STRB"),
  206. + PINCTRL_PIN(PAD_GMAC1_MDC, "GMAC1_MDC"),
  207. + PINCTRL_PIN(PAD_GMAC1_MDIO, "GMAC1_MDIO"),
  208. + PINCTRL_PIN(PAD_GMAC1_RXD0, "GMAC1_RXD0"),
  209. + PINCTRL_PIN(PAD_GMAC1_RXD1, "GMAC1_RXD1"),
  210. + PINCTRL_PIN(PAD_GMAC1_RXD2, "GMAC1_RXD2"),
  211. + PINCTRL_PIN(PAD_GMAC1_RXD3, "GMAC1_RXD3"),
  212. + PINCTRL_PIN(PAD_GMAC1_RXDV, "GMAC1_RXDV"),
  213. + PINCTRL_PIN(PAD_GMAC1_RXC, "GMAC1_RXC"),
  214. + PINCTRL_PIN(PAD_GMAC1_TXD0, "GMAC1_TXD0"),
  215. + PINCTRL_PIN(PAD_GMAC1_TXD1, "GMAC1_TXD1"),
  216. + PINCTRL_PIN(PAD_GMAC1_TXD2, "GMAC1_TXD2"),
  217. + PINCTRL_PIN(PAD_GMAC1_TXD3, "GMAC1_TXD3"),
  218. + PINCTRL_PIN(PAD_GMAC1_TXEN, "GMAC1_TXEN"),
  219. + PINCTRL_PIN(PAD_GMAC1_TXC, "GMAC1_TXC"),
  220. + PINCTRL_PIN(PAD_QSPI_SCLK, "QSPI_SCLK"),
  221. + PINCTRL_PIN(PAD_QSPI_CS0, "QSPI_CS0"),
  222. + PINCTRL_PIN(PAD_QSPI_DATA0, "QSPI_DATA0"),
  223. + PINCTRL_PIN(PAD_QSPI_DATA1, "QSPI_DATA1"),
  224. + PINCTRL_PIN(PAD_QSPI_DATA2, "QSPI_DATA2"),
  225. + PINCTRL_PIN(PAD_QSPI_DATA3, "QSPI_DATA3"),
  226. +};
  227. +
  228. +struct jh7110_func_sel {
  229. + u16 offset;
  230. + u8 shift;
  231. + u8 max;
  232. +};
  233. +
  234. +static const struct jh7110_func_sel
  235. + jh7110_sys_func_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
  236. + [PAD_GMAC1_RXC] = { 0x29c, 0, 1 },
  237. + [PAD_GPIO10] = { 0x29c, 2, 3 },
  238. + [PAD_GPIO11] = { 0x29c, 5, 3 },
  239. + [PAD_GPIO12] = { 0x29c, 8, 3 },
  240. + [PAD_GPIO13] = { 0x29c, 11, 3 },
  241. + [PAD_GPIO14] = { 0x29c, 14, 3 },
  242. + [PAD_GPIO15] = { 0x29c, 17, 3 },
  243. + [PAD_GPIO16] = { 0x29c, 20, 3 },
  244. + [PAD_GPIO17] = { 0x29c, 23, 3 },
  245. + [PAD_GPIO18] = { 0x29c, 26, 3 },
  246. + [PAD_GPIO19] = { 0x29c, 29, 3 },
  247. +
  248. + [PAD_GPIO20] = { 0x2a0, 0, 3 },
  249. + [PAD_GPIO21] = { 0x2a0, 3, 3 },
  250. + [PAD_GPIO22] = { 0x2a0, 6, 3 },
  251. + [PAD_GPIO23] = { 0x2a0, 9, 3 },
  252. + [PAD_GPIO24] = { 0x2a0, 12, 3 },
  253. + [PAD_GPIO25] = { 0x2a0, 15, 3 },
  254. + [PAD_GPIO26] = { 0x2a0, 18, 3 },
  255. + [PAD_GPIO27] = { 0x2a0, 21, 3 },
  256. + [PAD_GPIO28] = { 0x2a0, 24, 3 },
  257. + [PAD_GPIO29] = { 0x2a0, 27, 3 },
  258. +
  259. + [PAD_GPIO30] = { 0x2a4, 0, 3 },
  260. + [PAD_GPIO31] = { 0x2a4, 3, 3 },
  261. + [PAD_GPIO32] = { 0x2a4, 6, 3 },
  262. + [PAD_GPIO33] = { 0x2a4, 9, 3 },
  263. + [PAD_GPIO34] = { 0x2a4, 12, 3 },
  264. + [PAD_GPIO35] = { 0x2a4, 15, 3 },
  265. + [PAD_GPIO36] = { 0x2a4, 17, 3 },
  266. + [PAD_GPIO37] = { 0x2a4, 20, 3 },
  267. + [PAD_GPIO38] = { 0x2a4, 23, 3 },
  268. + [PAD_GPIO39] = { 0x2a4, 26, 3 },
  269. + [PAD_GPIO40] = { 0x2a4, 29, 3 },
  270. +
  271. + [PAD_GPIO41] = { 0x2a8, 0, 3 },
  272. + [PAD_GPIO42] = { 0x2a8, 3, 3 },
  273. + [PAD_GPIO43] = { 0x2a8, 6, 3 },
  274. + [PAD_GPIO44] = { 0x2a8, 9, 3 },
  275. + [PAD_GPIO45] = { 0x2a8, 12, 3 },
  276. + [PAD_GPIO46] = { 0x2a8, 15, 3 },
  277. + [PAD_GPIO47] = { 0x2a8, 18, 3 },
  278. + [PAD_GPIO48] = { 0x2a8, 21, 3 },
  279. + [PAD_GPIO49] = { 0x2a8, 24, 3 },
  280. + [PAD_GPIO50] = { 0x2a8, 27, 3 },
  281. + [PAD_GPIO51] = { 0x2a8, 30, 3 },
  282. +
  283. + [PAD_GPIO52] = { 0x2ac, 0, 3 },
  284. + [PAD_GPIO53] = { 0x2ac, 2, 3 },
  285. + [PAD_GPIO54] = { 0x2ac, 4, 3 },
  286. + [PAD_GPIO55] = { 0x2ac, 6, 3 },
  287. + [PAD_GPIO56] = { 0x2ac, 9, 3 },
  288. + [PAD_GPIO57] = { 0x2ac, 12, 3 },
  289. + [PAD_GPIO58] = { 0x2ac, 15, 3 },
  290. + [PAD_GPIO59] = { 0x2ac, 18, 3 },
  291. + [PAD_GPIO60] = { 0x2ac, 21, 3 },
  292. + [PAD_GPIO61] = { 0x2ac, 24, 3 },
  293. + [PAD_GPIO62] = { 0x2ac, 27, 3 },
  294. + [PAD_GPIO63] = { 0x2ac, 30, 3 },
  295. +
  296. + [PAD_GPIO6] = { 0x2b0, 0, 3 },
  297. + [PAD_GPIO7] = { 0x2b0, 2, 3 },
  298. + [PAD_GPIO8] = { 0x2b0, 5, 3 },
  299. + [PAD_GPIO9] = { 0x2b0, 8, 3 },
  300. +};
  301. +
  302. +struct jh7110_vin_group_sel {
  303. + u16 offset;
  304. + u8 shift;
  305. + u8 group;
  306. +};
  307. +
  308. +static const struct jh7110_vin_group_sel
  309. + jh7110_sys_vin_group_sel[ARRAY_SIZE(jh7110_sys_pins)] = {
  310. + [PAD_GPIO6] = { 0x2b4, 21, 0 },
  311. + [PAD_GPIO7] = { 0x2b4, 18, 0 },
  312. + [PAD_GPIO8] = { 0x2b4, 15, 0 },
  313. + [PAD_GPIO9] = { 0x2b0, 11, 0 },
  314. + [PAD_GPIO10] = { 0x2b0, 20, 0 },
  315. + [PAD_GPIO11] = { 0x2b0, 23, 0 },
  316. + [PAD_GPIO12] = { 0x2b0, 26, 0 },
  317. + [PAD_GPIO13] = { 0x2b0, 29, 0 },
  318. + [PAD_GPIO14] = { 0x2b4, 0, 0 },
  319. + [PAD_GPIO15] = { 0x2b4, 3, 0 },
  320. + [PAD_GPIO16] = { 0x2b4, 6, 0 },
  321. + [PAD_GPIO17] = { 0x2b4, 9, 0 },
  322. + [PAD_GPIO18] = { 0x2b4, 12, 0 },
  323. + [PAD_GPIO19] = { 0x2b0, 14, 0 },
  324. + [PAD_GPIO20] = { 0x2b0, 17, 0 },
  325. +
  326. + [PAD_GPIO21] = { 0x2b4, 21, 1 },
  327. + [PAD_GPIO22] = { 0x2b4, 18, 1 },
  328. + [PAD_GPIO23] = { 0x2b4, 15, 1 },
  329. + [PAD_GPIO24] = { 0x2b0, 11, 1 },
  330. + [PAD_GPIO25] = { 0x2b0, 20, 1 },
  331. + [PAD_GPIO26] = { 0x2b0, 23, 1 },
  332. + [PAD_GPIO27] = { 0x2b0, 26, 1 },
  333. + [PAD_GPIO28] = { 0x2b0, 29, 1 },
  334. + [PAD_GPIO29] = { 0x2b4, 0, 1 },
  335. + [PAD_GPIO30] = { 0x2b4, 3, 1 },
  336. + [PAD_GPIO31] = { 0x2b4, 6, 1 },
  337. + [PAD_GPIO32] = { 0x2b4, 9, 1 },
  338. + [PAD_GPIO33] = { 0x2b4, 12, 1 },
  339. + [PAD_GPIO34] = { 0x2b0, 14, 1 },
  340. + [PAD_GPIO35] = { 0x2b0, 17, 1 },
  341. +
  342. + [PAD_GPIO36] = { 0x2b4, 21, 2 },
  343. + [PAD_GPIO37] = { 0x2b4, 18, 2 },
  344. + [PAD_GPIO38] = { 0x2b4, 15, 2 },
  345. + [PAD_GPIO39] = { 0x2b0, 11, 2 },
  346. + [PAD_GPIO40] = { 0x2b0, 20, 2 },
  347. + [PAD_GPIO41] = { 0x2b0, 23, 2 },
  348. + [PAD_GPIO42] = { 0x2b0, 26, 2 },
  349. + [PAD_GPIO43] = { 0x2b0, 29, 2 },
  350. + [PAD_GPIO44] = { 0x2b4, 0, 2 },
  351. + [PAD_GPIO45] = { 0x2b4, 3, 2 },
  352. + [PAD_GPIO46] = { 0x2b4, 6, 2 },
  353. + [PAD_GPIO47] = { 0x2b4, 9, 2 },
  354. + [PAD_GPIO48] = { 0x2b4, 12, 2 },
  355. + [PAD_GPIO49] = { 0x2b0, 14, 2 },
  356. + [PAD_GPIO50] = { 0x2b0, 17, 2 },
  357. +};
  358. +
  359. +static void jh7110_set_function(struct jh7110_pinctrl *sfp,
  360. + unsigned int pin, u32 func)
  361. +{
  362. + const struct jh7110_func_sel *fs = &jh7110_sys_func_sel[pin];
  363. + unsigned long flags;
  364. + void __iomem *reg;
  365. + u32 mask;
  366. +
  367. + if (!fs->offset)
  368. + return;
  369. +
  370. + if (func > fs->max)
  371. + return;
  372. +
  373. + reg = sfp->base + fs->offset;
  374. + func = func << fs->shift;
  375. + mask = 0x3U << fs->shift;
  376. +
  377. + raw_spin_lock_irqsave(&sfp->lock, flags);
  378. + func |= readl_relaxed(reg) & ~mask;
  379. + writel_relaxed(func, reg);
  380. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  381. +}
  382. +
  383. +static void jh7110_set_vin_group(struct jh7110_pinctrl *sfp,
  384. + unsigned int pin)
  385. +{
  386. + const struct jh7110_vin_group_sel *gs = &jh7110_sys_vin_group_sel[pin];
  387. + unsigned long flags;
  388. + void __iomem *reg;
  389. + u32 mask;
  390. + u32 grp;
  391. +
  392. + if (!gs->offset)
  393. + return;
  394. +
  395. + reg = sfp->base + gs->offset;
  396. + grp = gs->group << gs->shift;
  397. + mask = 0x3U << gs->shift;
  398. +
  399. + raw_spin_lock_irqsave(&sfp->lock, flags);
  400. + grp |= readl_relaxed(reg) & ~mask;
  401. + writel_relaxed(grp, reg);
  402. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  403. +}
  404. +
  405. +static int jh7110_sys_set_one_pin_mux(struct jh7110_pinctrl *sfp,
  406. + unsigned int pin,
  407. + unsigned int din, u32 dout,
  408. + u32 doen, u32 func)
  409. +{
  410. + if (pin < sfp->gc.ngpio && func == 0)
  411. + jh7110_set_gpiomux(sfp, pin, din, dout, doen);
  412. +
  413. + jh7110_set_function(sfp, pin, func);
  414. +
  415. + if (pin < sfp->gc.ngpio && func == 2)
  416. + jh7110_set_vin_group(sfp, pin);
  417. +
  418. + return 0;
  419. +}
  420. +
  421. +static int jh7110_sys_get_padcfg_base(struct jh7110_pinctrl *sfp,
  422. + unsigned int pin)
  423. +{
  424. + if (pin < PAD_GMAC1_MDC)
  425. + return JH7110_SYS_GPO_PDA_0_74_CFG;
  426. + else if (pin > PAD_GMAC1_TXC && pin <= PAD_QSPI_DATA3)
  427. + return JH7110_SYS_GPO_PDA_89_94_CFG;
  428. + else
  429. + return -1;
  430. +}
  431. +
  432. +static void jh7110_sys_irq_handler(struct irq_desc *desc)
  433. +{
  434. + struct jh7110_pinctrl *sfp = jh7110_from_irq_desc(desc);
  435. + struct irq_chip *chip = irq_desc_get_chip(desc);
  436. + unsigned long mis;
  437. + unsigned int pin;
  438. +
  439. + chained_irq_enter(chip, desc);
  440. +
  441. + mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS0);
  442. + for_each_set_bit(pin, &mis, 32)
  443. + generic_handle_domain_irq(sfp->gc.irq.domain, pin);
  444. +
  445. + mis = readl_relaxed(sfp->base + JH7110_SYS_GPIOMIS1);
  446. + for_each_set_bit(pin, &mis, 32)
  447. + generic_handle_domain_irq(sfp->gc.irq.domain, pin + 32);
  448. +
  449. + chained_irq_exit(chip, desc);
  450. +}
  451. +
  452. +static int jh7110_sys_init_hw(struct gpio_chip *gc)
  453. +{
  454. + struct jh7110_pinctrl *sfp = container_of(gc,
  455. + struct jh7110_pinctrl, gc);
  456. +
  457. + /* mask all GPIO interrupts */
  458. + writel(0U, sfp->base + JH7110_SYS_GPIOIE0);
  459. + writel(0U, sfp->base + JH7110_SYS_GPIOIE1);
  460. + /* clear edge interrupt flags */
  461. + writel(~0U, sfp->base + JH7110_SYS_GPIOIC0);
  462. + writel(~0U, sfp->base + JH7110_SYS_GPIOIC1);
  463. + /* enable GPIO interrupts */
  464. + writel(1U, sfp->base + JH7110_SYS_GPIOEN);
  465. + return 0;
  466. +}
  467. +
  468. +static const struct jh7110_gpio_irq_reg jh7110_sys_irq_reg = {
  469. + .is_reg_base = JH7110_SYS_GPIOIS0,
  470. + .ic_reg_base = JH7110_SYS_GPIOIC0,
  471. + .ibe_reg_base = JH7110_SYS_GPIOIBE0,
  472. + .iev_reg_base = JH7110_SYS_GPIOIEV0,
  473. + .ie_reg_base = JH7110_SYS_GPIOIE0,
  474. + .ris_reg_base = JH7110_SYS_GPIORIS0,
  475. + .mis_reg_base = JH7110_SYS_GPIOMIS0,
  476. +};
  477. +
  478. +static const struct jh7110_pinctrl_soc_info jh7110_sys_pinctrl_info = {
  479. + .pins = jh7110_sys_pins,
  480. + .npins = ARRAY_SIZE(jh7110_sys_pins),
  481. + .ngpios = JH7110_SYS_NGPIO,
  482. + .gc_base = JH7110_SYS_GC_BASE,
  483. + .dout_reg_base = JH7110_SYS_DOUT,
  484. + .dout_mask = GENMASK(6, 0),
  485. + .doen_reg_base = JH7110_SYS_DOEN,
  486. + .doen_mask = GENMASK(5, 0),
  487. + .gpi_reg_base = JH7110_SYS_GPI,
  488. + .gpi_mask = GENMASK(6, 0),
  489. + .gpioin_reg_base = JH7110_SYS_GPIOIN,
  490. + .irq_reg = &jh7110_sys_irq_reg,
  491. + .jh7110_set_one_pin_mux = jh7110_sys_set_one_pin_mux,
  492. + .jh7110_get_padcfg_base = jh7110_sys_get_padcfg_base,
  493. + .jh7110_gpio_irq_handler = jh7110_sys_irq_handler,
  494. + .jh7110_gpio_init_hw = jh7110_sys_init_hw,
  495. +};
  496. +
  497. +static const struct of_device_id jh7110_sys_pinctrl_of_match[] = {
  498. + {
  499. + .compatible = "starfive,jh7110-sys-pinctrl",
  500. + .data = &jh7110_sys_pinctrl_info,
  501. + },
  502. + { /* sentinel */ }
  503. +};
  504. +MODULE_DEVICE_TABLE(of, jh7110_sys_pinctrl_of_match);
  505. +
  506. +static struct platform_driver jh7110_sys_pinctrl_driver = {
  507. + .probe = jh7110_pinctrl_probe,
  508. + .driver = {
  509. + .name = "starfive-jh7110-sys-pinctrl",
  510. + .of_match_table = jh7110_sys_pinctrl_of_match,
  511. + },
  512. +};
  513. +module_platform_driver(jh7110_sys_pinctrl_driver);
  514. +
  515. +MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC sys controller");
  516. +MODULE_AUTHOR("Emil Renner Berthing <[email protected]>");
  517. +MODULE_AUTHOR("Jianlong Huang <[email protected]>");
  518. +MODULE_LICENSE("GPL");
  519. --- /dev/null
  520. +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
  521. @@ -0,0 +1,982 @@
  522. +// SPDX-License-Identifier: GPL-2.0
  523. +/*
  524. + * Pinctrl / GPIO driver for StarFive JH7110 SoC
  525. + *
  526. + * Copyright (C) 2022 Emil Renner Berthing <[email protected]>
  527. + * Copyright (C) 2022 StarFive Technology Co., Ltd.
  528. + */
  529. +
  530. +#include <linux/bits.h>
  531. +#include <linux/clk.h>
  532. +#include <linux/gpio/driver.h>
  533. +#include <linux/io.h>
  534. +#include <linux/mod_devicetable.h>
  535. +#include <linux/module.h>
  536. +#include <linux/mutex.h>
  537. +#include <linux/of.h>
  538. +#include <linux/of_device.h>
  539. +#include <linux/platform_device.h>
  540. +#include <linux/reset.h>
  541. +#include <linux/seq_file.h>
  542. +#include <linux/spinlock.h>
  543. +
  544. +#include <linux/pinctrl/consumer.h>
  545. +#include <linux/pinctrl/pinconf.h>
  546. +#include <linux/pinctrl/pinctrl.h>
  547. +#include <linux/pinctrl/pinmux.h>
  548. +
  549. +#include <dt-bindings/pinctrl/starfive,jh7110-pinctrl.h>
  550. +
  551. +#include "../core.h"
  552. +#include "../pinctrl-utils.h"
  553. +#include "../pinmux.h"
  554. +#include "../pinconf.h"
  555. +#include "pinctrl-starfive-jh7110.h"
  556. +
  557. +/* pad control bits */
  558. +#define JH7110_PADCFG_POS BIT(7)
  559. +#define JH7110_PADCFG_SMT BIT(6)
  560. +#define JH7110_PADCFG_SLEW BIT(5)
  561. +#define JH7110_PADCFG_PD BIT(4)
  562. +#define JH7110_PADCFG_PU BIT(3)
  563. +#define JH7110_PADCFG_BIAS (JH7110_PADCFG_PD | JH7110_PADCFG_PU)
  564. +#define JH7110_PADCFG_DS_MASK GENMASK(2, 1)
  565. +#define JH7110_PADCFG_DS_2MA (0U << 1)
  566. +#define JH7110_PADCFG_DS_4MA BIT(1)
  567. +#define JH7110_PADCFG_DS_8MA (2U << 1)
  568. +#define JH7110_PADCFG_DS_12MA (3U << 1)
  569. +#define JH7110_PADCFG_IE BIT(0)
  570. +
  571. +/*
  572. + * The packed pinmux values from the device tree look like this:
  573. + *
  574. + * | 31 - 24 | 23 - 16 | 15 - 10 | 9 - 8 | 7 - 0 |
  575. + * | din | dout | doen | function | pin |
  576. + */
  577. +static unsigned int jh7110_pinmux_din(u32 v)
  578. +{
  579. + return (v & GENMASK(31, 24)) >> 24;
  580. +}
  581. +
  582. +static u32 jh7110_pinmux_dout(u32 v)
  583. +{
  584. + return (v & GENMASK(23, 16)) >> 16;
  585. +}
  586. +
  587. +static u32 jh7110_pinmux_doen(u32 v)
  588. +{
  589. + return (v & GENMASK(15, 10)) >> 10;
  590. +}
  591. +
  592. +static u32 jh7110_pinmux_function(u32 v)
  593. +{
  594. + return (v & GENMASK(9, 8)) >> 8;
  595. +}
  596. +
  597. +static unsigned int jh7110_pinmux_pin(u32 v)
  598. +{
  599. + return v & GENMASK(7, 0);
  600. +}
  601. +
  602. +static struct jh7110_pinctrl *jh7110_from_irq_data(struct irq_data *d)
  603. +{
  604. + struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  605. +
  606. + return container_of(gc, struct jh7110_pinctrl, gc);
  607. +}
  608. +
  609. +struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc)
  610. +{
  611. + struct gpio_chip *gc = irq_desc_get_handler_data(desc);
  612. +
  613. + return container_of(gc, struct jh7110_pinctrl, gc);
  614. +}
  615. +EXPORT_SYMBOL_GPL(jh7110_from_irq_desc);
  616. +
  617. +#ifdef CONFIG_DEBUG_FS
  618. +static void jh7110_pin_dbg_show(struct pinctrl_dev *pctldev,
  619. + struct seq_file *s, unsigned int pin)
  620. +{
  621. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  622. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  623. +
  624. + seq_printf(s, "%s", dev_name(pctldev->dev));
  625. +
  626. + if (pin < sfp->gc.ngpio) {
  627. + unsigned int offset = 4 * (pin / 4);
  628. + unsigned int shift = 8 * (pin % 4);
  629. + u32 dout = readl_relaxed(sfp->base + info->dout_reg_base + offset);
  630. + u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
  631. + u32 gpi = readl_relaxed(sfp->base + info->gpi_reg_base + offset);
  632. +
  633. + dout = (dout >> shift) & info->dout_mask;
  634. + doen = (doen >> shift) & info->doen_mask;
  635. + gpi = ((gpi >> shift) - 2) & info->gpi_mask;
  636. +
  637. + seq_printf(s, " dout=%u doen=%u din=%u", dout, doen, gpi);
  638. + }
  639. +}
  640. +#else
  641. +#define jh7110_pin_dbg_show NULL
  642. +#endif
  643. +
  644. +static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev,
  645. + struct device_node *np,
  646. + struct pinctrl_map **maps,
  647. + unsigned int *num_maps)
  648. +{
  649. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  650. + struct device *dev = sfp->gc.parent;
  651. + struct device_node *child;
  652. + struct pinctrl_map *map;
  653. + const char **pgnames;
  654. + const char *grpname;
  655. + int ngroups;
  656. + int nmaps;
  657. + int ret;
  658. +
  659. + ngroups = 0;
  660. + for_each_child_of_node(np, child)
  661. + ngroups += 1;
  662. + nmaps = 2 * ngroups;
  663. +
  664. + pgnames = devm_kcalloc(dev, ngroups, sizeof(*pgnames), GFP_KERNEL);
  665. + if (!pgnames)
  666. + return -ENOMEM;
  667. +
  668. + map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL);
  669. + if (!map)
  670. + return -ENOMEM;
  671. +
  672. + nmaps = 0;
  673. + ngroups = 0;
  674. + mutex_lock(&sfp->mutex);
  675. + for_each_child_of_node(np, child) {
  676. + int npins = of_property_count_u32_elems(child, "pinmux");
  677. + int *pins;
  678. + u32 *pinmux;
  679. + int i;
  680. +
  681. + if (npins < 1) {
  682. + dev_err(dev,
  683. + "invalid pinctrl group %pOFn.%pOFn: pinmux not set\n",
  684. + np, child);
  685. + ret = -EINVAL;
  686. + goto put_child;
  687. + }
  688. +
  689. + grpname = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", np, child);
  690. + if (!grpname) {
  691. + ret = -ENOMEM;
  692. + goto put_child;
  693. + }
  694. +
  695. + pgnames[ngroups++] = grpname;
  696. +
  697. + pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
  698. + if (!pins) {
  699. + ret = -ENOMEM;
  700. + goto put_child;
  701. + }
  702. +
  703. + pinmux = devm_kcalloc(dev, npins, sizeof(*pinmux), GFP_KERNEL);
  704. + if (!pinmux) {
  705. + ret = -ENOMEM;
  706. + goto put_child;
  707. + }
  708. +
  709. + ret = of_property_read_u32_array(child, "pinmux", pinmux, npins);
  710. + if (ret)
  711. + goto put_child;
  712. +
  713. + for (i = 0; i < npins; i++)
  714. + pins[i] = jh7110_pinmux_pin(pinmux[i]);
  715. +
  716. + map[nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
  717. + map[nmaps].data.mux.function = np->name;
  718. + map[nmaps].data.mux.group = grpname;
  719. + nmaps += 1;
  720. +
  721. + ret = pinctrl_generic_add_group(pctldev, grpname,
  722. + pins, npins, pinmux);
  723. + if (ret < 0) {
  724. + dev_err(dev, "error adding group %s: %d\n", grpname, ret);
  725. + goto put_child;
  726. + }
  727. +
  728. + ret = pinconf_generic_parse_dt_config(child, pctldev,
  729. + &map[nmaps].data.configs.configs,
  730. + &map[nmaps].data.configs.num_configs);
  731. + if (ret) {
  732. + dev_err(dev, "error parsing pin config of group %s: %d\n",
  733. + grpname, ret);
  734. + goto put_child;
  735. + }
  736. +
  737. + /* don't create a map if there are no pinconf settings */
  738. + if (map[nmaps].data.configs.num_configs == 0)
  739. + continue;
  740. +
  741. + map[nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
  742. + map[nmaps].data.configs.group_or_pin = grpname;
  743. + nmaps += 1;
  744. + }
  745. +
  746. + ret = pinmux_generic_add_function(pctldev, np->name,
  747. + pgnames, ngroups, NULL);
  748. + if (ret < 0) {
  749. + dev_err(dev, "error adding function %s: %d\n", np->name, ret);
  750. + goto free_map;
  751. + }
  752. + mutex_unlock(&sfp->mutex);
  753. +
  754. + *maps = map;
  755. + *num_maps = nmaps;
  756. + return 0;
  757. +
  758. +put_child:
  759. + of_node_put(child);
  760. +free_map:
  761. + pinctrl_utils_free_map(pctldev, map, nmaps);
  762. + mutex_unlock(&sfp->mutex);
  763. + return ret;
  764. +}
  765. +
  766. +static const struct pinctrl_ops jh7110_pinctrl_ops = {
  767. + .get_groups_count = pinctrl_generic_get_group_count,
  768. + .get_group_name = pinctrl_generic_get_group_name,
  769. + .get_group_pins = pinctrl_generic_get_group_pins,
  770. + .pin_dbg_show = jh7110_pin_dbg_show,
  771. + .dt_node_to_map = jh7110_dt_node_to_map,
  772. + .dt_free_map = pinctrl_utils_free_map,
  773. +};
  774. +
  775. +void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
  776. + unsigned int din, u32 dout, u32 doen)
  777. +{
  778. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  779. +
  780. + unsigned int offset = 4 * (pin / 4);
  781. + unsigned int shift = 8 * (pin % 4);
  782. + u32 dout_mask = info->dout_mask << shift;
  783. + u32 done_mask = info->doen_mask << shift;
  784. + u32 ival, imask;
  785. + void __iomem *reg_dout;
  786. + void __iomem *reg_doen;
  787. + void __iomem *reg_din;
  788. + unsigned long flags;
  789. +
  790. + reg_dout = sfp->base + info->dout_reg_base + offset;
  791. + reg_doen = sfp->base + info->doen_reg_base + offset;
  792. + dout <<= shift;
  793. + doen <<= shift;
  794. + if (din != GPI_NONE) {
  795. + unsigned int ioffset = 4 * (din / 4);
  796. + unsigned int ishift = 8 * (din % 4);
  797. +
  798. + reg_din = sfp->base + info->gpi_reg_base + ioffset;
  799. + ival = (pin + 2) << ishift;
  800. + imask = info->gpi_mask << ishift;
  801. + } else {
  802. + reg_din = NULL;
  803. + }
  804. +
  805. + raw_spin_lock_irqsave(&sfp->lock, flags);
  806. + dout |= readl_relaxed(reg_dout) & ~dout_mask;
  807. + writel_relaxed(dout, reg_dout);
  808. + doen |= readl_relaxed(reg_doen) & ~done_mask;
  809. + writel_relaxed(doen, reg_doen);
  810. + if (reg_din) {
  811. + ival |= readl_relaxed(reg_din) & ~imask;
  812. + writel_relaxed(ival, reg_din);
  813. + }
  814. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  815. +}
  816. +EXPORT_SYMBOL_GPL(jh7110_set_gpiomux);
  817. +
  818. +static int jh7110_set_mux(struct pinctrl_dev *pctldev,
  819. + unsigned int fsel, unsigned int gsel)
  820. +{
  821. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  822. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  823. + const struct group_desc *group;
  824. + const u32 *pinmux;
  825. + unsigned int i;
  826. +
  827. + group = pinctrl_generic_get_group(pctldev, gsel);
  828. + if (!group)
  829. + return -EINVAL;
  830. +
  831. + pinmux = group->data;
  832. + for (i = 0; i < group->num_pins; i++) {
  833. + u32 v = pinmux[i];
  834. +
  835. + if (info->jh7110_set_one_pin_mux)
  836. + info->jh7110_set_one_pin_mux(sfp,
  837. + jh7110_pinmux_pin(v),
  838. + jh7110_pinmux_din(v),
  839. + jh7110_pinmux_dout(v),
  840. + jh7110_pinmux_doen(v),
  841. + jh7110_pinmux_function(v));
  842. + }
  843. +
  844. + return 0;
  845. +}
  846. +
  847. +static const struct pinmux_ops jh7110_pinmux_ops = {
  848. + .get_functions_count = pinmux_generic_get_function_count,
  849. + .get_function_name = pinmux_generic_get_function_name,
  850. + .get_function_groups = pinmux_generic_get_function_groups,
  851. + .set_mux = jh7110_set_mux,
  852. + .strict = true,
  853. +};
  854. +
  855. +static const u8 jh7110_drive_strength_mA[4] = { 2, 4, 8, 12 };
  856. +
  857. +static u32 jh7110_padcfg_ds_to_mA(u32 padcfg)
  858. +{
  859. + return jh7110_drive_strength_mA[(padcfg >> 1) & 3U];
  860. +}
  861. +
  862. +static u32 jh7110_padcfg_ds_from_mA(u32 v)
  863. +{
  864. + int i;
  865. +
  866. + for (i = 0; i < 3; i++) {
  867. + if (v <= jh7110_drive_strength_mA[i])
  868. + break;
  869. + }
  870. + return i << 1;
  871. +}
  872. +
  873. +static void jh7110_padcfg_rmw(struct jh7110_pinctrl *sfp,
  874. + unsigned int pin, u32 mask, u32 value)
  875. +{
  876. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  877. + void __iomem *reg;
  878. + unsigned long flags;
  879. + int padcfg_base;
  880. +
  881. + if (!info->jh7110_get_padcfg_base)
  882. + return;
  883. +
  884. + padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
  885. + if (padcfg_base < 0)
  886. + return;
  887. +
  888. + reg = sfp->base + padcfg_base + 4 * pin;
  889. + value &= mask;
  890. +
  891. + raw_spin_lock_irqsave(&sfp->lock, flags);
  892. + value |= readl_relaxed(reg) & ~mask;
  893. + writel_relaxed(value, reg);
  894. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  895. +}
  896. +
  897. +static int jh7110_pinconf_get(struct pinctrl_dev *pctldev,
  898. + unsigned int pin, unsigned long *config)
  899. +{
  900. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  901. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  902. + int param = pinconf_to_config_param(*config);
  903. + u32 padcfg, arg;
  904. + bool enabled;
  905. + int padcfg_base;
  906. +
  907. + if (!info->jh7110_get_padcfg_base)
  908. + return 0;
  909. +
  910. + padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
  911. + if (padcfg_base < 0)
  912. + return 0;
  913. +
  914. + padcfg = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
  915. + switch (param) {
  916. + case PIN_CONFIG_BIAS_DISABLE:
  917. + enabled = !(padcfg & JH7110_PADCFG_BIAS);
  918. + arg = 0;
  919. + break;
  920. + case PIN_CONFIG_BIAS_PULL_DOWN:
  921. + enabled = padcfg & JH7110_PADCFG_PD;
  922. + arg = 1;
  923. + break;
  924. + case PIN_CONFIG_BIAS_PULL_UP:
  925. + enabled = padcfg & JH7110_PADCFG_PU;
  926. + arg = 1;
  927. + break;
  928. + case PIN_CONFIG_DRIVE_STRENGTH:
  929. + enabled = true;
  930. + arg = jh7110_padcfg_ds_to_mA(padcfg);
  931. + break;
  932. + case PIN_CONFIG_INPUT_ENABLE:
  933. + enabled = padcfg & JH7110_PADCFG_IE;
  934. + arg = enabled;
  935. + break;
  936. + case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
  937. + enabled = padcfg & JH7110_PADCFG_SMT;
  938. + arg = enabled;
  939. + break;
  940. + case PIN_CONFIG_SLEW_RATE:
  941. + enabled = true;
  942. + arg = !!(padcfg & JH7110_PADCFG_SLEW);
  943. + break;
  944. + default:
  945. + return -ENOTSUPP;
  946. + }
  947. +
  948. + *config = pinconf_to_config_packed(param, arg);
  949. + return enabled ? 0 : -EINVAL;
  950. +}
  951. +
  952. +static int jh7110_pinconf_group_get(struct pinctrl_dev *pctldev,
  953. + unsigned int gsel,
  954. + unsigned long *config)
  955. +{
  956. + const struct group_desc *group;
  957. +
  958. + group = pinctrl_generic_get_group(pctldev, gsel);
  959. + if (!group)
  960. + return -EINVAL;
  961. +
  962. + return jh7110_pinconf_get(pctldev, group->pins[0], config);
  963. +}
  964. +
  965. +static int jh7110_pinconf_group_set(struct pinctrl_dev *pctldev,
  966. + unsigned int gsel,
  967. + unsigned long *configs,
  968. + unsigned int num_configs)
  969. +{
  970. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  971. + const struct group_desc *group;
  972. + u16 mask, value;
  973. + int i;
  974. +
  975. + group = pinctrl_generic_get_group(pctldev, gsel);
  976. + if (!group)
  977. + return -EINVAL;
  978. +
  979. + mask = 0;
  980. + value = 0;
  981. + for (i = 0; i < num_configs; i++) {
  982. + int param = pinconf_to_config_param(configs[i]);
  983. + u32 arg = pinconf_to_config_argument(configs[i]);
  984. +
  985. + switch (param) {
  986. + case PIN_CONFIG_BIAS_DISABLE:
  987. + mask |= JH7110_PADCFG_BIAS;
  988. + value &= ~JH7110_PADCFG_BIAS;
  989. + break;
  990. + case PIN_CONFIG_BIAS_PULL_DOWN:
  991. + if (arg == 0)
  992. + return -ENOTSUPP;
  993. + mask |= JH7110_PADCFG_BIAS;
  994. + value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PD;
  995. + break;
  996. + case PIN_CONFIG_BIAS_PULL_UP:
  997. + if (arg == 0)
  998. + return -ENOTSUPP;
  999. + mask |= JH7110_PADCFG_BIAS;
  1000. + value = (value & ~JH7110_PADCFG_BIAS) | JH7110_PADCFG_PU;
  1001. + break;
  1002. + case PIN_CONFIG_DRIVE_STRENGTH:
  1003. + mask |= JH7110_PADCFG_DS_MASK;
  1004. + value = (value & ~JH7110_PADCFG_DS_MASK) |
  1005. + jh7110_padcfg_ds_from_mA(arg);
  1006. + break;
  1007. + case PIN_CONFIG_INPUT_ENABLE:
  1008. + mask |= JH7110_PADCFG_IE;
  1009. + if (arg)
  1010. + value |= JH7110_PADCFG_IE;
  1011. + else
  1012. + value &= ~JH7110_PADCFG_IE;
  1013. + break;
  1014. + case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
  1015. + mask |= JH7110_PADCFG_SMT;
  1016. + if (arg)
  1017. + value |= JH7110_PADCFG_SMT;
  1018. + else
  1019. + value &= ~JH7110_PADCFG_SMT;
  1020. + break;
  1021. + case PIN_CONFIG_SLEW_RATE:
  1022. + mask |= JH7110_PADCFG_SLEW;
  1023. + if (arg)
  1024. + value |= JH7110_PADCFG_SLEW;
  1025. + else
  1026. + value &= ~JH7110_PADCFG_SLEW;
  1027. + break;
  1028. + default:
  1029. + return -ENOTSUPP;
  1030. + }
  1031. + }
  1032. +
  1033. + for (i = 0; i < group->num_pins; i++)
  1034. + jh7110_padcfg_rmw(sfp, group->pins[i], mask, value);
  1035. +
  1036. + return 0;
  1037. +}
  1038. +
  1039. +#ifdef CONFIG_DEBUG_FS
  1040. +static void jh7110_pinconf_dbg_show(struct pinctrl_dev *pctldev,
  1041. + struct seq_file *s, unsigned int pin)
  1042. +{
  1043. + struct jh7110_pinctrl *sfp = pinctrl_dev_get_drvdata(pctldev);
  1044. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1045. + u32 value;
  1046. + int padcfg_base;
  1047. +
  1048. + if (!info->jh7110_get_padcfg_base)
  1049. + return;
  1050. +
  1051. + padcfg_base = info->jh7110_get_padcfg_base(sfp, pin);
  1052. + if (padcfg_base < 0)
  1053. + return;
  1054. +
  1055. + value = readl_relaxed(sfp->base + padcfg_base + 4 * pin);
  1056. + seq_printf(s, " (0x%02x)", value);
  1057. +}
  1058. +#else
  1059. +#define jh7110_pinconf_dbg_show NULL
  1060. +#endif
  1061. +
  1062. +static const struct pinconf_ops jh7110_pinconf_ops = {
  1063. + .pin_config_get = jh7110_pinconf_get,
  1064. + .pin_config_group_get = jh7110_pinconf_group_get,
  1065. + .pin_config_group_set = jh7110_pinconf_group_set,
  1066. + .pin_config_dbg_show = jh7110_pinconf_dbg_show,
  1067. + .is_generic = true,
  1068. +};
  1069. +
  1070. +static int jh7110_gpio_request(struct gpio_chip *gc, unsigned int gpio)
  1071. +{
  1072. + return pinctrl_gpio_request(gc->base + gpio);
  1073. +}
  1074. +
  1075. +static void jh7110_gpio_free(struct gpio_chip *gc, unsigned int gpio)
  1076. +{
  1077. + pinctrl_gpio_free(gc->base + gpio);
  1078. +}
  1079. +
  1080. +static int jh7110_gpio_get_direction(struct gpio_chip *gc,
  1081. + unsigned int gpio)
  1082. +{
  1083. + struct jh7110_pinctrl *sfp = container_of(gc,
  1084. + struct jh7110_pinctrl, gc);
  1085. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1086. + unsigned int offset = 4 * (gpio / 4);
  1087. + unsigned int shift = 8 * (gpio % 4);
  1088. + u32 doen = readl_relaxed(sfp->base + info->doen_reg_base + offset);
  1089. +
  1090. + doen = (doen >> shift) & info->doen_mask;
  1091. +
  1092. + return doen == GPOEN_ENABLE ?
  1093. + GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
  1094. +}
  1095. +
  1096. +static int jh7110_gpio_direction_input(struct gpio_chip *gc,
  1097. + unsigned int gpio)
  1098. +{
  1099. + struct jh7110_pinctrl *sfp = container_of(gc,
  1100. + struct jh7110_pinctrl, gc);
  1101. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1102. +
  1103. + /* enable input and schmitt trigger */
  1104. + jh7110_padcfg_rmw(sfp, gpio,
  1105. + JH7110_PADCFG_IE | JH7110_PADCFG_SMT,
  1106. + JH7110_PADCFG_IE | JH7110_PADCFG_SMT);
  1107. +
  1108. + if (info->jh7110_set_one_pin_mux)
  1109. + info->jh7110_set_one_pin_mux(sfp, gpio,
  1110. + GPI_NONE, GPOUT_LOW, GPOEN_DISABLE, 0);
  1111. +
  1112. + return 0;
  1113. +}
  1114. +
  1115. +static int jh7110_gpio_direction_output(struct gpio_chip *gc,
  1116. + unsigned int gpio, int value)
  1117. +{
  1118. + struct jh7110_pinctrl *sfp = container_of(gc,
  1119. + struct jh7110_pinctrl, gc);
  1120. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1121. +
  1122. + if (info->jh7110_set_one_pin_mux)
  1123. + info->jh7110_set_one_pin_mux(sfp, gpio,
  1124. + GPI_NONE, value ? GPOUT_HIGH : GPOUT_LOW,
  1125. + GPOEN_ENABLE, 0);
  1126. +
  1127. + /* disable input, schmitt trigger and bias */
  1128. + jh7110_padcfg_rmw(sfp, gpio,
  1129. + JH7110_PADCFG_IE | JH7110_PADCFG_SMT |
  1130. + JH7110_PADCFG_BIAS, 0);
  1131. + return 0;
  1132. +}
  1133. +
  1134. +static int jh7110_gpio_get(struct gpio_chip *gc, unsigned int gpio)
  1135. +{
  1136. + struct jh7110_pinctrl *sfp = container_of(gc,
  1137. + struct jh7110_pinctrl, gc);
  1138. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1139. + void __iomem *reg = sfp->base + info->gpioin_reg_base
  1140. + + 4 * (gpio / 32);
  1141. +
  1142. + return !!(readl_relaxed(reg) & BIT(gpio % 32));
  1143. +}
  1144. +
  1145. +static void jh7110_gpio_set(struct gpio_chip *gc,
  1146. + unsigned int gpio, int value)
  1147. +{
  1148. + struct jh7110_pinctrl *sfp = container_of(gc,
  1149. + struct jh7110_pinctrl, gc);
  1150. + const struct jh7110_pinctrl_soc_info *info = sfp->info;
  1151. + unsigned int offset = 4 * (gpio / 4);
  1152. + unsigned int shift = 8 * (gpio % 4);
  1153. + void __iomem *reg_dout = sfp->base + info->dout_reg_base + offset;
  1154. + u32 dout = (value ? GPOUT_HIGH : GPOUT_LOW) << shift;
  1155. + u32 mask = info->dout_mask << shift;
  1156. + unsigned long flags;
  1157. +
  1158. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1159. + dout |= readl_relaxed(reg_dout) & ~mask;
  1160. + writel_relaxed(dout, reg_dout);
  1161. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1162. +}
  1163. +
  1164. +static int jh7110_gpio_set_config(struct gpio_chip *gc,
  1165. + unsigned int gpio, unsigned long config)
  1166. +{
  1167. + struct jh7110_pinctrl *sfp = container_of(gc,
  1168. + struct jh7110_pinctrl, gc);
  1169. + u32 arg = pinconf_to_config_argument(config);
  1170. + u32 value;
  1171. + u32 mask;
  1172. +
  1173. + switch (pinconf_to_config_param(config)) {
  1174. + case PIN_CONFIG_BIAS_DISABLE:
  1175. + mask = JH7110_PADCFG_BIAS;
  1176. + value = 0;
  1177. + break;
  1178. + case PIN_CONFIG_BIAS_PULL_DOWN:
  1179. + if (arg == 0)
  1180. + return -ENOTSUPP;
  1181. + mask = JH7110_PADCFG_BIAS;
  1182. + value = JH7110_PADCFG_PD;
  1183. + break;
  1184. + case PIN_CONFIG_BIAS_PULL_UP:
  1185. + if (arg == 0)
  1186. + return -ENOTSUPP;
  1187. + mask = JH7110_PADCFG_BIAS;
  1188. + value = JH7110_PADCFG_PU;
  1189. + break;
  1190. + case PIN_CONFIG_DRIVE_PUSH_PULL:
  1191. + return 0;
  1192. + case PIN_CONFIG_INPUT_ENABLE:
  1193. + mask = JH7110_PADCFG_IE;
  1194. + value = arg ? JH7110_PADCFG_IE : 0;
  1195. + break;
  1196. + case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
  1197. + mask = JH7110_PADCFG_SMT;
  1198. + value = arg ? JH7110_PADCFG_SMT : 0;
  1199. + break;
  1200. + default:
  1201. + return -ENOTSUPP;
  1202. + }
  1203. +
  1204. + jh7110_padcfg_rmw(sfp, gpio, mask, value);
  1205. + return 0;
  1206. +}
  1207. +
  1208. +static int jh7110_gpio_add_pin_ranges(struct gpio_chip *gc)
  1209. +{
  1210. + struct jh7110_pinctrl *sfp = container_of(gc,
  1211. + struct jh7110_pinctrl, gc);
  1212. +
  1213. + sfp->gpios.name = sfp->gc.label;
  1214. + sfp->gpios.base = sfp->gc.base;
  1215. + sfp->gpios.pin_base = 0;
  1216. + sfp->gpios.npins = sfp->gc.ngpio;
  1217. + sfp->gpios.gc = &sfp->gc;
  1218. + pinctrl_add_gpio_range(sfp->pctl, &sfp->gpios);
  1219. + return 0;
  1220. +}
  1221. +
  1222. +static void jh7110_irq_ack(struct irq_data *d)
  1223. +{
  1224. + struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
  1225. + const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
  1226. + irq_hw_number_t gpio = irqd_to_hwirq(d);
  1227. + void __iomem *ic = sfp->base + irq_reg->ic_reg_base
  1228. + + 4 * (gpio / 32);
  1229. + u32 mask = BIT(gpio % 32);
  1230. + unsigned long flags;
  1231. + u32 value;
  1232. +
  1233. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1234. + value = readl_relaxed(ic) & ~mask;
  1235. + writel_relaxed(value, ic);
  1236. + writel_relaxed(value | mask, ic);
  1237. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1238. +}
  1239. +
  1240. +static void jh7110_irq_mask(struct irq_data *d)
  1241. +{
  1242. + struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
  1243. + const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
  1244. + irq_hw_number_t gpio = irqd_to_hwirq(d);
  1245. + void __iomem *ie = sfp->base + irq_reg->ie_reg_base
  1246. + + 4 * (gpio / 32);
  1247. + u32 mask = BIT(gpio % 32);
  1248. + unsigned long flags;
  1249. + u32 value;
  1250. +
  1251. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1252. + value = readl_relaxed(ie) & ~mask;
  1253. + writel_relaxed(value, ie);
  1254. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1255. +
  1256. + gpiochip_disable_irq(&sfp->gc, d->hwirq);
  1257. +}
  1258. +
  1259. +static void jh7110_irq_mask_ack(struct irq_data *d)
  1260. +{
  1261. + struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
  1262. + const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
  1263. + irq_hw_number_t gpio = irqd_to_hwirq(d);
  1264. + void __iomem *ie = sfp->base + irq_reg->ie_reg_base
  1265. + + 4 * (gpio / 32);
  1266. + void __iomem *ic = sfp->base + irq_reg->ic_reg_base
  1267. + + 4 * (gpio / 32);
  1268. + u32 mask = BIT(gpio % 32);
  1269. + unsigned long flags;
  1270. + u32 value;
  1271. +
  1272. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1273. + value = readl_relaxed(ie) & ~mask;
  1274. + writel_relaxed(value, ie);
  1275. +
  1276. + value = readl_relaxed(ic) & ~mask;
  1277. + writel_relaxed(value, ic);
  1278. + writel_relaxed(value | mask, ic);
  1279. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1280. +}
  1281. +
  1282. +static void jh7110_irq_unmask(struct irq_data *d)
  1283. +{
  1284. + struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
  1285. + const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
  1286. + irq_hw_number_t gpio = irqd_to_hwirq(d);
  1287. + void __iomem *ie = sfp->base + irq_reg->ie_reg_base
  1288. + + 4 * (gpio / 32);
  1289. + u32 mask = BIT(gpio % 32);
  1290. + unsigned long flags;
  1291. + u32 value;
  1292. +
  1293. + gpiochip_enable_irq(&sfp->gc, d->hwirq);
  1294. +
  1295. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1296. + value = readl_relaxed(ie) | mask;
  1297. + writel_relaxed(value, ie);
  1298. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1299. +}
  1300. +
  1301. +static int jh7110_irq_set_type(struct irq_data *d, unsigned int trigger)
  1302. +{
  1303. + struct jh7110_pinctrl *sfp = jh7110_from_irq_data(d);
  1304. + const struct jh7110_gpio_irq_reg *irq_reg = sfp->info->irq_reg;
  1305. + irq_hw_number_t gpio = irqd_to_hwirq(d);
  1306. + void __iomem *base = sfp->base + 4 * (gpio / 32);
  1307. + u32 mask = BIT(gpio % 32);
  1308. + u32 irq_type, edge_both, polarity;
  1309. + unsigned long flags;
  1310. +
  1311. + switch (trigger) {
  1312. + case IRQ_TYPE_EDGE_RISING:
  1313. + irq_type = mask; /* 1: edge triggered */
  1314. + edge_both = 0; /* 0: single edge */
  1315. + polarity = mask; /* 1: rising edge */
  1316. + break;
  1317. + case IRQ_TYPE_EDGE_FALLING:
  1318. + irq_type = mask; /* 1: edge triggered */
  1319. + edge_both = 0; /* 0: single edge */
  1320. + polarity = 0; /* 0: falling edge */
  1321. + break;
  1322. + case IRQ_TYPE_EDGE_BOTH:
  1323. + irq_type = mask; /* 1: edge triggered */
  1324. + edge_both = mask; /* 1: both edges */
  1325. + polarity = 0; /* 0: ignored */
  1326. + break;
  1327. + case IRQ_TYPE_LEVEL_HIGH:
  1328. + irq_type = 0; /* 0: level triggered */
  1329. + edge_both = 0; /* 0: ignored */
  1330. + polarity = mask; /* 1: high level */
  1331. + break;
  1332. + case IRQ_TYPE_LEVEL_LOW:
  1333. + irq_type = 0; /* 0: level triggered */
  1334. + edge_both = 0; /* 0: ignored */
  1335. + polarity = 0; /* 0: low level */
  1336. + break;
  1337. + default:
  1338. + return -EINVAL;
  1339. + }
  1340. +
  1341. + if (trigger & IRQ_TYPE_EDGE_BOTH)
  1342. + irq_set_handler_locked(d, handle_edge_irq);
  1343. + else
  1344. + irq_set_handler_locked(d, handle_level_irq);
  1345. +
  1346. + raw_spin_lock_irqsave(&sfp->lock, flags);
  1347. + irq_type |= readl_relaxed(base + irq_reg->is_reg_base) & ~mask;
  1348. + writel_relaxed(irq_type, base + irq_reg->is_reg_base);
  1349. +
  1350. + edge_both |= readl_relaxed(base + irq_reg->ibe_reg_base) & ~mask;
  1351. + writel_relaxed(edge_both, base + irq_reg->ibe_reg_base);
  1352. +
  1353. + polarity |= readl_relaxed(base + irq_reg->iev_reg_base) & ~mask;
  1354. + writel_relaxed(polarity, base + irq_reg->iev_reg_base);
  1355. + raw_spin_unlock_irqrestore(&sfp->lock, flags);
  1356. + return 0;
  1357. +}
  1358. +
  1359. +static struct irq_chip jh7110_irq_chip = {
  1360. + .irq_ack = jh7110_irq_ack,
  1361. + .irq_mask = jh7110_irq_mask,
  1362. + .irq_mask_ack = jh7110_irq_mask_ack,
  1363. + .irq_unmask = jh7110_irq_unmask,
  1364. + .irq_set_type = jh7110_irq_set_type,
  1365. + .flags = IRQCHIP_IMMUTABLE | IRQCHIP_SET_TYPE_MASKED,
  1366. + GPIOCHIP_IRQ_RESOURCE_HELPERS,
  1367. +};
  1368. +
  1369. +static void jh7110_disable_clock(void *data)
  1370. +{
  1371. + clk_disable_unprepare(data);
  1372. +}
  1373. +
  1374. +int jh7110_pinctrl_probe(struct platform_device *pdev)
  1375. +{
  1376. + struct device *dev = &pdev->dev;
  1377. + const struct jh7110_pinctrl_soc_info *info;
  1378. + struct jh7110_pinctrl *sfp;
  1379. + struct pinctrl_desc *jh7110_pinctrl_desc;
  1380. + struct reset_control *rst;
  1381. + struct clk *clk;
  1382. + int ret;
  1383. +
  1384. + info = of_device_get_match_data(&pdev->dev);
  1385. + if (!info)
  1386. + return -ENODEV;
  1387. +
  1388. + if (!info->pins || !info->npins) {
  1389. + dev_err(dev, "wrong pinctrl info\n");
  1390. + return -EINVAL;
  1391. + }
  1392. +
  1393. + sfp = devm_kzalloc(dev, sizeof(*sfp), GFP_KERNEL);
  1394. + if (!sfp)
  1395. + return -ENOMEM;
  1396. +
  1397. + sfp->base = devm_platform_ioremap_resource(pdev, 0);
  1398. + if (IS_ERR(sfp->base))
  1399. + return PTR_ERR(sfp->base);
  1400. +
  1401. + clk = devm_clk_get_optional(dev, NULL);
  1402. + if (IS_ERR(clk))
  1403. + return dev_err_probe(dev, PTR_ERR(clk), "could not get clock\n");
  1404. +
  1405. + rst = devm_reset_control_get_exclusive(dev, NULL);
  1406. + if (IS_ERR(rst))
  1407. + return dev_err_probe(dev, PTR_ERR(rst), "could not get reset\n");
  1408. +
  1409. + /*
  1410. + * we don't want to assert reset and risk undoing pin muxing for the
  1411. + * early boot serial console, but let's make sure the reset line is
  1412. + * deasserted in case someone runs a really minimal bootloader.
  1413. + */
  1414. + ret = reset_control_deassert(rst);
  1415. + if (ret)
  1416. + return dev_err_probe(dev, ret, "could not deassert reset\n");
  1417. +
  1418. + if (clk) {
  1419. + ret = clk_prepare_enable(clk);
  1420. + if (ret)
  1421. + return dev_err_probe(dev, ret, "could not enable clock\n");
  1422. +
  1423. + ret = devm_add_action_or_reset(dev, jh7110_disable_clock, clk);
  1424. + if (ret)
  1425. + return ret;
  1426. + }
  1427. +
  1428. + jh7110_pinctrl_desc = devm_kzalloc(&pdev->dev,
  1429. + sizeof(*jh7110_pinctrl_desc),
  1430. + GFP_KERNEL);
  1431. + if (!jh7110_pinctrl_desc)
  1432. + return -ENOMEM;
  1433. +
  1434. + jh7110_pinctrl_desc->name = dev_name(dev);
  1435. + jh7110_pinctrl_desc->pins = info->pins;
  1436. + jh7110_pinctrl_desc->npins = info->npins;
  1437. + jh7110_pinctrl_desc->pctlops = &jh7110_pinctrl_ops;
  1438. + jh7110_pinctrl_desc->pmxops = &jh7110_pinmux_ops;
  1439. + jh7110_pinctrl_desc->confops = &jh7110_pinconf_ops;
  1440. + jh7110_pinctrl_desc->owner = THIS_MODULE;
  1441. +
  1442. + sfp->info = info;
  1443. + sfp->dev = dev;
  1444. + platform_set_drvdata(pdev, sfp);
  1445. + sfp->gc.parent = dev;
  1446. + raw_spin_lock_init(&sfp->lock);
  1447. + mutex_init(&sfp->mutex);
  1448. +
  1449. + ret = devm_pinctrl_register_and_init(dev,
  1450. + jh7110_pinctrl_desc,
  1451. + sfp, &sfp->pctl);
  1452. + if (ret)
  1453. + return dev_err_probe(dev, ret,
  1454. + "could not register pinctrl driver\n");
  1455. +
  1456. + sfp->gc.label = dev_name(dev);
  1457. + sfp->gc.owner = THIS_MODULE;
  1458. + sfp->gc.request = jh7110_gpio_request;
  1459. + sfp->gc.free = jh7110_gpio_free;
  1460. + sfp->gc.get_direction = jh7110_gpio_get_direction;
  1461. + sfp->gc.direction_input = jh7110_gpio_direction_input;
  1462. + sfp->gc.direction_output = jh7110_gpio_direction_output;
  1463. + sfp->gc.get = jh7110_gpio_get;
  1464. + sfp->gc.set = jh7110_gpio_set;
  1465. + sfp->gc.set_config = jh7110_gpio_set_config;
  1466. + sfp->gc.add_pin_ranges = jh7110_gpio_add_pin_ranges;
  1467. + sfp->gc.base = info->gc_base;
  1468. + sfp->gc.ngpio = info->ngpios;
  1469. +
  1470. + jh7110_irq_chip.name = sfp->gc.label;
  1471. + gpio_irq_chip_set_chip(&sfp->gc.irq, &jh7110_irq_chip);
  1472. + sfp->gc.irq.parent_handler = info->jh7110_gpio_irq_handler;
  1473. + sfp->gc.irq.num_parents = 1;
  1474. + sfp->gc.irq.parents = devm_kcalloc(dev, sfp->gc.irq.num_parents,
  1475. + sizeof(*sfp->gc.irq.parents),
  1476. + GFP_KERNEL);
  1477. + if (!sfp->gc.irq.parents)
  1478. + return -ENOMEM;
  1479. + sfp->gc.irq.default_type = IRQ_TYPE_NONE;
  1480. + sfp->gc.irq.handler = handle_bad_irq;
  1481. + sfp->gc.irq.init_hw = info->jh7110_gpio_init_hw;
  1482. +
  1483. + ret = platform_get_irq(pdev, 0);
  1484. + if (ret < 0)
  1485. + return ret;
  1486. + sfp->gc.irq.parents[0] = ret;
  1487. +
  1488. + ret = devm_gpiochip_add_data(dev, &sfp->gc, sfp);
  1489. + if (ret)
  1490. + return dev_err_probe(dev, ret, "could not register gpiochip\n");
  1491. +
  1492. + irq_domain_set_pm_device(sfp->gc.irq.domain, dev);
  1493. +
  1494. + dev_info(dev, "StarFive GPIO chip registered %d GPIOs\n", sfp->gc.ngpio);
  1495. +
  1496. + return pinctrl_enable(sfp->pctl);
  1497. +}
  1498. +EXPORT_SYMBOL_GPL(jh7110_pinctrl_probe);
  1499. +
  1500. +MODULE_DESCRIPTION("Pinctrl driver for the StarFive JH7110 SoC");
  1501. +MODULE_AUTHOR("Emil Renner Berthing <[email protected]>");
  1502. +MODULE_AUTHOR("Jianlong Huang <[email protected]>");
  1503. +MODULE_LICENSE("GPL");
  1504. --- /dev/null
  1505. +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.h
  1506. @@ -0,0 +1,70 @@
  1507. +/* SPDX-License-Identifier: GPL-2.0 */
  1508. +/*
  1509. + * Pinctrl / GPIO driver for StarFive JH7110 SoC
  1510. + *
  1511. + * Copyright (C) 2022 StarFive Technology Co., Ltd.
  1512. + */
  1513. +
  1514. +#ifndef __PINCTRL_STARFIVE_JH7110_H__
  1515. +#define __PINCTRL_STARFIVE_JH7110_H__
  1516. +
  1517. +#include <linux/pinctrl/pinconf-generic.h>
  1518. +#include <linux/pinctrl/pinmux.h>
  1519. +
  1520. +struct jh7110_pinctrl {
  1521. + struct device *dev;
  1522. + struct gpio_chip gc;
  1523. + struct pinctrl_gpio_range gpios;
  1524. + raw_spinlock_t lock;
  1525. + void __iomem *base;
  1526. + struct pinctrl_dev *pctl;
  1527. + /* register read/write mutex */
  1528. + struct mutex mutex;
  1529. + const struct jh7110_pinctrl_soc_info *info;
  1530. +};
  1531. +
  1532. +struct jh7110_gpio_irq_reg {
  1533. + unsigned int is_reg_base;
  1534. + unsigned int ic_reg_base;
  1535. + unsigned int ibe_reg_base;
  1536. + unsigned int iev_reg_base;
  1537. + unsigned int ie_reg_base;
  1538. + unsigned int ris_reg_base;
  1539. + unsigned int mis_reg_base;
  1540. +};
  1541. +
  1542. +struct jh7110_pinctrl_soc_info {
  1543. + const struct pinctrl_pin_desc *pins;
  1544. + unsigned int npins;
  1545. + unsigned int ngpios;
  1546. + unsigned int gc_base;
  1547. +
  1548. + /* gpio dout/doen/din/gpioinput register */
  1549. + unsigned int dout_reg_base;
  1550. + unsigned int dout_mask;
  1551. + unsigned int doen_reg_base;
  1552. + unsigned int doen_mask;
  1553. + unsigned int gpi_reg_base;
  1554. + unsigned int gpi_mask;
  1555. + unsigned int gpioin_reg_base;
  1556. +
  1557. + const struct jh7110_gpio_irq_reg *irq_reg;
  1558. +
  1559. + /* generic pinmux */
  1560. + int (*jh7110_set_one_pin_mux)(struct jh7110_pinctrl *sfp,
  1561. + unsigned int pin,
  1562. + unsigned int din, u32 dout,
  1563. + u32 doen, u32 func);
  1564. + /* gpio chip */
  1565. + int (*jh7110_get_padcfg_base)(struct jh7110_pinctrl *sfp,
  1566. + unsigned int pin);
  1567. + void (*jh7110_gpio_irq_handler)(struct irq_desc *desc);
  1568. + int (*jh7110_gpio_init_hw)(struct gpio_chip *gc);
  1569. +};
  1570. +
  1571. +void jh7110_set_gpiomux(struct jh7110_pinctrl *sfp, unsigned int pin,
  1572. + unsigned int din, u32 dout, u32 doen);
  1573. +int jh7110_pinctrl_probe(struct platform_device *pdev);
  1574. +struct jh7110_pinctrl *jh7110_from_irq_desc(struct irq_desc *desc);
  1575. +
  1576. +#endif /* __PINCTRL_STARFIVE_JH7110_H__ */