pinctrl-s5pxx18.c 5.4 KB

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