pinctrl-uniphier-core.c 11 KB

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