All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roger Quadros <rogerq@ti.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v2 1/3] driver: net: cpsw: add support for RGMII id mode support and RMII clock source selection
Date: Wed, 24 Aug 2016 15:35:49 +0300	[thread overview]
Message-ID: <1472042151-24844-2-git-send-email-rogerq@ti.com> (raw)
In-Reply-To: <1472042151-24844-1-git-send-email-rogerq@ti.com>

From: Mugunthan V N <mugunthanvnm@ti.com>

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.

[Lokesh Vutla]
- Update for am43xx variants.
- Use DT data to configure external chip clock for RMII mode.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/cpsw.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 include/cpsw.h     |   1 +
 2 files changed, 144 insertions(+), 14 deletions(-)

diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 81ccc61..c1dc221 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,17 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev)
 				error("Not able to get gmii_sel reg address\n");
 				return -ENOENT;
 			}
+
+			if (fdt_get_property(fdt, subnode, "rmii-clock-ext",
+					     NULL))
+				priv->data.rmii_clock_external = true;
+
+			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 +1433,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;
 };
 
-- 
2.7.4

  reply	other threads:[~2016-08-24 12:35 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-24 12:35 [U-Boot] [PATCH v2 0/3] am335x-icev2: Ethernet support Roger Quadros
2016-08-24 12:35 ` Roger Quadros [this message]
2016-08-29 12:01   ` [U-Boot] [PATCH v2 1/3] driver: net: cpsw: add support for RGMII id mode support and RMII clock source selection Tom Rini
2016-09-02 14:53   ` Tom Rini
2016-10-14 12:24     ` Roger Quadros
2016-10-19 18:15       ` Joe Hershberger
2016-08-24 12:35 ` [U-Boot] [PATCH v2 2/3] board: am335x-icev2: add ethernet phy mode detection logic Roger Quadros
2016-08-29 12:01   ` Tom Rini
2016-09-02 14:53   ` Tom Rini
2016-10-11 21:52   ` Joe Hershberger
2016-10-13 17:38   ` [U-Boot] " Joe Hershberger
2016-08-24 12:35 ` [U-Boot] [PATCH v2 3/3] board: am335x: Always set eth/eth1addr environment variable Roger Quadros
2016-08-29 12:01   ` Tom Rini
2016-09-02 14:53   ` Tom Rini
2016-10-11 21:54   ` Joe Hershberger
2016-10-13 17:38   ` [U-Boot] " Joe Hershberger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1472042151-24844-2-git-send-email-rogerq@ti.com \
    --to=rogerq@ti.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.