kernel-brax3-ubuntu-touch/drivers/misc/mediatek/adsp/adsp_platform.c
erascape f319b992b1 kernel-5.15: Initial import brax3 UT kernel
* halium configs enabled

Signed-off-by: erascape <erascape@proton.me>
2025-09-23 15:17:10 +00:00

151 lines
2.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
*/
#include <linux/io.h>
#include <linux/delay.h>
#include "adsp_reg.h"
#include "adsp_core.h"
#include "adsp_platform_driver.h"
#include "adsp_platform.h"
#ifdef ADSP_BASE
#undef ADSP_BASE
#endif
#define ADSP_BASE mt_base
#define SET_BITS(addr, mask) writel(readl(addr) | (mask), addr)
#define CLR_BITS(addr, mask) writel(readl(addr) & ~(mask), addr)
static void __iomem *mt_base;
static u32 axibus_idle_val;
static void __iomem *mt_spm_sema;
/* below access adsp register necessary */
void adsp_mt_set_swirq(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return;
if (cid == ADSP_A_ID)
writel(ADSP_A_SW_INT, ADSP_SW_INT_SET);
else
writel(ADSP_B_SW_INT, ADSP_SW_INT_SET);
}
u32 adsp_mt_check_swirq(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return 0;
if (cid == ADSP_A_ID)
return readl(ADSP_SW_INT_SET) & ADSP_A_SW_INT;
else
return readl(ADSP_SW_INT_SET) & ADSP_B_SW_INT;
}
void adsp_mt_clr_sysirq(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return;
if (cid == ADSP_A_ID)
writel(ADSP_A_2HOST_IRQ_BIT, ADSP_GENERAL_IRQ_CLR);
else
writel(ADSP_B_2HOST_IRQ_BIT, ADSP_GENERAL_IRQ_CLR);
}
EXPORT_SYMBOL(adsp_mt_clr_sysirq);
void adsp_mt_clr_auidoirq(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return;
/* just clear correct bits*/
if (cid == ADSP_A_ID)
writel(ADSP_A_AFE2HOST_IRQ_BIT, ADSP_GENERAL_IRQ_CLR);
else
writel(ADSP_B_AFE2HOST_IRQ_BIT, ADSP_GENERAL_IRQ_CLR);
}
EXPORT_SYMBOL(adsp_mt_clr_auidoirq);
void adsp_mt_disable_wdt(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return;
if (cid == ADSP_A_ID)
CLR_BITS(ADSP_A_WDT_REG, WDT_EN_BIT);
else
CLR_BITS(ADSP_B_WDT_REG, WDT_EN_BIT);
}
EXPORT_SYMBOL(adsp_mt_disable_wdt);
void adsp_mt_clr_spm(u32 cid)
{
if (unlikely(cid >= get_adsp_core_total()))
return;
if (cid == ADSP_A_ID)
CLR_BITS(ADSP_A_SPM_WAKEUPSRC, ADSP_WAKEUP_SPM);
else
CLR_BITS(ADSP_B_SPM_WAKEUPSRC, ADSP_WAKEUP_SPM);
}
bool check_hifi_status(u32 mask)
{
return !!(readl(ADSP_SLEEP_STATUS_REG) & mask);
}
bool is_adsp_axibus_idle(u32 *backup)
{
u32 value = readl(ADSP_DBG_PEND_CNT);
if (backup)
*backup = value;
return (value == axibus_idle_val);
}
bool is_infrabus_timeout(void)
{
return readl(ADSP_A_INTR_STATUS) & INFRABUS_TIMEOUT_IRQ;
}
void adsp_mt_toggle_semaphore(u32 bit)
{
writel((1 << bit), ADSP_SEMAPHORE);
}
u32 adsp_mt_get_semaphore(u32 bit)
{
return (readl(ADSP_SEMAPHORE) >> bit) & 0x1;
}
bool is_spm_semaphore_valid(void)
{
return (mt_spm_sema == NULL) ? 0 : 1;
}
void adsp_mt_toggle_spm_semaphore(u32 bit)
{
writel((1 << bit), mt_spm_sema);
}
u32 adsp_mt_get_spm_semaphore(u32 bit)
{
return (readl(mt_spm_sema) >> bit) & 0x1;
}
void adsp_hardware_init(struct adspsys_priv *adspsys)
{
if (unlikely(!adspsys))
return;
mt_base = adspsys->cfg;
mt_spm_sema = adspsys->spm_sema;
axibus_idle_val = adspsys->desc->axibus_idle_val;
}