diff options
Diffstat (limited to 'chip/mt_scp/rv32i_common/ipi.c')
-rw-r--r-- | chip/mt_scp/rv32i_common/ipi.c | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/chip/mt_scp/rv32i_common/ipi.c b/chip/mt_scp/rv32i_common/ipi.c deleted file mode 100644 index cba5c65d0b..0000000000 --- a/chip/mt_scp/rv32i_common/ipi.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "atomic.h" -#include "cache.h" -#include "common.h" -#include "console.h" -#include "hooks.h" -#include "hostcmd.h" -#include "ipi_chip.h" -#include "registers.h" -#include "system.h" -#include "task.h" -#include "util.h" -#include "video.h" - -#define CPRINTF(format, args...) cprintf(CC_IPI, format, ##args) -#define CPRINTS(format, args...) cprints(CC_IPI, format, ##args) - -static uint8_t init_done; - -static struct mutex ipi_lock; -static struct ipc_shared_obj *const ipi_send_buf = - (struct ipc_shared_obj *)CONFIG_IPC_SHARED_OBJ_ADDR; -static struct ipc_shared_obj *const ipi_recv_buf = - (struct ipc_shared_obj *)(CONFIG_IPC_SHARED_OBJ_ADDR + - sizeof(struct ipc_shared_obj)); - -static uint32_t disable_irq_count, saved_int_mask; - -void ipi_disable_irq(void) -{ - if (atomic_read_add(&disable_irq_count, 1) == 0) - saved_int_mask = read_clear_int_mask(); -} - -void ipi_enable_irq(void) -{ - if (atomic_read_sub(&disable_irq_count, 1) == 1) - set_int_mask(saved_int_mask); -} - -static int ipi_is_busy(void) -{ - return SCP_SCP2APMCU_IPC_SET & IPC_SCP2HOST; -} - -static void ipi_wake_ap(int32_t id) -{ - if (id >= IPI_COUNT) - return; - - if (*ipi_wakeup_table[id]) - SCP_SCP2SPM_IPC_SET = IPC_SCP2HOST; -} - -int ipi_send(int32_t id, const void *buf, uint32_t len, int wait) -{ - int ret; - - if (!init_done) { - CPRINTS("IPI has not initialized"); - return EC_ERROR_BUSY; - } - - if (in_interrupt_context()) { - CPRINTS("invoke %s() in ISR context", __func__); - return EC_ERROR_BUSY; - } - - if (len > sizeof(ipi_send_buf->buffer)) { - CPRINTS("data length exceeds limitation"); - return EC_ERROR_INVAL; - } - - ipi_disable_irq(); - mutex_lock(&ipi_lock); - - if (ipi_is_busy()) { - /* - * If the following conditions meet, - * 1) There is an IPI pending in AP. - * 2) The incoming IPI is a wakeup IPI. - * then it assumes that AP is in suspend state. - * Send a AP wakeup request to SPM. - * - * The incoming IPI will be checked if it's a wakeup source. - */ - ipi_wake_ap(id); - - CPRINTS("IPI busy, id=%d", id); - ret = EC_ERROR_BUSY; - goto error; - } - - ipi_send_buf->id = id; - ipi_send_buf->len = len; - memcpy(ipi_send_buf->buffer, buf, len); - - /* flush memory cache (if any) */ - cache_flush_dcache_range((uintptr_t)ipi_send_buf, - sizeof(*ipi_send_buf)); - - /* interrupt AP to handle the message */ - ipi_wake_ap(id); - SCP_SCP2APMCU_IPC_SET = IPC_SCP2HOST; - - if (wait) - while (ipi_is_busy()) - ; - - ret = EC_SUCCESS; -error: - mutex_unlock(&ipi_lock); - ipi_enable_irq(); - return ret; -} - -static void ipi_enable_deferred(void) -{ - struct scp_run_t scp_run; - int ret; - - init_done = 1; - - /* inform AP that SCP is up */ - scp_run.signaled = 1; - strncpy(scp_run.fw_ver, system_get_version(EC_IMAGE_RW), - SCP_FW_VERSION_LEN); - scp_run.dec_capability = video_get_dec_capability(); - scp_run.enc_capability = video_get_enc_capability(); - - ret = ipi_send(SCP_IPI_INIT, (void *)&scp_run, sizeof(scp_run), 1); - if (ret) { - CPRINTS("failed to send initialization IPC messages"); - init_done = 0; - return; - } - -#ifdef HAS_TASK_HOSTCMD - hostcmd_init(); -#endif - - task_enable_irq(SCP_IRQ_GIPC_IN0); -} -DECLARE_DEFERRED(ipi_enable_deferred); - -static void ipi_init(void) -{ - memset(ipi_send_buf, 0, sizeof(struct ipc_shared_obj)); - memset(ipi_recv_buf, 0, sizeof(struct ipc_shared_obj)); - - /* enable IRQ after all tasks are up */ - hook_call_deferred(&ipi_enable_deferred_data, 0); -} -DECLARE_HOOK(HOOK_INIT, ipi_init, HOOK_PRIO_DEFAULT); - -static void ipi_handler(void) -{ - if (ipi_recv_buf->id >= IPI_COUNT) { - CPRINTS("invalid IPI, id=%d", ipi_recv_buf->id); - return; - } - - CPRINTS("IPI %d", ipi_recv_buf->id); - - ipi_handler_table[ipi_recv_buf->id]( - ipi_recv_buf->id, ipi_recv_buf->buffer, ipi_recv_buf->len); -} - -static void irq_group7_handler(void) -{ - extern volatile int ec_int; - - if (SCP_GIPC_IN_SET & GIPC_IN(0)) { - ipi_handler(); - SCP_GIPC_IN_CLR = GIPC_IN(0); - asm volatile ("fence.i" ::: "memory"); - task_clear_pending_irq(ec_int); - } -} -DECLARE_IRQ(7, irq_group7_handler, 0); |