/*
 * Copyright (c) 2020 IoT.bzh <julien.massot@iot.bzh>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <soc.h>
#include <drivers/timer/system_timer.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/rcar_clock_control.h>

#define DT_DRV_COMPAT renesas_rcar_cmt

#define TIMER_IRQ              DT_INST_IRQN(0)
#define TIMER_BASE_ADDR        DT_INST_REG_ADDR(0)
#define TIMER_CLOCK_FREQUENCY  DT_INST_PROP(0, clock_frequency)

#define CLOCK_SUBSYS           DT_INST_CLOCKS_CELL(0, module)

#define CYCLES_PER_SEC         TIMER_CLOCK_FREQUENCY
#define CYCLES_PER_TICK        (CYCLES_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)

static struct rcar_cpg_clk mod_clk = {
	.module = DT_INST_CLOCKS_CELL(0, module),
	.domain = DT_INST_CLOCKS_CELL(0, domain),
};

BUILD_ASSERT(CYCLES_PER_TICK > 1,
	     "CYCLES_PER_TICK must be greater than 1");

#define CMCOR0_OFFSET                   0x018   /* constant register 0 */
#define CMCNT0_OFFSET                   0x014   /* counter 0 */
#define CMCSR0_OFFSET                   0x010   /* control/status register 0 */

#define CMCOR1_OFFSET                   0x118   /* constant register 1 */
#define CMCNT1_OFFSET                   0x114   /* counter 1 */
#define CMCSR1_OFFSET                   0x110   /* control/status register 1 */

#define CMCLKE                          0xB00   /* CLK enable register */
#define CLKEN0                          BIT(5)  /* Enable Clock for channel 0 */
#define CLKEN1                          BIT(6)  /* Enable Clock for channel 1 */

#define CMSTR0_OFFSET                   0x000   /* Timer start register 0 */
#define CMSTR1_OFFSET                   0x100   /* Timer start register 1 */
#define START_BIT                       BIT(0)

#define CSR_CLK_DIV_1                   0x00000007
#define CSR_ENABLE_COUNTER_IN_DEBUG     BIT(3)
#define CSR_ENABLE_INTERRUPT            BIT(5)
#define CSR_FREE_RUN                    BIT(8)
#define CSR_WRITE_FLAG                  BIT(13)
#define CSR_OVERFLOW_FLAG               BIT(14)
#define CSR_MATCH_FLAG                  BIT(15)

static void cmt_isr(void *arg)
{
	ARG_UNUSED(arg);
	uint32_t reg_val;

	/* clear the interrupt */
	reg_val = sys_read32(TIMER_BASE_ADDR + CMCSR0_OFFSET);
	reg_val &= ~CSR_MATCH_FLAG;
	sys_write32(reg_val, TIMER_BASE_ADDR + CMCSR0_OFFSET);

	/* Announce to the kernel */
	sys_clock_announce(1);
}

/*
 * Initialize both channels at same frequency,
 * Set the first one to generates interrupt at CYCLES_PER_TICK.
 * The second one is used for cycles count, the match value is set
 * at max uint32_t.
 */
int sys_clock_driver_init(const struct device *device)
{
	const struct device *clk;
	uint32_t reg_val;
	int i, ret;

	ARG_UNUSED(device);
	clk = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0));
	if (clk == NULL) {
		return -ENODEV;
	}

	ret = clock_control_on(clk, (clock_control_subsys_t *)&mod_clk);
	if (ret < 0) {
		return ret;
	}

	/* Supply clock for both channels */
	sys_write32(CLKEN0 | CLKEN1, TIMER_BASE_ADDR + CMCLKE);

	/* Stop both channels */
	reg_val = sys_read32(TIMER_BASE_ADDR + CMSTR0_OFFSET);
	reg_val &= ~START_BIT;
	sys_write32(reg_val, TIMER_BASE_ADDR + CMSTR0_OFFSET);

	reg_val = sys_read32(TIMER_BASE_ADDR + CMSTR1_OFFSET);
	reg_val &= ~START_BIT;
	sys_write32(reg_val, TIMER_BASE_ADDR + CMSTR1_OFFSET);

	/* Set the timers as 32-bit, with RCLK/1 clock */
	sys_write32(CSR_FREE_RUN | CSR_CLK_DIV_1 | CSR_ENABLE_INTERRUPT,
		    TIMER_BASE_ADDR + CMCSR0_OFFSET);

	/* Do not enable interrupts for the second channel */
	sys_write32(CSR_FREE_RUN | CSR_CLK_DIV_1,
		    TIMER_BASE_ADDR + CMCSR1_OFFSET);

	/* Set the first channel match to CYCLES Per tick*/
	sys_write32(CYCLES_PER_TICK, TIMER_BASE_ADDR + CMCOR0_OFFSET);

	/* Set the second channel match to max uint32 */
	sys_write32(0xffffffff, TIMER_BASE_ADDR + CMCOR1_OFFSET);

	/* Reset the counter for first channel, check WRFLG first */
	while (sys_read32(TIMER_BASE_ADDR + CMCSR0_OFFSET) & CSR_WRITE_FLAG)
		;
	sys_write32(0, TIMER_BASE_ADDR + CMCNT0_OFFSET);

	for (i = 0; i < 1000; i++) {
		if (!sys_read32(TIMER_BASE_ADDR + CMCNT0_OFFSET)) {
			break;
		}
	}

	__ASSERT(sys_read32(TIMER_BASE_ADDR + CMCNT0_OFFSET) == 0,
			"Fail to clear CMCNT0 register");

	/* Connect timer interrupt for channel 0*/
	IRQ_CONNECT(TIMER_IRQ, 0, cmt_isr, 0, 0);
	irq_enable(TIMER_IRQ);

	/* Start the timers */
	sys_write32(START_BIT, TIMER_BASE_ADDR + CMSTR0_OFFSET);
	sys_write32(START_BIT, TIMER_BASE_ADDR + CMSTR1_OFFSET);

	return 0;
}

uint32_t sys_clock_elapsed(void)
{
	/* Always return 0 for tickful operation */
	return 0;
}

uint32_t sys_clock_cycle_get_32(void)
{
	return sys_read32(TIMER_BASE_ADDR + CMCNT1_OFFSET);
}
