/*
 * Copyright (c) 2020 IoT.bzh
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT renesas_rcar_cpg_mssr
#include <errno.h>
#include <soc.h>
#include <drivers/clock_control.h>
#include <drivers/clock_control/rcar_clock_control.h>
#include <dt-bindings/clock/renesas_rcar_cpg.h>

struct rcar_mssr_config {
	uint32_t base_address;
};

#define DEV_CFG(dev)  ((struct rcar_mssr_config *)(dev->config))

static const uint16_t rmstpsr[] = {
	0x110, 0x114, 0x118, 0x11c,
	0x120, 0x124, 0x128, 0x12c,
	0x980, 0x984, 0x988, 0x98c,
};

#define RMSTPSR(i)      rmstpsr[i]

/* Software Reset Register offsets */
static const uint16_t srcr[] = {
	0x0A0, 0x0A8, 0x0B0, 0x0B8,
	0x0BC, 0x0C4, 0x1C8, 0x1CC,
	0x920, 0x924, 0x928, 0x92C,
};

#define SRCR(i)         srcr[i]
#define SRSTCLR(i)      (0x940 + (i) * 4)

/* CPG write protect */
#define CPGWPR                    0x0900
/* CAN-FD Clock Frequency Control Register */
#define CANFDCKCR                 0x244

/* Clock stop bit */
#define CANFDCKCR_CKSTP           BIT(8)

/* On H3,M3,E3 parent clock of CANFD has 800MHz rate */
#define CANFDCKCR_PARENT_CLK_RATE 800000000
#define CANFDCKCR_DIVIDER_MASK    0x1FF

#define S3D4_CLK_RATE             66600000

static void cpg_write(const struct rcar_mssr_config *config,
		      uint32_t reg, uint32_t val)
{
	sys_write32(~val, config->base_address + CPGWPR);
	sys_write32(val, config->base_address + reg);
	/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
	k_sleep(K_USEC(35));
}

static void cpg_reset(const struct rcar_mssr_config *config,
		      uint32_t reg, uint32_t bit)
{
	cpg_write(config, SRCR(reg), BIT(bit));
	cpg_write(config, SRSTCLR(reg), BIT(bit));
}

static int cpg_core_clock_endisable(const struct device *dev,
				    uint32_t module, uint32_t rate, bool enable)
{
	const struct rcar_mssr_config *config = DEV_CFG(dev);
	uint32_t divider;
	unsigned int key;
	int ret;

	/* Only support CANFD core clock at the moment */
	if (module != CPG_CORE_CLK_CANFD) {
		return -EINVAL;
	}

	key = irq_lock();

	if (enable) {
		if ((CANFDCKCR_PARENT_CLK_RATE % rate) != 0) {
			__ASSERT(true, "Can not generate "
				 "%u from CANFD parent clock", rate);
			ret = -EINVAL;
			goto unlock;
		}
		divider = (CANFDCKCR_PARENT_CLK_RATE / rate) - 1;
		if (divider > CANFDCKCR_DIVIDER_MASK) {
			__ASSERT(true, "Can not generate %u "
				 "from CANFD parent clock", rate);
			ret = -EINVAL;
			goto unlock;
		}
		cpg_write(config, CANFDCKCR, divider);
	} else {
		cpg_write(config, CANFDCKCR, CANFDCKCR_CKSTP);
	}

unlock:
	irq_unlock(key);
	return 0;
}

static int cpg_rmstp_clock_endisable(const struct device *dev,
				     uint32_t module, bool enable)
{
	const struct rcar_mssr_config *config = DEV_CFG(dev);
	uint32_t reg = module / 100;
	uint32_t bit = module % 100;
	uint32_t bitmask = BIT(bit);
	uint32_t reg_val;

	__ASSERT((bit < 32) && reg < ARRAY_SIZE(rmstpsr),
		 "Invalid module number for cpg clock: %d", module);

	unsigned int key = irq_lock();

	reg_val = sys_read32(config->base_address + RMSTPSR(reg));
	if (enable) {
		reg_val &= ~bitmask;
	} else {
		reg_val |= bitmask;
	}

	sys_write32(reg_val, config->base_address + RMSTPSR(reg));
	if (!enable) {
		cpg_reset(config, reg, bit);
	}

	irq_unlock(key);

	return 0;
}

static int cpg_mssr_blocking_start(const struct device *dev,
			       clock_control_subsys_t sys)
{
	struct rcar_cpg_clk *clk = (struct rcar_cpg_clk *)sys;
	int ret = -EINVAL;

	if (clk->domain == CPG_MOD) {
		ret = cpg_rmstp_clock_endisable(dev, clk->module, true);
	} else if (clk->domain == CPG_CORE) {
		ret = cpg_core_clock_endisable(dev, clk->module, clk->rate,
					       true);
	}

	return ret;
}

static int cpg_mssr_stop(const struct device *dev,
		     clock_control_subsys_t sys)
{
	struct rcar_cpg_clk *clk = (struct rcar_cpg_clk *)sys;
	int ret = -EINVAL;

	if (clk->domain == CPG_MOD) {
		ret = cpg_rmstp_clock_endisable(dev, clk->module, false);
	} else if (clk->domain == CPG_CORE) {
		ret = cpg_core_clock_endisable(dev, clk->module, 0, false);
	}

	return ret;
}

static int cpg_get_rate(const struct device *dev,
			clock_control_subsys_t sys,
			uint32_t *rate)
{
	const struct rcar_mssr_config *config = DEV_CFG(dev);
	struct rcar_cpg_clk *clk = (struct rcar_cpg_clk *)sys;
	uint32_t val;
	int ret = 0;

	if (clk->domain != CPG_CORE) {
		return -ENOTSUP;
	}

	switch (clk->module) {
	case CPG_CORE_CLK_CANFD:
		val = sys_read32(config->base_address + CANFDCKCR);
		if (val & CANFDCKCR_CKSTP) {
			*rate = 0;
		} else {
			val &= CANFDCKCR_DIVIDER_MASK;
			*rate = CANFDCKCR_PARENT_CLK_RATE / (val + 1);
		}
		break;
	case CPG_CORE_CLK_S3D4:
		*rate = S3D4_CLK_RATE;
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}

static int rcar_cpg_mssr_init(const struct device *dev)
{
	return 0;
}

static const struct clock_control_driver_api rcar_cpg_mssr_api = {
	.on = cpg_mssr_blocking_start,
	.off = cpg_mssr_stop,
	.get_rate = cpg_get_rate,
};

#define RCAR_MSSR_INIT(inst)					    \
	static struct rcar_mssr_config rcar_mssr##inst##_config = { \
		.base_address = DT_INST_REG_ADDR(inst)		    \
	};							    \
								    \
	DEVICE_DT_INST_DEFINE(inst,				    \
			      &rcar_cpg_mssr_init,		    \
			      NULL,				    \
			      NULL, &rcar_mssr##inst##_config,	    \
			      PRE_KERNEL_1,			    \
			      CONFIG_KERNEL_INIT_PRIORITY_OBJECTS,  \
			      &rcar_cpg_mssr_api);

DT_INST_FOREACH_STATUS_OKAY(RCAR_MSSR_INIT)
