[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8d6ebfe2-e300-3f38-6316-196cba947d36@flygoat.com>
Date: Thu, 12 Nov 2020 18:04:28 +0800
From: Jiaxun Yang <jiaxun.yang@...goat.com>
To: Tiezhu Yang <yangtiezhu@...ngson.cn>,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Huacai Chen <chenhc@...ote.com>
Cc: linux-mips@...r.kernel.org, linux-kernel@...r.kernel.org,
Xuefeng Li <lixuefeng@...ngson.cn>,
Yinglu Yang <yangyinglu@...ngson.cn>
Subject: Re: [PATCH] MIPS: Loongson64: Add read_persistent_clock64()
Hi Tiezhu,
在 2020/11/12 16:29, Tiezhu Yang 写道:
> Add read_persistent_clock64() to read the time from the battery backed
> persistent clock. With this patch, we can fix the wrong time issue due
> to the system clock is not consistent with hardware clock after resume
> from sleep state S3 (suspend to RAM), at the same time, the system time
> can be right instead of "Thu Jan 1 08:00:00 CST 1970" without rtc driver.
>
> start_kernel()
> timekeeping_init()
> read_persistent_wall_and_boot_offset()
> read_persistent_clock64()
>
> timekeeping_resume()
> read_persistent_clock64()
>
> timekeeping_suspend()
> read_persistent_clock64()
It is highly discoraged to do anything with bridgetype, which isn't
probed via
devicetree.
Please check if you can deal with that inside RTC framework, or make it as
a part of RTC driver (e.g. set up a callback).
Also you should submit RTC driver at first if you intend to complete
LS7A support.
Thanks.
- Jiaxun
>
> Signed-off-by: Yinglu Yang <yangyinglu@...ngson.cn>
> Signed-off-by: Tiezhu Yang <yangtiezhu@...ngson.cn>
> ---
> arch/mips/include/asm/mach-loongson64/loongson.h | 20 +++++++++++++++++
> arch/mips/loongson64/time.c | 28 +++++++++++++++++++++++-
> 2 files changed, 47 insertions(+), 1 deletion(-)
>
> diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
> index fde1b75..448289e 100644
> --- a/arch/mips/include/asm/mach-loongson64/loongson.h
> +++ b/arch/mips/include/asm/mach-loongson64/loongson.h
> @@ -238,4 +238,24 @@ extern u64 loongson_freqctrl[MAX_PACKAGES];
> #define LOONGSON_PCIMAP_WIN(WIN, ADDR) \
> ((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
>
> +/* LS7A RTC */
> +#define LS7A_MISC_REG_BASE 0x10080000
> +#define LS7A_RTC_ADDR_OFFSET 0x50100
> +#define LS7A_RTC_SYS_TOYREAD0_OFFSET 0x2c
> +#define LS7A_RTC_SYS_TOYREAD1_OFFSET 0x30
> +#define LS7A_RTC_REG_BASE (LS7A_MISC_REG_BASE + LS7A_RTC_ADDR_OFFSET)
> +#define LS7A_RTC_SYS_TOYREAD0_ADDR (LS7A_RTC_REG_BASE + LS7A_RTC_SYS_TOYREAD0_OFFSET)
> +#define LS7A_RTC_SYS_TOYREAD1_ADDR (LS7A_RTC_REG_BASE + LS7A_RTC_SYS_TOYREAD1_OFFSET)
> +#define LS7A_RTC_TOY_MON_MASK GENMASK(31, 26)
> +#define LS7A_RTC_TOY_MON_SHIFT 26
> +#define LS7A_RTC_TOY_DAY_MASK GENMASK(25, 21)
> +#define LS7A_RTC_TOY_DAY_SHIFT 21
> +#define LS7A_RTC_TOY_HOUR_MASK GENMASK(20, 16)
> +#define LS7A_RTC_TOY_HOUR_SHIFT 16
> +#define LS7A_RTC_TOY_MIN_MASK GENMASK(15, 10)
> +#define LS7A_RTC_TOY_MIN_SHIFT 10
> +#define LS7A_RTC_TOY_SEC_MASK GENMASK(9, 4)
> +#define LS7A_RTC_TOY_SEC_SHIFT 4
> +#define LS7A_RTC_YEAR_BASE 1900
> +
> #endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */
> diff --git a/arch/mips/loongson64/time.c b/arch/mips/loongson64/time.c
> index 91e842b..7f3095546 100644
> --- a/arch/mips/loongson64/time.c
> +++ b/arch/mips/loongson64/time.c
> @@ -9,7 +9,7 @@
>
> #include <asm/time.h>
> #include <asm/hpet.h>
> -
> +#include <asm/mc146818-time.h>
> #include <loongson.h>
>
> void __init plat_time_init(void)
> @@ -21,3 +21,29 @@ void __init plat_time_init(void)
> setup_hpet_timer();
> #endif
> }
> +
> +static time64_t ls7a_get_rtc_time(void)
> +{
> + unsigned int year, mon, day, hour, min, sec;
> + unsigned int value;
> +
> + value = readl((void __iomem *)TO_UNCAC(LS7A_RTC_SYS_TOYREAD0_ADDR));
> + sec = (value & LS7A_RTC_TOY_SEC_MASK) >> LS7A_RTC_TOY_SEC_SHIFT;
> + min = (value & LS7A_RTC_TOY_MIN_MASK) >> LS7A_RTC_TOY_MIN_SHIFT;
> + hour = (value & LS7A_RTC_TOY_HOUR_MASK) >> LS7A_RTC_TOY_HOUR_SHIFT;
> + day = (value & LS7A_RTC_TOY_DAY_MASK) >> LS7A_RTC_TOY_DAY_SHIFT;
> + mon = (value & LS7A_RTC_TOY_MON_MASK) >> LS7A_RTC_TOY_MON_SHIFT;
> + year = readl((void __iomem *)TO_UNCAC(LS7A_RTC_SYS_TOYREAD1_ADDR));
> +
> + return mktime64(year + LS7A_RTC_YEAR_BASE, mon, day, hour, min, sec);
> +}
> +
> +void read_persistent_clock64(struct timespec64 *ts)
> +{
> + if (loongson_sysconf.bridgetype == LS7A)
> + ts->tv_sec = ls7a_get_rtc_time();
> + else
> + ts->tv_sec = mc146818_get_cmos_time();
> +
> + ts->tv_nsec = 0;
> +}
Powered by blists - more mailing lists