Skip to content

Commit

Permalink
rtc: rzn1: reduce register access
Browse files Browse the repository at this point in the history
This RTC has special 32bit registers which return multiple of the same
8bit registers at once. Use these to minimize register access. Also, do
the to/from BCD conversions right away, so 'tm' always contains values
as described in time.h.

Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Acked-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20241122101448.4374-3-wsa+renesas@sang-engineering.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
  • Loading branch information
Wolfram Sang authored and Alexandre Belloni committed Nov 25, 2024
1 parent 692f983 commit 3ed345c
Showing 1 changed file with 33 additions and 42 deletions.
75 changes: 33 additions & 42 deletions drivers/rtc/rtc-rzn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
#define RZN1_RTC_CTL2_WUST BIT(5)
#define RZN1_RTC_CTL2_STOPPED (RZN1_RTC_CTL2_WAIT | RZN1_RTC_CTL2_WST)

#define RZN1_RTC_SEC 0x14
#define RZN1_RTC_MIN 0x18
#define RZN1_RTC_HOUR 0x1c
#define RZN1_RTC_WEEK 0x20
#define RZN1_RTC_DAY 0x24
#define RZN1_RTC_MONTH 0x28
#define RZN1_RTC_YEAR 0x2c
#define RZN1_RTC_TIME 0x30
#define RZN1_RTC_TIME_MIN_SHIFT 8
#define RZN1_RTC_TIME_HOUR_SHIFT 16
#define RZN1_RTC_CAL 0x34
#define RZN1_RTC_CAL_DAY_SHIFT 8
#define RZN1_RTC_CAL_MON_SHIFT 16
#define RZN1_RTC_CAL_YEAR_SHIFT 24

#define RZN1_RTC_SUBU 0x38
#define RZN1_RTC_SUBU_DEV BIT(7)
Expand All @@ -52,12 +52,8 @@
#define RZN1_RTC_ALW 0x48

#define RZN1_RTC_SECC 0x4c
#define RZN1_RTC_MINC 0x50
#define RZN1_RTC_HOURC 0x54
#define RZN1_RTC_WEEKC 0x58
#define RZN1_RTC_DAYC 0x5c
#define RZN1_RTC_MONTHC 0x60
#define RZN1_RTC_YEARC 0x64
#define RZN1_RTC_TIMEC 0x68
#define RZN1_RTC_CALC 0x6c

struct rzn1_rtc {
struct rtc_device *rtcdev;
Expand All @@ -66,13 +62,18 @@ struct rzn1_rtc {

static void rzn1_rtc_get_time_snapshot(struct rzn1_rtc *rtc, struct rtc_time *tm)
{
tm->tm_sec = readl(rtc->base + RZN1_RTC_SECC);
tm->tm_min = readl(rtc->base + RZN1_RTC_MINC);
tm->tm_hour = readl(rtc->base + RZN1_RTC_HOURC);
tm->tm_wday = readl(rtc->base + RZN1_RTC_WEEKC);
tm->tm_mday = readl(rtc->base + RZN1_RTC_DAYC);
tm->tm_mon = readl(rtc->base + RZN1_RTC_MONTHC);
tm->tm_year = readl(rtc->base + RZN1_RTC_YEARC);
u32 val;

val = readl(rtc->base + RZN1_RTC_TIMEC);
tm->tm_sec = bcd2bin(val);
tm->tm_min = bcd2bin(val >> RZN1_RTC_TIME_MIN_SHIFT);
tm->tm_hour = bcd2bin(val >> RZN1_RTC_TIME_HOUR_SHIFT);

val = readl(rtc->base + RZN1_RTC_CALC);
tm->tm_wday = val & 0x0f;
tm->tm_mday = bcd2bin(val >> RZN1_RTC_CAL_DAY_SHIFT);
tm->tm_mon = bcd2bin(val >> RZN1_RTC_CAL_MON_SHIFT) - 1;
tm->tm_year = bcd2bin(val >> RZN1_RTC_CAL_YEAR_SHIFT) + 100;
}

static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)
Expand All @@ -90,16 +91,9 @@ static int rzn1_rtc_read_time(struct device *dev, struct rtc_time *tm)

rzn1_rtc_get_time_snapshot(rtc, tm);
secs = readl(rtc->base + RZN1_RTC_SECC);
if (tm->tm_sec != secs)
if (tm->tm_sec != bcd2bin(secs))
rzn1_rtc_get_time_snapshot(rtc, tm);

tm->tm_sec = bcd2bin(tm->tm_sec);
tm->tm_min = bcd2bin(tm->tm_min);
tm->tm_hour = bcd2bin(tm->tm_hour);
tm->tm_mday = bcd2bin(tm->tm_mday);
tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
tm->tm_year = bcd2bin(tm->tm_year) + 100;

return 0;
}

Expand All @@ -109,13 +103,6 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
u32 val;
int ret;

tm->tm_sec = bin2bcd(tm->tm_sec);
tm->tm_min = bin2bcd(tm->tm_min);
tm->tm_hour = bin2bcd(tm->tm_hour);
tm->tm_mday = bin2bcd(tm->tm_mday);
tm->tm_mon = bin2bcd(tm->tm_mon + 1);
tm->tm_year = bin2bcd(tm->tm_year - 100);

val = readl(rtc->base + RZN1_RTC_CTL2);
if (!(val & RZN1_RTC_CTL2_STOPPED)) {
/* Hold the counter if it was counting up */
Expand All @@ -129,13 +116,17 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
return ret;
}

writel(tm->tm_sec, rtc->base + RZN1_RTC_SEC);
writel(tm->tm_min, rtc->base + RZN1_RTC_MIN);
writel(tm->tm_hour, rtc->base + RZN1_RTC_HOUR);
writel(tm->tm_wday, rtc->base + RZN1_RTC_WEEK);
writel(tm->tm_mday, rtc->base + RZN1_RTC_DAY);
writel(tm->tm_mon, rtc->base + RZN1_RTC_MONTH);
writel(tm->tm_year, rtc->base + RZN1_RTC_YEAR);
val = bin2bcd(tm->tm_sec);
val |= bin2bcd(tm->tm_min) << RZN1_RTC_TIME_MIN_SHIFT;
val |= bin2bcd(tm->tm_hour) << RZN1_RTC_TIME_HOUR_SHIFT;
writel(val, rtc->base + RZN1_RTC_TIME);

val = tm->tm_wday;
val |= bin2bcd(tm->tm_mday) << RZN1_RTC_CAL_DAY_SHIFT;
val |= bin2bcd(tm->tm_mon + 1) << RZN1_RTC_CAL_MON_SHIFT;
val |= bin2bcd(tm->tm_year - 100) << RZN1_RTC_CAL_YEAR_SHIFT;
writel(val, rtc->base + RZN1_RTC_CAL);

writel(0, rtc->base + RZN1_RTC_CTL2);

return 0;
Expand Down

0 comments on commit 3ed345c

Please sign in to comment.