// SPDX-License-Identifier: GPL-2.0
/* Renesas R-Car Gen4 gPTP device driver
 *
 * Copyright (C) 2022 Renesas Electronics Corporation
 */

#include <linux/err.h>
#include <linux/etherdevice.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include "rcar_gen4_ptp.h"
#define ptp_to_priv(ptp)	container_of(ptp, struct rcar_gen4_ptp_private, info)

static const struct rcar_gen4_ptp_reg_offset s4_offs = {
	.enable = PTPTMEC,
	.disable = PTPTMDC,
	.increment = PTPTIVC0,
	.config_t0 = PTPTOVC00,
	.config_t1 = PTPTOVC10,
	.config_t2 = PTPTOVC20,
	.monitor_t0 = PTPGPTPTM00,
	.monitor_t1 = PTPGPTPTM10,
	.monitor_t2 = PTPGPTPTM20,
};

static int rcar_gen4_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);
	bool neg_adj = scaled_ppm < 0 ? true : false;
	s64 addend = ptp_priv->default_addend;
	s64 diff;

	if (neg_adj)
		scaled_ppm = -scaled_ppm;
	diff = div_s64(addend * scaled_ppm_to_ppb(scaled_ppm), NSEC_PER_SEC);
	addend = neg_adj ? addend - diff : addend + diff;

	iowrite32(addend, ptp_priv->addr + ptp_priv->offs->increment);

	return 0;
}

/* Caller must hold the lock */
static void _rcar_gen4_ptp_gettime(struct ptp_clock_info *ptp,
				   struct timespec64 *ts)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);

	ts->tv_nsec = ioread32(ptp_priv->addr + ptp_priv->offs->monitor_t0);
	ts->tv_sec = ioread32(ptp_priv->addr + ptp_priv->offs->monitor_t1) |
		     ((s64)ioread32(ptp_priv->addr + ptp_priv->offs->monitor_t2) << 32);
}

static int rcar_gen4_ptp_gettime(struct ptp_clock_info *ptp,
				 struct timespec64 *ts)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);
	unsigned long flags;

	spin_lock_irqsave(&ptp_priv->lock, flags);
	_rcar_gen4_ptp_gettime(ptp, ts);
	spin_unlock_irqrestore(&ptp_priv->lock, flags);

	return 0;
}

/* Caller must hold the lock */
static void _rcar_gen4_ptp_settime(struct ptp_clock_info *ptp,
				   const struct timespec64 *ts)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);

	iowrite32(1, ptp_priv->addr + ptp_priv->offs->disable);
	iowrite32(0, ptp_priv->addr + ptp_priv->offs->config_t2);
	iowrite32(0, ptp_priv->addr + ptp_priv->offs->config_t1);
	iowrite32(0, ptp_priv->addr + ptp_priv->offs->config_t0);
	iowrite32(1, ptp_priv->addr + ptp_priv->offs->enable);
	iowrite32(ts->tv_sec >> 32, ptp_priv->addr + ptp_priv->offs->config_t2);
	iowrite32(ts->tv_sec, ptp_priv->addr + ptp_priv->offs->config_t1);
	iowrite32(ts->tv_nsec, ptp_priv->addr + ptp_priv->offs->config_t0);
}

static int rcar_gen4_ptp_settime(struct ptp_clock_info *ptp,
				 const struct timespec64 *ts)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);
	unsigned long flags;

	spin_lock_irqsave(&ptp_priv->lock, flags);
	_rcar_gen4_ptp_settime(ptp, ts);
	spin_unlock_irqrestore(&ptp_priv->lock, flags);

	return 0;
}

static int rcar_gen4_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct rcar_gen4_ptp_private *ptp_priv = ptp_to_priv(ptp);
	struct timespec64 ts;
	unsigned long flags;
	s64 now;

	spin_lock_irqsave(&ptp_priv->lock, flags);
	_rcar_gen4_ptp_gettime(ptp, &ts);
	now = ktime_to_ns(timespec64_to_ktime(ts));
	ts = ns_to_timespec64(now + delta);
	_rcar_gen4_ptp_settime(ptp, &ts);
	spin_unlock_irqrestore(&ptp_priv->lock, flags);

	return 0;
}

static int rcar_gen4_ptp_enable(struct ptp_clock_info *ptp,
				struct ptp_clock_request *rq, int on)
{
	return -EOPNOTSUPP;
}

static struct ptp_clock_info rcar_gen4_ptp_info = {
	.owner = THIS_MODULE,
	.name = "rcar_gen4_ptp",
	.max_adj = 50000000,
	.adjfine = rcar_gen4_ptp_adjfine,
	.adjtime = rcar_gen4_ptp_adjtime,
	.gettime64 = rcar_gen4_ptp_gettime,
	.settime64 = rcar_gen4_ptp_settime,
	.enable = rcar_gen4_ptp_enable,
};

static void rcar_gen4_ptp_set_offs(struct rcar_gen4_ptp_private *ptp_priv,
				   enum rcar_gen4_ptp_reg_layout layout)
{
	WARN_ON(layout != RCAR_GEN4_PTP_REG_LAYOUT_S4);

	ptp_priv->offs = &s4_offs;
}

int rcar_gen4_ptp_register(struct rcar_gen4_ptp_private *ptp_priv,
			   enum rcar_gen4_ptp_reg_layout layout, u32 clock)
{
	if (ptp_priv->initialized)
		return 0;

	spin_lock_init(&ptp_priv->lock);

	rcar_gen4_ptp_set_offs(ptp_priv, layout);

	ptp_priv->default_addend = clock;
	iowrite32(ptp_priv->default_addend, ptp_priv->addr + ptp_priv->offs->increment);
	ptp_priv->clock = ptp_clock_register(&ptp_priv->info, NULL);
	if (IS_ERR(ptp_priv->clock))
		return PTR_ERR(ptp_priv->clock);

	iowrite32(0x01, ptp_priv->addr + ptp_priv->offs->enable);
	ptp_priv->initialized = true;

	return 0;
}

int rcar_gen4_ptp_unregister(struct rcar_gen4_ptp_private *ptp_priv)
{
	iowrite32(1, ptp_priv->addr + ptp_priv->offs->disable);

	return ptp_clock_unregister(ptp_priv->clock);
}

struct rcar_gen4_ptp_private *rcar_gen4_ptp_alloc(struct platform_device *pdev)
{
	struct rcar_gen4_ptp_private *ptp;

	ptp = devm_kzalloc(&pdev->dev, sizeof(*ptp), GFP_KERNEL);
	if (!ptp)
		return NULL;

	ptp->info = rcar_gen4_ptp_info;

	return ptp;
}
