0011-pinctrl-gemini-Support-drive-strength-setting.patch 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. From f147cf49ef39f5e87d5df9ef1fab52683bc75c63 Mon Sep 17 00:00:00 2001
  2. From: Linus Walleij <[email protected]>
  3. Date: Sat, 2 Dec 2017 12:23:09 +0100
  4. Subject: [PATCH 11/31] pinctrl: gemini: Support drive strength setting
  5. The Gemini pin controller can set drive strength for a few
  6. select groups of pins (not individually). Implement this
  7. for GMAC0 and 1 (ethernet ports), IDE and PCI.
  8. Cc: [email protected]
  9. Reviewed-by: Rob Herring <[email protected]>
  10. Signed-off-by: Linus Walleij <[email protected]>
  11. ---
  12. .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 3 +
  13. drivers/pinctrl/pinctrl-gemini.c | 81 ++++++++++++++++++++++
  14. 2 files changed, 84 insertions(+)
  15. --- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
  16. +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
  17. @@ -17,6 +17,9 @@ and generic pin config nodes.
  18. Supported configurations:
  19. - skew-delay is supported on the Ethernet pins
  20. +- drive-strength with 4, 8, 12 or 16 mA as argument is supported for
  21. + entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp"
  22. + and "pcigrp".
  23. Example:
  24. --- a/drivers/pinctrl/pinctrl-gemini.c
  25. +++ b/drivers/pinctrl/pinctrl-gemini.c
  26. @@ -67,6 +67,9 @@ struct gemini_pmx {
  27. * elements in .pins so we can iterate over that array
  28. * @mask: bits to clear to enable this when doing pin muxing
  29. * @value: bits to set to enable this when doing pin muxing
  30. + * @driving_mask: bitmask for the IO Pad driving register for this
  31. + * group, if it supports altering the driving strength of
  32. + * its lines.
  33. */
  34. struct gemini_pin_group {
  35. const char *name;
  36. @@ -74,12 +77,14 @@ struct gemini_pin_group {
  37. const unsigned int num_pins;
  38. u32 mask;
  39. u32 value;
  40. + u32 driving_mask;
  41. };
  42. /* Some straight-forward control registers */
  43. #define GLOBAL_WORD_ID 0x00
  44. #define GLOBAL_STATUS 0x04
  45. #define GLOBAL_STATUS_FLPIN BIT(20)
  46. +#define GLOBAL_IODRIVE 0x10
  47. #define GLOBAL_GMAC_CTRL_SKEW 0x1c
  48. #define GLOBAL_GMAC0_DATA_SKEW 0x20
  49. #define GLOBAL_GMAC1_DATA_SKEW 0x24
  50. @@ -738,6 +743,7 @@ static const struct gemini_pin_group gem
  51. /* Conflict with all flash usage */
  52. .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
  53. PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
  54. + .driving_mask = GENMASK(21, 20),
  55. },
  56. {
  57. .name = "satagrp",
  58. @@ -753,6 +759,7 @@ static const struct gemini_pin_group gem
  59. .name = "gmii_gmac0_grp",
  60. .pins = gmii_gmac0_3512_pins,
  61. .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins),
  62. + .driving_mask = GENMASK(17, 16),
  63. },
  64. {
  65. .name = "gmii_gmac1_grp",
  66. @@ -760,6 +767,7 @@ static const struct gemini_pin_group gem
  67. .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins),
  68. /* Bring out RGMII on the GMAC1 pins */
  69. .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
  70. + .driving_mask = GENMASK(19, 18),
  71. },
  72. {
  73. .name = "pcigrp",
  74. @@ -767,6 +775,7 @@ static const struct gemini_pin_group gem
  75. .num_pins = ARRAY_SIZE(pci_3512_pins),
  76. /* Conflict only with GPIO2 */
  77. .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
  78. + .driving_mask = GENMASK(23, 22),
  79. },
  80. {
  81. .name = "lpcgrp",
  82. @@ -1671,6 +1680,7 @@ static const struct gemini_pin_group gem
  83. /* Conflict with all flash usage */
  84. .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
  85. PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
  86. + .driving_mask = GENMASK(21, 20),
  87. },
  88. {
  89. .name = "satagrp",
  90. @@ -1686,6 +1696,7 @@ static const struct gemini_pin_group gem
  91. .name = "gmii_gmac0_grp",
  92. .pins = gmii_gmac0_3516_pins,
  93. .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins),
  94. + .driving_mask = GENMASK(17, 16),
  95. },
  96. {
  97. .name = "gmii_gmac1_grp",
  98. @@ -1693,6 +1704,7 @@ static const struct gemini_pin_group gem
  99. .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins),
  100. /* Bring out RGMII on the GMAC1 pins */
  101. .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
  102. + .driving_mask = GENMASK(19, 18),
  103. },
  104. {
  105. .name = "pcigrp",
  106. @@ -1700,6 +1712,7 @@ static const struct gemini_pin_group gem
  107. .num_pins = ARRAY_SIZE(pci_3516_pins),
  108. /* Conflict only with GPIO2 */
  109. .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
  110. + .driving_mask = GENMASK(23, 22),
  111. },
  112. {
  113. .name = "lpcgrp",
  114. @@ -2394,9 +2407,77 @@ static int gemini_pinconf_set(struct pin
  115. return ret;
  116. }
  117. +static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev,
  118. + unsigned selector,
  119. + unsigned long *configs,
  120. + unsigned num_configs)
  121. +{
  122. + struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
  123. + const struct gemini_pin_group *grp = NULL;
  124. + enum pin_config_param param;
  125. + u32 arg;
  126. + u32 val;
  127. + int i;
  128. +
  129. + if (pmx->is_3512)
  130. + grp = &gemini_3512_pin_groups[selector];
  131. + if (pmx->is_3516)
  132. + grp = &gemini_3516_pin_groups[selector];
  133. +
  134. + /* First figure out if this group supports configs */
  135. + if (!grp->driving_mask) {
  136. + dev_err(pmx->dev, "pin config group \"%s\" does "
  137. + "not support drive strength setting\n",
  138. + grp->name);
  139. + return -EINVAL;
  140. + }
  141. +
  142. + for (i = 0; i < num_configs; i++) {
  143. + param = pinconf_to_config_param(configs[i]);
  144. + arg = pinconf_to_config_argument(configs[i]);
  145. +
  146. + switch (param) {
  147. + case PIN_CONFIG_DRIVE_STRENGTH:
  148. + switch (arg) {
  149. + case 4:
  150. + val = 0;
  151. + break;
  152. + case 8:
  153. + val = 1;
  154. + break;
  155. + case 12:
  156. + val = 2;
  157. + break;
  158. + case 16:
  159. + val = 3;
  160. + break;
  161. + default:
  162. + dev_err(pmx->dev,
  163. + "invalid drive strength %d mA\n",
  164. + arg);
  165. + return -ENOTSUPP;
  166. + }
  167. + val <<= (ffs(grp->driving_mask) - 1);
  168. + regmap_update_bits(pmx->map, GLOBAL_IODRIVE,
  169. + grp->driving_mask,
  170. + val);
  171. + dev_info(pmx->dev,
  172. + "set group %s to %d mA drive strength mask %08x val %08x\n",
  173. + grp->name, arg, grp->driving_mask, val);
  174. + break;
  175. + default:
  176. + dev_err(pmx->dev, "invalid config param %04x\n", param);
  177. + return -ENOTSUPP;
  178. + }
  179. + }
  180. +
  181. + return 0;
  182. +}
  183. +
  184. static const struct pinconf_ops gemini_pinconf_ops = {
  185. .pin_config_get = gemini_pinconf_get,
  186. .pin_config_set = gemini_pinconf_set,
  187. + .pin_config_group_set = gemini_pinconf_group_set,
  188. .is_generic = true,
  189. };