xref: /rk3399_ARM-atf/plat/xilinx/common/ipi.c (revision bc11248abbcd05704bc88bc9c2dcfad32c2c232f)
163436bdeSJolly Shah /*
2619bc13eSMichal Simek  * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
30ee2dc11SRajan Vaja  * Copyright (c) 2020-2022, Xilinx, Inc. All rights reserved.
472eb16b7SDevanshi Chauhan Alpeshbhai  * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
563436bdeSJolly Shah  *
663436bdeSJolly Shah  * SPDX-License-Identifier: BSD-3-Clause
763436bdeSJolly Shah  */
863436bdeSJolly Shah 
963436bdeSJolly Shah /*
1063436bdeSJolly Shah  * Xilinx IPI agent registers access management
1163436bdeSJolly Shah  */
1263436bdeSJolly Shah 
1363436bdeSJolly Shah #include <errno.h>
1463436bdeSJolly Shah #include <string.h>
1563436bdeSJolly Shah 
1663436bdeSJolly Shah #include <common/debug.h>
1763436bdeSJolly Shah #include <common/runtime_svc.h>
1863436bdeSJolly Shah #include <lib/bakery_lock.h>
1963436bdeSJolly Shah #include <lib/mmio.h>
2063436bdeSJolly Shah 
2163436bdeSJolly Shah #include <ipi.h>
2263436bdeSJolly Shah #include <plat_private.h>
2372eb16b7SDevanshi Chauhan Alpeshbhai #include "pm_defs.h"
2463436bdeSJolly Shah 
2563436bdeSJolly Shah /*********************************************************************
2663436bdeSJolly Shah  * Macros definitions
2763436bdeSJolly Shah  ********************************************************************/
2863436bdeSJolly Shah 
2963436bdeSJolly Shah /* IPI registers offsets macros */
3063436bdeSJolly Shah #define IPI_TRIG_OFFSET 0x00U
3163436bdeSJolly Shah #define IPI_OBR_OFFSET  0x04U
3263436bdeSJolly Shah #define IPI_ISR_OFFSET  0x10U
3363436bdeSJolly Shah #define IPI_IMR_OFFSET  0x14U
3463436bdeSJolly Shah #define IPI_IER_OFFSET  0x18U
3563436bdeSJolly Shah #define IPI_IDR_OFFSET  0x1CU
3663436bdeSJolly Shah 
3763436bdeSJolly Shah /* IPI register start offset */
3863436bdeSJolly Shah #define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
3963436bdeSJolly Shah 
4063436bdeSJolly Shah /* IPI register bit mask */
4163436bdeSJolly Shah #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
4263436bdeSJolly Shah 
4363436bdeSJolly Shah /* IPI configuration table */
44f4b8470fSBoyan Karatotev static const struct ipi_config *ipi_table;
4563436bdeSJolly Shah 
4663436bdeSJolly Shah /* Total number of IPI */
4763436bdeSJolly Shah static uint32_t ipi_total;
4863436bdeSJolly Shah 
4963436bdeSJolly Shah /**
50de7ed953SPrasad Kummari  * ipi_config_table_init() - Initialize IPI configuration data.
51de7ed953SPrasad Kummari  * @ipi_config_table: IPI configuration table.
52de7ed953SPrasad Kummari  * @total_ipi: Total number of IPI available.
5363436bdeSJolly Shah  *
5463436bdeSJolly Shah  */
ipi_config_table_init(const struct ipi_config * ipi_config_table,uint32_t total_ipi)5563436bdeSJolly Shah void ipi_config_table_init(const struct ipi_config *ipi_config_table,
5663436bdeSJolly Shah 			   uint32_t total_ipi)
5763436bdeSJolly Shah {
5863436bdeSJolly Shah 	ipi_table = ipi_config_table;
5963436bdeSJolly Shah 	ipi_total = total_ipi;
6063436bdeSJolly Shah }
6163436bdeSJolly Shah 
62de7ed953SPrasad Kummari /**
63de7ed953SPrasad Kummari  * is_ipi_mb_within_range() - verify if IPI mailbox is within range.
64de7ed953SPrasad Kummari  * @local: local IPI ID.
65de7ed953SPrasad Kummari  * @remote: remote IPI ID.
6663436bdeSJolly Shah  *
67de7ed953SPrasad Kummari  * Return: - 1 if within range, 0 if not.
6863436bdeSJolly Shah  *
6963436bdeSJolly Shah  */
is_ipi_mb_within_range(uint32_t local,uint32_t remote)70*6df7184eSDevanshi Chauhan Alpeshbhai static inline uint32_t is_ipi_mb_within_range(uint32_t local, uint32_t remote)
7163436bdeSJolly Shah {
72*6df7184eSDevanshi Chauhan Alpeshbhai 	uint32_t ret = 1U;
7363436bdeSJolly Shah 
748e9a5a51SNithin G 	if ((remote >= ipi_total) || (local >= ipi_total)) {
75*6df7184eSDevanshi Chauhan Alpeshbhai 		ret = 0U;
76eb0d2b17SVenkatesh Yadav Abbarapu 	}
7763436bdeSJolly Shah 
7863436bdeSJolly Shah 	return ret;
7963436bdeSJolly Shah }
8063436bdeSJolly Shah 
8163436bdeSJolly Shah /**
82de7ed953SPrasad Kummari  * ipi_mb_validate() - validate IPI mailbox access.
83de7ed953SPrasad Kummari  * @local: local IPI ID.
84de7ed953SPrasad Kummari  * @remote: remote IPI ID.
85de7ed953SPrasad Kummari  * @is_secure: indicate if the requester is from secure software.
8663436bdeSJolly Shah  *
87de7ed953SPrasad Kummari  * Return: 0 success, negative value for errors.
8863436bdeSJolly Shah  *
8963436bdeSJolly Shah  */
ipi_mb_validate(uint32_t local,uint32_t remote,uint32_t is_secure)90*6df7184eSDevanshi Chauhan Alpeshbhai int32_t ipi_mb_validate(uint32_t local, uint32_t remote, uint32_t is_secure)
9163436bdeSJolly Shah {
92*6df7184eSDevanshi Chauhan Alpeshbhai 	int32_t ret = 0;
9363436bdeSJolly Shah 
94*6df7184eSDevanshi Chauhan Alpeshbhai 	if (is_ipi_mb_within_range(local, remote) == 0U) {
9563436bdeSJolly Shah 		ret = -EINVAL;
967d15b94bSMaheedhar Bollapalli 	} else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
9763436bdeSJolly Shah 		ret = -EPERM;
987d15b94bSMaheedhar Bollapalli 	} else if (IPI_IS_SECURE(remote) && (is_secure == 0U)) {
9963436bdeSJolly Shah 		ret = -EPERM;
10016de22d0SVenkatesh Yadav Abbarapu 	} else {
10116de22d0SVenkatesh Yadav Abbarapu 		/* To fix the misra 15.7 warning */
102eb0d2b17SVenkatesh Yadav Abbarapu 	}
10363436bdeSJolly Shah 
10463436bdeSJolly Shah 	return ret;
10563436bdeSJolly Shah }
10663436bdeSJolly Shah 
10763436bdeSJolly Shah /**
10863436bdeSJolly Shah  * ipi_mb_open() - Open IPI mailbox.
109de7ed953SPrasad Kummari  * @local: local IPI ID.
110de7ed953SPrasad Kummari  * @remote: remote IPI ID.
11163436bdeSJolly Shah  *
11263436bdeSJolly Shah  */
ipi_mb_open(uint32_t local,uint32_t remote)11363436bdeSJolly Shah void ipi_mb_open(uint32_t local, uint32_t remote)
11463436bdeSJolly Shah {
11550ab1357SMaheedhar Bollapalli 	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
11650ab1357SMaheedhar Bollapalli 	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
11750ab1357SMaheedhar Bollapalli 
11850ab1357SMaheedhar Bollapalli 	mmio_write_32(idr_offset,
11963436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
12050ab1357SMaheedhar Bollapalli 	mmio_write_32(isr_offset,
12163436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
12263436bdeSJolly Shah }
12363436bdeSJolly Shah 
12463436bdeSJolly Shah /**
12563436bdeSJolly Shah  * ipi_mb_release() - Open IPI mailbox.
126de7ed953SPrasad Kummari  * @local: local IPI ID.
127de7ed953SPrasad Kummari  * @remote: remote IPI ID.
12863436bdeSJolly Shah  *
12963436bdeSJolly Shah  */
ipi_mb_release(uint32_t local,uint32_t remote)13063436bdeSJolly Shah void ipi_mb_release(uint32_t local, uint32_t remote)
13163436bdeSJolly Shah {
13250ab1357SMaheedhar Bollapalli 	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
13350ab1357SMaheedhar Bollapalli 
13450ab1357SMaheedhar Bollapalli 	mmio_write_32(idr_offset,
13563436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
13663436bdeSJolly Shah }
13763436bdeSJolly Shah 
13863436bdeSJolly Shah /**
139de7ed953SPrasad Kummari  * ipi_mb_enquire_status() - Enquire IPI mailbox status.
140de7ed953SPrasad Kummari  * @local: local IPI ID.
141de7ed953SPrasad Kummari  * @remote: remote IPI ID.
14263436bdeSJolly Shah  *
143bdba3c84SDevanshi Chauhan Alpeshbhai  * Return: 0 idle and positive value for pending sending or receiving.
14463436bdeSJolly Shah  *
14563436bdeSJolly Shah  */
ipi_mb_enquire_status(uint32_t local,uint32_t remote)146bdba3c84SDevanshi Chauhan Alpeshbhai uint32_t ipi_mb_enquire_status(uint32_t local, uint32_t remote)
14763436bdeSJolly Shah {
148bdba3c84SDevanshi Chauhan Alpeshbhai 	uint32_t ret = (uint32_t)PM_RET_SUCCESS;
14963436bdeSJolly Shah 	uint32_t status;
15050ab1357SMaheedhar Bollapalli 	uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
15150ab1357SMaheedhar Bollapalli 	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
15263436bdeSJolly Shah 
15350ab1357SMaheedhar Bollapalli 	status = mmio_read_32(obr_offset);
154e2230375SMaheedhar Bollapalli 	if ((status & IPI_BIT_MASK(remote)) != 0U) {
15563436bdeSJolly Shah 		ret |= IPI_MB_STATUS_SEND_PENDING;
156eb0d2b17SVenkatesh Yadav Abbarapu 	}
15750ab1357SMaheedhar Bollapalli 	status = mmio_read_32(isr_offset);
158e2230375SMaheedhar Bollapalli 	if ((status & IPI_BIT_MASK(remote)) != 0U) {
15963436bdeSJolly Shah 		ret |= IPI_MB_STATUS_RECV_PENDING;
160eb0d2b17SVenkatesh Yadav Abbarapu 	}
16163436bdeSJolly Shah 
16263436bdeSJolly Shah 	return ret;
16363436bdeSJolly Shah }
16463436bdeSJolly Shah 
165de7ed953SPrasad Kummari /**
166de7ed953SPrasad Kummari  * ipi_mb_notify() - Trigger IPI mailbox notification.
167de7ed953SPrasad Kummari  * @local: local IPI ID.
168de7ed953SPrasad Kummari  * @remote: remote IPI ID.
169de7ed953SPrasad Kummari  * @is_blocking: if to trigger the notification in blocking mode or not.
17063436bdeSJolly Shah  *
17163436bdeSJolly Shah  * It sets the remote bit in the IPI agent trigger register.
17263436bdeSJolly Shah  *
17363436bdeSJolly Shah  */
ipi_mb_notify(uint32_t local,uint32_t remote,uint32_t is_blocking)17462f9134dSVenkatesh Yadav Abbarapu void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
17563436bdeSJolly Shah {
17663436bdeSJolly Shah 	uint32_t status;
17750ab1357SMaheedhar Bollapalli 	uint64_t trig_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_TRIG_OFFSET);
17850ab1357SMaheedhar Bollapalli 	uint64_t obr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
17963436bdeSJolly Shah 
18050ab1357SMaheedhar Bollapalli 	mmio_write_32(trig_offset,
18163436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
182e2230375SMaheedhar Bollapalli 	if (is_blocking != 0U) {
18363436bdeSJolly Shah 		do {
18450ab1357SMaheedhar Bollapalli 			status = mmio_read_32(obr_offset);
185e2230375SMaheedhar Bollapalli 		} while ((status & IPI_BIT_MASK(remote)) != 0U);
18663436bdeSJolly Shah 	}
18763436bdeSJolly Shah }
18863436bdeSJolly Shah 
189de7ed953SPrasad Kummari /**
190de7ed953SPrasad Kummari  * ipi_mb_ack() - Ack IPI mailbox notification from the other end.
191de7ed953SPrasad Kummari  * @local: local IPI ID.
192de7ed953SPrasad Kummari  * @remote: remote IPI ID.
19363436bdeSJolly Shah  *
19463436bdeSJolly Shah  * It will clear the remote bit in the isr register.
19563436bdeSJolly Shah  *
19663436bdeSJolly Shah  */
ipi_mb_ack(uint32_t local,uint32_t remote)19763436bdeSJolly Shah void ipi_mb_ack(uint32_t local, uint32_t remote)
19863436bdeSJolly Shah {
19950ab1357SMaheedhar Bollapalli 	uint64_t isr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
20050ab1357SMaheedhar Bollapalli 
20150ab1357SMaheedhar Bollapalli 	mmio_write_32(isr_offset,
20263436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
20363436bdeSJolly Shah }
20463436bdeSJolly Shah 
205de7ed953SPrasad Kummari /**
206de7ed953SPrasad Kummari  * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt.
207de7ed953SPrasad Kummari  * @local: local IPI ID.
208de7ed953SPrasad Kummari  * @remote: remote IPI ID.
20963436bdeSJolly Shah  *
21063436bdeSJolly Shah  * It will mask the remote bit in the idr register.
21163436bdeSJolly Shah  *
21263436bdeSJolly Shah  */
ipi_mb_disable_irq(uint32_t local,uint32_t remote)21363436bdeSJolly Shah void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
21463436bdeSJolly Shah {
21550ab1357SMaheedhar Bollapalli 	uint64_t idr_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IDR_OFFSET);
21650ab1357SMaheedhar Bollapalli 
21750ab1357SMaheedhar Bollapalli 	mmio_write_32(idr_offset,
21863436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
21963436bdeSJolly Shah }
22063436bdeSJolly Shah 
221de7ed953SPrasad Kummari /**
222de7ed953SPrasad Kummari  * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt.
223de7ed953SPrasad Kummari  * @local: local IPI ID.
224de7ed953SPrasad Kummari  * @remote: remote IPI ID.
22563436bdeSJolly Shah  *
22663436bdeSJolly Shah  * It will mask the remote bit in the idr register.
22763436bdeSJolly Shah  *
22863436bdeSJolly Shah  */
ipi_mb_enable_irq(uint32_t local,uint32_t remote)22963436bdeSJolly Shah void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
23063436bdeSJolly Shah {
23150ab1357SMaheedhar Bollapalli 	uint64_t ier_offset = (uint64_t)(IPI_REG_BASE(local) + IPI_IER_OFFSET);
23250ab1357SMaheedhar Bollapalli 
23350ab1357SMaheedhar Bollapalli 	mmio_write_32(ier_offset,
23463436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
23563436bdeSJolly Shah }
236