Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm...
[platform/kernel/linux-starfive.git] / drivers / net / can / dev / bittiming.c
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/can/dev.h>
8
9 /* Checks the validity of the specified bit-timing parameters prop_seg,
10  * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
11  * prescaler value brp. You can find more information in the header
12  * file linux/can/netlink.h.
13  */
14 static int can_fixup_bittiming(const struct net_device *dev, struct can_bittiming *bt,
15                                const struct can_bittiming_const *btc)
16 {
17         const struct can_priv *priv = netdev_priv(dev);
18         unsigned int tseg1, alltseg;
19         u64 brp64;
20
21         tseg1 = bt->prop_seg + bt->phase_seg1;
22         if (!bt->sjw)
23                 bt->sjw = 1;
24         if (bt->sjw > btc->sjw_max ||
25             tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
26             bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
27                 return -ERANGE;
28
29         brp64 = (u64)priv->clock.freq * (u64)bt->tq;
30         if (btc->brp_inc > 1)
31                 do_div(brp64, btc->brp_inc);
32         brp64 += 500000000UL - 1;
33         do_div(brp64, 1000000000UL); /* the practicable BRP */
34         if (btc->brp_inc > 1)
35                 brp64 *= btc->brp_inc;
36         bt->brp = (u32)brp64;
37
38         if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
39                 return -EINVAL;
40
41         alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
42         bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
43         bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
44
45         return 0;
46 }
47
48 /* Checks the validity of predefined bitrate settings */
49 static int
50 can_validate_bitrate(const struct net_device *dev, const struct can_bittiming *bt,
51                      const u32 *bitrate_const,
52                      const unsigned int bitrate_const_cnt)
53 {
54         unsigned int i;
55
56         for (i = 0; i < bitrate_const_cnt; i++) {
57                 if (bt->bitrate == bitrate_const[i])
58                         return 0;
59         }
60
61         return -EINVAL;
62 }
63
64 int can_get_bittiming(const struct net_device *dev, struct can_bittiming *bt,
65                       const struct can_bittiming_const *btc,
66                       const u32 *bitrate_const,
67                       const unsigned int bitrate_const_cnt)
68 {
69         int err;
70
71         /* Depending on the given can_bittiming parameter structure the CAN
72          * timing parameters are calculated based on the provided bitrate OR
73          * alternatively the CAN timing parameters (tq, prop_seg, etc.) are
74          * provided directly which are then checked and fixed up.
75          */
76         if (!bt->tq && bt->bitrate && btc)
77                 err = can_calc_bittiming(dev, bt, btc);
78         else if (bt->tq && !bt->bitrate && btc)
79                 err = can_fixup_bittiming(dev, bt, btc);
80         else if (!bt->tq && bt->bitrate && bitrate_const)
81                 err = can_validate_bitrate(dev, bt, bitrate_const,
82                                            bitrate_const_cnt);
83         else
84                 err = -EINVAL;
85
86         return err;
87 }