// SPDX-License-Identifier: GPL-2.0
/* Microchip KSZ PTP Implementation
 *
 * Copyright (C) 2020 ARRI Lighting
 * Copyright (C) 2022 Microchip Technology Inc.
 */

#include <linux/dsa/ksz_common.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_clock_kernel.h>

#include "ksz_common.h"
#include "ksz_ptp.h"
#include "ksz_ptp_reg.h"

#define ptp_caps_to_data(d) container_of((d), struct ksz_ptp_data, caps)
#define ptp_data_to_ksz_dev(d) container_of((d), struct ksz_device, ptp_data)
#define work_to_xmit_work(w) \
		container_of((w), struct ksz_deferred_xmit_work, work)

/* Sub-nanoseconds-adj,max * sub-nanoseconds / 40ns * 1ns
 * = (2^30-1) * (2 ^ 32) / 40 ns * 1 ns = 6249999
 */
#define KSZ_MAX_DRIFT_CORR 6249999
#define KSZ_MAX_PULSE_WIDTH 125000000LL

#define KSZ_PTP_INC_NS 40ULL  /* HW clock is incremented every 40 ns (by 40) */
#define KSZ_PTP_SUBNS_BITS 32

#define KSZ_PTP_INT_START 13

static int ksz_ptp_tou_gpio(struct ksz_device *dev)
{
	int ret;

	if (!is_lan937x(dev))
		return 0;

	ret = ksz_rmw32(dev, REG_PTP_CTRL_STAT__4, GPIO_OUT,
			GPIO_OUT);
	if (ret)
		return ret;

	ret = ksz_rmw32(dev, REG_SW_GLOBAL_LED_OVR__4, LED_OVR_1 | LED_OVR_2,
			LED_OVR_1 | LED_OVR_2);
	if (ret)
		return ret;

	return ksz_rmw32(dev, REG_SW_GLOBAL_LED_SRC__4,
			 LED_SRC_PTP_GPIO_1 | LED_SRC_PTP_GPIO_2,
			 LED_SRC_PTP_GPIO_1 | LED_SRC_PTP_GPIO_2);
}

static int ksz_ptp_tou_reset(struct ksz_device *dev, u8 unit)
{
	u32 data;
	int ret;

	/* Reset trigger unit (clears TRIGGER_EN, but not GPIOSTATx) */
	ret = ksz_rmw32(dev, REG_PTP_CTRL_STAT__4, TRIG_RESET, TRIG_RESET);

	data = FIELD_PREP(TRIG_DONE_M, BIT(unit));
	ret = ksz_write32(dev, REG_PTP_TRIG_STATUS__4, data);
	if (ret)
		return ret;

	data = FIELD_PREP(TRIG_INT_M, BIT(unit));
	ret = ksz_write32(dev, REG_PTP_INT_STATUS__4, data);
	if (ret)
		return ret;

	/* Clear reset and set GPIO direction */
	return ksz_rmw32(dev, REG_PTP_CTRL_STAT__4, (TRIG_RESET | TRIG_ENABLE),
			 0);
}

static int ksz_ptp_tou_pulse_verify(u64 pulse_ns)
{
	u32 data;

	if (pulse_ns & 0x3)
		return -EINVAL;

	data = (pulse_ns / 8);
	if (!FIELD_FIT(TRIG_PULSE_WIDTH_M, data))
		return -ERANGE;

	return 0;
}

static int ksz_ptp_tou_target_time_set(struct ksz_device *dev,
				       struct timespec64 const *ts)
{
	int ret;

	/* Hardware has only 32 bit */
	if ((ts->tv_sec & 0xffffffff) != ts->tv_sec)
		return -EINVAL;

	ret = ksz_write32(dev, REG_TRIG_TARGET_NANOSEC, ts->tv_nsec);
	if (ret)
		return ret;

	ret = ksz_write32(dev, REG_TRIG_TARGET_SEC, ts->tv_sec);
	if (ret)
		return ret;

	return 0;
}

static int ksz_ptp_tou_start(struct ksz_device *dev, u8 unit)
{
	u32 data;
	int ret;

	ret = ksz_rmw32(dev, REG_PTP_CTRL_STAT__4, TRIG_ENABLE, TRIG_ENABLE);
	if (ret)
		return ret;

	/* Check error flag:
	 * - the ACTIVE flag is NOT cleared an error!
	 */
	ret = ksz_read32(dev, REG_PTP_TRIG_STATUS__4, &data);
	if (ret)
		return ret;

	if (FIELD_GET(TRIG_ERROR_M, data) & (1 << unit)) {
		dev_err(dev->dev, "%s: Trigger unit%d error!\n", __func__,
			unit);
		ret = -EIO;
		/* Unit will be reset on next access */
		return ret;
	}

	return 0;
}

static int ksz_ptp_configure_perout(struct ksz_device *dev,
				    u32 cycle_width_ns, u32 pulse_width_ns,
				    struct timespec64 const *target_time,
				    u8 index)
{
	u32 data;
	int ret;

	data = FIELD_PREP(TRIG_NOTIFY, 1) |
		FIELD_PREP(TRIG_GPO_M, index) |
		FIELD_PREP(TRIG_PATTERN_M, TRIG_POS_PERIOD);
	ret = ksz_write32(dev, REG_TRIG_CTRL__4, data);
	if (ret)
		return ret;

	ret = ksz_write32(dev, REG_TRIG_CYCLE_WIDTH, cycle_width_ns);
	if (ret)
		return ret;

	/* Set cycle count 0 - Infinite */
	ret = ksz_rmw32(dev, REG_TRIG_CYCLE_CNT, TRIG_CYCLE_CNT_M, 0);
	if (ret)
		return ret;

	data = (pulse_width_ns / 8);
	ret = ksz_write32(dev, REG_TRIG_PULSE_WIDTH__4, data);
	if (ret)
		return ret;

	ret = ksz_ptp_tou_target_time_set(dev, target_time);
	if (ret)
		return ret;

	return 0;
}

static int ksz_ptp_enable_perout(struct ksz_device *dev,
				 struct ptp_perout_request const *request,
				 int on)
{
	struct ksz_ptp_data *ptp_data = &dev->ptp_data;
	u64 req_pulse_width_ns;
	u64 cycle_width_ns;
	u64 pulse_width_ns;
	int pin = 0;
	u32 data32;
	int ret;

	if (request->flags & ~PTP_PEROUT_DUTY_CYCLE)
		return -EOPNOTSUPP;

	if (ptp_data->tou_mode != KSZ_PTP_TOU_PEROUT &&
	    ptp_data->tou_mode != KSZ_PTP_TOU_IDLE)
		return -EBUSY;

	pin = ptp_find_pin(ptp_data->clock, PTP_PF_PEROUT, request->index);
	if (pin < 0)
		return -EINVAL;

	data32 = FIELD_PREP(PTP_GPIO_INDEX, pin) |
		 FIELD_PREP(PTP_TOU_INDEX, request->index);
	ret = ksz_rmw32(dev, REG_PTP_UNIT_INDEX__4,
			PTP_GPIO_INDEX | PTP_TOU_INDEX, data32);
	if (ret)
		return ret;

	ret = ksz_ptp_tou_reset(dev, request->index);
	if (ret)
		return ret;

	if (!on) {
		ptp_data->tou_mode = KSZ_PTP_TOU_IDLE;
		return 0;
	}

	ptp_data->perout_target_time_first.tv_sec  = request->start.sec;
	ptp_data->perout_target_time_first.tv_nsec = request->start.nsec;

	ptp_data->perout_period.tv_sec = request->period.sec;
	ptp_data->perout_period.tv_nsec = request->period.nsec;

	cycle_width_ns = timespec64_to_ns(&ptp_data->perout_period);
	if ((cycle_width_ns & TRIG_CYCLE_WIDTH_M) != cycle_width_ns)
		return -EINVAL;

	if (request->flags & PTP_PEROUT_DUTY_CYCLE) {
		pulse_width_ns = request->on.sec * NSEC_PER_SEC +
			request->on.nsec;
	} else {
		/* Use a duty cycle of 50%. Maximum pulse width supported by the
		 * hardware is a little bit more than 125 ms.
		 */
		req_pulse_width_ns = (request->period.sec * NSEC_PER_SEC +
				      request->period.nsec) / 2;
		pulse_width_ns = min_t(u64, req_pulse_width_ns,
				       KSZ_MAX_PULSE_WIDTH);
	}

	ret = ksz_ptp_tou_pulse_verify(pulse_width_ns);
	if (ret)
		return ret;

	ret = ksz_ptp_configure_perout(dev, cycle_width_ns, pulse_width_ns,
				       &ptp_data->perout_target_time_first,
				       pin);
	if (ret)
		return ret;

	ret = ksz_ptp_tou_gpio(dev);
	if (ret)
		return ret;

	ret = ksz_ptp_tou_start(dev, request->index);
	if (ret)
		return ret;

	ptp_data->tou_mode = KSZ_PTP_TOU_PEROUT;

	return 0;
}

static int ksz_ptp_enable_mode(struct ksz_device *dev)
{
	struct ksz_tagger_data *tagger_data = ksz_tagger_data(dev->ds);
	struct ksz_ptp_data *ptp_data = &dev->ptp_data;
	struct ksz_port *prt;
	struct dsa_port *dp;
	bool tag_en = false;

	dsa_switch_for_each_user_port(dp, dev->ds) {
		prt = &dev->ports[dp->index];
		if (prt->hwts_tx_en || prt->hwts_rx_en) {
			tag_en = true;
			break;
		}
	}

	if (tag_en) {
		ptp_schedule_worker(ptp_data->clock, 0);
	} else {
		ptp_cancel_worker_sync(ptp_data->clock);
	}

	tagger_data->hwtstamp_set_state(dev->ds, tag_en);

	return ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_ENABLE,
			 tag_en ? PTP_ENABLE : 0);
}

/* The function is return back the capability of timestamping feature when
 * requested through ethtool -T <interface> utility
 */
int ksz_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *ts)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_ptp_data *ptp_data;

	ptp_data = &dev->ptp_data;

	if (!ptp_data->clock)
		return -ENODEV;

	ts->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
			      SOF_TIMESTAMPING_RX_HARDWARE |
			      SOF_TIMESTAMPING_RAW_HARDWARE;

	ts->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ONESTEP_P2P);

	if (is_lan937x(dev))
		ts->tx_types |= BIT(HWTSTAMP_TX_ON);

	ts->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
			 BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
			 BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
			 BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);

	ts->phc_index = ptp_clock_index(ptp_data->clock);

	return 0;
}

int ksz_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr)
{
	struct ksz_device *dev = ds->priv;
	struct hwtstamp_config *config;
	struct ksz_port *prt;

	prt = &dev->ports[port];
	config = &prt->tstamp_config;

	return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?
		-EFAULT : 0;
}

static int ksz_set_hwtstamp_config(struct ksz_device *dev,
				   struct ksz_port *prt,
				   struct hwtstamp_config *config)
{
	int ret;

	if (config->flags)
		return -EINVAL;

	switch (config->tx_type) {
	case HWTSTAMP_TX_OFF:
		prt->ptpmsg_irq[KSZ_SYNC_MSG].ts_en  = false;
		prt->ptpmsg_irq[KSZ_XDREQ_MSG].ts_en = false;
		prt->ptpmsg_irq[KSZ_PDRES_MSG].ts_en = false;
		prt->hwts_tx_en = false;
		break;
	case HWTSTAMP_TX_ONESTEP_P2P:
		prt->ptpmsg_irq[KSZ_SYNC_MSG].ts_en  = false;
		prt->ptpmsg_irq[KSZ_XDREQ_MSG].ts_en = true;
		prt->ptpmsg_irq[KSZ_PDRES_MSG].ts_en = false;
		prt->hwts_tx_en = true;

		ret = ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_1STEP, PTP_1STEP);
		if (ret)
			return ret;

		break;
	case HWTSTAMP_TX_ON:
		if (!is_lan937x(dev))
			return -ERANGE;

		prt->ptpmsg_irq[KSZ_SYNC_MSG].ts_en  = true;
		prt->ptpmsg_irq[KSZ_XDREQ_MSG].ts_en = true;
		prt->ptpmsg_irq[KSZ_PDRES_MSG].ts_en = true;
		prt->hwts_tx_en = true;

		ret = ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_1STEP, 0);
		if (ret)
			return ret;

		break;
	default:
		return -ERANGE;
	}

	switch (config->rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		prt->hwts_rx_en = false;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
		prt->hwts_rx_en = true;
		break;
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
		prt->hwts_rx_en = true;
		break;
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
		config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
		prt->hwts_rx_en = true;
		break;
	default:
		config->rx_filter = HWTSTAMP_FILTER_NONE;
		return -ERANGE;
	}

	return ksz_ptp_enable_mode(dev);
}

int ksz_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
{
	struct ksz_device *dev = ds->priv;
	struct hwtstamp_config config;
	struct ksz_port *prt;
	int ret;

	prt = &dev->ports[port];

	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
		return -EFAULT;

	ret = ksz_set_hwtstamp_config(dev, prt, &config);
	if (ret)
		return ret;

	memcpy(&prt->tstamp_config, &config, sizeof(config));

	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
		return -EFAULT;

	return 0;
}

static ktime_t ksz_tstamp_reconstruct(struct ksz_device *dev, ktime_t tstamp)
{
	struct timespec64 ptp_clock_time;
	struct ksz_ptp_data *ptp_data;
	struct timespec64 diff;
	struct timespec64 ts;

	ptp_data = &dev->ptp_data;
	ts = ktime_to_timespec64(tstamp);

	spin_lock_bh(&ptp_data->clock_lock);
	ptp_clock_time = ptp_data->clock_time;
	spin_unlock_bh(&ptp_data->clock_lock);

	/* calculate full time from partial time stamp */
	ts.tv_sec = (ptp_clock_time.tv_sec & ~3) | ts.tv_sec;

	/* find nearest possible point in time */
	diff = timespec64_sub(ts, ptp_clock_time);
	if (diff.tv_sec > 2)
		ts.tv_sec -= 4;
	else if (diff.tv_sec < -2)
		ts.tv_sec += 4;

	return timespec64_to_ktime(ts);
}

bool ksz_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb,
		       unsigned int type)
{
	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
	struct ksz_device *dev = ds->priv;
	struct ptp_header *ptp_hdr;
	struct ksz_port *prt;
	u8 ptp_msg_type;
	ktime_t tstamp;
	s64 correction;

	prt = &dev->ports[port];

	tstamp = KSZ_SKB_CB(skb)->tstamp;
	memset(hwtstamps, 0, sizeof(*hwtstamps));
	hwtstamps->hwtstamp = ksz_tstamp_reconstruct(dev, tstamp);

	if (prt->tstamp_config.tx_type != HWTSTAMP_TX_ONESTEP_P2P)
		goto out;

	ptp_hdr = ptp_parse_header(skb, type);
	if (!ptp_hdr)
		goto out;

	ptp_msg_type = ptp_get_msgtype(ptp_hdr, type);
	if (ptp_msg_type != PTP_MSGTYPE_PDELAY_REQ)
		goto out;

	/* Only subtract the partial time stamp from the correction field.  When
	 * the hardware adds the egress time stamp to the correction field of
	 * the PDelay_Resp message on tx, also only the partial time stamp will
	 * be added.
	 */
	correction = (s64)get_unaligned_be64(&ptp_hdr->correction);
	correction -= ktime_to_ns(tstamp) << 16;

	ptp_header_update_correction(skb, type, ptp_hdr, correction);

out:
	return false;
}

void ksz_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
{
	struct ksz_device *dev = ds->priv;
	struct ptp_header *hdr;
	struct sk_buff *clone;
	struct ksz_port *prt;
	unsigned int type;
	u8 ptp_msg_type;

	prt = &dev->ports[port];

	if (!prt->hwts_tx_en)
		return;

	type = ptp_classify_raw(skb);
	if (type == PTP_CLASS_NONE)
		return;

	hdr = ptp_parse_header(skb, type);
	if (!hdr)
		return;

	ptp_msg_type = ptp_get_msgtype(hdr, type);

	switch (ptp_msg_type) {
	case PTP_MSGTYPE_SYNC:
		if (prt->tstamp_config.tx_type == HWTSTAMP_TX_ONESTEP_P2P)
			return;
		break;
	case PTP_MSGTYPE_PDELAY_REQ:
		break;
	case PTP_MSGTYPE_PDELAY_RESP:
		if (prt->tstamp_config.tx_type == HWTSTAMP_TX_ONESTEP_P2P) {
			KSZ_SKB_CB(skb)->ptp_type = type;
			KSZ_SKB_CB(skb)->update_correction = true;
			return;
		}
		break;

	default:
		return;
	}

	clone = skb_clone_sk(skb);
	if (!clone)
		return;

	/* caching the value to be used in tag_ksz.c */
	KSZ_SKB_CB(skb)->clone = clone;
}

static void ksz_ptp_txtstamp_skb(struct ksz_device *dev,
				 struct ksz_port *prt, struct sk_buff *skb)
{
	struct skb_shared_hwtstamps hwtstamps = {};
	int ret;

	/* timeout must include DSA master to transmit data, tstamp latency,
	 * IRQ latency and time for reading the time stamp.
	 */
	ret = wait_for_completion_timeout(&prt->tstamp_msg_comp,
					  msecs_to_jiffies(100));
	if (!ret)
		return;

	hwtstamps.hwtstamp = prt->tstamp_msg;
	skb_complete_tx_timestamp(skb, &hwtstamps);
}

void ksz_port_deferred_xmit(struct kthread_work *work)
{
	struct ksz_deferred_xmit_work *xmit_work = work_to_xmit_work(work);
	struct sk_buff *clone, *skb = xmit_work->skb;
	struct dsa_switch *ds = xmit_work->dp->ds;
	struct ksz_device *dev = ds->priv;
	struct ksz_port *prt;

	prt = &dev->ports[xmit_work->dp->index];

	clone = KSZ_SKB_CB(skb)->clone;

	skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;

	reinit_completion(&prt->tstamp_msg_comp);

	dsa_enqueue_skb(skb, skb->dev);

	ksz_ptp_txtstamp_skb(dev, prt, clone);

	kfree(xmit_work);
}

static int _ksz_ptp_gettime(struct ksz_device *dev, struct timespec64 *ts)
{
	u32 nanoseconds;
	u32 seconds;
	u8 phase;
	int ret;

	/* Copy current PTP clock into shadow registers and read */
	ret = ksz_rmw16(dev, REG_PTP_CLK_CTRL, PTP_READ_TIME, PTP_READ_TIME);
	if (ret)
		return ret;

	ret = ksz_read8(dev, REG_PTP_RTC_SUB_NANOSEC__2, &phase);
	if (ret)
		return ret;

	ret = ksz_read32(dev, REG_PTP_RTC_NANOSEC, &nanoseconds);
	if (ret)
		return ret;

	ret = ksz_read32(dev, REG_PTP_RTC_SEC, &seconds);
	if (ret)
		return ret;

	ts->tv_sec = seconds;
	ts->tv_nsec = nanoseconds + phase * 8;

	return 0;
}

static int ksz_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	int ret;

	mutex_lock(&ptp_data->lock);
	ret = _ksz_ptp_gettime(dev, ts);
	mutex_unlock(&ptp_data->lock);

	return ret;
}

static int ksz_ptp_restart_perout(struct ksz_device *dev)
{
	struct ksz_ptp_data *ptp_data = &dev->ptp_data;
	s64 now_ns, first_ns, period_ns, next_ns;
	struct ptp_perout_request request;
	struct timespec64 next;
	struct timespec64 now;
	unsigned int count;
	int ret;

	dev_info(dev->dev, "Restarting periodic output signal\n");

	ret = _ksz_ptp_gettime(dev, &now);
	if (ret)
		return ret;

	now_ns = timespec64_to_ns(&now);
	first_ns = timespec64_to_ns(&ptp_data->perout_target_time_first);

	/* Calculate next perout event based on start time and period */
	period_ns = timespec64_to_ns(&ptp_data->perout_period);

	if (first_ns < now_ns) {
		count = div_u64(now_ns - first_ns, period_ns);
		next_ns = first_ns + count * period_ns;
	} else {
		next_ns = first_ns;
	}

	/* Ensure 100 ms guard time prior next event */
	while (next_ns < now_ns + 100000000)
		next_ns += period_ns;

	/* Restart periodic output signal */
	next = ns_to_timespec64(next_ns);
	request.start.sec  = next.tv_sec;
	request.start.nsec = next.tv_nsec;
	request.period.sec  = ptp_data->perout_period.tv_sec;
	request.period.nsec = ptp_data->perout_period.tv_nsec;
	request.index = 0;
	request.flags = 0;

	return ksz_ptp_enable_perout(dev, &request, 1);
}

static int ksz_ptp_settime(struct ptp_clock_info *ptp,
			   const struct timespec64 *ts)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	int ret;

	mutex_lock(&ptp_data->lock);

	/* Write to shadow registers and Load PTP clock */
	ret = ksz_write16(dev, REG_PTP_RTC_SUB_NANOSEC__2, PTP_RTC_0NS);
	if (ret)
		goto unlock;

	ret = ksz_write32(dev, REG_PTP_RTC_NANOSEC, ts->tv_nsec);
	if (ret)
		goto unlock;

	ret = ksz_write32(dev, REG_PTP_RTC_SEC, ts->tv_sec);
	if (ret)
		goto unlock;

	ret = ksz_rmw16(dev, REG_PTP_CLK_CTRL, PTP_LOAD_TIME, PTP_LOAD_TIME);
	if (ret)
		goto unlock;

	switch (ptp_data->tou_mode) {
	case KSZ_PTP_TOU_IDLE:
		break;

	case KSZ_PTP_TOU_PEROUT:
		ret = ksz_ptp_restart_perout(dev);
		if (ret)
			goto unlock;

		break;
	}

	spin_lock_bh(&ptp_data->clock_lock);
	ptp_data->clock_time = *ts;
	spin_unlock_bh(&ptp_data->clock_lock);

unlock:
	mutex_unlock(&ptp_data->lock);

	return ret;
}

static int ksz_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	u64 base, adj;
	bool negative;
	u32 data32;
	int ret;

	mutex_lock(&ptp_data->lock);

	if (scaled_ppm) {
		base = KSZ_PTP_INC_NS << KSZ_PTP_SUBNS_BITS;
		negative = diff_by_scaled_ppm(base, scaled_ppm, &adj);

		data32 = (u32)adj;
		data32 &= PTP_SUBNANOSEC_M;
		if (!negative)
			data32 |= PTP_RATE_DIR;

		ret = ksz_write32(dev, REG_PTP_SUBNANOSEC_RATE, data32);
		if (ret)
			goto unlock;

		ret = ksz_rmw16(dev, REG_PTP_CLK_CTRL, PTP_CLK_ADJ_ENABLE,
				PTP_CLK_ADJ_ENABLE);
		if (ret)
			goto unlock;
	} else {
		ret = ksz_rmw16(dev, REG_PTP_CLK_CTRL, PTP_CLK_ADJ_ENABLE, 0);
		if (ret)
			goto unlock;
	}

unlock:
	mutex_unlock(&ptp_data->lock);
	return ret;
}

static int ksz_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	struct timespec64 delta64 = ns_to_timespec64(delta);
	s32 sec, nsec;
	u16 data16;
	int ret;

	mutex_lock(&ptp_data->lock);

	/* do not use ns_to_timespec64(),
	 * both sec and nsec are subtracted by hw
	 */
	sec = div_s64_rem(delta, NSEC_PER_SEC, &nsec);

	ret = ksz_write32(dev, REG_PTP_RTC_NANOSEC, abs(nsec));
	if (ret)
		goto unlock;

	ret = ksz_write32(dev, REG_PTP_RTC_SEC, abs(sec));
	if (ret)
		goto unlock;

	ret = ksz_read16(dev, REG_PTP_CLK_CTRL, &data16);
	if (ret)
		goto unlock;

	data16 |= PTP_STEP_ADJ;

	/* PTP_STEP_DIR -- 0: subtract, 1: add */
	if (delta < 0)
		data16 &= ~PTP_STEP_DIR;
	else
		data16 |= PTP_STEP_DIR;

	ret = ksz_write16(dev, REG_PTP_CLK_CTRL, data16);
	if (ret)
		goto unlock;

	switch (ptp_data->tou_mode) {
	case KSZ_PTP_TOU_IDLE:
		break;

	case KSZ_PTP_TOU_PEROUT:
		ret = ksz_ptp_restart_perout(dev);
		if (ret)
			goto unlock;

		break;
	}

	spin_lock_bh(&ptp_data->clock_lock);
	ptp_data->clock_time = timespec64_add(ptp_data->clock_time, delta64);
	spin_unlock_bh(&ptp_data->clock_lock);

unlock:
	mutex_unlock(&ptp_data->lock);
	return ret;
}

static int ksz_ptp_enable(struct ptp_clock_info *ptp,
			  struct ptp_clock_request *req, int on)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	int ret;

	switch (req->type) {
	case PTP_CLK_REQ_PEROUT:
		mutex_lock(&ptp_data->lock);
		ret = ksz_ptp_enable_perout(dev, &req->perout, on);
		mutex_unlock(&ptp_data->lock);
		break;
	default:
		return -EOPNOTSUPP;
	}

	return ret;
}

static int ksz_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,
			      enum ptp_pin_function func, unsigned int chan)
{
	int ret = 0;

	switch (func) {
	case PTP_PF_NONE:
	case PTP_PF_PEROUT:
		break;
	default:
		ret = -1;
		break;
	}

	return ret;
}

/*  Function is pointer to the do_aux_work in the ptp_clock capability */
static long ksz_ptp_do_aux_work(struct ptp_clock_info *ptp)
{
	struct ksz_ptp_data *ptp_data = ptp_caps_to_data(ptp);
	struct ksz_device *dev = ptp_data_to_ksz_dev(ptp_data);
	struct timespec64 ts;
	int ret;

	mutex_lock(&ptp_data->lock);
	ret = _ksz_ptp_gettime(dev, &ts);
	if (ret)
		goto out;

	spin_lock_bh(&ptp_data->clock_lock);
	ptp_data->clock_time = ts;
	spin_unlock_bh(&ptp_data->clock_lock);

out:
	mutex_unlock(&ptp_data->lock);

	return HZ;  /* reschedule in 1 second */
}

static int ksz_ptp_start_clock(struct ksz_device *dev)
{
	struct ksz_ptp_data *ptp_data = &dev->ptp_data;
	int ret;

	ret = ksz_rmw16(dev, REG_PTP_CLK_CTRL, PTP_CLK_ENABLE, PTP_CLK_ENABLE);
	if (ret)
		return ret;

	ptp_data->clock_time.tv_sec = 0;
	ptp_data->clock_time.tv_nsec = 0;

	return 0;
}

int ksz_ptp_clock_register(struct dsa_switch *ds)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_ptp_data *ptp_data;
	int ret;
	u8 i;

	ptp_data = &dev->ptp_data;
	mutex_init(&ptp_data->lock);
	spin_lock_init(&ptp_data->clock_lock);

	ptp_data->caps.owner		= THIS_MODULE;
	snprintf(ptp_data->caps.name, 16, "Microchip Clock");
	ptp_data->caps.max_adj		= KSZ_MAX_DRIFT_CORR;
	ptp_data->caps.gettime64	= ksz_ptp_gettime;
	ptp_data->caps.settime64	= ksz_ptp_settime;
	ptp_data->caps.adjfine		= ksz_ptp_adjfine;
	ptp_data->caps.adjtime		= ksz_ptp_adjtime;
	ptp_data->caps.do_aux_work	= ksz_ptp_do_aux_work;
	ptp_data->caps.enable		= ksz_ptp_enable;
	ptp_data->caps.verify		= ksz_ptp_verify_pin;
	ptp_data->caps.n_pins		= KSZ_PTP_N_GPIO;
	ptp_data->caps.n_per_out	= 3;

	ret = ksz_ptp_start_clock(dev);
	if (ret)
		return ret;

	for (i = 0; i < KSZ_PTP_N_GPIO; i++) {
		struct ptp_pin_desc *ptp_pin = &ptp_data->pin_config[i];

		snprintf(ptp_pin->name,
			 sizeof(ptp_pin->name), "ksz_ptp_pin_%02d", i);
		ptp_pin->index = i;
		ptp_pin->func = PTP_PF_NONE;
	}

	ptp_data->caps.pin_config = ptp_data->pin_config;

	/* Currently only P2P mode is supported. When 802_1AS bit is set, it
	 * forwards all PTP packets to host port and none to other ports.
	 */
	ret = ksz_rmw16(dev, REG_PTP_MSG_CONF1, PTP_TC_P2P | PTP_802_1AS,
			PTP_TC_P2P | PTP_802_1AS);
	if (ret)
		return ret;

	ptp_data->clock = ptp_clock_register(&ptp_data->caps, dev->dev);
	if (IS_ERR_OR_NULL(ptp_data->clock))
		return PTR_ERR(ptp_data->clock);

	return 0;
}

void ksz_ptp_clock_unregister(struct dsa_switch *ds)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_ptp_data *ptp_data;

	ptp_data = &dev->ptp_data;

	if (ptp_data->clock)
		ptp_clock_unregister(ptp_data->clock);
}

static irqreturn_t ksz_ptp_msg_thread_fn(int irq, void *dev_id)
{
	struct ksz_ptp_irq *ptpmsg_irq = dev_id;
	struct ksz_device *dev;
	struct ksz_port *port;
	u32 tstamp_raw;
	ktime_t tstamp;
	int ret;

	port = ptpmsg_irq->port;
	dev = port->ksz_dev;

	if (ptpmsg_irq->ts_en) {
		ret = ksz_read32(dev, ptpmsg_irq->ts_reg, &tstamp_raw);
		if (ret)
			return IRQ_NONE;

		tstamp = ksz_decode_tstamp(tstamp_raw);

		port->tstamp_msg = ksz_tstamp_reconstruct(dev, tstamp);

		complete(&port->tstamp_msg_comp);
	}

	return IRQ_HANDLED;
}

static irqreturn_t ksz_ptp_irq_thread_fn(int irq, void *dev_id)
{
	struct ksz_irq *ptpirq = dev_id;
	unsigned int nhandled = 0;
	struct ksz_device *dev;
	unsigned int sub_irq;
	u16 data;
	int ret;
	u8 n;

	dev = ptpirq->dev;

	ret = ksz_read16(dev, ptpirq->reg_status, &data);
	if (ret)
		goto out;

	/* Clear the interrupts W1C */
	ret = ksz_write16(dev, ptpirq->reg_status, data);
	if (ret)
		return IRQ_NONE;

	for (n = 0; n < ptpirq->nirqs; ++n) {
		if (data & BIT(n + KSZ_PTP_INT_START)) {
			sub_irq = irq_find_mapping(ptpirq->domain, n);
			handle_nested_irq(sub_irq);
			++nhandled;
		}
	}

out:
	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
}

static void ksz_ptp_irq_mask(struct irq_data *d)
{
	struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);

	kirq->masked &= ~BIT(d->hwirq + KSZ_PTP_INT_START);
}

static void ksz_ptp_irq_unmask(struct irq_data *d)
{
	struct ksz_irq *kirq = irq_data_get_irq_chip_data(d);

	kirq->masked |= BIT(d->hwirq + KSZ_PTP_INT_START);
}

static void ksz_ptp_irq_bus_lock(struct irq_data *d)
{
	struct ksz_irq *kirq  = irq_data_get_irq_chip_data(d);

	mutex_lock(&kirq->dev->lock_irq);
}

static void ksz_ptp_irq_bus_sync_unlock(struct irq_data *d)
{
	struct ksz_irq *kirq  = irq_data_get_irq_chip_data(d);
	struct ksz_device *dev = kirq->dev;
	int ret;

	ret = ksz_write16(dev, kirq->reg_mask, kirq->masked);
	if (ret)
		dev_err(dev->dev, "failed to change IRQ mask\n");

	mutex_unlock(&dev->lock_irq);
}

static const struct irq_chip ksz_ptp_irq_chip = {
	.name			= "ksz-irq",
	.irq_mask		= ksz_ptp_irq_mask,
	.irq_unmask		= ksz_ptp_irq_unmask,
	.irq_bus_lock		= ksz_ptp_irq_bus_lock,
	.irq_bus_sync_unlock	= ksz_ptp_irq_bus_sync_unlock,
};

static int ksz_ptp_irq_domain_map(struct irq_domain *d,
				  unsigned int irq, irq_hw_number_t hwirq)
{
	irq_set_chip_data(irq, d->host_data);
	irq_set_chip_and_handler(irq, &ksz_ptp_irq_chip, handle_level_irq);
	irq_set_noprobe(irq);

	return 0;
}

static const struct irq_domain_ops ksz_ptp_irq_domain_ops = {
	.map	= ksz_ptp_irq_domain_map,
	.xlate	= irq_domain_xlate_twocell,
};

static void ksz_ptp_msg_irq_free(struct ksz_port *port, u8 n)
{
	struct ksz_ptp_irq *ptpmsg_irq;

	ptpmsg_irq = &port->ptpmsg_irq[n];

	free_irq(ptpmsg_irq->num, ptpmsg_irq);
	irq_dispose_mapping(ptpmsg_irq->num);
}

static int ksz_ptp_msg_irq_setup(struct ksz_port *port, u8 n)
{
	u16 ts_reg[] = {REG_PTP_PORT_PDRESP_TS, REG_PTP_PORT_XDELAY_TS,
			REG_PTP_PORT_SYNC_TS};
	static const char * const name[] = {"pdresp-msg", "xdreq-msg",
					    "sync-msg"};
	const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops;
	struct ksz_ptp_irq *ptpmsg_irq;

	ptpmsg_irq = &port->ptpmsg_irq[n];

	ptpmsg_irq->port = port;
	ptpmsg_irq->ts_reg = ops->get_port_addr(port->num, ts_reg[n]);

	snprintf(ptpmsg_irq->name, sizeof(ptpmsg_irq->name), name[n]);

	ptpmsg_irq->num = irq_find_mapping(port->ptpirq.domain, n);
	if (ptpmsg_irq->num < 0)
		return ptpmsg_irq->num;

	return request_threaded_irq(ptpmsg_irq->num, NULL,
				    ksz_ptp_msg_thread_fn, IRQF_ONESHOT,
				    ptpmsg_irq->name, ptpmsg_irq);
}

int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p)
{
	struct ksz_device *dev = ds->priv;
	const struct ksz_dev_ops *ops = dev->dev_ops;
	struct ksz_port *port = &dev->ports[p];
	struct ksz_irq *ptpirq = &port->ptpirq;
	int irq;
	int ret;

	ptpirq->dev = dev;
	ptpirq->masked = 0;
	ptpirq->nirqs = 3;
	ptpirq->reg_mask = ops->get_port_addr(p, REG_PTP_PORT_TX_INT_ENABLE__2);
	ptpirq->reg_status = ops->get_port_addr(p,
						REG_PTP_PORT_TX_INT_STATUS__2);
	snprintf(ptpirq->name, sizeof(ptpirq->name), "ptp-irq-%d", p);

	init_completion(&port->tstamp_msg_comp);

	ptpirq->domain = irq_domain_add_linear(dev->dev->of_node, ptpirq->nirqs,
					       &ksz_ptp_irq_domain_ops, ptpirq);
	if (!ptpirq->domain)
		return -ENOMEM;

	for (irq = 0; irq < ptpirq->nirqs; irq++)
		irq_create_mapping(ptpirq->domain, irq);

	ptpirq->irq_num = irq_find_mapping(port->pirq.domain, PORT_SRC_PTP_INT);
	if (ptpirq->irq_num < 0) {
		ret = ptpirq->irq_num;
		goto out;
	}

	ret = request_threaded_irq(ptpirq->irq_num, NULL, ksz_ptp_irq_thread_fn,
				   IRQF_ONESHOT, ptpirq->name, ptpirq);
	if (ret)
		goto out;

	for (irq = 0; irq < ptpirq->nirqs; irq++) {
		ret = ksz_ptp_msg_irq_setup(port, irq);
		if (ret)
			goto out_ptp_msg;
	}

	return 0;

out_ptp_msg:
	free_irq(ptpirq->irq_num, ptpirq);
	while (irq--)
		free_irq(port->ptpmsg_irq[irq].num, &port->ptpmsg_irq[irq]);
out:
	for (irq = 0; irq < ptpirq->nirqs; irq++)
		irq_dispose_mapping(port->ptpmsg_irq[irq].num);

	irq_domain_remove(ptpirq->domain);

	return ret;
}

void ksz_ptp_irq_free(struct dsa_switch *ds, u8 p)
{
	struct ksz_device *dev = ds->priv;
	struct ksz_port *port = &dev->ports[p];
	struct ksz_irq *ptpirq = &port->ptpirq;
	u8 n;

	for (n = 0; n < ptpirq->nirqs; n++)
		ksz_ptp_msg_irq_free(port, n);

	free_irq(ptpirq->irq_num, ptpirq);
	irq_dispose_mapping(ptpirq->irq_num);

	irq_domain_remove(ptpirq->domain);
}

MODULE_AUTHOR("Christian Eggers <ceggers@arri.de>");
MODULE_AUTHOR("Arun Ramadoss <arun.ramadoss@microchip.com>");
MODULE_DESCRIPTION("PTP support for KSZ switch");
MODULE_LICENSE("GPL");
