/*
 * Copyright (c) 2024 Andes Technology Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_DRIVERS_CACHE_CACHE_ANDES_L2_H_
#define ZEPHYR_DRIVERS_CACHE_CACHE_ANDES_L2_H_

#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/drivers/syscon.h>

#define L2C_BASE		DT_REG_ADDR_BY_IDX(DT_INST(0, andestech_l2c), 0)

/* L2 cache Register Offset */
#define L2C_CONFIG		(L2C_BASE + 0x00)
#define L2C_CTRL		(L2C_BASE + 0x08)
#define L2C_CCTLCMD(hart_id)	\
	(L2C_BASE + 0x40 + (hart_id * l2_cache_cfg.cmd_offset))
#define L2C_CCTLACC(hart_id)	\
	(L2C_BASE + 0x48 + (hart_id * l2_cache_cfg.cmd_offset))
#define L2C_CCTLST(hart_id)	\
	(L2C_BASE + 0x80 + (hart_id * l2_cache_cfg.status_offset))

/* L2 cache config registers bitfields */
#define L2C_CONFIG_SIZE_SHIFT		7
#define L2C_CONFIG_MAP			BIT(20)
#define L2C_CONFIG_VERSION_SHIFT	24

/* L2 cache control registers bitfields */
#define L2C_CTRL_CEN		BIT(0)
#define L2C_CTRL_IPFDPT_3	GENMASK(4, 3)
#define L2C_CTRL_DPFDPT_8	GENMASK(7, 6)

/* L2 cache CCTL Access Line registers bitfields */
#define L2C_CCTLACC_WAY_SHIFT	28

/* L2 CCTL Command */
#define CCTL_L2_IX_INVAL	0x00
#define CCTL_L2_IX_WB		0x01
#define CCTL_L2_PA_INVAL	0x08
#define CCTL_L2_PA_WB		0x09
#define CCTL_L2_PA_WBINVAL	0x0a
#define CCTL_L2_WBINVAL_ALL	0x12

#define K_CACHE_WB		BIT(0)
#define K_CACHE_INVD		BIT(1)
#define K_CACHE_WB_INVD		(K_CACHE_WB | K_CACHE_INVD)

struct nds_l2_cache_config {
	uint32_t size;
	uint32_t cmd_offset;
	uint32_t status_offset;
	uint16_t status_shift;
	uint8_t version;
};

static struct nds_l2_cache_config l2_cache_cfg;

static ALWAYS_INLINE int nds_l2_cache_is_inclusive(void)
{
	return IS_ENABLED(CONFIG_L2C_INCLUSIVE_POLICY) &&
			(l2_cache_cfg.version > 15);

}

static ALWAYS_INLINE void nds_l2_cache_wait_status(uint8_t hart_id)
{
	uint32_t status;

	do {
		status = sys_read32(L2C_CCTLST(hart_id));
		status >>= hart_id * l2_cache_cfg.status_shift;
		status &= BIT_MASK(4);
	} while (status == 1);
}

static ALWAYS_INLINE int nds_l2_cache_all(int op)
{
	/* L2 cache fixed to 64 byte cache line size and 16 way */
	const unsigned long line_size = 64, ways = 16;
	unsigned long sets, index, cmd;
	uint8_t hart_id;
	unsigned long status = csr_read(mstatus);

	if (!l2_cache_cfg.size) {
		return -ENOTSUP;
	}

	if (csr_read(NDS_MMSC_CFG) & MMSC_CFG_VCCTL_2) {
		if ((status & MSTATUS_MPRV) && !(status & MSTATUS_MPP)) {
			if (!nds_l2_cache_is_inclusive()) {
				return -ENOTSUP;
			}
		}
	}

	switch (op) {
	case K_CACHE_WB:
		cmd = CCTL_L2_IX_WB;
		break;
	case K_CACHE_INVD:
		cmd = CCTL_L2_IX_INVAL;
		break;
	case K_CACHE_WB_INVD:
		cmd = CCTL_L2_WBINVAL_ALL;
		break;
	default:
		return -ENOTSUP;
	}

	hart_id = arch_proc_id();

	if (op == K_CACHE_WB_INVD) {
		sys_write32(CCTL_L2_WBINVAL_ALL, L2C_CCTLCMD(hart_id));

		/* Wait L2 CCTL Commands finished */
		nds_l2_cache_wait_status(hart_id);
	} else {
		sets = l2_cache_cfg.size / (ways * line_size);
		/* Invalidate all cache line by each way and each set */
		for (int j = 0; j < ways; j++) {
			/* Index of way */
			index = j << L2C_CCTLACC_WAY_SHIFT;
			for (int i = 0; i < sets; i++) {
				/* Index of set */
				index += line_size;

				/* Invalidate each cache line */
				sys_write32(index, L2C_CCTLACC(hart_id));
				sys_write32(cmd, L2C_CCTLCMD(hart_id));

				/* Wait L2 CCTL Commands finished */
				nds_l2_cache_wait_status(hart_id);
			}
		}
	}

	return 0;
}

static ALWAYS_INLINE int nds_l2_cache_range(void *addr, size_t size, int op)
{
	const unsigned long line_size = 64;
	unsigned long last_byte, align_addr, cmd;
	uint8_t hart_id;

	if (!l2_cache_cfg.size) {
		return -ENOTSUP;
	}

	switch (op) {
	case K_CACHE_WB:
		cmd = CCTL_L2_PA_WB;
		break;
	case K_CACHE_INVD:
		cmd = CCTL_L2_PA_INVAL;
		break;
	case K_CACHE_WB_INVD:
		cmd = CCTL_L2_PA_WBINVAL;
		break;
	default:
		return -ENOTSUP;
	}

	last_byte = (unsigned long)addr + size - 1;
	align_addr = ROUND_DOWN(addr, line_size);
	hart_id = arch_proc_id();

	while (align_addr <= last_byte) {
		sys_write32(align_addr, L2C_CCTLACC(hart_id));
		sys_write32(cmd, L2C_CCTLCMD(hart_id));
		align_addr += line_size;

		/* Wait L2 CCTL Commands finished */
		nds_l2_cache_wait_status(hart_id);
	}

	return 0;
}

static ALWAYS_INLINE void nds_l2_cache_enable(void)
{
	if (l2_cache_cfg.size) {
		uint32_t l2c_ctrl = sys_read32(L2C_CTRL);

		if (!(l2c_ctrl & L2C_CTRL_CEN)) {
			WRITE_BIT(l2c_ctrl, 0, true);
			sys_write32(l2c_ctrl, L2C_CTRL);
		}
	}
}

static ALWAYS_INLINE void nds_l2_cache_disable(void)
{
	if (l2_cache_cfg.size) {
		uint32_t l2c_ctrl = sys_read32(L2C_CTRL);

		if (l2c_ctrl & L2C_CTRL_CEN) {
			WRITE_BIT(l2c_ctrl, 0, false);
			sys_write32(l2c_ctrl, L2C_CTRL);
		}
	}
}

static ALWAYS_INLINE int nds_l2_cache_init(void)
{
	unsigned long line_size;

#if IS_ENABLED(CONFIG_SYSCON)
#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(syscon), andestech_atcsmu100, okay)
	uint32_t system_cfg;
	const struct device *syscon_dev = DEVICE_DT_GET(DT_NODELABEL(syscon));

	if (device_is_ready(syscon_dev)) {
		/* Check L2 cache feature from SMU */
		syscon_read_reg(syscon_dev, 0x08, &system_cfg);

		/* Platform doesn't support L2 cache controller */
		if (!(system_cfg & BIT(8))) {
			l2_cache_cfg.size = 0;
			return 0;
		}
	} else {
		LOG_ERR("Andes cache driver should be initialized after "
			"syscon driver initialization");
		return 0;
	}
#endif /* andestech_atcsmu100 dts node status okay */
#endif /* IS_ENABLED(CONFIG_SYSCON) */

	uint32_t l2c_ctrl;

	line_size = (sys_read32(L2C_CONFIG) >> L2C_CONFIG_SIZE_SHIFT) & BIT_MASK(7);
	l2_cache_cfg.size = line_size * 128 * 1024;

	if (sys_read32(L2C_CONFIG) & L2C_CONFIG_MAP) {
		l2_cache_cfg.cmd_offset = 0x10;
		l2_cache_cfg.status_offset = 0;
		l2_cache_cfg.status_shift = 4;
	} else {
		l2_cache_cfg.cmd_offset = 0x1000;
		l2_cache_cfg.status_offset = 0x1000;
		l2_cache_cfg.status_shift = 0;
	}

	l2_cache_cfg.version = (sys_read32(L2C_CONFIG) >> L2C_CONFIG_VERSION_SHIFT) & BIT_MASK(8);

	/* Initializing L2 cache instruction, data prefetch depth */
	l2c_ctrl = sys_read32(L2C_CTRL);
	l2c_ctrl |= (L2C_CTRL_IPFDPT_3 | L2C_CTRL_DPFDPT_8);

	/* Writeback and invalidate all I/D-Cache before setting L2C */
	__asm__ volatile ("fence.i");
	sys_write32(l2c_ctrl, L2C_CTRL);

	if (IS_ENABLED(CONFIG_SMP)) {
		if (l2_cache_cfg.size) {
			l2c_ctrl = sys_read32(L2C_CTRL);

			if (!(l2c_ctrl & L2C_CTRL_CEN)) {
				WRITE_BIT(l2c_ctrl, 0, true);
				sys_write32(l2c_ctrl, L2C_CTRL);
			}
		}
	}

	return l2_cache_cfg.size;
}

#endif /* ZEPHYR_DRIVERS_CACHE_CACHE_ANDES_L2_H_ */
