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. 4de7ed953SPrasad Kummari * Copyright (c) 2022-2023, 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> 2363436bdeSJolly Shah 2463436bdeSJolly Shah /********************************************************************* 2563436bdeSJolly Shah * Macros definitions 2663436bdeSJolly Shah ********************************************************************/ 2763436bdeSJolly Shah 2863436bdeSJolly Shah /* IPI registers offsets macros */ 2963436bdeSJolly Shah #define IPI_TRIG_OFFSET 0x00U 3063436bdeSJolly Shah #define IPI_OBR_OFFSET 0x04U 3163436bdeSJolly Shah #define IPI_ISR_OFFSET 0x10U 3263436bdeSJolly Shah #define IPI_IMR_OFFSET 0x14U 3363436bdeSJolly Shah #define IPI_IER_OFFSET 0x18U 3463436bdeSJolly Shah #define IPI_IDR_OFFSET 0x1CU 3563436bdeSJolly Shah 3663436bdeSJolly Shah /* IPI register start offset */ 3763436bdeSJolly Shah #define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base) 3863436bdeSJolly Shah 3963436bdeSJolly Shah /* IPI register bit mask */ 4063436bdeSJolly Shah #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask) 4163436bdeSJolly Shah 4263436bdeSJolly Shah /* IPI configuration table */ 43f4b8470fSBoyan Karatotev static const struct ipi_config *ipi_table; 4463436bdeSJolly Shah 4563436bdeSJolly Shah /* Total number of IPI */ 4663436bdeSJolly Shah static uint32_t ipi_total; 4763436bdeSJolly Shah 4863436bdeSJolly Shah /** 49de7ed953SPrasad Kummari * ipi_config_table_init() - Initialize IPI configuration data. 50de7ed953SPrasad Kummari * @ipi_config_table: IPI configuration table. 51de7ed953SPrasad Kummari * @total_ipi: Total number of IPI available. 5263436bdeSJolly Shah * 5363436bdeSJolly Shah */ 5463436bdeSJolly Shah void ipi_config_table_init(const struct ipi_config *ipi_config_table, 5563436bdeSJolly Shah uint32_t total_ipi) 5663436bdeSJolly Shah { 5763436bdeSJolly Shah ipi_table = ipi_config_table; 5863436bdeSJolly Shah ipi_total = total_ipi; 5963436bdeSJolly Shah } 6063436bdeSJolly Shah 61de7ed953SPrasad Kummari /** 62de7ed953SPrasad Kummari * is_ipi_mb_within_range() - verify if IPI mailbox is within range. 63de7ed953SPrasad Kummari * @local: local IPI ID. 64de7ed953SPrasad Kummari * @remote: remote IPI ID. 6563436bdeSJolly Shah * 66de7ed953SPrasad Kummari * Return: - 1 if within range, 0 if not. 6763436bdeSJolly Shah * 6863436bdeSJolly Shah */ 6963436bdeSJolly Shah static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote) 7063436bdeSJolly Shah { 7163436bdeSJolly Shah int ret = 1; 7263436bdeSJolly Shah 738e9a5a51SNithin G if ((remote >= ipi_total) || (local >= ipi_total)) { 7463436bdeSJolly Shah ret = 0; 75eb0d2b17SVenkatesh Yadav Abbarapu } 7663436bdeSJolly Shah 7763436bdeSJolly Shah return ret; 7863436bdeSJolly Shah } 7963436bdeSJolly Shah 8063436bdeSJolly Shah /** 81de7ed953SPrasad Kummari * ipi_mb_validate() - validate IPI mailbox access. 82de7ed953SPrasad Kummari * @local: local IPI ID. 83de7ed953SPrasad Kummari * @remote: remote IPI ID. 84de7ed953SPrasad Kummari * @is_secure: indicate if the requester is from secure software. 8563436bdeSJolly Shah * 86de7ed953SPrasad Kummari * Return: 0 success, negative value for errors. 8763436bdeSJolly Shah * 8863436bdeSJolly Shah */ 8963436bdeSJolly Shah int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure) 9063436bdeSJolly Shah { 9163436bdeSJolly Shah int ret = 0; 9263436bdeSJolly Shah 93eb0d2b17SVenkatesh Yadav Abbarapu if (!is_ipi_mb_within_range(local, remote)) { 9463436bdeSJolly Shah ret = -EINVAL; 95eb0d2b17SVenkatesh Yadav Abbarapu } else if (IPI_IS_SECURE(local) && !is_secure) { 9663436bdeSJolly Shah ret = -EPERM; 97eb0d2b17SVenkatesh Yadav Abbarapu } else if (IPI_IS_SECURE(remote) && !is_secure) { 9863436bdeSJolly Shah ret = -EPERM; 9916de22d0SVenkatesh Yadav Abbarapu } else { 10016de22d0SVenkatesh Yadav Abbarapu /* To fix the misra 15.7 warning */ 101eb0d2b17SVenkatesh Yadav Abbarapu } 10263436bdeSJolly Shah 10363436bdeSJolly Shah return ret; 10463436bdeSJolly Shah } 10563436bdeSJolly Shah 10663436bdeSJolly Shah /** 10763436bdeSJolly Shah * ipi_mb_open() - Open IPI mailbox. 108de7ed953SPrasad Kummari * @local: local IPI ID. 109de7ed953SPrasad Kummari * @remote: remote IPI ID. 11063436bdeSJolly Shah * 11163436bdeSJolly Shah */ 11263436bdeSJolly Shah void ipi_mb_open(uint32_t local, uint32_t remote) 11363436bdeSJolly Shah { 11463436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 11563436bdeSJolly Shah IPI_BIT_MASK(remote)); 11663436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET, 11763436bdeSJolly Shah IPI_BIT_MASK(remote)); 11863436bdeSJolly Shah } 11963436bdeSJolly Shah 12063436bdeSJolly Shah /** 12163436bdeSJolly Shah * ipi_mb_release() - Open IPI mailbox. 122de7ed953SPrasad Kummari * @local: local IPI ID. 123de7ed953SPrasad Kummari * @remote: remote IPI ID. 12463436bdeSJolly Shah * 12563436bdeSJolly Shah */ 12663436bdeSJolly Shah void ipi_mb_release(uint32_t local, uint32_t remote) 12763436bdeSJolly Shah { 12863436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 12963436bdeSJolly Shah IPI_BIT_MASK(remote)); 13063436bdeSJolly Shah } 13163436bdeSJolly Shah 13263436bdeSJolly Shah /** 133de7ed953SPrasad Kummari * ipi_mb_enquire_status() - Enquire IPI mailbox status. 134de7ed953SPrasad Kummari * @local: local IPI ID. 135de7ed953SPrasad Kummari * @remote: remote IPI ID. 13663436bdeSJolly Shah * 137de7ed953SPrasad Kummari * Return: 0 idle, positive value for pending sending or receiving, 138de7ed953SPrasad Kummari * negative value for errors. 13963436bdeSJolly Shah * 14063436bdeSJolly Shah */ 14163436bdeSJolly Shah int ipi_mb_enquire_status(uint32_t local, uint32_t remote) 14263436bdeSJolly Shah { 14315dc3e4fSHariBabu Gattem int ret = 0U; 14463436bdeSJolly Shah uint32_t status; 14563436bdeSJolly Shah 14663436bdeSJolly Shah status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET); 147*e2230375SMaheedhar Bollapalli if ((status & IPI_BIT_MASK(remote)) != 0U) { 14863436bdeSJolly Shah ret |= IPI_MB_STATUS_SEND_PENDING; 149eb0d2b17SVenkatesh Yadav Abbarapu } 15063436bdeSJolly Shah status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET); 151*e2230375SMaheedhar Bollapalli if ((status & IPI_BIT_MASK(remote)) != 0U) { 15263436bdeSJolly Shah ret |= IPI_MB_STATUS_RECV_PENDING; 153eb0d2b17SVenkatesh Yadav Abbarapu } 15463436bdeSJolly Shah 15563436bdeSJolly Shah return ret; 15663436bdeSJolly Shah } 15763436bdeSJolly Shah 158de7ed953SPrasad Kummari /** 159de7ed953SPrasad Kummari * ipi_mb_notify() - Trigger IPI mailbox notification. 160de7ed953SPrasad Kummari * @local: local IPI ID. 161de7ed953SPrasad Kummari * @remote: remote IPI ID. 162de7ed953SPrasad Kummari * @is_blocking: if to trigger the notification in blocking mode or not. 16363436bdeSJolly Shah * 16463436bdeSJolly Shah * It sets the remote bit in the IPI agent trigger register. 16563436bdeSJolly Shah * 16663436bdeSJolly Shah */ 16762f9134dSVenkatesh Yadav Abbarapu void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking) 16863436bdeSJolly Shah { 16963436bdeSJolly Shah uint32_t status; 17063436bdeSJolly Shah 17163436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET, 17263436bdeSJolly Shah IPI_BIT_MASK(remote)); 173*e2230375SMaheedhar Bollapalli if (is_blocking != 0U) { 17463436bdeSJolly Shah do { 17563436bdeSJolly Shah status = mmio_read_32(IPI_REG_BASE(local) + 17663436bdeSJolly Shah IPI_OBR_OFFSET); 177*e2230375SMaheedhar Bollapalli } while ((status & IPI_BIT_MASK(remote)) != 0U); 17863436bdeSJolly Shah } 17963436bdeSJolly Shah } 18063436bdeSJolly Shah 181de7ed953SPrasad Kummari /** 182de7ed953SPrasad Kummari * ipi_mb_ack() - Ack IPI mailbox notification from the other end. 183de7ed953SPrasad Kummari * @local: local IPI ID. 184de7ed953SPrasad Kummari * @remote: remote IPI ID. 18563436bdeSJolly Shah * 18663436bdeSJolly Shah * It will clear the remote bit in the isr register. 18763436bdeSJolly Shah * 18863436bdeSJolly Shah */ 18963436bdeSJolly Shah void ipi_mb_ack(uint32_t local, uint32_t remote) 19063436bdeSJolly Shah { 19163436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET, 19263436bdeSJolly Shah IPI_BIT_MASK(remote)); 19363436bdeSJolly Shah } 19463436bdeSJolly Shah 195de7ed953SPrasad Kummari /** 196de7ed953SPrasad Kummari * ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt. 197de7ed953SPrasad Kummari * @local: local IPI ID. 198de7ed953SPrasad Kummari * @remote: remote IPI ID. 19963436bdeSJolly Shah * 20063436bdeSJolly Shah * It will mask the remote bit in the idr register. 20163436bdeSJolly Shah * 20263436bdeSJolly Shah */ 20363436bdeSJolly Shah void ipi_mb_disable_irq(uint32_t local, uint32_t remote) 20463436bdeSJolly Shah { 20563436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET, 20663436bdeSJolly Shah IPI_BIT_MASK(remote)); 20763436bdeSJolly Shah } 20863436bdeSJolly Shah 209de7ed953SPrasad Kummari /** 210de7ed953SPrasad Kummari * ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt. 211de7ed953SPrasad Kummari * @local: local IPI ID. 212de7ed953SPrasad Kummari * @remote: remote IPI ID. 21363436bdeSJolly Shah * 21463436bdeSJolly Shah * It will mask the remote bit in the idr register. 21563436bdeSJolly Shah * 21663436bdeSJolly Shah */ 21763436bdeSJolly Shah void ipi_mb_enable_irq(uint32_t local, uint32_t remote) 21863436bdeSJolly Shah { 21963436bdeSJolly Shah mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET, 22063436bdeSJolly Shah IPI_BIT_MASK(remote)); 22163436bdeSJolly Shah } 222