// SPDX-License-Identifier: GPL-2.0
/*
 * J-Core SoC PIT/clocksource driver
 *
 * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/sched_clock.h>
#include <linux/cpu.h>
#include <linux/cpuhotplug.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define PIT_IRQ_SHIFT		12
#define PIT_PRIO_SHIFT		20
#define PIT_ENABLE_SHIFT	26
#define PIT_PRIO_MASK		0xf

#define REG_PITEN		0x00
#define REG_THROT		0x10
#define REG_COUNT		0x14
#define REG_BUSPD		0x18
#define REG_SECHI		0x20
#define REG_SECLO		0x24
#define REG_NSEC		0x28

struct jcore_pit {
	struct clock_event_device	ced;
	void __iomem			*base;
	unsigned long			periodic_delta;
	u32				enable_val;
};

static void __iomem *jcore_pit_base;
static struct jcore_pit __percpu *jcore_pit_percpu;

static notrace u64 jcore_sched_clock_read(void)
{
	u32 seclo, nsec, seclo0;
	__iomem void *base = jcore_pit_base;

	seclo = readl(base + REG_SECLO);
	do {
		seclo0 = seclo;
		nsec  = readl(base + REG_NSEC);
		seclo = readl(base + REG_SECLO);
	} while (seclo0 != seclo);

	return seclo * NSEC_PER_SEC + nsec;
}

static u64 jcore_clocksource_read(struct clocksource *cs)
{
	return jcore_sched_clock_read();
}

static int jcore_pit_disable(struct jcore_pit *pit)
{
	writel(0, pit->base + REG_PITEN);
	return 0;
}

static int jcore_pit_set(unsigned long delta, struct jcore_pit *pit)
{
	jcore_pit_disable(pit);
	writel(delta, pit->base + REG_THROT);
	writel(pit->enable_val, pit->base + REG_PITEN);
	return 0;
}

static int jcore_pit_set_state_shutdown(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_disable(pit);
}

static int jcore_pit_set_state_oneshot(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_disable(pit);
}

static int jcore_pit_set_state_periodic(struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_set(pit->periodic_delta, pit);
}

static int jcore_pit_set_next_event(unsigned long delta,
				    struct clock_event_device *ced)
{
	struct jcore_pit *pit = container_of(ced, struct jcore_pit, ced);

	return jcore_pit_set(delta, pit);
}

static int jcore_pit_local_init(unsigned cpu)
{
	struct jcore_pit *pit = this_cpu_ptr(jcore_pit_percpu);
	unsigned buspd, freq;

	pr_info("Local J-Core PIT init on cpu %u\n", cpu);

	buspd = readl(pit->base + REG_BUSPD);
	freq = DIV_ROUND_CLOSEST(NSEC_PER_SEC, buspd);
	pit->periodic_delta = DIV_ROUND_CLOSEST(NSEC_PER_SEC, HZ * buspd);

	clockevents_config_and_register(&pit->ced, freq, 1, ULONG_MAX);

	return 0;
}

static irqreturn_t jcore_timer_interrupt(int irq, void *dev_id)
{
	struct jcore_pit *pit = dev_id;

	if (clockevent_state_oneshot(&pit->ced))
		jcore_pit_disable(pit);

	pit->ced.event_handler(&pit->ced);

	return IRQ_HANDLED;
}

static int __init jcore_pit_init(struct device_node *node)
{
	int err;
	unsigned pit_irq, cpu;
	unsigned long hwirq;
	u32 irqprio, enable_val;

	jcore_pit_base = of_iomap(node, 0);
	if (!jcore_pit_base) {
		pr_err("Error: Cannot map base address for J-Core PIT\n");
		return -ENXIO;
	}

	pit_irq = irq_of_parse_and_map(node, 0);
	if (!pit_irq) {
		pr_err("Error: J-Core PIT has no IRQ\n");
		return -ENXIO;
	}

	pr_info("Initializing J-Core PIT at %p IRQ %d\n",
		jcore_pit_base, pit_irq);

	err = clocksource_mmio_init(jcore_pit_base, "jcore_pit_cs",
				    NSEC_PER_SEC, 400, 32,
				    jcore_clocksource_read);
	if (err) {
		pr_err("Error registering clocksource device: %d\n", err);
		return err;
	}

	sched_clock_register(jcore_sched_clock_read, 32, NSEC_PER_SEC);

	jcore_pit_percpu = alloc_percpu(struct jcore_pit);
	if (!jcore_pit_percpu) {
		pr_err("Failed to allocate memory for clock event device\n");
		return -ENOMEM;
	}

	err = request_percpu_irq(pit_irq, jcore_timer_interrupt,
				 "jcore_pit", jcore_pit_percpu);
	if (err) {
		pr_err("pit irq request failed: %d\n", err);
		free_percpu(jcore_pit_percpu);
		return err;
	}

	/*
	 * The J-Core PIT is not hard-wired to a particular IRQ, but
	 * integrated with the interrupt controller such that the IRQ it
	 * generates is programmable, as follows:
	 *
	 * The bit layout of the PIT enable register is:
	 *
	 *	.....e..ppppiiiiiiii............
	 *
	 * where the .'s indicate unrelated/unused bits, e is enable,
	 * p is priority, and i is hard irq number.
	 *
	 * For the PIT included in AIC1 (obsolete but still in use),
	 * any hard irq (trap number) can be programmed via the 8
	 * iiiiiiii bits, and a priority (0-15) is programmable
	 * separately in the pppp bits.
	 *
	 * For the PIT included in AIC2 (current), the programming
	 * interface is equivalent modulo interrupt mapping. This is
	 * why a different compatible tag was not used. However only
	 * traps 64-127 (the ones actually intended to be used for
	 * interrupts, rather than syscalls/exceptions/etc.) can be
	 * programmed (the high 2 bits of i are ignored) and the
	 * priority pppp is <<2'd and or'd onto the irq number. This
	 * choice seems to have been made on the hardware engineering
	 * side under an assumption that preserving old AIC1 priority
	 * mappings was important. Future models will likely ignore
	 * the pppp field.
	 */
	hwirq = irq_get_irq_data(pit_irq)->hwirq;
	irqprio = (hwirq >> 2) & PIT_PRIO_MASK;
	enable_val = (1U << PIT_ENABLE_SHIFT)
		   | (hwirq << PIT_IRQ_SHIFT)
		   | (irqprio << PIT_PRIO_SHIFT);

	for_each_present_cpu(cpu) {
		struct jcore_pit *pit = per_cpu_ptr(jcore_pit_percpu, cpu);

		pit->base = of_iomap(node, cpu);
		if (!pit->base) {
			pr_err("Unable to map PIT for cpu %u\n", cpu);
			continue;
		}

		pit->ced.name = "jcore_pit";
		pit->ced.features = CLOCK_EVT_FEAT_PERIODIC
				  | CLOCK_EVT_FEAT_ONESHOT
				  | CLOCK_EVT_FEAT_PERCPU;
		pit->ced.cpumask = cpumask_of(cpu);
		pit->ced.rating = 400;
		pit->ced.irq = pit_irq;
		pit->ced.set_state_shutdown = jcore_pit_set_state_shutdown;
		pit->ced.set_state_periodic = jcore_pit_set_state_periodic;
		pit->ced.set_state_oneshot = jcore_pit_set_state_oneshot;
		pit->ced.set_next_event = jcore_pit_set_next_event;

		pit->enable_val = enable_val;
	}

	cpuhp_setup_state(CPUHP_AP_JCORE_TIMER_STARTING,
			  "clockevents/jcore:starting",
			  jcore_pit_local_init, NULL);

	return 0;
}

TIMER_OF_DECLARE(jcore_pit, "jcore,pit", jcore_pit_init);
