blob: cc4b04d9f45b278b515fc7acbe43cdf165803855 [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.
Prasad Kummari7d0623a2023-06-09 14:32:00 +05304 * Copyright (c) 2022-2023, 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>
23
24/*********************************************************************
25 * Macros definitions
26 ********************************************************************/
27
28/* IPI registers offsets macros */
29#define IPI_TRIG_OFFSET 0x00U
30#define IPI_OBR_OFFSET 0x04U
31#define IPI_ISR_OFFSET 0x10U
32#define IPI_IMR_OFFSET 0x14U
33#define IPI_IER_OFFSET 0x18U
34#define IPI_IDR_OFFSET 0x1CU
35
36/* IPI register start offset */
37#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
38
39/* IPI register bit mask */
40#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
41
42/* IPI configuration table */
Boyan Karatotev05e9d4d2022-11-22 14:31:41 +000043static const struct ipi_config *ipi_table;
Jolly Shahc2583ab2019-01-08 11:31:49 -080044
45/* Total number of IPI */
46static uint32_t ipi_total;
47
48/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053049 * ipi_config_table_init() - Initialize IPI configuration data.
50 * @ipi_config_table: IPI configuration table.
51 * @total_ipi: Total number of IPI available.
Jolly Shahc2583ab2019-01-08 11:31:49 -080052 *
53 */
54void ipi_config_table_init(const struct ipi_config *ipi_config_table,
55 uint32_t total_ipi)
56{
57 ipi_table = ipi_config_table;
58 ipi_total = total_ipi;
59}
60
Prasad Kummari7d0623a2023-06-09 14:32:00 +053061/**
62 * is_ipi_mb_within_range() - verify if IPI mailbox is within range.
63 * @local: local IPI ID.
64 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -080065 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053066 * Return: - 1 if within range, 0 if not.
Jolly Shahc2583ab2019-01-08 11:31:49 -080067 *
Jolly Shahc2583ab2019-01-08 11:31:49 -080068 */
69static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
70{
71 int ret = 1;
72
Nithin Ge6c28532024-04-22 13:06:06 +053073 if ((remote >= ipi_total) || (local >= ipi_total)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080074 ret = 0;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +053075 }
Jolly Shahc2583ab2019-01-08 11:31:49 -080076
77 return ret;
78}
79
80/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +053081 * ipi_mb_validate() - validate IPI mailbox access.
82 * @local: local IPI ID.
83 * @remote: remote IPI ID.
84 * @is_secure: indicate if the requester is from secure software.
Jolly Shahc2583ab2019-01-08 11:31:49 -080085 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +053086 * Return: 0 success, negative value for errors.
Jolly Shahc2583ab2019-01-08 11:31:49 -080087 *
Jolly Shahc2583ab2019-01-08 11:31:49 -080088 */
89int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
90{
91 int ret = 0;
92
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053093 if (is_ipi_mb_within_range(local, remote) == 0) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080094 ret = -EINVAL;
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053095 } else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080096 ret = -EPERM;
Maheedhar Bollapalli9c3fc0b2024-04-24 12:53:28 +053097 } else if (IPI_IS_SECURE(remote) && (is_secure == 0U)) {
Jolly Shahc2583ab2019-01-08 11:31:49 -080098 ret = -EPERM;
Venkatesh Yadav Abbarapuccf6da72022-05-04 14:23:32 +053099 } else {
100 /* To fix the misra 15.7 warning */
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530101 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800102
103 return ret;
104}
105
106/**
107 * ipi_mb_open() - Open IPI mailbox.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530108 * @local: local IPI ID.
109 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800110 *
111 */
112void ipi_mb_open(uint32_t local, uint32_t remote)
113{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530114 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
115 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
116
117 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800118 IPI_BIT_MASK(remote));
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530119 mmio_write_32(isr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800120 IPI_BIT_MASK(remote));
121}
122
123/**
124 * ipi_mb_release() - Open IPI mailbox.
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530125 * @local: local IPI ID.
126 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800127 *
128 */
129void ipi_mb_release(uint32_t local, uint32_t remote)
130{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530131 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
132
133 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800134 IPI_BIT_MASK(remote));
135}
136
137/**
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530138 * ipi_mb_enquire_status() - Enquire IPI mailbox status.
139 * @local: local IPI ID.
140 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800141 *
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530142 * Return: 0 idle, positive value for pending sending or receiving,
143 * negative value for errors.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800144 *
Jolly Shahc2583ab2019-01-08 11:31:49 -0800145 */
146int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
147{
HariBabu Gattem9f9db612022-09-15 22:35:11 -0700148 int ret = 0U;
Jolly Shahc2583ab2019-01-08 11:31:49 -0800149 uint32_t status;
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530150 uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
151 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800152
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530153 status = mmio_read_32(obr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530154 if ((status & IPI_BIT_MASK(remote)) != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800155 ret |= IPI_MB_STATUS_SEND_PENDING;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530156 }
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530157 status = mmio_read_32(isr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530158 if ((status & IPI_BIT_MASK(remote)) != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800159 ret |= IPI_MB_STATUS_RECV_PENDING;
Venkatesh Yadav Abbarapu987fad32022-04-29 13:52:00 +0530160 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800161
162 return ret;
163}
164
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530165/**
166 * ipi_mb_notify() - Trigger IPI mailbox notification.
167 * @local: local IPI ID.
168 * @remote: remote IPI ID.
169 * @is_blocking: if to trigger the notification in blocking mode or not.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800170 *
171 * It sets the remote bit in the IPI agent trigger register.
172 *
173 */
Venkatesh Yadav Abbarapuefa1d322021-08-04 21:33:15 -0600174void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
Jolly Shahc2583ab2019-01-08 11:31:49 -0800175{
176 uint32_t status;
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530177 uint64_t trig_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_TRIG_OFFSET);
178 uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800179
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530180 mmio_write_32(trig_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800181 IPI_BIT_MASK(remote));
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530182 if (is_blocking != 0U) {
Jolly Shahc2583ab2019-01-08 11:31:49 -0800183 do {
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530184 status = mmio_read_32(obr_offset);
Maheedhar Bollapallia9cc0bd2024-04-22 15:27:02 +0530185 } while ((status & IPI_BIT_MASK(remote)) != 0U);
Jolly Shahc2583ab2019-01-08 11:31:49 -0800186 }
Jolly Shahc2583ab2019-01-08 11:31:49 -0800187}
188
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530189/**
190 * ipi_mb_ack() - Ack IPI mailbox notification from the other end.
191 * @local: local IPI ID.
192 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800193 *
194 * It will clear the remote bit in the isr register.
195 *
196 */
197void ipi_mb_ack(uint32_t local, uint32_t remote)
198{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530199 uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
200
201 mmio_write_32(isr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800202 IPI_BIT_MASK(remote));
203}
204
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530205/**
206 * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt.
207 * @local: local IPI ID.
208 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800209 *
210 * It will mask the remote bit in the idr register.
211 *
212 */
213void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
214{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530215 uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
216
217 mmio_write_32(idr_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800218 IPI_BIT_MASK(remote));
219}
220
Prasad Kummari7d0623a2023-06-09 14:32:00 +0530221/**
222 * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt.
223 * @local: local IPI ID.
224 * @remote: remote IPI ID.
Jolly Shahc2583ab2019-01-08 11:31:49 -0800225 *
226 * It will mask the remote bit in the idr register.
227 *
228 */
229void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
230{
Maheedhar Bollapalli0ec699c2024-04-23 12:17:22 +0530231 uint64_t ier_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IER_OFFSET);
232
233 mmio_write_32(ier_offset,
Jolly Shahc2583ab2019-01-08 11:31:49 -0800234 IPI_BIT_MASK(remote));
235}