From 102b0d2daa97dae68d3eed54d8fe37a9cc38a892 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:13:47 +0200 Subject: Adding upstream version 2.8.0+dfsg. Signed-off-by: Daniel Baumann --- plat/marvell/armada/common/mss/mss_ipc_drv.c | 113 +++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 plat/marvell/armada/common/mss/mss_ipc_drv.c (limited to 'plat/marvell/armada/common/mss/mss_ipc_drv.c') diff --git a/plat/marvell/armada/common/mss/mss_ipc_drv.c b/plat/marvell/armada/common/mss/mss_ipc_drv.c new file mode 100644 index 0000000..70ccfa5 --- /dev/null +++ b/plat/marvell/armada/common/mss/mss_ipc_drv.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2018 Marvell International Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + * https://spdx.org/licenses + */ + +#include + +#include +#include + +#include +#include + +#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK + +#define IPC_CH_NUM_OF_MSG (16) +#define IPC_CH_MSG_IDX (-1) + +unsigned long mv_pm_ipc_msg_base; +unsigned int mv_pm_ipc_queue_size; + +unsigned int msg_sync; +int msg_index = IPC_CH_MSG_IDX; + +/****************************************************************************** + * mss_pm_ipc_init + * + * DESCRIPTION: Initialize PM IPC infrastructure + ****************************************************************************** + */ +int mv_pm_ipc_init(unsigned long ipc_control_addr) +{ + struct mss_pm_ipc_ctrl *ipc_control = + (struct mss_pm_ipc_ctrl *)ipc_control_addr; + + /* Initialize PM IPC control block */ + mv_pm_ipc_msg_base = ipc_control->msg_base_address | + IPC_MSG_BASE_MASK; + mv_pm_ipc_queue_size = ipc_control->queue_size; + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_queue_addr_get + * + * DESCRIPTION: Returns the IPC queue address + ****************************************************************************** + */ +unsigned int mv_pm_ipc_queue_addr_get(void) +{ + unsigned int addr; + + inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + msg_index = msg_index + 1; + if (msg_index >= IPC_CH_NUM_OF_MSG) + msg_index = 0; + + addr = (unsigned int)(mv_pm_ipc_msg_base + + (msg_index * mv_pm_ipc_queue_size)); + + flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index)); + + return addr; +} + +/****************************************************************************** + * mv_pm_ipc_msg_rx + * + * DESCRIPTION: Retrieve message from IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC); + + return 0; +} + +/****************************************************************************** + * mv_pm_ipc_msg_tx + * + * DESCRIPTION: Send message via IPC channel + ****************************************************************************** + */ +int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id, + unsigned int cluster_power_state) +{ + unsigned int addr = mv_pm_ipc_queue_addr_get(); + + /* Validate the entry for message placed by the host is free */ + if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) { + inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + msg_sync = msg_sync + 1; + flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync)); + + mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync); + mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id); + mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id); + mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC, + cluster_power_state); + mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY); + + } else { + ERROR("%s: FAILED\n", __func__); + } + + return 0; +} -- cgit v1.2.3