blob: 3e6a64e1a113026581d94d18d3b0189430b61fd6 [file] [log] [blame]
Jolly Shahc2583ab2019-01-08 11:31:49 -08001/*
Michal Simek2a47faa2023-04-14 08:43:51 +02002 * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
Rajan Vaja34cce8e2022-08-31 12:54:40 +02003 * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
Devanshi Chauhan Alpeshbhaiee5a5d62025-03-26 01:50:27 -07004 * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
Jolly Shahc2583ab2019-01-08 11:31:49 -08005 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9/*
10 * Xilinx IPI agent registers access management
11 */
12
13#include <errno.h>
14#include <string.h>
15
16#include <common/debug.h>
17#include <common/runtime_svc.h>
18#include <lib/bakery_lock.h>
19#include <lib/mmio.h>
20
21#include <ipi.h>
Jolly Shahc2583ab2019-01-08 11:31:49 -080022#include <plat_private.h>
Devanshi Chauhan Alpeshbhaiee5a5d62025-03-26 01:50:27 -070023#include "pm_defs.h"
Jolly Shahc2583ab2019-01-08 11:31:49 -080024
25/*********************************************************************
26 * Macros definitions
27 ********************************************************************/
28
29/* IPI registers offsets macros */
30#define IPI_TRIG_OFFSET 0x00U
31#define IPI_OBR_OFFSET 0x04U
32#define IPI_ISR_OFFSET 0x10U
33#define IPI_IMR_OFFSET 0x14U
34#define IPI_IER_OFFSET 0x18U
35#define IPI_IDR_OFFSET 0x1CU
36
37/* IPI register start offset */
38#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
39
40/* IPI register bit mask */
41#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
42
43/* IPI configuration table */
Boyan Karatotev05e9d4d2022-11-22 14:31:41 +000044static const struct ipi_config *ipi_table;
Jolly Shahc2583ab2019-01-08 11:31:49 -080045
46/* Total number of IPI */
47static uint32_t ipi_total;
48
49/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053050 * ipi_config_table_init() - Initialize IPI configuration data.
51 * @ipi_config_table: IPI configuration table.
52 * @total_ipi: Total number of IPI available.
Jolly Shahc2583ab2019-01-08 11:31:49 -080053 *
54 */
55void ipi_config_table_init(const struct ipi_config *ipi_config_table,
56 uint32_t total_ipi)
57{
58 ipi_table = ipi_config_table;
59 ipi_total = total_ipi;
60}
61
Prasad Kummari7d0623a2023-06-09 14:32:00 +053062/**
63 * is_ipi_mb_within_range() - verify if IPI mailbox is within range.
64 * @local: local IPI ID.
65 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -080066 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053067 * Return: - 1 if within range, 0 if not.
Jolly Shahc2583ab2019-01-08 11:31:49 -080068 *
Jolly Shahc2583ab2019-01-08 11:31:49 -080069 */
70static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
71{
72 int ret = 1;
73
Nithin Ge6c28532024-04-22 13:06:06 +053074 if ((remote >= ipi_total) || (local >= ipi_total)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080075 ret = 0;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053076 }
Jolly Shahc2583ab2019-01-08 11:31:49 -080077
78 return ret;
79}
80
81/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053082 * ipi_mb_validate() - validate IPI mailbox access.
83 * @local: local IPI ID.
84 * @remote: remote IPI ID.
85 * @is_secure: indicate if the requester is from secure software.
Jolly Shahc2583ab2019-01-08 11:31:49 -080086 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053087 * Return: 0 success, negative value for errors.
Jolly Shahc2583ab2019-01-08 11:31:49 -080088 *
Jolly Shahc2583ab2019-01-08 11:31:49 -080089 */
90int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
91{
92 int ret = 0;
93
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053094 if (is_ipi_mb_within_range(local, remote) == 0) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080095 ret = -EINVAL;
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053096 } else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080097 ret = -EPERM;
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053098 } else if (IPI_IS_SECURE(remote) && (is_secure == 0U)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080099 ret = -EPERM;
Venkatesh Yadav Abbarapuccf6da72022-05-04 14:23:32 +0530100 } else {
101 /* To fix the misra 15.7 warning */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530102 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800103
104 return ret;
105}
106
107/**
108 * ipi_mb_open() - Open IPI mailbox.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530109 * @local: local IPI ID.
110 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800111 *
112 */
113void ipi_mb_open(uint32_t local, uint32_t remote)
114{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530115 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
116 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
117
118 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800119 IPI_BIT_MASK(remote));
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530120 mmio_write_32(isr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800121 IPI_BIT_MASK(remote));
122}
123
124/**
125 * ipi_mb_release() - Open IPI mailbox.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530126 * @local: local IPI ID.
127 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800128 *
129 */
130void ipi_mb_release(uint32_t local, uint32_t remote)
131{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530132 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
133
134 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800135 IPI_BIT_MASK(remote));
136}
137
138/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530139 * ipi_mb_enquire_status() - Enquire IPI mailbox status.
140 * @local: local IPI ID.
141 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800142 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530143 * Return: 0 idle, positive value for pending sending or receiving,
144 * negative value for errors.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800145 *
Jolly Shahc2583ab2019-01-08 11:31:49 -0800146 */
147int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
148{
Devanshi Chauhan Alpeshbhaiee5a5d62025-03-26 01:50:27 -0700149 int ret = (int)PM_RET_SUCCESS;
Jolly Shahc2583ab2019-01-08 11:31:49 -0800150 uint32_t status;
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530151 uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
152 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800153
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530154 status = mmio_read_32(obr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530155 if ((status & IPI_BIT_MASK(remote)) != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800156 ret |= IPI_MB_STATUS_SEND_PENDING;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530157 }
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530158 status = mmio_read_32(isr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530159 if ((status & IPI_BIT_MASK(remote)) != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800160 ret |= IPI_MB_STATUS_RECV_PENDING;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530161 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800162
163 return ret;
164}
165
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530166/**
167 * ipi_mb_notify() - Trigger IPI mailbox notification.
168 * @local: local IPI ID.
169 * @remote: remote IPI ID.
170 * @is_blocking: if to trigger the notification in blocking mode or not.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800171 *
172 * It sets the remote bit in the IPI agent trigger register.
173 *
174 */
Venkatesh Yadav Abbarapuefa1d322021-08-04 21:33:15 -0600175void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
Jolly Shahc2583ab2019-01-08 11:31:49 -0800176{
177 uint32_t status;
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530178 uint64_t trig_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_TRIG_OFFSET);
179 uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800180
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530181 mmio_write_32(trig_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800182 IPI_BIT_MASK(remote));
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530183 if (is_blocking != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800184 do {
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530185 status = mmio_read_32(obr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530186 } while ((status & IPI_BIT_MASK(remote)) != 0U);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800187 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800188}
189
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530190/**
191 * ipi_mb_ack() - Ack IPI mailbox notification from the other end.
192 * @local: local IPI ID.
193 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800194 *
195 * It will clear the remote bit in the isr register.
196 *
197 */
198void ipi_mb_ack(uint32_t local, uint32_t remote)
199{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530200 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
201
202 mmio_write_32(isr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800203 IPI_BIT_MASK(remote));
204}
205
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530206/**
207 * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt.
208 * @local: local IPI ID.
209 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800210 *
211 * It will mask the remote bit in the idr register.
212 *
213 */
214void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
215{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530216 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
217
218 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800219 IPI_BIT_MASK(remote));
220}
221
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530222/**
223 * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt.
224 * @local: local IPI ID.
225 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800226 *
227 * It will mask the remote bit in the idr register.
228 *
229 */
230void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
231{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530232 uint64_t ier_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IER_OFFSET);
233
234 mmio_write_32(ier_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800235 IPI_BIT_MASK(remote));
236}