// SPDX-License-Identifier: BSD-2-Clause
/*
 * andes_pmu.c - Andes PMU device callbacks and platform overrides
 *
 * Copyright (C) 2023 Andes Technology Corporation
 */

#include <andes/andes45.h>
#include <andes/andes_hpm.h>
#include <andes/andes_pmu.h>
#include <sbi/sbi_bitops.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_pmu.h>
#include <libfdt.h>

static void andes_hw_counter_enable_irq(uint32_t ctr_idx)
{
	unsigned long mip_val;

	if (ctr_idx >= SBI_PMU_HW_CTR_MAX)
		return;

	mip_val = csr_read(CSR_MIP);
	if (!(mip_val & MIP_PMOVI))
		csr_clear(CSR_MCOUNTEROVF, BIT(ctr_idx));

	csr_set(CSR_MCOUNTERINTEN, BIT(ctr_idx));
}

static void andes_hw_counter_disable_irq(uint32_t ctr_idx)
{
	csr_clear(CSR_MCOUNTERINTEN, BIT(ctr_idx));
}

static void andes_hw_counter_filter_mode(unsigned long flags, int ctr_idx)
{
	if (flags & SBI_PMU_CFG_FLAG_SET_UINH)
		csr_set(CSR_MCOUNTERMASK_U, BIT(ctr_idx));
	else
		csr_clear(CSR_MCOUNTERMASK_U, BIT(ctr_idx));

	if (flags & SBI_PMU_CFG_FLAG_SET_SINH)
		csr_set(CSR_MCOUNTERMASK_S, BIT(ctr_idx));
	else
		csr_clear(CSR_MCOUNTERMASK_S, BIT(ctr_idx));
}

static struct sbi_pmu_device andes_pmu = {
	.name = "andes_pmu",
	.hw_counter_enable_irq  = andes_hw_counter_enable_irq,
	.hw_counter_disable_irq = andes_hw_counter_disable_irq,
	/*
	 * We set delegation of supervisor local interrupts via
	 * 18th bit on mslideleg instead of mideleg, so leave
	 * hw_counter_irq_bit() callback unimplemented.
	 */
	.hw_counter_irq_bit     = NULL,
	.hw_counter_filter_mode = andes_hw_counter_filter_mode
};

int andes_pmu_extensions_init(const struct fdt_match *match,
			      struct sbi_hart_features *hfeatures)
{
	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();

	if (!has_andes_pmu())
		return 0;

	/*
	 * Don't expect both Andes PMU and standard Sscofpmf/Smcntrpmf,
	 * are supported as they serve the same purpose.
	 */
	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF) ||
		sbi_hart_has_extension(scratch, SBI_HART_EXT_SMCNTRPMF))
		return SBI_EINVAL;
	sbi_hart_update_extension(scratch, SBI_HART_EXT_XANDESPMU, true);

	/* Inhibit all HPM counters in M-mode */
	csr_write(CSR_MCOUNTERMASK_M, 0xfffffffd);
	/* Delegate counter overflow interrupt to S-mode */
	csr_write(CSR_MSLIDELEG, MIP_PMOVI);

	return 0;
}

int andes_pmu_init(const struct fdt_match *match)
{
	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
	void *fdt = fdt_get_address();
	int pmu_offset;

	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_XANDESPMU))
		sbi_pmu_set_device(&andes_pmu);

	/*
	 * Populate default mappings if device-tree doesn't
	 * provide a valid pmu node.
	 */
	pmu_offset = fdt_node_offset_by_compatible(fdt, -1, "riscv,pmu");
	if (pmu_offset < 0)
		return (pmu_offset == -FDT_ERR_NOTFOUND) ? andes_pmu_setup()
							 : SBI_EFAIL;

	return 0;
}
