forked from enclustra-bsp/xilinx-uboot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
bootcount: add a DM RTC backing store for bootcount
This implements a driver using a RTC-based backing store for the DM bootcount implementation. The node configuring this feature will be compatible with 'u-boot,bootcount-rtc' and the underlying RTC device shall be reference through the property 'rtc'. An offset into the RTC device's register space can be provided through the 'offset' property. Tested on a RK3399-Q7 on a Flamingo carrier board using the SRAM area of the carrier board's RV3029 RTC. Signed-off-by: Philipp Tomsich <[email protected]>
- Loading branch information
Philipp Tomsich
committed
Dec 10, 2018
1 parent
ebb73de
commit 482734a
Showing
3 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// SPDX-License-Identifier: GPL-2.0+ | ||
/* | ||
* (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH | ||
*/ | ||
|
||
#include <common.h> | ||
#include <bootcount.h> | ||
#include <dm.h> | ||
#include <rtc.h> | ||
|
||
static const u8 bootcount_magic = 0xbc; | ||
|
||
struct bootcount_rtc_priv { | ||
struct udevice *rtc; | ||
u32 offset; | ||
}; | ||
|
||
static int bootcount_rtc_set(struct udevice *dev, const u32 a) | ||
{ | ||
struct bootcount_rtc_priv *priv = dev_get_priv(dev); | ||
const u16 val = bootcount_magic << 8 | (a & 0xff); | ||
|
||
if (rtc_write16(priv->rtc, priv->offset, val) < 0) { | ||
debug("%s: rtc_write16 failed\n", __func__); | ||
return -EIO; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int bootcount_rtc_get(struct udevice *dev, u32 *a) | ||
{ | ||
struct bootcount_rtc_priv *priv = dev_get_priv(dev); | ||
u16 val; | ||
|
||
if (rtc_read16(priv->rtc, priv->offset, &val) < 0) { | ||
debug("%s: rtc_write16 failed\n", __func__); | ||
return -EIO; | ||
} | ||
|
||
if (val >> 8 == bootcount_magic) { | ||
*a = val & 0xff; | ||
return 0; | ||
} | ||
|
||
debug("%s: bootcount magic does not match on %04x\n", __func__, val); | ||
return -EIO; | ||
} | ||
|
||
static int bootcount_rtc_probe(struct udevice *dev) | ||
{ | ||
struct ofnode_phandle_args phandle_args; | ||
struct bootcount_rtc_priv *priv = dev_get_priv(dev); | ||
struct udevice *rtc; | ||
|
||
if (dev_read_phandle_with_args(dev, "rtc", NULL, 0, 0, &phandle_args)) { | ||
debug("%s: rtc backing device not specified\n", dev->name); | ||
return -ENOENT; | ||
} | ||
|
||
if (uclass_get_device_by_ofnode(UCLASS_RTC, phandle_args.node, &rtc)) { | ||
debug("%s: could not get backing device\n", dev->name); | ||
return -ENODEV; | ||
} | ||
|
||
priv->rtc = rtc; | ||
priv->offset = dev_read_u32_default(dev, "offset", 0); | ||
|
||
return 0; | ||
} | ||
|
||
static const struct bootcount_ops bootcount_rtc_ops = { | ||
.get = bootcount_rtc_get, | ||
.set = bootcount_rtc_set, | ||
}; | ||
|
||
static const struct udevice_id bootcount_rtc_ids[] = { | ||
{ .compatible = "u-boot,bootcount-rtc" }, | ||
{ } | ||
}; | ||
|
||
U_BOOT_DRIVER(bootcount_rtc) = { | ||
.name = "bootcount-rtc", | ||
.id = UCLASS_BOOTCOUNT, | ||
.priv_auto_alloc_size = sizeof(struct bootcount_rtc_priv), | ||
.probe = bootcount_rtc_probe, | ||
.of_match = bootcount_rtc_ids, | ||
.ops = &bootcount_rtc_ops, | ||
}; |