/* * Copyright (c) 2022, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include "mt_cpu_pm_mbox.h" #include #ifdef __GNUC__ #define MCDI_LIKELY(x) __builtin_expect(!!(x), 1) #define MCDI_UNLIKELY(x) __builtin_expect(!!(x), 0) #else #define MCDI_LIKELY(x) (x) #define MCDI_UNLIKELY(x) (x) #endif #define MCUPM_MBOX_3_BASE (CPU_EB_TCM_BASE + CPU_EB_MBOX3_OFFSET) #define MCUPM_MBOX_WRITE(id, val) mmio_write_32(MCUPM_MBOX_3_BASE + 4 * (id), val) #define MCUPM_MBOX_READ(id) mmio_read_32(MCUPM_MBOX_3_BASE + 4 * (id)) void mtk_set_mcupm_pll_mode(unsigned int mode) { if (mode < NF_MCUPM_ARMPLL_MODE) { MCUPM_MBOX_WRITE(MCUPM_MBOX_ARMPLL_MODE, mode); } } int mtk_get_mcupm_pll_mode(void) { return MCUPM_MBOX_READ(MCUPM_MBOX_ARMPLL_MODE); } void mtk_set_mcupm_buck_mode(unsigned int mode) { if (mode < NF_MCUPM_BUCK_MODE) { MCUPM_MBOX_WRITE(MCUPM_MBOX_BUCK_MODE, mode); } } int mtk_get_mcupm_buck_mode(void) { return MCUPM_MBOX_READ(MCUPM_MBOX_BUCK_MODE); } void mtk_set_cpu_pm_preffered_cpu(unsigned int cpuid) { return MCUPM_MBOX_WRITE(MCUPM_MBOX_WAKEUP_CPU, cpuid); } unsigned int mtk_get_cpu_pm_preffered_cpu(void) { return MCUPM_MBOX_READ(MCUPM_MBOX_WAKEUP_CPU); } static int mtk_wait_mbox_init_done(void) { int status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA); if (status != MCUPM_TASK_INIT) { return status; } mtk_set_mcupm_pll_mode(MCUPM_ARMPLL_OFF); mtk_set_mcupm_buck_mode(MCUPM_BUCK_OFF_MODE); MCUPM_MBOX_WRITE(MCUPM_MBOX_PWR_CTRL_EN, (MCUPM_MCUSYS_CTRL | MCUPM_CM_CTRL | MCUPM_BUCK_CTRL | MCUPM_ARMPLL_CTRL)); return status; } int mtk_lp_depd_condition(enum cpupm_mbox_depd_type type) { int status; if (type == CPUPM_MBOX_WAIT_DEV_INIT) { status = mtk_wait_mbox_init_done(); if (MCDI_UNLIKELY(status != MCUPM_TASK_INIT)) { return -ENXIO; } MCUPM_MBOX_WRITE(MCUPM_MBOX_AP_READY, 1); } else if (type == CPUPM_MBOX_WAIT_TASK_READY) { status = MCUPM_MBOX_READ(MCUPM_MBOX_TASK_STA); if (MCDI_UNLIKELY((status != MCUPM_TASK_WAIT) && (status != MCUPM_TASK_INIT_FINISH))) { return -ENXIO; } } return 0; }