xref: /rk3399_ARM-atf/plat/xilinx/common/ipi.c (revision eb0d2b17722c01a22bf3ec1123f7bed2bf891b09)
163436bdeSJolly Shah /*
263436bdeSJolly Shah  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
363436bdeSJolly Shah  *
463436bdeSJolly Shah  * SPDX-License-Identifier: BSD-3-Clause
563436bdeSJolly Shah  */
663436bdeSJolly Shah 
763436bdeSJolly Shah /*
863436bdeSJolly Shah  * Xilinx IPI agent registers access management
963436bdeSJolly Shah  */
1063436bdeSJolly Shah 
1163436bdeSJolly Shah #include <errno.h>
1263436bdeSJolly Shah #include <string.h>
1363436bdeSJolly Shah 
1463436bdeSJolly Shah #include <common/debug.h>
1563436bdeSJolly Shah #include <common/runtime_svc.h>
1663436bdeSJolly Shah #include <lib/bakery_lock.h>
1763436bdeSJolly Shah #include <lib/mmio.h>
1863436bdeSJolly Shah 
1963436bdeSJolly Shah #include <ipi.h>
2063436bdeSJolly Shah #include <plat_ipi.h>
2163436bdeSJolly Shah #include <plat_private.h>
2263436bdeSJolly Shah 
2363436bdeSJolly Shah /*********************************************************************
2463436bdeSJolly Shah  * Macros definitions
2563436bdeSJolly Shah  ********************************************************************/
2663436bdeSJolly Shah 
2763436bdeSJolly Shah /* IPI registers offsets macros */
2863436bdeSJolly Shah #define IPI_TRIG_OFFSET 0x00U
2963436bdeSJolly Shah #define IPI_OBR_OFFSET  0x04U
3063436bdeSJolly Shah #define IPI_ISR_OFFSET  0x10U
3163436bdeSJolly Shah #define IPI_IMR_OFFSET  0x14U
3263436bdeSJolly Shah #define IPI_IER_OFFSET  0x18U
3363436bdeSJolly Shah #define IPI_IDR_OFFSET  0x1CU
3463436bdeSJolly Shah 
3563436bdeSJolly Shah /* IPI register start offset */
3663436bdeSJolly Shah #define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
3763436bdeSJolly Shah 
3863436bdeSJolly Shah /* IPI register bit mask */
3963436bdeSJolly Shah #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
4063436bdeSJolly Shah 
4163436bdeSJolly Shah /* IPI configuration table */
4263436bdeSJolly Shah const static struct ipi_config *ipi_table;
4363436bdeSJolly Shah 
4463436bdeSJolly Shah /* Total number of IPI */
4563436bdeSJolly Shah static uint32_t ipi_total;
4663436bdeSJolly Shah 
4763436bdeSJolly Shah /**
4863436bdeSJolly Shah  * ipi_config_init() - Initialize IPI configuration data
4963436bdeSJolly Shah  *
5063436bdeSJolly Shah  * @ipi_config_table  - IPI configuration table
5163436bdeSJolly Shah  * @ipi_total - 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 
6163436bdeSJolly Shah /* is_ipi_mb_within_range() - verify if IPI mailbox is within range
6263436bdeSJolly Shah  *
6363436bdeSJolly Shah  * @local  - local IPI ID
6463436bdeSJolly Shah  * @remote - remote IPI ID
6563436bdeSJolly Shah  *
6663436bdeSJolly Shah  * return - 1 if within range, 0 if not
6763436bdeSJolly Shah  */
6863436bdeSJolly Shah static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
6963436bdeSJolly Shah {
7063436bdeSJolly Shah 	int ret = 1;
7163436bdeSJolly Shah 
72*eb0d2b17SVenkatesh Yadav Abbarapu 	if (remote >= ipi_total || local >= ipi_total) {
7363436bdeSJolly Shah 		ret = 0;
74*eb0d2b17SVenkatesh Yadav Abbarapu 	}
7563436bdeSJolly Shah 
7663436bdeSJolly Shah 	return ret;
7763436bdeSJolly Shah }
7863436bdeSJolly Shah 
7963436bdeSJolly Shah /**
8063436bdeSJolly Shah  * ipi_mb_validate() - validate IPI mailbox access
8163436bdeSJolly Shah  *
8263436bdeSJolly Shah  * @local  - local IPI ID
8363436bdeSJolly Shah  * @remote - remote IPI ID
8463436bdeSJolly Shah  * @is_secure - indicate if the requester is from secure software
8563436bdeSJolly Shah  *
8663436bdeSJolly Shah  * return - 0 success, negative value for errors
8763436bdeSJolly Shah  */
8863436bdeSJolly Shah int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
8963436bdeSJolly Shah {
9063436bdeSJolly Shah 	int ret = 0;
9163436bdeSJolly Shah 
92*eb0d2b17SVenkatesh Yadav Abbarapu 	if (!is_ipi_mb_within_range(local, remote)) {
9363436bdeSJolly Shah 		ret = -EINVAL;
94*eb0d2b17SVenkatesh Yadav Abbarapu 	} else if (IPI_IS_SECURE(local) && !is_secure) {
9563436bdeSJolly Shah 		ret = -EPERM;
96*eb0d2b17SVenkatesh Yadav Abbarapu 	} else if (IPI_IS_SECURE(remote) && !is_secure) {
9763436bdeSJolly Shah 		ret = -EPERM;
98*eb0d2b17SVenkatesh Yadav Abbarapu 	}
9963436bdeSJolly Shah 
10063436bdeSJolly Shah 	return ret;
10163436bdeSJolly Shah }
10263436bdeSJolly Shah 
10363436bdeSJolly Shah /**
10463436bdeSJolly Shah  * ipi_mb_open() - Open IPI mailbox.
10563436bdeSJolly Shah  *
10663436bdeSJolly Shah  * @local  - local IPI ID
10763436bdeSJolly Shah  * @remote - remote IPI ID
10863436bdeSJolly Shah  *
10963436bdeSJolly Shah  */
11063436bdeSJolly Shah void ipi_mb_open(uint32_t local, uint32_t remote)
11163436bdeSJolly Shah {
11263436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
11363436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
11463436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
11563436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
11663436bdeSJolly Shah }
11763436bdeSJolly Shah 
11863436bdeSJolly Shah /**
11963436bdeSJolly Shah  * ipi_mb_release() - Open IPI mailbox.
12063436bdeSJolly Shah  *
12163436bdeSJolly Shah  * @local  - local IPI ID
12263436bdeSJolly Shah  * @remote - remote IPI ID
12363436bdeSJolly Shah  *
12463436bdeSJolly Shah  */
12563436bdeSJolly Shah void ipi_mb_release(uint32_t local, uint32_t remote)
12663436bdeSJolly Shah {
12763436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
12863436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
12963436bdeSJolly Shah }
13063436bdeSJolly Shah 
13163436bdeSJolly Shah /**
13263436bdeSJolly Shah  * ipi_mb_enquire_status() - Enquire IPI mailbox status
13363436bdeSJolly Shah  *
13463436bdeSJolly Shah  * @local  - local IPI ID
13563436bdeSJolly Shah  * @remote - remote IPI ID
13663436bdeSJolly Shah  *
13763436bdeSJolly Shah  * return - 0 idle, positive value for pending sending or receiving,
13863436bdeSJolly Shah  *          negative value for errors
13963436bdeSJolly Shah  */
14063436bdeSJolly Shah int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
14163436bdeSJolly Shah {
14263436bdeSJolly Shah 	int ret = 0;
14363436bdeSJolly Shah 	uint32_t status;
14463436bdeSJolly Shah 
14563436bdeSJolly Shah 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
146*eb0d2b17SVenkatesh Yadav Abbarapu 	if (status & IPI_BIT_MASK(remote)) {
14763436bdeSJolly Shah 		ret |= IPI_MB_STATUS_SEND_PENDING;
148*eb0d2b17SVenkatesh Yadav Abbarapu 	}
14963436bdeSJolly Shah 	status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
150*eb0d2b17SVenkatesh Yadav Abbarapu 	if (status & IPI_BIT_MASK(remote)) {
15163436bdeSJolly Shah 		ret |= IPI_MB_STATUS_RECV_PENDING;
152*eb0d2b17SVenkatesh Yadav Abbarapu 	}
15363436bdeSJolly Shah 
15463436bdeSJolly Shah 	return ret;
15563436bdeSJolly Shah }
15663436bdeSJolly Shah 
15763436bdeSJolly Shah /* ipi_mb_notify() - Trigger IPI mailbox notification
15863436bdeSJolly Shah  *
15963436bdeSJolly Shah  * @local - local IPI ID
16063436bdeSJolly Shah  * @remote - remote IPI ID
16163436bdeSJolly Shah  * @is_blocking - if to trigger the notification in blocking mode or not.
16263436bdeSJolly Shah  *
16363436bdeSJolly Shah  * It sets the remote bit in the IPI agent trigger register.
16463436bdeSJolly Shah  *
16563436bdeSJolly Shah  */
16662f9134dSVenkatesh Yadav Abbarapu void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
16763436bdeSJolly Shah {
16863436bdeSJolly Shah 	uint32_t status;
16963436bdeSJolly Shah 
17063436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
17163436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
17263436bdeSJolly Shah 	if (is_blocking) {
17363436bdeSJolly Shah 		do {
17463436bdeSJolly Shah 			status = mmio_read_32(IPI_REG_BASE(local) +
17563436bdeSJolly Shah 					      IPI_OBR_OFFSET);
17663436bdeSJolly Shah 		} while (status & IPI_BIT_MASK(remote));
17763436bdeSJolly Shah 	}
17863436bdeSJolly Shah }
17963436bdeSJolly Shah 
18063436bdeSJolly Shah /* ipi_mb_ack() - Ack IPI mailbox notification from the other end
18163436bdeSJolly Shah  *
18263436bdeSJolly Shah  * @local - local IPI ID
18363436bdeSJolly Shah  * @remote - remote IPI ID
18463436bdeSJolly Shah  *
18563436bdeSJolly Shah  * It will clear the remote bit in the isr register.
18663436bdeSJolly Shah  *
18763436bdeSJolly Shah  */
18863436bdeSJolly Shah void ipi_mb_ack(uint32_t local, uint32_t remote)
18963436bdeSJolly Shah {
19063436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
19163436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
19263436bdeSJolly Shah }
19363436bdeSJolly Shah 
19463436bdeSJolly Shah /* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
19563436bdeSJolly Shah  *
19663436bdeSJolly Shah  * @local - local IPI ID
19763436bdeSJolly Shah  * @remote - remote IPI ID
19863436bdeSJolly Shah  *
19963436bdeSJolly Shah  * It will mask the remote bit in the idr register.
20063436bdeSJolly Shah  *
20163436bdeSJolly Shah  */
20263436bdeSJolly Shah void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
20363436bdeSJolly Shah {
20463436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
20563436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
20663436bdeSJolly Shah }
20763436bdeSJolly Shah 
20863436bdeSJolly Shah /* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
20963436bdeSJolly Shah  *
21063436bdeSJolly Shah  * @local - local IPI ID
21163436bdeSJolly Shah  * @remote - remote IPI ID
21263436bdeSJolly Shah  *
21363436bdeSJolly Shah  * It will mask the remote bit in the idr register.
21463436bdeSJolly Shah  *
21563436bdeSJolly Shah  */
21663436bdeSJolly Shah void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
21763436bdeSJolly Shah {
21863436bdeSJolly Shah 	mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
21963436bdeSJolly Shah 		      IPI_BIT_MASK(remote));
22063436bdeSJolly Shah }
221