From patchwork Mon Apr 25 11:53:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre TORGUE X-Patchwork-Id: 614405 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3qtl6m1XlTz9t5X for ; Mon, 25 Apr 2016 21:56:00 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=JoqiWuUw; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932279AbcDYLy3 (ORCPT ); Mon, 25 Apr 2016 07:54:29 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:36239 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932124AbcDYLy1 (ORCPT ); Mon, 25 Apr 2016 07:54:27 -0400 Received: by mail-wm0-f65.google.com with SMTP id w143so20376578wmw.3; Mon, 25 Apr 2016 04:54:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q1u1ZnQH6tpZNLbS5qOoQ5uJ1ASe1XuhEWo2oL9S5zM=; b=JoqiWuUwhgKNhTOMNsVrM4Wu9hkMJKR8y+5rau55xpuiBqVdTEoqp7cBkohuGBazO4 FCHAwUwz3zjbPK+9lX7CJG8hBodsCmfXKDbqH584FA6nmiIkYHa1zY5A3WcDguKV24pu q4Hbant+J3K3/Yw9jD3HVGkjs/I8z96oPmr+CemdcKSqgfg3DTQ75EoIwL0vP6FAfySb 3dVcUp0Uv0VKMSanCM19kNV1GbSnFlKR46wdaxP0CbNPtE6xis1hAx8u9gPbiSINyShb lkc5pLptS85x7X3CMY+NYPy8lXCD7RgjhpBTEx3jbwVkzLzEmWtN7+NW0ZDcwwJgZ41h b2GQ== 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:in-reply-to :references; bh=Q1u1ZnQH6tpZNLbS5qOoQ5uJ1ASe1XuhEWo2oL9S5zM=; b=cjvrurwq8WmoK3AsuUH931J4D2tr2lHqH/f8KF7pW49GqOUUi00Yggqip1BhjNCZ3i 6EtkggaTP3Om7M4YF/LxqODiGS2Qj01E5BbfMs7AI0ckHvhJap73Ptwm2hcCA20NgnOJ LFj/BJgq1aX17ilLPytkp0EUIu+z+YeplSHxks8pmv8Pp/H3bZ7Wkdx9Wx9C9J4xs7Zh 34mkZb77eDNzDySfyBm3iPkDBITD6tpEXB99Hiy5Grh/pwDWgLP2zBeI7PFV++ICKk/q AAMLyN3RhDslcNmvLghQ7a/J+6CbnBjYlqMJ1c2+VtQIaShsOqqJzz3AEQpV0via1w1y Z4tQ== X-Gm-Message-State: AOPr4FVmQ6fOjMPfl63sXlEKhwoETA7S7DkuOxVPXU9vSHwMgG+DmHpuzkdCnX6OFX8g3g== X-Received: by 10.28.94.5 with SMTP id s5mr12128324wmb.26.1461585265227; Mon, 25 Apr 2016 04:54:25 -0700 (PDT) Received: from LMENX29N.st.com. ([80.12.35.29]) by smtp.gmail.com with ESMTPSA id t206sm18349459wmt.21.2016.04.25.04.54.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 25 Apr 2016 04:54:24 -0700 (PDT) From: Alexandre TORGUE To: Maxime Coquelin , Giuseppe Cavallaro , netdev@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, robh@kernel.org, manabian@gmail.com, wens@csie.org Subject: [PATCH v6 1/6] net: ethernet: dwmac: add Ethernet glue logic for stm32 chip Date: Mon, 25 Apr 2016 13:53:57 +0200 Message-Id: <1461585242-32401-2-git-send-email-alexandre.torgue@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1461585242-32401-1-git-send-email-alexandre.torgue@gmail.com> References: <1461585242-32401-1-git-send-email-alexandre.torgue@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org stm324xx family chips support Synopsys MAC 3.510 IP. This patch adds settings for logical glue logic: -clocks -mode selection MII or RMII. Reviewed-by: Joachim Eastwood Acked-by: Giuseppe Cavallaro Tested-by: Maxime Coquelin Signed-off-by: Alexandre TORGUE diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig index cec147d..235d679 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -104,6 +104,18 @@ config DWMAC_STI device driver. This driver is used on for the STi series SOCs GMAC ethernet controller. +config DWMAC_STM32 + tristate "STM32 DWMAC support" + default ARCH_STM32 + depends on OF && HAS_IOMEM + select MFD_SYSCON + ---help--- + Support for ethernet controller on STM32 SOCs. + + This selects STM32 SoC glue layer support for the stmmac + device driver. This driver is used on for the STM32 series + SOCs GMAC ethernet controller. + config DWMAC_SUNXI tristate "Allwinner GMAC support" default ARCH_SUNXI diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 0fb362d..8828ada 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-socfpga.o obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o +obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o obj-$(CONFIG_DWMAC_SUNXI) += dwmac-sunxi.o obj-$(CONFIG_DWMAC_GENERIC) += dwmac-generic.o stmmac-platform-objs:= stmmac_platform.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c new file mode 100644 index 0000000..5c2afe5 --- /dev/null +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -0,0 +1,193 @@ +/* + * dwmac-stm32.c - DWMAC Specific Glue layer for STM32 MCU + * + * Copyright (C) Alexandre Torgue 2015 + * Author: Alexandre Torgue + * License terms: GNU General Public License (GPL), version 2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stmmac_platform.h" + +#define MII_PHY_SEL_MASK BIT(23) + +struct stm32_dwmac { + struct clk *clk_tx; + struct clk *clk_rx; + u32 mode_reg; /* MAC glue-logic mode register */ + struct regmap *regmap; + u32 speed; +}; + +static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) +{ + struct stm32_dwmac *dwmac = plat_dat->bsp_priv; + u32 reg = dwmac->mode_reg; + u32 val; + int ret; + + val = (plat_dat->interface == PHY_INTERFACE_MODE_MII) ? 0 : 1; + ret = regmap_update_bits(dwmac->regmap, reg, MII_PHY_SEL_MASK, val); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_tx); + if (ret) + return ret; + + ret = clk_prepare_enable(dwmac->clk_rx); + if (ret) + clk_disable_unprepare(dwmac->clk_tx); + + return ret; +} + +static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) +{ + clk_disable_unprepare(dwmac->clk_tx); + clk_disable_unprepare(dwmac->clk_rx); +} + +static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac, + struct device *dev) +{ + struct device_node *np = dev->of_node; + int err; + + /* Get TX/RX clocks */ + dwmac->clk_tx = devm_clk_get(dev, "mac-clk-tx"); + if (IS_ERR(dwmac->clk_tx)) { + dev_err(dev, "No tx clock provided...\n"); + return PTR_ERR(dwmac->clk_tx); + } + dwmac->clk_rx = devm_clk_get(dev, "mac-clk-rx"); + if (IS_ERR(dwmac->clk_rx)) { + dev_err(dev, "No rx clock provided...\n"); + return PTR_ERR(dwmac->clk_rx); + } + + /* Get mode register */ + dwmac->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscon"); + if (IS_ERR(dwmac->regmap)) + return PTR_ERR(dwmac->regmap); + + err = of_property_read_u32_index(np, "st,syscon", 1, &dwmac->mode_reg); + if (err) + dev_err(dev, "Can't get sysconfig mode offset (%d)\n", err); + + return err; +} + +static int stm32_dwmac_probe(struct platform_device *pdev) +{ + struct plat_stmmacenet_data *plat_dat; + struct stmmac_resources stmmac_res; + struct stm32_dwmac *dwmac; + int ret; + + 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; + + ret = stm32_dwmac_parse_data(dwmac, &pdev->dev); + if (ret) { + dev_err(&pdev->dev, "Unable to parse OF data\n"); + return ret; + } + + plat_dat->bsp_priv = dwmac; + + ret = stm32_dwmac_init(plat_dat); + if (ret) + return ret; + + ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); + if (ret) + stm32_dwmac_clk_disable(dwmac); + + return ret; +} + +static int stm32_dwmac_remove(struct platform_device *pdev) +{ + struct net_device *ndev = platform_get_drvdata(pdev); + struct stmmac_priv *priv = netdev_priv(ndev); + int ret = stmmac_dvr_remove(ndev); + + stm32_dwmac_clk_disable(priv->plat->bsp_priv); + + return ret; +} + +#ifdef CONFIG_PM_SLEEP +static int stm32_dwmac_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + int ret; + + ret = stmmac_suspend(ndev); + stm32_dwmac_clk_disable(priv->plat->bsp_priv); + + return ret; +} + +static int stm32_dwmac_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct stmmac_priv *priv = netdev_priv(ndev); + int ret; + + ret = stm32_dwmac_init(priv->plat); + if (ret) + return ret; + + ret = stmmac_resume(ndev); + + return ret; +} +#endif /* CONFIG_PM_SLEEP */ + +SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_ops, stm32_dwmac_suspend, stm32_dwmac_resume); + +static const struct of_device_id stm32_dwmac_match[] = { + { .compatible = "st,stm32-dwmac"}, + { } +}; +MODULE_DEVICE_TABLE(of, stm32_dwmac_match); + +static struct platform_driver stm32_dwmac_driver = { + .probe = stm32_dwmac_probe, + .remove = stm32_dwmac_remove, + .driver = { + .name = "stm32-dwmac", + .pm = &stm32_dwmac_pm_ops, + .of_match_table = stm32_dwmac_match, + }, +}; +module_platform_driver(stm32_dwmac_driver); + +MODULE_AUTHOR("Alexandre Torgue "); +MODULE_DESCRIPTION("STMicroelectronics MCU DWMAC Specific Glue layer"); +MODULE_LICENSE("GPL v2");