summaryrefslogtreecommitdiff
path: root/drivers/net/phy/microchip_rds_ptp.h
blob: 25af68337b94a4033b3a1c3409ada50e9d875da0 (plain)
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
237
238
239
240
241
242
243
244
245
246
247
/* SPDX-License-Identifier: GPL-2.0
 * Copyright (C) 2024 Microchip Technology
 */

#ifndef _MICROCHIP_RDS_PTP_H
#define _MICROCHIP_RDS_PTP_H

#include <linux/ptp_clock_kernel.h>
#include <linux/ptp_clock.h>
#include <linux/ptp_classify.h>
#include <linux/net_tstamp.h>
#include <linux/mii.h>
#include <linux/phy.h>

#define MCHP_RDS_PTP_CMD_CTL			0x0
#define MCHP_RDS_PTP_CMD_CTL_LTC_STEP_NSEC	BIT(6)
#define MCHP_RDS_PTP_CMD_CTL_LTC_STEP_SEC	BIT(5)
#define MCHP_RDS_PTP_CMD_CTL_CLOCK_LOAD		BIT(4)
#define MCHP_RDS_PTP_CMD_CTL_CLOCK_READ		BIT(3)
#define MCHP_RDS_PTP_CMD_CTL_EN			BIT(1)
#define MCHP_RDS_PTP_CMD_CTL_DIS		BIT(0)

#define MCHP_RDS_PTP_REF_CLK_CFG		0x2
#define MCHP_RDS_PTP_REF_CLK_SRC_250MHZ		0x0
#define MCHP_RDS_PTP_REF_CLK_PERIOD_OVERRIDE	BIT(9)
#define MCHP_RDS_PTP_REF_CLK_PERIOD		4
#define MCHP_RDS_PTP_REF_CLK_CFG_SET	(MCHP_RDS_PTP_REF_CLK_SRC_250MHZ |\
					 MCHP_RDS_PTP_REF_CLK_PERIOD_OVERRIDE |\
					 MCHP_RDS_PTP_REF_CLK_PERIOD)

#define MCHP_RDS_PTP_LTC_SEC_HI			0x5
#define MCHP_RDS_PTP_LTC_SEC_MID		0x6
#define MCHP_RDS_PTP_LTC_SEC_LO			0x7
#define MCHP_RDS_PTP_LTC_NS_HI			0x8
#define MCHP_RDS_PTP_LTC_NS_LO			0x9
#define MCHP_RDS_PTP_LTC_RATE_ADJ_HI		0xc
#define MCHP_RDS_PTP_LTC_RATE_ADJ_HI_DIR	BIT(15)
#define MCHP_RDS_PTP_LTC_RATE_ADJ_LO		0xd
#define MCHP_RDS_PTP_STEP_ADJ_HI		0x12
#define MCHP_RDS_PTP_STEP_ADJ_HI_DIR		BIT(15)
#define MCHP_RDS_PTP_STEP_ADJ_LO		0x13
#define MCHP_RDS_PTP_LTC_READ_SEC_HI		0x29
#define MCHP_RDS_PTP_LTC_READ_SEC_MID		0x2a
#define MCHP_RDS_PTP_LTC_READ_SEC_LO		0x2b
#define MCHP_RDS_PTP_LTC_READ_NS_HI		0x2c
#define MCHP_RDS_PTP_LTC_READ_NS_LO		0x2d
#define MCHP_RDS_PTP_OP_MODE			0x41
#define MCHP_RDS_PTP_OP_MODE_DIS		0
#define MCHP_RDS_PTP_OP_MODE_STANDALONE		1
#define MCHP_RDS_PTP_LATENCY_CORRECTION_CTL	0x44
#define MCHP_RDS_PTP_PREDICTOR_EN		BIT(6)
#define MCHP_RDS_PTP_TX_PRED_DIS		BIT(1)
#define MCHP_RDS_PTP_RX_PRED_DIS		BIT(0)
#define MCHP_RDS_PTP_LATENCY_SETTING		(MCHP_RDS_PTP_PREDICTOR_EN | \
						 MCHP_RDS_PTP_TX_PRED_DIS | \
						 MCHP_RDS_PTP_RX_PRED_DIS)

#define MCHP_RDS_PTP_INT_EN			0x0
#define MCHP_RDS_PTP_INT_STS			0x01
#define MCHP_RDS_PTP_INT_TX_TS_OVRFL_EN		BIT(3)
#define MCHP_RDS_PTP_INT_TX_TS_EN		BIT(2)
#define MCHP_RDS_PTP_INT_RX_TS_OVRFL_EN		BIT(1)
#define MCHP_RDS_PTP_INT_RX_TS_EN		BIT(0)
#define MCHP_RDS_PTP_INT_ALL_MSK	(MCHP_RDS_PTP_INT_TX_TS_OVRFL_EN | \
					 MCHP_RDS_PTP_INT_TX_TS_EN | \
					 MCHP_RDS_PTP_INT_RX_TS_OVRFL_EN |\
					 MCHP_RDS_PTP_INT_RX_TS_EN)

#define MCHP_RDS_PTP_CAP_INFO			0x2e
#define MCHP_RDS_PTP_TX_TS_CNT(v)		(((v) & GENMASK(11, 8)) >> 8)
#define MCHP_RDS_PTP_RX_TS_CNT(v)		((v) & GENMASK(3, 0))

#define MCHP_RDS_PTP_RX_PARSE_CONFIG		0x42
#define MCHP_RDS_PTP_RX_PARSE_L2_ADDR_EN	0x44
#define MCHP_RDS_PTP_RX_PARSE_IPV4_ADDR_EN	0x45

#define MCHP_RDS_PTP_RX_TIMESTAMP_CONFIG	0x4e
#define MCHP_RDS_PTP_RX_TIMESTAMP_CONFIG_PTP_FCS_DIS BIT(0)

#define MCHP_RDS_PTP_RX_VERSION			0x48
#define MCHP_RDS_PTP_RX_TIMESTAMP_EN		0x4d

#define MCHP_RDS_PTP_RX_INGRESS_NS_HI		0x54
#define MCHP_RDS_PTP_RX_INGRESS_NS_HI_TS_VALID	BIT(15)

#define MCHP_RDS_PTP_RX_INGRESS_NS_LO		0x55
#define MCHP_RDS_PTP_RX_INGRESS_SEC_HI		0x56
#define MCHP_RDS_PTP_RX_INGRESS_SEC_LO		0x57
#define MCHP_RDS_PTP_RX_MSG_HDR2		0x59

#define MCHP_RDS_PTP_TX_PARSE_CONFIG		0x82
#define MCHP_RDS_PTP_PARSE_CONFIG_LAYER2_EN	BIT(0)
#define MCHP_RDS_PTP_PARSE_CONFIG_IPV4_EN	BIT(1)
#define MCHP_RDS_PTP_PARSE_CONFIG_IPV6_EN	BIT(2)

#define MCHP_RDS_PTP_TX_PARSE_L2_ADDR_EN	0x84
#define MCHP_RDS_PTP_TX_PARSE_IPV4_ADDR_EN	0x85

#define MCHP_RDS_PTP_TX_VERSION			0x88
#define MCHP_RDS_PTP_MAX_VERSION(x)		(((x) & GENMASK(7, 0)) << 8)
#define MCHP_RDS_PTP_MIN_VERSION(x)		((x) & GENMASK(7, 0))

#define MCHP_RDS_PTP_TX_TIMESTAMP_EN		0x8d
#define MCHP_RDS_PTP_TIMESTAMP_EN_SYNC		BIT(0)
#define MCHP_RDS_PTP_TIMESTAMP_EN_DREQ		BIT(1)
#define MCHP_RDS_PTP_TIMESTAMP_EN_PDREQ		BIT(2)
#define MCHP_RDS_PTP_TIMESTAMP_EN_PDRES		BIT(3)
#define MCHP_RDS_PTP_TIMESTAMP_EN_ALL	(MCHP_RDS_PTP_TIMESTAMP_EN_SYNC |\
					 MCHP_RDS_PTP_TIMESTAMP_EN_DREQ |\
					 MCHP_RDS_PTP_TIMESTAMP_EN_PDREQ |\
					 MCHP_RDS_PTP_TIMESTAMP_EN_PDRES)

#define MCHP_RDS_PTP_TX_TIMESTAMP_CONFIG	0x8e
#define MCHP_RDS_PTP_TX_TIMESTAMP_CONFIG_PTP_FCS_DIS BIT(0)

#define MCHP_RDS_PTP_TX_MOD			0x8f
#define MCHP_RDS_TX_MOD_PTP_SYNC_TS_INSERT	BIT(12)

#define MCHP_RDS_PTP_TX_EGRESS_NS_HI		0x94
#define MCHP_RDS_PTP_TX_EGRESS_NS_HI_TS_VALID	BIT(15)

#define MCHP_RDS_PTP_TX_EGRESS_NS_LO		0x95
#define MCHP_RDS_PTP_TX_EGRESS_SEC_HI		0x96
#define MCHP_RDS_PTP_TX_EGRESS_SEC_LO		0x97
#define MCHP_RDS_PTP_TX_MSG_HDR2		0x99

#define MCHP_RDS_PTP_TSU_GEN_CONFIG		0xc0
#define MCHP_RDS_PTP_TSU_GEN_CFG_TSU_EN		BIT(0)

#define MCHP_RDS_PTP_TSU_HARD_RESET		0xc1
#define MCHP_RDS_PTP_TSU_HARDRESET		BIT(0)

#define MCHP_RDS_PTP_CLK_TRGT_SEC_HI		0x15
#define MCHP_RDS_PTP_CLK_TRGT_SEC_LO		0x16
#define MCHP_RDS_PTP_CLK_TRGT_NS_HI		0x17
#define MCHP_RDS_PTP_CLK_TRGT_NS_LO		0x18

#define MCHP_RDS_PTP_CLK_TRGT_RELOAD_SEC_HI	0x19
#define MCHP_RDS_PTP_CLK_TRGT_RELOAD_SEC_LO	0x1a
#define MCHP_RDS_PTP_CLK_TRGT_RELOAD_NS_HI	0x1b
#define MCHP_RDS_PTP_CLK_TRGT_RELOAD_NS_LO	0x1c

#define MCHP_RDS_PTP_GEN_CFG			0x01
#define MCHP_RDS_PTP_GEN_CFG_LTC_EVT_MASK	GENMASK(11, 8)

#define MCHP_RDS_PTP_GEN_CFG_LTC_EVT_SET(value) (((value) & 0xF) << 4)
#define MCHP_RDS_PTP_GEN_CFG_RELOAD_ADD		BIT(0)
#define MCHP_RDS_PTP_GEN_CFG_POLARITY		BIT(1)

/* Represents 1ppm adjustment in 2^32 format with
 * each nsec contains 4 clock cycles in 250MHz.
 * The value is calculated as following: (1/1000000)/((2^-32)/4)
 */
#define MCHP_RDS_PTP_1PPM_FORMAT		17179
#define MCHP_RDS_PTP_FIFO_SIZE			8
#define MCHP_RDS_PTP_MAX_ADJ			31249999

#define MCHP_RDS_PTP_BUFFER_TIME		2
#define MCHP_RDS_PTP_N_PIN			4
#define MCHP_RDS_PTP_N_PEROUT			1

#define BASE_CLK(p)				((p)->clk_base_addr)
#define BASE_PORT(p)				((p)->port_base_addr)
#define PTP_MMD(p)				((p)->mmd)

enum mchp_rds_ptp_base {
	MCHP_RDS_PTP_PORT,
	MCHP_RDS_PTP_CLOCK
};

enum mchp_rds_ptp_fifo_dir {
	MCHP_RDS_PTP_INGRESS_FIFO,
	MCHP_RDS_PTP_EGRESS_FIFO
};

struct mchp_rds_ptp_clock {
	struct mii_timestamper mii_ts;
	struct phy_device *phydev;
	struct ptp_clock *ptp_clock;

	struct sk_buff_head tx_queue;
	struct sk_buff_head rx_queue;
	struct list_head rx_ts_list;

	struct ptp_clock_info caps;

	/* Lock for Rx ts fifo */
	spinlock_t rx_ts_lock;
	int hwts_tx_type;

	enum hwtstamp_rx_filters rx_filter;
	int layer;
	int version;
	u16 port_base_addr;
	u16 clk_base_addr;

	/* Lock for phc */
	struct mutex ptp_lock;
	u8 mmd;
	int mchp_rds_ptp_event;
	int event_pin;
	struct ptp_pin_desc *pin_config;
};

struct mchp_rds_ptp_rx_ts {
	struct list_head list;
	u32 seconds;
	u32 nsec;
	u16 seq_id;
};

#if IS_ENABLED(CONFIG_MICROCHIP_PHY_RDS_PTP)

struct mchp_rds_ptp_clock *mchp_rds_ptp_probe(struct phy_device *phydev, u8 mmd,
					      u16 clk_base, u16 port_base);

int mchp_rds_ptp_top_config_intr(struct mchp_rds_ptp_clock *clock,
				 u16 reg, u16 val, bool enable);

irqreturn_t mchp_rds_ptp_handle_interrupt(struct mchp_rds_ptp_clock *clock);

#else

static inline struct mchp_rds_ptp_clock *mchp_rds_ptp_probe(struct phy_device
							    *phydev, u8 mmd,
							    u16 clk_base,
							    u16 port_base)
{
	return NULL;
}

static inline int mchp_rds_ptp_top_config_intr(struct mchp_rds_ptp_clock *clock,
					       u16 reg, u16 val, bool enable)
{
	return 0;
}

static inline irqreturn_t mchp_rds_ptp_handle_interrupt(struct
							mchp_rds_ptp_clock
							* clock)
{
	return IRQ_NONE;
}

#endif //CONFIG_MICROCHIP_PHY_RDS_PTP

#endif //_MICROCHIP_RDS_PTP_H