arm64: zynqmp: Use mailbox driver for PMUFW config loading
authorMichal Simek <michal.simek@xilinx.com>
Fri, 27 Sep 2019 12:20:00 +0000 (14:20 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 8 Oct 2019 07:55:11 +0000 (09:55 +0200)
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 <michal.simek@xilinx.com>
Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>
arch/arm/mach-zynqmp/Makefile
arch/arm/mach-zynqmp/include/mach/sys_proto.h
arch/arm/mach-zynqmp/pmu_ipc.c [deleted file]
drivers/firmware/firmware-zynqmp.c
include/zynqmp_firmware.h

index f3765e45b1b90337ba8c455c3c9b3b83a681343a..8a3b0747244aa17c347b203a01f144e793dd64f9 100644 (file)
@@ -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
index 27603a60ff8f7d65b9c2be494c0d9195a3407a71..69e729fb7625ddced74603bf3a99698ee2b26413 100644 (file)
@@ -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 (file)
index d8858ea..0000000
+++ /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 <luca@lucaceresoli.net>
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/arch/sys_proto.h>
-
-/* 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);
-}
index 304398fed6df0afcf5a209aa288df5005533aa73..15e82ac3b311c7b653c77b0db1e9af1da698ab91 100644 (file)
@@ -84,6 +84,30 @@ unsigned int zynqmp_firmware_version(void)
        return pm_api_version;
 };
 
+/**
+ * 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[] = {
+               PM_SET_CONFIGURATION,
+               (u32)((u64)cfg_obj)
+       };
+       u32 response;
+       int err;
+
+       printf("Loading new PMUFW cfg obj (%ld bytes)\n", size);
+
+       err = send_req(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);
+}
+
 static int zynqmp_power_probe(struct udevice *dev)
 {
        int ret = 0;
index cebac74e9140b2e2fe6ebf3030e049df8371428a..a20cbcdb869ec6867367edea5e4369552e8b5232 100644 (file)
@@ -32,5 +32,6 @@ enum pm_api_id {
 #define PMUFW_V1_0      ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
 
 unsigned int zynqmp_firmware_version(void);
+void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
 
 #endif /* _ZYNQMP_FIRMWARE_H_ */