pinctrl-rk3308.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2019 Rockchip Electronics Co., Ltd
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <log.h>
  8. #include <dm/pinctrl.h>
  9. #include <regmap.h>
  10. #include <syscon.h>
  11. #include <linux/bitops.h>
  12. #include "pinctrl-rockchip.h"
  13. static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = {
  14. {
  15. .num = 1,
  16. .pin = 14,
  17. .reg = 0x28,
  18. .bit = 12,
  19. .mask = 0xf
  20. }, {
  21. .num = 1,
  22. .pin = 15,
  23. .reg = 0x2c,
  24. .bit = 0,
  25. .mask = 0x3
  26. }, {
  27. .num = 1,
  28. .pin = 18,
  29. .reg = 0x30,
  30. .bit = 4,
  31. .mask = 0xf
  32. }, {
  33. .num = 1,
  34. .pin = 19,
  35. .reg = 0x30,
  36. .bit = 8,
  37. .mask = 0xf
  38. }, {
  39. .num = 1,
  40. .pin = 20,
  41. .reg = 0x30,
  42. .bit = 12,
  43. .mask = 0xf
  44. }, {
  45. .num = 1,
  46. .pin = 21,
  47. .reg = 0x34,
  48. .bit = 0,
  49. .mask = 0xf
  50. }, {
  51. .num = 1,
  52. .pin = 22,
  53. .reg = 0x34,
  54. .bit = 4,
  55. .mask = 0xf
  56. }, {
  57. .num = 1,
  58. .pin = 23,
  59. .reg = 0x34,
  60. .bit = 8,
  61. .mask = 0xf
  62. }, {
  63. .num = 3,
  64. .pin = 12,
  65. .reg = 0x68,
  66. .bit = 8,
  67. .mask = 0xf
  68. }, {
  69. .num = 3,
  70. .pin = 13,
  71. .reg = 0x68,
  72. .bit = 12,
  73. .mask = 0xf
  74. }, {
  75. .num = 2,
  76. .pin = 2,
  77. .reg = 0x608,
  78. .bit = 0,
  79. .mask = 0x7
  80. }, {
  81. .num = 2,
  82. .pin = 3,
  83. .reg = 0x608,
  84. .bit = 4,
  85. .mask = 0x7
  86. }, {
  87. .num = 2,
  88. .pin = 16,
  89. .reg = 0x610,
  90. .bit = 8,
  91. .mask = 0x7
  92. }, {
  93. .num = 3,
  94. .pin = 10,
  95. .reg = 0x610,
  96. .bit = 0,
  97. .mask = 0x7
  98. }, {
  99. .num = 3,
  100. .pin = 11,
  101. .reg = 0x610,
  102. .bit = 4,
  103. .mask = 0x7
  104. },
  105. };
  106. static struct rockchip_mux_route_data rk3308_mux_route_data[] = {
  107. {
  108. /* rtc_clk */
  109. .bank_num = 0,
  110. .pin = 19,
  111. .func = 1,
  112. .route_offset = 0x314,
  113. .route_val = BIT(16 + 0) | BIT(0),
  114. }, {
  115. /* uart2_rxm0 */
  116. .bank_num = 1,
  117. .pin = 22,
  118. .func = 2,
  119. .route_offset = 0x314,
  120. .route_val = BIT(16 + 2) | BIT(16 + 3),
  121. }, {
  122. /* uart2_rxm1 */
  123. .bank_num = 4,
  124. .pin = 26,
  125. .func = 2,
  126. .route_offset = 0x314,
  127. .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2),
  128. }, {
  129. /* i2c3_sdam0 */
  130. .bank_num = 0,
  131. .pin = 15,
  132. .func = 2,
  133. .route_offset = 0x608,
  134. .route_val = BIT(16 + 8) | BIT(16 + 9),
  135. }, {
  136. /* i2c3_sdam1 */
  137. .bank_num = 3,
  138. .pin = 12,
  139. .func = 2,
  140. .route_offset = 0x608,
  141. .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(8),
  142. }, {
  143. /* i2c3_sdam2 */
  144. .bank_num = 2,
  145. .pin = 0,
  146. .func = 3,
  147. .route_offset = 0x608,
  148. .route_val = BIT(16 + 8) | BIT(16 + 9) | BIT(9),
  149. }, {
  150. /* i2s-8ch-1-sclktxm0 */
  151. .bank_num = 1,
  152. .pin = 3,
  153. .func = 2,
  154. .route_offset = 0x308,
  155. .route_val = BIT(16 + 3),
  156. }, {
  157. /* i2s-8ch-1-sclkrxm0 */
  158. .bank_num = 1,
  159. .pin = 4,
  160. .func = 2,
  161. .route_offset = 0x308,
  162. .route_val = BIT(16 + 3),
  163. }, {
  164. /* i2s-8ch-1-sclktxm1 */
  165. .bank_num = 1,
  166. .pin = 13,
  167. .func = 2,
  168. .route_offset = 0x308,
  169. .route_val = BIT(16 + 3) | BIT(3),
  170. }, {
  171. /* i2s-8ch-1-sclkrxm1 */
  172. .bank_num = 1,
  173. .pin = 14,
  174. .func = 2,
  175. .route_offset = 0x308,
  176. .route_val = BIT(16 + 3) | BIT(3),
  177. }, {
  178. /* pdm-clkm0 */
  179. .bank_num = 1,
  180. .pin = 4,
  181. .func = 3,
  182. .route_offset = 0x308,
  183. .route_val = BIT(16 + 12) | BIT(16 + 13),
  184. }, {
  185. /* pdm-clkm1 */
  186. .bank_num = 1,
  187. .pin = 14,
  188. .func = 4,
  189. .route_offset = 0x308,
  190. .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(12),
  191. }, {
  192. /* pdm-clkm2 */
  193. .bank_num = 2,
  194. .pin = 6,
  195. .func = 2,
  196. .route_offset = 0x308,
  197. .route_val = BIT(16 + 12) | BIT(16 + 13) | BIT(13),
  198. }, {
  199. /* pdm-clkm-m2 */
  200. .bank_num = 2,
  201. .pin = 4,
  202. .func = 3,
  203. .route_offset = 0x600,
  204. .route_val = BIT(16 + 2) | BIT(2),
  205. }, {
  206. /* spi1_miso */
  207. .bank_num = 3,
  208. .pin = 10,
  209. .func = 3,
  210. .route_offset = 0x314,
  211. .route_val = BIT(16 + 9),
  212. }, {
  213. /* spi1_miso_m1 */
  214. .bank_num = 2,
  215. .pin = 4,
  216. .func = 2,
  217. .route_offset = 0x314,
  218. .route_val = BIT(16 + 9) | BIT(9),
  219. }, {
  220. /* mac_rxd0_m0 */
  221. .bank_num = 1,
  222. .pin = 20,
  223. .func = 3,
  224. .route_offset = 0x314,
  225. .route_val = BIT(16 + 14),
  226. }, {
  227. /* mac_rxd0_m1 */
  228. .bank_num = 4,
  229. .pin = 2,
  230. .func = 2,
  231. .route_offset = 0x314,
  232. .route_val = BIT(16 + 14) | BIT(14),
  233. }, {
  234. /* uart3_rx */
  235. .bank_num = 3,
  236. .pin = 12,
  237. .func = 4,
  238. .route_offset = 0x314,
  239. .route_val = BIT(16 + 15),
  240. }, {
  241. /* uart3_rx_m1 */
  242. .bank_num = 0,
  243. .pin = 17,
  244. .func = 3,
  245. .route_offset = 0x314,
  246. .route_val = BIT(16 + 15) | BIT(15),
  247. },
  248. };
  249. static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
  250. {
  251. struct rockchip_pinctrl_priv *priv = bank->priv;
  252. int iomux_num = (pin / 8);
  253. struct regmap *regmap;
  254. int reg, ret, mask, mux_type;
  255. u8 bit;
  256. u32 data, route_reg, route_val;
  257. regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
  258. ? priv->regmap_pmu : priv->regmap_base;
  259. /* get basic quadrupel of mux registers and the correct reg inside */
  260. mux_type = bank->iomux[iomux_num].type;
  261. reg = bank->iomux[iomux_num].offset;
  262. reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
  263. if (bank->recalced_mask & BIT(pin))
  264. rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
  265. if (bank->route_mask & BIT(pin)) {
  266. if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
  267. &route_val)) {
  268. ret = regmap_write(regmap, route_reg, route_val);
  269. if (ret)
  270. return ret;
  271. }
  272. }
  273. data = (mask << (bit + 16));
  274. data |= (mux & mask) << bit;
  275. ret = regmap_write(regmap, reg, data);
  276. return ret;
  277. }
  278. #define RK3308_PULL_OFFSET 0xa0
  279. static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
  280. int pin_num, struct regmap **regmap,
  281. int *reg, u8 *bit)
  282. {
  283. struct rockchip_pinctrl_priv *priv = bank->priv;
  284. *regmap = priv->regmap_base;
  285. *reg = RK3308_PULL_OFFSET;
  286. *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
  287. *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
  288. *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
  289. *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
  290. }
  291. static int rk3308_set_pull(struct rockchip_pin_bank *bank,
  292. int pin_num, int pull)
  293. {
  294. struct regmap *regmap;
  295. int reg, ret;
  296. u8 bit, type;
  297. u32 data;
  298. if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
  299. return -ENOTSUPP;
  300. rk3308_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  301. type = bank->pull_type[pin_num / 8];
  302. ret = rockchip_translate_pull_value(type, pull);
  303. if (ret < 0) {
  304. debug("unsupported pull setting %d\n", pull);
  305. return ret;
  306. }
  307. /* enable the write to the equivalent lower bits */
  308. data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
  309. data |= (ret << bit);
  310. ret = regmap_write(regmap, reg, data);
  311. return ret;
  312. }
  313. #define RK3308_DRV_GRF_OFFSET 0x100
  314. static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
  315. int pin_num, struct regmap **regmap,
  316. int *reg, u8 *bit)
  317. {
  318. struct rockchip_pinctrl_priv *priv = bank->priv;
  319. *regmap = priv->regmap_base;
  320. *reg = RK3308_DRV_GRF_OFFSET;
  321. *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
  322. *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
  323. *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
  324. *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
  325. }
  326. static int rk3308_set_drive(struct rockchip_pin_bank *bank,
  327. int pin_num, int strength)
  328. {
  329. struct regmap *regmap;
  330. int reg, ret;
  331. u32 data;
  332. u8 bit;
  333. int type = bank->drv[pin_num / 8].drv_type;
  334. rk3308_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  335. ret = rockchip_translate_drive_value(type, strength);
  336. if (ret < 0) {
  337. debug("unsupported driver strength %d\n", strength);
  338. return ret;
  339. }
  340. /* enable the write to the equivalent lower bits */
  341. data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
  342. data |= (ret << bit);
  343. ret = regmap_write(regmap, reg, data);
  344. return ret;
  345. }
  346. #define RK3308_SCHMITT_PINS_PER_REG 8
  347. #define RK3308_SCHMITT_BANK_STRIDE 16
  348. #define RK3308_SCHMITT_GRF_OFFSET 0x1a0
  349. static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
  350. int pin_num,
  351. struct regmap **regmap,
  352. int *reg, u8 *bit)
  353. {
  354. struct rockchip_pinctrl_priv *priv = bank->priv;
  355. *regmap = priv->regmap_base;
  356. *reg = RK3308_SCHMITT_GRF_OFFSET;
  357. *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE;
  358. *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4);
  359. *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG;
  360. return 0;
  361. }
  362. static int rk3308_set_schmitt(struct rockchip_pin_bank *bank,
  363. int pin_num, int enable)
  364. {
  365. struct regmap *regmap;
  366. int reg;
  367. u8 bit;
  368. u32 data;
  369. rk3308_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  370. /* enable the write to the equivalent lower bits */
  371. data = BIT(bit + 16) | (enable << bit);
  372. return regmap_write(regmap, reg, data);
  373. }
  374. static struct rockchip_pin_bank rk3308_pin_banks[] = {
  375. PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_8WIDTH_2BIT,
  376. IOMUX_8WIDTH_2BIT,
  377. IOMUX_8WIDTH_2BIT,
  378. IOMUX_8WIDTH_2BIT),
  379. PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_8WIDTH_2BIT,
  380. IOMUX_8WIDTH_2BIT,
  381. IOMUX_8WIDTH_2BIT,
  382. IOMUX_8WIDTH_2BIT),
  383. PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_8WIDTH_2BIT,
  384. IOMUX_8WIDTH_2BIT,
  385. IOMUX_8WIDTH_2BIT,
  386. IOMUX_8WIDTH_2BIT),
  387. PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_8WIDTH_2BIT,
  388. IOMUX_8WIDTH_2BIT,
  389. IOMUX_8WIDTH_2BIT,
  390. IOMUX_8WIDTH_2BIT),
  391. PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_8WIDTH_2BIT,
  392. IOMUX_8WIDTH_2BIT,
  393. IOMUX_8WIDTH_2BIT,
  394. IOMUX_8WIDTH_2BIT),
  395. };
  396. static struct rockchip_pin_ctrl rk3308_pin_ctrl = {
  397. .pin_banks = rk3308_pin_banks,
  398. .nr_banks = ARRAY_SIZE(rk3308_pin_banks),
  399. .grf_mux_offset = 0x0,
  400. .iomux_recalced = rk3308_mux_recalced_data,
  401. .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data),
  402. .iomux_routes = rk3308_mux_route_data,
  403. .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data),
  404. .set_mux = rk3308_set_mux,
  405. .set_drive = rk3308_set_drive,
  406. .set_pull = rk3308_set_pull,
  407. .set_schmitt = rk3308_set_schmitt,
  408. };
  409. static const struct udevice_id rk3308_pinctrl_ids[] = {
  410. {
  411. .compatible = "rockchip,rk3308-pinctrl",
  412. .data = (ulong)&rk3308_pin_ctrl
  413. },
  414. { }
  415. };
  416. U_BOOT_DRIVER(pinctrl_rk3308) = {
  417. .name = "rockchip_rk3308_pinctrl",
  418. .id = UCLASS_PINCTRL,
  419. .of_match = rk3308_pinctrl_ids,
  420. .priv_auto = sizeof(struct rockchip_pinctrl_priv),
  421. .ops = &rockchip_pinctrl_ops,
  422. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  423. .bind = dm_scan_fdt_dev,
  424. #endif
  425. .probe = rockchip_pinctrl_probe,
  426. };