This source file includes following definitions.
- config_hw_tstamping
- config_sub_second_increment
- init_systime
- config_addend
- adjust_systime
- get_systime
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/io.h>
13 #include <linux/delay.h>
14 #include "common.h"
15 #include "stmmac_ptp.h"
16
17 static void config_hw_tstamping(void __iomem *ioaddr, u32 data)
18 {
19 writel(data, ioaddr + PTP_TCR);
20 }
21
22 static void config_sub_second_increment(void __iomem *ioaddr,
23 u32 ptp_clock, int gmac4, u32 *ssinc)
24 {
25 u32 value = readl(ioaddr + PTP_TCR);
26 unsigned long data;
27 u32 reg_value;
28
29
30
31
32
33
34
35
36
37 if (value & PTP_TCR_TSCFUPDT)
38 data = (2000000000ULL / ptp_clock);
39 else
40 data = (1000000000ULL / ptp_clock);
41
42
43 if (!(value & PTP_TCR_TSCTRLSSR))
44 data = (data * 1000) / 465;
45
46 data &= PTP_SSIR_SSINC_MASK;
47
48 reg_value = data;
49 if (gmac4)
50 reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT;
51
52 writel(reg_value, ioaddr + PTP_SSIR);
53
54 if (ssinc)
55 *ssinc = data;
56 }
57
58 static int init_systime(void __iomem *ioaddr, u32 sec, u32 nsec)
59 {
60 int limit;
61 u32 value;
62
63 writel(sec, ioaddr + PTP_STSUR);
64 writel(nsec, ioaddr + PTP_STNSUR);
65
66 value = readl(ioaddr + PTP_TCR);
67 value |= PTP_TCR_TSINIT;
68 writel(value, ioaddr + PTP_TCR);
69
70
71 limit = 10;
72 while (limit--) {
73 if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSINIT))
74 break;
75 mdelay(10);
76 }
77 if (limit < 0)
78 return -EBUSY;
79
80 return 0;
81 }
82
83 static int config_addend(void __iomem *ioaddr, u32 addend)
84 {
85 u32 value;
86 int limit;
87
88 writel(addend, ioaddr + PTP_TAR);
89
90 value = readl(ioaddr + PTP_TCR);
91 value |= PTP_TCR_TSADDREG;
92 writel(value, ioaddr + PTP_TCR);
93
94
95 limit = 10;
96 while (limit--) {
97 if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSADDREG))
98 break;
99 mdelay(10);
100 }
101 if (limit < 0)
102 return -EBUSY;
103
104 return 0;
105 }
106
107 static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
108 int add_sub, int gmac4)
109 {
110 u32 value;
111 int limit;
112
113 if (add_sub) {
114
115
116
117
118 if (gmac4)
119 sec = -sec;
120
121 value = readl(ioaddr + PTP_TCR);
122 if (value & PTP_TCR_TSCTRLSSR)
123 nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec);
124 else
125 nsec = (PTP_BINARY_ROLLOVER_MODE - nsec);
126 }
127
128 writel(sec, ioaddr + PTP_STSUR);
129 value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec;
130 writel(value, ioaddr + PTP_STNSUR);
131
132
133 value = readl(ioaddr + PTP_TCR);
134 value |= PTP_TCR_TSUPDT;
135 writel(value, ioaddr + PTP_TCR);
136
137
138 limit = 10;
139 while (limit--) {
140 if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSUPDT))
141 break;
142 mdelay(10);
143 }
144 if (limit < 0)
145 return -EBUSY;
146
147 return 0;
148 }
149
150 static void get_systime(void __iomem *ioaddr, u64 *systime)
151 {
152 u64 ns;
153
154
155 ns = readl(ioaddr + PTP_STNSR);
156
157 ns += readl(ioaddr + PTP_STSR) * 1000000000ULL;
158
159 if (systime)
160 *systime = ns;
161 }
162
163 const struct stmmac_hwtimestamp stmmac_ptp = {
164 .config_hw_tstamping = config_hw_tstamping,
165 .init_systime = init_systime,
166 .config_sub_second_increment = config_sub_second_increment,
167 .config_addend = config_addend,
168 .adjust_systime = adjust_systime,
169 .get_systime = get_systime,
170 };