[U-Boot] [PATCH v4 0/2] arm: qemu-arm: enable PL031 (RTC)

Virtual Machines provided by qemu for arm are already equipped with RTCdevice (PL031). With this patch set, PL031 driver is converted to driver model and by default enabled on qemu-arm. It allows us not only to use date command but also to enable UEFI's GetTime/SetTime() services.
This work is motivated by running UEFI SCT(Self-Certification Test) and measuring time. Heinrich has already posted UEFI's GetTime() implementation.
This is a revised version of my proposal[1].
[1] https://lists.denx.de/pipermail/u-boot/2018-July/333534.html
Changes in v4 (Sep 14, 2018) * rebased to v2018.09-rc as my v3 was incompletely merged * drop v3's patch#1 * remove duplicated CONFIG_RTC_PL031 and CONFIG_SYS_RTC_PL031_BASE
Changes in v3 (July 11, 2018) * compile drivers/rtc/date.c if DM_RTC * rename pl031_rtc_xxx to pl031_xxx * make struct pl031_platdata private to the driver * add probe function, removing pl031_initted variable * use readl/writel() instead of private macros * add a debug message to pl031_rtc_set() * remove CONFIG_SYS_RTC_PL031_BASE from config_whitelist.txt * enable RTC_PL031 for QEMU_ARM in arch/arm/Kconfig
Changes in v2 (July 4, 2018) * based on Heinrich's comments, * remove legacy mode interface * enable the driver in defconfig
AKASHI Takahiro (2): rtc: pl031: convert the driver to driver model arm: qemu-arm: enable RTC (PL031) by default
arch/arm/Kconfig | 2 + drivers/rtc/pl031.c | 126 ++++++++++++++++++++++------------- include/configs/qemu-arm.h | 3 - scripts/config_whitelist.txt | 1 - 4 files changed, 82 insertions(+), 50 deletions(-)

From: AKASHI Takahiro takahiro.akashi@linaro.org
With this patch, PL031 driver is converted to driver-model-compliant driver. In addition, CONFIG_SYS_RTC_PL031_BASE is no longer valid.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- drivers/rtc/pl031.c | 126 ++++++++++++++++++++++------------- include/configs/qemu-arm.h | 3 - scripts/config_whitelist.txt | 1 - 3 files changed, 80 insertions(+), 50 deletions(-)
diff --git a/drivers/rtc/pl031.c b/drivers/rtc/pl031.c index 8955805e3bc1..8bf04f26a375 100644 --- a/drivers/rtc/pl031.c +++ b/drivers/rtc/pl031.c @@ -8,13 +8,11 @@
#include <common.h> #include <command.h> +#include <dm.h> +#include <errno.h> #include <rtc.h> - -#if defined(CONFIG_CMD_DATE) - -#ifndef CONFIG_SYS_RTC_PL031_BASE -#error CONFIG_SYS_RTC_PL031_BASE is not defined! -#endif +#include <asm/io.h> +#include <asm/types.h>
/* * Register definitions @@ -30,78 +28,114 @@
#define RTC_CR_START (1 << 0)
-#define RTC_WRITE_REG(addr, val) \ - (*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr)) = (val)) -#define RTC_READ_REG(addr) \ - (*(volatile unsigned int *)(CONFIG_SYS_RTC_PL031_BASE + (addr))) +struct pl031_platdata { + phys_addr_t base; +};
-static int pl031_initted = 0; +static inline u32 pl031_read_reg(struct udevice *dev, int reg) +{ + struct pl031_platdata *pdata = dev_get_platdata(dev);
-/* Enable RTC Start in Control register*/ -void rtc_init(void) + return readl(pdata->base + reg); +} + +static inline u32 pl031_write_reg(struct udevice *dev, int reg, u32 value) { - RTC_WRITE_REG(RTC_CR, RTC_CR_START); + struct pl031_platdata *pdata = dev_get_platdata(dev);
- pl031_initted = 1; + return writel(value, pdata->base + reg); }
/* - * Reset the RTC. We set the date back to 1970-01-01. + * Probe RTC device + */ +static int pl031_probe(struct udevice *dev) +{ + /* Enable RTC Start in Control register*/ + pl031_write_reg(dev, RTC_CR, RTC_CR_START); + + return 0; +} + +/* + * Get the current time from the RTC */ -void rtc_reset(void) +static int pl031_get(struct udevice *dev, struct rtc_time *tm) { - RTC_WRITE_REG(RTC_LR, 0x00); - if(!pl031_initted) - rtc_init(); + unsigned long tim; + + if (!tm) + return -EINVAL; + + tim = pl031_read_reg(dev, RTC_DR); + + rtc_to_tm(tim, tm); + + debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + + return 0; }
/* * Set the RTC -*/ -int rtc_set(struct rtc_time *tmp) + */ +static int pl031_set(struct udevice *dev, const struct rtc_time *tm) { unsigned long tim;
- if(!pl031_initted) - rtc_init(); + if (!tm) + return -EINVAL;
- if (tmp == NULL) { - puts("Error setting the date/time\n"); - return -1; - } + debug("Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, + tm->tm_hour, tm->tm_min, tm->tm_sec);
/* Calculate number of seconds this incoming time represents */ - tim = rtc_mktime(tmp); + tim = rtc_mktime(tm);
- RTC_WRITE_REG(RTC_LR, tim); + pl031_write_reg(dev, RTC_LR, tim);
- return -1; + return 0; }
/* - * Get the current time from the RTC + * Reset the RTC. We set the date back to 1970-01-01. */ -int rtc_get(struct rtc_time *tmp) +static int pl031_reset(struct udevice *dev) { - ulong tim; + pl031_write_reg(dev, RTC_LR, 0);
- if(!pl031_initted) - rtc_init(); + return 0; +}
- if (tmp == NULL) { - puts("Error getting the date/time\n"); - return -1; - } +static const struct rtc_ops pl031_ops = { + .get = pl031_get, + .set = pl031_set, + .reset = pl031_reset, +};
- tim = RTC_READ_REG(RTC_DR); +static const struct udevice_id pl031_ids[] = { + { .compatible = "arm,pl031" }, + { } +};
- rtc_to_tm(tim, tmp); +static int pl031_ofdata_to_platdata(struct udevice *dev) +{ + struct pl031_platdata *pdata = dev_get_platdata(dev);
- debug ( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, - tmp->tm_hour, tmp->tm_min, tmp->tm_sec); + pdata->base = dev_read_addr(dev);
return 0; }
-#endif +U_BOOT_DRIVER(rtc_pl031) = { + .name = "rtc-pl031", + .id = UCLASS_RTC, + .of_match = pl031_ids, + .probe = pl031_probe, + .ofdata_to_platdata = pl031_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct pl031_platdata), + .ops = &pl031_ops, +}; diff --git a/include/configs/qemu-arm.h b/include/configs/qemu-arm.h index 913ff4f2636f..ba106247dc6f 100644 --- a/include/configs/qemu-arm.h +++ b/include/configs/qemu-arm.h @@ -23,9 +23,6 @@ /* For block devices, QEMU emulates an ICH9 AHCI controller over PCI */ #define CONFIG_SYS_SCSI_MAX_SCSI_ID 6
-/* QEMU emulates the ARM AMBA PL031 RTC */ -#define CONFIG_SYS_RTC_PL031_BASE 0x09010000 - /* Environment options */ #define CONFIG_ENV_SIZE SZ_64K
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index fc37099cbe0e..6168684daabf 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4070,7 +4070,6 @@ CONFIG_SYS_RSTC_RMR_VAL CONFIG_SYS_RTC_BUS_NUM CONFIG_SYS_RTC_CNT CONFIG_SYS_RTC_OSCILLATOR -CONFIG_SYS_RTC_PL031_BASE CONFIG_SYS_RTC_REG_BASE_ADDR CONFIG_SYS_RTC_SETUP CONFIG_SYS_RV3029_TCR

From: AKASHI Takahiro takahiro.akashi@linaro.org
Virtual machine provided by qemu-arm has a ARM PL031 Real Time Clock device. With this patch, the driver is enabled by default.
Signed-off-by: AKASHI Takahiro takahiro.akashi@linaro.org --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8a23c76db846..f9fdbabba81b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -741,6 +741,8 @@ config ARCH_QEMU select OF_CONTROL select PL01X_SERIAL imply CMD_DM + imply DM_RTC + imply RTC_PL031
config ARCH_RMOBILE bool "Renesas ARM SoCs"
participants (1)
-
Akashi, Takahiro