Merge "plat: xilinx: Add timeout while waiting for IPI Ack" into integration
This commit is contained in:
commit
0fb7363899
|
@ -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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
/* 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)
|
||||||
* @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,
|
||||||
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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue