// SPDX-License-Identifier: GPL-2.0
/*
 * Synaptics AS390 SoC timer support
 *
 * Copyright (C) 2019 Synaptics Incorporated
 *
 * Author: Jisheng Zhang <jszhang@kernel.org>
 */

#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#define TIMER_NAME "as390_timer"

#define CONTROL			0x00
#define WD_CONTROL		0x04
#define INT_STAT		0x08
#define TERMINAL_COUNT		0x0c
#define RESET_TERMINAL_COUNT	0x10
#define WD_CMD_WINDOWN		0x14
#define CURRENT_COUNT		0x18

struct as390_timer {
	void __iomem *base;
	struct clk *clk;
	unsigned long freq;
};

struct as390_clkevt {
	struct clock_event_device ced;
	struct as390_timer timer;
};

static inline struct as390_timer *
ced_to_as390_timer(struct clock_event_device *ced)
{
	return &container_of(ced, struct as390_clkevt, ced)->timer;
}

static inline u32 rdl(struct as390_timer *timer, u32 offset)
{
	return readl_relaxed(timer->base + offset);
}

static inline void wrl(struct as390_timer *timer, u32 offset, u32 data)
{
	writel_relaxed(data, timer->base + offset);
}

static int as390_timer_set_next_event(unsigned long cycles,
				      struct clock_event_device *ced)
{
	u32 val;
	struct as390_timer *timer = ced_to_as390_timer(ced);

	val = rdl(timer, CONTROL);
	val &= ~(1 << 1);
	wrl(timer, CONTROL, val);

	wrl(timer, CURRENT_COUNT, 0);
	wrl(timer, TERMINAL_COUNT, cycles);

	val = rdl(timer, CONTROL);
	val |= (1 << 1);
	wrl(timer, CONTROL, val);

	return 0;
}

static int as390_timer_shutdown(struct clock_event_device *ced)
{
	u32 val;
	struct as390_timer *timer = ced_to_as390_timer(ced);

	val = rdl(timer, CONTROL);
	val &= ~(1 << 1);
	wrl(timer, CONTROL, val);

	return 0;
}

static int as390_timer_set_periodic(struct clock_event_device *ced)
{
	u32 val;
	struct as390_timer *timer = ced_to_as390_timer(ced);

	wrl(timer, CONTROL, 1 << 0);

	wrl(timer, CURRENT_COUNT, 0);

	val = DIV_ROUND_UP(timer->freq, HZ);
	wrl(timer, TERMINAL_COUNT, val);

	val = (1 << 0);
	val |= (1 << 1);
	val |= (1 << 5);
	val |= (1 << 4);
	wrl(timer, CONTROL, val);

	return 0;
}

static int as390_timer_set_oneshot(struct clock_event_device *ced)
{
	u32 val;
	struct as390_timer *timer = ced_to_as390_timer(ced);

	wrl(timer, CONTROL, 1 << 0);

	val = (1 << 0);
	val |= (1 << 1);
	val |= (1 << 5);
	wrl(timer, CONTROL, val);

	return 0;
}

static irqreturn_t as390_timer_interrupt(int irq, void *dev_id)
{
	struct clock_event_device *ced = dev_id;
	struct as390_timer *timer = ced_to_as390_timer(ced);

	wrl(timer, INT_STAT, 1);
	ced->event_handler(ced);

	return IRQ_HANDLED;
}

static int __init
as390_timer_probe(struct as390_timer *timer, struct device_node *np)
{
	struct clk *clk;
	int ret;

	timer->base = of_iomap(np, 0);
	if (!timer->base) {
		pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
		return -ENXIO;
	}

	clk = of_clk_get_by_name(np, "timer");
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME);
		goto out_unmap;
	}

	ret = clk_prepare_enable(clk);
	if (ret) {
		pr_err("Failed to enable timer clock\n");
		goto out_unmap;
	}
	timer->clk = clk;
	timer->freq = clk_get_rate(clk);

	return 0;

out_unmap:
	iounmap(timer->base);

	return ret;
}

static void __init as390_timer_cleanup(struct as390_timer *timer)
{
	clk_disable_unprepare(timer->clk);
	iounmap(timer->base);
}

static int __init as390_clkevt_init(struct device_node *np)
{
	struct as390_clkevt *as390_clkevt;
	struct clock_event_device *ced;
	int ret, irq;

	as390_clkevt = kzalloc(sizeof(struct as390_clkevt), GFP_KERNEL);
	if (!as390_clkevt)
		return -ENOMEM;

	irq = irq_of_parse_and_map(np, 0);
	if (!irq) {
		ret = -EINVAL;
		pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
		goto out_probe;
	}

	ret = as390_timer_probe(&as390_clkevt->timer, np);
	if (ret)
		goto out_probe;

	ced = &as390_clkevt->ced;
	ced->name = TIMER_NAME;
	ced->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
		       CLOCK_EVT_FEAT_DYNIRQ;
	ced->set_next_event = as390_timer_set_next_event;
	ced->set_state_shutdown = as390_timer_shutdown;
	ced->set_state_periodic = as390_timer_set_periodic;
	ced->set_state_oneshot = as390_timer_set_oneshot;
	ced->irq = irq;
	ced->cpumask = cpu_possible_mask;
	ced->rating = 200;

	ret = request_irq(ced->irq, as390_timer_interrupt, IRQF_TIMER,
			  TIMER_NAME, ced);
	if (ret)
		goto out_irq;

	clockevents_config_and_register(&as390_clkevt->ced,
					as390_clkevt->timer.freq, 1, UINT_MAX);
	return 0;

out_irq:
	as390_timer_cleanup(&as390_clkevt->timer);
out_probe:
	kfree(as390_clkevt);
	return ret;
}

static int __init as390_clksrc_init(struct device_node *np)
{
	struct as390_timer *as390_clksrc;
	int ret;
	u32 val;

	as390_clksrc = kzalloc(sizeof(struct as390_timer), GFP_KERNEL);
	if (!as390_clksrc)
		return -ENOMEM;

	ret = as390_timer_probe(as390_clksrc, np);
	if (ret)
		goto out_probe;

	wrl(as390_clksrc, CONTROL, 1);
	wrl(as390_clksrc, TERMINAL_COUNT, ~0);
	val = (1 << 0);
	val |= (1 << 1);
	val |= (1 << 4);
	wrl(as390_clksrc, CONTROL, val);

	ret = clocksource_mmio_init(as390_clksrc->base + CURRENT_COUNT,
		TIMER_NAME, as390_clksrc->freq, 200, 32,
		clocksource_mmio_readl_up);
	if (ret) {
		pr_err("Failed to register clocksource");
		goto out_clocksource;
	}

	return 0;

out_clocksource:
	as390_timer_cleanup(as390_clksrc);
out_probe:
	kfree(as390_clksrc);
	return ret;
}

static int num_called __initdata;
static int __init as390_timer_init(struct device_node *np)
{
	switch (num_called) {
	case 0:
		as390_clkevt_init(np);
		break;
	case 1:
		as390_clksrc_init(np);
		break;
	default:
		break;
	}
	num_called++;

	return 0;
}
TIMER_OF_DECLARE(as3903288_timer, "syna,as390-timer", as390_timer_init);
