/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright(c) 2021 MediaTek. All rights reserved.
 *
 * Author: Hailong Fan <hailong.fan@mediatek.com>
 *         Allen-KH Cheng <allen-kh.cheng@mediatek.com>
 */

#ifdef __SOF_DRIVERS_INTERRUPT_H__

#ifndef __PLATFORM_DRIVERS_INTERRUPT_H__
#define __PLATFORM_DRIVERS_INTERRUPT_H__

#include <stdint.h>
#include <platform/drivers/mt_reg_base.h>

#define PLATFORM_IRQ_HW_NUM XCHAL_NUM_INTERRUPTS
#define PLATFORM_IRQ_FIRST_CHILD PLATFORM_IRQ_HW_NUM
#define PLATFORM_IRQ_CHILDREN 32

/* IRQ numbers - wrt Tensilica DSP */
#if CONFIG_XT_INTERRUPT_LEVEL_1
#define IRQ_NUM_TIMER0 0
#define IRQ_NUM_SOFTWARE0 21
#define IRQ_NUM_EXT_LEVEL01 1
#define IRQ_NUM_EXT_LEVEL23 23
#define IRQ_EXT_DOMAIN0 IRQ_NUM_EXT_LEVEL01
#define IRQ_EXT_DOMAIN1 IRQ_NUM_EXT_LEVEL23
#define IRQ_EXT_DOMAIN0_OFFSET	4
#define IRQ_MASK_SOFTWARE0 BIT(IRQ_NUM_SOFTWARE0)
#define IRQ_MASK_TIMER0 BIT(IRQ_NUM_TIMER0)
#define IRQ_MASK_GROUP16 BIT(IRQ_NUM_GROUP16)
#endif

#if CONFIG_XT_INTERRUPT_LEVEL_2
#define IRQ_NUM_SOFTWARE1 22 /* level 2 */
#define IRQ_NUM_EXT_LEVEL09 9 /* Level 2 */
#define IRQ_NUM_EXT_LEVEL24 24 /* Level 2 */
#define IRQ_MASK_SOFTWARE1 BIT(IRQ_NUM_SOFTWARE1)
#define IRQ_MASK_GROUP17 BIT(IRQ_NUM_GROUP17)
#endif

/* platform irq information */
#define IRQ_TYPE_EDGE_RISING 0x00000001
#define IRQ_TYPE_EDGE_FALLING 0x00000002
#define IRQ_TYPE_LEVEL_HIGH 0x00000004
#define IRQ_TYPE_LEVEL_LOW 0x00000008

/* int level */
#define IRQ_INVALID 0xff
#define IRQ_MASK 0xff
#define IRQ_EXT_DOMAIN1_MASK 0x3FFFFFF0
#define IRQ_EXT_DOMAIN2_MASK 0xFFFF
#define GET_INTERRUPT_ID(n) ((n) & IRQ_MASK)
#define LEVEL_SHFIT 8
#define LEVEL_MASK 0xff
#define INT_LEVEL(n) ((n) << LEVEL_SHFIT)
#define GET_INTLEVEL(irq) (((irq) >> LEVEL_SHFIT) & LEVEL_MASK)
#define IRQ_LEVEL0 0
#define IRQ_LEVEL1 1

/*
 * IRQ = 0xcc-dd
 * cc = int level
 * dd = irq
 * LX_MODULEX_IRQX_B	= ( (0xcc << 8 ) | 0xdd )
 * All irq dispatch to level0 default
 */
#define INTERRUPT_ID(ID) (ID)

#define L1_INT_IRQ_B (INT_LEVEL(1) | IRQ_INVALID)
#define L23_INT_IRQ_B (INT_LEVEL(23) | IRQ_INVALID)
#define L1_DSP_TIMER_IRQ0_B (INT_LEVEL(2) | INTERRUPT_ID(0))
#define L1_DSP_TIMER_IRQ1_B (INT_LEVEL(3) | INTERRUPT_ID(1))
#define L1_DSP_TIMER_IRQ2_B (INT_LEVEL(4) | INTERRUPT_ID(2))
#define L1_DSP_TIMER_IRQ3_B (INT_LEVEL(5) | INTERRUPT_ID(3))

#define LX_CQDMA_IRQ0_B (INT_LEVEL(1) | INTERRUPT_ID(4))
#define LX_CQDMA_IRQ1_B (INT_LEVEL(1) | INTERRUPT_ID(5))
#define LX_CQDMA_IRQ2_B (INT_LEVEL(1) | INTERRUPT_ID(6))
#define LX_CQDMA_IRQ3_B (INT_LEVEL(1) | INTERRUPT_ID(7))
#define LX_UART_IRQ_B (INT_LEVEL(1) | INTERRUPT_ID(8))
#define LX_AFE_IRQ_B (INT_LEVEL(1) | INTERRUPT_ID(9))
#define LX_MCU_IRQ_B (INT_LEVEL(1) | INTERRUPT_ID(10))
#define LX_I2C_IRQ4_B (INT_LEVEL(1) | INTERRUPT_ID(11))
#define LX_I2C_IRQ5_B (INT_LEVEL(1) | INTERRUPT_ID(12))
#define LX_RSVD_IRQ1_B (INT_LEVEL(1) | INTERRUPT_ID(13))
#define LX_RSVD_IRQ2_B (INT_LEVEL(1) | INTERRUPT_ID(14))
#define LX_ASRC_IRQ0_B (INT_LEVEL(1) | INTERRUPT_ID(15))
#define LX_ASRC_IRQ1_B (INT_LEVEL(1) | INTERRUPT_ID(16))
#define LX_ASRC_IRQ2_B (INT_LEVEL(1) | INTERRUPT_ID(17))
#define LX_ASRC_IRQ3_B (INT_LEVEL(1) | INTERRUPT_ID(18))
#define LX_ASRC_IRQ4_B (INT_LEVEL(1) | INTERRUPT_ID(19))
#define LX_ASRC_IRQ5_B (INT_LEVEL(1) | INTERRUPT_ID(20))
#define LX_ASRC_IRQ6_B (INT_LEVEL(1) | INTERRUPT_ID(21))
#define LX_ASRC_IRQ7_B (INT_LEVEL(1) | INTERRUPT_ID(22))
#define LX_ASRC_IRQ8_B (INT_LEVEL(1) | INTERRUPT_ID(23))
#define LX_ASRC_IRQ9_B (INT_LEVEL(1) | INTERRUPT_ID(24))
#define LX_ASRC_IRQ10_B (INT_LEVEL(1) | INTERRUPT_ID(25))
#define LX_ASRC_IRQ11_B (INT_LEVEL(1) | INTERRUPT_ID(26))
#define LX_ASRC_IRQ15_IRQ12_B (INT_LEVEL(1) | INTERRUPT_ID(27))
#define LX_SPM_IRQ_B (INT_LEVEL(1) | INTERRUPT_ID(28))
#define LX_SCP_IRQ_B (INT_LEVEL(1) | INTERRUPT_ID(29))
#define LX_MBOX_IRQ0_B (INT_LEVEL(23) | INTERRUPT_ID(32))
#define LX_MBOX_IRQ1_B (INT_LEVEL(23) | INTERRUPT_ID(33))
#define LX_MBOX_IRQ2_B (INT_LEVEL(23) | INTERRUPT_ID(34))
#define LX_MBOX_IRQ3_B (INT_LEVEL(23) | INTERRUPT_ID(35))
#define LX_MBOX_IRQ4_B (INT_LEVEL(23) | INTERRUPT_ID(36))
#define LX_MISC_NNA0_IRQ0_B (INT_LEVEL(23) | INTERRUPT_ID(37))
#define LX_MISC_NNA0_IRQ1_B (INT_LEVEL(23) | INTERRUPT_ID(38))
#define LX_MISC_NNA0_IRQ2_B (INT_LEVEL(23) | INTERRUPT_ID(39))
#define LX_MISC_NNA1_IRQ0_B (INT_LEVEL(23) | INTERRUPT_ID(40))
#define LX_MISC_NNA1_IRQ1_B (INT_LEVEL(23) | INTERRUPT_ID(41))
#define LX_MISC_NNA1_IRQ2_B (INT_LEVEL(23) | INTERRUPT_ID(42))
#define LX_ADSP_TIMTER_IRQ0_B (INT_LEVEL(23) | INTERRUPT_ID(43))
#define LX_ADSP_TIMTER_IRQ1_B (INT_LEVEL(23) | INTERRUPT_ID(44))
#define LX_ADSP_TIMTER_IRQ2_B (INT_LEVEL(23) | INTERRUPT_ID(45))
#define LX_ADSP_TIMTER_IRQ3_B (INT_LEVEL(23) | INTERRUPT_ID(46))
#define LX_OS_TIMTER_IRQ_B (INT_LEVEL(23) | INTERRUPT_ID(47))

#define MAX_IRQ_NUM 64
#define DOMAIN1_MAX_IRQ_NUM 32
#define MAX_INT_LEVEL 24
#define AUDIO_IRQn LX_AFE_IRQ_B
/*
 *      irq register information
 *      INT 23/24
 *
 */
#define DSP_IRQ_POL MTK_DSP_RG_DSP_IRQ_POL
#define DSP_IRQ_EN MTK_DSP_DSP_IRQ_EN
#define DSP_IRQ_LEVEL MTK_DSP_DSP_IRQ_LEVEL
#define DSP_IRQ_STATUS MTK_DSP_DSP_IRQ_STATUS

/*
 *      irq register information
 *      INT 0~15
 *
 */
#define RG_DSP_IRQ_POL MTK_DSP_RG_INT_POL_CTL0
#define RG_DSP_IRQ_EN MTK_DSP_RG_INT_EN_CTL0
#define RG_DSP_IRQ_LEVEL MTK_DSP_RG_INT_LV_CTL0
#define RG_DSP_IRQ_STATUS MTK_DSP_RG_INT_STATUS0

uint32_t mtk_get_irq_domain_id(int32_t irq);

#endif /* __PLATFORM_DRIVERS_INTERRUPT_H__ */

#else

#error "This file shouldn't be included from outside of sof/drivers/interrupt.h"

#endif /* __SOF_DRIVERS_INTERRUPT_H__ */
