/**
 * 1588 PTP support for Cadence GEM device.
 *
 * Copyright (C) 2017 Cadence Design Systems - http://www.cadence.com
 *
 * Authors: Rafal Ozieblo <rafalo@cadence.com>
 *          Bartosz Folta <bfolta@cadence.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2  of
 * the License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/time64.h>
#include <linux/ptp_classify.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/net_tstamp.h>
#include <linux/circ_buf.h>
#include <linux/spinlock.h>

#include "macb.h"

#define  GEM_PTP_TIMER_NAME "gem-ptp-timer"

static struct macb_dma_desc_ptp *macb_ptp_desc(struct macb *bp,
					       struct macb_dma_desc *desc)
{
	if (bp->hw_dma_cap == HW_DMA_CAP_PTP)
		return (struct macb_dma_desc_ptp *)
				((u8 *)desc + sizeof(struct macb_dma_desc));
	if (bp->hw_dma_cap == HW_DMA_CAP_64B_PTP)
		return (struct macb_dma_desc_ptp *)
				((u8 *)desc + sizeof(struct macb_dma_desc)
				+ sizeof(struct macb_dma_desc_64));
	return NULL;
}

static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
	struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
	unsigned long flags;
	long first, second;
	u32 secl, sech;

	spin_lock_irqsave(&bp->tsu_clk_lock, flags);
	first = gem_readl(bp, TN);
	secl = gem_readl(bp, TSL);
	sech = gem_readl(bp, TSH);
	second = gem_readl(bp, TN);

	/* test for nsec rollover */
	if (first > second) {
		/* if so, use later read & re-read seconds
		 * (assume all done within 1s)
		 */
		ts->tv_nsec = gem_readl(bp, TN);
		secl = gem_readl(bp, TSL);
		sech = gem_readl(bp, TSH);
	} else {
		ts->tv_nsec = first;
	}

	spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);
	ts->tv_sec = (((u64)sech << GEM_TSL_SIZE) | secl)
			& TSU_SEC_MAX_VAL;
	return 0;
}

static int gem_tsu_set_time(struct ptp_clock_info *ptp,
			    const struct timespec64 *ts)
{
	struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
	unsigned long flags;
	u32 ns, sech, secl;

	secl = (u32)ts->tv_sec;
	sech = (ts->tv_sec >> GEM_TSL_SIZE) & ((1 << GEM_TSH_SIZE) - 1);
	ns = ts->tv_nsec;

	spin_lock_irqsave(&bp->tsu_clk_lock, flags);

	/* TSH doesn't latch the time and no atomicity! */
	gem_writel(bp, TN, 0); /* clear to avoid overflow */
	gem_writel(bp, TSH, sech);
	/* write lower bits 2nd, for synchronized secs update */
	gem_writel(bp, TSL, secl);
	gem_writel(bp, TN, ns);

	spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);

	return 0;
}

static int gem_tsu_incr_set(struct macb *bp, struct tsu_incr *incr_spec)
{
	unsigned long flags;

	/* tsu_timer_incr register must be written after
	 * the tsu_timer_incr_sub_ns register and the write operation
	 * will cause the value written to the tsu_timer_incr_sub_ns register
	 * to take effect.
	 */
	spin_lock_irqsave(&bp->tsu_clk_lock, flags);
	gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, incr_spec->sub_ns));
	gem_writel(bp, TI, GEM_BF(NSINCR, incr_spec->ns));
	spin_unlock_irqrestore(&bp->tsu_clk_lock, flags);

	return 0;
}

static int gem_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
	struct tsu_incr incr_spec;
	bool neg_adj = false;
	u32 word;
	u64 adj;

	if (scaled_ppm < 0) {
		neg_adj = true;
		scaled_ppm = -scaled_ppm;
	}

	/* Adjustment is relative to base frequency */
	incr_spec.sub_ns = bp->tsu_incr.sub_ns;
	incr_spec.ns = bp->tsu_incr.ns;

	/* scaling: unused(8bit) | ns(8bit) | fractions(16bit) */
	word = ((u64)incr_spec.ns << GEM_SUBNSINCR_SIZE) + incr_spec.sub_ns;
	adj = (u64)scaled_ppm * word;
	/* Divide with rounding, equivalent to floating dividing:
	 * (temp / USEC_PER_SEC) + 0.5
	 */
	adj += (USEC_PER_SEC >> 1);
	adj >>= GEM_SUBNSINCR_SIZE; /* remove fractions */
	adj = div_u64(adj, USEC_PER_SEC);
	adj = neg_adj ? (word - adj) : (word + adj);

	incr_spec.ns = (adj >> GEM_SUBNSINCR_SIZE)
			& ((1 << GEM_NSINCR_SIZE) - 1);
	incr_spec.sub_ns = adj & ((1 << GEM_SUBNSINCR_SIZE) - 1);
	gem_tsu_incr_set(bp, &incr_spec);
	return 0;
}

static int gem_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct macb *bp = container_of(ptp, struct macb, ptp_clock_info);
	struct timespec64 now, then = ns_to_timespec64(delta);
	u32 adj, sign = 0;

	if (delta < 0) {
		sign = 1;
		delta = -delta;
	}

	if (delta > TSU_NSEC_MAX_VAL) {
		gem_tsu_get_time(&bp->ptp_clock_info, &now);
		now = timespec64_add(now, then);

		gem_tsu_set_time(&bp->ptp_clock_info,
				 (const struct timespec64 *)&now);
	} else {
		adj = (sign << GEM_ADDSUB_OFFSET) | delta;

		gem_writel(bp, TA, adj);
	}

	return 0;
}

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

static const struct ptp_clock_info gem_ptp_caps_template = {
	.owner		= THIS_MODULE,
	.name		= GEM_PTP_TIMER_NAME,
	.max_adj	= 0,
	.n_alarm	= 0,
	.n_ext_ts	= 0,
	.n_per_out	= 0,
	.n_pins		= 0,
	.pps		= 1,
	.adjfine	= gem_ptp_adjfine,
	.adjtime	= gem_ptp_adjtime,
	.gettime64	= gem_tsu_get_time,
	.settime64	= gem_tsu_set_time,
	.enable		= gem_ptp_enable,
};

static void gem_ptp_init_timer(struct macb *bp)
{
	u32 rem = 0;
	u64 adj;

	bp->tsu_incr.ns = div_u64_rem(NSEC_PER_SEC, bp->tsu_rate, &rem);
	if (rem) {
		adj = rem;
		adj <<= GEM_SUBNSINCR_SIZE;
		bp->tsu_incr.sub_ns = div_u64(adj, bp->tsu_rate);
	} else {
		bp->tsu_incr.sub_ns = 0;
	}
}

static void gem_ptp_init_tsu(struct macb *bp)
{
	struct timespec64 ts;

	/* 1. get current system time */
	ts = ns_to_timespec64(ktime_to_ns(ktime_get_real()));

	/* 2. set ptp timer */
	gem_tsu_set_time(&bp->ptp_clock_info, &ts);

	/* 3. set PTP timer increment value to BASE_INCREMENT */
	gem_tsu_incr_set(bp, &bp->tsu_incr);

	gem_writel(bp, TA, 0);
}

static void gem_ptp_clear_timer(struct macb *bp)
{
	bp->tsu_incr.sub_ns = 0;
	bp->tsu_incr.ns = 0;

	gem_writel(bp, TISUBN, GEM_BF(SUBNSINCR, 0));
	gem_writel(bp, TI, GEM_BF(NSINCR, 0));
	gem_writel(bp, TA, 0);
}

static int gem_hw_timestamp(struct macb *bp, u32 dma_desc_ts_1,
			    u32 dma_desc_ts_2, struct timespec64 *ts)
{
	struct timespec64 tsu;

	ts->tv_sec = (GEM_BFEXT(DMA_SECH, dma_desc_ts_2) << GEM_DMA_SECL_SIZE) |
			GEM_BFEXT(DMA_SECL, dma_desc_ts_1);
	ts->tv_nsec = GEM_BFEXT(DMA_NSEC, dma_desc_ts_1);

	/* TSU overlapping workaround
	 * The timestamp only contains lower few bits of seconds,
	 * so add value from 1588 timer
	 */
	gem_tsu_get_time(&bp->ptp_clock_info, &tsu);

	/* If the top bit is set in the timestamp,
	 * but not in 1588 timer, it has rolled over,
	 * so subtract max size
	 */
	if ((ts->tv_sec & (GEM_DMA_SEC_TOP >> 1)) &&
	    !(tsu.tv_sec & (GEM_DMA_SEC_TOP >> 1)))
		ts->tv_sec -= GEM_DMA_SEC_TOP;

	ts->tv_sec += ((~GEM_DMA_SEC_MASK) & tsu.tv_sec);

	return 0;
}

void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb,
		     struct macb_dma_desc *desc)
{
	struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
	struct macb_dma_desc_ptp *desc_ptp;
	struct timespec64 ts;

	if (GEM_BFEXT(DMA_RXVALID, desc->addr)) {
		desc_ptp = macb_ptp_desc(bp, desc);
		gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts);
		memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
		shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
	}
}

static void gem_tstamp_tx(struct macb *bp, struct sk_buff *skb,
			  struct macb_dma_desc_ptp *desc_ptp)
{
	struct skb_shared_hwtstamps shhwtstamps;
	struct timespec64 ts;

	gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts);
	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
	shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
	skb_tstamp_tx(skb, &shhwtstamps);
}

int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb,
		    struct macb_dma_desc *desc)
{
	unsigned long tail = READ_ONCE(queue->tx_ts_tail);
	unsigned long head = queue->tx_ts_head;
	struct macb_dma_desc_ptp *desc_ptp;
	struct gem_tx_ts *tx_timestamp;

	if (!GEM_BFEXT(DMA_TXVALID, desc->ctrl))
		return -EINVAL;

	if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0)
		return -ENOMEM;

	skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
	desc_ptp = macb_ptp_desc(queue->bp, desc);
	tx_timestamp = &queue->tx_timestamps[head];
	tx_timestamp->skb = skb;
	/* ensure ts_1/ts_2 is loaded after ctrl (TX_USED check) */
	dma_rmb();
	tx_timestamp->desc_ptp.ts_1 = desc_ptp->ts_1;
	tx_timestamp->desc_ptp.ts_2 = desc_ptp->ts_2;
	/* move head */
	smp_store_release(&queue->tx_ts_head,
			  (head + 1) & (PTP_TS_BUFFER_SIZE - 1));

	schedule_work(&queue->tx_ts_task);
	return 0;
}

static void gem_tx_timestamp_flush(struct work_struct *work)
{
	struct macb_queue *queue =
			container_of(work, struct macb_queue, tx_ts_task);
	unsigned long head, tail;
	struct gem_tx_ts *tx_ts;

	/* take current head */
	head = smp_load_acquire(&queue->tx_ts_head);
	tail = queue->tx_ts_tail;

	while (CIRC_CNT(head, tail, PTP_TS_BUFFER_SIZE)) {
		tx_ts = &queue->tx_timestamps[tail];
		gem_tstamp_tx(queue->bp, tx_ts->skb, &tx_ts->desc_ptp);
		/* cleanup */
		dev_kfree_skb_any(tx_ts->skb);
		/* remove old tail */
		smp_store_release(&queue->tx_ts_tail,
				  (tail + 1) & (PTP_TS_BUFFER_SIZE - 1));
		tail = queue->tx_ts_tail;
	}
}

void gem_ptp_init(struct net_device *dev)
{
	struct macb *bp = netdev_priv(dev);
	struct macb_queue *queue;
	unsigned int q;

	bp->ptp_clock_info = gem_ptp_caps_template;

	/* nominal frequency and maximum adjustment in ppb */
	bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
	bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
	gem_ptp_init_timer(bp);
	bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev);
	if (IS_ERR(bp->ptp_clock)) {
		pr_err("ptp clock register failed: %ld\n",
			PTR_ERR(bp->ptp_clock));
		bp->ptp_clock = NULL;
		return;
	} else if (bp->ptp_clock == NULL) {
		pr_err("ptp clock register failed\n");
		return;
	}

	spin_lock_init(&bp->tsu_clk_lock);
	for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
		queue->tx_ts_head = 0;
		queue->tx_ts_tail = 0;
		INIT_WORK(&queue->tx_ts_task, gem_tx_timestamp_flush);
	}

	gem_ptp_init_tsu(bp);

	dev_info(&bp->pdev->dev, "%s ptp clock registered.\n",
		 GEM_PTP_TIMER_NAME);
}

void gem_ptp_remove(struct net_device *ndev)
{
	struct macb *bp = netdev_priv(ndev);

	if (bp->ptp_clock)
		ptp_clock_unregister(bp->ptp_clock);

	gem_ptp_clear_timer(bp);

	dev_info(&bp->pdev->dev, "%s ptp clock unregistered.\n",
		 GEM_PTP_TIMER_NAME);
}

static int gem_ptp_set_ts_mode(struct macb *bp,
			       enum macb_bd_control tx_bd_control,
			       enum macb_bd_control rx_bd_control)
{
	gem_writel(bp, TXBDCTRL, GEM_BF(TXTSMODE, tx_bd_control));
	gem_writel(bp, RXBDCTRL, GEM_BF(RXTSMODE, rx_bd_control));

	return 0;
}

int gem_get_hwtst(struct net_device *dev, struct ifreq *rq)
{
	struct hwtstamp_config *tstamp_config;
	struct macb *bp = netdev_priv(dev);

	tstamp_config = &bp->tstamp_config;
	if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0)
		return -EOPNOTSUPP;

	if (copy_to_user(rq->ifr_data, tstamp_config, sizeof(*tstamp_config)))
		return -EFAULT;
	else
		return 0;
}

static int gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
{
	u32 reg_val;

	reg_val = macb_readl(bp, NCR);

	if (enable)
		macb_writel(bp, NCR, reg_val | MACB_BIT(OSSMODE));
	else
		macb_writel(bp, NCR, reg_val & ~MACB_BIT(OSSMODE));

	return 0;
}

int gem_set_hwtst(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	enum macb_bd_control tx_bd_control = TSTAMP_DISABLED;
	enum macb_bd_control rx_bd_control = TSTAMP_DISABLED;
	struct hwtstamp_config *tstamp_config;
	struct macb *bp = netdev_priv(dev);
	u32 regval;

	tstamp_config = &bp->tstamp_config;
	if ((bp->hw_dma_cap & HW_DMA_CAP_PTP) == 0)
		return -EOPNOTSUPP;

	if (copy_from_user(tstamp_config, ifr->ifr_data,
			   sizeof(*tstamp_config)))
		return -EFAULT;

	/* reserved for future extensions */
	if (tstamp_config->flags)
		return -EINVAL;

	switch (tstamp_config->tx_type) {
	case HWTSTAMP_TX_OFF:
		break;
	case HWTSTAMP_TX_ONESTEP_SYNC:
		if (gem_ptp_set_one_step_sync(bp, 1) != 0)
			return -ERANGE;
		/* fall through */
	case HWTSTAMP_TX_ON:
		tx_bd_control = TSTAMP_ALL_FRAMES;
		break;
	default:
		return -ERANGE;
	}

	switch (tstamp_config->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
		break;
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
		rx_bd_control =  TSTAMP_ALL_PTP_FRAMES;
		tstamp_config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
		regval = macb_readl(bp, NCR);
		macb_writel(bp, NCR, (regval | MACB_BIT(SRTSM)));
		break;
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
	case HWTSTAMP_FILTER_ALL:
		rx_bd_control = TSTAMP_ALL_FRAMES;
		tstamp_config->rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		tstamp_config->rx_filter = HWTSTAMP_FILTER_NONE;
		return -ERANGE;
	}

	if (gem_ptp_set_ts_mode(bp, tx_bd_control, rx_bd_control) != 0)
		return -ERANGE;

	if (copy_to_user(ifr->ifr_data, tstamp_config, sizeof(*tstamp_config)))
		return -EFAULT;
	else
		return 0;
}

