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