// SPDX-License-Identifier: GPL-2.0 // // Copyright (c) 2023, 2024 Pengutronix, // Marc Kleine-Budde // #include #include "rockchip_canfd.h" static u64 rkcanfd_timestamp_read(const struct cyclecounter *cc) { const struct rkcanfd_priv *priv = container_of(cc, struct rkcanfd_priv, cc); return rkcanfd_get_timestamp(priv); } void rkcanfd_skb_set_timestamp(const struct rkcanfd_priv *priv, struct sk_buff *skb, const u32 timestamp) { struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); u64 ns; ns = timecounter_cyc2time(&priv->tc, timestamp); hwtstamps->hwtstamp = ns_to_ktime(ns); } static void rkcanfd_timestamp_work(struct work_struct *work) { const struct delayed_work *delayed_work = to_delayed_work(work); struct rkcanfd_priv *priv; priv = container_of(delayed_work, struct rkcanfd_priv, timestamp); timecounter_read(&priv->tc); schedule_delayed_work(&priv->timestamp, priv->work_delay_jiffies); } void rkcanfd_timestamp_init(struct rkcanfd_priv *priv) { const struct can_bittiming *dbt = &priv->can.data_bittiming; const struct can_bittiming *bt = &priv->can.bittiming; struct cyclecounter *cc = &priv->cc; u32 bitrate, div, reg, rate; u64 work_delay_ns; u64 max_cycles; /* At the standard clock rate of 300Mhz on the rk3658, the 32 * bit timer overflows every 14s. This means that we have to * poll it quite often to avoid missing a wrap around. * * Divide it down to a reasonable rate, at least twice the bit * rate. */ bitrate = max(bt->bitrate, dbt->bitrate); div = min(DIV_ROUND_UP(priv->can.clock.freq, bitrate * 2), FIELD_MAX(RKCANFD_REG_TIMESTAMP_CTRL_TIME_BASE_COUNTER_PRESCALE) + 1); reg = FIELD_PREP(RKCANFD_REG_TIMESTAMP_CTRL_TIME_BASE_COUNTER_PRESCALE, div - 1) | RKCANFD_REG_TIMESTAMP_CTRL_TIME_BASE_COUNTER_ENABLE; rkcanfd_write(priv, RKCANFD_REG_TIMESTAMP_CTRL, reg); cc->read = rkcanfd_timestamp_read; cc->mask = CYCLECOUNTER_MASK(32); rate = priv->can.clock.freq / div; clocks_calc_mult_shift(&cc->mult, &cc->shift, rate, NSEC_PER_SEC, RKCANFD_TIMESTAMP_WORK_MAX_DELAY_SEC); max_cycles = div_u64(ULLONG_MAX, cc->mult); max_cycles = min(max_cycles, cc->mask); work_delay_ns = clocksource_cyc2ns(max_cycles, cc->mult, cc->shift); priv->work_delay_jiffies = div_u64(work_delay_ns, 3u * NSEC_PER_SEC / HZ); INIT_DELAYED_WORK(&priv->timestamp, rkcanfd_timestamp_work); netdev_dbg(priv->ndev, "clock=%lu.%02luMHz bitrate=%lu.%02luMBit/s div=%u rate=%lu.%02luMHz mult=%u shift=%u delay=%lus\n", priv->can.clock.freq / MEGA, priv->can.clock.freq % MEGA / KILO / 10, bitrate / MEGA, bitrate % MEGA / KILO / 100, div, rate / MEGA, rate % MEGA / KILO / 10, cc->mult, cc->shift, priv->work_delay_jiffies / HZ); } void rkcanfd_timestamp_start(struct rkcanfd_priv *priv) { timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns()); schedule_delayed_work(&priv->timestamp, priv->work_delay_jiffies); } void rkcanfd_timestamp_stop(struct rkcanfd_priv *priv) { cancel_delayed_work(&priv->timestamp); } void rkcanfd_timestamp_stop_sync(struct rkcanfd_priv *priv) { cancel_delayed_work_sync(&priv->timestamp); }