aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch')
-rw-r--r--target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch198
1 files changed, 198 insertions, 0 deletions
diff --git a/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch b/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch
new file mode 100644
index 0000000000..5fefece493
--- /dev/null
+++ b/target/linux/gemini/patches-4.14/0011-pinctrl-gemini-Support-drive-strength-setting.patch
@@ -0,0 +1,198 @@
+From f147cf49ef39f5e87d5df9ef1fab52683bc75c63 Mon Sep 17 00:00:00 2001
+From: Linus Walleij <linus.walleij@linaro.org>
+Date: Sat, 2 Dec 2017 12:23:09 +0100
+Subject: [PATCH 11/31] pinctrl: gemini: Support drive strength setting
+
+The Gemini pin controller can set drive strength for a few
+select groups of pins (not individually). Implement this
+for GMAC0 and 1 (ethernet ports), IDE and PCI.
+
+Cc: devicetree@vger.kernel.org
+Reviewed-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 3 +
+ drivers/pinctrl/pinctrl-gemini.c | 81 ++++++++++++++++++++++
+ 2 files changed, 84 insertions(+)
+
+--- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
++++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
+@@ -17,6 +17,9 @@ and generic pin config nodes.
+
+ Supported configurations:
+ - skew-delay is supported on the Ethernet pins
++- drive-strength with 4, 8, 12 or 16 mA as argument is supported for
++ entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp"
++ and "pcigrp".
+
+ Example:
+
+--- a/drivers/pinctrl/pinctrl-gemini.c
++++ b/drivers/pinctrl/pinctrl-gemini.c
+@@ -67,6 +67,9 @@ struct gemini_pmx {
+ * elements in .pins so we can iterate over that array
+ * @mask: bits to clear to enable this when doing pin muxing
+ * @value: bits to set to enable this when doing pin muxing
++ * @driving_mask: bitmask for the IO Pad driving register for this
++ * group, if it supports altering the driving strength of
++ * its lines.
+ */
+ struct gemini_pin_group {
+ const char *name;
+@@ -74,12 +77,14 @@ struct gemini_pin_group {
+ const unsigned int num_pins;
+ u32 mask;
+ u32 value;
++ u32 driving_mask;
+ };
+
+ /* Some straight-forward control registers */
+ #define GLOBAL_WORD_ID 0x00
+ #define GLOBAL_STATUS 0x04
+ #define GLOBAL_STATUS_FLPIN BIT(20)
++#define GLOBAL_IODRIVE 0x10
+ #define GLOBAL_GMAC_CTRL_SKEW 0x1c
+ #define GLOBAL_GMAC0_DATA_SKEW 0x20
+ #define GLOBAL_GMAC1_DATA_SKEW 0x24
+@@ -738,6 +743,7 @@ static const struct gemini_pin_group gem
+ /* Conflict with all flash usage */
+ .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
+ PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
++ .driving_mask = GENMASK(21, 20),
+ },
+ {
+ .name = "satagrp",
+@@ -753,6 +759,7 @@ static const struct gemini_pin_group gem
+ .name = "gmii_gmac0_grp",
+ .pins = gmii_gmac0_3512_pins,
+ .num_pins = ARRAY_SIZE(gmii_gmac0_3512_pins),
++ .driving_mask = GENMASK(17, 16),
+ },
+ {
+ .name = "gmii_gmac1_grp",
+@@ -760,6 +767,7 @@ static const struct gemini_pin_group gem
+ .num_pins = ARRAY_SIZE(gmii_gmac1_3512_pins),
+ /* Bring out RGMII on the GMAC1 pins */
+ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
++ .driving_mask = GENMASK(19, 18),
+ },
+ {
+ .name = "pcigrp",
+@@ -767,6 +775,7 @@ static const struct gemini_pin_group gem
+ .num_pins = ARRAY_SIZE(pci_3512_pins),
+ /* Conflict only with GPIO2 */
+ .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
++ .driving_mask = GENMASK(23, 22),
+ },
+ {
+ .name = "lpcgrp",
+@@ -1671,6 +1680,7 @@ static const struct gemini_pin_group gem
+ /* Conflict with all flash usage */
+ .value = IDE_PADS_ENABLE | NAND_PADS_DISABLE |
+ PFLASH_PADS_DISABLE | SFLASH_PADS_DISABLE,
++ .driving_mask = GENMASK(21, 20),
+ },
+ {
+ .name = "satagrp",
+@@ -1686,6 +1696,7 @@ static const struct gemini_pin_group gem
+ .name = "gmii_gmac0_grp",
+ .pins = gmii_gmac0_3516_pins,
+ .num_pins = ARRAY_SIZE(gmii_gmac0_3516_pins),
++ .driving_mask = GENMASK(17, 16),
+ },
+ {
+ .name = "gmii_gmac1_grp",
+@@ -1693,6 +1704,7 @@ static const struct gemini_pin_group gem
+ .num_pins = ARRAY_SIZE(gmii_gmac1_3516_pins),
+ /* Bring out RGMII on the GMAC1 pins */
+ .value = GEMINI_GMAC_IOSEL_GMAC0_GMAC1_RGMII,
++ .driving_mask = GENMASK(19, 18),
+ },
+ {
+ .name = "pcigrp",
+@@ -1700,6 +1712,7 @@ static const struct gemini_pin_group gem
+ .num_pins = ARRAY_SIZE(pci_3516_pins),
+ /* Conflict only with GPIO2 */
+ .value = PCI_PADS_ENABLE | PCI_CLK_PAD_ENABLE,
++ .driving_mask = GENMASK(23, 22),
+ },
+ {
+ .name = "lpcgrp",
+@@ -2394,9 +2407,77 @@ static int gemini_pinconf_set(struct pin
+ return ret;
+ }
+
++static int gemini_pinconf_group_set(struct pinctrl_dev *pctldev,
++ unsigned selector,
++ unsigned long *configs,
++ unsigned num_configs)
++{
++ struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
++ const struct gemini_pin_group *grp = NULL;
++ enum pin_config_param param;
++ u32 arg;
++ u32 val;
++ int i;
++
++ if (pmx->is_3512)
++ grp = &gemini_3512_pin_groups[selector];
++ if (pmx->is_3516)
++ grp = &gemini_3516_pin_groups[selector];
++
++ /* First figure out if this group supports configs */
++ if (!grp->driving_mask) {
++ dev_err(pmx->dev, "pin config group \"%s\" does "
++ "not support drive strength setting\n",
++ grp->name);
++ return -EINVAL;
++ }
++
++ for (i = 0; i < num_configs; i++) {
++ param = pinconf_to_config_param(configs[i]);
++ arg = pinconf_to_config_argument(configs[i]);
++
++ switch (param) {
++ case PIN_CONFIG_DRIVE_STRENGTH:
++ switch (arg) {
++ case 4:
++ val = 0;
++ break;
++ case 8:
++ val = 1;
++ break;
++ case 12:
++ val = 2;
++ break;
++ case 16:
++ val = 3;
++ break;
++ default:
++ dev_err(pmx->dev,
++ "invalid drive strength %d mA\n",
++ arg);
++ return -ENOTSUPP;
++ }
++ val <<= (ffs(grp->driving_mask) - 1);
++ regmap_update_bits(pmx->map, GLOBAL_IODRIVE,
++ grp->driving_mask,
++ val);
++ dev_info(pmx->dev,
++ "set group %s to %d mA drive strength mask %08x val %08x\n",
++ grp->name, arg, grp->driving_mask, val);
++ break;
++ default:
++ dev_err(pmx->dev, "invalid config param %04x\n", param);
++ return -ENOTSUPP;
++ }
++ }
++
++ return 0;
++}
++
+ static const struct pinconf_ops gemini_pinconf_ops = {
+ .pin_config_get = gemini_pinconf_get,
+ .pin_config_set = gemini_pinconf_set,
++ .pin_config_group_set = gemini_pinconf_group_set,
+ .is_generic = true,
+ };
+