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 | |
7 | #include <linux/units.h> |
8 | #include <linux/can/dev.h> |
9 | |
10 | #define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ |
11 | |
12 | /* Bit-timing calculation derived from: |
13 | * |
14 | * Code based on LinCAN sources and H8S2638 project |
15 | * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz |
16 | * Copyright 2005 Stanislav Marek |
17 | * email: pisa@cmp.felk.cvut.cz |
18 | * |
19 | * Calculates proper bit-timing parameters for a specified bit-rate |
20 | * and sample-point, which can then be used to set the bit-timing |
21 | * registers of the CAN controller. You can find more information |
22 | * in the header file linux/can/netlink.h. |
23 | */ |
24 | static int |
25 | can_update_sample_point(const struct can_bittiming_const *btc, |
26 | const unsigned int sample_point_nominal, const unsigned int tseg, |
27 | unsigned int *tseg1_ptr, unsigned int *tseg2_ptr, |
28 | unsigned int *sample_point_error_ptr) |
29 | { |
30 | unsigned int sample_point_error, best_sample_point_error = UINT_MAX; |
31 | unsigned int sample_point, best_sample_point = 0; |
32 | unsigned int tseg1, tseg2; |
33 | int i; |
34 | |
35 | for (i = 0; i <= 1; i++) { |
36 | tseg2 = tseg + CAN_SYNC_SEG - |
37 | (sample_point_nominal * (tseg + CAN_SYNC_SEG)) / |
38 | 1000 - i; |
39 | tseg2 = clamp(tseg2, btc->tseg2_min, btc->tseg2_max); |
40 | tseg1 = tseg - tseg2; |
41 | if (tseg1 > btc->tseg1_max) { |
42 | tseg1 = btc->tseg1_max; |
43 | tseg2 = tseg - tseg1; |
44 | } |
45 | |
46 | sample_point = 1000 * (tseg + CAN_SYNC_SEG - tseg2) / |
47 | (tseg + CAN_SYNC_SEG); |
48 | sample_point_error = abs(sample_point_nominal - sample_point); |
49 | |
50 | if (sample_point <= sample_point_nominal && |
51 | sample_point_error < best_sample_point_error) { |
52 | best_sample_point = sample_point; |
53 | best_sample_point_error = sample_point_error; |
54 | *tseg1_ptr = tseg1; |
55 | *tseg2_ptr = tseg2; |
56 | } |
57 | } |
58 | |
59 | if (sample_point_error_ptr) |
60 | *sample_point_error_ptr = best_sample_point_error; |
61 | |
62 | return best_sample_point; |
63 | } |
64 | |
65 | int can_calc_bittiming(const struct net_device *dev, struct can_bittiming *bt, |
66 | const struct can_bittiming_const *btc, struct netlink_ext_ack *extack) |
67 | { |
68 | struct can_priv *priv = netdev_priv(dev); |
69 | unsigned int bitrate; /* current bitrate */ |
70 | unsigned int bitrate_error; /* difference between current and nominal value */ |
71 | unsigned int best_bitrate_error = UINT_MAX; |
72 | unsigned int sample_point_error; /* difference between current and nominal value */ |
73 | unsigned int best_sample_point_error = UINT_MAX; |
74 | unsigned int sample_point_nominal; /* nominal sample point */ |
75 | unsigned int best_tseg = 0; /* current best value for tseg */ |
76 | unsigned int best_brp = 0; /* current best value for brp */ |
77 | unsigned int brp, tsegall, tseg, tseg1 = 0, tseg2 = 0; |
78 | u64 v64; |
79 | int err; |
80 | |
81 | /* Use CiA recommended sample points */ |
82 | if (bt->sample_point) { |
83 | sample_point_nominal = bt->sample_point; |
84 | } else { |
85 | if (bt->bitrate > 800 * KILO /* BPS */) |
86 | sample_point_nominal = 750; |
87 | else if (bt->bitrate > 500 * KILO /* BPS */) |
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: tseg / 2, |
118 | tseg1_ptr: &tseg1, tseg2_ptr: &tseg2, sample_point_error_ptr: &sample_point_error); |
119 | if (sample_point_error >= best_sample_point_error) |
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 | NL_SET_ERR_MSG_FMT(extack, |
138 | "bitrate error: %u.%u%% too high" , |
139 | bitrate_error / 10, bitrate_error % 10); |
140 | return -EINVAL; |
141 | } |
142 | NL_SET_ERR_MSG_FMT(extack, |
143 | "bitrate error: %u.%u%%" , |
144 | bitrate_error / 10, bitrate_error % 10); |
145 | } |
146 | |
147 | /* real sample point */ |
148 | bt->sample_point = can_update_sample_point(btc, sample_point_nominal, |
149 | tseg: best_tseg, tseg1_ptr: &tseg1, tseg2_ptr: &tseg2, |
150 | NULL); |
151 | |
152 | v64 = (u64)best_brp * 1000 * 1000 * 1000; |
153 | do_div(v64, priv->clock.freq); |
154 | bt->tq = (u32)v64; |
155 | bt->prop_seg = tseg1 / 2; |
156 | bt->phase_seg1 = tseg1 - bt->prop_seg; |
157 | bt->phase_seg2 = tseg2; |
158 | |
159 | can_sjw_set_default(bt); |
160 | |
161 | err = can_sjw_check(dev, bt, btc, extack); |
162 | if (err) |
163 | return err; |
164 | |
165 | bt->brp = best_brp; |
166 | |
167 | /* real bitrate */ |
168 | bt->bitrate = priv->clock.freq / |
169 | (bt->brp * can_bit_time(bt)); |
170 | |
171 | return 0; |
172 | } |
173 | |
174 | void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, |
175 | const struct can_bittiming *dbt, |
176 | u32 *ctrlmode, u32 ctrlmode_supported) |
177 | |
178 | { |
179 | if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) |
180 | return; |
181 | |
182 | *ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; |
183 | |
184 | /* As specified in ISO 11898-1 section 11.3.3 "Transmitter |
185 | * delay compensation" (TDC) is only applicable if data BRP is |
186 | * one or two. |
187 | */ |
188 | if (dbt->brp == 1 || dbt->brp == 2) { |
189 | /* Sample point in clock periods */ |
190 | u32 sample_point_in_tc = (CAN_SYNC_SEG + dbt->prop_seg + |
191 | dbt->phase_seg1) * dbt->brp; |
192 | |
193 | if (sample_point_in_tc < tdc_const->tdco_min) |
194 | return; |
195 | tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max); |
196 | *ctrlmode |= CAN_CTRLMODE_TDC_AUTO; |
197 | } |
198 | } |
199 | |