// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
 * DSA driver for:
 * Hirschmann Hellcreek TSN switch.
 *
 * Copyright (C) 2019,2020 Hochschule Offenburg
 * Copyright (C) 2019,2020 Linutronix GmbH
 * Authors: Kamil Alkhouri <kamil.alkhouri@hs-offenburg.de>
 *	    Kurt Kanzenbach <kurt@linutronix.de>
 */

#include <linux/of.h>
#include <linux/ptp_clock_kernel.h>
#include "hellcreek.h"
#include "hellcreek_ptp.h"
#include "hellcreek_hwtstamp.h"

u16 hellcreek_ptp_read(struct hellcreek *hellcreek, unsigned int offset)
{
	return readw(hellcreek->ptp_base + offset);
}

void hellcreek_ptp_write(struct hellcreek *hellcreek, u16 data,
			 unsigned int offset)
{
	writew(data, hellcreek->ptp_base + offset);
}

/* Get nanoseconds from PTP clock */
static u64 hellcreek_ptp_clock_read(struct hellcreek *hellcreek,
				    struct ptp_system_timestamp *sts)
{
	u16 nsl, nsh;

	/* Take a snapshot */
	hellcreek_ptp_write(hellcreek, PR_COMMAND_C_SS, PR_COMMAND_C);

	/* The time of the day is saved as 96 bits. However, due to hardware
	 * limitations the seconds are not or only partly kept in the PTP
	 * core. Currently only three bits for the seconds are available. That's
	 * why only the nanoseconds are used and the seconds are tracked in
	 * software. Anyway due to internal locking all five registers should be
	 * read.
	 */
	nsh = hellcreek_ptp_read(hellcreek, PR_SS_SYNC_DATA_C);
	nsh = hellcreek_ptp_read(hellcreek, PR_SS_SYNC_DATA_C);
	nsh = hellcreek_ptp_read(hellcreek, PR_SS_SYNC_DATA_C);
	nsh = hellcreek_ptp_read(hellcreek, PR_SS_SYNC_DATA_C);
	ptp_read_system_prets(sts);
	nsl = hellcreek_ptp_read(hellcreek, PR_SS_SYNC_DATA_C);
	ptp_read_system_postts(sts);

	return (u64)nsl | ((u64)nsh << 16);
}

static u64 __hellcreek_ptp_gettime(struct hellcreek *hellcreek,
				   struct ptp_system_timestamp *sts)
{
	u64 ns;

	ns = hellcreek_ptp_clock_read(hellcreek, sts);
	if (ns < hellcreek->last_ts)
		hellcreek->seconds++;
	hellcreek->last_ts = ns;
	ns += hellcreek->seconds * NSEC_PER_SEC;

	return ns;
}

/* Retrieve the seconds parts in nanoseconds for a packet timestamped with @ns.
 * There has to be a check whether an overflow occurred between the packet
 * arrival and now. If so use the correct seconds (-1) for calculating the
 * packet arrival time.
 */
u64 hellcreek_ptp_gettime_seconds(struct hellcreek *hellcreek, u64 ns)
{
	u64 s;

	__hellcreek_ptp_gettime(hellcreek, NULL);
	if (hellcreek->last_ts > ns)
		s = hellcreek->seconds * NSEC_PER_SEC;
	else
		s = (hellcreek->seconds - 1) * NSEC_PER_SEC;

	return s;
}

static int hellcreek_ptp_gettimex(struct ptp_clock_info *ptp,
				  struct timespec64 *ts,
				  struct ptp_system_timestamp *sts)
{
	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
	u64 ns;

	mutex_lock(&hellcreek->ptp_lock);
	ns = __hellcreek_ptp_gettime(hellcreek, sts);
	mutex_unlock(&hellcreek->ptp_lock);

	*ts = ns_to_timespec64(ns);

	return 0;
}

static int hellcreek_ptp_settime(struct ptp_clock_info *ptp,
				 const struct timespec64 *ts)
{
	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
	u16 secl, nsh, nsl;

	secl = ts->tv_sec & 0xffff;
	nsh  = ((u32)ts->tv_nsec & 0xffff0000) >> 16;
	nsl  = ts->tv_nsec & 0xffff;

	mutex_lock(&hellcreek->ptp_lock);

	/* Update overflow data structure */
	hellcreek->seconds = ts->tv_sec;
	hellcreek->last_ts = ts->tv_nsec;

	/* Set time in clock */
	hellcreek_ptp_write(hellcreek, 0x00, PR_CLOCK_WRITE_C);
	hellcreek_ptp_write(hellcreek, 0x00, PR_CLOCK_WRITE_C);
	hellcreek_ptp_write(hellcreek, secl, PR_CLOCK_WRITE_C);
	hellcreek_ptp_write(hellcreek, nsh,  PR_CLOCK_WRITE_C);
	hellcreek_ptp_write(hellcreek, nsl,  PR_CLOCK_WRITE_C);

	mutex_unlock(&hellcreek->ptp_lock);

	return 0;
}

static int hellcreek_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
	u16 negative = 0, addendh, addendl;
	u32 addend;
	u64 adj;

	if (scaled_ppm < 0) {
		negative = 1;
		scaled_ppm = -scaled_ppm;
	}

	/* IP-Core adjusts the nominal frequency by adding or subtracting 1 ns
	 * from the 8 ns (period of the oscillator) every time the accumulator
	 * register overflows. The value stored in the addend register is added
	 * to the accumulator register every 8 ns.
	 *
	 * addend value = (2^30 * accumulator_overflow_rate) /
	 *                oscillator_frequency
	 * where:
	 *
	 * oscillator_frequency = 125 MHz
	 * accumulator_overflow_rate = 125 MHz * scaled_ppm * 2^-16 * 10^-6 * 8
	 */
	adj = scaled_ppm;
	adj <<= 11;
	addend = (u32)div_u64(adj, 15625);

	addendh = (addend & 0xffff0000) >> 16;
	addendl = addend & 0xffff;

	negative = (negative << 15) & 0x8000;

	mutex_lock(&hellcreek->ptp_lock);

	/* Set drift register */
	hellcreek_ptp_write(hellcreek, negative, PR_CLOCK_DRIFT_C);
	hellcreek_ptp_write(hellcreek, 0x00, PR_CLOCK_DRIFT_C);
	hellcreek_ptp_write(hellcreek, 0x00, PR_CLOCK_DRIFT_C);
	hellcreek_ptp_write(hellcreek, addendh,  PR_CLOCK_DRIFT_C);
	hellcreek_ptp_write(hellcreek, addendl,  PR_CLOCK_DRIFT_C);

	mutex_unlock(&hellcreek->ptp_lock);

	return 0;
}

static int hellcreek_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
{
	struct hellcreek *hellcreek = ptp_to_hellcreek(ptp);
	u16 negative = 0, counth, countl;
	u32 count_val;

	/* If the offset is larger than IP-Core slow offset resources. Don't
	 * consider slow adjustment. Rather, add the offset directly to the
	 * current time
	 */
	if (abs(delta) > MAX_SLOW_OFFSET_ADJ) {
		struct timespec64 now, then = ns_to_timespec64(delta);

		hellcreek_ptp_gettimex(ptp, &now, NULL);
		now = timespec64_add(now, then);
		hellcreek_ptp_settime(ptp, &now);

		return 0;
	}

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

	/* 'count_val' does not exceed the maximum register size (2^30) */
	count_val = div_s64(delta, MAX_NS_PER_STEP);

	counth = (count_val & 0xffff0000) >> 16;
	countl = count_val & 0xffff;

	negative = (negative << 15) & 0x8000;

	mutex_lock(&hellcreek->ptp_lock);

	/* Set offset write register */
	hellcreek_ptp_write(hellcreek, negative, PR_CLOCK_OFFSET_C);
	hellcreek_ptp_write(hellcreek, MAX_NS_PER_STEP, PR_CLOCK_OFFSET_C);
	hellcreek_ptp_write(hellcreek, MIN_CLK_CYCLES_BETWEEN_STEPS,
			    PR_CLOCK_OFFSET_C);
	hellcreek_ptp_write(hellcreek, countl,  PR_CLOCK_OFFSET_C);
	hellcreek_ptp_write(hellcreek, counth,  PR_CLOCK_OFFSET_C);

	mutex_unlock(&hellcreek->ptp_lock);

	return 0;
}

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

static void hellcreek_ptp_overflow_check(struct work_struct *work)
{
	struct delayed_work *dw = to_delayed_work(work);
	struct hellcreek *hellcreek;

	hellcreek = dw_overflow_to_hellcreek(dw);

	mutex_lock(&hellcreek->ptp_lock);
	__hellcreek_ptp_gettime(hellcreek, NULL);
	mutex_unlock(&hellcreek->ptp_lock);

	schedule_delayed_work(&hellcreek->overflow_work,
			      HELLCREEK_OVERFLOW_PERIOD);
}

static enum led_brightness hellcreek_get_brightness(struct hellcreek *hellcreek,
						    int led)
{
	return (hellcreek->status_out & led) ? 1 : 0;
}

static void hellcreek_set_brightness(struct hellcreek *hellcreek, int led,
				     enum led_brightness b)
{
	mutex_lock(&hellcreek->ptp_lock);

	if (b)
		hellcreek->status_out |= led;
	else
		hellcreek->status_out &= ~led;

	hellcreek_ptp_write(hellcreek, hellcreek->status_out, STATUS_OUT);

	mutex_unlock(&hellcreek->ptp_lock);
}

static void hellcreek_led_sync_good_set(struct led_classdev *ldev,
					enum led_brightness b)
{
	struct hellcreek *hellcreek = led_to_hellcreek(ldev, led_sync_good);

	hellcreek_set_brightness(hellcreek, STATUS_OUT_SYNC_GOOD, b);
}

static enum led_brightness hellcreek_led_sync_good_get(struct led_classdev *ldev)
{
	struct hellcreek *hellcreek = led_to_hellcreek(ldev, led_sync_good);

	return hellcreek_get_brightness(hellcreek, STATUS_OUT_SYNC_GOOD);
}

static void hellcreek_led_is_gm_set(struct led_classdev *ldev,
				    enum led_brightness b)
{
	struct hellcreek *hellcreek = led_to_hellcreek(ldev, led_is_gm);

	hellcreek_set_brightness(hellcreek, STATUS_OUT_IS_GM, b);
}

static enum led_brightness hellcreek_led_is_gm_get(struct led_classdev *ldev)
{
	struct hellcreek *hellcreek = led_to_hellcreek(ldev, led_is_gm);

	return hellcreek_get_brightness(hellcreek, STATUS_OUT_IS_GM);
}

/* There two available LEDs internally called sync_good and is_gm. However, the
 * user might want to use a different label and specify the default state. Take
 * those properties from device tree.
 */
static int hellcreek_led_setup(struct hellcreek *hellcreek)
{
	struct device_node *leds, *led = NULL;
	enum led_default_state state;
	const char *label;
	int ret = -EINVAL;

	of_node_get(hellcreek->dev->of_node);
	leds = of_find_node_by_name(hellcreek->dev->of_node, "leds");
	if (!leds) {
		dev_err(hellcreek->dev, "No LEDs specified in device tree!\n");
		return ret;
	}

	hellcreek->status_out = 0;

	led = of_get_next_available_child(leds, led);
	if (!led) {
		dev_err(hellcreek->dev, "First LED not specified!\n");
		goto out;
	}

	ret = of_property_read_string(led, "label", &label);
	hellcreek->led_sync_good.name = ret ? "sync_good" : label;

	state = led_init_default_state_get(of_fwnode_handle(led));
	switch (state) {
	case LEDS_DEFSTATE_ON:
		hellcreek->led_sync_good.brightness = 1;
		break;
	case LEDS_DEFSTATE_KEEP:
		hellcreek->led_sync_good.brightness =
			hellcreek_get_brightness(hellcreek, STATUS_OUT_SYNC_GOOD);
		break;
	default:
		hellcreek->led_sync_good.brightness = 0;
	}

	hellcreek->led_sync_good.max_brightness = 1;
	hellcreek->led_sync_good.brightness_set = hellcreek_led_sync_good_set;
	hellcreek->led_sync_good.brightness_get = hellcreek_led_sync_good_get;

	led = of_get_next_available_child(leds, led);
	if (!led) {
		dev_err(hellcreek->dev, "Second LED not specified!\n");
		ret = -EINVAL;
		goto out;
	}

	ret = of_property_read_string(led, "label", &label);
	hellcreek->led_is_gm.name = ret ? "is_gm" : label;

	state = led_init_default_state_get(of_fwnode_handle(led));
	switch (state) {
	case LEDS_DEFSTATE_ON:
		hellcreek->led_is_gm.brightness = 1;
		break;
	case LEDS_DEFSTATE_KEEP:
		hellcreek->led_is_gm.brightness =
			hellcreek_get_brightness(hellcreek, STATUS_OUT_IS_GM);
		break;
	default:
		hellcreek->led_is_gm.brightness = 0;
	}

	hellcreek->led_is_gm.max_brightness = 1;
	hellcreek->led_is_gm.brightness_set = hellcreek_led_is_gm_set;
	hellcreek->led_is_gm.brightness_get = hellcreek_led_is_gm_get;

	/* Set initial state */
	if (hellcreek->led_sync_good.brightness == 1)
		hellcreek_set_brightness(hellcreek, STATUS_OUT_SYNC_GOOD, 1);
	if (hellcreek->led_is_gm.brightness == 1)
		hellcreek_set_brightness(hellcreek, STATUS_OUT_IS_GM, 1);

	/* Register both leds */
	led_classdev_register(hellcreek->dev, &hellcreek->led_sync_good);
	led_classdev_register(hellcreek->dev, &hellcreek->led_is_gm);

	ret = 0;

out:
	of_node_put(leds);

	return ret;
}

int hellcreek_ptp_setup(struct hellcreek *hellcreek)
{
	u16 status;
	int ret;

	/* Set up the overflow work */
	INIT_DELAYED_WORK(&hellcreek->overflow_work,
			  hellcreek_ptp_overflow_check);

	/* Setup PTP clock */
	hellcreek->ptp_clock_info.owner = THIS_MODULE;
	snprintf(hellcreek->ptp_clock_info.name,
		 sizeof(hellcreek->ptp_clock_info.name),
		 dev_name(hellcreek->dev));

	/* IP-Core can add up to 0.5 ns per 8 ns cycle, which means
	 * accumulator_overflow_rate shall not exceed 62.5 MHz (which adjusts
	 * the nominal frequency by 6.25%)
	 */
	hellcreek->ptp_clock_info.max_adj     = 62500000;
	hellcreek->ptp_clock_info.n_alarm     = 0;
	hellcreek->ptp_clock_info.n_pins      = 0;
	hellcreek->ptp_clock_info.n_ext_ts    = 0;
	hellcreek->ptp_clock_info.n_per_out   = 0;
	hellcreek->ptp_clock_info.pps	      = 0;
	hellcreek->ptp_clock_info.adjfine     = hellcreek_ptp_adjfine;
	hellcreek->ptp_clock_info.adjtime     = hellcreek_ptp_adjtime;
	hellcreek->ptp_clock_info.gettimex64  = hellcreek_ptp_gettimex;
	hellcreek->ptp_clock_info.settime64   = hellcreek_ptp_settime;
	hellcreek->ptp_clock_info.enable      = hellcreek_ptp_enable;
	hellcreek->ptp_clock_info.do_aux_work = hellcreek_hwtstamp_work;

	hellcreek->ptp_clock = ptp_clock_register(&hellcreek->ptp_clock_info,
						  hellcreek->dev);
	if (IS_ERR(hellcreek->ptp_clock))
		return PTR_ERR(hellcreek->ptp_clock);

	/* Enable the offset correction process, if no offset correction is
	 * already taking place
	 */
	status = hellcreek_ptp_read(hellcreek, PR_CLOCK_STATUS_C);
	if (!(status & PR_CLOCK_STATUS_C_OFS_ACT))
		hellcreek_ptp_write(hellcreek,
				    status | PR_CLOCK_STATUS_C_ENA_OFS,
				    PR_CLOCK_STATUS_C);

	/* Enable the drift correction process */
	hellcreek_ptp_write(hellcreek, status | PR_CLOCK_STATUS_C_ENA_DRIFT,
			    PR_CLOCK_STATUS_C);

	/* LED setup */
	ret = hellcreek_led_setup(hellcreek);
	if (ret) {
		if (hellcreek->ptp_clock)
			ptp_clock_unregister(hellcreek->ptp_clock);
		return ret;
	}

	schedule_delayed_work(&hellcreek->overflow_work,
			      HELLCREEK_OVERFLOW_PERIOD);

	return 0;
}

void hellcreek_ptp_free(struct hellcreek *hellcreek)
{
	led_classdev_unregister(&hellcreek->led_is_gm);
	led_classdev_unregister(&hellcreek->led_sync_good);
	cancel_delayed_work_sync(&hellcreek->overflow_work);
	if (hellcreek->ptp_clock)
		ptp_clock_unregister(hellcreek->ptp_clock);
	hellcreek->ptp_clock = NULL;
}
