summaryrefslogtreecommitdiff
path: root/drivers/bootcount/bootcount_zynqmp.c
diff options
context:
space:
mode:
authorVasileios Amoiridis <vasileios.amoiridis@cern.ch>2024-11-05 14:27:44 +0100
committerMichal Simek <michal.simek@amd.com>2024-11-15 14:32:47 +0100
commit159dfef2615dcc83acf4e28bbed0387d72066b0c (patch)
tree127e1c9ac5c0f1fed91b5d0300abaa1a6ecce97f /drivers/bootcount/bootcount_zynqmp.c
parent4bd7222c6ba36715c5a4e1f6684bec63489e1acd (diff)
drivers: bootcount: Add ZynqMP specific bootcount support
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>
Diffstat (limited to 'drivers/bootcount/bootcount_zynqmp.c')
-rw-r--r--drivers/bootcount/bootcount_zynqmp.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/bootcount/bootcount_zynqmp.c b/drivers/bootcount/bootcount_zynqmp.c
new file mode 100644
index 00000000000..bc0984e2d26
--- /dev/null
+++ b/drivers/bootcount/bootcount_zynqmp.c
@@ -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,
+};