Messages in this thread | | | Subject | Re: [PATCH] MIPS: Loongson64: Add read_persistent_clock64() | From | Jiaxun Yang <> | Date | Thu, 12 Nov 2020 18:04:28 +0800 |
| |
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@loongson.cn> > Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.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; > +}
| |