pinctrl-armada-38x.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. // (C) 2022 Pali Rohár <pali@kernel.org>
  3. #include <common.h>
  4. #include <config.h>
  5. #include <dm.h>
  6. #include <dm/devres.h>
  7. #include <dm/lists.h>
  8. #include <dm/pinctrl.h>
  9. #include <dm/root.h>
  10. #include <errno.h>
  11. #include <asm/io.h>
  12. struct mvebu_mpp_ctrl_setting {
  13. const char *name;
  14. const char *subname;
  15. u8 val;
  16. u8 variant;
  17. };
  18. struct mvebu_mpp_mode {
  19. const char *name;
  20. size_t nsettings;
  21. struct mvebu_mpp_ctrl_setting *settings;
  22. };
  23. #define MPP_MODE(_name, ...) \
  24. { \
  25. .name = _name, \
  26. .nsettings = ARRAY_SIZE(( \
  27. (struct mvebu_mpp_ctrl_setting[]) \
  28. { __VA_ARGS__ })), \
  29. .settings = (struct mvebu_mpp_ctrl_setting[]){ \
  30. __VA_ARGS__ }, \
  31. }
  32. #define MPP_VAR_FUNCTION(_val, _name, _subname, _mask) \
  33. { \
  34. .val = _val, \
  35. .name = _name, \
  36. .subname = _subname, \
  37. .variant = _mask, \
  38. }
  39. #define MVEBU_MPPS_PER_REG 8
  40. #define MVEBU_MPP_BITS 4
  41. #define MVEBU_MPP_MASK 0xf
  42. enum {
  43. V_88F6810 = BIT(0),
  44. V_88F6820 = BIT(1),
  45. V_88F6828 = BIT(2),
  46. V_88F6810_PLUS = (V_88F6810 | V_88F6820 | V_88F6828),
  47. V_88F6820_PLUS = (V_88F6820 | V_88F6828),
  48. };
  49. static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
  50. MPP_MODE("mpp0",
  51. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  52. MPP_VAR_FUNCTION(1, "ua0", "rxd", V_88F6810_PLUS)),
  53. MPP_MODE("mpp1",
  54. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  55. MPP_VAR_FUNCTION(1, "ua0", "txd", V_88F6810_PLUS)),
  56. MPP_MODE("mpp2",
  57. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  58. MPP_VAR_FUNCTION(1, "i2c0", "sck", V_88F6810_PLUS)),
  59. MPP_MODE("mpp3",
  60. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  61. MPP_VAR_FUNCTION(1, "i2c0", "sda", V_88F6810_PLUS)),
  62. MPP_MODE("mpp4",
  63. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  64. MPP_VAR_FUNCTION(1, "ge", "mdc", V_88F6810_PLUS),
  65. MPP_VAR_FUNCTION(2, "ua1", "txd", V_88F6810_PLUS),
  66. MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS)),
  67. MPP_MODE("mpp5",
  68. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  69. MPP_VAR_FUNCTION(1, "ge", "mdio", V_88F6810_PLUS),
  70. MPP_VAR_FUNCTION(2, "ua1", "rxd", V_88F6810_PLUS),
  71. MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS)),
  72. MPP_MODE("mpp6",
  73. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  74. MPP_VAR_FUNCTION(1, "ge0", "txclkout", V_88F6810_PLUS),
  75. MPP_VAR_FUNCTION(2, "ge0", "crs", V_88F6810_PLUS),
  76. MPP_VAR_FUNCTION(5, "dev", "cs3", V_88F6810_PLUS)),
  77. MPP_MODE("mpp7",
  78. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  79. MPP_VAR_FUNCTION(1, "ge0", "txd0", V_88F6810_PLUS),
  80. MPP_VAR_FUNCTION(5, "dev", "ad9", V_88F6810_PLUS)),
  81. MPP_MODE("mpp8",
  82. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  83. MPP_VAR_FUNCTION(1, "ge0", "txd1", V_88F6810_PLUS),
  84. MPP_VAR_FUNCTION(5, "dev", "ad10", V_88F6810_PLUS)),
  85. MPP_MODE("mpp9",
  86. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  87. MPP_VAR_FUNCTION(1, "ge0", "txd2", V_88F6810_PLUS),
  88. MPP_VAR_FUNCTION(5, "dev", "ad11", V_88F6810_PLUS)),
  89. MPP_MODE("mpp10",
  90. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  91. MPP_VAR_FUNCTION(1, "ge0", "txd3", V_88F6810_PLUS),
  92. MPP_VAR_FUNCTION(5, "dev", "ad12", V_88F6810_PLUS)),
  93. MPP_MODE("mpp11",
  94. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  95. MPP_VAR_FUNCTION(1, "ge0", "txctl", V_88F6810_PLUS),
  96. MPP_VAR_FUNCTION(5, "dev", "ad13", V_88F6810_PLUS)),
  97. MPP_MODE("mpp12",
  98. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  99. MPP_VAR_FUNCTION(1, "ge0", "rxd0", V_88F6810_PLUS),
  100. MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
  101. MPP_VAR_FUNCTION(4, "spi0", "cs1", V_88F6810_PLUS),
  102. MPP_VAR_FUNCTION(5, "dev", "ad14", V_88F6810_PLUS),
  103. MPP_VAR_FUNCTION(6, "pcie3", "clkreq", V_88F6810_PLUS)),
  104. MPP_MODE("mpp13",
  105. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  106. MPP_VAR_FUNCTION(1, "ge0", "rxd1", V_88F6810_PLUS),
  107. MPP_VAR_FUNCTION(2, "pcie0", "clkreq", V_88F6810_PLUS),
  108. MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
  109. MPP_VAR_FUNCTION(4, "spi0", "cs2", V_88F6810_PLUS),
  110. MPP_VAR_FUNCTION(5, "dev", "ad15", V_88F6810_PLUS),
  111. MPP_VAR_FUNCTION(6, "pcie2", "clkreq", V_88F6810_PLUS)),
  112. MPP_MODE("mpp14",
  113. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  114. MPP_VAR_FUNCTION(1, "ge0", "rxd2", V_88F6810_PLUS),
  115. MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
  116. MPP_VAR_FUNCTION(3, "dram", "vttctrl", V_88F6810_PLUS),
  117. MPP_VAR_FUNCTION(4, "spi0", "cs3", V_88F6810_PLUS),
  118. MPP_VAR_FUNCTION(5, "dev", "we1", V_88F6810_PLUS),
  119. MPP_VAR_FUNCTION(6, "pcie3", "clkreq", V_88F6810_PLUS)),
  120. MPP_MODE("mpp15",
  121. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  122. MPP_VAR_FUNCTION(1, "ge0", "rxd3", V_88F6810_PLUS),
  123. MPP_VAR_FUNCTION(2, "ge", "mdc slave", V_88F6810_PLUS),
  124. MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
  125. MPP_VAR_FUNCTION(4, "spi0", "mosi", V_88F6810_PLUS)),
  126. MPP_MODE("mpp16",
  127. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  128. MPP_VAR_FUNCTION(1, "ge0", "rxctl", V_88F6810_PLUS),
  129. MPP_VAR_FUNCTION(2, "ge", "mdio slave", V_88F6810_PLUS),
  130. MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
  131. MPP_VAR_FUNCTION(4, "spi0", "miso", V_88F6810_PLUS),
  132. MPP_VAR_FUNCTION(5, "pcie0", "clkreq", V_88F6810_PLUS),
  133. MPP_VAR_FUNCTION(6, "pcie1", "clkreq", V_88F6820_PLUS)),
  134. MPP_MODE("mpp17",
  135. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  136. MPP_VAR_FUNCTION(1, "ge0", "rxclk", V_88F6810_PLUS),
  137. MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
  138. MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
  139. MPP_VAR_FUNCTION(4, "spi0", "sck", V_88F6810_PLUS),
  140. MPP_VAR_FUNCTION(5, "sata1", "prsnt", V_88F6810_PLUS),
  141. MPP_VAR_FUNCTION(6, "sata0", "prsnt", V_88F6810_PLUS)),
  142. MPP_MODE("mpp18",
  143. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  144. MPP_VAR_FUNCTION(1, "ge0", "rxerr", V_88F6810_PLUS),
  145. MPP_VAR_FUNCTION(2, "ptp", "trig", V_88F6810_PLUS),
  146. MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
  147. MPP_VAR_FUNCTION(4, "spi0", "cs0", V_88F6810_PLUS)),
  148. MPP_MODE("mpp19",
  149. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  150. MPP_VAR_FUNCTION(1, "ge0", "col", V_88F6810_PLUS),
  151. MPP_VAR_FUNCTION(2, "ptp", "evreq", V_88F6810_PLUS),
  152. MPP_VAR_FUNCTION(3, "ge0", "txerr", V_88F6810_PLUS),
  153. MPP_VAR_FUNCTION(4, "sata1", "prsnt", V_88F6810_PLUS),
  154. MPP_VAR_FUNCTION(5, "ua0", "cts", V_88F6810_PLUS),
  155. MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
  156. MPP_MODE("mpp20",
  157. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  158. MPP_VAR_FUNCTION(1, "ge0", "txclk", V_88F6810_PLUS),
  159. MPP_VAR_FUNCTION(2, "ptp", "clk", V_88F6810_PLUS),
  160. MPP_VAR_FUNCTION(4, "sata0", "prsnt", V_88F6810_PLUS),
  161. MPP_VAR_FUNCTION(5, "ua0", "rts", V_88F6810_PLUS),
  162. MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
  163. MPP_MODE("mpp21",
  164. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  165. MPP_VAR_FUNCTION(1, "spi0", "cs1", V_88F6810_PLUS),
  166. MPP_VAR_FUNCTION(2, "ge1", "rxd0", V_88F6810_PLUS),
  167. MPP_VAR_FUNCTION(3, "sata0", "prsnt", V_88F6810_PLUS),
  168. MPP_VAR_FUNCTION(4, "sd0", "cmd", V_88F6810_PLUS),
  169. MPP_VAR_FUNCTION(5, "dev", "bootcs", V_88F6810_PLUS),
  170. MPP_VAR_FUNCTION(6, "sata1", "prsnt", V_88F6810_PLUS)),
  171. MPP_MODE("mpp22",
  172. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  173. MPP_VAR_FUNCTION(1, "spi0", "mosi", V_88F6810_PLUS),
  174. MPP_VAR_FUNCTION(5, "dev", "ad0", V_88F6810_PLUS)),
  175. MPP_MODE("mpp23",
  176. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  177. MPP_VAR_FUNCTION(1, "spi0", "sck", V_88F6810_PLUS),
  178. MPP_VAR_FUNCTION(5, "dev", "ad2", V_88F6810_PLUS)),
  179. MPP_MODE("mpp24",
  180. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  181. MPP_VAR_FUNCTION(1, "spi0", "miso", V_88F6810_PLUS),
  182. MPP_VAR_FUNCTION(2, "ua0", "cts", V_88F6810_PLUS),
  183. MPP_VAR_FUNCTION(3, "ua1", "rxd", V_88F6810_PLUS),
  184. MPP_VAR_FUNCTION(4, "sd0", "d4", V_88F6810_PLUS),
  185. MPP_VAR_FUNCTION(5, "dev", "ready", V_88F6810_PLUS)),
  186. MPP_MODE("mpp25",
  187. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  188. MPP_VAR_FUNCTION(1, "spi0", "cs0", V_88F6810_PLUS),
  189. MPP_VAR_FUNCTION(2, "ua0", "rts", V_88F6810_PLUS),
  190. MPP_VAR_FUNCTION(3, "ua1", "txd", V_88F6810_PLUS),
  191. MPP_VAR_FUNCTION(4, "sd0", "d5", V_88F6810_PLUS),
  192. MPP_VAR_FUNCTION(5, "dev", "cs0", V_88F6810_PLUS)),
  193. MPP_MODE("mpp26",
  194. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  195. MPP_VAR_FUNCTION(1, "spi0", "cs2", V_88F6810_PLUS),
  196. MPP_VAR_FUNCTION(3, "i2c1", "sck", V_88F6810_PLUS),
  197. MPP_VAR_FUNCTION(4, "sd0", "d6", V_88F6810_PLUS),
  198. MPP_VAR_FUNCTION(5, "dev", "cs1", V_88F6810_PLUS)),
  199. MPP_MODE("mpp27",
  200. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  201. MPP_VAR_FUNCTION(1, "spi0", "cs3", V_88F6810_PLUS),
  202. MPP_VAR_FUNCTION(2, "ge1", "txclkout", V_88F6810_PLUS),
  203. MPP_VAR_FUNCTION(3, "i2c1", "sda", V_88F6810_PLUS),
  204. MPP_VAR_FUNCTION(4, "sd0", "d7", V_88F6810_PLUS),
  205. MPP_VAR_FUNCTION(5, "dev", "cs2", V_88F6810_PLUS)),
  206. MPP_MODE("mpp28",
  207. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  208. MPP_VAR_FUNCTION(2, "ge1", "txd0", V_88F6810_PLUS),
  209. MPP_VAR_FUNCTION(4, "sd0", "clk", V_88F6810_PLUS),
  210. MPP_VAR_FUNCTION(5, "dev", "ad5", V_88F6810_PLUS)),
  211. MPP_MODE("mpp29",
  212. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  213. MPP_VAR_FUNCTION(2, "ge1", "txd1", V_88F6810_PLUS),
  214. MPP_VAR_FUNCTION(5, "dev", "ale0", V_88F6810_PLUS)),
  215. MPP_MODE("mpp30",
  216. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  217. MPP_VAR_FUNCTION(2, "ge1", "txd2", V_88F6810_PLUS),
  218. MPP_VAR_FUNCTION(5, "dev", "oe", V_88F6810_PLUS)),
  219. MPP_MODE("mpp31",
  220. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  221. MPP_VAR_FUNCTION(2, "ge1", "txd3", V_88F6810_PLUS),
  222. MPP_VAR_FUNCTION(5, "dev", "ale1", V_88F6810_PLUS)),
  223. MPP_MODE("mpp32",
  224. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  225. MPP_VAR_FUNCTION(2, "ge1", "txctl", V_88F6810_PLUS),
  226. MPP_VAR_FUNCTION(5, "dev", "we0", V_88F6810_PLUS)),
  227. MPP_MODE("mpp33",
  228. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  229. MPP_VAR_FUNCTION(1, "dram", "deccerr", V_88F6810_PLUS),
  230. MPP_VAR_FUNCTION(5, "dev", "ad3", V_88F6810_PLUS)),
  231. MPP_MODE("mpp34",
  232. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  233. MPP_VAR_FUNCTION(5, "dev", "ad1", V_88F6810_PLUS)),
  234. MPP_MODE("mpp35",
  235. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  236. MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
  237. MPP_VAR_FUNCTION(5, "dev", "a1", V_88F6810_PLUS)),
  238. MPP_MODE("mpp36",
  239. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  240. MPP_VAR_FUNCTION(1, "ptp", "trig", V_88F6810_PLUS),
  241. MPP_VAR_FUNCTION(5, "dev", "a0", V_88F6810_PLUS)),
  242. MPP_MODE("mpp37",
  243. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  244. MPP_VAR_FUNCTION(1, "ptp", "clk", V_88F6810_PLUS),
  245. MPP_VAR_FUNCTION(2, "ge1", "rxclk", V_88F6810_PLUS),
  246. MPP_VAR_FUNCTION(4, "sd0", "d3", V_88F6810_PLUS),
  247. MPP_VAR_FUNCTION(5, "dev", "ad8", V_88F6810_PLUS)),
  248. MPP_MODE("mpp38",
  249. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  250. MPP_VAR_FUNCTION(1, "ptp", "evreq", V_88F6810_PLUS),
  251. MPP_VAR_FUNCTION(2, "ge1", "rxd1", V_88F6810_PLUS),
  252. MPP_VAR_FUNCTION(3, "ref", "clk_out0", V_88F6810_PLUS),
  253. MPP_VAR_FUNCTION(4, "sd0", "d0", V_88F6810_PLUS),
  254. MPP_VAR_FUNCTION(5, "dev", "ad4", V_88F6810_PLUS)),
  255. MPP_MODE("mpp39",
  256. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  257. MPP_VAR_FUNCTION(1, "i2c1", "sck", V_88F6810_PLUS),
  258. MPP_VAR_FUNCTION(2, "ge1", "rxd2", V_88F6810_PLUS),
  259. MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
  260. MPP_VAR_FUNCTION(4, "sd0", "d1", V_88F6810_PLUS),
  261. MPP_VAR_FUNCTION(5, "dev", "a2", V_88F6810_PLUS)),
  262. MPP_MODE("mpp40",
  263. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  264. MPP_VAR_FUNCTION(1, "i2c1", "sda", V_88F6810_PLUS),
  265. MPP_VAR_FUNCTION(2, "ge1", "rxd3", V_88F6810_PLUS),
  266. MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
  267. MPP_VAR_FUNCTION(4, "sd0", "d2", V_88F6810_PLUS),
  268. MPP_VAR_FUNCTION(5, "dev", "ad6", V_88F6810_PLUS)),
  269. MPP_MODE("mpp41",
  270. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  271. MPP_VAR_FUNCTION(1, "ua1", "rxd", V_88F6810_PLUS),
  272. MPP_VAR_FUNCTION(2, "ge1", "rxctl", V_88F6810_PLUS),
  273. MPP_VAR_FUNCTION(3, "ua0", "cts", V_88F6810_PLUS),
  274. MPP_VAR_FUNCTION(4, "spi1", "cs3", V_88F6810_PLUS),
  275. MPP_VAR_FUNCTION(5, "dev", "burst/last", V_88F6810_PLUS),
  276. MPP_VAR_FUNCTION(6, "nand", "rb0", V_88F6810_PLUS)),
  277. MPP_MODE("mpp42",
  278. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  279. MPP_VAR_FUNCTION(1, "ua1", "txd", V_88F6810_PLUS),
  280. MPP_VAR_FUNCTION(3, "ua0", "rts", V_88F6810_PLUS),
  281. MPP_VAR_FUNCTION(5, "dev", "ad7", V_88F6810_PLUS)),
  282. MPP_MODE("mpp43",
  283. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  284. MPP_VAR_FUNCTION(1, "pcie0", "clkreq", V_88F6810_PLUS),
  285. MPP_VAR_FUNCTION(2, "dram", "vttctrl", V_88F6810_PLUS),
  286. MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
  287. MPP_VAR_FUNCTION(4, "spi1", "cs2", V_88F6810_PLUS),
  288. MPP_VAR_FUNCTION(5, "dev", "clkout", V_88F6810_PLUS),
  289. MPP_VAR_FUNCTION(6, "nand", "rb1", V_88F6810_PLUS)),
  290. MPP_MODE("mpp44",
  291. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  292. MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
  293. MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
  294. MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
  295. MPP_VAR_FUNCTION(4, "sata3", "prsnt", V_88F6828)),
  296. MPP_MODE("mpp45",
  297. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  298. MPP_VAR_FUNCTION(1, "ref", "clk_out0", V_88F6810_PLUS),
  299. MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
  300. MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
  301. MPP_MODE("mpp46",
  302. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  303. MPP_VAR_FUNCTION(1, "ref", "clk_out1", V_88F6810_PLUS),
  304. MPP_VAR_FUNCTION(2, "pcie0", "rstout", V_88F6810_PLUS),
  305. MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
  306. MPP_MODE("mpp47",
  307. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  308. MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
  309. MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
  310. MPP_VAR_FUNCTION(3, "sata2", "prsnt", V_88F6828),
  311. MPP_VAR_FUNCTION(5, "sata3", "prsnt", V_88F6828)),
  312. MPP_MODE("mpp48",
  313. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  314. MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
  315. MPP_VAR_FUNCTION(2, "dram", "vttctrl", V_88F6810_PLUS),
  316. MPP_VAR_FUNCTION(3, "tdm", "pclk", V_88F6810_PLUS),
  317. MPP_VAR_FUNCTION(4, "audio", "mclk", V_88F6810_PLUS),
  318. MPP_VAR_FUNCTION(5, "sd0", "d4", V_88F6810_PLUS),
  319. MPP_VAR_FUNCTION(6, "pcie0", "clkreq", V_88F6810_PLUS)),
  320. MPP_MODE("mpp49",
  321. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  322. MPP_VAR_FUNCTION(1, "sata2", "prsnt", V_88F6828),
  323. MPP_VAR_FUNCTION(2, "sata3", "prsnt", V_88F6828),
  324. MPP_VAR_FUNCTION(3, "tdm", "fsync", V_88F6810_PLUS),
  325. MPP_VAR_FUNCTION(4, "audio", "lrclk", V_88F6810_PLUS),
  326. MPP_VAR_FUNCTION(5, "sd0", "d5", V_88F6810_PLUS),
  327. MPP_VAR_FUNCTION(6, "pcie1", "clkreq", V_88F6820_PLUS)),
  328. MPP_MODE("mpp50",
  329. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  330. MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
  331. MPP_VAR_FUNCTION(3, "tdm", "drx", V_88F6810_PLUS),
  332. MPP_VAR_FUNCTION(4, "audio", "extclk", V_88F6810_PLUS),
  333. MPP_VAR_FUNCTION(5, "sd0", "cmd", V_88F6810_PLUS)),
  334. MPP_MODE("mpp51",
  335. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  336. MPP_VAR_FUNCTION(3, "tdm", "dtx", V_88F6810_PLUS),
  337. MPP_VAR_FUNCTION(4, "audio", "sdo", V_88F6810_PLUS),
  338. MPP_VAR_FUNCTION(5, "dram", "deccerr", V_88F6810_PLUS),
  339. MPP_VAR_FUNCTION(6, "ptp", "trig", V_88F6810_PLUS)),
  340. MPP_MODE("mpp52",
  341. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  342. MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
  343. MPP_VAR_FUNCTION(3, "tdm", "int", V_88F6810_PLUS),
  344. MPP_VAR_FUNCTION(4, "audio", "sdi", V_88F6810_PLUS),
  345. MPP_VAR_FUNCTION(5, "sd0", "d6", V_88F6810_PLUS),
  346. MPP_VAR_FUNCTION(6, "ptp", "clk", V_88F6810_PLUS)),
  347. MPP_MODE("mpp53",
  348. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  349. MPP_VAR_FUNCTION(1, "sata1", "prsnt", V_88F6810_PLUS),
  350. MPP_VAR_FUNCTION(2, "sata0", "prsnt", V_88F6810_PLUS),
  351. MPP_VAR_FUNCTION(3, "tdm", "rst", V_88F6810_PLUS),
  352. MPP_VAR_FUNCTION(4, "audio", "bclk", V_88F6810_PLUS),
  353. MPP_VAR_FUNCTION(5, "sd0", "d7", V_88F6810_PLUS),
  354. MPP_VAR_FUNCTION(6, "ptp", "evreq", V_88F6810_PLUS)),
  355. MPP_MODE("mpp54",
  356. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  357. MPP_VAR_FUNCTION(1, "sata0", "prsnt", V_88F6810_PLUS),
  358. MPP_VAR_FUNCTION(2, "sata1", "prsnt", V_88F6810_PLUS),
  359. MPP_VAR_FUNCTION(3, "pcie0", "rstout", V_88F6810_PLUS),
  360. MPP_VAR_FUNCTION(4, "ge0", "txerr", V_88F6810_PLUS),
  361. MPP_VAR_FUNCTION(5, "sd0", "d3", V_88F6810_PLUS)),
  362. MPP_MODE("mpp55",
  363. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  364. MPP_VAR_FUNCTION(1, "ua1", "cts", V_88F6810_PLUS),
  365. MPP_VAR_FUNCTION(2, "ge", "mdio", V_88F6810_PLUS),
  366. MPP_VAR_FUNCTION(3, "pcie1", "clkreq", V_88F6820_PLUS),
  367. MPP_VAR_FUNCTION(4, "spi1", "cs1", V_88F6810_PLUS),
  368. MPP_VAR_FUNCTION(5, "sd0", "d0", V_88F6810_PLUS),
  369. MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
  370. MPP_MODE("mpp56",
  371. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  372. MPP_VAR_FUNCTION(1, "ua1", "rts", V_88F6810_PLUS),
  373. MPP_VAR_FUNCTION(2, "ge", "mdc", V_88F6810_PLUS),
  374. MPP_VAR_FUNCTION(3, "dram", "deccerr", V_88F6810_PLUS),
  375. MPP_VAR_FUNCTION(4, "spi1", "mosi", V_88F6810_PLUS),
  376. MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
  377. MPP_MODE("mpp57",
  378. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  379. MPP_VAR_FUNCTION(4, "spi1", "sck", V_88F6810_PLUS),
  380. MPP_VAR_FUNCTION(5, "sd0", "clk", V_88F6810_PLUS),
  381. MPP_VAR_FUNCTION(6, "ua1", "txd", V_88F6810_PLUS)),
  382. MPP_MODE("mpp58",
  383. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  384. MPP_VAR_FUNCTION(1, "pcie1", "clkreq", V_88F6820_PLUS),
  385. MPP_VAR_FUNCTION(2, "i2c1", "sck", V_88F6810_PLUS),
  386. MPP_VAR_FUNCTION(3, "pcie2", "clkreq", V_88F6810_PLUS),
  387. MPP_VAR_FUNCTION(4, "spi1", "miso", V_88F6810_PLUS),
  388. MPP_VAR_FUNCTION(5, "sd0", "d1", V_88F6810_PLUS),
  389. MPP_VAR_FUNCTION(6, "ua1", "rxd", V_88F6810_PLUS)),
  390. MPP_MODE("mpp59",
  391. MPP_VAR_FUNCTION(0, "gpio", NULL, V_88F6810_PLUS),
  392. MPP_VAR_FUNCTION(1, "pcie0", "rstout", V_88F6810_PLUS),
  393. MPP_VAR_FUNCTION(2, "i2c1", "sda", V_88F6810_PLUS),
  394. MPP_VAR_FUNCTION(4, "spi1", "cs0", V_88F6810_PLUS),
  395. MPP_VAR_FUNCTION(5, "sd0", "d2", V_88F6810_PLUS)),
  396. };
  397. static const char * const armada_38x_mpp_function_names[] = {
  398. "gpio", /* make gpio always as function 0 */
  399. "audio",
  400. "dev",
  401. "dram",
  402. "ge",
  403. "ge0",
  404. "ge1",
  405. "i2c0",
  406. "i2c1",
  407. "nand",
  408. "pcie0",
  409. "pcie1",
  410. "pcie2",
  411. "pcie3",
  412. "ptp",
  413. "ref",
  414. "sata0",
  415. "sata1",
  416. "sata2",
  417. "sata3",
  418. "sd0",
  419. "spi0",
  420. "spi1",
  421. "tdm",
  422. "ua0",
  423. "ua1",
  424. };
  425. struct armada_38x_pinctrl {
  426. void __iomem *base;
  427. u8 variant;
  428. };
  429. static int armada_38x_pinctrl_get_pins_count(struct udevice *dev)
  430. {
  431. return ARRAY_SIZE(armada_38x_mpp_modes);
  432. }
  433. static const char *armada_38x_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector)
  434. {
  435. return armada_38x_mpp_modes[selector].name;
  436. }
  437. static int armada_38x_pinctrl_get_functions_count(struct udevice *dev)
  438. {
  439. return ARRAY_SIZE(armada_38x_mpp_function_names);
  440. }
  441. static const char *armada_38x_pinctrl_get_function_name(struct udevice *dev, unsigned int selector)
  442. {
  443. return armada_38x_mpp_function_names[selector];
  444. }
  445. static int armada_38x_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector,
  446. char *buf, int size)
  447. {
  448. struct armada_38x_pinctrl *info = dev_get_priv(dev);
  449. unsigned int off = (selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
  450. unsigned int shift = (selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
  451. const char *func_name = NULL;
  452. const char *sub_name = NULL;
  453. unsigned long config;
  454. int i;
  455. config = (readl(info->base + off) >> shift) & MVEBU_MPP_MASK;
  456. for (i = 0; i < armada_38x_mpp_modes[selector].nsettings; i++) {
  457. if (armada_38x_mpp_modes[selector].settings[i].val == config)
  458. break;
  459. }
  460. if (i < armada_38x_mpp_modes[selector].nsettings) {
  461. func_name = armada_38x_mpp_modes[selector].settings[i].name;
  462. sub_name = armada_38x_mpp_modes[selector].settings[i].subname;
  463. }
  464. snprintf(buf, size, "%s%s%s",
  465. func_name ? func_name : "unknown",
  466. sub_name ? "_" : "",
  467. sub_name ? sub_name : "");
  468. return 0;
  469. }
  470. static int armada_38x_pinctrl_pinmux_set(struct udevice *dev, unsigned int pin_selector,
  471. unsigned int func_selector)
  472. {
  473. struct armada_38x_pinctrl *info = dev_get_priv(dev);
  474. unsigned int off = (pin_selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
  475. unsigned int shift = (pin_selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
  476. const char *func_name = armada_38x_mpp_function_names[func_selector];
  477. unsigned long config, reg;
  478. int i;
  479. for (i = 0; i < armada_38x_mpp_modes[pin_selector].nsettings; i++) {
  480. if (strcmp(armada_38x_mpp_modes[pin_selector].settings[i].name, func_name) == 0)
  481. break;
  482. }
  483. if (i >= armada_38x_mpp_modes[pin_selector].nsettings)
  484. return -EINVAL;
  485. if (!(info->variant & armada_38x_mpp_modes[pin_selector].settings[i].variant))
  486. return -EINVAL;
  487. reg = readl(info->base + off) & ~(MVEBU_MPP_MASK << shift);
  488. config = armada_38x_mpp_modes[pin_selector].settings[i].val;
  489. writel(reg | (config << shift), info->base + off);
  490. return 0;
  491. }
  492. static int armada_38x_pinctrl_gpio_request_enable(struct udevice *dev, unsigned int selector)
  493. {
  494. char buf[20];
  495. armada_38x_pinctrl_get_pin_muxing(dev, selector, buf, sizeof(buf));
  496. if (strcmp(buf, "gpio") != 0)
  497. printf("Warning: Changing mpp%u function from %s to gpio...\n", selector, buf);
  498. return armada_38x_pinctrl_pinmux_set(dev, selector, 0); /* gpio is always function 0 */
  499. }
  500. static int armada_38x_pinctrl_gpio_disable_free(struct udevice *dev, unsigned int selector)
  501. {
  502. /* nothing to do */
  503. return 0;
  504. }
  505. static int armada_38x_pinctrl_set_state(struct udevice *dev, struct udevice *config)
  506. {
  507. return pinctrl_generic_set_state_prefix(dev, config, "marvell,");
  508. }
  509. static int armada_38x_pinctrl_probe(struct udevice *dev)
  510. {
  511. struct armada_38x_pinctrl *info = dev_get_priv(dev);
  512. info->variant = (u8)dev_get_driver_data(dev);
  513. info->base = dev_read_addr_ptr(dev);
  514. if (!info->base)
  515. return -EINVAL;
  516. return 0;
  517. }
  518. struct pinctrl_ops armada_37xx_pinctrl_ops = {
  519. .get_pins_count = armada_38x_pinctrl_get_pins_count,
  520. .get_pin_name = armada_38x_pinctrl_get_pin_name,
  521. .get_functions_count = armada_38x_pinctrl_get_functions_count,
  522. .get_function_name = armada_38x_pinctrl_get_function_name,
  523. .get_pin_muxing = armada_38x_pinctrl_get_pin_muxing,
  524. .pinmux_set = armada_38x_pinctrl_pinmux_set,
  525. .gpio_request_enable = armada_38x_pinctrl_gpio_request_enable,
  526. .gpio_disable_free = armada_38x_pinctrl_gpio_disable_free,
  527. .set_state = armada_38x_pinctrl_set_state,
  528. };
  529. static const struct udevice_id armada_38x_pinctrl_of_match[] = {
  530. {
  531. .compatible = "marvell,mv88f6810-pinctrl",
  532. .data = V_88F6810,
  533. },
  534. {
  535. .compatible = "marvell,mv88f6820-pinctrl",
  536. .data = V_88F6820,
  537. },
  538. {
  539. .compatible = "marvell,mv88f6828-pinctrl",
  540. .data = V_88F6828,
  541. },
  542. { },
  543. };
  544. U_BOOT_DRIVER(armada_38x_pinctrl) = {
  545. .name = "armada-38x-pinctrl",
  546. .id = UCLASS_PINCTRL,
  547. .of_match = of_match_ptr(armada_38x_pinctrl_of_match),
  548. .probe = armada_38x_pinctrl_probe,
  549. .priv_auto = sizeof(struct armada_38x_pinctrl),
  550. .ops = &armada_37xx_pinctrl_ops,
  551. };