// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PTP 1588 clock for Freescale QorIQ 1588 timer
 *
 * Copyright (C) 2010 OMICRON electronics GmbH
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/device.h>
#include <linux/hrtimer.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/clk.h>

#include <linux/fsl/ptp_qoriq.h>

/*
 * Register access functions
 */

/* Caller must hold ptp_qoriq->lock. */
static u64 tmr_cnt_read(struct ptp_qoriq *ptp_qoriq)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	u64 ns;
	u32 lo, hi;

	lo = ptp_qoriq->read(&regs->ctrl_regs->tmr_cnt_l);
	hi = ptp_qoriq->read(&regs->ctrl_regs->tmr_cnt_h);
	ns = ((u64) hi) << 32;
	ns |= lo;
	return ns;
}

/* Caller must hold ptp_qoriq->lock. */
static void tmr_cnt_write(struct ptp_qoriq *ptp_qoriq, u64 ns)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	u32 hi = ns >> 32;
	u32 lo = ns & 0xffffffff;

	ptp_qoriq->write(&regs->ctrl_regs->tmr_cnt_l, lo);
	ptp_qoriq->write(&regs->ctrl_regs->tmr_cnt_h, hi);
}

/* Caller must hold ptp_qoriq->lock. */
static void set_alarm(struct ptp_qoriq *ptp_qoriq)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	u64 ns;
	u32 lo, hi;

	ns = tmr_cnt_read(ptp_qoriq) + 1500000000ULL;
	ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
	ns -= ptp_qoriq->tclk_period;
	hi = ns >> 32;
	lo = ns & 0xffffffff;
	ptp_qoriq->write(&regs->alarm_regs->tmr_alarm1_l, lo);
	ptp_qoriq->write(&regs->alarm_regs->tmr_alarm1_h, hi);
}

/* Caller must hold ptp_qoriq->lock. */
static void set_fipers(struct ptp_qoriq *ptp_qoriq)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;

	set_alarm(ptp_qoriq);
	ptp_qoriq->write(&regs->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
	ptp_qoriq->write(&regs->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
}

static int extts_clean_up(struct ptp_qoriq *ptp_qoriq, int index,
			  bool update_event)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	struct ptp_clock_event event;
	void __iomem *reg_etts_l;
	void __iomem *reg_etts_h;
	u32 valid, stat, lo, hi;

	switch (index) {
	case 0:
		valid = ETS1_VLD;
		reg_etts_l = &regs->etts_regs->tmr_etts1_l;
		reg_etts_h = &regs->etts_regs->tmr_etts1_h;
		break;
	case 1:
		valid = ETS2_VLD;
		reg_etts_l = &regs->etts_regs->tmr_etts2_l;
		reg_etts_h = &regs->etts_regs->tmr_etts2_h;
		break;
	default:
		return -EINVAL;
	}

	event.type = PTP_CLOCK_EXTTS;
	event.index = index;

	do {
		lo = ptp_qoriq->read(reg_etts_l);
		hi = ptp_qoriq->read(reg_etts_h);

		if (update_event) {
			event.timestamp = ((u64) hi) << 32;
			event.timestamp |= lo;
			ptp_clock_event(ptp_qoriq->clock, &event);
		}

		stat = ptp_qoriq->read(&regs->ctrl_regs->tmr_stat);
	} while (ptp_qoriq->extts_fifo_support && (stat & valid));

	return 0;
}

/*
 * Interrupt service routine
 */

irqreturn_t ptp_qoriq_isr(int irq, void *priv)
{
	struct ptp_qoriq *ptp_qoriq = priv;
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	struct ptp_clock_event event;
	u64 ns;
	u32 ack = 0, lo, hi, mask, val, irqs;

	spin_lock(&ptp_qoriq->lock);

	val = ptp_qoriq->read(&regs->ctrl_regs->tmr_tevent);
	mask = ptp_qoriq->read(&regs->ctrl_regs->tmr_temask);

	spin_unlock(&ptp_qoriq->lock);

	irqs = val & mask;

	if (irqs & ETS1) {
		ack |= ETS1;
		extts_clean_up(ptp_qoriq, 0, true);
	}

	if (irqs & ETS2) {
		ack |= ETS2;
		extts_clean_up(ptp_qoriq, 1, true);
	}

	if (irqs & ALM2) {
		ack |= ALM2;
		if (ptp_qoriq->alarm_value) {
			event.type = PTP_CLOCK_ALARM;
			event.index = 0;
			event.timestamp = ptp_qoriq->alarm_value;
			ptp_clock_event(ptp_qoriq->clock, &event);
		}
		if (ptp_qoriq->alarm_interval) {
			ns = ptp_qoriq->alarm_value + ptp_qoriq->alarm_interval;
			hi = ns >> 32;
			lo = ns & 0xffffffff;
			ptp_qoriq->write(&regs->alarm_regs->tmr_alarm2_l, lo);
			ptp_qoriq->write(&regs->alarm_regs->tmr_alarm2_h, hi);
			ptp_qoriq->alarm_value = ns;
		} else {
			spin_lock(&ptp_qoriq->lock);
			mask = ptp_qoriq->read(&regs->ctrl_regs->tmr_temask);
			mask &= ~ALM2EN;
			ptp_qoriq->write(&regs->ctrl_regs->tmr_temask, mask);
			spin_unlock(&ptp_qoriq->lock);
			ptp_qoriq->alarm_value = 0;
			ptp_qoriq->alarm_interval = 0;
		}
	}

	if (irqs & PP1) {
		ack |= PP1;
		event.type = PTP_CLOCK_PPS;
		ptp_clock_event(ptp_qoriq->clock, &event);
	}

	if (ack) {
		ptp_qoriq->write(&regs->ctrl_regs->tmr_tevent, ack);
		return IRQ_HANDLED;
	} else
		return IRQ_NONE;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_isr);

/*
 * PTP clock operations
 */

int ptp_qoriq_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	u64 adj, diff;
	u32 tmr_add;
	int neg_adj = 0;
	struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;

	if (scaled_ppm < 0) {
		neg_adj = 1;
		scaled_ppm = -scaled_ppm;
	}
	tmr_add = ptp_qoriq->tmr_add;
	adj = tmr_add;

	/* calculate diff as adj*(scaled_ppm/65536)/1000000
	 * and round() to the nearest integer
	 */
	adj *= scaled_ppm;
	diff = div_u64(adj, 8000000);
	diff = (diff >> 13) + ((diff >> 12) & 1);

	tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;

	ptp_qoriq->write(&regs->ctrl_regs->tmr_add, tmr_add);

	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_adjfine);

int ptp_qoriq_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	s64 now;
	unsigned long flags;
	struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);

	spin_lock_irqsave(&ptp_qoriq->lock, flags);

	now = tmr_cnt_read(ptp_qoriq);
	now += delta;
	tmr_cnt_write(ptp_qoriq, now);
	set_fipers(ptp_qoriq);

	spin_unlock_irqrestore(&ptp_qoriq->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_adjtime);

int ptp_qoriq_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
	u64 ns;
	unsigned long flags;
	struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);

	spin_lock_irqsave(&ptp_qoriq->lock, flags);

	ns = tmr_cnt_read(ptp_qoriq);

	spin_unlock_irqrestore(&ptp_qoriq->lock, flags);

	*ts = ns_to_timespec64(ns);

	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_gettime);

int ptp_qoriq_settime(struct ptp_clock_info *ptp,
		      const struct timespec64 *ts)
{
	u64 ns;
	unsigned long flags;
	struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);

	ns = timespec64_to_ns(ts);

	spin_lock_irqsave(&ptp_qoriq->lock, flags);

	tmr_cnt_write(ptp_qoriq, ns);
	set_fipers(ptp_qoriq);

	spin_unlock_irqrestore(&ptp_qoriq->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_settime);

int ptp_qoriq_enable(struct ptp_clock_info *ptp,
		     struct ptp_clock_request *rq, int on)
{
	struct ptp_qoriq *ptp_qoriq = container_of(ptp, struct ptp_qoriq, caps);
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;
	unsigned long flags;
	u32 bit, mask = 0;

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		switch (rq->extts.index) {
		case 0:
			bit = ETS1EN;
			break;
		case 1:
			bit = ETS2EN;
			break;
		default:
			return -EINVAL;
		}

		if (on)
			extts_clean_up(ptp_qoriq, rq->extts.index, false);

		break;
	case PTP_CLK_REQ_PPS:
		bit = PP1EN;
		break;
	default:
		return -EOPNOTSUPP;
	}

	spin_lock_irqsave(&ptp_qoriq->lock, flags);

	mask = ptp_qoriq->read(&regs->ctrl_regs->tmr_temask);
	if (on) {
		mask |= bit;
		ptp_qoriq->write(&regs->ctrl_regs->tmr_tevent, bit);
	} else {
		mask &= ~bit;
	}

	ptp_qoriq->write(&regs->ctrl_regs->tmr_temask, mask);

	spin_unlock_irqrestore(&ptp_qoriq->lock, flags);
	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_enable);

static const struct ptp_clock_info ptp_qoriq_caps = {
	.owner		= THIS_MODULE,
	.name		= "qoriq ptp clock",
	.max_adj	= 512000,
	.n_alarm	= 0,
	.n_ext_ts	= N_EXT_TS,
	.n_per_out	= 0,
	.n_pins		= 0,
	.pps		= 1,
	.adjfine	= ptp_qoriq_adjfine,
	.adjtime	= ptp_qoriq_adjtime,
	.gettime64	= ptp_qoriq_gettime,
	.settime64	= ptp_qoriq_settime,
	.enable		= ptp_qoriq_enable,
};

/**
 * ptp_qoriq_nominal_freq - calculate nominal frequency according to
 *			    reference clock frequency
 *
 * @clk_src: reference clock frequency
 *
 * The nominal frequency is the desired clock frequency.
 * It should be less than the reference clock frequency.
 * It should be a factor of 1000MHz.
 *
 * Return the nominal frequency
 */
static u32 ptp_qoriq_nominal_freq(u32 clk_src)
{
	u32 remainder = 0;

	clk_src /= 1000000;
	remainder = clk_src % 100;
	if (remainder) {
		clk_src -= remainder;
		clk_src += 100;
	}

	do {
		clk_src -= 100;

	} while (1000 % clk_src);

	return clk_src * 1000000;
}

/**
 * ptp_qoriq_auto_config - calculate a set of default configurations
 *
 * @ptp_qoriq: pointer to ptp_qoriq
 * @node: pointer to device_node
 *
 * If below dts properties are not provided, this function will be
 * called to calculate a set of default configurations for them.
 *   "fsl,tclk-period"
 *   "fsl,tmr-prsc"
 *   "fsl,tmr-add"
 *   "fsl,tmr-fiper1"
 *   "fsl,tmr-fiper2"
 *   "fsl,max-adj"
 *
 * Return 0 if success
 */
static int ptp_qoriq_auto_config(struct ptp_qoriq *ptp_qoriq,
				 struct device_node *node)
{
	struct clk *clk;
	u64 freq_comp;
	u64 max_adj;
	u32 nominal_freq;
	u32 remainder = 0;
	u32 clk_src = 0;

	ptp_qoriq->cksel = DEFAULT_CKSEL;

	clk = of_clk_get(node, 0);
	if (!IS_ERR(clk)) {
		clk_src = clk_get_rate(clk);
		clk_put(clk);
	}

	if (clk_src <= 100000000UL) {
		pr_err("error reference clock value, or lower than 100MHz\n");
		return -EINVAL;
	}

	nominal_freq = ptp_qoriq_nominal_freq(clk_src);
	if (!nominal_freq)
		return -EINVAL;

	ptp_qoriq->tclk_period = 1000000000UL / nominal_freq;
	ptp_qoriq->tmr_prsc = DEFAULT_TMR_PRSC;

	/* Calculate initial frequency compensation value for TMR_ADD register.
	 * freq_comp = ceil(2^32 / freq_ratio)
	 * freq_ratio = reference_clock_freq / nominal_freq
	 */
	freq_comp = ((u64)1 << 32) * nominal_freq;
	freq_comp = div_u64_rem(freq_comp, clk_src, &remainder);
	if (remainder)
		freq_comp++;

	ptp_qoriq->tmr_add = freq_comp;
	ptp_qoriq->tmr_fiper1 = DEFAULT_FIPER1_PERIOD - ptp_qoriq->tclk_period;
	ptp_qoriq->tmr_fiper2 = DEFAULT_FIPER2_PERIOD - ptp_qoriq->tclk_period;

	/* max_adj = 1000000000 * (freq_ratio - 1.0) - 1
	 * freq_ratio = reference_clock_freq / nominal_freq
	 */
	max_adj = 1000000000ULL * (clk_src - nominal_freq);
	max_adj = div_u64(max_adj, nominal_freq) - 1;
	ptp_qoriq->caps.max_adj = max_adj;

	return 0;
}

int ptp_qoriq_init(struct ptp_qoriq *ptp_qoriq, void __iomem *base,
		   const struct ptp_clock_info *caps)
{
	struct device_node *node = ptp_qoriq->dev->of_node;
	struct ptp_qoriq_registers *regs;
	struct timespec64 now;
	unsigned long flags;
	u32 tmr_ctrl;

	if (!node)
		return -ENODEV;

	ptp_qoriq->base = base;
	ptp_qoriq->caps = *caps;

	if (of_property_read_u32(node, "fsl,cksel", &ptp_qoriq->cksel))
		ptp_qoriq->cksel = DEFAULT_CKSEL;

	if (of_property_read_bool(node, "fsl,extts-fifo"))
		ptp_qoriq->extts_fifo_support = true;
	else
		ptp_qoriq->extts_fifo_support = false;

	if (of_property_read_u32(node,
				 "fsl,tclk-period", &ptp_qoriq->tclk_period) ||
	    of_property_read_u32(node,
				 "fsl,tmr-prsc", &ptp_qoriq->tmr_prsc) ||
	    of_property_read_u32(node,
				 "fsl,tmr-add", &ptp_qoriq->tmr_add) ||
	    of_property_read_u32(node,
				 "fsl,tmr-fiper1", &ptp_qoriq->tmr_fiper1) ||
	    of_property_read_u32(node,
				 "fsl,tmr-fiper2", &ptp_qoriq->tmr_fiper2) ||
	    of_property_read_u32(node,
				 "fsl,max-adj", &ptp_qoriq->caps.max_adj)) {
		pr_warn("device tree node missing required elements, try automatic configuration\n");

		if (ptp_qoriq_auto_config(ptp_qoriq, node))
			return -ENODEV;
	}

	if (of_property_read_bool(node, "little-endian")) {
		ptp_qoriq->read = qoriq_read_le;
		ptp_qoriq->write = qoriq_write_le;
	} else {
		ptp_qoriq->read = qoriq_read_be;
		ptp_qoriq->write = qoriq_write_be;
	}

	/* The eTSEC uses differnt memory map with DPAA/ENETC */
	if (of_device_is_compatible(node, "fsl,etsec-ptp")) {
		ptp_qoriq->regs.ctrl_regs = base + ETSEC_CTRL_REGS_OFFSET;
		ptp_qoriq->regs.alarm_regs = base + ETSEC_ALARM_REGS_OFFSET;
		ptp_qoriq->regs.fiper_regs = base + ETSEC_FIPER_REGS_OFFSET;
		ptp_qoriq->regs.etts_regs = base + ETSEC_ETTS_REGS_OFFSET;
	} else {
		ptp_qoriq->regs.ctrl_regs = base + CTRL_REGS_OFFSET;
		ptp_qoriq->regs.alarm_regs = base + ALARM_REGS_OFFSET;
		ptp_qoriq->regs.fiper_regs = base + FIPER_REGS_OFFSET;
		ptp_qoriq->regs.etts_regs = base + ETTS_REGS_OFFSET;
	}

	spin_lock_init(&ptp_qoriq->lock);

	ktime_get_real_ts64(&now);
	ptp_qoriq_settime(&ptp_qoriq->caps, &now);

	tmr_ctrl =
	  (ptp_qoriq->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
	  (ptp_qoriq->cksel & CKSEL_MASK) << CKSEL_SHIFT;

	spin_lock_irqsave(&ptp_qoriq->lock, flags);

	regs = &ptp_qoriq->regs;
	ptp_qoriq->write(&regs->ctrl_regs->tmr_ctrl, tmr_ctrl);
	ptp_qoriq->write(&regs->ctrl_regs->tmr_add, ptp_qoriq->tmr_add);
	ptp_qoriq->write(&regs->ctrl_regs->tmr_prsc, ptp_qoriq->tmr_prsc);
	ptp_qoriq->write(&regs->fiper_regs->tmr_fiper1, ptp_qoriq->tmr_fiper1);
	ptp_qoriq->write(&regs->fiper_regs->tmr_fiper2, ptp_qoriq->tmr_fiper2);
	set_alarm(ptp_qoriq);
	ptp_qoriq->write(&regs->ctrl_regs->tmr_ctrl,
			 tmr_ctrl|FIPERST|RTPE|TE|FRD);

	spin_unlock_irqrestore(&ptp_qoriq->lock, flags);

	ptp_qoriq->clock = ptp_clock_register(&ptp_qoriq->caps, ptp_qoriq->dev);
	if (IS_ERR(ptp_qoriq->clock))
		return PTR_ERR(ptp_qoriq->clock);

	ptp_qoriq->phc_index = ptp_clock_index(ptp_qoriq->clock);
	ptp_qoriq_create_debugfs(ptp_qoriq);
	return 0;
}
EXPORT_SYMBOL_GPL(ptp_qoriq_init);

void ptp_qoriq_free(struct ptp_qoriq *ptp_qoriq)
{
	struct ptp_qoriq_registers *regs = &ptp_qoriq->regs;

	ptp_qoriq->write(&regs->ctrl_regs->tmr_temask, 0);
	ptp_qoriq->write(&regs->ctrl_regs->tmr_ctrl,   0);

	ptp_qoriq_remove_debugfs(ptp_qoriq);
	ptp_clock_unregister(ptp_qoriq->clock);
	iounmap(ptp_qoriq->base);
	free_irq(ptp_qoriq->irq, ptp_qoriq);
}
EXPORT_SYMBOL_GPL(ptp_qoriq_free);

static int ptp_qoriq_probe(struct platform_device *dev)
{
	struct ptp_qoriq *ptp_qoriq;
	int err = -ENOMEM;
	void __iomem *base;

	ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
	if (!ptp_qoriq)
		goto no_memory;

	ptp_qoriq->dev = &dev->dev;

	err = -ENODEV;

	ptp_qoriq->irq = platform_get_irq(dev, 0);
	if (ptp_qoriq->irq < 0) {
		pr_err("irq not in device tree\n");
		goto no_node;
	}
	if (request_irq(ptp_qoriq->irq, ptp_qoriq_isr, IRQF_SHARED,
			DRIVER, ptp_qoriq)) {
		pr_err("request_irq failed\n");
		goto no_node;
	}

	ptp_qoriq->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!ptp_qoriq->rsrc) {
		pr_err("no resource\n");
		goto no_resource;
	}
	if (request_resource(&iomem_resource, ptp_qoriq->rsrc)) {
		pr_err("resource busy\n");
		goto no_resource;
	}

	base = ioremap(ptp_qoriq->rsrc->start,
		       resource_size(ptp_qoriq->rsrc));
	if (!base) {
		pr_err("ioremap ptp registers failed\n");
		goto no_ioremap;
	}

	err = ptp_qoriq_init(ptp_qoriq, base, &ptp_qoriq_caps);
	if (err)
		goto no_clock;

	platform_set_drvdata(dev, ptp_qoriq);
	return 0;

no_clock:
	iounmap(ptp_qoriq->base);
no_ioremap:
	release_resource(ptp_qoriq->rsrc);
no_resource:
	free_irq(ptp_qoriq->irq, ptp_qoriq);
no_node:
	kfree(ptp_qoriq);
no_memory:
	return err;
}

static int ptp_qoriq_remove(struct platform_device *dev)
{
	struct ptp_qoriq *ptp_qoriq = platform_get_drvdata(dev);

	ptp_qoriq_free(ptp_qoriq);
	release_resource(ptp_qoriq->rsrc);
	kfree(ptp_qoriq);
	return 0;
}

static const struct of_device_id match_table[] = {
	{ .compatible = "fsl,etsec-ptp" },
	{ .compatible = "fsl,fman-ptp-timer" },
	{},
};
MODULE_DEVICE_TABLE(of, match_table);

static struct platform_driver ptp_qoriq_driver = {
	.driver = {
		.name		= "ptp_qoriq",
		.of_match_table	= match_table,
	},
	.probe       = ptp_qoriq_probe,
	.remove      = ptp_qoriq_remove,
};

module_platform_driver(ptp_qoriq_driver);

MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
MODULE_DESCRIPTION("PTP clock for Freescale QorIQ 1588 timer");
MODULE_LICENSE("GPL");
