pinctrl-rk3328.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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 rk3328_mux_recalced_data[] = {
  14. {
  15. .num = 2,
  16. .pin = 12,
  17. .reg = 0x24,
  18. .bit = 8,
  19. .mask = 0x3
  20. }, {
  21. .num = 2,
  22. .pin = 15,
  23. .reg = 0x28,
  24. .bit = 0,
  25. .mask = 0x7
  26. }, {
  27. .num = 2,
  28. .pin = 23,
  29. .reg = 0x30,
  30. .bit = 14,
  31. .mask = 0x3
  32. },
  33. };
  34. static struct rockchip_mux_route_data rk3328_mux_route_data[] = {
  35. {
  36. /* uart2dbg_rxm0 */
  37. .bank_num = 1,
  38. .pin = 1,
  39. .func = 2,
  40. .route_offset = 0x50,
  41. .route_val = BIT(16) | BIT(16 + 1),
  42. }, {
  43. /* uart2dbg_rxm1 */
  44. .bank_num = 2,
  45. .pin = 1,
  46. .func = 1,
  47. .route_offset = 0x50,
  48. .route_val = BIT(16) | BIT(16 + 1) | BIT(0),
  49. }, {
  50. /* gmac-m1_rxd0 */
  51. .bank_num = 1,
  52. .pin = 11,
  53. .func = 2,
  54. .route_offset = 0x50,
  55. .route_val = BIT(16 + 2) | BIT(2),
  56. }, {
  57. /* gmac-m1-optimized_rxd3 */
  58. .bank_num = 1,
  59. .pin = 14,
  60. .func = 2,
  61. .route_offset = 0x50,
  62. .route_val = BIT(16 + 10) | BIT(10),
  63. }, {
  64. /* pdm_sdi0m0 */
  65. .bank_num = 2,
  66. .pin = 19,
  67. .func = 2,
  68. .route_offset = 0x50,
  69. .route_val = BIT(16 + 3),
  70. }, {
  71. /* pdm_sdi0m1 */
  72. .bank_num = 1,
  73. .pin = 23,
  74. .func = 3,
  75. .route_offset = 0x50,
  76. .route_val = BIT(16 + 3) | BIT(3),
  77. }, {
  78. /* spi_rxdm2 */
  79. .bank_num = 3,
  80. .pin = 2,
  81. .func = 4,
  82. .route_offset = 0x50,
  83. .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
  84. }, {
  85. /* i2s2_sdim0 */
  86. .bank_num = 1,
  87. .pin = 24,
  88. .func = 1,
  89. .route_offset = 0x50,
  90. .route_val = BIT(16 + 6),
  91. }, {
  92. /* i2s2_sdim1 */
  93. .bank_num = 3,
  94. .pin = 2,
  95. .func = 6,
  96. .route_offset = 0x50,
  97. .route_val = BIT(16 + 6) | BIT(6),
  98. }, {
  99. /* card_iom1 */
  100. .bank_num = 2,
  101. .pin = 22,
  102. .func = 3,
  103. .route_offset = 0x50,
  104. .route_val = BIT(16 + 7) | BIT(7),
  105. }, {
  106. /* tsp_d5m1 */
  107. .bank_num = 2,
  108. .pin = 16,
  109. .func = 3,
  110. .route_offset = 0x50,
  111. .route_val = BIT(16 + 8) | BIT(8),
  112. }, {
  113. /* cif_data5m1 */
  114. .bank_num = 2,
  115. .pin = 16,
  116. .func = 4,
  117. .route_offset = 0x50,
  118. .route_val = BIT(16 + 9) | BIT(9),
  119. },
  120. };
  121. static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
  122. {
  123. struct rockchip_pinctrl_priv *priv = bank->priv;
  124. int iomux_num = (pin / 8);
  125. struct regmap *regmap;
  126. int reg, ret, mask, mux_type;
  127. u8 bit;
  128. u32 data, route_reg, route_val;
  129. regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
  130. ? priv->regmap_pmu : priv->regmap_base;
  131. /* get basic quadrupel of mux registers and the correct reg inside */
  132. mux_type = bank->iomux[iomux_num].type;
  133. reg = bank->iomux[iomux_num].offset;
  134. reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
  135. if (bank->recalced_mask & BIT(pin))
  136. rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
  137. if (bank->route_mask & BIT(pin)) {
  138. if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
  139. &route_val)) {
  140. ret = regmap_write(regmap, route_reg, route_val);
  141. if (ret)
  142. return ret;
  143. }
  144. }
  145. data = (mask << (bit + 16));
  146. data |= (mux & mask) << bit;
  147. ret = regmap_write(regmap, reg, data);
  148. return ret;
  149. }
  150. #define RK3328_PULL_OFFSET 0x100
  151. static void rk3328_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
  152. int pin_num, struct regmap **regmap,
  153. int *reg, u8 *bit)
  154. {
  155. struct rockchip_pinctrl_priv *priv = bank->priv;
  156. *regmap = priv->regmap_base;
  157. *reg = RK3328_PULL_OFFSET;
  158. *reg += bank->bank_num * ROCKCHIP_PULL_BANK_STRIDE;
  159. *reg += ((pin_num / ROCKCHIP_PULL_PINS_PER_REG) * 4);
  160. *bit = (pin_num % ROCKCHIP_PULL_PINS_PER_REG);
  161. *bit *= ROCKCHIP_PULL_BITS_PER_PIN;
  162. }
  163. static int rk3328_set_pull(struct rockchip_pin_bank *bank,
  164. int pin_num, int pull)
  165. {
  166. struct regmap *regmap;
  167. int reg, ret;
  168. u8 bit, type;
  169. u32 data;
  170. if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
  171. return -ENOTSUPP;
  172. rk3328_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  173. type = bank->pull_type[pin_num / 8];
  174. ret = rockchip_translate_pull_value(type, pull);
  175. if (ret < 0) {
  176. debug("unsupported pull setting %d\n", pull);
  177. return ret;
  178. }
  179. /* enable the write to the equivalent lower bits */
  180. data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
  181. data |= (ret << bit);
  182. ret = regmap_write(regmap, reg, data);
  183. return ret;
  184. }
  185. #define RK3328_DRV_GRF_OFFSET 0x200
  186. static void rk3328_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
  187. int pin_num, struct regmap **regmap,
  188. int *reg, u8 *bit)
  189. {
  190. struct rockchip_pinctrl_priv *priv = bank->priv;
  191. *regmap = priv->regmap_base;
  192. *reg = RK3328_DRV_GRF_OFFSET;
  193. *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE;
  194. *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4);
  195. *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG);
  196. *bit *= ROCKCHIP_DRV_BITS_PER_PIN;
  197. }
  198. static int rk3328_set_drive(struct rockchip_pin_bank *bank,
  199. int pin_num, int strength)
  200. {
  201. struct regmap *regmap;
  202. int reg, ret;
  203. u32 data;
  204. u8 bit;
  205. int type = bank->drv[pin_num / 8].drv_type;
  206. rk3328_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  207. ret = rockchip_translate_drive_value(type, strength);
  208. if (ret < 0) {
  209. debug("unsupported driver strength %d\n", strength);
  210. return ret;
  211. }
  212. /* enable the write to the equivalent lower bits */
  213. data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
  214. data |= (ret << bit);
  215. ret = regmap_write(regmap, reg, data);
  216. return ret;
  217. }
  218. #define RK3328_SCHMITT_BITS_PER_PIN 1
  219. #define RK3328_SCHMITT_PINS_PER_REG 16
  220. #define RK3328_SCHMITT_BANK_STRIDE 8
  221. #define RK3328_SCHMITT_GRF_OFFSET 0x380
  222. static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
  223. int pin_num,
  224. struct regmap **regmap,
  225. int *reg, u8 *bit)
  226. {
  227. struct rockchip_pinctrl_priv *priv = bank->priv;
  228. *regmap = priv->regmap_base;
  229. *reg = RK3328_SCHMITT_GRF_OFFSET;
  230. *reg += bank->bank_num * RK3328_SCHMITT_BANK_STRIDE;
  231. *reg += ((pin_num / RK3328_SCHMITT_PINS_PER_REG) * 4);
  232. *bit = pin_num % RK3328_SCHMITT_PINS_PER_REG;
  233. return 0;
  234. }
  235. static int rk3328_set_schmitt(struct rockchip_pin_bank *bank,
  236. int pin_num, int enable)
  237. {
  238. struct regmap *regmap;
  239. int reg;
  240. u8 bit;
  241. u32 data;
  242. rk3328_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
  243. /* enable the write to the equivalent lower bits */
  244. data = BIT(bit + 16) | (enable << bit);
  245. return regmap_write(regmap, reg, data);
  246. }
  247. static struct rockchip_pin_bank rk3328_pin_banks[] = {
  248. PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
  249. PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
  250. PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
  251. IOMUX_WIDTH_3BIT,
  252. IOMUX_WIDTH_3BIT,
  253. 0),
  254. PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
  255. IOMUX_WIDTH_3BIT,
  256. IOMUX_WIDTH_3BIT,
  257. 0,
  258. 0),
  259. };
  260. static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
  261. .pin_banks = rk3328_pin_banks,
  262. .nr_banks = ARRAY_SIZE(rk3328_pin_banks),
  263. .grf_mux_offset = 0x0,
  264. .iomux_recalced = rk3328_mux_recalced_data,
  265. .niomux_recalced = ARRAY_SIZE(rk3328_mux_recalced_data),
  266. .iomux_routes = rk3328_mux_route_data,
  267. .niomux_routes = ARRAY_SIZE(rk3328_mux_route_data),
  268. .set_mux = rk3328_set_mux,
  269. .set_pull = rk3328_set_pull,
  270. .set_drive = rk3328_set_drive,
  271. .set_schmitt = rk3328_set_schmitt,
  272. };
  273. static const struct udevice_id rk3328_pinctrl_ids[] = {
  274. {
  275. .compatible = "rockchip,rk3328-pinctrl",
  276. .data = (ulong)&rk3328_pin_ctrl
  277. },
  278. { }
  279. };
  280. U_BOOT_DRIVER(rockchip_rk3328_pinctrl) = {
  281. .name = "rockchip_rk3328_pinctrl",
  282. .id = UCLASS_PINCTRL,
  283. .of_match = rk3328_pinctrl_ids,
  284. .priv_auto = sizeof(struct rockchip_pinctrl_priv),
  285. .ops = &rockchip_pinctrl_ops,
  286. #if !CONFIG_IS_ENABLED(OF_PLATDATA)
  287. .bind = dm_scan_fdt_dev,
  288. #endif
  289. .probe = rockchip_pinctrl_probe,
  290. };