diff options
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.patch | 198 |
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, + }; + |