2019-04-26 20:12:23 +03:00
/* SPDX-License-Identifier: GPL-2.0+ */
2012-10-29 08:45:16 +00:00
/*
* TI Common Platform Time Sync
*
* Copyright ( C ) 2012 Richard Cochran < richardcochran @ gmail . com >
*
*/
# ifndef _TI_CPTS_H_
# define _TI_CPTS_H_
2016-12-06 18:00:41 -06:00
# if IS_ENABLED(CONFIG_TI_CPTS)
2012-10-29 08:45:16 +00:00
# include <linux/clk.h>
# include <linux/clkdev.h>
# include <linux/clocksource.h>
# include <linux/device.h>
# include <linux/list.h>
2016-12-06 18:00:42 -06:00
# include <linux/of.h>
2012-10-29 08:45:16 +00:00
# include <linux/ptp_clock_kernel.h>
# include <linux/skbuff.h>
2017-06-27 16:58:52 +03:00
# include <linux/ptp_classify.h>
2014-12-21 19:46:56 +01:00
# include <linux/timecounter.h>
2012-10-29 08:45:16 +00:00
struct cpsw_cpts {
u32 idver ; /* Identification and version */
u32 control ; /* Time sync control */
2019-06-06 19:30:41 +03:00
u32 rftclk_sel ; /* Reference Clock Select Register */
2012-10-29 08:45:16 +00:00
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 */
} ;
# define CPTS_FIFO_DEPTH 16
# define CPTS_MAX_EVENTS 32
struct cpts_event {
struct list_head list ;
unsigned long tmo ;
u32 high ;
u32 low ;
2020-04-23 17:20:14 +03:00
u64 timestamp ;
2012-10-29 08:45:16 +00:00
} ;
struct cpts {
2016-12-06 18:00:41 -06:00
struct device * dev ;
2012-10-29 08:45:16 +00:00
struct cpsw_cpts __iomem * reg ;
int tx_enable ;
int rx_enable ;
struct ptp_clock_info info ;
struct ptp_clock * clock ;
spinlock_t lock ; /* protects time registers */
u32 cc_mult ; /* for the nominal frequency */
struct cyclecounter cc ;
struct timecounter tc ;
int phc_index ;
struct clk * refclk ;
struct list_head events ;
struct list_head pool ;
struct cpts_event pool_data [ CPTS_MAX_EVENTS ] ;
2016-12-06 18:00:45 -06:00
unsigned long ov_check_period ;
2017-07-28 17:30:04 -05:00
struct sk_buff_head txq ;
2020-04-23 17:20:14 +03:00
u64 cur_timestamp ;
2012-10-29 08:45:16 +00:00
} ;
2013-09-23 11:37:59 -07:00
void cpts_rx_timestamp ( struct cpts * cpts , struct sk_buff * skb ) ;
void cpts_tx_timestamp ( struct cpts * cpts , struct sk_buff * skb ) ;
2016-12-06 18:00:41 -06:00
int cpts_register ( struct cpts * cpts ) ;
2016-12-06 18:00:34 -06:00
void cpts_unregister ( struct cpts * cpts ) ;
2016-12-06 18:00:41 -06:00
struct cpts * cpts_create ( struct device * dev , void __iomem * regs ,
2016-12-06 18:00:42 -06:00
struct device_node * node ) ;
2016-12-06 18:00:41 -06:00
void cpts_release ( struct cpts * cpts ) ;
2016-12-06 18:00:35 -06:00
2017-06-27 16:58:52 +03:00
static inline bool cpts_can_timestamp ( struct cpts * cpts , struct sk_buff * skb )
{
unsigned int class = ptp_classify_raw ( skb ) ;
if ( class = = PTP_CLASS_NONE )
return false ;
return true ;
}
2012-10-29 08:45:16 +00:00
# else
2016-12-06 18:00:41 -06:00
struct cpts ;
2012-10-29 08:45:16 +00:00
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 )
{
}
2016-12-06 18:00:34 -06:00
2016-12-06 18:00:41 -06:00
static inline
struct cpts * cpts_create ( struct device * dev , void __iomem * regs ,
2016-12-06 18:00:42 -06:00
struct device_node * node )
2016-12-06 18:00:41 -06:00
{
return NULL ;
}
static inline void cpts_release ( struct cpts * cpts )
{
}
2016-12-06 18:00:34 -06:00
static inline int
2016-12-06 18:00:41 -06:00
cpts_register ( struct cpts * cpts )
2016-12-06 18:00:34 -06:00
{
return 0 ;
}
static inline void cpts_unregister ( struct cpts * cpts )
{
}
2016-12-06 18:00:35 -06:00
2017-06-27 16:58:52 +03:00
static inline bool cpts_can_timestamp ( struct cpts * cpts , struct sk_buff * skb )
{
return false ;
}
2012-10-29 08:45:16 +00:00
# endif
# endif