diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.h b/plat/xilinx/common/include/ipi.h similarity index 69% rename from plat/xilinx/zynqmp/zynqmp_ipi.h rename to plat/xilinx/common/include/ipi.h index b9b40dde39caab7131302d38630b41bf0c45ed1b..483902e0ead786cc34e2362763b0b05e426d0f52 100644 --- a/plat/xilinx/zynqmp/zynqmp_ipi.h +++ b/plat/xilinx/common/include/ipi.h @@ -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 */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_common.h b/plat/xilinx/common/include/pm_common.h similarity index 60% rename from plat/xilinx/zynqmp/pm_service/pm_common.h rename to plat/xilinx/common/include/pm_common.h index 94e0568f6059c2617fbd1f300cc3068a88313c35..c0a51f0294adf3461f79eef4fb2e979b0292be79 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_common.h +++ b/plat/xilinx/common/include/pm_common.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 */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h similarity index 79% rename from plat/xilinx/zynqmp/pm_service/pm_ipi.h rename to plat/xilinx/common/include/pm_ipi.h index 650de5220535a04f32908714937754fa0eef3504..16db5c548217bfe5c1d70e6379a919b811ab103a 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_ipi.h +++ b/plat/xilinx/common/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 */ @@ -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 */ diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c new file mode 100644 index 0000000000000000000000000000000000000000..0b8020b4016bae584a3c6b61f6398beb38483509 --- /dev/null +++ b/plat/xilinx/common/ipi.c @@ -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)); +} diff --git a/plat/xilinx/zynqmp/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c similarity index 75% rename from plat/xilinx/zynqmp/pm_service/pm_ipi.c rename to plat/xilinx/common/pm_service/pm_ipi.c index b3d833dfe294b215a030242aea5988d7121c38ce..034cd5bc8ce46a0e98ced735fb140d6a188177cd 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -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; } diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c index 23c02e068bfb8c2459ea1bdbd6bf8a24351e44c3..8ff6c436046ff86160127576ff78aadc0b21e3af 100644 --- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c +++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c @@ -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" /* diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 01cd781ff64ee13c1079bd35ff00df57ba18f66e..8ecd6d7afbe567fd36917c26a4cec0a8be071e8d 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -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; diff --git a/plat/xilinx/zynqmp/include/plat_ipi.h b/plat/xilinx/zynqmp/include/plat_ipi.h new file mode 100644 index 0000000000000000000000000000000000000000..bccd2f1944868a4e2cfd2933a0eb573b6fd11d99 --- /dev/null +++ b/plat/xilinx/zynqmp/include/plat_ipi.h @@ -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 */ diff --git a/plat/xilinx/zynqmp/include/plat_macros.S b/plat/xilinx/zynqmp/include/plat_macros.S index e54cfc49866651ec3ab7e0238ea5adecdceabeb8..bf1ff82b37e45b414536ed52c9abcc3657b53efd 100644 --- a/plat/xilinx/zynqmp/include/plat_macros.S +++ b/plat/xilinx/zynqmp/include/plat_macros.S @@ -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 diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h new file mode 100644 index 0000000000000000000000000000000000000000..1b371cc367a903cc968d35ef8983c1188e63899e --- /dev/null +++ b/plat/xilinx/zynqmp/include/plat_pm_common.h @@ -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_ */ diff --git a/plat/xilinx/zynqmp/zynqmp_private.h b/plat/xilinx/zynqmp/include/plat_private.h similarity index 91% rename from plat/xilinx/zynqmp/zynqmp_private.h rename to plat/xilinx/zynqmp/include/plat_private.h index a8ebcebeeb219ec7c6f2c473484d4aa9f5ae9c56..99d0bc673278ee095f3353b115f53d3b872cbe24 100644 --- a/plat/xilinx/zynqmp/zynqmp_private.h +++ b/plat/xilinx/zynqmp/include/plat_private.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 */ diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h index e3c9fcc1720740740e707e26a1f86bd52fb65c0c..fb1041137fde7861ed841912ce621995abf903b8 100644 --- a/plat/xilinx/zynqmp/include/platform_def.h +++ b/plat/xilinx/zynqmp/include/platform_def.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 diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h similarity index 94% rename from plat/xilinx/zynqmp/zynqmp_def.h rename to plat/xilinx/zynqmp/include/zynqmp_def.h index f75530e7fa61aeb6b9bcd70a39394d324cbd9b03..8648b9ab2c32df0610b39f2efe1c5257c7e1731d 100644 --- a/plat/xilinx/zynqmp/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -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 diff --git a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c index 11f382a05392b1b68725e2c98faaf78cab175268..c499d78e91ad44eee0afb242b6fc4514dc784876 100644 --- a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c +++ b/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c @@ -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" /********************************************************************* diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c index 4183979a2c4af7676918227ff2e58664b52e6d63..8522d3e6c1c2217f5a0a4c4353c563fb47e2a1a1 100644 --- a/plat/xilinx/zynqmp/plat_psci.c +++ b/plat/xilinx/zynqmp/plat_psci.c @@ -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; diff --git a/plat/xilinx/zynqmp/plat_startup.c b/plat/xilinx/zynqmp/plat_startup.c index 03f0e3d82d72175181433a8cf1aa9eebc453353f..cd2c3bac6e6816702f522b7a4250aaf75176639a 100644 --- a/plat/xilinx/zynqmp/plat_startup.c +++ b/plat/xilinx/zynqmp/plat_startup.c @@ -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 diff --git a/plat/xilinx/zynqmp/plat_zynqmp.c b/plat/xilinx/zynqmp/plat_zynqmp.c index ad18aafc305988298701c3ce2d91df873dda4068..906ce1b7feb3a73ad8c5f3b316fab9b18027bfd7 100644 --- a/plat/xilinx/zynqmp/plat_zynqmp.c +++ b/plat/xilinx/zynqmp/plat_zynqmp.c @@ -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) diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index 35c8983cdb1928a0a3629f1cfd2ad905b2f7d74f..d147916f7cf43c7147c3eacee5961fc549ab43e0 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -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 diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index d3f1fbfec1c6329de23b48fc0746aa93a6368ee8..44acb4bd5892abf083d2610b799652e679e3c211 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.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 diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.c b/plat/xilinx/zynqmp/pm_service/pm_client.c index bebb74ce7fb96963de4ae8430a2835e6f5e2b7ad..163e8916f2fa30019a56c137a61de48856f25653 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_client.c +++ b/plat/xilinx/zynqmp/pm_service/pm_client.c @@ -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 */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.h b/plat/xilinx/zynqmp/pm_service/pm_client.h index 0a34a07578500b9303593e379bb6f735274d9675..adbb76f9b19fd42ce23722a0602f56fd15c01ece 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_client.h +++ b/plat/xilinx/zynqmp/pm_service/pm_client.h @@ -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; diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index 0b8fc23529a5d083d804a29f8ec62ba1412eaf62..faa2827450bb44b2e3abd2b6fcfc6205dffc4e1f 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -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" diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c index 8d23a014c553f4800035d95013e0da44e6851d4d..edb81f5c3b333063c75ff8169d2e06575f1bf54b 100644 --- a/plat/xilinx/zynqmp/sip_svc_setup.c +++ b/plat/xilinx/zynqmp/sip_svc_setup.c @@ -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(); diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c index 25359f91aa4ce55e735848859a17efec41da0c0f..97718d6566b452be5e73e2ed34436c04b3161044 100644 --- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c +++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c @@ -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__) diff --git a/plat/xilinx/zynqmp/zynqmp_ipi.c b/plat/xilinx/zynqmp/zynqmp_ipi.c index 54b18380def0158e03c6a416cd1a3a711caa1681..f57369fc3a70c499a6c256e405d54c6a8bd55603 100644 --- a/plat/xilinx/zynqmp/zynqmp_ipi.c +++ b/plat/xilinx/zynqmp/zynqmp_ipi.c @@ -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 - * - */ -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. + * zynqmp_ipi_config_table_init() - Initialize ZynqMP IPI configuration data * */ -void ipi_mb_enable_irq(uint32_t local, uint32_t remote) +void zynqmp_ipi_config_table_init(void) { - 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)); }