Hi Michal, thanks for the feedback.
On 27/03/19 16:03, Michal Simek wrote: > On 21. 03. 19 16:48, Luca Ceresoli wrote: >> Optionally allow U-Boot to load at the PMU firmware configuration object >> into the Power Management Unit (PMU) on Xilinx ZynqMP. >> >> The configuration object is required by the PMU FW to enable most SoC >> peripherals. So far the only way to boot using U-Boot SPL was to hard-code >> the configuration object in the PMU firmware. Allow a different boot >> process, where the PMU FW is equal for any ZynqMP chip and its >> configuration is passed at runtime by U-Boot SPL. >> >> All the code for Inter-processor communication with the PMU is isolated in >> a new file (pmu_ipc.c). The code is inspired by the same feature as >> implemented in the Xilinx First Stage Bootloader (FSBL) and Arm Trusted >> Firmware: >> >> * >> https://github.com/Xilinx/embeddedsw/blob/fb647e6b4c00f5154eba52a88b948195b6f1dc2b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c#L295 >> * >> https://github.com/ARM-software/arm-trusted-firmware/blob/c48d02bade88b07fa7f43aa44e5217f68e5d047f/plat/xilinx/zynqmp/pm_service/pm_api_sys.c#L357 >> >> The load is logged on the console during boot: >> >> U-Boot SPL 2018.01 (Mar 20 2019 - 08:12:21) >> Loading PMUFW cfg obj (2008 bytes) >> EL Level: EL3 >> ... >> >> Signed-off-by: Luca Ceresoli <[email protected]> [...] >> diff --git a/board/xilinx/zynqmp/pmu_ipc.c b/board/xilinx/zynqmp/pmu_ipc.c >> new file mode 100644 >> index 000000000000..6306d33d6f17 >> --- /dev/null >> +++ b/board/xilinx/zynqmp/pmu_ipc.c >> @@ -0,0 +1,116 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * Inter-Processor Communication with the Platform Management Unit (PMU) >> + * firmware. [...] >> +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; >> +} > > All above should be mailbox driver. It means this should go to > drivers/mailbox and be split to mbox send/recv functions. Oh, wow, there's a mailbox uclass! I'll have a look into it. > But I have no problem to use this configuration in the first patch and > move to mbox driver in separate patch. Good to know, I'll use this option in case it takes too long to make it a proper mailbox driver. >> +/** >> + * 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 *ocm = (u32 *)CONFIG_SPL_TEXT_BASE; >> + const u32 request[] = { >> + PMUFW_CMD_SET_CONFIGURATION, >> + CONFIG_SPL_TEXT_BASE >> + }; >> + u32 response; >> + int err; >> + >> + printf("Loading PMUFW cfg obj (%ld bytes)\n", size); >> + >> + memcpy(ocm, cfg_obj, 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); >> +} > > And this can stay here or go to arch/arm/mach-zynq/ Ok, I'll move it to arch/arm/mach-zynq/pmu.c or so. I assume "zynq" here means the whole zynq family, including zynqmp. >> diff --git a/board/xilinx/zynqmp/pmu_ipc.h b/board/xilinx/zynqmp/pmu_ipc.h >> new file mode 100644 >> index 000000000000..37bb72c1b20a >> --- /dev/null >> +++ b/board/xilinx/zynqmp/pmu_ipc.h >> @@ -0,0 +1,14 @@ >> +/* SPDX-License-Identifier: GPL-2.0+ */ >> +/* >> + * (C) Copyright 2019 Luca Ceresoli >> + * Luca Ceresoli <[email protected]> >> + */ >> + >> +#ifndef __ZYNQMP_PMU_IPC_H__ >> +#define __ZYNQMP_PMU_IPC_H__ >> + >> +#include <linux/types.h> >> + >> +void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); >> + > > > arch/arm/mach-zynqmp/include/mach/sys_proto.h should be fine. Ok, but I guess you mean s/zynqmp/zynq/, as above. >> +#endif /* __ZYNQMP_PMU_IPC_H__ */ >> diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c >> index 5e1d2116bc32..1d5e25961863 100644 >> --- a/board/xilinx/zynqmp/zynqmp.c >> +++ b/board/xilinx/zynqmp/zynqmp.c >> @@ -4,6 +4,8 @@ >> * Michal Simek <[email protected]> >> */ >> >> +#include "pmu_ipc.h" >> + >> #include <common.h> >> #include <sata.h> >> #include <ahci.h> >> @@ -302,6 +304,10 @@ static char *zynqmp_get_silicon_idcode_name(void) >> } >> #endif >> >> +#ifdef ZYNQMP_LOAD_PM_CFG_OBJ >> +#include CONFIG_ZYNQMP_LOAD_PM_CFG_OBJ_FILE >> +#endif >> + >> int board_early_init_f(void) >> { >> int ret = 0; >> @@ -332,6 +338,11 @@ int board_early_init_f(void) >> >> int board_init(void) >> { >> +#if defined(CONFIG_SPL_BUILD) && defined(ZYNQMP_LOAD_PM_CFG_OBJ) >> + zynqmp_pmufw_load_config_object(XPm_ConfigObject, >> + sizeof(XPm_ConfigObject)); >> +#endif > > As we discussed over IRC. I think that this should be simply bin > firmware file compare to C built by u-boot. Sure. I have a working prototype that uses a binary blob. It still needs a decent way to produce a blob and to be updated according to your review. -- Luca _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

