pinctrl-uniphier-core.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015-2016 Socionext Inc.
  4. * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <linux/io.h>
  9. #include <linux/err.h>
  10. #include <linux/kernel.h>
  11. #include <linux/sizes.h>
  12. #include <dm/pinctrl.h>
  13. #include "pinctrl-uniphier.h"
  14. #define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
  15. #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
  16. #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x1800
  17. #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900
  18. #define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980
  19. #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
  20. #define UNIPHIER_PINCTRL_IECTRL 0x1d00
  21. static const char *uniphier_pinctrl_dummy_name = "_dummy";
  22. static int uniphier_pinctrl_get_pins_count(struct udevice *dev)
  23. {
  24. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  25. const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
  26. int pins_count = priv->socdata->pins_count;
  27. /*
  28. * We do not list all pins in the pin table to save memory footprint.
  29. * Report the max pin number + 1 to fake the framework.
  30. */
  31. return pins[pins_count - 1].number + 1;
  32. }
  33. static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev,
  34. unsigned int selector)
  35. {
  36. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  37. const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
  38. int pins_count = priv->socdata->pins_count;
  39. int i;
  40. for (i = 0; i < pins_count; i++)
  41. if (pins[i].number == selector)
  42. return pins[i].name;
  43. return uniphier_pinctrl_dummy_name;
  44. }
  45. static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
  46. {
  47. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  48. return priv->socdata->groups_count;
  49. }
  50. static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
  51. unsigned selector)
  52. {
  53. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  54. if (!priv->socdata->groups[selector].name)
  55. return uniphier_pinctrl_dummy_name;
  56. return priv->socdata->groups[selector].name;
  57. }
  58. static int uniphier_pinmux_get_functions_count(struct udevice *dev)
  59. {
  60. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  61. return priv->socdata->functions_count;
  62. }
  63. static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
  64. unsigned selector)
  65. {
  66. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  67. if (!priv->socdata->functions[selector])
  68. return uniphier_pinctrl_dummy_name;
  69. return priv->socdata->functions[selector];
  70. }
  71. static int uniphier_pinconf_input_enable_perpin(struct udevice *dev,
  72. unsigned int pin, int enable)
  73. {
  74. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  75. unsigned reg;
  76. u32 mask, tmp;
  77. reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4;
  78. mask = BIT(pin % 32);
  79. tmp = readl(priv->base + reg);
  80. if (enable)
  81. tmp |= mask;
  82. else
  83. tmp &= ~mask;
  84. writel(tmp, priv->base + reg);
  85. return 0;
  86. }
  87. static int uniphier_pinconf_input_enable_legacy(struct udevice *dev,
  88. unsigned int pin, int enable)
  89. {
  90. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  91. /*
  92. * Multiple pins share one input enable, per-pin disabling is
  93. * impossible.
  94. */
  95. if (!enable)
  96. return -EINVAL;
  97. /* Set all bits instead of having a bunch of pin data */
  98. writel(U32_MAX, priv->base + UNIPHIER_PINCTRL_IECTRL);
  99. return 0;
  100. }
  101. static int uniphier_pinconf_input_enable(struct udevice *dev,
  102. unsigned int pin, int enable)
  103. {
  104. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  105. if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
  106. return uniphier_pinconf_input_enable_perpin(dev, pin, enable);
  107. else
  108. return uniphier_pinconf_input_enable_legacy(dev, pin, enable);
  109. }
  110. #if CONFIG_IS_ENABLED(PINCONF)
  111. static const struct pinconf_param uniphier_pinconf_params[] = {
  112. { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
  113. { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
  114. { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
  115. { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
  116. { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
  117. { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
  118. { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
  119. };
  120. static const struct uniphier_pinctrl_pin *
  121. uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin)
  122. {
  123. const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
  124. int pins_count = priv->socdata->pins_count;
  125. int i;
  126. for (i = 0; i < pins_count; i++)
  127. if (pins[i].number == pin)
  128. return &pins[i];
  129. return NULL;
  130. }
  131. static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
  132. unsigned int param, unsigned int arg)
  133. {
  134. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  135. unsigned int enable = 1;
  136. unsigned int reg;
  137. u32 mask, tmp;
  138. if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE))
  139. return -ENOTSUPP;
  140. switch (param) {
  141. case PIN_CONFIG_BIAS_DISABLE:
  142. enable = 0;
  143. break;
  144. case PIN_CONFIG_BIAS_PULL_UP:
  145. case PIN_CONFIG_BIAS_PULL_DOWN:
  146. if (arg == 0) /* total bias is not supported */
  147. return -EINVAL;
  148. break;
  149. case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
  150. if (arg == 0) /* configuration ignored */
  151. return 0;
  152. default:
  153. BUG();
  154. }
  155. reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4;
  156. mask = BIT(pin % 32);
  157. tmp = readl(priv->base + reg);
  158. if (enable)
  159. tmp |= mask;
  160. else
  161. tmp &= ~mask;
  162. writel(tmp, priv->base + reg);
  163. return 0;
  164. }
  165. static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = {
  166. 4, 8,
  167. };
  168. static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = {
  169. 8, 12, 16, 20,
  170. };
  171. static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = {
  172. 4, 5, 7, 9, 11, 12, 14, 16,
  173. };
  174. static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin,
  175. unsigned int strength)
  176. {
  177. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  178. const struct uniphier_pinctrl_pin *desc;
  179. const unsigned int *strengths;
  180. unsigned int base, stride, width, drvctrl, reg, shift;
  181. u32 val, mask, tmp;
  182. desc = uniphier_pinctrl_pin_get(priv, pin);
  183. if (WARN_ON(!desc))
  184. return -EINVAL;
  185. switch (uniphier_pin_get_drv_type(desc->data)) {
  186. case UNIPHIER_PIN_DRV_1BIT:
  187. strengths = uniphier_pinconf_drv_strengths_1bit;
  188. base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
  189. stride = 1;
  190. width = 1;
  191. break;
  192. case UNIPHIER_PIN_DRV_2BIT:
  193. strengths = uniphier_pinconf_drv_strengths_2bit;
  194. base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
  195. stride = 2;
  196. width = 2;
  197. break;
  198. case UNIPHIER_PIN_DRV_3BIT:
  199. strengths = uniphier_pinconf_drv_strengths_3bit;
  200. base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
  201. stride = 4;
  202. width = 3;
  203. break;
  204. default:
  205. /* drive strength control is not supported for this pin */
  206. return -EINVAL;
  207. }
  208. drvctrl = uniphier_pin_get_drvctrl(desc->data);
  209. drvctrl *= stride;
  210. reg = base + drvctrl / 32 * 4;
  211. shift = drvctrl % 32;
  212. mask = (1U << width) - 1;
  213. for (val = 0; val <= mask; val++) {
  214. if (strengths[val] > strength)
  215. break;
  216. }
  217. if (val == 0) {
  218. dev_err(dev, "unsupported drive strength %u mA for pin %s\n",
  219. strength, desc->name);
  220. return -EINVAL;
  221. }
  222. if (!mask)
  223. return 0;
  224. val--;
  225. tmp = readl(priv->base + reg);
  226. tmp &= ~(mask << shift);
  227. tmp |= (mask & val) << shift;
  228. writel(tmp, priv->base + reg);
  229. return 0;
  230. }
  231. static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin,
  232. unsigned int param, unsigned int arg)
  233. {
  234. int ret;
  235. switch (param) {
  236. case PIN_CONFIG_BIAS_DISABLE:
  237. case PIN_CONFIG_BIAS_PULL_UP:
  238. case PIN_CONFIG_BIAS_PULL_DOWN:
  239. case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
  240. ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
  241. break;
  242. case PIN_CONFIG_DRIVE_STRENGTH:
  243. ret = uniphier_pinconf_drive_set(dev, pin, arg);
  244. break;
  245. case PIN_CONFIG_INPUT_ENABLE:
  246. ret = uniphier_pinconf_input_enable(dev, pin, arg);
  247. break;
  248. default:
  249. dev_err(dev, "unsupported configuration parameter %u\n", param);
  250. return -EINVAL;
  251. }
  252. return ret;
  253. }
  254. static int uniphier_pinconf_group_set(struct udevice *dev,
  255. unsigned int group_selector,
  256. unsigned int param, unsigned int arg)
  257. {
  258. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  259. const struct uniphier_pinctrl_group *grp =
  260. &priv->socdata->groups[group_selector];
  261. int i, ret;
  262. for (i = 0; i < grp->num_pins; i++) {
  263. ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg);
  264. if (ret)
  265. return ret;
  266. }
  267. return 0;
  268. }
  269. #endif /* CONFIG_IS_ENABLED(PINCONF) */
  270. static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
  271. int muxval)
  272. {
  273. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  274. unsigned reg, reg_end, shift, mask;
  275. unsigned mux_bits = 8;
  276. unsigned reg_stride = 4;
  277. bool load_pinctrl = false;
  278. u32 tmp;
  279. /* some pins need input-enabling */
  280. uniphier_pinconf_input_enable(dev, pin, 1);
  281. if (muxval < 0)
  282. return; /* dedicated pin; nothing to do for pin-mux */
  283. if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_MUX_4BIT)
  284. mux_bits = 4;
  285. if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
  286. /*
  287. * Mode offset bit
  288. * Normal 4 * n shift+3:shift
  289. * Debug 4 * n shift+7:shift+4
  290. */
  291. mux_bits /= 2;
  292. reg_stride = 8;
  293. load_pinctrl = true;
  294. }
  295. reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
  296. reg_end = reg + reg_stride;
  297. shift = pin * mux_bits % 32;
  298. mask = (1U << mux_bits) - 1;
  299. /*
  300. * If reg_stride is greater than 4, the MSB of each pinsel shall be
  301. * stored in the offset+4.
  302. */
  303. for (; reg < reg_end; reg += 4) {
  304. tmp = readl(priv->base + reg);
  305. tmp &= ~(mask << shift);
  306. tmp |= (mask & muxval) << shift;
  307. writel(tmp, priv->base + reg);
  308. muxval >>= mux_bits;
  309. }
  310. if (load_pinctrl)
  311. writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX);
  312. }
  313. static int uniphier_pinmux_group_set(struct udevice *dev,
  314. unsigned group_selector,
  315. unsigned func_selector)
  316. {
  317. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  318. const struct uniphier_pinctrl_group *grp =
  319. &priv->socdata->groups[group_selector];
  320. int i;
  321. for (i = 0; i < grp->num_pins; i++)
  322. uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]);
  323. return 0;
  324. }
  325. const struct pinctrl_ops uniphier_pinctrl_ops = {
  326. .get_pins_count = uniphier_pinctrl_get_pins_count,
  327. .get_pin_name = uniphier_pinctrl_get_pin_name,
  328. .get_groups_count = uniphier_pinctrl_get_groups_count,
  329. .get_group_name = uniphier_pinctrl_get_group_name,
  330. .get_functions_count = uniphier_pinmux_get_functions_count,
  331. .get_function_name = uniphier_pinmux_get_function_name,
  332. .pinmux_group_set = uniphier_pinmux_group_set,
  333. #if CONFIG_IS_ENABLED(PINCONF)
  334. .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
  335. .pinconf_params = uniphier_pinconf_params,
  336. .pinconf_set = uniphier_pinconf_set,
  337. .pinconf_group_set = uniphier_pinconf_group_set,
  338. #endif
  339. .set_state = pinctrl_generic_set_state,
  340. };
  341. int uniphier_pinctrl_probe(struct udevice *dev,
  342. struct uniphier_pinctrl_socdata *socdata)
  343. {
  344. struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
  345. fdt_addr_t addr;
  346. addr = devfdt_get_addr(dev->parent);
  347. if (addr == FDT_ADDR_T_NONE)
  348. return -EINVAL;
  349. priv->base = devm_ioremap(dev, addr, SZ_4K);
  350. if (!priv->base)
  351. return -ENOMEM;
  352. priv->socdata = socdata;
  353. return 0;
  354. }