From patchwork Fri Oct 21 08:44:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neil Armstrong X-Patchwork-Id: 9388231 X-Patchwork-Delegate: neil.armstrong@linaro.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 68B1D60231 for ; Fri, 21 Oct 2016 08:44:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5984529F18 for ; Fri, 21 Oct 2016 08:44:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E05229F1C; Fri, 21 Oct 2016 08:44:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_LOW,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mx1.tuxfamily.net (mail.tuxfamily.net [212.85.158.8]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id CFF0429F18 for ; Fri, 21 Oct 2016 08:44:56 +0000 (UTC) Received: from listengine (helo=tuxfamily.org) by mx1.tuxfamily.net with local-bsmtp (Exim 4.84_2) (envelope-from ) id 1bxVRe-00047H-1E for patchwork-linux-oxnas@patchwork.kernel.org; Fri, 21 Oct 2016 10:44:54 +0200 Received: from mail-qk0-x236.google.com ([2607:f8b0:400d:c09::236]) by mx1.tuxfamily.net with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84_2) (envelope-from ) id 1bxVRb-00046t-4J for linux-oxnas@lists.tuxfamily.org; Fri, 21 Oct 2016 10:44:51 +0200 Received: by mail-qk0-x236.google.com with SMTP id n189so138528857qke.0 for ; Fri, 21 Oct 2016 01:44:50 -0700 (PDT) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=zfWnAUC17Dw62a/5koEU9ppDFEd5LJOFnaUEW2AqA9g=; b=gIPf5x+a6GUHoI2tyrdlA/af+5q0IlIHRAu17fZ49XPP5RrFYXgJSQYnIGSuqXMARK 51F8yuSVACLNZql3yb0aarNbR8Z7X+Nj1QWd0m73oXOwgj/iQ8MEiTmn2pDpMr26Wo4F FK1lXqxardUax1mPir/1AqBM8V4iCJ43Q95/GGaJEmFyQ9pxn8QTSzyY5om05YiFJzyW C3CJGtIIy7F0FXKEbbdHVWtDQK8NrjOkCuHpixZt7U5IEUGWopTLiBdCeD9C40kAYGRC K6ytLcb7F/bBs2dhuEDj0aUgP5eLvMCG1dbLlA0RFkxd+JzeLwY9tBgXPOtW2/CHw0N8 F+FA== X-Google-Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=zfWnAUC17Dw62a/5koEU9ppDFEd5LJOFnaUEW2AqA9g=; b=FUfMUDT4c+aIFj36H6JrleF8iIWzezvow1SyR8PFtHcyOznY0tdI7tBbL0YmUNGJfu kgJ4QCrvXZ0iA6yaRl1jShxKM6JFpl4u5qtliwPw2uKwD7ZEC1rDzpKO9HoI4b3D1CaA +A0kLWZDxO0Um2mwbjhEXeF6IUrKkwHCIQvYIV+KBnlbzqT+Ovs0WldvU6BJYOHxrSNT zeHvl5QNcvpcXuwMtTlPO1hqhNTPXmFGHttCAC3hWpfruPC+Q4Vdw5MCmQAs/wSqrHZw DBhzYNutT6Jwpj4eC4PmUkpydzvuakk/yyInfNmoLBzBlx4QCW6W1actQHHYjGXKTDUO 3MKA== X-GM-Message-State: ABUngvekrd+te6BK5cpse3RfjYbgtUKUBRG3iq08Hz6b349CQYyeTeV+QF7/55BGZLrmsdbq X-Received: by 10.194.28.5 with SMTP id x5mr3143118wjg.63.1477039489650; Fri, 21 Oct 2016 01:44:49 -0700 (PDT) Received: from build.net (build.baylibre.com. [37.187.146.144]) by smtp.gmail.com with ESMTPSA id rv12sm1694172wjb.29.2016.10.21.01.44.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Oct 2016 01:44:49 -0700 (PDT) From: Neil Armstrong To: peppe.cavallaro@st.com, alexandre.torgue@st.com CC: Neil Armstrong , netdev@vger.kernel.org, linux-oxnas@lists.tuxfamily.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [linux-oxnas] [PATCH] net: stmmac: Add OXNAS Glue Driver Date: Fri, 21 Oct 2016 10:44:45 +0200 Message-ID: <20161021084445.24989-1-narmstrong@baylibre.com> X-Mailer: git-send-email 2.9.3 List-Unsubscribe: List-Subscribe: List-Help: List-Software: Listengine, VHFFS 4.7-dev-4c39578052 List-ID: List-Post: List-Archive: Precedence: list Reply-To: linux-oxnas@lists.tuxfamily.org X-Virus-Scanned: ClamAV using ClamSMTP Add Synopsys Designware MAC Glue layer for the Oxford Semiconductor OX820. Signed-off-by: Neil Armstrong Acked-by: Joachim Eastwood --- .../devicetree/bindings/net/oxnas-dwmac.txt | 44 +++++ drivers/net/ethernet/stmicro/stmmac/Kconfig | 11 ++ drivers/net/ethernet/stmicro/stmmac/Makefile | 1 + drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 219 +++++++++++++++++++++ 4 files changed, 275 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/oxnas-dwmac.txt create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c Changes since RFC at https://patchwork.kernel.org/patch/9387257 : - Drop init/exit callbacks - Implement proper remove and PM callback - Call init from probe - Disable/Unprepare clock if stmmac probe fails diff --git a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt new file mode 100644 index 0000000..5d2696c --- /dev/null +++ b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt @@ -0,0 +1,44 @@ +* Oxford Semiconductor OXNAS DWMAC Ethernet controller + +The device inherits all the properties of the dwmac/stmmac devices +described in the file stmmac.txt in the current directory with the +following changes. + +Required properties on all platforms: + +- compatible: Depending on the platform this should be one of: + - "oxsemi,ox820-dwmac" + Additionally "snps,dwmac" and any applicable more + detailed version number described in net/stmmac.txt + should be used. + +- reg: The first register range should be the one of the DWMAC + controller. + +- clocks: Should contain phandles to the following clocks +- clock-names: Should contain the following: + - "stmmaceth" - see stmmac.txt + - "gmac" - peripheral gate clock + +- oxsemi,sys-ctrl: a phandle to the system controller syscon node + +Example : + +etha: ethernet@40400000 { + compatible = "oxsemi,ox820-dwmac", "snps,dwmac"; + reg = <0x40400000 0x2000>; + interrupts = , + ; + interrupt-names = "macirq", "eth_wake_irq"; + mac-address = [000000000000]; /* Filled in by U-Boot */ + phy-mode = "rgmii"; + + clocks = <&stdclk CLK_820_ETHA>, <&gmacclk>; + clock-names = "gmac", "stmmaceth"; + resets = <&reset RESET_MAC>; + + /* Regmap for sys registers */ + oxsemi,sys-ctrl = <&sys>; + + status = "disabled"; +}; diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index 3818c5e..27ed913 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -62,6 +62,7 @@ config DWMAC_MESON tristate "Amlogic Meson dwmac support" default ARCH_MESON depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST) + select MFD_SYSCON help Support for Ethernet controller on Amlogic Meson SoCs. @@ -69,6 +70,16 @@ config DWMAC_MESON the stmmac device driver. This driver is used for Meson6, Meson8, Meson8b and GXBB SoCs. +config DWMAC_OXNAS + tristate "Oxford Semiconductor OXNAS dwmac support" + default ARCH_OXNAS + depends on OF && COMMON_CLK && (ARCH_OXNAS || COMPILE_TEST) + help + Support for Ethernet controller on Oxford Semiconductor OXNAS SoCs. + + This selects the Oxford Semiconductor OXNASSoC glue layer support for + the stmmac device driver. This driver is used for OX820. + config DWMAC_ROCKCHIP tristate "Rockchip dwmac support" default ARCH_ROCKCHIP diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 5d6ece5..8f83a86 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o obj-$(CONFIG_DWMAC_IPQ806X) += dwmac-ipq806x.o obj-$(CONFIG_DWMAC_LPC18XX) += dwmac-lpc18xx.o obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o +obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c new file mode 100644 index 0000000..40fd845 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c @@ -0,0 +1,219 @@ +/* + * Oxford Semiconductor OXNAS DWMAC glue layer + * + * Copyright (C) 2016 Neil Armstrong + * Copyright (C) 2014 Daniel Golle + * Copyright (C) 2013 Ma Haijun + * Copyright (C) 2012 John Crispin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +/* System Control regmap offsets */ +#define OXNAS_DWMAC_CTRL_REGOFFSET 0x78 +#define OXNAS_DWMAC_DELAY_REGOFFSET 0x100 + +/* Control Register */ +#define DWMAC_CKEN_RX_IN 14 +#define DWMAC_CKEN_RXN_OUT 13 +#define DWMAC_CKEN_RX_OUT 12 +#define DWMAC_CKEN_TX_IN 10 +#define DWMAC_CKEN_TXN_OUT 9 +#define DWMAC_CKEN_TX_OUT 8 +#define DWMAC_RX_SOURCE 7 +#define DWMAC_TX_SOURCE 6 +#define DWMAC_LOW_TX_SOURCE 4 +#define DWMAC_AUTO_TX_SOURCE 3 +#define DWMAC_RGMII 2 +#define DWMAC_SIMPLE_MUX 1 +#define DWMAC_CKEN_GTX 0 + +/* Delay register */ +#define DWMAC_TX_VARDELAY_SHIFT 0 +#define DWMAC_TXN_VARDELAY_SHIFT 8 +#define DWMAC_RX_VARDELAY_SHIFT 16 +#define DWMAC_RXN_VARDELAY_SHIFT 24 +#define DWMAC_TX_VARDELAY(d) ((d) << DWMAC_TX_VARDELAY_SHIFT) +#define DWMAC_TXN_VARDELAY(d) ((d) << DWMAC_TXN_VARDELAY_SHIFT) +#define DWMAC_RX_VARDELAY(d) ((d) << DWMAC_RX_VARDELAY_SHIFT) +#define DWMAC_RXN_VARDELAY(d) ((d) << DWMAC_RXN_VARDELAY_SHIFT) + +struct oxnas_dwmac { + struct device *dev; + struct clk *clk; + struct regmap *regmap; +}; + +static int oxnas_dwmac_init(struct oxnas_dwmac *dwmac) +{ + unsigned int value; + int ret; + + /* Reset HW here before changing the glue configuration */ + ret = device_reset(dwmac->dev); + if (ret) + return ret; + + clk_prepare_enable(dwmac->clk); + + ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value); + if (ret < 0) + return ret; + + /* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */ + value |= BIT(DWMAC_CKEN_GTX); + /* Use simple mux for 25/125 Mhz clock switching */ + value |= BIT(DWMAC_SIMPLE_MUX); + /* set auto switch tx clock source */ + value |= BIT(DWMAC_AUTO_TX_SOURCE); + /* enable tx & rx vardelay */ + value |= BIT(DWMAC_CKEN_TX_OUT); + value |= BIT(DWMAC_CKEN_TXN_OUT); + value |= BIT(DWMAC_CKEN_TX_IN); + value |= BIT(DWMAC_CKEN_RX_OUT); + value |= BIT(DWMAC_CKEN_RXN_OUT); + value |= BIT(DWMAC_CKEN_RX_IN); + regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value); + + /* set tx & rx vardelay */ + value = DWMAC_TX_VARDELAY(4); + value |= DWMAC_TXN_VARDELAY(2); + value |= DWMAC_RX_VARDELAY(10); + value |= DWMAC_RXN_VARDELAY(8); + regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value); + + return 0; +} + +static int oxnas_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct device_node *sysctrl; + struct oxnas_dwmac *dwmac; + int ret; + + sysctrl = of_parse_phandle(pdev->dev.of_node, "oxsemi,sys-ctrl", 0); + if (!sysctrl) { + dev_err(&pdev->dev, "failed to get sys-ctrl node\n"); + return -EINVAL; + } + + ret = stmmac_get_platform_resources(pdev, &stmmac_res); + if (ret) + return ret; + + plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); + if (IS_ERR(plat_dat)) + return PTR_ERR(plat_dat); + + dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); + if (!dwmac) + return -ENOMEM; + + dwmac->dev = &pdev->dev; + plat_dat->bsp_priv = dwmac; + + dwmac->regmap = syscon_node_to_regmap(sysctrl); + if (IS_ERR(dwmac->regmap)) { + dev_err(&pdev->dev, "failed to have sysctrl regmap\n"); + return PTR_ERR(dwmac->regmap); + } + + dwmac->clk = devm_clk_get(&pdev->dev, "gmac"); + if (IS_ERR(dwmac->clk)) + return PTR_ERR(dwmac->clk); + + ret = oxnas_dwmac_init(dwmac); + if (ret) + return ret; + + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + if (ret) + clk_disable_unprepare(dwmac->clk); + + return ret; +} + +static int oxnas_dwmac_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(ndev); + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv; + int ret = stmmac_dvr_remove(&pdev->dev); + + clk_disable_unprepare(dwmac->clk); + + return ret; +} + +#ifdef CONFIG_PM_SLEEP +static int oxnas_dwmac_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv; + int ret; + + ret = stmmac_suspend(dev); + clk_disable_unprepare(dwmac->clk); + + return ret; +} + +static int oxnas_dwmac_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + struct oxnas_dwmac *dwmac = priv->plat->bsp_priv; + int ret; + + ret = oxnas_dwmac_init(dwmac); + if (ret) + return ret; + + ret = stmmac_resume(dev); + + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +static SIMPLE_DEV_PM_OPS(oxnas_dwmac_pm_ops, + oxnas_dwmac_suspend, oxnas_dwmac_resume); + +static const struct of_device_id oxnas_dwmac_match[] = { + { .compatible = "oxsemi,ox820-dwmac" }, + { } +}; +MODULE_DEVICE_TABLE(of, oxnas_dwmac_match); + +static struct platform_driver oxnas_dwmac_driver = { + .probe = oxnas_dwmac_probe, + .remove = oxnas_dwmac_remove, + .driver = { + .name = "oxnas-dwmac", + .pm = &oxnas_dwmac_pm_ops, + .of_match_table = oxnas_dwmac_match, + }, +}; +module_platform_driver(oxnas_dwmac_driver); + +MODULE_AUTHOR("Neil Armstrong "); +MODULE_DESCRIPTION("Oxford Semiconductor OXNAS DWMAC glue layer"); +MODULE_LICENSE("GPL v2");