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