/*
 * Copyright (c) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <arch/xtensa/xtensa_api.h>
#include <xtensa/xtruntime.h>
#include <irq_nextlevel.h>
#include <xtensa/hal.h>
#include <init.h>

#include "soc.h"

#ifdef CONFIG_DYNAMIC_INTERRUPTS
#include <sw_isr_table.h>
#endif

#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(soc);

#define CAVS_INTC_NODE(n) DT_INST(n, intel_cavs_intc)

void z_soc_irq_enable(u32_t irq)
{
	struct device *dev_cavs;

	switch (XTENSA_IRQ_NUMBER(irq)) {
	case DT_IRQN(CAVS_INTC_NODE(0)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(0)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(1)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(1)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(2)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(2)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(3)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(3)));
		break;
	default:
		/* regular interrupt */
		z_xtensa_irq_enable(XTENSA_IRQ_NUMBER(irq));
		return;
	}

	if (!dev_cavs) {
		LOG_DBG("board: CAVS device binding failed");
		return;
	}

	/*
	 * The specified interrupt is in CAVS interrupt controller.
	 * So enable core interrupt first.
	 */
	z_xtensa_irq_enable(XTENSA_IRQ_NUMBER(irq));

	/* Then enable the interrupt in CAVS interrupt controller */
	irq_enable_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));
}

void z_soc_irq_disable(u32_t irq)
{
	struct device *dev_cavs;

	switch (XTENSA_IRQ_NUMBER(irq)) {
	case DT_IRQN(CAVS_INTC_NODE(0)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(0)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(1)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(1)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(2)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(2)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(3)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(3)));
		break;
	default:
		/* regular interrupt */
		z_xtensa_irq_disable(XTENSA_IRQ_NUMBER(irq));
		return;
	}

	if (!dev_cavs) {
		LOG_DBG("board: CAVS device binding failed");
		return;
	}

	/*
	 * The specified interrupt is in CAVS interrupt controller.
	 * So disable the interrupt in CAVS interrupt controller.
	 */
	irq_disable_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));

	/* Then disable the parent IRQ if all children are disabled */
	if (!irq_is_enabled_next_level(dev_cavs)) {
		z_xtensa_irq_disable(XTENSA_IRQ_NUMBER(irq));
	}
}

int z_soc_irq_is_enabled(unsigned int irq)
{
	struct device *dev_cavs;
	int ret = 0;

	switch (XTENSA_IRQ_NUMBER(irq)) {
	case DT_IRQN(CAVS_INTC_NODE(0)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(0)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(1)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(1)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(2)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(2)));
		break;
	case DT_IRQN(CAVS_INTC_NODE(3)):
		dev_cavs = device_get_binding(DT_LABEL(CAVS_INTC_NODE(3)));
		break;
	default:
		/* regular interrupt */
		ret = z_xtensa_irq_is_enabled(XTENSA_IRQ_NUMBER(irq));
		goto out;
	}

	if (!dev_cavs) {
		LOG_DBG("board: CAVS device binding failed");
		ret = -ENODEV;
		goto out;
	}

	/* Then enable the interrupt in CAVS interrupt controller */
	ret = irq_line_is_enabled_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));

out:
	return ret;
}

#ifdef CONFIG_DYNAMIC_INTERRUPTS
int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
			      void (*routine)(void *parameter),
			      void *parameter, u32_t flags)
{
	uint32_t table_idx;
	uint32_t cavs_irq, cavs_idx;
	int ret;

	ARG_UNUSED(flags);
	ARG_UNUSED(priority);

	/* extract 2nd level interrupt number */
	cavs_irq = CAVS_IRQ_NUMBER(irq);
	ret = irq;

	if (cavs_irq == 0) {
		/* Not affecting 2nd level interrupts */
		z_isr_install(irq, routine, parameter);
		goto irq_connect_out;
	}

	/* Figure out the base index. */
	switch (XTENSA_IRQ_NUMBER(irq)) {
	case DT_IRQN(CAVS_INTC_NODE(0)):
		cavs_idx = 0;
		break;
	case DT_IRQN(CAVS_INTC_NODE(1)):
		cavs_idx = 1;
		break;
	case DT_IRQN(CAVS_INTC_NODE(2)):
		cavs_idx = 2;
		break;
	case DT_IRQN(CAVS_INTC_NODE(3)):
		cavs_idx = 3;
		break;
	default:
		ret = -EINVAL;
		goto irq_connect_out;
	}

	table_idx = CONFIG_CAVS_ISR_TBL_OFFSET +
		CONFIG_MAX_IRQ_PER_AGGREGATOR * cavs_idx;
	table_idx += cavs_irq;

	_sw_isr_table[table_idx].arg = parameter;
	_sw_isr_table[table_idx].isr = routine;

irq_connect_out:
	return ret;
}
#endif

static inline void soc_set_power_and_clock(void)
{
	volatile struct soc_dsp_shim_regs *dsp_shim_regs =
		(volatile struct soc_dsp_shim_regs *)SOC_DSP_SHIM_REG_BASE;

	/*
	 * DSP Core 0 PLL Clock Select divide by 1
	 * DSP Core 1 PLL Clock Select divide by 1
	 * Low Power Domain Clock Select depends on LMPCS bit
	 * High Power Domain Clock Select depands on HMPCS bit
	 * Low Power Domain PLL Clock Select device by 4
	 * High Power Domain PLL Clock Select device by 2
	 * Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS)
	 * Tensilica Core Prevent Local Clock Gating (Core 0)
	 * Tensilica Core Prevent Local Clock Gating (Core 1)
	 */
	dsp_shim_regs->clkctl =
		SOC_CLKCTL_DPCS_DIV1(0) |
		SOC_CLKCTL_DPCS_DIV1(1) |
		SOC_CLKCTL_LDCS_LMPCS |
		SOC_CLKCTL_HDCS_HMPCS |
		SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 |
		SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 |
		SOC_CLKCTL_TCPAPLLS |
		SOC_CLKCTL_TCPLCG_DIS(0) |
		SOC_CLKCTL_TCPLCG_DIS(1);

	/* Disable power gating for both cores */
	dsp_shim_regs->pwrctl |= SOC_PWRCTL_DISABLE_PWR_GATING_DSP1 |
		SOC_PWRCTL_DISABLE_PWR_GATING_DSP0;

	/* Rewrite the low power sequencing control bits */
	dsp_shim_regs->lpsctl = dsp_shim_regs->lpsctl;
}

static int soc_init(struct device *dev)
{
	soc_set_power_and_clock();

	return 0;
}

SYS_INIT(soc_init, PRE_KERNEL_1, 99);
