pinctrl-s5pxx18.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Pinctrl driver for Nexell SoCs
  4. * (C) Copyright 2016 Nexell
  5. * Bongyu, KOO <freestyle@nexell.co.kr>
  6. *
  7. * (C) Copyright 2019 Stefan Bosch <stefan_b@posteo.net>
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <asm/global_data.h>
  13. #include <asm/io.h>
  14. #include <dm/pinctrl.h>
  15. #include <dm/root.h>
  16. #include "pinctrl-nexell.h"
  17. #include "pinctrl-s5pxx18.h"
  18. DECLARE_GLOBAL_DATA_PTR;
  19. static void nx_gpio_set_bit(u32 *value, u32 bit, int enable)
  20. {
  21. register u32 newvalue;
  22. newvalue = *value;
  23. newvalue &= ~(1ul << bit);
  24. newvalue |= (u32)enable << bit;
  25. writel(newvalue, value);
  26. }
  27. static void nx_gpio_set_bit2(u32 *value, u32 bit, u32 bit_value)
  28. {
  29. register u32 newvalue = *value;
  30. newvalue = (u32)(newvalue & ~(3ul << (bit * 2)));
  31. newvalue = (u32)(newvalue | (bit_value << (bit * 2)));
  32. writel(newvalue, value);
  33. }
  34. static int nx_gpio_open_module(void *base)
  35. {
  36. writel(0xFFFFFFFF, base + GPIOX_SLEW_DISABLE_DEFAULT);
  37. writel(0xFFFFFFFF, base + GPIOX_DRV1_DISABLE_DEFAULT);
  38. writel(0xFFFFFFFF, base + GPIOX_DRV0_DISABLE_DEFAULT);
  39. writel(0xFFFFFFFF, base + GPIOX_PULLSEL_DISABLE_DEFAULT);
  40. writel(0xFFFFFFFF, base + GPIOX_PULLENB_DISABLE_DEFAULT);
  41. return true;
  42. }
  43. static void nx_gpio_set_pad_function(void *base, u32 pin, u32 padfunc)
  44. {
  45. u32 reg = (pin / 16) ? GPIOX_ALTFN1 : GPIOX_ALTFN0;
  46. nx_gpio_set_bit2(base + reg, pin % 16, padfunc);
  47. }
  48. static void nx_gpio_set_drive_strength(void *base, u32 pin, u32 drv)
  49. {
  50. nx_gpio_set_bit(base + GPIOX_DRV1, pin, (int)(((u32)drv >> 0) & 0x1));
  51. nx_gpio_set_bit(base + GPIOX_DRV0, pin, (int)(((u32)drv >> 1) & 0x1));
  52. }
  53. static void nx_gpio_set_pull_mode(void *base, u32 pin, u32 mode)
  54. {
  55. if (mode == nx_gpio_pull_off) {
  56. nx_gpio_set_bit(base + GPIOX_PULLENB, pin, false);
  57. nx_gpio_set_bit(base + GPIOX_PULLSEL, pin, false);
  58. } else {
  59. nx_gpio_set_bit(base + GPIOX_PULLSEL,
  60. pin, (mode & 1 ? true : false));
  61. nx_gpio_set_bit(base + GPIOX_PULLENB, pin, true);
  62. }
  63. }
  64. static void nx_alive_set_pullup(void *base, u32 pin, bool enable)
  65. {
  66. u32 PULLUP_MASK;
  67. PULLUP_MASK = (1UL << pin);
  68. if (enable)
  69. writel(PULLUP_MASK, base + ALIVE_PADPULLUPSET);
  70. else
  71. writel(PULLUP_MASK, base + ALIVE_PADPULLUPRST);
  72. }
  73. static int s5pxx18_pinctrl_gpio_init(struct udevice *dev)
  74. {
  75. struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
  76. const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
  77. unsigned long reg = priv->base;
  78. int i;
  79. for (i = 0; i < ctrl->nr_banks - 1; i++) /* except alive bank */
  80. nx_gpio_open_module((void *)(reg + ctrl->pin_banks[i].offset));
  81. return 0;
  82. }
  83. static int s5pxx18_pinctrl_alive_init(struct udevice *dev)
  84. {
  85. struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
  86. const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
  87. unsigned long reg = priv->base;
  88. reg += ctrl->pin_banks[ctrl->nr_banks - 1].offset;
  89. writel(1, reg + ALIVE_PWRGATE);
  90. return 0;
  91. }
  92. int s5pxx18_pinctrl_init(struct udevice *dev)
  93. {
  94. s5pxx18_pinctrl_gpio_init(dev);
  95. s5pxx18_pinctrl_alive_init(dev);
  96. return 0;
  97. }
  98. static int is_pin_alive(const char *name)
  99. {
  100. return !strncmp(name, "alive", 5);
  101. }
  102. /**
  103. * s5pxx18_pinctrl_set_state: configure a pin state.
  104. * dev: the pinctrl device to be configured.
  105. * config: the state to be configured.
  106. */
  107. static int s5pxx18_pinctrl_set_state(struct udevice *dev,
  108. struct udevice *config)
  109. {
  110. unsigned int count, idx, pin;
  111. unsigned int pinfunc, pinpud, pindrv;
  112. unsigned long reg;
  113. const char *name;
  114. int ret;
  115. /*
  116. * refer to the following document for the pinctrl bindings
  117. * doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
  118. */
  119. count = dev_read_string_count(config, "pins");
  120. if (count <= 0)
  121. return -EINVAL;
  122. pinfunc = dev_read_s32_default(config, "pin-function", -1);
  123. pinpud = dev_read_s32_default(config, "pin-pull", -1);
  124. pindrv = dev_read_s32_default(config, "pin-strength", -1);
  125. for (idx = 0; idx < count; idx++) {
  126. ret = dev_read_string_index(config, "pins", idx, &name);
  127. if (ret)
  128. return ret;
  129. if (!name)
  130. continue;
  131. reg = pin_to_bank_base(dev, name, &pin);
  132. if (is_pin_alive(name)) {
  133. /* pin pull up/down */
  134. if (pinpud != -1)
  135. nx_alive_set_pullup((void *)reg, pin,
  136. pinpud & 1);
  137. continue;
  138. }
  139. /* pin function */
  140. if (pinfunc != -1)
  141. nx_gpio_set_pad_function((void *)reg, pin, pinfunc);
  142. /* pin pull up/down/off */
  143. if (pinpud != -1)
  144. nx_gpio_set_pull_mode((void *)reg, pin, pinpud);
  145. /* pin drive strength */
  146. if (pindrv != -1)
  147. nx_gpio_set_drive_strength((void *)reg, pin, pindrv);
  148. }
  149. return 0;
  150. }
  151. static struct pinctrl_ops s5pxx18_pinctrl_ops = {
  152. .set_state = s5pxx18_pinctrl_set_state,
  153. };
  154. /* pin banks of s5pxx18 pin-controller */
  155. static const struct nexell_pin_bank_data s5pxx18_pin_banks[] = {
  156. NEXELL_PIN_BANK(32, 0xA000, "gpioa"),
  157. NEXELL_PIN_BANK(32, 0xB000, "gpiob"),
  158. NEXELL_PIN_BANK(32, 0xC000, "gpioc"),
  159. NEXELL_PIN_BANK(32, 0xD000, "gpiod"),
  160. NEXELL_PIN_BANK(32, 0xE000, "gpioe"),
  161. NEXELL_PIN_BANK(6, 0x0800, "alive"),
  162. };
  163. const struct nexell_pin_ctrl s5pxx18_pin_ctrl[] = {
  164. {
  165. /* pin-controller data */
  166. .pin_banks = s5pxx18_pin_banks,
  167. .nr_banks = ARRAY_SIZE(s5pxx18_pin_banks),
  168. },
  169. };
  170. static const struct udevice_id s5pxx18_pinctrl_ids[] = {
  171. { .compatible = "nexell,s5pxx18-pinctrl",
  172. .data = (ulong)s5pxx18_pin_ctrl },
  173. { }
  174. };
  175. U_BOOT_DRIVER(pinctrl_s5pxx18) = {
  176. .name = "pinctrl_s5pxx18",
  177. .id = UCLASS_PINCTRL,
  178. .of_match = s5pxx18_pinctrl_ids,
  179. .priv_auto = sizeof(struct nexell_pinctrl_priv),
  180. .ops = &s5pxx18_pinctrl_ops,
  181. .probe = nexell_pinctrl_probe,
  182. .flags = DM_FLAG_PRE_RELOC
  183. };