mscc_sgpio.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // SPDX-License-Identifier: (GPL-2.0 OR MIT)
  2. /*
  3. * Microsemi SoCs serial gpio driver
  4. *
  5. * Author: <lars.povlsen@microchip.com>
  6. *
  7. * Copyright (c) 2018 Microsemi Corporation
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <log.h>
  12. #include <asm/gpio.h>
  13. #include <asm/io.h>
  14. #include <errno.h>
  15. #include <clk.h>
  16. #include <dm/device_compat.h>
  17. #include <linux/bitops.h>
  18. #include <linux/err.h>
  19. #define MSCC_SGPIOS_PER_BANK 32
  20. #define MSCC_SGPIO_BANK_DEPTH 4
  21. enum {
  22. REG_INPUT_DATA,
  23. REG_PORT_CONFIG,
  24. REG_PORT_ENABLE,
  25. REG_SIO_CONFIG,
  26. REG_SIO_CLOCK,
  27. MAXREG
  28. };
  29. struct mscc_sgpio_bf {
  30. u8 beg;
  31. u8 end;
  32. };
  33. struct mscc_sgpio_props {
  34. u8 regoff[MAXREG];
  35. struct mscc_sgpio_bf auto_repeat;
  36. struct mscc_sgpio_bf port_width;
  37. struct mscc_sgpio_bf clk_freq;
  38. struct mscc_sgpio_bf bit_source;
  39. };
  40. #define __M(bf) GENMASK((bf).end, (bf).beg)
  41. #define __F(bf, x) (__M(bf) & ((x) << (bf).beg))
  42. #define __X(bf, x) (((x) >> (bf).beg) & GENMASK(((bf).end - (bf).beg), 0))
  43. #define MSCC_M_CFG_SIO_AUTO_REPEAT(p) BIT(p->props->auto_repeat.beg)
  44. #define MSCC_F_CFG_SIO_PORT_WIDTH(p, x) __F(p->props->port_width, x)
  45. #define MSCC_M_CFG_SIO_PORT_WIDTH(p) __M(p->props->port_width)
  46. #define MSCC_F_CLOCK_SIO_CLK_FREQ(p, x) __F(p->props->clk_freq, x)
  47. #define MSCC_M_CLOCK_SIO_CLK_FREQ(p) __M(p->props->clk_freq)
  48. #define MSCC_F_PORT_CFG_BIT_SOURCE(p, x) __F(p->props->bit_source, x)
  49. #define MSCC_X_PORT_CFG_BIT_SOURCE(p, x) __X(p->props->bit_source, x)
  50. const struct mscc_sgpio_props props_luton = {
  51. .regoff = { 0x00, 0x09, 0x29, 0x2a, 0x2b },
  52. .auto_repeat = { 5, 5 },
  53. .port_width = { 2, 3 },
  54. .clk_freq = { 0, 11 },
  55. .bit_source = { 0, 11 },
  56. };
  57. const struct mscc_sgpio_props props_ocelot = {
  58. .regoff = { 0x00, 0x06, 0x26, 0x04, 0x05 },
  59. .auto_repeat = { 10, 10 },
  60. .port_width = { 7, 8 },
  61. .clk_freq = { 8, 19 },
  62. .bit_source = { 12, 23 },
  63. };
  64. struct mscc_sgpio_priv {
  65. u32 bitcount;
  66. u32 ports;
  67. u32 clock;
  68. u32 mode[MSCC_SGPIOS_PER_BANK];
  69. u32 __iomem *regs;
  70. const struct mscc_sgpio_props *props;
  71. };
  72. static inline u32 sgpio_readl(struct mscc_sgpio_priv *priv, u32 rno, u32 off)
  73. {
  74. u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];
  75. return readl(reg);
  76. }
  77. static inline void sgpio_writel(struct mscc_sgpio_priv *priv,
  78. u32 val, u32 rno, u32 off)
  79. {
  80. u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];
  81. writel(val, reg);
  82. }
  83. static void sgpio_clrsetbits(struct mscc_sgpio_priv *priv,
  84. u32 rno, u32 off, u32 clear, u32 set)
  85. {
  86. u32 __iomem *reg = &priv->regs[priv->props->regoff[rno] + off];
  87. clrsetbits_le32(reg, clear, set);
  88. }
  89. static int mscc_sgpio_direction_input(struct udevice *dev, unsigned int gpio)
  90. {
  91. struct mscc_sgpio_priv *priv = dev_get_priv(dev);
  92. u32 port = gpio % MSCC_SGPIOS_PER_BANK;
  93. u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
  94. priv->mode[port] |= BIT(bit);
  95. return 0;
  96. }
  97. static int mscc_sgpio_direction_output(struct udevice *dev,
  98. unsigned int gpio, int value)
  99. {
  100. struct mscc_sgpio_priv *priv = dev_get_priv(dev);
  101. u32 port = gpio % MSCC_SGPIOS_PER_BANK;
  102. u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
  103. u32 mask = 3 << (3 * bit);
  104. debug("set: port %d, bit %d, mask 0x%08x, value %d\n",
  105. port, bit, mask, value);
  106. value = (value & 3) << (3 * bit);
  107. sgpio_clrsetbits(priv, REG_PORT_CONFIG, port,
  108. MSCC_F_PORT_CFG_BIT_SOURCE(priv, mask),
  109. MSCC_F_PORT_CFG_BIT_SOURCE(priv, value));
  110. clrbits_le32(&priv->mode[port], BIT(bit));
  111. return 0;
  112. }
  113. static int mscc_sgpio_get_function(struct udevice *dev, unsigned int gpio)
  114. {
  115. struct mscc_sgpio_priv *priv = dev_get_priv(dev);
  116. u32 port = gpio % MSCC_SGPIOS_PER_BANK;
  117. u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
  118. u32 val = priv->mode[port] & BIT(bit);
  119. if (val)
  120. return GPIOF_INPUT;
  121. else
  122. return GPIOF_OUTPUT;
  123. }
  124. static int mscc_sgpio_set_value(struct udevice *dev,
  125. unsigned int gpio, int value)
  126. {
  127. return mscc_sgpio_direction_output(dev, gpio, value);
  128. }
  129. static int mscc_sgpio_get_value(struct udevice *dev, unsigned int gpio)
  130. {
  131. struct mscc_sgpio_priv *priv = dev_get_priv(dev);
  132. u32 port = gpio % MSCC_SGPIOS_PER_BANK;
  133. u32 bit = gpio / MSCC_SGPIOS_PER_BANK;
  134. int ret;
  135. if (mscc_sgpio_get_function(dev, gpio) == GPIOF_INPUT) {
  136. ret = !!(sgpio_readl(priv, REG_INPUT_DATA, bit) & BIT(port));
  137. } else {
  138. u32 portval = sgpio_readl(priv, REG_PORT_CONFIG, port);
  139. ret = MSCC_X_PORT_CFG_BIT_SOURCE(priv, portval);
  140. ret = !!(ret & (3 << (3 * bit)));
  141. }
  142. debug("get: gpio %d, port %d, bit %d, value %d\n",
  143. gpio, port, bit, ret);
  144. return ret;
  145. }
  146. static int mscc_sgpio_get_count(struct udevice *dev)
  147. {
  148. struct ofnode_phandle_args args;
  149. int count = 0, i = 0, ret;
  150. ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3, i, &args);
  151. while (ret != -ENOENT) {
  152. count += args.args[2];
  153. ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
  154. ++i, &args);
  155. }
  156. return count;
  157. }
  158. static int mscc_sgpio_probe(struct udevice *dev)
  159. {
  160. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  161. struct mscc_sgpio_priv *priv = dev_get_priv(dev);
  162. int err, div_clock = 0, port;
  163. u32 val;
  164. struct clk clk;
  165. err = clk_get_by_index(dev, 0, &clk);
  166. if (!err) {
  167. err = clk_get_rate(&clk);
  168. if (IS_ERR_VALUE(err)) {
  169. dev_err(dev, "Invalid clk rate\n");
  170. return -EINVAL;
  171. }
  172. div_clock = err;
  173. } else {
  174. dev_err(dev, "Failed to get clock\n");
  175. return err;
  176. }
  177. priv->props = (const struct mscc_sgpio_props *)dev_get_driver_data(dev);
  178. priv->ports = dev_read_u32_default(dev, "mscc,sgpio-ports", 0xFFFFFFFF);
  179. priv->clock = dev_read_u32_default(dev, "mscc,sgpio-frequency",
  180. 12500000);
  181. if (priv->clock <= 0 || priv->clock > div_clock) {
  182. dev_err(dev, "Invalid frequency %d\n", priv->clock);
  183. return -EINVAL;
  184. }
  185. uc_priv->gpio_count = mscc_sgpio_get_count(dev);
  186. uc_priv->gpio_count = dev_read_u32_default(dev, "ngpios",
  187. uc_priv->gpio_count);
  188. if (uc_priv->gpio_count < 1 || uc_priv->gpio_count >
  189. (4 * MSCC_SGPIOS_PER_BANK)) {
  190. dev_err(dev, "Invalid gpio count %d\n", uc_priv->gpio_count);
  191. return -EINVAL;
  192. }
  193. priv->bitcount = DIV_ROUND_UP(uc_priv->gpio_count,
  194. MSCC_SGPIOS_PER_BANK);
  195. debug("probe: gpios = %d, bit-count = %d\n",
  196. uc_priv->gpio_count, priv->bitcount);
  197. priv->regs = (u32 __iomem *)dev_read_addr(dev);
  198. uc_priv->bank_name = "sgpio";
  199. sgpio_clrsetbits(priv, REG_SIO_CONFIG, 0,
  200. MSCC_M_CFG_SIO_PORT_WIDTH(priv),
  201. MSCC_F_CFG_SIO_PORT_WIDTH(priv, priv->bitcount - 1) |
  202. MSCC_M_CFG_SIO_AUTO_REPEAT(priv));
  203. val = div_clock / priv->clock;
  204. debug("probe: div-clock = %d KHz, freq = %d KHz, div = %d\n",
  205. div_clock / 1000, priv->clock / 1000, val);
  206. sgpio_clrsetbits(priv, REG_SIO_CLOCK, 0,
  207. MSCC_M_CLOCK_SIO_CLK_FREQ(priv),
  208. MSCC_F_CLOCK_SIO_CLK_FREQ(priv, val));
  209. for (port = 0; port < 32; port++)
  210. sgpio_writel(priv, 0, REG_PORT_CONFIG, port);
  211. sgpio_writel(priv, priv->ports, REG_PORT_ENABLE, 0);
  212. debug("probe: sgpio regs = %p\n", priv->regs);
  213. return 0;
  214. }
  215. static const struct dm_gpio_ops mscc_sgpio_ops = {
  216. .direction_input = mscc_sgpio_direction_input,
  217. .direction_output = mscc_sgpio_direction_output,
  218. .get_function = mscc_sgpio_get_function,
  219. .get_value = mscc_sgpio_get_value,
  220. .set_value = mscc_sgpio_set_value,
  221. };
  222. static const struct udevice_id mscc_sgpio_ids[] = {
  223. { .compatible = "mscc,luton-sgpio", .data = (ulong)&props_luton },
  224. { .compatible = "mscc,ocelot-sgpio", .data = (ulong)&props_ocelot },
  225. { }
  226. };
  227. U_BOOT_DRIVER(gpio_mscc_sgpio) = {
  228. .name = "mscc-sgpio",
  229. .id = UCLASS_GPIO,
  230. .of_match = mscc_sgpio_ids,
  231. .ops = &mscc_sgpio_ops,
  232. .probe = mscc_sgpio_probe,
  233. .priv_auto_alloc_size = sizeof(struct mscc_sgpio_priv),
  234. };