Re: [PATCH 9/9] can: rcar_canfd: Add support for Transceiver Delay Compensation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 02/06/2025 at 23:08, Geert Uytterhoeven wrote:
> Hi Vincent,
> 
> On Mon, 2 Jun 2025 at 15:41, Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> wrote:
>> On 02/06/2025 at 20:54, Geert Uytterhoeven wrote:
>>> The Renesas CAN-FD hardware block supports configuring Transceiver Delay
>>> Compensation, and reading back the Transceiver Delay Compensation
>>> Result, which is needed to support high transfer rates like 8 Mbps.
>>> The Secondary Sample Point is either the measured delay plus the
>>> configured offset, or just the configured offset.
>>>
>>> Fix the existing RCANFD_FDCFG_TDCO() macro for the intended use case
>>> (writing instead of reading the field).  Add register definition bits
>>> for the Channel n CAN-FD Status Register.
>>>
>>> Signed-off-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx>
> 
>>> --- a/drivers/net/can/rcar/rcar_canfd.c
>>> +++ b/drivers/net/can/rcar/rcar_canfd.c
>>> @@ -191,9 +191,19 @@
>>>  /* RSCFDnCFDCmFDCFG */
>>>  #define RCANFD_GEN4_FDCFG_CLOE               BIT(30)
>>>  #define RCANFD_GEN4_FDCFG_FDOE               BIT(28)
>>> +#define RCANFD_FDCFG_TDCO            GENMASK(23, 16)
>>>  #define RCANFD_FDCFG_TDCE            BIT(9)
>>>  #define RCANFD_FDCFG_TDCOC           BIT(8)
>>> -#define RCANFD_FDCFG_TDCO(x)         (((x) & 0x7f) >> 16)
>>> +
>>> +/* RSCFDnCFDCmFDSTS */
>>> +#define RCANFD_FDSTS_SOC             GENMASK(31, 24)
>>> +#define RCANFD_FDSTS_EOC             GENMASK(23, 16)
>>> +#define RCANFD_GEN4_FDSTS_PNSTS              GENMASK(13, 12)
>>> +#define RCANFD_FDSTS_SOCO            BIT(9)
>>> +#define RCANFD_FDSTS_EOCO            BIT(8)
>>> +#define RCANFD_FDSTS_TDCR(gpriv, x)  ((x) & ((gpriv)->info->tdc_const->tdcv_max - 1))
>>> +#define RCANFD_FDSTS_TDCVF(gpriv) \
>>> +     ((gpriv)->info->tdc_const->tdcv_max > 128 ? BIT(15) : BIT(7))
>>
>> See my previous comment: no more function like macro please.
> 
> OK, "int rcar_canfd_get_fdsts_tdcr(gpriv, sts)".
> 
> RCANFD_FDSTS_TDCVF() is unused, so I'll drop it.
> 
>>> @@ -634,6 +645,25 @@ static const struct can_bittiming_const rcar_canfd_bittiming_const = {
>>>       .brp_inc = 1,
>>>  };
>>>
>>> +/* CAN FD Transmission Delay Compensation constants */
>>> +static const struct can_tdc_const rcar_canfd_gen3_tdc_const = {
>>> +     .tdcv_min = 1,
>>
>> Interesting. This is the first time I see a driver with the tdcv_min and the
>> tdco_min different than 0. At one point in time, I wanted those to be implicit
>> values. Guess it was finally a good idea to include those minimums to the framework.
> 
> Really? As most other timing values need subtracting 1 when programming
> the hardware, I would expect it to be rather common.

Do a

  git grep "tdc[ov]_min ="

and see by yourself :)

I also expected that this might occur one day, so glad I anticipated.

>>> @@ -1477,6 +1514,22 @@ static void rcar_canfd_set_bittiming(struct net_device *ndev)
>>>       rcar_canfd_write(priv->base, RCANFD_F_DCFG(gpriv, ch), cfg);
>>>       netdev_dbg(ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n",
>>>                  brp, sjw, tseg1, tseg2);
>>> +
>>> +     /* Transceiver Delay Compensation */
>>> +     if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_AUTO) {
>>> +             /* TDC enabled, measured + offset */
>>> +             tdcmode = RCANFD_FDCFG_TDCE;
>>> +             tdco = tdc->tdco - 1;
>>> +             netdev_dbg(ndev, "tdc: auto %u\n", tdco);
>>
>> Same as previously. Are those debugs really useful? You can get the value
>> through the netlink interface (OK, you still have to do the minus one by hand,
>> but don't tell me that's the reason).
> 
> No, I just mimicked the existing debug prints, which we already agreed
> upon to remove.
> 
>>> +     } else if (priv->can.ctrlmode & CAN_CTRLMODE_TDC_MANUAL) {
>>> +             /* TDC enabled, offset only */
>>> +             tdcmode = RCANFD_FDCFG_TDCE | RCANFD_FDCFG_TDCOC;
>>> +             tdco = min(tdc->tdcv + tdc->tdco, tdc_const->tdco_max) - 1;
>>
>> That's an edge case I did not think of and that is thus not handled by the
>> framework. This min() is a bit hacky, but I do not see a better workaround.
>> Also, I guess that this edge case will rarely occur.
> 
> can_calc_tdco() also does a silent min(..., tdc_const->tdco_max).

Good catch!

>>> +             netdev_dbg(ndev, "tdc: manual %u\n", tdco);
>>> +     }
>>> +
>>> +     rcar_canfd_update_bit(gpriv->base, RCANFD_F_CFDCFG(gpriv, ch), mask,
>>> +                           tdcmode | FIELD_PREP(RCANFD_FDCFG_TDCO, tdco));
>>>  }

Yours sincerely,
Vincent Mailhol





[Index of Archives]     [Linux Samsung SOC]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux