From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heinrich Schuchardt Date: Mon, 26 Oct 2020 20:18:08 +0100 Subject: [PATCH v2 2/2] rtc: provide an emulated RTC In-Reply-To: References: <20201025071316.37416-1-xypron.glpk@gmx.de> <20201025071316.37416-3-xypron.glpk@gmx.de> Message-ID: <7c77ff7f-24fa-05e3-fac3-0949d1d9ffc4@gmx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 26.10.20 16:31, Grant Likely wrote: > On Mon, Oct 26, 2020 at 3:30 PM Grant Likely wrote: >> >> On Sun, Oct 25, 2020 at 7:13 AM Heinrich Schuchardt wrote: >>> >>> On a board without hardware clock this software real time clock can be >>> used. The build time is used to initialize the RTC. So you will have >>> to adjust the time either manually using the 'date' command or use >>> the 'sntp' to update the RTC with the time from a network time server. >>> See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is >>> advanced according to CPU ticks. >>> >>> Signed-off-by: Heinrich Schuchardt >> >> Looks good to me, and tested on RockPro64 w/ UEFI SCT. >> >> Tested-by: Grant Likely > > One thought: Can this be automatically enabled if no other RTC driver > is configured in? * This RTC does not show the correct time unless you use SNTP to set it. * There is no need for an RTC to boot an OS. * Many board maintainers struggle with the size of there U-Boot binary. So it does not make sense to me to enable this driver as fallback by default. Best regards Heinrich > > g. > >> >> g. >> >>> --- >>> v2: >>> more elaborate Kconfig message >>> adjust device name properties >>> use build time as initial time >>> --- >>> MAINTAINERS | 1 + >>> drivers/rtc/Kconfig | 11 ++++++ >>> drivers/rtc/Makefile | 1 + >>> drivers/rtc/emul_rtc.c | 80 ++++++++++++++++++++++++++++++++++++++++++ >>> 4 files changed, 93 insertions(+) >>> create mode 100644 drivers/rtc/emul_rtc.c >>> >>> diff --git a/MAINTAINERS b/MAINTAINERS >>> index fc4fad46ee..a98e0c5b76 100644 >>> --- a/MAINTAINERS >>> +++ b/MAINTAINERS >>> @@ -678,6 +678,7 @@ S: Maintained >>> T: git https://gitlab.denx.de/u-boot/custodians/u-boot-efi.git >>> F: doc/api/efi.rst >>> F: doc/uefi/* >>> +F: drivers/rtc/emul_rtc.c >>> F: include/capitalization.h >>> F: include/charset.h >>> F: include/cp1250.h >>> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig >>> index 63662001c2..d06d272e14 100644 >>> --- a/drivers/rtc/Kconfig >>> +++ b/drivers/rtc/Kconfig >>> @@ -63,6 +63,17 @@ config RTC_DS3232 >>> Support for Dallas Semiconductor (now Maxim) DS3232 compatible >>> Real Time Clock devices. >>> >>> +config RTC_EMULATION >>> + bool "Enable emulated RTC" >>> + depends on DM_RTC >>> + help >>> + On a board without hardware clock this software real time clock can be >>> + used. The build time is used to initialize the RTC. So you will have >>> + to adjust the time either manually using the 'date' command or use >>> + the 'sntp' to update the RTC with the time from a network time server. >>> + See CONFIG_CMD_SNTP and CONFIG_BOOTP_NTPSERVER. The RTC time is >>> + advanced according to CPU ticks. >>> + >>> config RTC_ISL1208 >>> bool "Enable ISL1208 driver" >>> depends on DM_RTC >>> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile >>> index 12eb449583..ef66dc4bf0 100644 >>> --- a/drivers/rtc/Makefile >>> +++ b/drivers/rtc/Makefile >>> @@ -22,6 +22,7 @@ obj-$(CONFIG_RTC_DS164x) += ds164x.o >>> obj-$(CONFIG_RTC_DS174x) += ds174x.o >>> obj-$(CONFIG_RTC_DS3231) += ds3231.o >>> obj-$(CONFIG_RTC_DS3232) += ds3232.o >>> +obj-$(CONFIG_RTC_EMULATION) += emul_rtc.o >>> obj-$(CONFIG_RTC_FTRTC010) += ftrtc010.o >>> obj-$(CONFIG_SANDBOX) += i2c_rtc_emul.o >>> obj-$(CONFIG_RTC_IMXDI) += imxdi.o >>> diff --git a/drivers/rtc/emul_rtc.c b/drivers/rtc/emul_rtc.c >>> new file mode 100644 >>> index 0000000000..c98c24bbb3 >>> --- /dev/null >>> +++ b/drivers/rtc/emul_rtc.c >>> @@ -0,0 +1,80 @@ >>> +// SPDX-License-Identifier: GPL-2.0+ >>> +/* >>> + * Copyright 2020, Heinrich Schuchardt >>> + * >>> + * This driver emulates a real time clock based on timer ticks. >>> + */ >>> + >>> +#include >>> +#include >>> +#include >>> +#include >>> +#include >>> + >>> +/** >>> + * struct emul_rtc - private data for emulated RTC driver >>> + */ >>> +struct emul_rtc { >>> + /** >>> + * @offset_us: microseconds from 1970-01-01 to timer_get_us() base >>> + */ >>> + u64 offset_us; >>> + /** >>> + * @isdst: daylight saving time >>> + */ >>> + int isdst; >>> +}; >>> + >>> +static int emul_rtc_get(struct udevice *dev, struct rtc_time *time) >>> +{ >>> + struct emul_rtc *priv = dev_get_priv(dev); >>> + u64 now; >>> + >>> + if (!priv->offset_us) { >>> + /* Use the build date as initial time */ >>> + priv->offset_us = U_BOOT_EPOCH * 1000000ULL - timer_get_us(); >>> + priv->isdst = -1; >>> + } >>> + >>> + now = timer_get_us() + priv->offset_us; >>> + do_div(now, 1000000); >>> + rtc_to_tm(now, time); >>> + time->tm_isdst = priv->isdst; >>> + >>> + return 0; >>> +} >>> + >>> +static int emul_rtc_set(struct udevice *dev, const struct rtc_time *time) >>> +{ >>> + struct emul_rtc *priv = dev_get_priv(dev); >>> + >>> + if (time->tm_year < 1970) >>> + return -EINVAL; >>> + >>> + priv->offset_us = rtc_mktime(time) * 1000000ULL - timer_get_us(); >>> + >>> + if (time->tm_isdst > 0) >>> + priv->isdst = 1; >>> + else if (time->tm_isdst < 0) >>> + priv->isdst = -1; >>> + else >>> + priv->isdst = 0; >>> + >>> + return 0; >>> +} >>> + >>> +static const struct rtc_ops emul_rtc_ops = { >>> + .get = emul_rtc_get, >>> + .set = emul_rtc_set, >>> +}; >>> + >>> +U_BOOT_DRIVER(rtc_emul) = { >>> + .name = "rtc_emul", >>> + .id = UCLASS_RTC, >>> + .ops = &emul_rtc_ops, >>> + .priv_auto_alloc_size = sizeof(struct emul_rtc), >>> +}; >>> + >>> +U_BOOT_DEVICE(rtc_emul) = { >>> + .name = "rtc_emul", >>> +}; >>> -- >>> 2.28.0 >>>