Merge pull request #1744 from jollysxilinx/integration
plat: xilinx: code restructure
This commit is contained in:
commit
63b9b5425f
|
@ -1,31 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2018, Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* ZynqMP IPI management enums and defines */
|
||||
/* Xilinx IPI management configuration data and macros */
|
||||
|
||||
#ifndef ZYNQMP_IPI_H
|
||||
#define ZYNQMP_IPI_H
|
||||
#ifndef IPI_H
|
||||
#define IPI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*********************************************************************
|
||||
* IPI agent IDs macros
|
||||
********************************************************************/
|
||||
#define IPI_ID_APU 0U
|
||||
#define IPI_ID_RPU0 1U
|
||||
#define IPI_ID_RPU1 2U
|
||||
#define IPI_ID_PMU0 3U
|
||||
#define IPI_ID_PMU1 4U
|
||||
#define IPI_ID_PMU2 5U
|
||||
#define IPI_ID_PMU3 6U
|
||||
#define IPI_ID_PL0 7U
|
||||
#define IPI_ID_PL1 8U
|
||||
#define IPI_ID_PL2 9U
|
||||
#define IPI_ID_PL3 10U
|
||||
|
||||
/*********************************************************************
|
||||
* IPI mailbox status macros
|
||||
********************************************************************/
|
||||
|
@ -39,10 +24,32 @@
|
|||
#define IPI_MB_CALL_NOTSECURE 0
|
||||
#define IPI_MB_CALL_SECURE 1
|
||||
|
||||
/*********************************************************************
|
||||
* IPI secure check
|
||||
********************************************************************/
|
||||
#define IPI_SECURE_MASK 0x1U
|
||||
#define IPI_IS_SECURE(I) ((ipi_table[(I)].secure_only & \
|
||||
IPI_SECURE_MASK) ? 1 : 0)
|
||||
|
||||
/*********************************************************************
|
||||
* Struct definitions
|
||||
********************************************************************/
|
||||
|
||||
/* structure to maintain IPI configuration information */
|
||||
struct ipi_config {
|
||||
unsigned int ipi_bit_mask;
|
||||
unsigned int ipi_reg_base;
|
||||
unsigned char secure_only;
|
||||
};
|
||||
|
||||
/*********************************************************************
|
||||
* IPI APIs declarations
|
||||
********************************************************************/
|
||||
|
||||
/* Initialize IPI configuration table */
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_table,
|
||||
uint32_t total_ipi);
|
||||
|
||||
/* Validate IPI mailbox access */
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
|
||||
|
||||
|
@ -67,4 +74,4 @@ void ipi_mb_disable_irq(uint32_t local, uint32_t remote);
|
|||
/* Enable IPI mailbox notification interrupt */
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote);
|
||||
|
||||
#endif /* ZYNQMP_IPI_H */
|
||||
#endif /* IPI_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -13,28 +13,17 @@
|
|||
#define PM_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
|
||||
#include "pm_defs.h"
|
||||
|
||||
#define PAYLOAD_ARG_CNT 6U
|
||||
#define PAYLOAD_ARG_SIZE 4U /* size in bytes */
|
||||
|
||||
#define ZYNQMP_TZ_VERSION_MAJOR 1
|
||||
#define ZYNQMP_TZ_VERSION_MINOR 0
|
||||
#define ZYNQMP_TZ_VERSION ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
|
||||
ZYNQMP_TZ_VERSION_MINOR)
|
||||
#include <plat_pm_common.h>
|
||||
|
||||
/**
|
||||
* pm_ipi - struct for capturing IPI-channel specific info
|
||||
* @apu_ipi_id APU IPI agent ID
|
||||
* @pmu_ipi_id PMU Agent ID
|
||||
* @local_ipi_id Local IPI agent ID
|
||||
* @remote_ipi_id Remote IPI Agent ID
|
||||
* @buffer_base base address for payload buffer
|
||||
*/
|
||||
struct pm_ipi {
|
||||
const uint32_t apu_ipi_id;
|
||||
const uint32_t pmu_ipi_id;
|
||||
const uint32_t local_ipi_id;
|
||||
const uint32_t remote_ipi_id;
|
||||
const uintptr_t buffer_base;
|
||||
};
|
||||
|
||||
|
@ -46,12 +35,11 @@ struct pm_ipi {
|
|||
* (in APU all processors share one IPI channel)
|
||||
*/
|
||||
struct pm_proc {
|
||||
const enum pm_node_id node_id;
|
||||
const uint32_t node_id;
|
||||
const unsigned int pwrdn_mask;
|
||||
const struct pm_ipi *ipi;
|
||||
};
|
||||
|
||||
const struct pm_proc *pm_get_proc(unsigned int cpuid);
|
||||
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
|
||||
|
||||
#endif /* PM_COMMON_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -7,8 +7,12 @@
|
|||
#ifndef PM_IPI_H
|
||||
#define PM_IPI_H
|
||||
|
||||
#include <plat_ipi.h>
|
||||
#include "pm_common.h"
|
||||
|
||||
#define IPI_BLOCKING 1
|
||||
#define IPI_NON_BLOCKING 0
|
||||
|
||||
int pm_ipi_init(const struct pm_proc *proc);
|
||||
|
||||
enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
|
||||
|
@ -21,5 +25,6 @@ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc,
|
|||
void pm_ipi_buff_read_callb(unsigned int *value, size_t count);
|
||||
void pm_ipi_irq_enable(const struct pm_proc *proc);
|
||||
void pm_ipi_irq_clear(const struct pm_proc *proc);
|
||||
uint32_t pm_ipi_irq_status(const struct pm_proc *proc);
|
||||
|
||||
#endif /* PM_IPI_H */
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Xilinx IPI agent registers access management
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/runtime_svc.h>
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
/*********************************************************************
|
||||
* Macros definitions
|
||||
********************************************************************/
|
||||
|
||||
/* IPI registers offsets macros */
|
||||
#define IPI_TRIG_OFFSET 0x00U
|
||||
#define IPI_OBR_OFFSET 0x04U
|
||||
#define IPI_ISR_OFFSET 0x10U
|
||||
#define IPI_IMR_OFFSET 0x14U
|
||||
#define IPI_IER_OFFSET 0x18U
|
||||
#define IPI_IDR_OFFSET 0x1CU
|
||||
|
||||
/* IPI register start offset */
|
||||
#define IPI_REG_BASE(I) (ipi_table[(I)].ipi_reg_base)
|
||||
|
||||
/* IPI register bit mask */
|
||||
#define IPI_BIT_MASK(I) (ipi_table[(I)].ipi_bit_mask)
|
||||
|
||||
/* IPI configuration table */
|
||||
const static struct ipi_config *ipi_table;
|
||||
|
||||
/* Total number of IPI */
|
||||
static uint32_t ipi_total;
|
||||
|
||||
/**
|
||||
* ipi_config_init() - Initialize IPI configuration data
|
||||
*
|
||||
* @ipi_config_table - IPI configuration table
|
||||
* @ipi_total - Total number of IPI available
|
||||
*
|
||||
*/
|
||||
void ipi_config_table_init(const struct ipi_config *ipi_config_table,
|
||||
uint32_t total_ipi)
|
||||
{
|
||||
ipi_table = ipi_config_table;
|
||||
ipi_total = total_ipi;
|
||||
}
|
||||
|
||||
/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 1 if within range, 0 if not
|
||||
*/
|
||||
static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (remote >= ipi_total || local >= ipi_total)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_validate() - validate IPI mailbox access
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_secure - indicate if the requester is from secure software
|
||||
*
|
||||
* return - 0 success, negative value for errors
|
||||
*/
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!is_ipi_mb_within_range(local, remote))
|
||||
ret = -EINVAL;
|
||||
else if (IPI_IS_SECURE(local) && !is_secure)
|
||||
ret = -EPERM;
|
||||
else if (IPI_IS_SECURE(remote) && !is_secure)
|
||||
ret = -EPERM;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_open() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_release() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_enquire_status() - Enquire IPI mailbox status
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 0 idle, positive value for pending sending or receiving,
|
||||
* negative value for errors
|
||||
*/
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t status;
|
||||
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_SEND_PENDING;
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_RECV_PENDING;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ipi_mb_notify() - Trigger IPI mailbox notification
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_blocking - if to trigger the notification in blocking mode or not.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
if (is_blocking) {
|
||||
do {
|
||||
status = mmio_read_32(IPI_REG_BASE(local) +
|
||||
IPI_OBR_OFFSET);
|
||||
} while (status & IPI_BIT_MASK(remote));
|
||||
}
|
||||
}
|
||||
|
||||
/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will clear the remote bit in the isr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
|
@ -1,45 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#include <arch_helpers.h>
|
||||
|
||||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "../zynqmp_ipi.h"
|
||||
#include "../zynqmp_private.h"
|
||||
#include "pm_ipi.h"
|
||||
|
||||
/* IPI message buffers */
|
||||
#define IPI_BUFFER_BASEADDR 0xFF990000U
|
||||
|
||||
#define IPI_BUFFER_APU_BASE (IPI_BUFFER_BASEADDR + 0x400U)
|
||||
#define IPI_BUFFER_PMU_BASE (IPI_BUFFER_BASEADDR + 0xE00U)
|
||||
|
||||
#define IPI_BUFFER_TARGET_APU_OFFSET 0x80U
|
||||
#define IPI_BUFFER_TARGET_PMU_OFFSET 0x1C0U
|
||||
|
||||
#define IPI_BUFFER_MAX_WORDS 8
|
||||
|
||||
#define IPI_BUFFER_REQ_OFFSET 0x0U
|
||||
#define IPI_BUFFER_RESP_OFFSET 0x20U
|
||||
|
||||
#define IPI_BLOCKING 1
|
||||
#define IPI_NON_BLOCKING 0
|
||||
|
||||
DEFINE_BAKERY_LOCK(pm_secure_lock);
|
||||
|
||||
const struct pm_ipi apu_ipi = {
|
||||
.apu_ipi_id = IPI_ID_APU,
|
||||
.pmu_ipi_id = IPI_ID_PMU0,
|
||||
.buffer_base = IPI_BUFFER_APU_BASE,
|
||||
};
|
||||
|
||||
/**
|
||||
* pm_ipi_init() - Initialize IPI peripheral for communication with PMU
|
||||
* pm_ipi_init() - Initialize IPI peripheral for communication with
|
||||
* remote processor
|
||||
*
|
||||
* @proc Pointer to the processor who is initiating request
|
||||
* @return On success, the initialization function must return 0.
|
||||
|
@ -51,13 +34,13 @@ const struct pm_ipi apu_ipi = {
|
|||
int pm_ipi_init(const struct pm_proc *proc)
|
||||
{
|
||||
bakery_lock_init(&pm_secure_lock);
|
||||
ipi_mb_open(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
|
||||
ipi_mb_open(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_send_common() - Sends IPI request to the PMU
|
||||
* pm_ipi_send_common() - Sends IPI request to the remote processor
|
||||
* @proc Pointer to the processor who is initiating request
|
||||
* @payload API id and call arguments to be written in IPI buffer
|
||||
*
|
||||
|
@ -72,7 +55,7 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
|
|||
{
|
||||
unsigned int offset = 0;
|
||||
uintptr_t buffer_base = proc->ipi->buffer_base +
|
||||
IPI_BUFFER_TARGET_PMU_OFFSET +
|
||||
IPI_BUFFER_TARGET_REMOTE_OFFSET +
|
||||
IPI_BUFFER_REQ_OFFSET;
|
||||
|
||||
/* Write payload into IPI buffer */
|
||||
|
@ -81,16 +64,16 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc,
|
|||
offset += PAYLOAD_ARG_SIZE;
|
||||
}
|
||||
|
||||
/* Generate IPI to PMU */
|
||||
ipi_mb_notify(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id,
|
||||
/* Generate IPI to remote processor */
|
||||
ipi_mb_notify(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id,
|
||||
is_blocking);
|
||||
|
||||
return PM_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_send_non_blocking() - Sends IPI request to the PMU without blocking
|
||||
* notification
|
||||
* pm_ipi_send_non_blocking() - Sends IPI request to the remote processor
|
||||
* without blocking notification
|
||||
* @proc Pointer to the processor who is initiating request
|
||||
* @payload API id and call arguments to be written in IPI buffer
|
||||
*
|
||||
|
@ -113,7 +96,7 @@ enum pm_ret_status pm_ipi_send_non_blocking(const struct pm_proc *proc,
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_send() - Sends IPI request to the PMU
|
||||
* pm_ipi_send() - Sends IPI request to the remote processor
|
||||
* @proc Pointer to the processor who is initiating request
|
||||
* @payload API id and call arguments to be written in IPI buffer
|
||||
*
|
||||
|
@ -137,7 +120,8 @@ enum pm_ret_status pm_ipi_send(const struct pm_proc *proc,
|
|||
|
||||
|
||||
/**
|
||||
* pm_ipi_buff_read() - Reads IPI response after PMU has handled interrupt
|
||||
* pm_ipi_buff_read() - Reads IPI response after remote processor has handled
|
||||
* interrupt
|
||||
* @proc Pointer to the processor who is waiting and reading response
|
||||
* @value Used to return value from IPI buffer element (optional)
|
||||
* @count Number of values to return in @value
|
||||
|
@ -149,7 +133,7 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
|
|||
{
|
||||
size_t i;
|
||||
uintptr_t buffer_base = proc->ipi->buffer_base +
|
||||
IPI_BUFFER_TARGET_PMU_OFFSET +
|
||||
IPI_BUFFER_TARGET_REMOTE_OFFSET +
|
||||
IPI_BUFFER_RESP_OFFSET;
|
||||
|
||||
/*
|
||||
|
@ -168,7 +152,8 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_buff_read_callb() - Reads IPI response after PMU has handled interrupt
|
||||
* pm_ipi_buff_read_callb() - Reads IPI response after remote processor has
|
||||
* handled interrupt
|
||||
* @value Used to return value from IPI buffer element (optional)
|
||||
* @count Number of values to return in @value
|
||||
*
|
||||
|
@ -177,8 +162,8 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc,
|
|||
void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
uintptr_t buffer_base = IPI_BUFFER_PMU_BASE +
|
||||
IPI_BUFFER_TARGET_APU_OFFSET +
|
||||
uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE +
|
||||
IPI_BUFFER_TARGET_LOCAL_OFFSET +
|
||||
IPI_BUFFER_REQ_OFFSET;
|
||||
|
||||
if (count > IPI_BUFFER_MAX_WORDS)
|
||||
|
@ -191,7 +176,7 @@ void pm_ipi_buff_read_callb(unsigned int *value, size_t count)
|
|||
}
|
||||
|
||||
/**
|
||||
* pm_ipi_send_sync() - Sends IPI request to the PMU
|
||||
* pm_ipi_send_sync() - Sends IPI request to the remote processor
|
||||
* @proc Pointer to the processor who is initiating request
|
||||
* @payload API id and call arguments to be written in IPI buffer
|
||||
* @value Used to return value from IPI buffer element (optional)
|
||||
|
@ -224,10 +209,22 @@ unlock:
|
|||
|
||||
void pm_ipi_irq_enable(const struct pm_proc *proc)
|
||||
{
|
||||
ipi_mb_enable_irq(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
|
||||
ipi_mb_enable_irq(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
|
||||
}
|
||||
|
||||
void pm_ipi_irq_clear(const struct pm_proc *proc)
|
||||
{
|
||||
ipi_mb_ack(proc->ipi->apu_ipi_id, proc->ipi->pmu_ipi_id);
|
||||
ipi_mb_ack(proc->ipi->local_ipi_id, proc->ipi->remote_ipi_id);
|
||||
}
|
||||
|
||||
uint32_t pm_ipi_irq_status(const struct pm_proc *proc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ipi_mb_enquire_status(proc->ipi->local_ipi_id,
|
||||
proc->ipi->remote_ipi_id);
|
||||
if (ret & IPI_MB_STATUS_RECV_PENDING)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
|
@ -11,9 +11,9 @@
|
|||
#include <drivers/generic_delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/xlat_tables/xlat_tables.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "../zynqmp_private.h"
|
||||
#include "pm_api_sys.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
#include <common/debug.h>
|
||||
#include <drivers/console.h>
|
||||
#include <plat_arm.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "zynqmp_private.h"
|
||||
|
||||
#define BL31_END (unsigned long)(&__BL31_END__)
|
||||
|
||||
static entry_point_info_t bl32_image_ep_info;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* ZynqMP IPI management enums and defines */
|
||||
|
||||
#ifndef PLAT_IPI_H
|
||||
#define PLAT_IPI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipi.h>
|
||||
|
||||
/*********************************************************************
|
||||
* IPI agent IDs macros
|
||||
********************************************************************/
|
||||
#define IPI_ID_APU 0U
|
||||
#define IPI_ID_RPU0 1U
|
||||
#define IPI_ID_RPU1 2U
|
||||
#define IPI_ID_PMU0 3U
|
||||
#define IPI_ID_PMU1 4U
|
||||
#define IPI_ID_PMU2 5U
|
||||
#define IPI_ID_PMU3 6U
|
||||
#define IPI_ID_PL0 7U
|
||||
#define IPI_ID_PL1 8U
|
||||
#define IPI_ID_PL2 9U
|
||||
#define IPI_ID_PL3 10U
|
||||
|
||||
/*********************************************************************
|
||||
* IPI message buffers
|
||||
********************************************************************/
|
||||
#define IPI_BUFFER_BASEADDR 0xFF990000U
|
||||
|
||||
#define IPI_BUFFER_APU_BASE (IPI_BUFFER_BASEADDR + 0x400U)
|
||||
#define IPI_BUFFER_PMU_BASE (IPI_BUFFER_BASEADDR + 0xE00U)
|
||||
|
||||
#define IPI_BUFFER_LOCAL_BASE IPI_BUFFER_APU_BASE
|
||||
#define IPI_BUFFER_REMOTE_BASE IPI_BUFFER_PMU_BASE
|
||||
|
||||
#define IPI_BUFFER_TARGET_LOCAL_OFFSET 0x80U
|
||||
#define IPI_BUFFER_TARGET_REMOTE_OFFSET 0x1C0U
|
||||
|
||||
#define IPI_BUFFER_MAX_WORDS 8
|
||||
|
||||
#define IPI_BUFFER_REQ_OFFSET 0x0U
|
||||
#define IPI_BUFFER_RESP_OFFSET 0x20U
|
||||
|
||||
/*********************************************************************
|
||||
* Platform specific IPI API declarations
|
||||
********************************************************************/
|
||||
|
||||
/* Configure IPI table for zynqmp */
|
||||
void zynqmp_ipi_config_table_init(void);
|
||||
|
||||
#endif /* PLAT_IPI_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include <arm_macros.S>
|
||||
#include <cci_macros.S>
|
||||
#include "../zynqmp_def.h"
|
||||
#include "zynqmp_def.h"
|
||||
|
||||
/* ---------------------------------------------
|
||||
* The below required platform porting macro
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains platform specific definitions of commonly used macros data types
|
||||
* for PU Power Management. This file should be common for all PU's.
|
||||
*/
|
||||
|
||||
#ifndef PLAT_PM_COMMON_H
|
||||
#define PLAT_PM_COMMON_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <common/debug.h>
|
||||
#include "pm_defs.h"
|
||||
|
||||
#define PAYLOAD_ARG_CNT 6U
|
||||
#define PAYLOAD_ARG_SIZE 4U /* size in bytes */
|
||||
|
||||
#define ZYNQMP_TZ_VERSION_MAJOR 1
|
||||
#define ZYNQMP_TZ_VERSION_MINOR 0
|
||||
#define ZYNQMP_TZ_VERSION ((ZYNQMP_TZ_VERSION_MAJOR << 16) | \
|
||||
ZYNQMP_TZ_VERSION_MINOR)
|
||||
#endif /* _PLAT_PM_COMMON_H_ */
|
|
@ -4,8 +4,8 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ZYNQMP_PRIVATE_H
|
||||
#define ZYNQMP_PRIVATE_H
|
||||
#ifndef PLAT_PRIVATE_H
|
||||
#define PLAT_PRIVATE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -39,4 +39,4 @@ int request_intr_type_el3(uint32_t, interrupt_type_handler_t);
|
|||
enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info,
|
||||
entry_point_info_t *bl33_image_ep_info);
|
||||
|
||||
#endif /* ZYNQMP_PRIVATE_H */
|
||||
#endif /* PLAT_PRIVATE_H */
|
|
@ -12,7 +12,7 @@
|
|||
#include <drivers/arm/gic_common.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
#include "../zynqmp_def.h"
|
||||
#include "zynqmp_def.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Generic platform constants
|
||||
|
|
|
@ -60,8 +60,10 @@
|
|||
#define CRL_APB_BOOT_PIN_MASK (U(0xf0f) << 0)
|
||||
#define CRL_APB_BOOT_DRIVE_PIN_1_SHIFT U(9)
|
||||
#define CRL_APB_BOOT_ENABLE_PIN_1_SHIFT U(1)
|
||||
#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
|
||||
#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
|
||||
#define CRL_APB_BOOT_ENABLE_PIN_1 (U(0x1) << \
|
||||
CRL_APB_BOOT_ENABLE_PIN_1_SHIFT)
|
||||
#define CRL_APB_BOOT_DRIVE_PIN_1 (U(0x1) << \
|
||||
CRL_APB_BOOT_DRIVE_PIN_1_SHIFT)
|
||||
#define ZYNQMP_BOOTMODE_JTAG U(0)
|
||||
#define ZYNQMP_ULPI_RESET_VAL_HIGH (CRL_APB_BOOT_ENABLE_PIN_1 | \
|
||||
CRL_APB_BOOT_DRIVE_PIN_1)
|
||||
|
@ -137,7 +139,7 @@
|
|||
#define ZYNQMP_UART0_BASE 0xFF000000
|
||||
#define ZYNQMP_UART1_BASE 0xFF010000
|
||||
|
||||
#if ZYNQMP_CONSOLE_IS(cadence)
|
||||
#if ZYNQMP_CONSOLE_IS(cadence) || ZYNQMP_CONSOLE_IS(dcc)
|
||||
# define ZYNQMP_UART_BASE ZYNQMP_UART0_BASE
|
||||
#elif ZYNQMP_CONSOLE_IS(cadence1)
|
||||
# define ZYNQMP_UART_BASE ZYNQMP_UART1_BASE
|
||||
|
@ -167,22 +169,27 @@
|
|||
#define ZYNQMP_CSU_IDCODE_OFFSET 0x40
|
||||
|
||||
#define ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT 0
|
||||
#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFF << ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_XILINX_ID_MASK (0xFFF << \
|
||||
ZYNQMP_CSU_IDCODE_XILINX_ID_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_XILINX_ID 0x093
|
||||
|
||||
#define ZYNQMP_CSU_IDCODE_SVD_SHIFT 12
|
||||
#define ZYNQMP_CSU_IDCODE_SVD_MASK (0x7 << \
|
||||
ZYNQMP_CSU_IDCODE_SVD_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT 15
|
||||
#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xF << ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK (0xF << \
|
||||
ZYNQMP_CSU_IDCODE_DEVICE_CODE_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT 19
|
||||
#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3 << ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_SUB_FAMILY_MASK (0x3 << \
|
||||
ZYNQMP_CSU_IDCODE_SUB_FAMILY_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_FAMILY_SHIFT 21
|
||||
#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7F << ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_FAMILY_MASK (0x7F << \
|
||||
ZYNQMP_CSU_IDCODE_FAMILY_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_FAMILY 0x23
|
||||
|
||||
#define ZYNQMP_CSU_IDCODE_REVISION_SHIFT 28
|
||||
#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xF << ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_REVISION_MASK (0xF << \
|
||||
ZYNQMP_CSU_IDCODE_REVISION_SHIFT)
|
||||
#define ZYNQMP_CSU_IDCODE_REVISION 0
|
||||
|
||||
#define ZYNQMP_CSU_VERSION_OFFSET 0x44
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -16,9 +16,11 @@
|
|||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
#include "ipi_mailbox_svc.h"
|
||||
#include "../zynqmp_ipi.h"
|
||||
#include "../zynqmp_private.h"
|
||||
#include "../../../services/spd/trusty/smcall.h"
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
#include <drivers/arm/gicv2.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <lib/psci/psci.h>
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include <plat_arm.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "zynqmp_private.h"
|
||||
|
||||
uintptr_t zynqmp_sec_entry;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -9,9 +9,9 @@
|
|||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
#include "zynqmp_def.h"
|
||||
#include "zynqmp_private.h"
|
||||
|
||||
/*
|
||||
* ATFHandoffParams
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <plat_private.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#include "zynqmp_private.h"
|
||||
|
||||
int plat_core_pos_by_mpidr(u_register_t mpidr)
|
||||
{
|
||||
if (mpidr & MPIDR_CLUSTER_MASK)
|
||||
|
|
|
@ -47,6 +47,7 @@ endif
|
|||
|
||||
PLAT_INCLUDES := -Iinclude/plat/arm/common/ \
|
||||
-Iinclude/plat/arm/common/aarch64/ \
|
||||
-Iplat/xilinx/common/include/ \
|
||||
-Iplat/xilinx/zynqmp/include/ \
|
||||
-Iplat/xilinx/zynqmp/pm_service/ \
|
||||
-Iplat/xilinx/zynqmp/ipi_mailbox_service/
|
||||
|
@ -64,6 +65,7 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
|
|||
plat/arm/common/arm_common.c \
|
||||
plat/arm/common/arm_gicv2.c \
|
||||
plat/common/plat_gicv2.c \
|
||||
plat/xilinx/common/ipi.c \
|
||||
plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S \
|
||||
plat/xilinx/zynqmp/aarch64/zynqmp_common.c
|
||||
|
||||
|
@ -71,6 +73,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
|
|||
lib/cpus/aarch64/aem_generic.S \
|
||||
lib/cpus/aarch64/cortex_a53.S \
|
||||
plat/common/plat_psci_common.c \
|
||||
plat/xilinx/common/pm_service/pm_ipi.c \
|
||||
plat/xilinx/zynqmp/bl31_zynqmp_setup.c \
|
||||
plat/xilinx/zynqmp/plat_psci.c \
|
||||
plat/xilinx/zynqmp/plat_zynqmp.c \
|
||||
|
@ -83,6 +86,5 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
|
|||
plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_api_clock.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_ipi.c \
|
||||
plat/xilinx/zynqmp/pm_service/pm_client.c \
|
||||
plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <drivers/delay_timer.h>
|
||||
#include <lib/mmio.h>
|
||||
#include <plat/common/platform.h>
|
||||
#include <zynqmp_def.h>
|
||||
|
||||
#include "pm_api_clock.h"
|
||||
#include "pm_api_ioctl.h"
|
||||
|
@ -19,7 +20,6 @@
|
|||
#include "pm_client.h"
|
||||
#include "pm_common.h"
|
||||
#include "pm_ipi.h"
|
||||
#include "../zynqmp_def.h"
|
||||
|
||||
/**
|
||||
* pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -19,7 +19,8 @@
|
|||
#include <lib/mmio.h>
|
||||
#include <lib/utils.h>
|
||||
|
||||
#include "../zynqmp_def.h"
|
||||
#include <plat_ipi.h>
|
||||
#include <zynqmp_def.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_ipi.h"
|
||||
|
@ -35,6 +36,12 @@ DEFINE_BAKERY_LOCK(pm_client_secure_lock);
|
|||
|
||||
extern const struct pm_ipi apu_ipi;
|
||||
|
||||
const struct pm_ipi apu_ipi = {
|
||||
.local_ipi_id = IPI_ID_APU,
|
||||
.remote_ipi_id = IPI_ID_PMU0,
|
||||
.buffer_base = IPI_BUFFER_APU_BASE,
|
||||
};
|
||||
|
||||
static uint32_t suspend_mode = PM_SUSPEND_MODE_STD;
|
||||
|
||||
/* Order in pm_procs_all array must match cpu ids */
|
||||
|
|
|
@ -21,6 +21,7 @@ void pm_client_abort_suspend(void);
|
|||
void pm_client_wakeup(const struct pm_proc *proc);
|
||||
enum pm_ret_status set_ocm_retention(void);
|
||||
enum pm_ret_status pm_set_suspend_mode(uint32_t mode);
|
||||
const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid);
|
||||
|
||||
/* Global variables to be set in pm_client.c */
|
||||
extern const struct pm_proc *primary_proc;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <plat/common/platform.h>
|
||||
#endif
|
||||
|
||||
#include "../zynqmp_private.h"
|
||||
#include <plat_private.h>
|
||||
#include "pm_api_sys.h"
|
||||
#include "pm_client.h"
|
||||
#include "pm_ipi.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -9,9 +9,9 @@
|
|||
#include <common/runtime_svc.h>
|
||||
#include <tools_share/uuid.h>
|
||||
|
||||
#include <plat_ipi.h>
|
||||
#include "ipi_mailbox_svc.h"
|
||||
#include "pm_svc_main.h"
|
||||
#include "zynqmp_ipi.h"
|
||||
|
||||
/* SMC function IDs for SiP Service queries */
|
||||
#define ZYNQMP_SIP_SVC_CALL_COUNT 0x8200ff00
|
||||
|
@ -41,6 +41,9 @@ DEFINE_SVC_UUID2(zynqmp_sip_uuid,
|
|||
*/
|
||||
static int32_t sip_svc_setup(void)
|
||||
{
|
||||
/* Configure IPI data for ZynqMP */
|
||||
zynqmp_ipi_config_table_init();
|
||||
|
||||
/* PM implementation as SiP Service */
|
||||
pm_setup();
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
#include <drivers/console.h>
|
||||
|
||||
#include <plat_arm.h>
|
||||
#include <plat_private.h>
|
||||
#include <platform_tsp.h>
|
||||
|
||||
#include "../zynqmp_private.h"
|
||||
|
||||
#define BL32_END (unsigned long)(&__BL32_END__)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -16,48 +16,12 @@
|
|||
#include <lib/bakery_lock.h>
|
||||
#include <lib/mmio.h>
|
||||
|
||||
#include "zynqmp_ipi.h"
|
||||
#include "../zynqmp_private.h"
|
||||
|
||||
/*********************************************************************
|
||||
* Macros definitions
|
||||
********************************************************************/
|
||||
|
||||
/* IPI registers base address */
|
||||
#define IPI_REGS_BASE 0xFF300000U
|
||||
|
||||
/* IPI registers offsets macros */
|
||||
#define IPI_TRIG_OFFSET 0x00U
|
||||
#define IPI_OBR_OFFSET 0x04U
|
||||
#define IPI_ISR_OFFSET 0x10U
|
||||
#define IPI_IMR_OFFSET 0x14U
|
||||
#define IPI_IER_OFFSET 0x18U
|
||||
#define IPI_IDR_OFFSET 0x1CU
|
||||
|
||||
/* IPI register start offset */
|
||||
#define IPI_REG_BASE(I) (zynqmp_ipi_table[(I)].ipi_reg_base)
|
||||
|
||||
/* IPI register bit mask */
|
||||
#define IPI_BIT_MASK(I) (zynqmp_ipi_table[(I)].ipi_bit_mask)
|
||||
|
||||
/* IPI secure check */
|
||||
#define IPI_SECURE_MASK 0x1U
|
||||
#define IPI_IS_SECURE(I) ((zynqmp_ipi_table[(I)].secure_only & \
|
||||
IPI_SECURE_MASK) ? 1 : 0)
|
||||
|
||||
/*********************************************************************
|
||||
* Struct definitions
|
||||
********************************************************************/
|
||||
|
||||
/* structure to maintain IPI configuration information */
|
||||
struct zynqmp_ipi_config {
|
||||
unsigned int ipi_bit_mask;
|
||||
unsigned int ipi_reg_base;
|
||||
unsigned char secure_only;
|
||||
};
|
||||
#include <ipi.h>
|
||||
#include <plat_ipi.h>
|
||||
#include <plat_private.h>
|
||||
|
||||
/* Zynqmp ipi configuration table */
|
||||
const static struct zynqmp_ipi_config zynqmp_ipi_table[] = {
|
||||
const static struct ipi_config zynqmp_ipi_table[] = {
|
||||
/* APU IPI */
|
||||
{
|
||||
.ipi_bit_mask = 0x1,
|
||||
|
@ -126,160 +90,11 @@ const static struct zynqmp_ipi_config zynqmp_ipi_table[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* is_ipi_mb_within_range() - verify if IPI mailbox is within range
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 1 if within range, 0 if not
|
||||
*/
|
||||
static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 1;
|
||||
uint32_t ipi_total = ARRAY_SIZE(zynqmp_ipi_table);
|
||||
|
||||
if (remote >= ipi_total || local >= ipi_total)
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_validate() - validate IPI mailbox access
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_secure - indicate if the requester is from secure software
|
||||
*
|
||||
* return - 0 success, negative value for errors
|
||||
*/
|
||||
int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!is_ipi_mb_within_range(local, remote))
|
||||
ret = -EINVAL;
|
||||
else if (IPI_IS_SECURE(local) && !is_secure)
|
||||
ret = -EPERM;
|
||||
else if (IPI_IS_SECURE(remote) && !is_secure)
|
||||
ret = -EPERM;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_open() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data
|
||||
*
|
||||
*/
|
||||
void ipi_mb_open(uint32_t local, uint32_t remote)
|
||||
void zynqmp_ipi_config_table_init(void)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_release() - Open IPI mailbox.
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
*/
|
||||
void ipi_mb_release(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/**
|
||||
* ipi_mb_enquire_status() - Enquire IPI mailbox status
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* return - 0 idle, positive value for pending sending or receiving,
|
||||
* negative value for errors
|
||||
*/
|
||||
int ipi_mb_enquire_status(uint32_t local, uint32_t remote)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t status;
|
||||
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_OBR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_SEND_PENDING;
|
||||
status = mmio_read_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET);
|
||||
if (status & IPI_BIT_MASK(remote))
|
||||
ret |= IPI_MB_STATUS_RECV_PENDING;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ipi_mb_notify() - Trigger IPI mailbox notification
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
* @is_blocking - if to trigger the notification in blocking mode or not.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_TRIG_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
if (is_blocking) {
|
||||
do {
|
||||
status = mmio_read_32(IPI_REG_BASE(local) +
|
||||
IPI_OBR_OFFSET);
|
||||
} while (status & IPI_BIT_MASK(remote));
|
||||
}
|
||||
}
|
||||
|
||||
/* ipi_mb_ack() - Ack IPI mailbox notification from the other end
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will clear the remote bit in the isr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_ack(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_ISR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_disable_irq() - Disable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_disable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IDR_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
}
|
||||
|
||||
/* ipi_mb_enable_irq() - Enable IPI mailbox notification interrupt
|
||||
*
|
||||
* @local - local IPI ID
|
||||
* @remote - remote IPI ID
|
||||
*
|
||||
* It will mask the remote bit in the idr register.
|
||||
*
|
||||
*/
|
||||
void ipi_mb_enable_irq(uint32_t local, uint32_t remote)
|
||||
{
|
||||
mmio_write_32(IPI_REG_BASE(local) + IPI_IER_OFFSET,
|
||||
IPI_BIT_MASK(remote));
|
||||
ipi_config_table_init(zynqmp_ipi_table, ARRAY_SIZE(zynqmp_ipi_table));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue