From patchwork Sat Oct 28 13:37:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 117395 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp610821qgn; Sat, 28 Oct 2017 06:41:51 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Rdbz2yO1ynJbu6si0ptxX3jZXF8Myv1NtHH6ooyx82uyBwDwjm0qiHJUo6SP7ktJM8oKhZ X-Received: by 10.99.51.11 with SMTP id z11mr3082917pgz.223.1509198111038; Sat, 28 Oct 2017 06:41:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509198111; cv=none; d=google.com; s=arc-20160816; b=ObBzd6k+jy7X4+8q37xZQzu3Qhqlv3NxeiJ2zfZUyc6HbC9IBuoHhLXmg4+13d4Y7L qtyCceljqYc1Ld1mZO8k6audV4l2H0pP07dB0pcrr1GUTRKbAhuGt25pKBCmZtGLIBmM D1zbm4iVEjT9I6uyYaV1jvcCz/UmFk/5ns7r01MShRCAD1SNHMTwiudMqeNyZSZknKUM cyh7sfxWlkNtkXHjtz9Qz3aOoenNkHH2HS+c0tJK8Qtk7F+hXfO3LQ7xbYD/gXT/buUy 9kVnp6AA2owhKm/GBTzE+9j+L2SJZDko5/EbiLiwkgTZ5CAxts8gt8FdEi0seWQvXkY9 ZbUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=2EClafLVJpQGnt5r9mvJIHNR5NM7ei7dHd+5IVVqjXc=; b=YYjzcCEDp6pVWbTZ0fv0qXt0o05TecPkfP+RP8GndOzUOH7LmF+DHzmk485uIalyjl EKG7h4XfGPPRWsbV/uexoe17wZq/WXCdS8I9Qm23sZbo96Pf+IIBk9xLcLN2tWA4uD/Y 4ul9Rr0/btVOCzhdJ35T6RujPO2QDT7q3vAL7vP+cYGVhODIWu38anHAGK2UzgcoobH8 tVsggbp4nWH2K6jYoMxKVMsQmP+ArnUCDImNPDU3ABJdfcj+l4odeIMUypFAO4E2EMPw xE82oK77EjeeqP+aPczWfdfBZVpfRi7uOwBqy7uXkT7CicUxW8MUopfxt8ISDM0aD0WB mJgQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=g4oFoi3h; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l185si372828pfc.43.2017.10.28.06.41.50; Sat, 28 Oct 2017 06:41:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=g4oFoi3h; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751238AbdJ1Nlu (ORCPT + 6 others); Sat, 28 Oct 2017 09:41:50 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:47494 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751199AbdJ1Nlt (ORCPT ); Sat, 28 Oct 2017 09:41:49 -0400 Received: by mail-lf0-f67.google.com with SMTP id k40so10122205lfi.4 for ; Sat, 28 Oct 2017 06:41:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rup2dG4vocFOfP4/86uj2Bk+Qf0hatJXJIeOWXp2Evc=; b=g4oFoi3hFa3w9cw2JoHP3ZfhYUwus36pgPQiOoN+FLOEDRK87nVsaL6i+ovqzk3LZ/ eYcVVD0rIqd7QOljpds2VGCCQfXonRAXYEJmOotfAuec1yg8ti9u0wUphJtbr+FUGnVo 8yOSdcOwKQc/Tg6ZC3NKXedvOn3ENcm+yGnvI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rup2dG4vocFOfP4/86uj2Bk+Qf0hatJXJIeOWXp2Evc=; b=S3p12kHgsYsGuYsmII2IgrKzkyc7ZvEYLNnZ2FVj33PAj0n/WxEuKvYyOdhHnkcFk+ ni907mR1aDP4Diie2aCgzYReL2aYJ7ovpktGZWeHotQ/F+Uadgcjo5/5bP4YTEs59HJE co8N71u9dntnLbjv9TF89DBXpPVpwwsT4BnG4TTIwLRbP9ZTDMRA0Ph3EGXnVaj9Q7zU GTEsjijx1JgBQ1FBaBqZ90RGz9L24nttSOkL1vVg0ovGXMYkN9bxGImbVCaXwE1CJQNl F3aCFfgy9ko3A//wvd6vcf2npLPKmvd8lzO/erlUlv7fW/isfJ8CEEOI1wLB2wv0hCU3 Xrmg== X-Gm-Message-State: AMCzsaX1qGJ4cm/Pn3LF99JNe2cotM3dQLDHIaCPTllM2N2mhg12NK47 VYIOqzYQIEW2/U6YLk4BUi7djtFfOyQ= X-Received: by 10.25.204.81 with SMTP id c78mr1239675lfg.49.1509198107608; Sat, 28 Oct 2017 06:41:47 -0700 (PDT) Received: from localhost.localdomain (c-567171d5.014-348-6c756e10.cust.bredbandsbolaget.se. [213.113.113.86]) by smtp.gmail.com with ESMTPSA id r23sm2447913lja.32.2017.10.28.06.41.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 28 Oct 2017 06:41:46 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org, Hans Ulli Kroll , Florian Fainelli Cc: Janos Laube , Paulius Zaleckas , linux-arm-kernel@lists.infradead.org, Linus Walleij Subject: [PATCH 4/4] pinctrl: gemini: Implement clock skew/delay config Date: Sat, 28 Oct 2017 15:37:19 +0200 Message-Id: <20171028133719.27528-4-linus.walleij@linaro.org> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171028133719.27528-1-linus.walleij@linaro.org> References: <20171028133719.27528-1-linus.walleij@linaro.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org This enabled pin config on the Gemini driver and implements pin skew/delay so that the ethernet pins clocking can be properly configured. Signed-off-by: Linus Walleij --- .../bindings/pinctrl/cortina,gemini-pinctrl.txt | 10 +- drivers/pinctrl/pinctrl-gemini.c | 178 ++++++++++++++++++++- 2 files changed, 182 insertions(+), 6 deletions(-) -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Acked-by: Hans Ulli Kroll diff --git a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt index 61466c58faae..d857b67fab72 100644 --- a/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt @@ -9,8 +9,14 @@ The pin controller node must be a subnode of the system controller node. Required properties: - compatible: "cortina,gemini-pinctrl" -Subnodes of the pin controller contain pin control multiplexing set-up. -Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes. +Subnodes of the pin controller contain pin control multiplexing set-up +and pin configuration of individual pins. + +Please refer to pinctrl-bindings.txt for generic pin multiplexing nodes +and generic pin config nodes. + +Supported configurations: +- skew-delay is supported on the Ethernet pins Example: diff --git a/drivers/pinctrl/pinctrl-gemini.c b/drivers/pinctrl/pinctrl-gemini.c index 18fb5ff8a442..bd6133f06759 100644 --- a/drivers/pinctrl/pinctrl-gemini.c +++ b/drivers/pinctrl/pinctrl-gemini.c @@ -24,6 +24,19 @@ #define DRIVER_NAME "pinctrl-gemini" /** + * struct gemini_pin_conf - information about configuring a pin + * @pin: the pin number + * @reg: config register + * @mask: the bits affecting the configuration of the pin + */ +struct gemini_pin_conf { + unsigned int pin; + u32 reg; + u32 mask; +}; + +/** + * struct gemini_pmx - state holder for the gemini pin controller * @dev: a pointer back to containing device * @virtbase: the offset to the controller in virtual memory * @map: regmap to access registers @@ -31,6 +44,8 @@ * @is_3516: whether the SoC/package is the 3516 variant * @flash_pin: whether the flash pin (extended pins for parallel * flash) is set + * @confs: pin config information + * @nconfs: number of pin config information items */ struct gemini_pmx { struct device *dev; @@ -39,6 +54,8 @@ struct gemini_pmx { bool is_3512; bool is_3516; bool flash_pin; + const struct gemini_pin_conf *confs; + unsigned int nconfs; }; /** @@ -59,6 +76,13 @@ struct gemini_pin_group { u32 value; }; +/* Some straight-forward control registers */ +#define GLOBAL_WORD_ID 0x00 +#define GLOBAL_STATUS 0x04 +#define GLOBAL_STATUS_FLPIN BIT(20) +#define GLOBAL_GMAC_CTRL_SKEW 0x1c +#define GLOBAL_GMAC0_DATA_SKEW 0x20 +#define GLOBAL_GMAC1_DATA_SKEW 0x24 /* * Global Miscellaneous Control Register * This register controls all Gemini pad/pin multiplexing @@ -71,9 +95,6 @@ struct gemini_pin_group { * DISABLED again. So you select a flash configuration once, and then * you are stuck with it. */ -#define GLOBAL_WORD_ID 0x00 -#define GLOBAL_STATUS 0x04 -#define GLOBAL_STATUS_FLPIN BIT(20) #define GLOBAL_MISC_CTRL 0x30 #define TVC_CLK_PAD_ENABLE BIT(20) #define PCI_CLK_PAD_ENABLE BIT(17) @@ -1925,7 +1946,7 @@ static const struct pinctrl_ops gemini_pctrl_ops = { .get_group_name = gemini_get_group_name, .get_group_pins = gemini_get_group_pins, .pin_dbg_show = gemini_pin_dbg_show, - .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_node_to_map = pinconf_generic_dt_node_to_map_all, .dt_free_map = pinconf_generic_dt_free_map, }; @@ -2203,10 +2224,155 @@ static const struct pinmux_ops gemini_pmx_ops = { .set_mux = gemini_pmx_set_mux, }; +#define GEMINI_CFGPIN(_n, _r, _lb, _hb) { \ + .pin = _n, \ + .reg = _r, \ + .mask = GENMASK(_hb, _lb) \ +} + +static const struct gemini_pin_conf gemini_confs_3512[] = { + GEMINI_CFGPIN(259, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */ + GEMINI_CFGPIN(277, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */ + GEMINI_CFGPIN(241, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */ + GEMINI_CFGPIN(312, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */ + GEMINI_CFGPIN(298, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */ + GEMINI_CFGPIN(280, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */ + GEMINI_CFGPIN(316, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */ + GEMINI_CFGPIN(243, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */ + GEMINI_CFGPIN(295, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */ + GEMINI_CFGPIN(313, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */ + GEMINI_CFGPIN(242, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */ + GEMINI_CFGPIN(260, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */ + GEMINI_CFGPIN(294, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */ + GEMINI_CFGPIN(276, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */ + GEMINI_CFGPIN(258, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */ + GEMINI_CFGPIN(240, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */ + GEMINI_CFGPIN(262, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */ + GEMINI_CFGPIN(244, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */ + GEMINI_CFGPIN(317, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */ + GEMINI_CFGPIN(299, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */ + GEMINI_CFGPIN(261, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */ + GEMINI_CFGPIN(279, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */ + GEMINI_CFGPIN(297, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */ + GEMINI_CFGPIN(315, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */ +}; + +static const struct gemini_pin_conf gemini_confs_3516[] = { + GEMINI_CFGPIN(347, GLOBAL_GMAC_CTRL_SKEW, 0, 3), /* GMAC0 RXDV */ + GEMINI_CFGPIN(386, GLOBAL_GMAC_CTRL_SKEW, 4, 7), /* GMAC0 RXC */ + GEMINI_CFGPIN(307, GLOBAL_GMAC_CTRL_SKEW, 8, 11), /* GMAC0 TXEN */ + GEMINI_CFGPIN(327, GLOBAL_GMAC_CTRL_SKEW, 12, 15), /* GMAC0 TXC */ + GEMINI_CFGPIN(309, GLOBAL_GMAC_CTRL_SKEW, 16, 19), /* GMAC1 RXDV */ + GEMINI_CFGPIN(390, GLOBAL_GMAC_CTRL_SKEW, 20, 23), /* GMAC1 RXC */ + GEMINI_CFGPIN(370, GLOBAL_GMAC_CTRL_SKEW, 24, 27), /* GMAC1 TXEN */ + GEMINI_CFGPIN(350, GLOBAL_GMAC_CTRL_SKEW, 28, 31), /* GMAC1 TXC */ + GEMINI_CFGPIN(367, GLOBAL_GMAC0_DATA_SKEW, 0, 3), /* GMAC0 RXD0 */ + GEMINI_CFGPIN(348, GLOBAL_GMAC0_DATA_SKEW, 4, 7), /* GMAC0 RXD1 */ + GEMINI_CFGPIN(387, GLOBAL_GMAC0_DATA_SKEW, 8, 11), /* GMAC0 RXD2 */ + GEMINI_CFGPIN(328, GLOBAL_GMAC0_DATA_SKEW, 12, 15), /* GMAC0 RXD3 */ + GEMINI_CFGPIN(306, GLOBAL_GMAC0_DATA_SKEW, 16, 19), /* GMAC0 TXD0 */ + GEMINI_CFGPIN(325, GLOBAL_GMAC0_DATA_SKEW, 20, 23), /* GMAC0 TXD1 */ + GEMINI_CFGPIN(346, GLOBAL_GMAC0_DATA_SKEW, 24, 27), /* GMAC0 TXD2 */ + GEMINI_CFGPIN(326, GLOBAL_GMAC0_DATA_SKEW, 28, 31), /* GMAC0 TXD3 */ + GEMINI_CFGPIN(391, GLOBAL_GMAC1_DATA_SKEW, 0, 3), /* GMAC1 RXD0 */ + GEMINI_CFGPIN(351, GLOBAL_GMAC1_DATA_SKEW, 4, 7), /* GMAC1 RXD1 */ + GEMINI_CFGPIN(310, GLOBAL_GMAC1_DATA_SKEW, 8, 11), /* GMAC1 RXD2 */ + GEMINI_CFGPIN(371, GLOBAL_GMAC1_DATA_SKEW, 12, 15), /* GMAC1 RXD3 */ + GEMINI_CFGPIN(329, GLOBAL_GMAC1_DATA_SKEW, 16, 19), /* GMAC1 TXD0 */ + GEMINI_CFGPIN(389, GLOBAL_GMAC1_DATA_SKEW, 20, 23), /* GMAC1 TXD1 */ + GEMINI_CFGPIN(369, GLOBAL_GMAC1_DATA_SKEW, 24, 27), /* GMAC1 TXD2 */ + GEMINI_CFGPIN(308, GLOBAL_GMAC1_DATA_SKEW, 28, 31), /* GMAC1 TXD3 */ +}; + +static const struct gemini_pin_conf *gemini_get_pin_conf(struct gemini_pmx *pmx, + unsigned int pin) +{ + const struct gemini_pin_conf *retconf; + int i; + + for (i = 0; i < pmx->nconfs; i++) { + retconf = &gemini_confs_3516[i]; + if (retconf->pin == pin) + return retconf; + } + return NULL; +} + +static int gemini_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + const struct gemini_pin_conf *conf; + u32 val; + + switch (param) { + case PIN_CONFIG_SKEW_DELAY: + conf = gemini_get_pin_conf(pmx, pin); + if (!conf) + return -ENOTSUPP; + regmap_read(pmx->map, conf->reg, &val); + val &= conf->mask; + val >>= (ffs(conf->mask) - 1); + *config = pinconf_to_config_packed(PIN_CONFIG_SKEW_DELAY, val); + break; + default: + return -ENOTSUPP; + } + + return 0; +} + +static int gemini_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct gemini_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); + const struct gemini_pin_conf *conf; + enum pin_config_param param; + u32 arg; + int ret = 0; + int i; + + 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_SKEW_DELAY: + if (arg > 0xf) + return -EINVAL; + conf = gemini_get_pin_conf(pmx, pin); + if (!conf) { + dev_err(pmx->dev, + "invalid pin for skew delay %d\n", pin); + return -ENOTSUPP; + } + arg <<= (ffs(conf->mask) - 1); + dev_dbg(pmx->dev, + "set pin %d to skew delay mask %08x, val %08x\n", + pin, conf->mask, arg); + regmap_update_bits(pmx->map, conf->reg, conf->mask, arg); + break; + default: + dev_err(pmx->dev, "Invalid config param %04x\n", param); + return -ENOTSUPP; + } + } + + return ret; +} + +static const struct pinconf_ops gemini_pinconf_ops = { + .pin_config_get = gemini_pinconf_get, + .pin_config_set = gemini_pinconf_set, + .is_generic = true, +}; + static struct pinctrl_desc gemini_pmx_desc = { .name = DRIVER_NAME, .pctlops = &gemini_pctrl_ops, .pmxops = &gemini_pmx_ops, + .confops = &gemini_pinconf_ops, .owner = THIS_MODULE, }; @@ -2249,11 +2415,15 @@ static int gemini_pmx_probe(struct platform_device *pdev) val &= 0xffff; if (val == 0x3512) { pmx->is_3512 = true; + pmx->confs = gemini_confs_3512; + pmx->nconfs = ARRAY_SIZE(gemini_confs_3512); gemini_pmx_desc.pins = gemini_3512_pins; gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3512_pins); dev_info(dev, "detected 3512 chip variant\n"); } else if (val == 0x3516) { pmx->is_3516 = true; + pmx->confs = gemini_confs_3516; + pmx->nconfs = ARRAY_SIZE(gemini_confs_3516); gemini_pmx_desc.pins = gemini_3516_pins; gemini_pmx_desc.npins = ARRAY_SIZE(gemini_3516_pins); dev_info(dev, "detected 3516 chip variant\n");