xref: /openbmc/linux/drivers/net/ethernet/ti/cpts.h (revision 0d5f54fe)
187c0e764SRichard Cochran /*
287c0e764SRichard Cochran  * TI Common Platform Time Sync
387c0e764SRichard Cochran  *
487c0e764SRichard Cochran  * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
587c0e764SRichard Cochran  *
687c0e764SRichard Cochran  * This program is free software; you can redistribute it and/or modify
787c0e764SRichard Cochran  * it under the terms of the GNU General Public License as published by
887c0e764SRichard Cochran  * the Free Software Foundation; either version 2 of the License, or
987c0e764SRichard Cochran  * (at your option) any later version.
1087c0e764SRichard Cochran  *
1187c0e764SRichard Cochran  * This program is distributed in the hope that it will be useful,
1287c0e764SRichard Cochran  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1387c0e764SRichard Cochran  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1487c0e764SRichard Cochran  * GNU General Public License for more details.
1587c0e764SRichard Cochran  *
1687c0e764SRichard Cochran  * You should have received a copy of the GNU General Public License
1787c0e764SRichard Cochran  * along with this program; if not, write to the Free Software
1887c0e764SRichard Cochran  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1987c0e764SRichard Cochran  */
2087c0e764SRichard Cochran #ifndef _TI_CPTS_H_
2187c0e764SRichard Cochran #define _TI_CPTS_H_
2287c0e764SRichard Cochran 
238a2c9a5aSGrygorii Strashko #if IS_ENABLED(CONFIG_TI_CPTS)
248a2c9a5aSGrygorii Strashko 
2587c0e764SRichard Cochran #include <linux/clk.h>
2687c0e764SRichard Cochran #include <linux/clkdev.h>
2787c0e764SRichard Cochran #include <linux/clocksource.h>
2887c0e764SRichard Cochran #include <linux/device.h>
2987c0e764SRichard Cochran #include <linux/list.h>
304a88fb95SGrygorii Strashko #include <linux/of.h>
3187c0e764SRichard Cochran #include <linux/ptp_clock_kernel.h>
3287c0e764SRichard Cochran #include <linux/skbuff.h>
33f44f8417SIvan Khoronzhuk #include <linux/ptp_classify.h>
3474d23cc7SRichard Cochran #include <linux/timecounter.h>
3587c0e764SRichard Cochran 
3687c0e764SRichard Cochran struct cpsw_cpts {
3787c0e764SRichard Cochran 	u32 idver;                /* Identification and version */
3887c0e764SRichard Cochran 	u32 control;              /* Time sync control */
3987c0e764SRichard Cochran 	u32 res1;
4087c0e764SRichard Cochran 	u32 ts_push;              /* Time stamp event push */
4187c0e764SRichard Cochran 	u32 ts_load_val;          /* Time stamp load value */
4287c0e764SRichard Cochran 	u32 ts_load_en;           /* Time stamp load enable */
4387c0e764SRichard Cochran 	u32 res2[2];
4487c0e764SRichard Cochran 	u32 intstat_raw;          /* Time sync interrupt status raw */
4587c0e764SRichard Cochran 	u32 intstat_masked;       /* Time sync interrupt status masked */
4687c0e764SRichard Cochran 	u32 int_enable;           /* Time sync interrupt enable */
4787c0e764SRichard Cochran 	u32 res3;
4887c0e764SRichard Cochran 	u32 event_pop;            /* Event interrupt pop */
4987c0e764SRichard Cochran 	u32 event_low;            /* 32 Bit Event Time Stamp */
5087c0e764SRichard Cochran 	u32 event_high;           /* Event Type Fields */
5187c0e764SRichard Cochran };
5287c0e764SRichard Cochran 
5387c0e764SRichard Cochran /* Bit definitions for the IDVER register */
5487c0e764SRichard Cochran #define TX_IDENT_SHIFT       (16)    /* TX Identification Value */
5587c0e764SRichard Cochran #define TX_IDENT_MASK        (0xffff)
5687c0e764SRichard Cochran #define RTL_VER_SHIFT        (11)    /* RTL Version Value */
5787c0e764SRichard Cochran #define RTL_VER_MASK         (0x1f)
5887c0e764SRichard Cochran #define MAJOR_VER_SHIFT      (8)     /* Major Version Value */
5987c0e764SRichard Cochran #define MAJOR_VER_MASK       (0x7)
6087c0e764SRichard Cochran #define MINOR_VER_SHIFT      (0)     /* Minor Version Value */
6187c0e764SRichard Cochran #define MINOR_VER_MASK       (0xff)
6287c0e764SRichard Cochran 
6387c0e764SRichard Cochran /* Bit definitions for the CONTROL register */
6487c0e764SRichard Cochran #define HW4_TS_PUSH_EN       (1<<11) /* Hardware push 4 enable */
6587c0e764SRichard Cochran #define HW3_TS_PUSH_EN       (1<<10) /* Hardware push 3 enable */
6687c0e764SRichard Cochran #define HW2_TS_PUSH_EN       (1<<9)  /* Hardware push 2 enable */
6787c0e764SRichard Cochran #define HW1_TS_PUSH_EN       (1<<8)  /* Hardware push 1 enable */
6887c0e764SRichard Cochran #define INT_TEST             (1<<1)  /* Interrupt Test */
6987c0e764SRichard Cochran #define CPTS_EN              (1<<0)  /* Time Sync Enable */
7087c0e764SRichard Cochran 
7187c0e764SRichard Cochran /*
7287c0e764SRichard Cochran  * Definitions for the single bit resisters:
7387c0e764SRichard Cochran  * TS_PUSH TS_LOAD_EN  INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP
7487c0e764SRichard Cochran  */
7587c0e764SRichard Cochran #define TS_PUSH             (1<<0)  /* Time stamp event push */
7687c0e764SRichard Cochran #define TS_LOAD_EN          (1<<0)  /* Time Stamp Load */
7787c0e764SRichard Cochran #define TS_PEND_RAW         (1<<0)  /* int read (before enable) */
7887c0e764SRichard Cochran #define TS_PEND             (1<<0)  /* masked interrupt read (after enable) */
7987c0e764SRichard Cochran #define TS_PEND_EN          (1<<0)  /* masked interrupt enable */
8087c0e764SRichard Cochran #define EVENT_POP           (1<<0)  /* writing discards one event */
8187c0e764SRichard Cochran 
8287c0e764SRichard Cochran /* Bit definitions for the EVENT_HIGH register */
8387c0e764SRichard Cochran #define PORT_NUMBER_SHIFT    (24)    /* Indicates Ethernet port or HW pin */
8487c0e764SRichard Cochran #define PORT_NUMBER_MASK     (0x1f)
8587c0e764SRichard Cochran #define EVENT_TYPE_SHIFT     (20)    /* Time sync event type */
8687c0e764SRichard Cochran #define EVENT_TYPE_MASK      (0xf)
8787c0e764SRichard Cochran #define MESSAGE_TYPE_SHIFT   (16)    /* PTP message type */
8887c0e764SRichard Cochran #define MESSAGE_TYPE_MASK    (0xf)
8987c0e764SRichard Cochran #define SEQUENCE_ID_SHIFT    (0)     /* PTP message sequence ID */
9087c0e764SRichard Cochran #define SEQUENCE_ID_MASK     (0xffff)
9187c0e764SRichard Cochran 
9287c0e764SRichard Cochran enum {
9387c0e764SRichard Cochran 	CPTS_EV_PUSH, /* Time Stamp Push Event */
9487c0e764SRichard Cochran 	CPTS_EV_ROLL, /* Time Stamp Rollover Event */
9587c0e764SRichard Cochran 	CPTS_EV_HALF, /* Time Stamp Half Rollover Event */
9687c0e764SRichard Cochran 	CPTS_EV_HW,   /* Hardware Time Stamp Push Event */
9787c0e764SRichard Cochran 	CPTS_EV_RX,   /* Ethernet Receive Event */
9887c0e764SRichard Cochran 	CPTS_EV_TX,   /* Ethernet Transmit Event */
9987c0e764SRichard Cochran };
10087c0e764SRichard Cochran 
10187c0e764SRichard Cochran #define CPTS_FIFO_DEPTH 16
10287c0e764SRichard Cochran #define CPTS_MAX_EVENTS 32
10387c0e764SRichard Cochran 
10487c0e764SRichard Cochran struct cpts_event {
10587c0e764SRichard Cochran 	struct list_head list;
10687c0e764SRichard Cochran 	unsigned long tmo;
10787c0e764SRichard Cochran 	u32 high;
10887c0e764SRichard Cochran 	u32 low;
10987c0e764SRichard Cochran };
11087c0e764SRichard Cochran 
11187c0e764SRichard Cochran struct cpts {
1128a2c9a5aSGrygorii Strashko 	struct device *dev;
11387c0e764SRichard Cochran 	struct cpsw_cpts __iomem *reg;
11487c0e764SRichard Cochran 	int tx_enable;
11587c0e764SRichard Cochran 	int rx_enable;
11687c0e764SRichard Cochran 	struct ptp_clock_info info;
11787c0e764SRichard Cochran 	struct ptp_clock *clock;
11887c0e764SRichard Cochran 	spinlock_t lock; /* protects time registers */
11987c0e764SRichard Cochran 	u32 cc_mult; /* for the nominal frequency */
12087c0e764SRichard Cochran 	struct cyclecounter cc;
12187c0e764SRichard Cochran 	struct timecounter tc;
12287c0e764SRichard Cochran 	int phc_index;
12387c0e764SRichard Cochran 	struct clk *refclk;
12487c0e764SRichard Cochran 	struct list_head events;
12587c0e764SRichard Cochran 	struct list_head pool;
12687c0e764SRichard Cochran 	struct cpts_event pool_data[CPTS_MAX_EVENTS];
12720138cf9SGrygorii Strashko 	unsigned long ov_check_period;
1280d5f54feSGrygorii Strashko 	struct sk_buff_head txq;
12987c0e764SRichard Cochran };
13087c0e764SRichard Cochran 
13195f7f151SJoe Perches void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
13295f7f151SJoe Perches void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
1338a2c9a5aSGrygorii Strashko int cpts_register(struct cpts *cpts);
134c8395d4eSGrygorii Strashko void cpts_unregister(struct cpts *cpts);
1358a2c9a5aSGrygorii Strashko struct cpts *cpts_create(struct device *dev, void __iomem *regs,
1364a88fb95SGrygorii Strashko 			 struct device_node *node);
1378a2c9a5aSGrygorii Strashko void cpts_release(struct cpts *cpts);
138b63ba58eSGrygorii Strashko 
139b63ba58eSGrygorii Strashko static inline void cpts_rx_enable(struct cpts *cpts, int enable)
140b63ba58eSGrygorii Strashko {
141b63ba58eSGrygorii Strashko 	cpts->rx_enable = enable;
142b63ba58eSGrygorii Strashko }
143b63ba58eSGrygorii Strashko 
144b63ba58eSGrygorii Strashko static inline bool cpts_is_rx_enabled(struct cpts *cpts)
145b63ba58eSGrygorii Strashko {
146b63ba58eSGrygorii Strashko 	return !!cpts->rx_enable;
147b63ba58eSGrygorii Strashko }
148b63ba58eSGrygorii Strashko 
149b63ba58eSGrygorii Strashko static inline void cpts_tx_enable(struct cpts *cpts, int enable)
150b63ba58eSGrygorii Strashko {
151b63ba58eSGrygorii Strashko 	cpts->tx_enable = enable;
152b63ba58eSGrygorii Strashko }
153b63ba58eSGrygorii Strashko 
154b63ba58eSGrygorii Strashko static inline bool cpts_is_tx_enabled(struct cpts *cpts)
155b63ba58eSGrygorii Strashko {
156b63ba58eSGrygorii Strashko 	return !!cpts->tx_enable;
157b63ba58eSGrygorii Strashko }
158b63ba58eSGrygorii Strashko 
159f44f8417SIvan Khoronzhuk static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb)
160f44f8417SIvan Khoronzhuk {
161f44f8417SIvan Khoronzhuk 	unsigned int class = ptp_classify_raw(skb);
162f44f8417SIvan Khoronzhuk 
163f44f8417SIvan Khoronzhuk 	if (class == PTP_CLASS_NONE)
164f44f8417SIvan Khoronzhuk 		return false;
165f44f8417SIvan Khoronzhuk 
166f44f8417SIvan Khoronzhuk 	return true;
167f44f8417SIvan Khoronzhuk }
168f44f8417SIvan Khoronzhuk 
16987c0e764SRichard Cochran #else
1708a2c9a5aSGrygorii Strashko struct cpts;
1718a2c9a5aSGrygorii Strashko 
17287c0e764SRichard Cochran static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
17387c0e764SRichard Cochran {
17487c0e764SRichard Cochran }
17587c0e764SRichard Cochran static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
17687c0e764SRichard Cochran {
17787c0e764SRichard Cochran }
178c8395d4eSGrygorii Strashko 
1798a2c9a5aSGrygorii Strashko static inline
1808a2c9a5aSGrygorii Strashko struct cpts *cpts_create(struct device *dev, void __iomem *regs,
1814a88fb95SGrygorii Strashko 			 struct device_node *node)
1828a2c9a5aSGrygorii Strashko {
1838a2c9a5aSGrygorii Strashko 	return NULL;
1848a2c9a5aSGrygorii Strashko }
1858a2c9a5aSGrygorii Strashko 
1868a2c9a5aSGrygorii Strashko static inline void cpts_release(struct cpts *cpts)
1878a2c9a5aSGrygorii Strashko {
1888a2c9a5aSGrygorii Strashko }
1898a2c9a5aSGrygorii Strashko 
190c8395d4eSGrygorii Strashko static inline int
1918a2c9a5aSGrygorii Strashko cpts_register(struct cpts *cpts)
192c8395d4eSGrygorii Strashko {
193c8395d4eSGrygorii Strashko 	return 0;
194c8395d4eSGrygorii Strashko }
195c8395d4eSGrygorii Strashko 
196c8395d4eSGrygorii Strashko static inline void cpts_unregister(struct cpts *cpts)
197c8395d4eSGrygorii Strashko {
198c8395d4eSGrygorii Strashko }
199b63ba58eSGrygorii Strashko 
200b63ba58eSGrygorii Strashko static inline void cpts_rx_enable(struct cpts *cpts, int enable)
201b63ba58eSGrygorii Strashko {
202b63ba58eSGrygorii Strashko }
203b63ba58eSGrygorii Strashko 
204b63ba58eSGrygorii Strashko static inline bool cpts_is_rx_enabled(struct cpts *cpts)
205b63ba58eSGrygorii Strashko {
206b63ba58eSGrygorii Strashko 	return false;
207b63ba58eSGrygorii Strashko }
208b63ba58eSGrygorii Strashko 
209b63ba58eSGrygorii Strashko static inline void cpts_tx_enable(struct cpts *cpts, int enable)
210b63ba58eSGrygorii Strashko {
211b63ba58eSGrygorii Strashko }
212b63ba58eSGrygorii Strashko 
213b63ba58eSGrygorii Strashko static inline bool cpts_is_tx_enabled(struct cpts *cpts)
214b63ba58eSGrygorii Strashko {
215b63ba58eSGrygorii Strashko 	return false;
216b63ba58eSGrygorii Strashko }
217f44f8417SIvan Khoronzhuk 
218f44f8417SIvan Khoronzhuk static inline bool cpts_can_timestamp(struct cpts *cpts, struct sk_buff *skb)
219f44f8417SIvan Khoronzhuk {
220f44f8417SIvan Khoronzhuk 	return false;
221f44f8417SIvan Khoronzhuk }
22287c0e764SRichard Cochran #endif
22387c0e764SRichard Cochran 
22487c0e764SRichard Cochran 
22587c0e764SRichard Cochran #endif
226