Commit 0fb73638 authored by Madhukar Pappireddy's avatar Madhukar Pappireddy Committed by TrustedFirmware Code Review
Browse files

Merge "plat: xilinx: Add timeout while waiting for IPI Ack" into integration

parents 706058c2 4d9b9b23
...@@ -63,7 +63,7 @@ void ipi_mb_release(uint32_t local, uint32_t remote); ...@@ -63,7 +63,7 @@ void ipi_mb_release(uint32_t local, uint32_t remote);
int ipi_mb_enquire_status(uint32_t local, uint32_t remote); int ipi_mb_enquire_status(uint32_t local, uint32_t remote);
/* Trigger notification on the IPI mailbox */ /* Trigger notification on the IPI mailbox */
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking); int ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking);
/* Ack IPI mailbox notification */ /* Ack IPI mailbox notification */
void ipi_mb_ack(uint32_t local, uint32_t remote); void ipi_mb_ack(uint32_t local, uint32_t remote);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <common/debug.h> #include <common/debug.h>
#include <common/runtime_svc.h> #include <common/runtime_svc.h>
#include <drivers/delay_timer.h>
#include <lib/bakery_lock.h> #include <lib/bakery_lock.h>
#include <lib/mmio.h> #include <lib/mmio.h>
...@@ -38,6 +39,9 @@ ...@@ -38,6 +39,9 @@
/* IPI register bit mask */ /* IPI register bit mask */
#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask) #define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
/* IPI Timeout */
#define TIMEOUT_COUNT_US U(0x4000)
/* IPI configuration table */ /* IPI configuration table */
const static struct ipi_config *ipi_table; const static struct ipi_config *ipi_table;
...@@ -156,21 +160,30 @@ int ipi_mb_enquire_status(uint32_t local, uint32_t remote) ...@@ -156,21 +160,30 @@ int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
* @remote - remote IPI ID * @remote - remote IPI ID
* @is_blocking - if to trigger the notification in blocking mode or not. * @is_blocking - if to trigger the notification in blocking mode or not.
* *
* return - 0 - Success or Error incase of timeout
* It sets the remote bit in the IPI agent trigger register. * It sets the remote bit in the IPI agent trigger register.
* *
*/ */
void ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking) int ipi_mb_notify(uint32_t local, uint32_t remote, uint32_t is_blocking)
{ {
uint32_t status; uint32_t status;
const unsigned int timeout_count = TIMEOUT_COUNT_US;
uint64_t timeout;
mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET, mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
IPI_BIT_MASK(remote)); IPI_BIT_MASK(remote));
if (is_blocking) { if (is_blocking) {
timeout = timeout_init_us(timeout_count);
do { do {
status = mmio_read_32(IPI_REG_BASE(local) + status = mmio_read_32(IPI_REG_BASE(local) +
IPI_OBR_OFFSET); IPI_OBR_OFFSET);
if (timeout_elapsed(timeout)) {
return -ETIMEDOUT;
}
} while (status & IPI_BIT_MASK(remote)); } while (status & IPI_BIT_MASK(remote));
} }
return 0;
} }
/* ipi_mb_ack() - Ack IPI mailbox notification from the other end /* ipi_mb_ack() - Ack IPI mailbox notification from the other end
......
...@@ -107,8 +107,8 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, ...@@ -107,8 +107,8 @@ uint64_t ipi_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
uint32_t is_blocking; uint32_t is_blocking;
is_blocking = (x3 & IPI_SMC_NOTIFY_BLOCK_MASK) ? 1 : 0; is_blocking = (x3 & IPI_SMC_NOTIFY_BLOCK_MASK) ? 1 : 0;
ipi_mb_notify(ipi_local_id, ipi_remote_id, is_blocking); ret = ipi_mb_notify(ipi_local_id, ipi_remote_id, is_blocking);
SMC_RET1(handle, 0); SMC_RET1(handle, ret);
} }
case IPI_MAILBOX_ACK: case IPI_MAILBOX_ACK:
{ {
......
...@@ -55,6 +55,7 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc, ...@@ -55,6 +55,7 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
uint32_t payload[PAYLOAD_ARG_CNT], uint32_t payload[PAYLOAD_ARG_CNT],
uint32_t is_blocking) uint32_t is_blocking)
{ {
int status;
unsigned int offset = 0; unsigned int offset = 0;
uintptr_t buffer_base = proc->ipi->buffer_base + uintptr_t buffer_base = proc->ipi->buffer_base +
IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_TARGET_REMOTE_OFFSET +
...@@ -70,10 +71,13 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc, ...@@ -70,10 +71,13 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
} }
/* Generate IPI to remote processor */ /* Generate IPI to remote processor */
ipi_mb_notify(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id, status = ipi_mb_notify(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id,
is_blocking); is_blocking);
if (status == 0) {
return PM_RET_SUCCESS; return PM_RET_SUCCESS;
}
return PM_RET_ERROR_TIMEOUT;
} }
/** /**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment