]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
drivers: bootcount: Add ZynqMP specific bootcount support
authorVasileios Amoiridis <vasileios.amoiridis@cern.ch>
Tue, 5 Nov 2024 13:27:44 +0000 (14:27 +0100)
committerMichal Simek <michal.simek@amd.com>
Fri, 15 Nov 2024 13:32:47 +0000 (14:32 +0100)
Add native support of the bootcount mechanism in the ZynqMP by
utilising internal PMU registers. The Persistent Global Storage
Registers of the Platform Management Unit can keep their value
during reboot cycles unless there is a POR reset, making them
appropriate for the bootcount mechanism.

Signed-off-by: Vasileios Amoiridis <vasileios.amoiridis@cern.ch>
Reviewed-by: Heiko Schocher <hs@denx.de>
Link: https://lore.kernel.org/r/20241105132744.1572759-2-vassilisamir@gmail.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
MAINTAINERS
arch/arm/mach-zynqmp/include/mach/hardware.h
drivers/bootcount/Kconfig
drivers/bootcount/Makefile
drivers/bootcount/bootcount_zynqmp.c [new file with mode: 0644]

index 0399ed1dbf6459e44d85aaf48f2da9576310628c..bc27a514e86d987ad37a819c7bedeb56206b7c9f 100644 (file)
@@ -860,6 +860,7 @@ M:  Michal Simek <michal.simek@amd.com>
 S:     Maintained
 T:     git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git
 F:     arch/arm/mach-zynqmp/
+F:     drivers/bootcount/bootcount_zynqmp.c
 F:     drivers/clk/clk_zynqmp.c
 F:     driver/firmware/firmware-zynqmp.c
 F:     drivers/fpga/zynqpl.c
index 49e449ebd61dff1aae336f88f565b536756c8ecf..3c372bd6dcf3a6df11efe30d455055f5bbef0ec3 100644 (file)
@@ -188,6 +188,8 @@ struct pmu_regs {
        u32 gen_storage4; /* 0x40 */
        u32 reserved1[1];
        u32 gen_storage6; /* 0x48 */
+       u32 reserved2[3];
+       u32 pers_gen_storage2; /* 0x58 */
 };
 
 #define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR)
index fa6d8e71281add74e979c2b39a9328c86e871cd5..0080d2a165cb016104386ce574ea67ecd90cfc61 100644 (file)
@@ -164,6 +164,13 @@ config DM_BOOTCOUNT_SYSCON
 
          Accessing the backend is done using the regmap interface.
 
+config DM_BOOTCOUNT_ZYNQMP
+       bool "Support ZynqMP PMUFW as a backing store for bootcount"
+       depends on ARCH_ZYNQMP
+       help
+         Enable support for the bootcount API by utilising the Persistent
+         Global General Storage Register 2 of the PMU.
+
 endmenu
 
 endif
index 245f87963377bbb4a4c97a7481fc7b6cc58d1d66..0cf79e428d6838b22e87d26ccb87e86a16ad4e8e 100644 (file)
@@ -16,3 +16,4 @@ obj-$(CONFIG_DM_BOOTCOUNT_I2C_EEPROM) += i2c-eeprom.o
 obj-$(CONFIG_DM_BOOTCOUNT_I2C) += bootcount_dm_i2c.o
 obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH)   += spi-flash.o
 obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o
+obj-$(CONFIG_DM_BOOTCOUNT_ZYNQMP)      += bootcount_zynqmp.o
diff --git a/drivers/bootcount/bootcount_zynqmp.c b/drivers/bootcount/bootcount_zynqmp.c
new file mode 100644 (file)
index 0000000..bc0984e
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+// SPDX-FileCopyrightText: 2024 CERN (home.cern)
+
+#include <bootcount.h>
+#include <dm.h>
+#include <stdio.h>
+#include <zynqmp_firmware.h>
+#include <asm/arch/hardware.h>
+#include <dm/platdata.h>
+
+static int bootcount_zynqmp_set(struct udevice *dev, const u32 val)
+{
+       int ret;
+
+       ret = zynqmp_mmio_write((ulong)&pmu_base->pers_gen_storage2, 0xFF, val);
+       if (ret)
+               pr_info("%s write fail\n", __func__);
+
+       return ret;
+}
+
+static int bootcount_zynqmp_get(struct udevice *dev, u32 *val)
+{
+       int ret;
+
+       *val = 0;
+       ret = zynqmp_mmio_read((ulong)&pmu_base->pers_gen_storage2, val);
+       if (ret)
+               pr_info("%s read fail\n", __func__);
+
+       return ret;
+}
+
+U_BOOT_DRVINFO(bootcount_zynqmp) = {
+       .name = "bootcount_zynqmp",
+};
+
+static const struct bootcount_ops bootcount_zynqmp_ops = {
+       .get = bootcount_zynqmp_get,
+       .set = bootcount_zynqmp_set,
+};
+
+U_BOOT_DRIVER(bootcount_zynqmp) = {
+       .name = "bootcount_zynqmp",
+       .id = UCLASS_BOOTCOUNT,
+       .ops = &bootcount_zynqmp_ops,
+};