octeon_gpio.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Marvell International Ltd.
  4. *
  5. * (C) Copyright 2011
  6. * eInfochips Ltd. <www.einfochips.com>
  7. * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
  8. *
  9. * (C) Copyright 2010
  10. * Marvell Semiconductor <www.marvell.com>
  11. */
  12. #include <dm.h>
  13. #include <pci.h>
  14. #include <pci_ids.h>
  15. #include <asm/gpio.h>
  16. #include <asm/io.h>
  17. #include <linux/bitfield.h>
  18. #include <linux/compat.h>
  19. #include <dt-bindings/gpio/gpio.h>
  20. /* Returns the bit value to write or read based on the offset */
  21. #define GPIO_BIT(x) BIT_ULL((x) & 0x3f)
  22. #define GPIO_RX_DAT 0x00
  23. #define GPIO_TX_SET 0x08
  24. #define GPIO_TX_CLR 0x10
  25. #define GPIO_CONST 0x90 /* OcteonTX only */
  26. /* Offset to register-set for 2nd GPIOs (> 63), OcteonTX only */
  27. #define GPIO1_OFFSET 0x1400
  28. /* GPIO_CONST register bits */
  29. #define GPIO_CONST_GPIOS_MASK GENMASK_ULL(7, 0)
  30. /* GPIO_BIT_CFG register bits */
  31. #define GPIO_BIT_CFG_TX_OE BIT_ULL(0)
  32. #define GPIO_BIT_CFG_PIN_XOR BIT_ULL(1)
  33. #define GPIO_BIT_CFG_INT_EN BIT_ULL(2)
  34. #define GPIO_BIT_CFG_PIN_SEL_MASK GENMASK_ULL(26, 16)
  35. enum {
  36. PROBE_PCI = 0, /* PCI based probing */
  37. PROBE_DT, /* DT based probing */
  38. };
  39. struct octeon_gpio_data {
  40. int probe;
  41. u32 reg_offs;
  42. u32 gpio_bit_cfg_offs;
  43. };
  44. struct octeon_gpio {
  45. void __iomem *base;
  46. const struct octeon_gpio_data *data;
  47. };
  48. /* Returns the offset to the output register based on the offset and value */
  49. static u32 gpio_tx_reg(int offset, int value)
  50. {
  51. u32 ret;
  52. ret = value ? GPIO_TX_SET : GPIO_TX_CLR;
  53. if (offset > 63)
  54. ret += GPIO1_OFFSET;
  55. return ret;
  56. }
  57. /* Returns the offset to the input data register based on the offset */
  58. static u32 gpio_rx_dat_reg(int offset)
  59. {
  60. u32 ret;
  61. ret = GPIO_RX_DAT;
  62. if (offset > 63)
  63. ret += GPIO1_OFFSET;
  64. return ret;
  65. }
  66. static int octeon_gpio_dir_input(struct udevice *dev, unsigned int offset)
  67. {
  68. struct octeon_gpio *gpio = dev_get_priv(dev);
  69. debug("%s(%s, %u)\n", __func__, dev->name, offset);
  70. clrbits_64(gpio->base + gpio->data->gpio_bit_cfg_offs + 8 * offset,
  71. GPIO_BIT_CFG_TX_OE | GPIO_BIT_CFG_PIN_XOR |
  72. GPIO_BIT_CFG_INT_EN | GPIO_BIT_CFG_PIN_SEL_MASK);
  73. return 0;
  74. }
  75. static int octeon_gpio_dir_output(struct udevice *dev, unsigned int offset,
  76. int value)
  77. {
  78. struct octeon_gpio *gpio = dev_get_priv(dev);
  79. debug("%s(%s, %u, %d)\n", __func__, dev->name, offset, value);
  80. writeq(GPIO_BIT(offset), gpio->base + gpio->data->reg_offs +
  81. gpio_tx_reg(offset, value));
  82. clrsetbits_64(gpio->base + gpio->data->gpio_bit_cfg_offs + 8 * offset,
  83. GPIO_BIT_CFG_PIN_SEL_MASK | GPIO_BIT_CFG_INT_EN,
  84. GPIO_BIT_CFG_TX_OE);
  85. return 0;
  86. }
  87. static int octeon_gpio_get_value(struct udevice *dev, unsigned int offset)
  88. {
  89. struct octeon_gpio *gpio = dev_get_priv(dev);
  90. u64 reg = readq(gpio->base + gpio->data->reg_offs +
  91. gpio_rx_dat_reg(offset));
  92. debug("%s(%s, %u): value: %d\n", __func__, dev->name, offset,
  93. !!(reg & GPIO_BIT(offset)));
  94. return !!(reg & GPIO_BIT(offset));
  95. }
  96. static int octeon_gpio_set_value(struct udevice *dev,
  97. unsigned int offset, int value)
  98. {
  99. struct octeon_gpio *gpio = dev_get_priv(dev);
  100. debug("%s(%s, %u, %d)\n", __func__, dev->name, offset, value);
  101. writeq(GPIO_BIT(offset), gpio->base + gpio->data->reg_offs +
  102. gpio_tx_reg(offset, value));
  103. return 0;
  104. }
  105. static int octeon_gpio_get_function(struct udevice *dev, unsigned int offset)
  106. {
  107. struct octeon_gpio *gpio = dev_get_priv(dev);
  108. u64 val = readq(gpio->base + gpio->data->gpio_bit_cfg_offs +
  109. 8 * offset);
  110. int pin_sel;
  111. debug("%s(%s, %u): GPIO_BIT_CFG: 0x%llx\n", __func__, dev->name,
  112. offset, val);
  113. pin_sel = FIELD_GET(GPIO_BIT_CFG_PIN_SEL_MASK, val);
  114. if (pin_sel)
  115. return GPIOF_FUNC;
  116. else if (val & GPIO_BIT_CFG_TX_OE)
  117. return GPIOF_OUTPUT;
  118. else
  119. return GPIOF_INPUT;
  120. }
  121. static int octeon_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
  122. struct ofnode_phandle_args *args)
  123. {
  124. if (args->args_count < 1)
  125. return -EINVAL;
  126. desc->offset = args->args[0];
  127. desc->flags = 0;
  128. if (args->args_count > 1) {
  129. if (args->args[1] & GPIO_ACTIVE_LOW)
  130. desc->flags |= GPIOD_ACTIVE_LOW;
  131. /* In the future add tri-state flag support */
  132. }
  133. return 0;
  134. }
  135. static const struct dm_gpio_ops octeon_gpio_ops = {
  136. .direction_input = octeon_gpio_dir_input,
  137. .direction_output = octeon_gpio_dir_output,
  138. .get_value = octeon_gpio_get_value,
  139. .set_value = octeon_gpio_set_value,
  140. .get_function = octeon_gpio_get_function,
  141. .xlate = octeon_gpio_xlate,
  142. };
  143. static int octeon_gpio_probe(struct udevice *dev)
  144. {
  145. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  146. struct octeon_gpio *priv = dev_get_priv(dev);
  147. char *end;
  148. priv->data = (const struct octeon_gpio_data *)dev_get_driver_data(dev);
  149. if (priv->data->probe == PROBE_PCI) {
  150. priv->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
  151. PCI_REGION_MEM);
  152. uc_priv->gpio_count = readq(priv->base +
  153. priv->data->reg_offs + GPIO_CONST) &
  154. GPIO_CONST_GPIOS_MASK;
  155. } else {
  156. priv->base = dev_remap_addr(dev);
  157. uc_priv->gpio_count = ofnode_read_u32_default(dev_ofnode(dev),
  158. "nr-gpios", 32);
  159. }
  160. if (!priv->base) {
  161. debug("%s(%s): Could not get base address\n",
  162. __func__, dev->name);
  163. return -ENODEV;
  164. }
  165. uc_priv->bank_name = strdup(dev->name);
  166. end = strchr(uc_priv->bank_name, '@');
  167. end[0] = 'A' + dev_seq(dev);
  168. end[1] = '\0';
  169. debug("%s(%s): base address: %p, pin count: %d\n",
  170. __func__, dev->name, priv->base, uc_priv->gpio_count);
  171. return 0;
  172. }
  173. static const struct octeon_gpio_data gpio_octeon_data = {
  174. .probe = PROBE_DT,
  175. .reg_offs = 0x80,
  176. .gpio_bit_cfg_offs = 0x100,
  177. };
  178. static const struct octeon_gpio_data gpio_octeontx_data = {
  179. .probe = PROBE_PCI,
  180. .reg_offs = 0x00,
  181. .gpio_bit_cfg_offs = 0x400,
  182. };
  183. static const struct udevice_id octeon_gpio_ids[] = {
  184. { .compatible = "cavium,thunder-8890-gpio",
  185. .data = (ulong)&gpio_octeontx_data },
  186. { .compatible = "cavium,octeon-7890-gpio",
  187. .data = (ulong)&gpio_octeon_data },
  188. { }
  189. };
  190. U_BOOT_DRIVER(octeon_gpio) = {
  191. .name = "octeon_gpio",
  192. .id = UCLASS_GPIO,
  193. .of_match = of_match_ptr(octeon_gpio_ids),
  194. .probe = octeon_gpio_probe,
  195. .priv_auto = sizeof(struct octeon_gpio),
  196. .ops = &octeon_gpio_ops,
  197. .flags = DM_FLAG_PRE_RELOC,
  198. };