xref: /openbmc/linux/drivers/net/ethernet/ti/cpts.h (revision 8a2c9a5a)
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>
3087c0e764SRichard Cochran #include <linux/ptp_clock_kernel.h>
3187c0e764SRichard Cochran #include <linux/skbuff.h>
3274d23cc7SRichard Cochran #include <linux/timecounter.h>
3387c0e764SRichard Cochran 
3487c0e764SRichard Cochran struct cpsw_cpts {
3587c0e764SRichard Cochran 	u32 idver;                /* Identification and version */
3687c0e764SRichard Cochran 	u32 control;              /* Time sync control */
3787c0e764SRichard Cochran 	u32 res1;
3887c0e764SRichard Cochran 	u32 ts_push;              /* Time stamp event push */
3987c0e764SRichard Cochran 	u32 ts_load_val;          /* Time stamp load value */
4087c0e764SRichard Cochran 	u32 ts_load_en;           /* Time stamp load enable */
4187c0e764SRichard Cochran 	u32 res2[2];
4287c0e764SRichard Cochran 	u32 intstat_raw;          /* Time sync interrupt status raw */
4387c0e764SRichard Cochran 	u32 intstat_masked;       /* Time sync interrupt status masked */
4487c0e764SRichard Cochran 	u32 int_enable;           /* Time sync interrupt enable */
4587c0e764SRichard Cochran 	u32 res3;
4687c0e764SRichard Cochran 	u32 event_pop;            /* Event interrupt pop */
4787c0e764SRichard Cochran 	u32 event_low;            /* 32 Bit Event Time Stamp */
4887c0e764SRichard Cochran 	u32 event_high;           /* Event Type Fields */
4987c0e764SRichard Cochran };
5087c0e764SRichard Cochran 
5187c0e764SRichard Cochran /* Bit definitions for the IDVER register */
5287c0e764SRichard Cochran #define TX_IDENT_SHIFT       (16)    /* TX Identification Value */
5387c0e764SRichard Cochran #define TX_IDENT_MASK        (0xffff)
5487c0e764SRichard Cochran #define RTL_VER_SHIFT        (11)    /* RTL Version Value */
5587c0e764SRichard Cochran #define RTL_VER_MASK         (0x1f)
5687c0e764SRichard Cochran #define MAJOR_VER_SHIFT      (8)     /* Major Version Value */
5787c0e764SRichard Cochran #define MAJOR_VER_MASK       (0x7)
5887c0e764SRichard Cochran #define MINOR_VER_SHIFT      (0)     /* Minor Version Value */
5987c0e764SRichard Cochran #define MINOR_VER_MASK       (0xff)
6087c0e764SRichard Cochran 
6187c0e764SRichard Cochran /* Bit definitions for the CONTROL register */
6287c0e764SRichard Cochran #define HW4_TS_PUSH_EN       (1<<11) /* Hardware push 4 enable */
6387c0e764SRichard Cochran #define HW3_TS_PUSH_EN       (1<<10) /* Hardware push 3 enable */
6487c0e764SRichard Cochran #define HW2_TS_PUSH_EN       (1<<9)  /* Hardware push 2 enable */
6587c0e764SRichard Cochran #define HW1_TS_PUSH_EN       (1<<8)  /* Hardware push 1 enable */
6687c0e764SRichard Cochran #define INT_TEST             (1<<1)  /* Interrupt Test */
6787c0e764SRichard Cochran #define CPTS_EN              (1<<0)  /* Time Sync Enable */
6887c0e764SRichard Cochran 
6987c0e764SRichard Cochran /*
7087c0e764SRichard Cochran  * Definitions for the single bit resisters:
7187c0e764SRichard Cochran  * TS_PUSH TS_LOAD_EN  INTSTAT_RAW INTSTAT_MASKED INT_ENABLE EVENT_POP
7287c0e764SRichard Cochran  */
7387c0e764SRichard Cochran #define TS_PUSH             (1<<0)  /* Time stamp event push */
7487c0e764SRichard Cochran #define TS_LOAD_EN          (1<<0)  /* Time Stamp Load */
7587c0e764SRichard Cochran #define TS_PEND_RAW         (1<<0)  /* int read (before enable) */
7687c0e764SRichard Cochran #define TS_PEND             (1<<0)  /* masked interrupt read (after enable) */
7787c0e764SRichard Cochran #define TS_PEND_EN          (1<<0)  /* masked interrupt enable */
7887c0e764SRichard Cochran #define EVENT_POP           (1<<0)  /* writing discards one event */
7987c0e764SRichard Cochran 
8087c0e764SRichard Cochran /* Bit definitions for the EVENT_HIGH register */
8187c0e764SRichard Cochran #define PORT_NUMBER_SHIFT    (24)    /* Indicates Ethernet port or HW pin */
8287c0e764SRichard Cochran #define PORT_NUMBER_MASK     (0x1f)
8387c0e764SRichard Cochran #define EVENT_TYPE_SHIFT     (20)    /* Time sync event type */
8487c0e764SRichard Cochran #define EVENT_TYPE_MASK      (0xf)
8587c0e764SRichard Cochran #define MESSAGE_TYPE_SHIFT   (16)    /* PTP message type */
8687c0e764SRichard Cochran #define MESSAGE_TYPE_MASK    (0xf)
8787c0e764SRichard Cochran #define SEQUENCE_ID_SHIFT    (0)     /* PTP message sequence ID */
8887c0e764SRichard Cochran #define SEQUENCE_ID_MASK     (0xffff)
8987c0e764SRichard Cochran 
9087c0e764SRichard Cochran enum {
9187c0e764SRichard Cochran 	CPTS_EV_PUSH, /* Time Stamp Push Event */
9287c0e764SRichard Cochran 	CPTS_EV_ROLL, /* Time Stamp Rollover Event */
9387c0e764SRichard Cochran 	CPTS_EV_HALF, /* Time Stamp Half Rollover Event */
9487c0e764SRichard Cochran 	CPTS_EV_HW,   /* Hardware Time Stamp Push Event */
9587c0e764SRichard Cochran 	CPTS_EV_RX,   /* Ethernet Receive Event */
9687c0e764SRichard Cochran 	CPTS_EV_TX,   /* Ethernet Transmit Event */
9787c0e764SRichard Cochran };
9887c0e764SRichard Cochran 
9987c0e764SRichard Cochran /* This covers any input clock up to about 500 MHz. */
10087c0e764SRichard Cochran #define CPTS_OVERFLOW_PERIOD (HZ * 8)
10187c0e764SRichard Cochran 
10287c0e764SRichard Cochran #define CPTS_FIFO_DEPTH 16
10387c0e764SRichard Cochran #define CPTS_MAX_EVENTS 32
10487c0e764SRichard Cochran 
10587c0e764SRichard Cochran struct cpts_event {
10687c0e764SRichard Cochran 	struct list_head list;
10787c0e764SRichard Cochran 	unsigned long tmo;
10887c0e764SRichard Cochran 	u32 high;
10987c0e764SRichard Cochran 	u32 low;
11087c0e764SRichard Cochran };
11187c0e764SRichard Cochran 
11287c0e764SRichard Cochran struct cpts {
1138a2c9a5aSGrygorii Strashko 	struct device *dev;
11487c0e764SRichard Cochran 	struct cpsw_cpts __iomem *reg;
11587c0e764SRichard Cochran 	int tx_enable;
11687c0e764SRichard Cochran 	int rx_enable;
11787c0e764SRichard Cochran 	struct ptp_clock_info info;
11887c0e764SRichard Cochran 	struct ptp_clock *clock;
11987c0e764SRichard Cochran 	spinlock_t lock; /* protects time registers */
12087c0e764SRichard Cochran 	u32 cc_mult; /* for the nominal frequency */
12187c0e764SRichard Cochran 	struct cyclecounter cc;
12287c0e764SRichard Cochran 	struct timecounter tc;
12387c0e764SRichard Cochran 	struct delayed_work overflow_work;
12487c0e764SRichard Cochran 	int phc_index;
12587c0e764SRichard Cochran 	struct clk *refclk;
12687c0e764SRichard Cochran 	struct list_head events;
12787c0e764SRichard Cochran 	struct list_head pool;
12887c0e764SRichard Cochran 	struct cpts_event pool_data[CPTS_MAX_EVENTS];
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,
1368a2c9a5aSGrygorii Strashko 			 u32 mult, u32 shift);
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 
15987c0e764SRichard Cochran #else
1608a2c9a5aSGrygorii Strashko struct cpts;
1618a2c9a5aSGrygorii Strashko 
16287c0e764SRichard Cochran static inline void cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
16387c0e764SRichard Cochran {
16487c0e764SRichard Cochran }
16587c0e764SRichard Cochran static inline void cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
16687c0e764SRichard Cochran {
16787c0e764SRichard Cochran }
168c8395d4eSGrygorii Strashko 
1698a2c9a5aSGrygorii Strashko static inline
1708a2c9a5aSGrygorii Strashko struct cpts *cpts_create(struct device *dev, void __iomem *regs,
1718a2c9a5aSGrygorii Strashko 			 u32 mult, u32 shift)
1728a2c9a5aSGrygorii Strashko {
1738a2c9a5aSGrygorii Strashko 	return NULL;
1748a2c9a5aSGrygorii Strashko }
1758a2c9a5aSGrygorii Strashko 
1768a2c9a5aSGrygorii Strashko static inline void cpts_release(struct cpts *cpts)
1778a2c9a5aSGrygorii Strashko {
1788a2c9a5aSGrygorii Strashko }
1798a2c9a5aSGrygorii Strashko 
180c8395d4eSGrygorii Strashko static inline int
1818a2c9a5aSGrygorii Strashko cpts_register(struct cpts *cpts)
182c8395d4eSGrygorii Strashko {
183c8395d4eSGrygorii Strashko 	return 0;
184c8395d4eSGrygorii Strashko }
185c8395d4eSGrygorii Strashko 
186c8395d4eSGrygorii Strashko static inline void cpts_unregister(struct cpts *cpts)
187c8395d4eSGrygorii Strashko {
188c8395d4eSGrygorii Strashko }
189b63ba58eSGrygorii Strashko 
190b63ba58eSGrygorii Strashko static inline void cpts_rx_enable(struct cpts *cpts, int enable)
191b63ba58eSGrygorii Strashko {
192b63ba58eSGrygorii Strashko }
193b63ba58eSGrygorii Strashko 
194b63ba58eSGrygorii Strashko static inline bool cpts_is_rx_enabled(struct cpts *cpts)
195b63ba58eSGrygorii Strashko {
196b63ba58eSGrygorii Strashko 	return false;
197b63ba58eSGrygorii Strashko }
198b63ba58eSGrygorii Strashko 
199b63ba58eSGrygorii Strashko static inline void cpts_tx_enable(struct cpts *cpts, int enable)
200b63ba58eSGrygorii Strashko {
201b63ba58eSGrygorii Strashko }
202b63ba58eSGrygorii Strashko 
203b63ba58eSGrygorii Strashko static inline bool cpts_is_tx_enabled(struct cpts *cpts)
204b63ba58eSGrygorii Strashko {
205b63ba58eSGrygorii Strashko 	return false;
206b63ba58eSGrygorii Strashko }
20787c0e764SRichard Cochran #endif
20887c0e764SRichard Cochran 
20987c0e764SRichard Cochran 
21087c0e764SRichard Cochran #endif
211