From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
To: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>,
soren.brinkmann@xilinx.com,
Michal Simek <michal.simek@xilinx.com>,
rtc-linux@googlegroups.com, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
Punnaiah Choudary Kalluri <punnaia@xilinx.com>,
Anirudha Sarangi <anirudh@xilinx.com>,
Srikanth Vemula <svemula@xilinx.com>,
Srinivas Goud <sgoud@xilinx.com>,
Anurag Kumar Vulisha <anuragku@xilinx.com>
Subject: [rtc-linux] Re: [PATCH V2] rtc: zynqmp: Update seconds time programming logic
Date: Wed, 20 Apr 2016 16:03:10 +0200 [thread overview]
Message-ID: <20160420140310.GS29844@piout.net> (raw)
In-Reply-To: <1461160279-40600-1-git-send-email-anuragku@xilinx.com>
On 20/04/2016 at 19:21:19 +0530, Anurag Kumar Vulisha wrote :
> We programe RTC time using SET_TIME_WRITE register and read the RTC
> current time using CURRENT_TIME register. When we set the time by
> writing into SET_TIME_WRITE Register and immediately try to read the
> rtc time from CURRENT_TIME register, the previous old value is
> returned instead of the new loaded time. This is because RTC takes
> nearly 1 sec to update the new loaded value into the CURRENT_TIME
> register. This behaviour is expected in our RTC IP.
>
> This patch updates the driver to read the current time from SET_TIME_WRITE
> register instead of CURRENT_TIME when rtc time is requested within an 1sec
> period after setting the RTC time. Doing so will ensure the correct time
> is given to the user.
>
> Since there is an delay of 1sec in updating the CURRENT_TIME we are loading
> set time +1sec while programming the SET_TIME_WRITE register, doing this
> will give correct time without any delay when read from CURRENT_TIME.
>
> This patch updates the above said.
>
> Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
> ---
> Changes in v2:
> 1. Updated the Time programming logic as suggested by Alexandre Belloni
> 2. Changed the commit message
> ---
> drivers/rtc/rtc-zynqmp.c | 41 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 36 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> index f87f971..ba4203a 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -64,6 +64,12 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> unsigned long new_time;
>
> + /*
> + * The value written will be updated after 1 sec into the
> + * seconds read register, so we need to program time +1 sec
> + * to get the correct time on read.
> + */
> + tm->tm_sec += 1;
> new_time = rtc_tm_to_time64(tm);
>
> if (new_time > RTC_SEC_MAX_VAL)
> @@ -78,14 +84,41 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
>
> writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
>
> + /*
> + * Clear the rtc interrupt status register after setting the
> + * time. During a read_time function, the code should read the
> + * RTC_INT_STATUS register and if bit 0 is still 0, it means
> + * that one second has not elapsed yet since RTC was set and
> + * the current time should be read from SET_TIME_READ register;
> + * otherwise, CURRENT_TIME register is read to report the time
> + */
> + writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
> +
> return 0;
> }
>
> static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
> {
> + int status;
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>
> - rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + status = readl(xrtcdev->reg_base + RTC_INT_STS);
> +
> + if (status & RTC_INT_SEC) {
> + /*
> + * RTC has updated the CURRENT_TIME with the time written into
> + * SET_TIME_WRITE register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + } else {
> + /*
> + * Time written in SET_TIME_WRITE has not yet updated into
> + * the seconds read register, so read the time from the
> + * SET_TIME_WRITE instead of CURRENT_TIME register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD), tm);
> + tm->tm_sec -= 1;
Well, I didn't point it out directly earlier but this doesn't work while
my example is working:
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1, tm);
Think about what is happening when tm->tm_sec == 0 ...
> + }
>
> return rtc_valid_tm(tm);
> }
> @@ -166,11 +199,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
> return IRQ_NONE;
>
> - /* Clear interrupt */
> - writel(status, xrtcdev->reg_base + RTC_INT_STS);
> + /* Clear RTC_INT_ALRM interrupt only */
> + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
>
> - if (status & RTC_INT_SEC)
> - rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
> if (status & RTC_INT_ALRM)
> rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
>
> --
> 2.1.2
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
--
--
You received this message because you are subscribed to "rtc-linux".
Membership options at http://groups.google.com/group/rtc-linux .
Please read http://groups.google.com/group/rtc-linux/web/checklist
before submitting a driver.
---
You received this message because you are subscribed to the Google Groups "rtc-linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rtc-linux+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
WARNING: multiple messages have this Message-ID (diff)
From: alexandre.belloni@free-electrons.com (Alexandre Belloni)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH V2] rtc: zynqmp: Update seconds time programming logic
Date: Wed, 20 Apr 2016 16:03:10 +0200 [thread overview]
Message-ID: <20160420140310.GS29844@piout.net> (raw)
In-Reply-To: <1461160279-40600-1-git-send-email-anuragku@xilinx.com>
On 20/04/2016 at 19:21:19 +0530, Anurag Kumar Vulisha wrote :
> We programe RTC time using SET_TIME_WRITE register and read the RTC
> current time using CURRENT_TIME register. When we set the time by
> writing into SET_TIME_WRITE Register and immediately try to read the
> rtc time from CURRENT_TIME register, the previous old value is
> returned instead of the new loaded time. This is because RTC takes
> nearly 1 sec to update the new loaded value into the CURRENT_TIME
> register. This behaviour is expected in our RTC IP.
>
> This patch updates the driver to read the current time from SET_TIME_WRITE
> register instead of CURRENT_TIME when rtc time is requested within an 1sec
> period after setting the RTC time. Doing so will ensure the correct time
> is given to the user.
>
> Since there is an delay of 1sec in updating the CURRENT_TIME we are loading
> set time +1sec while programming the SET_TIME_WRITE register, doing this
> will give correct time without any delay when read from CURRENT_TIME.
>
> This patch updates the above said.
>
> Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
> ---
> Changes in v2:
> 1. Updated the Time programming logic as suggested by Alexandre Belloni
> 2. Changed the commit message
> ---
> drivers/rtc/rtc-zynqmp.c | 41 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 36 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> index f87f971..ba4203a 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -64,6 +64,12 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> unsigned long new_time;
>
> + /*
> + * The value written will be updated after 1 sec into the
> + * seconds read register, so we need to program time +1 sec
> + * to get the correct time on read.
> + */
> + tm->tm_sec += 1;
> new_time = rtc_tm_to_time64(tm);
>
> if (new_time > RTC_SEC_MAX_VAL)
> @@ -78,14 +84,41 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
>
> writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
>
> + /*
> + * Clear the rtc interrupt status register after setting the
> + * time. During a read_time function, the code should read the
> + * RTC_INT_STATUS register and if bit 0 is still 0, it means
> + * that one second has not elapsed yet since RTC was set and
> + * the current time should be read from SET_TIME_READ register;
> + * otherwise, CURRENT_TIME register is read to report the time
> + */
> + writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
> +
> return 0;
> }
>
> static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
> {
> + int status;
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>
> - rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + status = readl(xrtcdev->reg_base + RTC_INT_STS);
> +
> + if (status & RTC_INT_SEC) {
> + /*
> + * RTC has updated the CURRENT_TIME with the time written into
> + * SET_TIME_WRITE register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + } else {
> + /*
> + * Time written in SET_TIME_WRITE has not yet updated into
> + * the seconds read register, so read the time from the
> + * SET_TIME_WRITE instead of CURRENT_TIME register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD), tm);
> + tm->tm_sec -= 1;
Well, I didn't point it out directly earlier but this doesn't work while
my example is working:
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1, tm);
Think about what is happening when tm->tm_sec == 0 ...
> + }
>
> return rtc_valid_tm(tm);
> }
> @@ -166,11 +199,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
> return IRQ_NONE;
>
> - /* Clear interrupt */
> - writel(status, xrtcdev->reg_base + RTC_INT_STS);
> + /* Clear RTC_INT_ALRM interrupt only */
> + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
>
> - if (status & RTC_INT_SEC)
> - rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
> if (status & RTC_INT_ALRM)
> rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
>
> --
> 2.1.2
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
WARNING: multiple messages have this Message-ID (diff)
From: Alexandre Belloni <alexandre.belloni@free-electrons.com>
To: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Cc: Alessandro Zummo <a.zummo@towertech.it>,
soren.brinkmann@xilinx.com,
Michal Simek <michal.simek@xilinx.com>,
rtc-linux@googlegroups.com, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
Punnaiah Choudary Kalluri <punnaia@xilinx.com>,
Anirudha Sarangi <anirudh@xilinx.com>,
Srikanth Vemula <svemula@xilinx.com>,
Srinivas Goud <sgoud@xilinx.com>,
Anurag Kumar Vulisha <anuragku@xilinx.com>
Subject: Re: [PATCH V2] rtc: zynqmp: Update seconds time programming logic
Date: Wed, 20 Apr 2016 16:03:10 +0200 [thread overview]
Message-ID: <20160420140310.GS29844@piout.net> (raw)
In-Reply-To: <1461160279-40600-1-git-send-email-anuragku@xilinx.com>
On 20/04/2016 at 19:21:19 +0530, Anurag Kumar Vulisha wrote :
> We programe RTC time using SET_TIME_WRITE register and read the RTC
> current time using CURRENT_TIME register. When we set the time by
> writing into SET_TIME_WRITE Register and immediately try to read the
> rtc time from CURRENT_TIME register, the previous old value is
> returned instead of the new loaded time. This is because RTC takes
> nearly 1 sec to update the new loaded value into the CURRENT_TIME
> register. This behaviour is expected in our RTC IP.
>
> This patch updates the driver to read the current time from SET_TIME_WRITE
> register instead of CURRENT_TIME when rtc time is requested within an 1sec
> period after setting the RTC time. Doing so will ensure the correct time
> is given to the user.
>
> Since there is an delay of 1sec in updating the CURRENT_TIME we are loading
> set time +1sec while programming the SET_TIME_WRITE register, doing this
> will give correct time without any delay when read from CURRENT_TIME.
>
> This patch updates the above said.
>
> Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
> ---
> Changes in v2:
> 1. Updated the Time programming logic as suggested by Alexandre Belloni
> 2. Changed the commit message
> ---
> drivers/rtc/rtc-zynqmp.c | 41 ++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 36 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> index f87f971..ba4203a 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -64,6 +64,12 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> unsigned long new_time;
>
> + /*
> + * The value written will be updated after 1 sec into the
> + * seconds read register, so we need to program time +1 sec
> + * to get the correct time on read.
> + */
> + tm->tm_sec += 1;
> new_time = rtc_tm_to_time64(tm);
>
> if (new_time > RTC_SEC_MAX_VAL)
> @@ -78,14 +84,41 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
>
> writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
>
> + /*
> + * Clear the rtc interrupt status register after setting the
> + * time. During a read_time function, the code should read the
> + * RTC_INT_STATUS register and if bit 0 is still 0, it means
> + * that one second has not elapsed yet since RTC was set and
> + * the current time should be read from SET_TIME_READ register;
> + * otherwise, CURRENT_TIME register is read to report the time
> + */
> + writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
> +
> return 0;
> }
>
> static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
> {
> + int status;
> struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
>
> - rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + status = readl(xrtcdev->reg_base + RTC_INT_STS);
> +
> + if (status & RTC_INT_SEC) {
> + /*
> + * RTC has updated the CURRENT_TIME with the time written into
> + * SET_TIME_WRITE register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
> + } else {
> + /*
> + * Time written in SET_TIME_WRITE has not yet updated into
> + * the seconds read register, so read the time from the
> + * SET_TIME_WRITE instead of CURRENT_TIME register.
> + */
> + rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD), tm);
> + tm->tm_sec -= 1;
Well, I didn't point it out directly earlier but this doesn't work while
my example is working:
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1, tm);
Think about what is happening when tm->tm_sec == 0 ...
> + }
>
> return rtc_valid_tm(tm);
> }
> @@ -166,11 +199,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
> return IRQ_NONE;
>
> - /* Clear interrupt */
> - writel(status, xrtcdev->reg_base + RTC_INT_STS);
> + /* Clear RTC_INT_ALRM interrupt only */
> + writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
>
> - if (status & RTC_INT_SEC)
> - rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
> if (status & RTC_INT_ALRM)
> rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
>
> --
> 2.1.2
>
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
next prev parent reply other threads:[~2016-04-20 14:03 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-20 13:51 [rtc-linux] [PATCH V2] rtc: zynqmp: Update seconds time programming logic Anurag Kumar Vulisha
2016-04-20 13:51 ` Anurag Kumar Vulisha
2016-04-20 13:51 ` Anurag Kumar Vulisha
2016-04-20 14:03 ` Alexandre Belloni [this message]
2016-04-20 14:03 ` Alexandre Belloni
2016-04-20 14:03 ` Alexandre Belloni
2016-04-20 14:20 ` [rtc-linux] " Anurag Kumar Vulisha
2016-04-20 14:20 ` Anurag Kumar Vulisha
2016-04-20 14:20 ` Anurag Kumar Vulisha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160420140310.GS29844@piout.net \
--to=alexandre.belloni@free-electrons.com \
--cc=a.zummo@towertech.it \
--cc=anirudh@xilinx.com \
--cc=anurag.kumar.vulisha@xilinx.com \
--cc=anuragku@xilinx.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.simek@xilinx.com \
--cc=punnaia@xilinx.com \
--cc=rtc-linux@googlegroups.com \
--cc=sgoud@xilinx.com \
--cc=soren.brinkmann@xilinx.com \
--cc=svemula@xilinx.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.