From patchwork Mon Oct 10 12:57:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mugunthan V N X-Patchwork-Id: 680390 X-Patchwork-Delegate: joe.hershberger@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 3st0Xc2ttXz9s3s for ; Mon, 10 Oct 2016 23:57:52 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0CADAB3813; Mon, 10 Oct 2016 14:57:44 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Gd_YfYi8bVxK; Mon, 10 Oct 2016 14:57:43 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A54024B77D; Mon, 10 Oct 2016 14:57:37 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9A49C4BA35 for ; Mon, 10 Oct 2016 14:57:31 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ph84Lz46KLEw for ; Mon, 10 Oct 2016 14:57:31 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from devils.ext.ti.com (devils.ext.ti.com [198.47.26.153]) by theia.denx.de (Postfix) with ESMTPS id 414CF4B77D for ; Mon, 10 Oct 2016 14:57:27 +0200 (CEST) Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by devils.ext.ti.com (8.13.7/8.13.7) with ESMTP id u9ACvMG0026595; Mon, 10 Oct 2016 07:57:22 -0500 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id u9ACvM9R006326; Mon, 10 Oct 2016 07:57:22 -0500 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.294.0; Mon, 10 Oct 2016 07:57:21 -0500 Received: from a0131834lt.india.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id u9ACv7gk024102; Mon, 10 Oct 2016 07:57:18 -0500 From: Mugunthan V N To: Date: Mon, 10 Oct 2016 18:27:04 +0530 Message-ID: <20161010125704.1058-4-mugunthanvnm@ti.com> X-Mailer: git-send-email 2.10.0.372.g6fe1b14 In-Reply-To: <20161010125704.1058-1-mugunthanvnm@ti.com> References: <20161010125704.1058-1-mugunthanvnm@ti.com> MIME-Version: 1.0 Cc: Tom Rini , Joe Hershberger , Fabio Estevam Subject: [U-Boot] [PATCH 3/3] driver: net: cpsw: add support for RGMII id mode support and RMII clock source selection X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.15 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" cpsw driver supports only selection of phy mode in control module but control module has more setting like RGMII ID mode selection, RMII clock source selection. So ported to cpsw-phy-sel driver from kernel to u-boot. Signed-off-by: Mugunthan V N Acked-by: Joe Hershberger --- drivers/net/cpsw.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++----- include/cpsw.h | 1 + 2 files changed, 140 insertions(+), 14 deletions(-) diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c index d17505e..1441f44 100644 --- a/drivers/net/cpsw.c +++ b/drivers/net/cpsw.c @@ -225,6 +225,18 @@ struct cpdma_chan { void *hdp, *cp, *rxfree; }; +/* AM33xx SoC specific definitions for the CONTROL port */ +#define AM33XX_GMII_SEL_MODE_MII 0 +#define AM33XX_GMII_SEL_MODE_RMII 1 +#define AM33XX_GMII_SEL_MODE_RGMII 2 + +#define AM33XX_GMII_SEL_RGMII1_IDMODE BIT(4) +#define AM33XX_GMII_SEL_RGMII2_IDMODE BIT(5) +#define AM33XX_GMII_SEL_RMII1_IO_CLK_EN BIT(6) +#define AM33XX_GMII_SEL_RMII2_IO_CLK_EN BIT(7) + +#define GMII_SEL_MODE_MASK 0x3 + #define desc_write(desc, fld, val) __raw_writel((u32)(val), &(desc)->fld) #define desc_read(desc, fld) __raw_readl(&(desc)->fld) #define desc_read_ptr(desc, fld) ((void *)__raw_readl(&(desc)->fld)) @@ -1150,12 +1162,129 @@ static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node) false); } +static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv, + phy_interface_t phy_mode) +{ + u32 reg; + u32 mask; + u32 mode = 0; + bool rgmii_id = false; + int slave = priv->data.active_slave; + + reg = readl(priv->data.gmii_sel); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + mode = AM33XX_GMII_SEL_MODE_RMII; + break; + + case PHY_INTERFACE_MODE_RGMII: + mode = AM33XX_GMII_SEL_MODE_RGMII; + break; + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + mode = AM33XX_GMII_SEL_MODE_RGMII; + rgmii_id = true; + break; + + case PHY_INTERFACE_MODE_MII: + default: + mode = AM33XX_GMII_SEL_MODE_MII; + break; + }; + + mask = GMII_SEL_MODE_MASK << (slave * 2) | BIT(slave + 6); + mode <<= slave * 2; + + if (priv->data.rmii_clock_external) { + if (slave == 0) + mode |= AM33XX_GMII_SEL_RMII1_IO_CLK_EN; + else + mode |= AM33XX_GMII_SEL_RMII2_IO_CLK_EN; + } + + if (rgmii_id) { + if (slave == 0) + mode |= AM33XX_GMII_SEL_RGMII1_IDMODE; + else + mode |= AM33XX_GMII_SEL_RGMII2_IDMODE; + } + + reg &= ~mask; + reg |= mode; + + writel(reg, priv->data.gmii_sel); +} + +static void cpsw_gmii_sel_dra7xx(struct cpsw_priv *priv, + phy_interface_t phy_mode) +{ + u32 reg; + u32 mask; + u32 mode = 0; + int slave = priv->data.active_slave; + + reg = readl(priv->data.gmii_sel); + + switch (phy_mode) { + case PHY_INTERFACE_MODE_RMII: + mode = AM33XX_GMII_SEL_MODE_RMII; + break; + + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + case PHY_INTERFACE_MODE_RGMII_RXID: + case PHY_INTERFACE_MODE_RGMII_TXID: + mode = AM33XX_GMII_SEL_MODE_RGMII; + break; + + case PHY_INTERFACE_MODE_MII: + default: + mode = AM33XX_GMII_SEL_MODE_MII; + break; + }; + + switch (slave) { + case 0: + mask = GMII_SEL_MODE_MASK; + break; + case 1: + mask = GMII_SEL_MODE_MASK << 4; + mode <<= 4; + break; + default: + dev_err(priv->dev, "invalid slave number...\n"); + return; + } + + if (priv->data.rmii_clock_external) + dev_err(priv->dev, "RMII External clock is not supported\n"); + + reg &= ~mask; + reg |= mode; + + writel(reg, priv->data.gmii_sel); +} + +static void cpsw_phy_sel(struct cpsw_priv *priv, const char *compat, + phy_interface_t phy_mode) +{ + if (!strcmp(compat, "ti,am3352-cpsw-phy-sel")) + cpsw_gmii_sel_am3352(priv, phy_mode); + if (!strcmp(compat, "ti,am43xx-cpsw-phy-sel")) + cpsw_gmii_sel_am3352(priv, phy_mode); + else if (!strcmp(compat, "ti,dra7xx-cpsw-phy-sel")) + cpsw_gmii_sel_dra7xx(priv, phy_mode); +} + static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct cpsw_priv *priv = dev_get_priv(dev); struct gpio_desc *mode_gpios; const char *phy_mode; + const char *phy_sel_compat = NULL; const void *fdt = gd->fdt_blob; int node = dev->of_offset; int subnode; @@ -1271,6 +1400,13 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) error("Not able to get gmii_sel reg address\n"); return -ENOENT; } + + phy_sel_compat = fdt_getprop(fdt, subnode, "compatible", + NULL); + if (!phy_sel_compat) { + error("Not able to get gmii_sel compatible\n"); + return -ENOENT; + } } } @@ -1293,20 +1429,9 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); return -EINVAL; } - switch (pdata->phy_interface) { - case PHY_INTERFACE_MODE_MII: - writel(MII_MODE_ENABLE, priv->data.gmii_sel); - break; - case PHY_INTERFACE_MODE_RMII: - writel(RMII_MODE_ENABLE, priv->data.gmii_sel); - break; - case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: - case PHY_INTERFACE_MODE_RGMII_TXID: - writel(RGMII_MODE_ENABLE, priv->data.gmii_sel); - break; - } + + /* Select phy interface in control module */ + cpsw_phy_sel(priv, phy_sel_compat, pdata->phy_interface); return 0; } diff --git a/include/cpsw.h b/include/cpsw.h index 257d12a..f135e7b 100644 --- a/include/cpsw.h +++ b/include/cpsw.h @@ -48,6 +48,7 @@ struct cpsw_platform_data { void (*control)(int enabled); u32 host_port_num; u32 active_slave; + bool rmii_clock_external; u8 version; };