From patchwork Thu Apr 19 07:24:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kunihiko Hayashi X-Patchwork-Id: 133705 Delivered-To: patch@linaro.org Received: by 10.46.66.142 with SMTP id h14csp319727ljf; Thu, 19 Apr 2018 00:26:09 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/mJvuMt+yAXZnjJC8xKXZLJNFXE+St/lHyU1J7vC1ThrJY8h/aAo+XvUlc9D9ZH6AG+4Ch X-Received: by 2002:a17:902:bd4a:: with SMTP id b10-v6mr5108722plx.271.1524122769806; Thu, 19 Apr 2018 00:26:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524122769; cv=none; d=google.com; s=arc-20160816; b=wB5XO11wNVq7mLoYFFSht6PcgF8D5tXJyMK8x4klOxPc5nh4rm2VdoG05JjUqqRMWP xoMHg30ZfOzxPpAIH6XwFomUkauIt+8NGTeA8DnIBdUfSvH7QQU5JcVkc7QUgnIsRDOz Z6aYQN6p/mV+9/UikkY2q4ePf0Ubf3i7z75gMFC57FVC50q2Fc/jDe0NaDtvdWUtQW/F L8GUPYOjVW1wH7eFscAdTOM49mVBK4/OSMnkHytOOeNJTdWL0SF7EkeNuvAa4gWXXiIc 3JXtiXgm5a8XXm5SxFGpRoij2VRsrAqVtScIqIX0pyWwcrcZltn56DJMyxkh/Ty9TcDY Jacg== 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:arc-authentication-results; bh=nK/5rtTwN48/jyA4wmyHJra0ZN11WKLAzthulCfQVLg=; b=DLmbtVMzVZBc2hthpabvZZmDSDiTRXnFmB1WG9x6bBrYZov1cDVorebZVdhoYT/Gng G3XNzu58PG3XGgz6YzJ1oBBrlRlGS/96jbrqLGSFmuCVNV8h9UH2K3Zf6ZmfRNBO8qgC u7MC92i0bjjXKnZFZffNh2F8pmHozzkzwsW2iNstxCfPpWfo0YPQt43Fu6A8Rx4WqZvH vwKe6FPc9omPgsywcJZkdm3oFxVzBshz0pD0Dmi1H9Y8wPh/WKejKOimr00pYI2C0ze2 f3/H/qur1prMjJpQTVGAqwLkOSNahu4TkHGy96YO6sw8tO1UAgqKdFoQpqlenkeiX0lf 3EDw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y75si2770491pfk.34.2018.04.19.00.26.09; Thu, 19 Apr 2018 00:26:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752332AbeDSHZK (ORCPT + 29 others); Thu, 19 Apr 2018 03:25:10 -0400 Received: from mx.socionext.com ([202.248.49.38]:32904 "EHLO mx.socionext.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751381AbeDSHZH (ORCPT ); Thu, 19 Apr 2018 03:25:07 -0400 Received: from unknown (HELO kinkan-ex.css.socionext.com) ([172.31.9.52]) by mx.socionext.com with ESMTP; 19 Apr 2018 16:25:06 +0900 Received: from mail.mfilter.local (m-filter-2 [10.213.24.62]) by kinkan-ex.css.socionext.com (Postfix) with ESMTP id 1B76C180B67; Thu, 19 Apr 2018 16:25:06 +0900 (JST) Received: from 172.31.9.51 (172.31.9.51) by m-FILTER with ESMTP; Thu, 19 Apr 2018 16:25:06 +0900 Received: from plum.e01.socionext.com (unknown [10.213.132.32]) by kinkan.css.socionext.com (Postfix) with ESMTP id 55A081A1279; Thu, 19 Apr 2018 16:25:05 +0900 (JST) From: Kunihiko Hayashi To: David Miller , netdev@vger.kernel.org Cc: Andrew Lunn , Florian Fainelli , Rob Herring , Mark Rutland , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Masahiro Yamada , Masami Hiramatsu , Jassi Brar , Kunihiko Hayashi Subject: [PATCH net-next v2 1/3] net: ethernet: ave: add multiple clocks and resets support as required property Date: Thu, 19 Apr 2018 16:24:53 +0900 Message-Id: <1524122695-19597-2-git-send-email-hayashi.kunihiko@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1524122695-19597-1-git-send-email-hayashi.kunihiko@socionext.com> References: <1524122695-19597-1-git-send-email-hayashi.kunihiko@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When the link is becoming up for Pro4 SoC, the kernel is stalled due to some missing clocks and resets. The AVE block for Pro4 is connected to the GIO bus in the SoC. Without its clock/reset, the access to the AVE register makes the system stall. In the same way, another MAC clock for Giga-bit Connection and the PHY clock are also required for Pro4 to activate the Giga-bit feature and to recognize the PHY. To satisfy these requirements, this patch adds support for multiple clocks and resets, and adds the clock-names and reset-names to the binding because we need to distinguish clock/reset for the AVE main block and the others. Also, make the resets a required property. Currently, "reset is optional" relies on that the bootloader or firmware has deasserted the reset before booting the kernel. Drivers should work without such expectation. Fixes: 4c270b55a5af ("net: ethernet: socionext: add AVE ethernet driver") Suggested-by: Masahiro Yamada Signed-off-by: Kunihiko Hayashi Reviewed-by: Rob Herring --- .../bindings/net/socionext,uniphier-ave4.txt | 13 ++- drivers/net/ethernet/socionext/sni_ave.c | 108 ++++++++++++++++----- 2 files changed, 96 insertions(+), 25 deletions(-) -- 2.7.4 diff --git a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt index 96398cc..85e0c49 100644 --- a/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt +++ b/Documentation/devicetree/bindings/net/socionext,uniphier-ave4.txt @@ -17,9 +17,18 @@ Required properties: - phy-handle: Should point to the external phy device. See ethernet.txt file in the same directory. - clocks: A phandle to the clock for the MAC. + For Pro4 SoC, that is "socionext,uniphier-pro4-ave4", + another MAC clock, GIO bus clock and PHY clock are also required. + - clock-names: Should contain + - "ether", "ether-gb", "gio", "ether-phy" for Pro4 SoC + - "ether" for others + - resets: A phandle to the reset control for the MAC. For Pro4 SoC, + GIO bus reset is also required. + - reset-names: Should contain + - "ether", "gio" for Pro4 SoC + - "ether" for others Optional properties: - - resets: A phandle to the reset control for the MAC. - local-mac-address: See ethernet.txt in the same directory. Required subnode: @@ -34,7 +43,9 @@ Example: interrupts = <0 66 4>; phy-mode = "rgmii"; phy-handle = <ðphy>; + clock-names = "ether"; clocks = <&sys_clk 6>; + reset-names = "ether"; resets = <&sys_rst 6>; local-mac-address = [00 00 00 00 00 00]; diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c index 0b3b7a4..52940bd 100644 --- a/drivers/net/ethernet/socionext/sni_ave.c +++ b/drivers/net/ethernet/socionext/sni_ave.c @@ -199,6 +199,9 @@ #define IS_DESC_64BIT(p) ((p)->data->is_desc_64bit) +#define AVE_MAX_CLKS 4 +#define AVE_MAX_RSTS 2 + enum desc_id { AVE_DESCID_RX, AVE_DESCID_TX, @@ -227,6 +230,8 @@ struct ave_desc_info { struct ave_soc_data { bool is_desc_64bit; + const char *clock_names[AVE_MAX_CLKS]; + const char *reset_names[AVE_MAX_RSTS]; }; struct ave_stats { @@ -245,8 +250,10 @@ struct ave_private { int phy_id; unsigned int desc_size; u32 msg_enable; - struct clk *clk; - struct reset_control *rst; + int nclks; + struct clk *clk[AVE_MAX_CLKS]; + int nrsts; + struct reset_control *rst[AVE_MAX_RSTS]; phy_interface_t phy_mode; struct phy_device *phydev; struct mii_bus *mdio; @@ -1153,18 +1160,23 @@ static int ave_init(struct net_device *ndev) struct device_node *np = dev->of_node; struct device_node *mdio_np; struct phy_device *phydev; - int ret; + int nc, nr, ret; /* enable clk because of hw access until ndo_open */ - ret = clk_prepare_enable(priv->clk); - if (ret) { - dev_err(dev, "can't enable clock\n"); - return ret; + for (nc = 0; nc < priv->nclks; nc++) { + ret = clk_prepare_enable(priv->clk[nc]); + if (ret) { + dev_err(dev, "can't enable clock\n"); + goto out_clk_disable; + } } - ret = reset_control_deassert(priv->rst); - if (ret) { - dev_err(dev, "can't deassert reset\n"); - goto out_clk_disable; + + for (nr = 0; nr < priv->nrsts; nr++) { + ret = reset_control_deassert(priv->rst[nr]); + if (ret) { + dev_err(dev, "can't deassert reset\n"); + goto out_reset_assert; + } } ave_global_reset(ndev); @@ -1207,9 +1219,11 @@ static int ave_init(struct net_device *ndev) out_mdio_unregister: mdiobus_unregister(priv->mdio); out_reset_assert: - reset_control_assert(priv->rst); + while (--nr >= 0) + reset_control_assert(priv->rst[nr]); out_clk_disable: - clk_disable_unprepare(priv->clk); + while (--nc >= 0) + clk_disable_unprepare(priv->clk[nc]); return ret; } @@ -1217,13 +1231,16 @@ static int ave_init(struct net_device *ndev) static void ave_uninit(struct net_device *ndev) { struct ave_private *priv = netdev_priv(ndev); + int i; phy_disconnect(priv->phydev); mdiobus_unregister(priv->mdio); /* disable clk because of hw access after ndo_stop */ - reset_control_assert(priv->rst); - clk_disable_unprepare(priv->clk); + for (i = 0; i < priv->nrsts; i++) + reset_control_assert(priv->rst[i]); + for (i = 0; i < priv->nclks; i++) + clk_disable_unprepare(priv->clk[i]); } static int ave_open(struct net_device *ndev) @@ -1527,8 +1544,9 @@ static int ave_probe(struct platform_device *pdev) struct resource *res; const void *mac_addr; void __iomem *base; + const char *name; + int i, irq, ret; u64 dma_mask; - int irq, ret; u32 ave_id; data = of_device_get_match_data(dev); @@ -1614,16 +1632,28 @@ static int ave_probe(struct platform_device *pdev) u64_stats_init(&priv->stats_tx.syncp); u64_stats_init(&priv->stats_rx.syncp); - priv->clk = devm_clk_get(dev, NULL); - if (IS_ERR(priv->clk)) { - ret = PTR_ERR(priv->clk); - goto out_free_netdev; + for (i = 0; i < AVE_MAX_CLKS; i++) { + name = priv->data->clock_names[i]; + if (!name) + break; + priv->clk[i] = devm_clk_get(dev, name); + if (IS_ERR(priv->clk[i])) { + ret = PTR_ERR(priv->clk[i]); + goto out_free_netdev; + } + priv->nclks++; } - priv->rst = devm_reset_control_get_optional_shared(dev, NULL); - if (IS_ERR(priv->rst)) { - ret = PTR_ERR(priv->rst); - goto out_free_netdev; + for (i = 0; i < AVE_MAX_RSTS; i++) { + name = priv->data->reset_names[i]; + if (!name) + break; + priv->rst[i] = devm_reset_control_get_shared(dev, name); + if (IS_ERR(priv->rst[i])) { + ret = PTR_ERR(priv->rst[i]); + goto out_free_netdev; + } + priv->nrsts++; } priv->mdio = devm_mdiobus_alloc(dev); @@ -1687,22 +1717,52 @@ static int ave_remove(struct platform_device *pdev) static const struct ave_soc_data ave_pro4_data = { .is_desc_64bit = false, + .clock_names = { + "gio", "ether", "ether-gb", "ether-phy", + }, + .reset_names = { + "gio", "ether", + }, }; static const struct ave_soc_data ave_pxs2_data = { .is_desc_64bit = false, + .clock_names = { + "ether", + }, + .reset_names = { + "ether", + }, }; static const struct ave_soc_data ave_ld11_data = { .is_desc_64bit = false, + .clock_names = { + "ether", + }, + .reset_names = { + "ether", + }, }; static const struct ave_soc_data ave_ld20_data = { .is_desc_64bit = true, + .clock_names = { + "ether", + }, + .reset_names = { + "ether", + }, }; static const struct ave_soc_data ave_pxs3_data = { .is_desc_64bit = false, + .clock_names = { + "ether", + }, + .reset_names = { + "ether", + }, }; static const struct of_device_id of_ave_match[] = { From patchwork Thu Apr 19 07:24:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kunihiko Hayashi X-Patchwork-Id: 133704 Delivered-To: patch@linaro.org Received: by 10.46.66.142 with SMTP id h14csp319221ljf; Thu, 19 Apr 2018 00:25:29 -0700 (PDT) X-Google-Smtp-Source: AIpwx4+3IXF+/qME/PoFGO4SM5HbqTUTO2RwPg0BttClyyNbbgfMxLWbVCs1YLrd0QSlSE4OYErJ X-Received: by 2002:a17:902:9a90:: with SMTP id w16-v6mr5044971plp.390.1524122728843; Thu, 19 Apr 2018 00:25:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524122728; cv=none; d=google.com; s=arc-20160816; b=pWw4CtxljYHgOJCfNKAyXHwVCztaISXSQHdYzutbgP+pUxSrKgq9VXXOVeoEUvt5aP UMpRxrgV4mWNLACEcosv+ypHGSVqRQi6mp97ECZ+IOp7GwTihADwAQ+1NIP1fFKQir9R QJQXVjHbXAWarB0PYAPXvnViJnsXc/P515OMLTUY/MCrf9g2iTPmKoG3z83HecqHzwFU tHzsvEwl4pcTp/Hw9QudRl+TOUJD2Q4MCzaYbcD3L9YUUoCCH1kYUoGAftwing79OsOL O/PL8oLOHAPgWEX/cmauCpLCf6jlMTl2xnGZBNortf9FXQjhzfCEC8+KsIsJWbxUSR+B L5Rg== 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:arc-authentication-results; bh=zp4+3x2nL2c1tYuy7GSNgjIg2fIcl3VirGqS5hnEo7o=; b=fUSgIYIcIxInPiLMla8qRYZ53cKFU2FpHoxewrTgIZTTzfHffF8Z5tMQp7/EnE+KYM 6Y6pjy4UJ+KCCrtiUAA0pZzkItwHSEKpBTfUN69EW36KtHkfqkwr3+F0CBqTsq78pawb ZrCGmjzGGy6sQsc++nZzB9CR5gKrIcyV1O+3z9t3V1YN6wOFQ4fo29D9ntwAS9IW1IMt TqIigm9p0t7rO8I16tRG0kNM6rFUb+9a+Enw2DEH8qwRKraHhTk50kveHohBAn5dOAEt stGFUYiLfEbGGQgWpMvsa2Wy4iHD6ph0jy1Op7LwSKvCKpfcoviiC0tHFVRcfEi1KrfY olcg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c26si2800900pfh.215.2018.04.19.00.25.28; Thu, 19 Apr 2018 00:25:28 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752671AbeDSHZZ (ORCPT + 29 others); Thu, 19 Apr 2018 03:25:25 -0400 Received: from mx.socionext.com ([202.248.49.38]:32904 "EHLO mx.socionext.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752273AbeDSHZL (ORCPT ); Thu, 19 Apr 2018 03:25:11 -0400 Received: from unknown (HELO kinkan-ex.css.socionext.com) ([172.31.9.52]) by mx.socionext.com with ESMTP; 19 Apr 2018 16:25:10 +0900 Received: from mail.mfilter.local (m-filter-2 [10.213.24.62]) by kinkan-ex.css.socionext.com (Postfix) with ESMTP id 3F86C180B67; Thu, 19 Apr 2018 16:25:10 +0900 (JST) Received: from 172.31.9.51 (172.31.9.51) by m-FILTER with ESMTP; Thu, 19 Apr 2018 16:25:10 +0900 Received: from plum.e01.socionext.com (unknown [10.213.132.32]) by kinkan.css.socionext.com (Postfix) with ESMTP id 828AB1A1279; Thu, 19 Apr 2018 16:25:08 +0900 (JST) From: Kunihiko Hayashi To: David Miller , netdev@vger.kernel.org Cc: Andrew Lunn , Florian Fainelli , Rob Herring , Mark Rutland , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Masahiro Yamada , Masami Hiramatsu , Jassi Brar , Kunihiko Hayashi Subject: [PATCH net-next v2 3/3] net: ethernet: ave: add support for phy-mode setting of system controller Date: Thu, 19 Apr 2018 16:24:55 +0900 Message-Id: <1524122695-19597-4-git-send-email-hayashi.kunihiko@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1524122695-19597-1-git-send-email-hayashi.kunihiko@socionext.com> References: <1524122695-19597-1-git-send-email-hayashi.kunihiko@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch adds support for specifying system controller that configures phy-mode setting. According to the DT property "phy-mode", it's necessary to configure the controller, which is used to choose the settings of the MAC suitable, for example, mdio pin connections, internal clocks, and so on. Supported phy-modes are SoC-dependent. The driver allows phy-mode to set "internal" if the SoC has a built-in PHY, and {"mii", "rmii", "rgmii"} if the SoC supports each mode. So we have to check whether the phy-mode is valid or not. This adds the following features for each SoC: - check whether the SoC supports the specified phy-mode - configure the controller accroding to phy-mode The DT property accepts one argument to distinguish them for multiple MAC instances. ethernet@65000000 { ... socionext,syscon-phy-mode = <&soc_glue 0>; }; ethernet@65200000 { ... socionext,syscon-phy-mode = <&soc_glue 1>; }; Signed-off-by: Kunihiko Hayashi Signed-off-by: Masahiro Yamada --- drivers/net/ethernet/socionext/Kconfig | 2 + drivers/net/ethernet/socionext/sni_ave.c | 150 ++++++++++++++++++++++++++++--- 2 files changed, 140 insertions(+), 12 deletions(-) -- 2.7.4 diff --git a/drivers/net/ethernet/socionext/Kconfig b/drivers/net/ethernet/socionext/Kconfig index 6bcfe27..b80048c 100644 --- a/drivers/net/ethernet/socionext/Kconfig +++ b/drivers/net/ethernet/socionext/Kconfig @@ -14,6 +14,8 @@ if NET_VENDOR_SOCIONEXT config SNI_AVE tristate "Socionext AVE ethernet support" depends on (ARCH_UNIPHIER || COMPILE_TEST) && OF + depends on HAS_IOMEM + select MFD_SYSCON select PHYLIB ---help--- Driver for gigabit ethernet MACs, called AVE, in the diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c index 52940bd..f7eccee 100644 --- a/drivers/net/ethernet/socionext/sni_ave.c +++ b/drivers/net/ethernet/socionext/sni_ave.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -197,6 +199,11 @@ #define AVE_INTM_COUNT 20 #define AVE_FORCE_TXINTCNT 1 +/* SG */ +#define SG_ETPINMODE 0x540 +#define SG_ETPINMODE_EXTPHY BIT(1) /* for LD11 */ +#define SG_ETPINMODE_RMII(ins) BIT(ins) + #define IS_DESC_64BIT(p) ((p)->data->is_desc_64bit) #define AVE_MAX_CLKS 4 @@ -228,12 +235,6 @@ struct ave_desc_info { struct ave_desc *desc; /* skb info related descriptor */ }; -struct ave_soc_data { - bool is_desc_64bit; - const char *clock_names[AVE_MAX_CLKS]; - const char *reset_names[AVE_MAX_RSTS]; -}; - struct ave_stats { struct u64_stats_sync syncp; u64 packets; @@ -257,6 +258,9 @@ struct ave_private { phy_interface_t phy_mode; struct phy_device *phydev; struct mii_bus *mdio; + struct regmap *regmap; + unsigned int pinmode_mask; + unsigned int pinmode_val; /* stats */ struct ave_stats stats_rx; @@ -279,6 +283,14 @@ struct ave_private { const struct ave_soc_data *data; }; +struct ave_soc_data { + bool is_desc_64bit; + const char *clock_names[AVE_MAX_CLKS]; + const char *reset_names[AVE_MAX_RSTS]; + int (*get_pinmode)(struct ave_private *priv, + phy_interface_t phy_mode, u32 arg); +}; + static u32 ave_desc_read(struct net_device *ndev, enum desc_id id, int entry, int offset) { @@ -1179,6 +1191,11 @@ static int ave_init(struct net_device *ndev) } } + ret = regmap_update_bits(priv->regmap, SG_ETPINMODE, + priv->pinmode_mask, priv->pinmode_val); + if (ret) + return ret; + ave_global_reset(ndev); mdio_np = of_get_child_by_name(np, "mdio"); @@ -1537,6 +1554,7 @@ static int ave_probe(struct platform_device *pdev) const struct ave_soc_data *data; struct device *dev = &pdev->dev; char buf[ETHTOOL_FWVERS_LEN]; + struct of_phandle_args args; phy_interface_t phy_mode; struct ave_private *priv; struct net_device *ndev; @@ -1559,12 +1577,6 @@ static int ave_probe(struct platform_device *pdev) dev_err(dev, "phy-mode not found\n"); return -EINVAL; } - if ((!phy_interface_mode_is_rgmii(phy_mode)) && - phy_mode != PHY_INTERFACE_MODE_RMII && - phy_mode != PHY_INTERFACE_MODE_MII) { - dev_err(dev, "phy-mode is invalid\n"); - return -EINVAL; - } irq = platform_get_irq(pdev, 0); if (irq < 0) { @@ -1656,6 +1668,26 @@ static int ave_probe(struct platform_device *pdev) priv->nrsts++; } + ret = of_parse_phandle_with_fixed_args(np, + "socionext,syscon-phy-mode", + 1, 0, &args); + if (ret) { + netdev_err(ndev, "can't get syscon-phy-mode property\n"); + goto out_free_netdev; + } + priv->regmap = syscon_node_to_regmap(args.np); + of_node_put(args.np); + if (IS_ERR(priv->regmap)) { + netdev_err(ndev, "can't map syscon-phy-mode\n"); + ret = PTR_ERR(priv->regmap); + goto out_free_netdev; + } + ret = priv->data->get_pinmode(priv, phy_mode, args.args[0]); + if (ret) { + netdev_err(ndev, "invalid phy-mode setting\n"); + goto out_free_netdev; + } + priv->mdio = devm_mdiobus_alloc(dev); if (!priv->mdio) { ret = -ENOMEM; @@ -1715,6 +1747,95 @@ static int ave_remove(struct platform_device *pdev) return 0; } +static int ave_pro4_get_pinmode(struct ave_private *priv, + phy_interface_t phy_mode, u32 arg) +{ + if (arg > 0) + return -EINVAL; + + priv->pinmode_mask = SG_ETPINMODE_RMII(0); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + priv->pinmode_val = SG_ETPINMODE_RMII(0); + break; + case PHY_INTERFACE_MODE_MII: + case PHY_INTERFACE_MODE_RGMII: + priv->pinmode_val = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ave_ld11_get_pinmode(struct ave_private *priv, + phy_interface_t phy_mode, u32 arg) +{ + if (arg > 0) + return -EINVAL; + + priv->pinmode_mask = SG_ETPINMODE_EXTPHY | SG_ETPINMODE_RMII(0); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_INTERNAL: + priv->pinmode_val = 0; + break; + case PHY_INTERFACE_MODE_RMII: + priv->pinmode_val = SG_ETPINMODE_EXTPHY | SG_ETPINMODE_RMII(0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ave_ld20_get_pinmode(struct ave_private *priv, + phy_interface_t phy_mode, u32 arg) +{ + if (arg > 0) + return -EINVAL; + + priv->pinmode_mask = SG_ETPINMODE_RMII(0); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + priv->pinmode_val = SG_ETPINMODE_RMII(0); + break; + case PHY_INTERFACE_MODE_RGMII: + priv->pinmode_val = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ave_pxs3_get_pinmode(struct ave_private *priv, + phy_interface_t phy_mode, u32 arg) +{ + if (arg > 1) + return -EINVAL; + + priv->pinmode_mask = SG_ETPINMODE_RMII(arg); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + priv->pinmode_val = SG_ETPINMODE_RMII(arg); + break; + case PHY_INTERFACE_MODE_RGMII: + priv->pinmode_val = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + static const struct ave_soc_data ave_pro4_data = { .is_desc_64bit = false, .clock_names = { @@ -1723,6 +1844,7 @@ static const struct ave_soc_data ave_pro4_data = { .reset_names = { "gio", "ether", }, + .get_pinmode = ave_pro4_get_pinmode, }; static const struct ave_soc_data ave_pxs2_data = { @@ -1733,6 +1855,7 @@ static const struct ave_soc_data ave_pxs2_data = { .reset_names = { "ether", }, + .get_pinmode = ave_pro4_get_pinmode, }; static const struct ave_soc_data ave_ld11_data = { @@ -1743,6 +1866,7 @@ static const struct ave_soc_data ave_ld11_data = { .reset_names = { "ether", }, + .get_pinmode = ave_ld11_get_pinmode, }; static const struct ave_soc_data ave_ld20_data = { @@ -1753,6 +1877,7 @@ static const struct ave_soc_data ave_ld20_data = { .reset_names = { "ether", }, + .get_pinmode = ave_ld20_get_pinmode, }; static const struct ave_soc_data ave_pxs3_data = { @@ -1763,6 +1888,7 @@ static const struct ave_soc_data ave_pxs3_data = { .reset_names = { "ether", }, + .get_pinmode = ave_pxs3_get_pinmode, }; static const struct of_device_id of_ave_match[] = {