// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2023, 2024 Pengutronix,
//               Marc Kleine-Budde <kernel@pengutronix.de>
//

#include <linux/clocksource.h>

#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);
}
