intel_ich6_gpio.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * Copyright (c) 2012 The Chromium OS Authors.
  3. * SPDX-License-Identifier: GPL-2.0+
  4. */
  5. /*
  6. * This is a GPIO driver for Intel ICH6 and later. The x86 GPIOs are accessed
  7. * through the PCI bus. Each PCI device has 256 bytes of configuration space,
  8. * consisting of a standard header and a device-specific set of registers. PCI
  9. * bus 0, device 31, function 0 gives us access to the chipset GPIOs (among
  10. * other things). Within the PCI configuration space, the GPIOBASE register
  11. * tells us where in the device's I/O region we can find more registers to
  12. * actually access the GPIOs.
  13. *
  14. * PCI bus/device/function 0:1f:0 => PCI config registers
  15. * PCI config register "GPIOBASE"
  16. * PCI I/O space + [GPIOBASE] => start of GPIO registers
  17. * GPIO registers => gpio pin function, direction, value
  18. *
  19. *
  20. * Danger Will Robinson! Bank 0 (GPIOs 0-31) seems to be fairly stable. Most
  21. * ICH versions have more, but the decoding the matrix that describes them is
  22. * absurdly complex and constantly changing. We'll provide Bank 1 and Bank 2,
  23. * but they will ONLY work for certain unspecified chipsets because the offset
  24. * from GPIOBASE changes randomly. Even then, many GPIOs are unimplemented or
  25. * reserved or subject to arcane restrictions.
  26. */
  27. #include <common.h>
  28. #include <dm.h>
  29. #include <errno.h>
  30. #include <fdtdec.h>
  31. #include <pch.h>
  32. #include <pci.h>
  33. #include <asm/gpio.h>
  34. #include <asm/io.h>
  35. #include <asm/pci.h>
  36. DECLARE_GLOBAL_DATA_PTR;
  37. #define GPIO_PER_BANK 32
  38. struct ich6_bank_priv {
  39. /* These are I/O addresses */
  40. uint16_t use_sel;
  41. uint16_t io_sel;
  42. uint16_t lvl;
  43. };
  44. #define GPIO_USESEL_OFFSET(x) (x)
  45. #define GPIO_IOSEL_OFFSET(x) (x + 4)
  46. #define GPIO_LVL_OFFSET(x) (x + 8)
  47. #define IOPAD_MODE_MASK 0x7
  48. #define IOPAD_PULL_ASSIGN_SHIFT 7
  49. #define IOPAD_PULL_ASSIGN_MASK (0x3 << IOPAD_PULL_ASSIGN_SHIFT)
  50. #define IOPAD_PULL_STRENGTH_SHIFT 9
  51. #define IOPAD_PULL_STRENGTH_MASK (0x3 << IOPAD_PULL_STRENGTH_SHIFT)
  52. /* TODO: Move this to device tree, or platform data */
  53. void ich_gpio_set_gpio_map(const struct pch_gpio_map *map)
  54. {
  55. gd->arch.gpio_map = map;
  56. }
  57. static int _ich6_gpio_set_value(uint16_t base, unsigned offset, int value)
  58. {
  59. u32 val;
  60. val = inl(base);
  61. if (value)
  62. val |= (1UL << offset);
  63. else
  64. val &= ~(1UL << offset);
  65. outl(val, base);
  66. return 0;
  67. }
  68. static int _ich6_gpio_set_function(uint16_t base, unsigned offset, int func)
  69. {
  70. u32 val;
  71. if (func) {
  72. val = inl(base);
  73. val |= (1UL << offset);
  74. outl(val, base);
  75. } else {
  76. val = inl(base);
  77. val &= ~(1UL << offset);
  78. outl(val, base);
  79. }
  80. return 0;
  81. }
  82. static int _ich6_gpio_set_direction(uint16_t base, unsigned offset, int dir)
  83. {
  84. u32 val;
  85. if (!dir) {
  86. val = inl(base);
  87. val |= (1UL << offset);
  88. outl(val, base);
  89. } else {
  90. val = inl(base);
  91. val &= ~(1UL << offset);
  92. outl(val, base);
  93. }
  94. return 0;
  95. }
  96. static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
  97. {
  98. u32 gpio_offset[2];
  99. int pad_offset;
  100. int val;
  101. int ret;
  102. const void *prop;
  103. /*
  104. * GPIO node is not mandatory, so we only do the
  105. * pinmuxing if the node exist.
  106. */
  107. ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
  108. gpio_offset, 2);
  109. if (!ret) {
  110. /* Do we want to force the GPIO mode? */
  111. prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio",
  112. NULL);
  113. if (prop)
  114. _ich6_gpio_set_function(GPIO_USESEL_OFFSET
  115. (gpiobase) +
  116. gpio_offset[0],
  117. gpio_offset[1], 1);
  118. val =
  119. fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
  120. if (val != -1)
  121. _ich6_gpio_set_direction(GPIO_IOSEL_OFFSET
  122. (gpiobase) +
  123. gpio_offset[0],
  124. gpio_offset[1], val);
  125. val =
  126. fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1);
  127. if (val != -1)
  128. _ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase)
  129. + gpio_offset[0],
  130. gpio_offset[1], val);
  131. }
  132. /* if iobase is present, let's configure the pad */
  133. if (iobase != -1) {
  134. int iobase_addr;
  135. /*
  136. * The offset for the same pin for the IOBASE and GPIOBASE are
  137. * different, so instead of maintaining a lookup table,
  138. * the device tree should provide directly the correct
  139. * value for both mapping.
  140. */
  141. pad_offset =
  142. fdtdec_get_int(gd->fdt_blob, pin_node, "pad-offset", -1);
  143. if (pad_offset == -1) {
  144. debug("%s: Invalid register io offset %d\n",
  145. __func__, pad_offset);
  146. return -EINVAL;
  147. }
  148. /* compute the absolute pad address */
  149. iobase_addr = iobase + pad_offset;
  150. /*
  151. * Do we need to set a specific function mode?
  152. * If someone put also 'mode-gpio', this option will
  153. * be just ignored by the controller
  154. */
  155. val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1);
  156. if (val != -1)
  157. clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val);
  158. /* Configure the pull-up/down if needed */
  159. val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1);
  160. if (val != -1)
  161. clrsetbits_le32(iobase_addr,
  162. IOPAD_PULL_ASSIGN_MASK,
  163. val << IOPAD_PULL_ASSIGN_SHIFT);
  164. val =
  165. fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength", -1);
  166. if (val != -1)
  167. clrsetbits_le32(iobase_addr,
  168. IOPAD_PULL_STRENGTH_MASK,
  169. val << IOPAD_PULL_STRENGTH_SHIFT);
  170. debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset,
  171. readl(iobase_addr));
  172. }
  173. return 0;
  174. }
  175. int gpio_ich6_pinctrl_init(void)
  176. {
  177. struct udevice *pch;
  178. int pin_node;
  179. int node;
  180. int ret;
  181. u32 gpiobase;
  182. u32 iobase = -1;
  183. ret = uclass_first_device(UCLASS_PCH, &pch);
  184. if (ret)
  185. return ret;
  186. if (!pch)
  187. return -ENODEV;
  188. /*
  189. * Get the memory/io base address to configure every pins.
  190. * IOBASE is used to configure the mode/pads
  191. * GPIOBASE is used to configure the direction and default value
  192. */
  193. ret = pch_get_gpio_base(pch, &gpiobase);
  194. if (ret) {
  195. debug("%s: invalid GPIOBASE address (%08x)\n", __func__,
  196. gpiobase);
  197. return -EINVAL;
  198. }
  199. /* This is not an error to not have a pinctrl node */
  200. node =
  201. fdtdec_next_compatible(gd->fdt_blob, 0, COMPAT_INTEL_X86_PINCTRL);
  202. if (node <= 0) {
  203. debug("%s: no pinctrl node\n", __func__);
  204. return 0;
  205. }
  206. /*
  207. * Get the IOBASE, this is not mandatory as this is not
  208. * supported by all the CPU
  209. */
  210. ret = pch_get_io_base(pch, &iobase);
  211. if (ret && ret != -ENOSYS) {
  212. debug("%s: invalid IOBASE address (%08x)\n", __func__,
  213. iobase);
  214. return -EINVAL;
  215. }
  216. for (pin_node = fdt_first_subnode(gd->fdt_blob, node);
  217. pin_node > 0;
  218. pin_node = fdt_next_subnode(gd->fdt_blob, pin_node)) {
  219. /* Configure the pin */
  220. ret = _gpio_ich6_pinctrl_cfg_pin(gpiobase, iobase, pin_node);
  221. if (ret != 0) {
  222. debug("%s: invalid configuration for the pin %d\n",
  223. __func__, pin_node);
  224. return ret;
  225. }
  226. }
  227. return 0;
  228. }
  229. static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
  230. {
  231. struct ich6_bank_platdata *plat = dev_get_platdata(dev);
  232. u32 gpiobase;
  233. int offset;
  234. int ret;
  235. ret = pch_get_gpio_base(dev->parent, &gpiobase);
  236. if (ret)
  237. return ret;
  238. offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
  239. if (offset == -1) {
  240. debug("%s: Invalid register offset %d\n", __func__, offset);
  241. return -EINVAL;
  242. }
  243. plat->offset = offset;
  244. plat->base_addr = gpiobase + offset;
  245. plat->bank_name = fdt_getprop(gd->fdt_blob, dev->of_offset,
  246. "bank-name", NULL);
  247. return 0;
  248. }
  249. static int ich6_gpio_probe(struct udevice *dev)
  250. {
  251. struct ich6_bank_platdata *plat = dev_get_platdata(dev);
  252. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  253. struct ich6_bank_priv *bank = dev_get_priv(dev);
  254. if (gd->arch.gpio_map) {
  255. setup_pch_gpios(plat->base_addr - plat->offset,
  256. gd->arch.gpio_map);
  257. gd->arch.gpio_map = NULL;
  258. }
  259. uc_priv->gpio_count = GPIO_PER_BANK;
  260. uc_priv->bank_name = plat->bank_name;
  261. bank->use_sel = plat->base_addr;
  262. bank->io_sel = plat->base_addr + 4;
  263. bank->lvl = plat->base_addr + 8;
  264. return 0;
  265. }
  266. static int ich6_gpio_request(struct udevice *dev, unsigned offset,
  267. const char *label)
  268. {
  269. struct ich6_bank_priv *bank = dev_get_priv(dev);
  270. u32 tmplong;
  271. /*
  272. * Make sure that the GPIO pin we want isn't already in use for some
  273. * built-in hardware function. We have to check this for every
  274. * requested pin.
  275. */
  276. tmplong = inl(bank->use_sel);
  277. if (!(tmplong & (1UL << offset))) {
  278. debug("%s: gpio %d is reserved for internal use\n", __func__,
  279. offset);
  280. return -EPERM;
  281. }
  282. return 0;
  283. }
  284. static int ich6_gpio_direction_input(struct udevice *dev, unsigned offset)
  285. {
  286. struct ich6_bank_priv *bank = dev_get_priv(dev);
  287. return _ich6_gpio_set_direction(bank->io_sel, offset, 0);
  288. }
  289. static int ich6_gpio_direction_output(struct udevice *dev, unsigned offset,
  290. int value)
  291. {
  292. int ret;
  293. struct ich6_bank_priv *bank = dev_get_priv(dev);
  294. ret = _ich6_gpio_set_direction(bank->io_sel, offset, 1);
  295. if (ret)
  296. return ret;
  297. return _ich6_gpio_set_value(bank->lvl, offset, value);
  298. }
  299. static int ich6_gpio_get_value(struct udevice *dev, unsigned offset)
  300. {
  301. struct ich6_bank_priv *bank = dev_get_priv(dev);
  302. u32 tmplong;
  303. int r;
  304. tmplong = inl(bank->lvl);
  305. r = (tmplong & (1UL << offset)) ? 1 : 0;
  306. return r;
  307. }
  308. static int ich6_gpio_set_value(struct udevice *dev, unsigned offset,
  309. int value)
  310. {
  311. struct ich6_bank_priv *bank = dev_get_priv(dev);
  312. return _ich6_gpio_set_value(bank->lvl, offset, value);
  313. }
  314. static int ich6_gpio_get_function(struct udevice *dev, unsigned offset)
  315. {
  316. struct ich6_bank_priv *bank = dev_get_priv(dev);
  317. u32 mask = 1UL << offset;
  318. if (!(inl(bank->use_sel) & mask))
  319. return GPIOF_FUNC;
  320. if (inl(bank->io_sel) & mask)
  321. return GPIOF_INPUT;
  322. else
  323. return GPIOF_OUTPUT;
  324. }
  325. static const struct dm_gpio_ops gpio_ich6_ops = {
  326. .request = ich6_gpio_request,
  327. .direction_input = ich6_gpio_direction_input,
  328. .direction_output = ich6_gpio_direction_output,
  329. .get_value = ich6_gpio_get_value,
  330. .set_value = ich6_gpio_set_value,
  331. .get_function = ich6_gpio_get_function,
  332. };
  333. static const struct udevice_id intel_ich6_gpio_ids[] = {
  334. { .compatible = "intel,ich6-gpio" },
  335. { }
  336. };
  337. U_BOOT_DRIVER(gpio_ich6) = {
  338. .name = "gpio_ich6",
  339. .id = UCLASS_GPIO,
  340. .of_match = intel_ich6_gpio_ids,
  341. .ops = &gpio_ich6_ops,
  342. .ofdata_to_platdata = gpio_ich6_ofdata_to_platdata,
  343. .probe = ich6_gpio_probe,
  344. .priv_auto_alloc_size = sizeof(struct ich6_bank_priv),
  345. .platdata_auto_alloc_size = sizeof(struct ich6_bank_platdata),
  346. };