]>
Commit | Line | Data |
---|---|---|
891434b1 RK |
1 | /******************************************************************************* |
2 | Copyright (C) 2013 Vayavya Labs Pvt Ltd | |
3 | ||
4 | This implements all the API for managing HW timestamp & PTP. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify it | |
7 | under the terms and conditions of the GNU General Public License, | |
8 | version 2, as published by the Free Software Foundation. | |
9 | ||
10 | This program is distributed in the hope it will be useful, but WITHOUT | |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | more details. | |
14 | ||
891434b1 RK |
15 | The full GNU General Public License is included in this distribution in |
16 | the file called "COPYING". | |
17 | ||
18 | Author: Rayagond Kokatanur <rayagond@vayavyalabs.com> | |
19 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | |
20 | *******************************************************************************/ | |
21 | ||
22 | #include <linux/io.h> | |
23 | #include <linux/delay.h> | |
24 | #include "common.h" | |
25 | #include "stmmac_ptp.h" | |
26 | ||
27 | static void stmmac_config_hw_tstamping(void __iomem *ioaddr, u32 data) | |
28 | { | |
29 | writel(data, ioaddr + PTP_TCR); | |
30 | } | |
31 | ||
19d857c9 | 32 | static u32 stmmac_config_sub_second_increment(void __iomem *ioaddr, |
ba1ffd74 | 33 | u32 ptp_clock, int gmac4) |
891434b1 RK |
34 | { |
35 | u32 value = readl(ioaddr + PTP_TCR); | |
36 | unsigned long data; | |
200922c9 | 37 | u32 reg_value; |
891434b1 | 38 | |
ba1ffd74 GC |
39 | /* For GMAC3.x, 4.x versions, convert the ptp_clock to nano second |
40 | * formula = (1/ptp_clock) * 1000000000 | |
41 | * where ptp_clock is 50MHz if fine method is used to update system | |
891434b1 | 42 | */ |
ba1ffd74 GC |
43 | if (value & PTP_TCR_TSCFUPDT) |
44 | data = (1000000000ULL / 50000000); | |
45 | else | |
46 | data = (1000000000ULL / ptp_clock); | |
891434b1 RK |
47 | |
48 | /* 0.465ns accuracy */ | |
0cf91580 SZ |
49 | if (!(value & PTP_TCR_TSCTRLSSR)) |
50 | data = (data * 1000) / 465; | |
891434b1 | 51 | |
ba1ffd74 GC |
52 | data &= PTP_SSIR_SSINC_MASK; |
53 | ||
200922c9 | 54 | reg_value = data; |
ba1ffd74 | 55 | if (gmac4) |
200922c9 | 56 | reg_value <<= GMAC4_PTP_SSIR_SSINC_SHIFT; |
ba1ffd74 | 57 | |
200922c9 | 58 | writel(reg_value, ioaddr + PTP_SSIR); |
19d857c9 PR |
59 | |
60 | return data; | |
891434b1 RK |
61 | } |
62 | ||
63 | static int stmmac_init_systime(void __iomem *ioaddr, u32 sec, u32 nsec) | |
64 | { | |
65 | int limit; | |
66 | u32 value; | |
67 | ||
68 | writel(sec, ioaddr + PTP_STSUR); | |
69 | writel(nsec, ioaddr + PTP_STNSUR); | |
70 | /* issue command to initialize the system time value */ | |
71 | value = readl(ioaddr + PTP_TCR); | |
72 | value |= PTP_TCR_TSINIT; | |
73 | writel(value, ioaddr + PTP_TCR); | |
74 | ||
75 | /* wait for present system time initialize to complete */ | |
76 | limit = 10; | |
77 | while (limit--) { | |
78 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSINIT)) | |
79 | break; | |
80 | mdelay(10); | |
81 | } | |
82 | if (limit < 0) | |
83 | return -EBUSY; | |
84 | ||
85 | return 0; | |
86 | } | |
87 | ||
88 | static int stmmac_config_addend(void __iomem *ioaddr, u32 addend) | |
89 | { | |
90 | u32 value; | |
91 | int limit; | |
92 | ||
93 | writel(addend, ioaddr + PTP_TAR); | |
94 | /* issue command to update the addend value */ | |
95 | value = readl(ioaddr + PTP_TCR); | |
96 | value |= PTP_TCR_TSADDREG; | |
97 | writel(value, ioaddr + PTP_TCR); | |
98 | ||
99 | /* wait for present addend update to complete */ | |
100 | limit = 10; | |
101 | while (limit--) { | |
102 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSADDREG)) | |
103 | break; | |
104 | mdelay(10); | |
105 | } | |
106 | if (limit < 0) | |
107 | return -EBUSY; | |
108 | ||
109 | return 0; | |
110 | } | |
111 | ||
92ba6888 | 112 | static int stmmac_adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec, |
ba1ffd74 | 113 | int add_sub, int gmac4) |
92ba6888 RK |
114 | { |
115 | u32 value; | |
116 | int limit; | |
117 | ||
ba1ffd74 GC |
118 | if (add_sub) { |
119 | /* If the new sec value needs to be subtracted with | |
120 | * the system time, then MAC_STSUR reg should be | |
121 | * programmed with (2^32 – <new_sec_value>) | |
122 | */ | |
123 | if (gmac4) | |
124 | sec = (100000000ULL - sec); | |
125 | ||
126 | value = readl(ioaddr + PTP_TCR); | |
127 | if (value & PTP_TCR_TSCTRLSSR) | |
128 | nsec = (PTP_DIGITAL_ROLLOVER_MODE - nsec); | |
129 | else | |
130 | nsec = (PTP_BINARY_ROLLOVER_MODE - nsec); | |
131 | } | |
132 | ||
92ba6888 | 133 | writel(sec, ioaddr + PTP_STSUR); |
ba1ffd74 GC |
134 | value = (add_sub << PTP_STNSUR_ADDSUB_SHIFT) | nsec; |
135 | writel(value, ioaddr + PTP_STNSUR); | |
136 | ||
92ba6888 RK |
137 | /* issue command to initialize the system time value */ |
138 | value = readl(ioaddr + PTP_TCR); | |
139 | value |= PTP_TCR_TSUPDT; | |
140 | writel(value, ioaddr + PTP_TCR); | |
141 | ||
142 | /* wait for present system time adjust/update to complete */ | |
143 | limit = 10; | |
144 | while (limit--) { | |
145 | if (!(readl(ioaddr + PTP_TCR) & PTP_TCR_TSUPDT)) | |
146 | break; | |
147 | mdelay(10); | |
148 | } | |
149 | if (limit < 0) | |
150 | return -EBUSY; | |
151 | ||
152 | return 0; | |
153 | } | |
154 | ||
155 | static u64 stmmac_get_systime(void __iomem *ioaddr) | |
156 | { | |
157 | u64 ns; | |
158 | ||
ba1ffd74 | 159 | /* Get the TSSS value */ |
92ba6888 | 160 | ns = readl(ioaddr + PTP_STNSR); |
ba1ffd74 | 161 | /* Get the TSS and convert sec time value to nanosecond */ |
92ba6888 RK |
162 | ns += readl(ioaddr + PTP_STSR) * 1000000000ULL; |
163 | ||
164 | return ns; | |
165 | } | |
166 | ||
891434b1 RK |
167 | const struct stmmac_hwtimestamp stmmac_ptp = { |
168 | .config_hw_tstamping = stmmac_config_hw_tstamping, | |
169 | .init_systime = stmmac_init_systime, | |
170 | .config_sub_second_increment = stmmac_config_sub_second_increment, | |
171 | .config_addend = stmmac_config_addend, | |
92ba6888 RK |
172 | .adjust_systime = stmmac_adjust_systime, |
173 | .get_systime = stmmac_get_systime, | |
891434b1 | 174 | }; |