Blame view

kernel/linux-rt-4.4.41/drivers/net/ethernet/ti/cpts.h 6.97 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  /*
   * TI Common Platform Time Sync
   *
   * Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  #ifndef _TI_CPTS_H_
  #define _TI_CPTS_H_
  
  #if IS_ENABLED(CONFIG_TI_CPTS)
  
  #include <linux/clk.h>
  #include <linux/clkdev.h>
  #include <linux/clocksource.h>
  #include <linux/device.h>
  #include <linux/list.h>
  #include <linux/of.h>
  #include <linux/ptp_clock_kernel.h>
  #include <linux/skbuff.h>
  #include <linux/timecounter.h>
  
  struct cpsw_cpts {
  	u32 idver;                /* Identification and version */
  	u32 control;              /* Time sync control */
  	u32 rftclk_sel;		  /* Reference Clock Select Register */
  	u32 ts_push;              /* Time stamp event push */
  	u32 ts_load_val;          /* Time stamp load value */
  	u32 ts_load_en;           /* Time stamp load enable */
  	u32 ts_comp_val;          /* Time stamp comparison value, v1.5 & up */
  	u32 ts_comp_length;       /* Time stamp comp assert len, v1.5 & up */
  	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 TS_COMP_POL	     BIT(2)  /* TS_COMP Polarity */
  #define INT_TEST             (1<<1)  /* Interrupt Test */
  #define CPTS_EN              (1<<0)  /* Time Sync Enable */
  
  #define CPTS_RFTCLK_SEL_MASK 0x1f
  
  #define CPTS_TS_COMP_LENGTH_MASK 0xffff
  
  /*
   * 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 */
  	CPTS_EV_COMP, /* Time Stamp Compare Event */
  };
  
  #define CPTS_FIFO_DEPTH 16
  #define CPTS_MAX_EVENTS 32
  
  #define CPTS_EVENT_RX_TX_TIMEOUT 20 /* ms */
  #define CPTS_EVENT_HWSTAMP_TIMEOUT 200 /* ms */
  
  struct cpts_event {
  	struct list_head list;
  	unsigned long tmo;
  	u32 high;
  	u32 low;
  };
  
  #define CPTS_CAP_RFTCLK_SEL BIT(0)
  #define CPTS_CAP_TS_COMP_EN BIT(1)
  #define CPTS_CAP_TS_COMP_POL_LOW_SEL BIT(2)
  
  struct cpts {
  	struct device *dev;
  	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;
  	struct delayed_work overflow_work;
  	int phc_index;
  	struct clk *refclk;
  	struct list_head events;
  	struct list_head pool;
  	struct cpts_event pool_data[CPTS_MAX_EVENTS];
  	unsigned long ov_check_period;
  	unsigned long ov_check_period_slow;
  	u32 rftclk_sel;
  	u32 ext_ts_inputs;
  	u32 hw_ts_enable;
  	u32 caps;
  	u32 ts_comp_next;	/* next time_stamp value to compare with */
  	u32 ts_comp_length;	/* TS_COMP Output pulse width */
  	u32 ts_comp_one_sec_cycs; /* number of counter cycles in one sec */
  	int ts_comp_enabled;
  	struct mutex ptp_clk_mutex; /* sync PTP interface with overflow_work */
  };
  
  int cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb);
  int cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb);
  int cpts_register(struct cpts *cpts);
  void cpts_unregister(struct cpts *cpts);
  struct cpts *cpts_create(struct device *dev, void __iomem *regs,
  			 struct device_node *node);
  void cpts_release(struct cpts *cpts);
  
  static inline void cpts_rx_enable(struct cpts *cpts, int enable)
  {
  	cpts->rx_enable = enable;
  }
  
  static inline bool cpts_is_rx_enabled(struct cpts *cpts)
  {
  	return !!cpts->rx_enable;
  }
  
  static inline void cpts_tx_enable(struct cpts *cpts, int enable)
  {
  	cpts->tx_enable = enable;
  }
  
  static inline bool cpts_is_tx_enabled(struct cpts *cpts)
  {
  	return !!cpts->tx_enable;
  }
  
  #else
  struct cpts;
  
  static inline int cpts_rx_timestamp(struct cpts *cpts, struct sk_buff *skb)
  {
  	return -EOPNOTSUPP;
  }
  
  static inline int cpts_tx_timestamp(struct cpts *cpts, struct sk_buff *skb)
  {
  	return -EOPNOTSUPP;
  }
  
  static inline
  struct cpts *cpts_create(struct device *dev, void __iomem *regs,
  			 struct device_node *node)
  {
  	return NULL;
  }
  
  static inline void cpts_release(struct cpts *cpts)
  {
  }
  
  static inline int
  cpts_register(struct cpts *cpts)
  {
  	return 0;
  }
  
  static inline void cpts_unregister(struct cpts *cpts)
  {
  }
  
  static inline void cpts_rx_enable(struct cpts *cpts, int enable)
  {
  }
  
  static inline bool cpts_is_rx_enabled(struct cpts *cpts)
  {
  	return false;
  }
  
  static inline void cpts_tx_enable(struct cpts *cpts, int enable)
  {
  }
  
  static inline bool cpts_is_tx_enabled(struct cpts *cpts)
  {
  	return false;
  }
  #endif
  
  
  #endif