Commit | Line | Data |
---|---|---|
5a9d5ecd MKB |
1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix | |
3 | * Copyright (C) 2006 Andrey Volkov, Varma Electronics | |
4 | * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com> | |
5 | */ | |
6 | ||
330c6d3b | 7 | #include <linux/units.h> |
5a9d5ecd MKB |
8 | #include <linux/can/dev.h> |
9 | ||
10 | #ifdef CONFIG_CAN_CALC_BITTIMING | |
11 | #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ | |
12 | ||
13 | /* Bit-timing calculation derived from: | |
14 | * | |
15 | * Code based on LinCAN sources and H8S2638 project | |
16 | * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz | |
17 | * Copyright 2005 Stanislav Marek | |
18 | * email: pisa@cmp.felk.cvut.cz | |
19 | * | |
20 | * Calculates proper bit-timing parameters for a specified bit-rate | |
21 | * and sample-point, which can then be used to set the bit-timing | |
22 | * registers of the CAN controller. You can find more information | |
23 | * in the header file linux/can/netlink.h. | |
24 | */ | |
25 | static int | |
26 | can_update_sample_point(const struct can_bittiming_const *btc, | |
5597f082 | 27 | const unsigned int sample_point_nominal, const unsigned int tseg, |
5a9d5ecd MKB |
28 | unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, |
29 | unsigned int *sample_point_error_ptr) | |
30 | { | |
31 | unsigned int sample_point_error, best_sample_point_error = UINT_MAX; | |
32 | unsigned int sample_point, best_sample_point = 0; | |
33 | unsigned int tseg1, tseg2; | |
34 | int i; | |
35 | ||
36 | for (i = 0; i <= 1; i++) { | |
37 | tseg2 = tseg + CAN_SYNC_SEG - | |
38 | (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / | |
39 | 1000 - i; | |
40 | tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); | |
41 | tseg1 = tseg - tseg2; | |
42 | if (tseg1 > btc->tseg1_max) { | |
43 | tseg1 = btc->tseg1_max; | |
44 | tseg2 = tseg - tseg1; | |
45 | } | |
46 | ||
47 | sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / | |
48 | (tseg + CAN_SYNC_SEG); | |
49 | sample_point_error = abs(sample_point_nominal - sample_point); | |
50 | ||
51 | if (sample_point <= sample_point_nominal && | |
52 | sample_point_error < best_sample_point_error) { | |
53 | best_sample_point = sample_point; | |
54 | best_sample_point_error = sample_point_error; | |
55 | *tseg1_ptr = tseg1; | |
56 | *tseg2_ptr = tseg2; | |
57 | } | |
58 | } | |
59 | ||
60 | if (sample_point_error_ptr) | |
61 | *sample_point_error_ptr = best_sample_point_error; | |
62 | ||
63 | return best_sample_point; | |
64 | } | |
65 | ||
5597f082 | 66 | int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, |
5a9d5ecd MKB |
67 | const struct can_bittiming_const *btc) |
68 | { | |
69 | struct can_priv *priv = netdev_priv(dev); | |
70 | unsigned int bitrate; /* current bitrate */ | |
71 | unsigned int bitrate_error; /* difference between current and nominal value */ | |
72 | unsigned int best_bitrate_error = UINT_MAX; | |
73 | unsigned int sample_point_error; /* difference between current and nominal value */ | |
74 | unsigned int best_sample_point_error = UINT_MAX; | |
75 | unsigned int sample_point_nominal; /* nominal sample point */ | |
76 | unsigned int best_tseg = 0; /* current best value for tseg */ | |
77 | unsigned int best_brp = 0; /* current best value for brp */ | |
78 | unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; | |
79 | u64 v64; | |
80 | ||
81 | /* Use CiA recommended sample points */ | |
82 | if (bt->sample_point) { | |
83 | sample_point_nominal = bt->sample_point; | |
84 | } else { | |
330c6d3b | 85 | if (bt->bitrate > 800 * KILO /* BPS */) |
5a9d5ecd | 86 | sample_point_nominal = 750; |
330c6d3b | 87 | else if (bt->bitrate > 500 * KILO /* BPS */) |
5a9d5ecd MKB |
88 | sample_point_nominal = 800; |
89 | else | |
90 | sample_point_nominal = 875; | |
91 | } | |
92 | ||
93 | /* tseg even = round down, odd = round up */ | |
94 | for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1; | |
95 | tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) { | |
96 | tsegall = CAN_SYNC_SEG + tseg / 2; | |
97 | ||
98 | /* Compute all possible tseg choices (tseg=tseg1+tseg2) */ | |
99 | brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2; | |
100 | ||
101 | /* choose brp step which is possible in system */ | |
102 | brp = (brp / btc->brp_inc) * btc->brp_inc; | |
103 | if (brp < btc->brp_min || brp > btc->brp_max) | |
104 | continue; | |
105 | ||
106 | bitrate = priv->clock.freq / (brp * tsegall); | |
107 | bitrate_error = abs(bt->bitrate - bitrate); | |
108 | ||
109 | /* tseg brp biterror */ | |
110 | if (bitrate_error > best_bitrate_error) | |
111 | continue; | |
112 | ||
113 | /* reset sample point error if we have a better bitrate */ | |
114 | if (bitrate_error < best_bitrate_error) | |
115 | best_sample_point_error = UINT_MAX; | |
116 | ||
117 | can_update_sample_point(btc, sample_point_nominal, tseg / 2, | |
118 | &tseg1, &tseg2, &sample_point_error); | |
85d4eb2a | 119 | if (sample_point_error >= best_sample_point_error) |
5a9d5ecd MKB |
120 | continue; |
121 | ||
122 | best_sample_point_error = sample_point_error; | |
123 | best_bitrate_error = bitrate_error; | |
124 | best_tseg = tseg / 2; | |
125 | best_brp = brp; | |
126 | ||
127 | if (bitrate_error == 0 && sample_point_error == 0) | |
128 | break; | |
129 | } | |
130 | ||
131 | if (best_bitrate_error) { | |
132 | /* Error in one-tenth of a percent */ | |
133 | v64 = (u64)best_bitrate_error * 1000; | |
134 | do_div(v64, bt->bitrate); | |
135 | bitrate_error = (u32)v64; | |
136 | if (bitrate_error > CAN_CALC_MAX_ERROR) { | |
137 | netdev_err(dev, | |
138 | "bitrate error %d.%d%% too high\n", | |
139 | bitrate_error / 10, bitrate_error % 10); | |
140 | return -EDOM; | |
141 | } | |
142 | netdev_warn(dev, "bitrate error %d.%d%%\n", | |
143 | bitrate_error / 10, bitrate_error % 10); | |
144 | } | |
145 | ||
146 | /* real sample point */ | |
147 | bt->sample_point = can_update_sample_point(btc, sample_point_nominal, | |
148 | best_tseg, &tseg1, &tseg2, | |
149 | NULL); | |
150 | ||
151 | v64 = (u64)best_brp * 1000 * 1000 * 1000; | |
152 | do_div(v64, priv->clock.freq); | |
153 | bt->tq = (u32)v64; | |
154 | bt->prop_seg = tseg1 / 2; | |
155 | bt->phase_seg1 = tseg1 - bt->prop_seg; | |
156 | bt->phase_seg2 = tseg2; | |
157 | ||
158 | /* check for sjw user settings */ | |
159 | if (!bt->sjw || !btc->sjw_max) { | |
160 | bt->sjw = 1; | |
161 | } else { | |
162 | /* bt->sjw is at least 1 -> sanitize upper bound to sjw_max */ | |
163 | if (bt->sjw > btc->sjw_max) | |
164 | bt->sjw = btc->sjw_max; | |
165 | /* bt->sjw must not be higher than tseg2 */ | |
166 | if (tseg2 < bt->sjw) | |
167 | bt->sjw = tseg2; | |
168 | } | |
169 | ||
170 | bt->brp = best_brp; | |
171 | ||
172 | /* real bitrate */ | |
173 | bt->bitrate = priv->clock.freq / | |
174 | (bt->brp * (CAN_SYNC_SEG + tseg1 + tseg2)); | |
175 | ||
176 | return 0; | |
177 | } | |
c25cc799 | 178 | |
da45a1e4 VM |
179 | void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, |
180 | const struct can_bittiming *dbt, | |
181 | u32 *ctrlmode, u32 ctrlmode_supported) | |
c25cc799 | 182 | |
da45a1e4 VM |
183 | { |
184 | if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) | |
c25cc799 VM |
185 | return; |
186 | ||
da45a1e4 | 187 | *ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; |
63dfe070 | 188 | |
c25cc799 VM |
189 | /* As specified in ISO 11898-1 section 11.3.3 "Transmitter |
190 | * delay compensation" (TDC) is only applicable if data BRP is | |
191 | * one or two. | |
192 | */ | |
193 | if (dbt->brp == 1 || dbt->brp == 2) { | |
39f66c9e VM |
194 | /* Sample point in clock periods */ |
195 | u32 sample_point_in_tc = (CAN_SYNC_SEG + dbt->prop_seg + | |
196 | dbt->phase_seg1) * dbt->brp; | |
c25cc799 | 197 | |
39f66c9e | 198 | if (sample_point_in_tc < tdc_const->tdco_min) |
63dfe070 | 199 | return; |
39f66c9e | 200 | tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max); |
da45a1e4 | 201 | *ctrlmode |= CAN_CTRLMODE_TDC_AUTO; |
c25cc799 VM |
202 | } |
203 | } | |
5a9d5ecd MKB |
204 | #endif /* CONFIG_CAN_CALC_BITTIMING */ |
205 | ||
206 | /* Checks the validity of the specified bit-timing parameters prop_seg, | |
207 | * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate | |
208 | * prescaler value brp. You can find more information in the header | |
209 | * file linux/can/netlink.h. | |
210 | */ | |
5597f082 | 211 | static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt, |
5a9d5ecd MKB |
212 | const struct can_bittiming_const *btc) |
213 | { | |
5597f082 | 214 | const struct can_priv *priv = netdev_priv(dev); |
e3462904 | 215 | unsigned int tseg1, alltseg; |
5a9d5ecd MKB |
216 | u64 brp64; |
217 | ||
218 | tseg1 = bt->prop_seg + bt->phase_seg1; | |
219 | if (!bt->sjw) | |
220 | bt->sjw = 1; | |
221 | if (bt->sjw > btc->sjw_max || | |
222 | tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max || | |
223 | bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max) | |
224 | return -ERANGE; | |
225 | ||
226 | brp64 = (u64)priv->clock.freq * (u64)bt->tq; | |
227 | if (btc->brp_inc > 1) | |
228 | do_div(brp64, btc->brp_inc); | |
229 | brp64 += 500000000UL - 1; | |
230 | do_div(brp64, 1000000000UL); /* the practicable BRP */ | |
231 | if (btc->brp_inc > 1) | |
232 | brp64 *= btc->brp_inc; | |
233 | bt->brp = (u32)brp64; | |
234 | ||
235 | if (bt->brp < btc->brp_min || bt->brp > btc->brp_max) | |
236 | return -EINVAL; | |
237 | ||
238 | alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1; | |
239 | bt->bitrate = priv->clock.freq / (bt->brp * alltseg); | |
240 | bt->sample_point = ((tseg1 + 1) * 1000) / alltseg; | |
241 | ||
242 | return 0; | |
243 | } | |
244 | ||
245 | /* Checks the validity of predefined bitrate settings */ | |
246 | static int | |
5597f082 | 247 | can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt, |
5a9d5ecd MKB |
248 | const u32 *bitrate_const, |
249 | const unsigned int bitrate_const_cnt) | |
250 | { | |
5a9d5ecd MKB |
251 | unsigned int i; |
252 | ||
253 | for (i = 0; i < bitrate_const_cnt; i++) { | |
254 | if (bt->bitrate == bitrate_const[i]) | |
5b60d334 | 255 | return 0; |
5a9d5ecd MKB |
256 | } |
257 | ||
5b60d334 | 258 | return -EINVAL; |
5a9d5ecd MKB |
259 | } |
260 | ||
5597f082 | 261 | int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt, |
5a9d5ecd MKB |
262 | const struct can_bittiming_const *btc, |
263 | const u32 *bitrate_const, | |
264 | const unsigned int bitrate_const_cnt) | |
265 | { | |
266 | int err; | |
267 | ||
268 | /* Depending on the given can_bittiming parameter structure the CAN | |
269 | * timing parameters are calculated based on the provided bitrate OR | |
270 | * alternatively the CAN timing parameters (tq, prop_seg, etc.) are | |
271 | * provided directly which are then checked and fixed up. | |
272 | */ | |
273 | if (!bt->tq && bt->bitrate && btc) | |
274 | err = can_calc_bittiming(dev, bt, btc); | |
275 | else if (bt->tq && !bt->bitrate && btc) | |
276 | err = can_fixup_bittiming(dev, bt, btc); | |
277 | else if (!bt->tq && bt->bitrate && bitrate_const) | |
278 | err = can_validate_bitrate(dev, bt, bitrate_const, | |
279 | bitrate_const_cnt); | |
280 | else | |
281 | err = -EINVAL; | |
282 | ||
283 | return err; | |
284 | } |