From 660b0c77d81603c7911a3e5c024d646a801cd0ac Mon Sep 17 00:00:00 2001 From: Ibai Erkiaga Date: Fri, 27 Sep 2019 11:36:56 +0100 Subject: mailbox: zynqmp: ipi mailbox driver ZynqMP mailbox driver implementing IPI communication with PMU. This would allow U-Boot SPL to communicate with PMUFW to request privileged operations. Signed-off-by: Ibai Erkiaga Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mach-zynqmp') diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 915badc6fb..f25d414dcb 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -54,6 +54,11 @@ enum { TCM_SPLIT, }; +struct zynqmp_ipi_msg { + size_t len; + u32 *buf; +}; + int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); unsigned int zynqmp_get_silicon_version(void); -- cgit From 17eb88e4e59111199279c5f53bbdb2b34fcedadd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 27 Sep 2019 11:36:59 +0100 Subject: arm64: zynqmp: Cleanup PM SMC macro composition Cleanup PM ID handling by using enum values. Signed-off-by: Michal Simek Signed-off-by: Ibai Erkiaga Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-zynqmp') diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index f25d414dcb..573c4ffcee 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -10,7 +10,8 @@ #define PAYLOAD_ARG_CNT 5 #define ZYNQMP_CSU_SILICON_VER_MASK 0xF -#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD 0xC200002D +#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD \ + (PM_SIP_SVC + PM_SECURE_IMAGE) #define KEY_PTR_LEN 32 #define ZYNQMP_FPGA_BIT_AUTH_DDR 1 @@ -21,7 +22,8 @@ #define ZYNQMP_FPGA_AUTH_DDR 1 -#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001 +#define ZYNQMP_SIP_SVC_GET_API_VERSION \ + (PM_SIP_SVC + PM_GET_API_VERSION) #define ZYNQMP_PM_VERSION_MAJOR 1 #define ZYNQMP_PM_VERSION_MINOR 0 @@ -36,6 +38,13 @@ #define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) +#define PM_SIP_SVC 0xc2000000 + +enum pm_api_id { + PM_GET_API_VERSION = 1, + PM_SECURE_IMAGE = 45, +}; + enum { IDCODE, VERSION, -- cgit From 009ab7b93abac255a3dbfa76a9d7ebe69d846e98 Mon Sep 17 00:00:00 2001 From: Ibai Erkiaga Date: Fri, 27 Sep 2019 11:37:01 +0100 Subject: firmware: zynqmp: create firmware header New firmware header to place firmware specific macro and function declarations. The patch also moves the macros defining PM operations as well as some helper macros. Signed-off-by: Ibai Erkiaga Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/cpu.c | 1 + arch/arm/mach-zynqmp/include/mach/sys_proto.h | 25 ------------------------- 2 files changed, 1 insertion(+), 25 deletions(-) (limited to 'arch/arm/mach-zynqmp') diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c index 5ef1a52862..f28b964a15 100644 --- a/arch/arm/mach-zynqmp/cpu.c +++ b/arch/arm/mach-zynqmp/cpu.c @@ -9,6 +9,7 @@ #include #include #include +#include #define ZYNQ_SILICON_VER_MASK 0xF000 #define ZYNQ_SILICON_VER_SHIFT 12 diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 573c4ffcee..6589744454 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -10,8 +10,6 @@ #define PAYLOAD_ARG_CNT 5 #define ZYNQMP_CSU_SILICON_VER_MASK 0xF -#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD \ - (PM_SIP_SVC + PM_SECURE_IMAGE) #define KEY_PTR_LEN 32 #define ZYNQMP_FPGA_BIT_AUTH_DDR 1 @@ -22,29 +20,6 @@ #define ZYNQMP_FPGA_AUTH_DDR 1 -#define ZYNQMP_SIP_SVC_GET_API_VERSION \ - (PM_SIP_SVC + PM_GET_API_VERSION) - -#define ZYNQMP_PM_VERSION_MAJOR 1 -#define ZYNQMP_PM_VERSION_MINOR 0 -#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 -#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF - -#define ZYNQMP_PM_VERSION \ - ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ - ZYNQMP_PM_VERSION_MINOR) - -#define ZYNQMP_PM_VERSION_INVALID ~0 - -#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) - -#define PM_SIP_SVC 0xc2000000 - -enum pm_api_id { - PM_GET_API_VERSION = 1, - PM_SECURE_IMAGE = 45, -}; - enum { IDCODE, VERSION, -- cgit From 283d81acba00828366bbb4a38f62b035ba36d003 Mon Sep 17 00:00:00 2001 From: Ibai Erkiaga Date: Fri, 27 Sep 2019 11:37:03 +0100 Subject: arm64: zynqmp: remove old fw version function Removes the old function to get the firmware version. Signed-off-by: Ibai Erkiaga Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/cpu.c | 23 ----------------------- arch/arm/mach-zynqmp/include/mach/sys_proto.h | 1 - 2 files changed, 24 deletions(-) (limited to 'arch/arm/mach-zynqmp') diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c index f28b964a15..bb21cbcadf 100644 --- a/arch/arm/mach-zynqmp/cpu.c +++ b/arch/arm/mach-zynqmp/cpu.c @@ -180,29 +180,6 @@ int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, return regs.regs[0]; } -unsigned int __maybe_unused zynqmp_pmufw_version(void) -{ - int ret; - u32 ret_payload[PAYLOAD_ARG_CNT]; - static u32 pm_api_version = ZYNQMP_PM_VERSION_INVALID; - - /* - * Get PMU version only once and later - * just return stored values instead of - * asking PMUFW again. - */ - if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) { - ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0, - ret_payload); - pm_api_version = ret_payload[1]; - - if (ret) - panic("PMUFW is not found - Please load it!\n"); - } - - return pm_api_version; -} - static int zynqmp_mmio_rawwrite(const u32 address, const u32 mask, const u32 value) diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 6589744454..27603a60ff 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -48,7 +48,6 @@ unsigned int zynqmp_get_silicon_version(void); void handoff_setup(void); -unsigned int zynqmp_pmufw_version(void); int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value); int zynqmp_mmio_read(const u32 address, u32 *value); int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, -- cgit From a3e552b53fb85abce33a8e00bc430d014d7ee733 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 27 Sep 2019 14:20:00 +0200 Subject: arm64: zynqmp: Use mailbox driver for PMUFW config loading With new mailbox driver PMUFW configuration object can be loaded via the same interface and there is no need to have pmu_ipc.c completely. Signed-off-by: Michal Simek Reviewed-by: Luca Ceresoli --- arch/arm/mach-zynqmp/Makefile | 4 - arch/arm/mach-zynqmp/include/mach/sys_proto.h | 2 - arch/arm/mach-zynqmp/pmu_ipc.c | 112 -------------------------- 3 files changed, 118 deletions(-) delete mode 100644 arch/arm/mach-zynqmp/pmu_ipc.c (limited to 'arch/arm/mach-zynqmp') diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index f3765e45b1..8a3b074724 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -8,7 +8,3 @@ obj-y += cpu.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o - -ifneq ($(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE),"") -obj-$(CONFIG_SPL_BUILD) += pmu_ipc.o -endif diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 27603a60ff..69e729fb76 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -60,6 +60,4 @@ int chip_id(unsigned char id); void tcm_init(u8 mode); #endif -void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); - #endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-zynqmp/pmu_ipc.c b/arch/arm/mach-zynqmp/pmu_ipc.c deleted file mode 100644 index d8858ea3ff..0000000000 --- a/arch/arm/mach-zynqmp/pmu_ipc.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Inter-Processor Communication with the Platform Management Unit (PMU) - * firmware. - * - * (C) Copyright 2019 Luca Ceresoli - * Luca Ceresoli - */ - -#include -#include -#include - -/* IPI bitmasks, register base and register offsets */ -#define IPI_BIT_MASK_APU 0x00001 -#define IPI_BIT_MASK_PMU0 0x10000 -#define IPI_REG_BASE_APU 0xFF300000 -#define IPI_REG_BASE_PMU0 0xFF330000 -#define IPI_REG_OFFSET_TRIG 0x00 -#define IPI_REG_OFFSET_OBR 0x04 - -/* IPI mailbox buffer offsets */ -#define IPI_BUF_BASE_APU 0xFF990400 -#define IPI_BUF_OFFSET_TARGET_PMU 0x1C0 -#define IPI_BUF_OFFSET_REQ 0x00 -#define IPI_BUF_OFFSET_RESP 0x20 - -#define PMUFW_PAYLOAD_ARG_CNT 8 - -/* PMUFW commands */ -#define PMUFW_CMD_SET_CONFIGURATION 2 - -static void pmu_ipc_send_request(const u32 *req, size_t req_len) -{ - u32 *mbx = (u32 *)(IPI_BUF_BASE_APU + - IPI_BUF_OFFSET_TARGET_PMU + - IPI_BUF_OFFSET_REQ); - size_t i; - - for (i = 0; i < req_len; i++) - writel(req[i], &mbx[i]); -} - -static void pmu_ipc_read_response(unsigned int *value, size_t count) -{ - u32 *mbx = (u32 *)(IPI_BUF_BASE_APU + - IPI_BUF_OFFSET_TARGET_PMU + - IPI_BUF_OFFSET_RESP); - size_t i; - - for (i = 0; i < count; i++) - value[i] = readl(&mbx[i]); -} - -/** - * Send request to PMU and get the response. - * - * @req: Request buffer. Byte 0 is the API ID, other bytes are optional - * parameters. - * @req_len: Request length in number of 32-bit words. - * @res: Response buffer. Byte 0 is the error code, other bytes are - * optional parameters. Optional, if @res_maxlen==0 the parameters - * will not be read. - * @res_maxlen: Space allocated for the response in number of 32-bit words. - * - * @return Error code returned by the PMU (i.e. the first word of the response) - */ -static int pmu_ipc_request(const u32 *req, size_t req_len, - u32 *res, size_t res_maxlen) -{ - u32 status; - - if (req_len > PMUFW_PAYLOAD_ARG_CNT || - res_maxlen > PMUFW_PAYLOAD_ARG_CNT) - return -EINVAL; - - pmu_ipc_send_request(req, req_len); - - /* Raise Inter-Processor Interrupt to PMU and wait for response */ - writel(IPI_BIT_MASK_PMU0, IPI_REG_BASE_APU + IPI_REG_OFFSET_TRIG); - do { - status = readl(IPI_REG_BASE_APU + IPI_REG_OFFSET_OBR); - } while (status & IPI_BIT_MASK_PMU0); - - pmu_ipc_read_response(res, res_maxlen); - - return 0; -} - -/** - * Send a configuration object to the PMU firmware. - * - * @cfg_obj: Pointer to the configuration object - * @size: Size of @cfg_obj in bytes - */ -void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) -{ - const u32 request[] = { - PMUFW_CMD_SET_CONFIGURATION, - (u32)((u64)cfg_obj) - }; - u32 response; - int err; - - printf("Loading PMUFW cfg obj (%ld bytes)\n", size); - - err = pmu_ipc_request(request, ARRAY_SIZE(request), &response, 1); - if (err) - panic("Cannot load PMUFW configuration object (%d)\n", err); - if (response != 0) - panic("PMUFW returned 0x%08x status!\n", response); -} -- cgit