* [PATCH V2 0/7] support the cpts found on am335x devices
@ 2012-10-15 19:48 Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 1/7] cpsw: rename register banks to match the reference manual Richard Cochran
                   ` (7 more replies)
  0 siblings, 8 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
This patch series, based on linux-3.7-rc1 plus the fixes I posted
today, adds support for the Common Platform Time Sync (CPTS) found on
the popular BeagleBone. The code enables hardware time stamping and a
PTP Hardware Clock.
Changes in V2
   - Now uses device tree
   - Actually works with vanilla kernel
This work has been tested using the linuxptp PTP stack, and it seems
to be working quite well. One limitation of the hardware is that not
possible to adjust the clock frequency. Even without with this
capability, the driver will be still be useful for 802.1AS
applications, since they typically use a free running clock.
There is one open issue with this driver which will hopefully soon be
resolved. Time stamping only works on UDP packets. Although Layer 2 is
supposed to work according to the TRM, I have not yet figured out
how. The UDP only works when setting an undocumented bit, so maybe
someone from TI can fill me in on this.
Thanks,
Richard
Richard Cochran (7):
  cpsw: rename register banks to match the reference manual
  cpsw: add missing fields to the CPSW_SS register bank.
  cpsw: correct the CPSW_PORT register bank declaration
  cpsw: add a common header file for regsiter declarations
  cpts: introduce time stamping code and a PTP hardware clock.
  cpsw: add a DT field for the cpts offset
  cpsw: use the time stamping capabilities of the cpts
 Documentation/devicetree/bindings/net/cpsw.txt |   11 +-
 arch/arm/boot/dts/am33xx.dtsi                  |    5 +-
 drivers/net/ethernet/ti/Kconfig                |    8 +
 drivers/net/ethernet/ti/Makefile               |    2 +-
 drivers/net/ethernet/ti/cpsw.c                 |   84 ++++-
 drivers/net/ethernet/ti/cpsw_reg.h             |   81 ++++
 drivers/net/ethernet/ti/cpts.c                 |  468 ++++++++++++++++++++++++
 drivers/net/ethernet/ti/cpts.h                 |  148 ++++++++
 include/linux/platform_data/cpsw.h             |    1 +
 9 files changed, 788 insertions(+), 20 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/cpsw_reg.h
 create mode 100644 drivers/net/ethernet/ti/cpts.c
 create mode 100644 drivers/net/ethernet/ti/cpts.h
-- 
1.7.2.5
^ permalink raw reply	[flat|nested] 14+ messages in thread
* [PATCH V2 1/7] cpsw: rename register banks to match the reference manual
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 2/7] cpsw: add missing fields to the CPSW_SS register bank Richard Cochran
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
The code mixes up the CPSW_SS and the CPSW_WR register naming. This patch
changes the names to conform to the published Technical Reference Manual
from TI, in order to make working on the code less confusing.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/ti/cpsw.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index fb1a692..3568b46 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -129,7 +129,7 @@ static int rx_packet_max = CPSW_MAX_PACKET_SIZE;
 module_param(rx_packet_max, int, 0);
 MODULE_PARM_DESC(rx_packet_max, "maximum receive packet size (bytes)");
 
-struct cpsw_ss_regs {
+struct cpsw_wr_regs {
 	u32	id_ver;
 	u32	soft_reset;
 	u32	control;
@@ -140,7 +140,7 @@ struct cpsw_ss_regs {
 	u32	misc_en;
 };
 
-struct cpsw_regs {
+struct cpsw_ss_regs {
 	u32	id_ver;
 	u32	control;
 	u32	soft_reset;
@@ -202,8 +202,8 @@ struct cpsw_priv {
 	struct napi_struct		napi;
 	struct device			*dev;
 	struct cpsw_platform_data	data;
-	struct cpsw_regs __iomem	*regs;
-	struct cpsw_ss_regs __iomem	*ss_regs;
+	struct cpsw_ss_regs __iomem	*regs;
+	struct cpsw_wr_regs __iomem	*wr_regs;
 	struct cpsw_host_regs __iomem	*host_port_regs;
 	u32				msg_enable;
 	struct net_device_stats		stats;
@@ -230,8 +230,8 @@ struct cpsw_priv {
 
 static void cpsw_intr_enable(struct cpsw_priv *priv)
 {
-	__raw_writel(0xFF, &priv->ss_regs->tx_en);
-	__raw_writel(0xFF, &priv->ss_regs->rx_en);
+	__raw_writel(0xFF, &priv->wr_regs->tx_en);
+	__raw_writel(0xFF, &priv->wr_regs->rx_en);
 
 	cpdma_ctlr_int_ctrl(priv->dma, true);
 	return;
@@ -239,8 +239,8 @@ static void cpsw_intr_enable(struct cpsw_priv *priv)
 
 static void cpsw_intr_disable(struct cpsw_priv *priv)
 {
-	__raw_writel(0, &priv->ss_regs->tx_en);
-	__raw_writel(0, &priv->ss_regs->rx_en);
+	__raw_writel(0, &priv->wr_regs->tx_en);
+	__raw_writel(0, &priv->wr_regs->rx_en);
 
 	cpdma_ctlr_int_ctrl(priv->dma, false);
 	return;
@@ -984,7 +984,7 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 		dev_err(priv->dev, "unable to map i/o region\n");
 		goto clean_cpsw_ss_iores_ret;
 	}
-	priv->ss_regs = regs;
+	priv->wr_regs = regs;
 
 	for_each_slave(priv, cpsw_slave_init, priv);
 
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 2/7] cpsw: add missing fields to the CPSW_SS register bank.
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 1/7] cpsw: rename register banks to match the reference manual Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 3/7] cpsw: correct the CPSW_PORT register bank declaration Richard Cochran
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/ti/cpsw.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 3568b46..1bdbb36 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -146,6 +146,14 @@ struct cpsw_ss_regs {
 	u32	soft_reset;
 	u32	stat_port_en;
 	u32	ptype;
+	u32	soft_idle;
+	u32	thru_rate;
+	u32	gap_thresh;
+	u32	tx_start_wds;
+	u32	flow_control;
+	u32	vlan_ltype;
+	u32	ts_ltype;
+	u32	dlr_ltype;
 };
 
 struct cpsw_slave_regs {
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 3/7] cpsw: correct the CPSW_PORT register bank declaration
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 1/7] cpsw: rename register banks to match the reference manual Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 2/7] cpsw: add missing fields to the CPSW_SS register bank Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 4/7] cpsw: add a common header file for regsiter declarations Richard Cochran
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
This commit corrects and expands the slave port register bank
according to TI's Technical Reference Manual.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 Documentation/devicetree/bindings/net/cpsw.txt |    8 ++++----
 arch/arm/boot/dts/am33xx.dtsi                  |    4 ++--
 drivers/net/ethernet/ti/cpsw.c                 |   18 ++++++++++++++----
 3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index dcaabe9..3af47b7 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -59,14 +59,14 @@ Examples:
 		mac_control = <0x20>;
 		slaves = <2>;
 		cpsw_emac0: slave@0 {
-			slave_reg_ofs = <0x208>;
+			slave_reg_ofs = <0x200>;
 			sliver_reg_ofs = <0xd80>;
 			phy_id = "davinci_mdio.16:00";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
 		cpsw_emac1: slave@1 {
-			slave_reg_ofs = <0x308>;
+			slave_reg_ofs = <0x300>;
 			sliver_reg_ofs = <0xdc0>;
 			phy_id = "davinci_mdio.16:01";
 			/* Filled in by U-Boot */
@@ -93,14 +93,14 @@ Examples:
 		mac_control = <0x20>;
 		slaves = <2>;
 		cpsw_emac0: slave@0 {
-			slave_reg_ofs = <0x208>;
+			slave_reg_ofs = <0x200>;
 			sliver_reg_ofs = <0xd80>;
 			phy_id = "davinci_mdio.16:00";
 			/* Filled in by U-Boot */
 			mac-address = [ 00 00 00 00 00 00 ];
 		};
 		cpsw_emac1: slave@1 {
-			slave_reg_ofs = <0x308>;
+			slave_reg_ofs = <0x300>;
 			sliver_reg_ofs = <0xdc0>;
 			phy_id = "davinci_mdio.16:01";
 			/* Filled in by U-Boot */
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index f6bea04..cd9b3b4 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -238,13 +238,13 @@
 			interrupts = <40 41 42 43>;
 			ranges;
 			cpsw_emac0: slave@0 {
-				slave_reg_ofs = <0x208>;
+				slave_reg_ofs = <0x200>;
 				sliver_reg_ofs = <0xd80>;
 				/* Filled in by U-Boot */
 				mac-address = [ 00 00 00 00 00 00 ];
 			};
 			cpsw_emac1: slave@1 {
-				slave_reg_ofs = <0x308>;
+				slave_reg_ofs = <0x300>;
 				sliver_reg_ofs = <0xdc0>;
 				/* Filled in by U-Boot */
 				mac-address = [ 00 00 00 00 00 00 ];
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1bdbb36..e29bb8f 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -157,16 +157,26 @@ struct cpsw_ss_regs {
 };
 
 struct cpsw_slave_regs {
+	u32	control;
+	u32	res1;
 	u32	max_blks;
 	u32	blk_cnt;
-	u32	flow_thresh;
+	u32	tx_in_ctl;
 	u32	port_vlan;
 	u32	tx_pri_map;
-	u32	ts_ctl;
-	u32	ts_seq_ltype;
-	u32	ts_vlan;
+	u32	ts_seq_mtype;
 	u32	sa_lo;
 	u32	sa_hi;
+	u32	send_percent;
+	u32	res2;
+	u32	rx_dscp_pri_map0;
+	u32	rx_dscp_pri_map1;
+	u32	rx_dscp_pri_map2;
+	u32	rx_dscp_pri_map3;
+	u32	rx_dscp_pri_map4;
+	u32	rx_dscp_pri_map5;
+	u32	rx_dscp_pri_map6;
+	u32	rx_dscp_pri_map7;
 };
 
 struct cpsw_host_regs {
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 4/7] cpsw: add a common header file for regsiter declarations
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
                   ` (2 preceding siblings ...)
  2012-10-15 19:48 ` [PATCH V2 3/7] cpsw: correct the CPSW_PORT register bank declaration Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 5/7] cpts: introduce time stamping code and a PTP hardware clock Richard Cochran
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/ti/cpsw_reg.h |   81 ++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/cpsw_reg.h
diff --git a/drivers/net/ethernet/ti/cpsw_reg.h b/drivers/net/ethernet/ti/cpsw_reg.h
new file mode 100644
index 0000000..88fb15f
--- /dev/null
+++ b/drivers/net/ethernet/ti/cpsw_reg.h
@@ -0,0 +1,81 @@
+/*
+ * Common CPSW register declarations
+ *
+ * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef _TI_CPSW_REG_H_
+#define _TI_CPSW_REG_H_
+
+struct cpsw_port {
+	u32 control;                /* Control Register */
+	u32 res1;
+	u32 max_blks;               /* Maximum FIFO Blocks */
+	u32 blk_cnt;                /* FIFO Block Usage Count (Read Only) */
+	u32 tx_in_ctl;              /* Transmit FIFO Control */
+	u32 port_vlan;              /* VLAN Register */
+	u32 tx_pri_map;             /* Tx Header Priority to Switch Pri Map */
+	u32 ts_seq_mtype;           /* Time Sync Seq ID Offset and Msg Type */
+	u32 sa_lo;                  /* CPGMAC_SL Source Address Low */
+	u32 sa_hi;                  /* CPGMAC_SL Source Address High */
+	u32 send_percent;           /* Transmit Queue Send Percentages */
+	u32 res2;
+	u32 rx_dscp_pri_map0;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map1;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map2;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map3;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map4;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map5;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map6;       /* Rx DSCP Priority to Rx Packet Mapping */
+	u32 rx_dscp_pri_map7;       /* Rx DSCP Priority to Rx Packet Mapping */
+};
+
+/* Bit definitions for the CONTROL register */
+#define PASS_PRI_TAGGED        (1<<24) /* Pass Priority Tagged */
+#define VLAN_LTYPE2_EN         (1<<21) /* VLAN LTYPE 2 enable */
+#define VLAN_LTYPE1_EN         (1<<20) /* VLAN LTYPE 1 enable */
+#define DSCP_PRI_EN            (1<<16) /* DSCP Priority Enable */
+#define TS_320                 (1<<14) /* Time Sync Dest Port 320 enable */
+#define TS_319                 (1<<13) /* Time Sync Dest Port 319 enable */
+#define TS_132                 (1<<12) /* Time Sync Dest IP Addr 132 enable */
+#define TS_131                 (1<<11) /* Time Sync Dest IP Addr 131 enable */
+#define TS_130                 (1<<10) /* Time Sync Dest IP Addr 130 enable */
+#define TS_129                 (1<<9)  /* Time Sync Dest IP Addr 129 enable */
+#define TS_BIT8                (1<<8)  /* ts_ttl_nonzero? */
+#define TS_ANNEX_D_EN          (1<<4)  /* Time Sync Annex D enable */
+#define TS_LTYPE2_EN           (1<<3)  /* Time Sync LTYPE 2 enable */
+#define TS_LTYPE1_EN           (1<<2)  /* Time Sync LTYPE 1 enable */
+#define TS_TX_EN               (1<<1)  /* Time Sync Transmit Enable */
+#define TS_RX_EN               (1<<0)  /* Time Sync Receive Enable */
+
+#define CTRL_TS_BITS \
+	(TS_320 | TS_319 | TS_132 | TS_131 | TS_130 | TS_129 | TS_BIT8 | \
+	 TS_ANNEX_D_EN | TS_LTYPE2_EN | TS_LTYPE1_EN)
+
+#define CTRL_ALL_TS_MASK (CTRL_TS_BITS | TS_TX_EN | TS_RX_EN)
+#define CTRL_TX_TS_BITS  (CTRL_TS_BITS | TS_TX_EN)
+#define CTRL_RX_TS_BITS  (CTRL_TS_BITS | TS_RX_EN)
+
+/* Bit definitions for the TS_SEQ_MTYPE register */
+#define TS_SEQ_ID_OFFSET_SHIFT (16)    /* Time Sync Sequence ID Offset */
+#define TS_SEQ_ID_OFFSET_MASK  (0x3f)
+#define TS_MSG_TYPE_EN_SHIFT   (0)     /* Time Sync Message Type Enable */
+#define TS_MSG_TYPE_EN_MASK    (0xffff)
+
+/* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */
+#define EVENT_MSG_BITS ((1<<0) | (1<<1) | (1<<2) | (1<<3))
+
+#endif
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 5/7] cpts: introduce time stamping code and a PTP hardware clock.
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
                   ` (3 preceding siblings ...)
  2012-10-15 19:48 ` [PATCH V2 4/7] cpsw: add a common header file for regsiter declarations Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 6/7] cpsw: add a DT field for the cpts offset Richard Cochran
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
This patch adds a driver for the CPTS that offers time
stamping and a PTP hardware clock. Even though the
hardware does not support frequency adjustment, still the
unit can be useful for 802.1AS for example.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/ti/Kconfig  |    8 +
 drivers/net/ethernet/ti/Makefile |    2 +-
 drivers/net/ethernet/ti/cpts.c   |  468 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ethernet/ti/cpts.h   |  148 ++++++++++++
 4 files changed, 625 insertions(+), 1 deletions(-)
 create mode 100644 drivers/net/ethernet/ti/cpts.c
 create mode 100644 drivers/net/ethernet/ti/cpts.h
diff --git a/drivers/net/ethernet/ti/Kconfig b/drivers/net/ethernet/ti/Kconfig
index b26cbda..cbc3905 100644
--- a/drivers/net/ethernet/ti/Kconfig
+++ b/drivers/net/ethernet/ti/Kconfig
@@ -60,6 +60,14 @@ config TI_CPSW
 	  To compile this driver as a module, choose M here: the module
 	  will be called cpsw.
 
+config TI_CPTS
+	boolean "TI Common Platform Time Sync (CPTS) Support"
+	depends on TI_CPSW && PTP_1588_CLOCK && !(TI_CPSW=y && PTP_1588_CLOCK=m)
+	---help---
+	  This driver supports the Common Platform Time Sync unit of
+	  the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4
+	  and Layer 2 packets, and the driver offers a PTP Hardware Clock.
+
 config TLAN
 	tristate "TI ThunderLAN support"
 	depends on (PCI || EISA)
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index 91bd8bb..c65148e 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -8,4 +8,4 @@ obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
 obj-$(CONFIG_TI_DAVINCI_MDIO) += davinci_mdio.o
 obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
 obj-$(CONFIG_TI_CPSW) += ti_cpsw.o
-ti_cpsw-y := cpsw_ale.o cpsw.o
+ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o
diff --git a/drivers/net/ethernet/ti/cpts.c b/drivers/net/ethernet/ti/cpts.c
new file mode 100644
index 0000000..bdb20c4
--- /dev/null
+++ b/drivers/net/ethernet/ti/cpts.c
@@ -0,0 +1,468 @@
+/*
+ * TI Common Platform Time Sync
+ *
+ * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/err.h>
+#include <linux/if.h>
+#include <linux/hrtimer.h>
+#include <linux/module.h>
+#include <linux/net_tstamp.h>
+#include <linux/ptp_classify.h>
+#include <linux/time.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+
+#include <plat/clock.h>
+
+#include "cpts.h"
+
+#ifdef CONFIG_TI_CPTS
+
+static struct sock_filter ptp_filter[] = {
+	PTP_FILTER
+};
+
+#define cpts_read32(c, r)	__raw_readl(&c->reg->r)
+#define cpts_write32(c, v, r)	__raw_writel(v, &c->reg->r)
+#define port_read32(c, r)	__raw_readl(&c->tsp->r)
+#define port_write32(c, v, r)	__raw_writel(v, &c->tsp->r)
+
+static int event_expired(struct cpts_event *event)
+{
+	return time_after(jiffies, event->tmo);
+}
+
+static int event_type(struct cpts_event *event)
+{
+	return (event->high >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
+}
+
+static int cpts_fifo_pop(struct cpts *cpts, u32 *high, u32 *low)
+{
+	u32 r = cpts_read32(cpts, intstat_raw);
+
+	if (r & TS_PEND_RAW) {
+		*high = cpts_read32(cpts, event_high);
+		*low  = cpts_read32(cpts, event_low);
+		cpts_write32(cpts, EVENT_POP, event_pop);
+		return 0;
+	}
+	return -1;
+}
+
+/*
+ * Returns zero if matching event type was found.
+ */
+static int cpts_fifo_read(struct cpts *cpts, int match)
+{
+	int i, type = -1;
+	u32 hi, lo;
+	struct cpts_event *event;
+
+	for (i = 0; i < CPTS_FIFO_DEPTH; i++) {
+		if (cpts_fifo_pop(cpts, &hi, &lo))
+			break;
+		if (list_empty(&cpts->pool)) {
+			pr_err("cpts: event pool is empty\n");
+			return -1;
+		}
+		event = list_first_entry(&cpts->pool, struct cpts_event, list);
+		event->tmo = jiffies + 2;
+		event->high = hi;
+		event->low = lo;
+		type = event_type(event);
+		switch (type) {
+		case CPTS_EV_PUSH:
+		case CPTS_EV_RX:
+		case CPTS_EV_TX:
+			list_del_init(&event->list);
+			list_add_tail(&event->list, &cpts->events);
+			break;
+		case CPTS_EV_ROLL:
+		case CPTS_EV_HALF:
+		case CPTS_EV_HW:
+			break;
+		default:
+			pr_err("cpts: unkown event type\n");
+			break;
+		}
+		if (type == match)
+			break;
+	}
+	return type == match ? 0 : -1;
+}
+
+static cycle_t cpts_systim_read(const struct cyclecounter *cc)
+{
+	u64 val = 0;
+	struct cpts_event *event;
+	struct list_head *this, *next;
+	struct cpts *cpts = container_of(cc, struct cpts, cc);
+
+	cpts_write32(cpts, TS_PUSH, ts_push);
+	if (cpts_fifo_read(cpts, CPTS_EV_PUSH))
+		pr_err("cpts: unable to obtain a time stamp\n");
+
+	list_for_each_safe(this, next, &cpts->events) {
+		event = list_entry(this, struct cpts_event, list);
+		if (event_type(event) == CPTS_EV_PUSH) {
+			list_del_init(&event->list);
+			list_add(&event->list, &cpts->pool);
+			val = event->low;
+			break;
+		}
+	}
+
+	return val;
+}
+
+/* PTP clock operations */
+
+static int cpts_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	return -EOPNOTSUPP;
+}
+
+static int cpts_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	s64 now;
+	unsigned long flags;
+	struct cpts *cpts = container_of(ptp, struct cpts, info);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	now = timecounter_read(&cpts->tc);
+	now += delta;
+	timecounter_init(&cpts->tc, &cpts->cc, now);
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return 0;
+}
+
+static int cpts_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	u64 ns;
+	u32 remainder;
+	unsigned long flags;
+	struct cpts *cpts = container_of(ptp, struct cpts, info);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	ns = timecounter_read(&cpts->tc);
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
+	ts->tv_nsec = remainder;
+
+	return 0;
+}
+
+static int cpts_ptp_settime(struct ptp_clock_info *ptp,
+			    const struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct cpts *cpts = container_of(ptp, struct cpts, info);
+
+	ns = ts->tv_sec * 1000000000ULL;
+	ns += ts->tv_nsec;
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	timecounter_init(&cpts->tc, &cpts->cc, ns);
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return 0;
+}
+
+static int cpts_ptp_enable(struct ptp_clock_info *ptp,
+			   struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info cpts_info = {
+	.owner		= THIS_MODULE,
+	.name		= "CTPS timer",
+	.max_adj	= 0,
+	.n_ext_ts	= 0,
+	.pps		= 0,
+	.adjfreq	= cpts_ptp_adjfreq,
+	.adjtime	= cpts_ptp_adjtime,
+	.gettime	= cpts_ptp_gettime,
+	.settime	= cpts_ptp_settime,
+	.enable		= cpts_ptp_enable,
+};
+
+static void cpts_overflow_check(struct work_struct *work)
+{
+	struct timespec ts;
+	struct cpts *cpts = container_of(work, struct cpts, overflow_work.work);
+
+	cpts_write32(cpts, CPTS_EN, control);
+	cpts_write32(cpts, TS_PEND_EN, int_enable);
+	cpts_ptp_gettime(&cpts->info, &ts);
+	pr_debug("cpts overflow check at %ld.%09lu\n", ts.tv_sec, ts.tv_nsec);
+	schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
+}
+
+#define CPTS_REF_CLOCK_NAME "cpsw_cpts_rft_clk"
+
+static void cpts_clk_init(struct cpts *cpts)
+{
+	cpts->refclk = clk_get(NULL, CPTS_REF_CLOCK_NAME);
+	if (IS_ERR(cpts->refclk)) {
+		pr_err("Failed to clk_get %s\n", CPTS_REF_CLOCK_NAME);
+		cpts->refclk = NULL;
+		return;
+	}
+	clk_enable(cpts->refclk);
+	cpts->freq = cpts->refclk->recalc(cpts->refclk);
+}
+
+static void cpts_clk_release(struct cpts *cpts)
+{
+	clk_disable(cpts->refclk);
+	clk_put(cpts->refclk);
+}
+
+static int cpts_match(struct sk_buff *skb, unsigned int ptp_class,
+		      u16 ts_seqid, u8 ts_msgtype)
+{
+	u16 *seqid;
+	unsigned int offset;
+	u8 *msgtype, *data = skb->data;
+
+	switch (ptp_class) {
+	case PTP_CLASS_V1_IPV4:
+	case PTP_CLASS_V2_IPV4:
+		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
+		break;
+	case PTP_CLASS_V1_IPV6:
+	case PTP_CLASS_V2_IPV6:
+		offset = OFF_PTP6;
+		break;
+	case PTP_CLASS_V2_L2:
+		offset = ETH_HLEN;
+		break;
+	case PTP_CLASS_V2_VLAN:
+		offset = ETH_HLEN + VLAN_HLEN;
+		break;
+	default:
+		return 0;
+	}
+
+	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
+		return 0;
+
+	if (unlikely(ptp_class & PTP_CLASS_V1))
+		msgtype = data + offset + OFF_PTP_CONTROL;
+	else
+		msgtype = data + offset;
+
+	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+
+	return (ts_msgtype == (*msgtype & 0xf) && ts_seqid == ntohs(*seqid));
+}
+
+static u64 cpts_find_ts(struct cpts *cpts, struct sk_buff *skb, int ev_type)
+{
+	u64 ns = 0;
+	struct cpts_event *event;
+	struct list_head *this, *next;
+	unsigned int class = sk_run_filter(skb, ptp_filter);
+	unsigned long flags;
+	u16 seqid;
+	u8 mtype;
+
+	if (class == PTP_CLASS_NONE)
+		return 0;
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	cpts_fifo_read(cpts, CPTS_EV_PUSH);
+	list_for_each_safe(this, next, &cpts->events) {
+		event = list_entry(this, struct cpts_event, list);
+		if (event_expired(event)) {
+			list_del_init(&event->list);
+			list_add(&event->list, &cpts->pool);
+			continue;
+		}
+		mtype = (event->high >> MESSAGE_TYPE_SHIFT) & MESSAGE_TYPE_MASK;
+		seqid = (event->high >> SEQUENCE_ID_SHIFT) & SEQUENCE_ID_MASK;
+		if (ev_type == event_type(event) &&
+		    cpts_match(skb, class, seqid, mtype)) {
+			ns = timecounter_cyc2time(&cpts->tc, event->low);
+			list_del_init(&event->list);
+			list_add(&event->list, &cpts->pool);
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return ns;
+}
+
+void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
+{
+	u64 ns;
+	struct skb_shared_hwtstamps *ssh;
+
+	if (!cpts->rx_enable)
+		return;
+	ns = cpts_find_ts(cpts, skb, CPTS_EV_RX);
+	if (!ns)
+		return;
+	ssh = skb_hwtstamps(skb);
+	memset(ssh, 0, sizeof(*ssh));
+	ssh->hwtstamp = ns_to_ktime(ns);
+}
+
+void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
+{
+	u64 ns;
+	struct skb_shared_hwtstamps ssh;
+
+	if (!(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
+		return;
+	ns = cpts_find_ts(cpts, skb, CPTS_EV_TX);
+	if (!ns)
+		return;
+	memset(&ssh, 0, sizeof(ssh));
+	ssh.hwtstamp = ns_to_ktime(ns);
+	skb_tstamp_tx(skb, &ssh);
+}
+
+#endif /*CONFIG_TI_CPTS*/
+
+int cpts_hwtstamp_ioctl(struct cpts *cpts, struct ifreq *ifr)
+{
+#ifdef CONFIG_TI_CPTS
+	struct hwtstamp_config cfg;
+	u32 ctrl, mtype;
+
+	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+		return -EFAULT;
+
+	/* reserved for future extensions */
+	if (cfg.flags)
+		return -EINVAL;
+
+	ctrl = port_read32(cpts, control);
+	ctrl &= ~CTRL_ALL_TS_MASK;
+
+	switch (cfg.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		cpts->tx_enable = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		cpts->tx_enable = 1;
+		ctrl |= CTRL_TX_TS_BITS;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (cfg.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		cpts->rx_enable = 0;
+		break;
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		return -ERANGE;
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		cpts->rx_enable = 1;
+		cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
+		ctrl |= CTRL_RX_TS_BITS;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	mtype = (30 << TS_SEQ_ID_OFFSET_SHIFT) | EVENT_MSG_BITS;
+	port_write32(cpts, mtype, ts_seq_mtype);
+	port_write32(cpts, ctrl, control);
+
+	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
+int cpts_register(struct device *dev, struct cpts *cpts)
+{
+#ifdef CONFIG_TI_CPTS
+	int err, i;
+	unsigned long flags;
+
+	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
+		pr_err("cpts: bad ptp filter\n");
+		return -EINVAL;
+	}
+	cpts->info = cpts_info;
+	cpts->clock = ptp_clock_register(&cpts->info, dev);
+	if (IS_ERR(cpts->clock)) {
+		err = PTR_ERR(cpts->clock);
+		cpts->clock = NULL;
+		return err;
+	}
+	spin_lock_init(&cpts->lock);
+
+	cpts->cc.read = cpts_systim_read;
+	cpts->cc.mask = CLOCKSOURCE_MASK(32);
+	cpts->cc.mult = 4;
+	cpts->cc.shift = 0;
+
+	INIT_LIST_HEAD(&cpts->events);
+	INIT_LIST_HEAD(&cpts->pool);
+	for (i = 0; i < CPTS_MAX_EVENTS; i++)
+		list_add(&cpts->pool_data[i].list, &cpts->pool);
+
+	cpts_clk_init(cpts);
+	cpts_write32(cpts, CPTS_EN, control);
+	cpts_write32(cpts, TS_PEND_EN, int_enable);
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	timecounter_init(&cpts->tc, &cpts->cc, ktime_to_ns(ktime_get_real()));
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	INIT_DELAYED_WORK(&cpts->overflow_work, cpts_overflow_check);
+	schedule_delayed_work(&cpts->overflow_work, CPTS_OVERFLOW_PERIOD);
+
+	cpts->phc_index = ptp_clock_index(cpts->clock);
+#endif
+	return 0;
+}
+
+void cpts_unregister(struct cpts *cpts)
+{
+#ifdef CONFIG_TI_CPTS
+	if (cpts->clock) {
+		ptp_clock_unregister(cpts->clock);
+		cancel_delayed_work_sync(&cpts->overflow_work);
+	}
+	if (cpts->refclk)
+		cpts_clk_release(cpts);
+#endif
+}
diff --git a/drivers/net/ethernet/ti/cpts.h b/drivers/net/ethernet/ti/cpts.h
new file mode 100644
index 0000000..86e45ff
--- /dev/null
+++ b/drivers/net/ethernet/ti/cpts.h
@@ -0,0 +1,148 @@
+/*
+ * TI Common Platform Time Sync
+ *
+ * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef _TI_CPTS_H_
+#define _TI_CPTS_H_
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clocksource.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/skbuff.h>
+
+#include "cpsw_reg.h"
+
+struct cpsw_cpts {
+	u32 idver;                /* Identification and version */
+	u32 control;              /* Time sync control */
+	u32 res1;
+	u32 ts_push;              /* Time stamp event push */
+	u32 ts_load_val;          /* Time stamp load value */
+	u32 ts_load_en;           /* Time stamp load enable */
+	u32 res2[2];
+	u32 intstat_raw;          /* Time sync interrupt status raw */
+	u32 intstat_masked;       /* Time sync interrupt status masked */
+	u32 int_enable;           /* Time sync interrupt enable */
+	u32 res3;
+	u32 event_pop;            /* Event interrupt pop */
+	u32 event_low;            /* 32 Bit Event Time Stamp */
+	u32 event_high;           /* Event Type Fields */
+};
+
+/* Bit definitions for the IDVER register */
+#define TX_IDENT_SHIFT       (16)    /* TX Identification Value */
+#define TX_IDENT_MASK        (0xffff)
+#define RTL_VER_SHIFT        (11)    /* RTL Version Value */
+#define RTL_VER_MASK         (0x1f)
+#define MAJOR_VER_SHIFT      (8)     /* Major Version Value */
+#define MAJOR_VER_MASK       (0x7)
+#define MINOR_VER_SHIFT      (0)     /* Minor Version Value */
+#define MINOR_VER_MASK       (0xff)
+
+/* Bit definitions for the CONTROL register */
+#define HW4_TS_PUSH_EN       (1<<11) /* Hardware push 4 enable */
+#define HW3_TS_PUSH_EN       (1<<10) /* Hardware push 3 enable */
+#define HW2_TS_PUSH_EN       (1<<9)  /* Hardware push 2 enable */
+#define HW1_TS_PUSH_EN       (1<<8)  /* Hardware push 1 enable */
+#define INT_TEST             (1<<1)  /* Interrupt Test */
+#define CPTS_EN              (1<<0)  /* Time Sync Enable */
+
+/*
+ * Definitions for the single bit resisters:
+ * TS_PUSH TS_LOAD_EN  INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP
+ */
+#define TS_PUSH             (1<<0)  /* Time stamp event push */
+#define TS_LOAD_EN          (1<<0)  /* Time Stamp Load */
+#define TS_PEND_RAW         (1<<0)  /* int read (before enable) */
+#define TS_PEND             (1<<0)  /* masked interrupt read (after enable) */
+#define TS_PEND_EN          (1<<0)  /* masked interrupt enable */
+#define EVENT_POP           (1<<0)  /* writing discards one event */
+
+/* Bit definitions for the EVENT_HIGH register */
+#define PORT_NUMBER_SHIFT    (24)    /* Indicates Ethernet port or HW pin */
+#define PORT_NUMBER_MASK     (0x1f)
+#define EVENT_TYPE_SHIFT     (20)    /* Time sync event type */
+#define EVENT_TYPE_MASK      (0xf)
+#define MESSAGE_TYPE_SHIFT   (16)    /* PTP message type */
+#define MESSAGE_TYPE_MASK    (0xf)
+#define SEQUENCE_ID_SHIFT    (0)     /* PTP message sequence ID */
+#define SEQUENCE_ID_MASK     (0xffff)
+
+enum {
+	CPTS_EV_PUSH, /* Time Stamp Push Event */
+	CPTS_EV_ROLL, /* Time Stamp Rollover Event */
+	CPTS_EV_HALF, /* Time Stamp Half Rollover Event */
+	CPTS_EV_HW,   /* Hardware Time Stamp Push Event */
+	CPTS_EV_RX,   /* Ethernet Receive Event */
+	CPTS_EV_TX,   /* Ethernet Transmit Event */
+};
+
+/* This covers any input clock up to about 500 MHz. */
+#define CPTS_OVERFLOW_PERIOD (HZ * 8)
+
+#define CPTS_FIFO_DEPTH 16
+#define CPTS_MAX_EVENTS 32
+
+struct cpts_event {
+	struct list_head list;
+	unsigned long tmo;
+	u32 high;
+	u32 low;
+};
+
+struct cpts {
+	struct cpsw_cpts __iomem *reg;
+	struct cpsw_port __iomem *tsp;
+	int tx_enable;
+#ifdef CONFIG_TI_CPTS
+	int rx_enable;
+	struct ptp_clock_info info;
+	struct ptp_clock *clock;
+	spinlock_t lock; /* protects time registers */
+	struct cyclecounter cc;
+	struct timecounter tc;
+	struct delayed_work overflow_work;
+	int phc_index;
+	struct clk *refclk;
+	unsigned long freq;
+	struct list_head events;
+	struct list_head pool;
+	struct cpts_event pool_data[CPTS_MAX_EVENTS];
+#endif
+};
+
+#ifdef CONFIG_TI_CPTS
+extern void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
+extern void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
+#else
+static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
+{
+}
+static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
+{
+}
+#endif
+
+extern int cpts_hwtstamp_ioctl(struct cpts *cpts, struct ifreq *ifr);
+extern int cpts_register(struct device *dev, struct cpts *cpts);
+extern void cpts_unregister(struct cpts *cpts);
+
+#endif
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 6/7] cpsw: add a DT field for the cpts offset
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
                   ` (4 preceding siblings ...)
  2012-10-15 19:48 ` [PATCH V2 5/7] cpts: introduce time stamping code and a PTP hardware clock Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-15 19:48 ` [PATCH V2 7/7] cpsw: use the time stamping capabilities of the cpts Richard Cochran
  2012-10-16 16:33 ` [PATCH V2 0/7] support the cpts found on am335x devices N, Mugunthan V
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 Documentation/devicetree/bindings/net/cpsw.txt |    3 +++
 arch/arm/boot/dts/am33xx.dtsi                  |    1 +
 drivers/net/ethernet/ti/cpsw.c                 |    7 +++++++
 include/linux/platform_data/cpsw.h             |    1 +
 4 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/cpsw.txt b/Documentation/devicetree/bindings/net/cpsw.txt
index 3af47b7..dba014f 100644
--- a/Documentation/devicetree/bindings/net/cpsw.txt
+++ b/Documentation/devicetree/bindings/net/cpsw.txt
@@ -16,6 +16,7 @@ Required properties:
 - ale_entries		: Specifies No of entries ALE can hold
 - host_port_reg_ofs	: Specifies host port register offset
 - hw_stats_reg_ofs	: Specifies hardware statistics register offset
+- cpts_reg_ofs		: Specifies the offset of the CPTS registers
 - bd_ram_ofs		: Specifies internal desciptor RAM offset
 - bd_ram_size		: Specifies internal descriptor RAM size
 - rx_descs		: Specifies number of Rx descriptors
@@ -52,6 +53,7 @@ Examples:
 		ale_entries = <1024>;
 		host_port_reg_ofs = <0x108>;
 		hw_stats_reg_ofs = <0x900>;
+		cpts_reg_ofs = <0xc00>;
 		bd_ram_ofs = <0x2000>;
 		bd_ram_size = <0x2000>;
 		no_bd_ram = <0>;
@@ -86,6 +88,7 @@ Examples:
 		ale_entries = <1024>;
 		host_port_reg_ofs = <0x108>;
 		hw_stats_reg_ofs = <0x900>;
+		cpts_reg_ofs = <0xc00>;
 		bd_ram_ofs = <0x2000>;
 		bd_ram_size = <0x2000>;
 		no_bd_ram = <0>;
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index cd9b3b4..c981753 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -222,6 +222,7 @@
 			ale_entries = <1024>;
 			host_port_reg_ofs = <0x108>;
 			hw_stats_reg_ofs = <0x900>;
+			cpts_reg_ofs = <0xc00>;
 			bd_ram_ofs = <0x2000>;
 			bd_ram_size = <0x2000>;
 			no_bd_ram = <0>;
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index e29bb8f..aeaa3bb 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -817,6 +817,13 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
 	}
 	data->hw_stats_reg_ofs = prop;
 
+	if (of_property_read_u32(node, "cpts_reg_ofs", &prop)) {
+		pr_err("Missing cpts_reg_ofs property in the DT.\n");
+		ret = -EINVAL;
+		goto error_ret;
+	}
+	data->cpts_reg_ofs = prop;
+
 	if (of_property_read_u32(node, "bd_ram_ofs", &prop)) {
 		pr_err("Missing bd_ram_ofs property in the DT.\n");
 		ret = -EINVAL;
diff --git a/include/linux/platform_data/cpsw.h b/include/linux/platform_data/cpsw.h
index c4e23d0..a052b1d 100644
--- a/include/linux/platform_data/cpsw.h
+++ b/include/linux/platform_data/cpsw.h
@@ -41,6 +41,7 @@ struct cpsw_platform_data {
 	u32     host_port_num; /* The port number for the host port */
 
 	u32	hw_stats_reg_ofs;  /* cpsw hardware statistics counters */
+	u32	cpts_reg_ofs;      /* cpts registers */
 
 	u32	bd_ram_ofs;   /* embedded buffer descriptor RAM offset*/
 	u32	bd_ram_size;  /*buffer descriptor ram size */
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH V2 7/7] cpsw: use the time stamping capabilities of the cpts
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
                   ` (5 preceding siblings ...)
  2012-10-15 19:48 ` [PATCH V2 6/7] cpsw: add a DT field for the cpts offset Richard Cochran
@ 2012-10-15 19:48 ` Richard Cochran
  2012-10-16 16:33 ` [PATCH V2 0/7] support the cpts found on am335x devices N, Mugunthan V
  7 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-15 19:48 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, David Miller, Cyril Chemparathy, Mugunthan V N,
	Sriramakrishnan A G
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
---
 drivers/net/ethernet/ti/cpsw.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index aeaa3bb..06a134f 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -35,6 +35,7 @@
 #include <linux/platform_data/cpsw.h>
 
 #include "cpsw_ale.h"
+#include "cpts.h"
 #include "davinci_cpdma.h"
 
 #define CPSW_DEBUG	(NETIF_MSG_HW		| NETIF_MSG_WOL		| \
@@ -236,6 +237,7 @@ struct cpsw_priv {
 	/* snapshot of IRQ numbers */
 	u32 irqs_table[4];
 	u32 num_irqs;
+	struct cpts cpts;
 };
 
 #define napi_to_priv(napi)	container_of(napi, struct cpsw_priv, napi)
@@ -272,6 +274,7 @@ void cpsw_tx_handler(void *token, int len, int status)
 
 	if (unlikely(netif_queue_stopped(ndev)))
 		netif_start_queue(ndev);
+	cpts_tx_timestamp(&priv->cpts, skb);
 	priv->stats.tx_packets++;
 	priv->stats.tx_bytes += len;
 	dev_kfree_skb_any(skb);
@@ -292,6 +295,7 @@ void cpsw_rx_handler(void *token, int len, int status)
 	}
 	if (likely(status >= 0)) {
 		skb_put(skb, len);
+		cpts_rx_timestamp(&priv->cpts, skb);
 		skb->protocol = eth_type_trans(skb, ndev);
 		netif_receive_skb(skb);
 		priv->stats.rx_bytes += len;
@@ -610,6 +614,11 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb,
 		return NETDEV_TX_OK;
 	}
 
+	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && priv->cpts.tx_enable)
+		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+	skb_tx_timestamp(skb);
+
 	ret = cpdma_chan_submit(priv->txch, skb, skb->data,
 				skb->len, GFP_KERNEL);
 	if (unlikely(ret != 0)) {
@@ -647,6 +656,21 @@ static void cpsw_ndo_change_rx_flags(struct net_device *ndev, int flags)
 		dev_err(&ndev->dev, "multicast traffic cannot be filtered!\n");
 }
 
+static int cpsw_ndo_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+	struct cpsw_priv *priv = netdev_priv(dev);
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	switch (cmd) {
+	case SIOCSHWTSTAMP:
+		return cpts_hwtstamp_ioctl(&priv->cpts, req);
+	}
+
+	return -ENOTSUPP;
+}
+
 static void cpsw_ndo_tx_timeout(struct net_device *ndev)
 {
 	struct cpsw_priv *priv = netdev_priv(ndev);
@@ -687,6 +711,7 @@ static const struct net_device_ops cpsw_netdev_ops = {
 	.ndo_stop		= cpsw_ndo_stop,
 	.ndo_start_xmit		= cpsw_ndo_start_xmit,
 	.ndo_change_rx_flags	= cpsw_ndo_change_rx_flags,
+	.ndo_do_ioctl		= cpsw_ndo_ioctl,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_tx_timeout		= cpsw_ndo_tx_timeout,
@@ -988,6 +1013,8 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 	priv->regs = regs;
 	priv->host_port = data->host_port_num;
 	priv->host_port_regs = regs + data->host_port_reg_ofs;
+	priv->cpts.reg = regs + data->cpts_reg_ofs;
+	priv->cpts.tsp = regs + priv->data.slave_data[0].slave_reg_ofs;
 
 	priv->cpsw_ss_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!priv->cpsw_ss_res) {
@@ -1109,6 +1136,11 @@ static int __devinit cpsw_probe(struct platform_device *pdev)
 		goto clean_irq_ret;
 	}
 
+	if (cpts_register(&pdev->dev, &priv->cpts))
+		dev_err(priv->dev, "error registering cpts device\n");
+
+	__raw_writel(ETH_P_1588, &priv->regs->ts_ltype);
+
 	cpsw_notice(priv, probe, "initialized device (regs %x, irq %d)\n",
 		  priv->cpsw_res->start, ndev->irq);
 
@@ -1148,6 +1180,7 @@ static int __devexit cpsw_remove(struct platform_device *pdev)
 	pr_info("removing device");
 	platform_set_drvdata(pdev, NULL);
 
+	cpts_unregister(&priv->cpts);
 	free_irq(ndev->irq, priv);
 	cpsw_ale_destroy(priv->ale);
 	cpdma_chan_destroy(priv->txch);
-- 
1.7.2.5
^ permalink raw reply related	[flat|nested] 14+ messages in thread
* RE: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
                   ` (6 preceding siblings ...)
  2012-10-15 19:48 ` [PATCH V2 7/7] cpsw: use the time stamping capabilities of the cpts Richard Cochran
@ 2012-10-16 16:33 ` N, Mugunthan V
  2012-10-16 17:14   ` Richard Cochran
  7 siblings, 1 reply; 14+ messages in thread
From: N, Mugunthan V @ 2012-10-16 16:33 UTC (permalink / raw)
  To: Richard Cochran, netdev@vger.kernel.org
  Cc: linux-arm-kernel@lists.infradead.org, David Miller,
	Chemparathy, Cyril, Govindarajan, Sriramakrishnan
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Tuesday, October 16, 2012 1:18 AM
> To: netdev@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org; David Miller; Chemparathy,
> Cyril; N, Mugunthan V; Govindarajan, Sriramakrishnan
> Subject: [PATCH V2 0/7] support the cpts found on am335x devices
> 
> This patch series, based on linux-3.7-rc1 plus the fixes I posted
> today, adds support for the Common Platform Time Sync (CPTS) found on
> the popular BeagleBone. The code enables hardware time stamping and a
> PTP Hardware Clock.
> 
> Changes in V2
>    - Now uses device tree
>    - Actually works with vanilla kernel
> 
> This work has been tested using the linuxptp PTP stack, and it seems
> to be working quite well. One limitation of the hardware is that not
> possible to adjust the clock frequency. Even without with this
> capability, the driver will be still be useful for 802.1AS
> applications, since they typically use a free running clock.
> 
> There is one open issue with this driver which will hopefully soon be
> resolved. Time stamping only works on UDP packets. Although Layer 2 is
> supposed to work according to the TRM, I have not yet figured out
> how. The UDP only works when setting an undocumented bit, so maybe
> someone from TI can fill me in on this.
> 
> Thanks,
> Richard
> 
> 
> Richard Cochran (7):
>   cpsw: rename register banks to match the reference manual
>   cpsw: add missing fields to the CPSW_SS register bank.
>   cpsw: correct the CPSW_PORT register bank declaration
>   cpsw: add a common header file for regsiter declarations
>   cpts: introduce time stamping code and a PTP hardware clock.
>   cpsw: add a DT field for the cpts offset
>   cpsw: use the time stamping capabilities of the cpts
> 
>  Documentation/devicetree/bindings/net/cpsw.txt |   11 +-
>  arch/arm/boot/dts/am33xx.dtsi                  |    5 +-
>  drivers/net/ethernet/ti/Kconfig                |    8 +
>  drivers/net/ethernet/ti/Makefile               |    2 +-
>  drivers/net/ethernet/ti/cpsw.c                 |   84 ++++-
>  drivers/net/ethernet/ti/cpsw_reg.h             |   81 ++++
>  drivers/net/ethernet/ti/cpts.c                 |  468
> ++++++++++++++++++++++++
>  drivers/net/ethernet/ti/cpts.h                 |  148 ++++++++
>  include/linux/platform_data/cpsw.h             |    1 +
>  9 files changed, 788 insertions(+), 20 deletions(-)
>  create mode 100644 drivers/net/ethernet/ti/cpsw_reg.h
>  create mode 100644 drivers/net/ethernet/ti/cpts.c
>  create mode 100644 drivers/net/ethernet/ti/cpts.h
> 
> --
> 1.7.2.5
Richard
I had seen some issues with the patch series.
* CPTS will hold only LSB 32 bits of 64 bit Timer and the upper 32 bit
  time value has to be taken care by the software, but the time stamp
  which is passed to skb or PTP clock consist of only 32 bit time value
* CPTS interrupts should be utilized to service Half and Full roll over
  events as it is non sync events with respect to get/set time and PTP
  pkt Tx/Rx
* CPTS Time which is obtained from hardware is not actually a nano
  seconds as the CPTS ref clock is tied to 250MHz for AM335x.
* CPSW register mapping done in this patch series removes the CPSW
  driver support for previous version found in TI814x
* CPSW Time stamping is done only for port 0 and port 1 is not done
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-16 16:33 ` [PATCH V2 0/7] support the cpts found on am335x devices N, Mugunthan V
@ 2012-10-16 17:14   ` Richard Cochran
  2012-10-16 23:11     ` N, Mugunthan V
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Cochran @ 2012-10-16 17:14 UTC (permalink / raw)
  To: N, Mugunthan V
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	David Miller, Chemparathy, Cyril, Govindarajan, Sriramakrishnan
On Tue, Oct 16, 2012 at 04:33:55PM +0000, N, Mugunthan V wrote:
> I had seen some issues with the patch series.
Please take another look. Excepting the last, none of your points
holds water.
 
> * CPTS will hold only LSB 32 bits of 64 bit Timer and the upper 32 bit
>   time value has to be taken care by the software, but the time stamp
>   which is passed to skb or PTP clock consist of only 32 bit time value
The driver handles this already.
> * CPTS interrupts should be utilized to service Half and Full roll over
>   events as it is non sync events with respect to get/set time and PTP
>   pkt Tx/Rx
Nope, no need for interrupts, since we already have a better way to
handle this.
> * CPTS Time which is obtained from hardware is not actually a nano
>   seconds as the CPTS ref clock is tied to 250MHz for AM335x.
Did you even look at the code in my patch?
> * CPSW register mapping done in this patch series removes the CPSW
>   driver support for previous version found in TI814x
In which Linux version (or commit) did this driver appear?
I never saw it.
> * CPSW Time stamping is done only for port 0 and port 1 is not done
Yes, you are right, and it is strange that the hardware time stamps on
the external ports of the switch, and not at the host port as it
should. Of course it does present us with a problem, since we cannot
reasonably have both ports time stamping at the same time. I propose
simply using a device tree attribute to tell which port to activate.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 14+ messages in thread
* RE: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-16 17:14   ` Richard Cochran
@ 2012-10-16 23:11     ` N, Mugunthan V
  2012-10-17 18:27       ` Richard Cochran
  0 siblings, 1 reply; 14+ messages in thread
From: N, Mugunthan V @ 2012-10-16 23:11 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	David Miller, Chemparathy, Cyril, Govindarajan, Sriramakrishnan
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Tuesday, October 16, 2012 10:44 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; David
> Miller; Chemparathy, Cyril; Govindarajan, Sriramakrishnan
> Subject: Re: [PATCH V2 0/7] support the cpts found on am335x devices
> 
> On Tue, Oct 16, 2012 at 04:33:55PM +0000, N, Mugunthan V wrote:
> > I had seen some issues with the patch series.
> 
> Please take another look. Excepting the last, none of your points
> holds water.
> 
> > * CPTS will hold only LSB 32 bits of 64 bit Timer and the upper 32
> bit
> >   time value has to be taken care by the software, but the time stamp
> >   which is passed to skb or PTP clock consist of only 32 bit time
> value
> 
> The driver handles this already.
Yes, I do agree that driver handles it. As Half roll over and Full roll
over events are not handled in the driver, I am just curious how will
the misaligned TS would be handled and also in cpts set time, the Lower
32 bit time is written to CPTS counter
> 
> > * CPTS interrupts should be utilized to service Half and Full roll
> over
> >   events as it is non sync events with respect to get/set time and
> PTP
> >   pkt Tx/Rx
> 
> Nope, no need for interrupts, since we already have a better way to
> handle this.
Since we poll for the 32bit over flow for every HZ * 8 cycle, won't
there be a system overhead. If the CPTS ref clock is changed according
to the ptp freq adjust api, how will the timecounter take care of change
in frequency
> 
> > * CPTS Time which is obtained from hardware is not actually a nano
> >   seconds as the CPTS ref clock is tied to 250MHz for AM335x.
> 
> Did you even look at the code in my patch?
I had gone through the patch, but the same driver can be used in TI814x
where the user has the option to change the frequency from 250MHz may to
1GHz also, I thought of how it will be handled if we fix the multiplication
factor
> 
> > * CPSW register mapping done in this patch series removes the CPSW
> >   driver support for previous version found in TI814x
> 
> In which Linux version (or commit) did this driver appear?
> I never saw it.
The current driver which is in vanilla kernel doesn't use extended slave
address which are conflict between TI814x CPSW IP version and AM335x CPSW
IP version. I have just posted my version of CPTS implementation. May be
we can work together make the driver compatible with both CPSW versions
> 
> > * CPSW Time stamping is done only for port 0 and port 1 is not done
> 
> Yes, you are right, and it is strange that the hardware time stamps on
> the external ports of the switch, and not at the host port as it
> should. Of course it does present us with a problem, since we cannot
> reasonably have both ports time stamping at the same time. I propose
> simply using a device tree attribute to tell which port to activate.
Since CPSW is a 3port Switch we should not fix time stamping will be enabled
only for slave 0 or passing slave number through DT. Its better if we
can configure both the slaves. This can be tested with EVM-sk which has
both the slave ports pinned out.
> 
> Thanks,
> Richard
^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-16 23:11     ` N, Mugunthan V
@ 2012-10-17 18:27       ` Richard Cochran
  2012-10-22 10:39         ` N, Mugunthan V
  0 siblings, 1 reply; 14+ messages in thread
From: Richard Cochran @ 2012-10-17 18:27 UTC (permalink / raw)
  To: N, Mugunthan V
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	David Miller, Chemparathy, Cyril, Govindarajan, Sriramakrishnan
On Tue, Oct 16, 2012 at 11:11:29PM +0000, N, Mugunthan V wrote:
> 
> Yes, I do agree that driver handles it. As Half roll over and Full roll
> over events are not handled in the driver, I am just curious how will
> the misaligned TS would be handled and also in cpts set time, the Lower
> 32 bit time is written to CPTS counter
#include <linux/clocksource.h>
> Since we poll for the 32bit over flow for every HZ * 8 cycle, won't
> there be a system overhead. If the CPTS ref clock is changed according
> to the ptp freq adjust api, how will the timecounter take care of change
> in frequency
There is nothing to do here. What are you asking?
> The current driver which is in vanilla kernel doesn't use extended slave
> address which are conflict between TI814x CPSW IP version and AM335x CPSW
> IP version. I have just posted my version of CPTS implementation. May be
> we can work together make the driver compatible with both CPSW versions
Okay.
> Since CPSW is a 3port Switch we should not fix time stamping will be enabled
> only for slave 0 or passing slave number through DT. Its better if we
> can configure both the slaves. This can be tested with EVM-sk which has
> both the slave ports pinned out.
I hope that you meant, "better if we can configure _either_ slave."
Considering how SO_TIMESTAMPING works, you can't use both at once.
Thanks,
Richard
^ permalink raw reply	[flat|nested] 14+ messages in thread
* RE: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-17 18:27       ` Richard Cochran
@ 2012-10-22 10:39         ` N, Mugunthan V
  2012-10-22 11:02           ` Richard Cochran
  0 siblings, 1 reply; 14+ messages in thread
From: N, Mugunthan V @ 2012-10-22 10:39 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	David Miller, Chemparathy, Cyril, Govindarajan, Sriramakrishnan
> -----Original Message-----
> From: Richard Cochran [mailto:richardcochran@gmail.com]
> Sent: Wednesday, October 17, 2012 11:57 PM
> To: N, Mugunthan V
> Cc: netdev@vger.kernel.org; linux-arm-kernel@lists.infradead.org; David
> Miller; Chemparathy, Cyril; Govindarajan, Sriramakrishnan
> Subject: Re: [PATCH V2 0/7] support the cpts found on am335x devices
> 
> On Tue, Oct 16, 2012 at 11:11:29PM +0000, N, Mugunthan V wrote:
> >
> > Yes, I do agree that driver handles it. As Half roll over and Full
> roll
> > over events are not handled in the driver, I am just curious how will
> > the misaligned TS would be handled and also in cpts set time, the
> Lower
> > 32 bit time is written to CPTS counter
> 
> #include <linux/clocksource.h>
I think the timecounter_init initializes only the software. But still I am
not clear how the time given in cpts_ptp_settime will be projected to
hardware. Can you correct me if I am wrong.
> 
> > Since we poll for the 32bit over flow for every HZ * 8 cycle, won't
> > there be a system overhead. If the CPTS ref clock is changed
> according
> > to the ptp freq adjust api, how will the timecounter take care of
> change
> > in frequency
> 
> There is nothing to do here. What are you asking?
I think instead of fixing the driver to AM335X, let's make the driver
generic as the same driver can be used to TI814X, TI813X and other
upcoming platforms TI811X where the CPTS ref clock can be changed as
per usage requirement.
> 
> > The current driver which is in vanilla kernel doesn't use extended
> slave
> > address which are conflict between TI814x CPSW IP version and AM335x
> CPSW
> > IP version. I have just posted my version of CPTS implementation. May
> be
> > we can work together make the driver compatible with both CPSW
> versions
> 
> Okay.
> 
> > Since CPSW is a 3port Switch we should not fix time stamping will be
> enabled
> > only for slave 0 or passing slave number through DT. Its better if we
> > can configure both the slaves. This can be tested with EVM-sk which
> has
> > both the slave ports pinned out.
> 
> I hope that you meant, "better if we can configure _either_ slave."
> Considering how SO_TIMESTAMPING works, you can't use both at once.
> 
Since CPSW as a Ethernet switch, the PTP packet can be delivered to
any downstream port. So if we fix the PTP time stamping to one port
then the driver won't receive time stamping information when the packet
is delivered to the other port.
Regards
Mugunthan V N
^ permalink raw reply	[flat|nested] 14+ messages in thread
* Re: [PATCH V2 0/7] support the cpts found on am335x devices
  2012-10-22 10:39         ` N, Mugunthan V
@ 2012-10-22 11:02           ` Richard Cochran
  0 siblings, 0 replies; 14+ messages in thread
From: Richard Cochran @ 2012-10-22 11:02 UTC (permalink / raw)
  To: N, Mugunthan V
  Cc: netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	David Miller, Chemparathy, Cyril, Govindarajan, Sriramakrishnan
On Mon, Oct 22, 2012 at 10:39:40AM +0000, N, Mugunthan V wrote:
> 
> I think the timecounter_init initializes only the software. But still I am
> not clear how the time given in cpts_ptp_settime will be projected to
> hardware. Can you correct me if I am wrong.
Look at the settime function:
+static int cpts_ptp_settime(struct ptp_clock_info *ptp,
+			    const struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct cpts *cpts = container_of(ptp, struct cpts, info);
+
+	ns = ts->tv_sec * 1000000000ULL;
+	ns += ts->tv_nsec;
+
+	spin_lock_irqsave(&cpts->lock, flags);
+	timecounter_init(&cpts->tc, &cpts->cc, ns);
+	spin_unlock_irqrestore(&cpts->lock, flags);
+
+	return 0;
+}
Then, look at the implementation of timecounter_init().
> > > Since we poll for the 32bit over flow for every HZ * 8 cycle, won't
> > > there be a system overhead. If the CPTS ref clock is changed
> > according
> > > to the ptp freq adjust api, how will the timecounter take care of
> > change
> > > in frequency
> > 
> > There is nothing to do here. What are you asking?
> 
> I think instead of fixing the driver to AM335X, let's make the driver
> generic as the same driver can be used to TI814X, TI813X and other
> upcoming platforms TI811X where the CPTS ref clock can be changed as
> per usage requirement.
Now I see what your are worried about, but it really isn't a big
problem. The solution in your driver of doing a 64 bit division in the
hot path is unattractive and unnecessary. We can accomodate variable
reference clock frequencies using a board specific DT, just as we do
for gianfar today.
Let's just get the am335x working, shall we? Until we actually have
the other boards working, all this talk about TI81xx is really just
talk. I mean, ATM the CPSW does not work on *any* board at all.
> > I hope that you meant, "better if we can configure _either_ slave."
> > Considering how SO_TIMESTAMPING works, you can't use both at once.
> > 
> 
> Since CPSW as a Ethernet switch, the PTP packet can be delivered to
> any downstream port. So if we fix the PTP time stamping to one port
> then the driver won't receive time stamping information when the packet
> is delivered to the other port.
And just how is this supposed to work with SO_TIMESTAMPING?
Thanks,
Richard
^ permalink raw reply	[flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-10-22 11:02 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-15 19:48 [PATCH V2 0/7] support the cpts found on am335x devices Richard Cochran
2012-10-15 19:48 ` [PATCH V2 1/7] cpsw: rename register banks to match the reference manual Richard Cochran
2012-10-15 19:48 ` [PATCH V2 2/7] cpsw: add missing fields to the CPSW_SS register bank Richard Cochran
2012-10-15 19:48 ` [PATCH V2 3/7] cpsw: correct the CPSW_PORT register bank declaration Richard Cochran
2012-10-15 19:48 ` [PATCH V2 4/7] cpsw: add a common header file for regsiter declarations Richard Cochran
2012-10-15 19:48 ` [PATCH V2 5/7] cpts: introduce time stamping code and a PTP hardware clock Richard Cochran
2012-10-15 19:48 ` [PATCH V2 6/7] cpsw: add a DT field for the cpts offset Richard Cochran
2012-10-15 19:48 ` [PATCH V2 7/7] cpsw: use the time stamping capabilities of the cpts Richard Cochran
2012-10-16 16:33 ` [PATCH V2 0/7] support the cpts found on am335x devices N, Mugunthan V
2012-10-16 17:14   ` Richard Cochran
2012-10-16 23:11     ` N, Mugunthan V
2012-10-17 18:27       ` Richard Cochran
2012-10-22 10:39         ` N, Mugunthan V
2012-10-22 11:02           ` Richard Cochran
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).