linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode
@ 2018-07-10  6:50 Keerthy
  2018-07-10  6:50 ` [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec Keerthy
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Keerthy @ 2018-07-10  6:50 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni
  Cc: t-kristo, j-keerthy, linux-rtc, linux-omap, linux-kernel, johan

Prepare rtc driver for rtc-only with DDR in self-refresh mode.
The patch series is based on top of Johan Hovald's series:

https://lkml.kernel.org/r/20180704090558.16647-1-johan@kernel.org

Tested for suspend/resume and poweroff on am437x-gp-evm.

Keerthy (4):
  rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  rtc: OMAP: Add support for rtc-only mode
  rtc: omap: use of_device_is_system_power_controller function
  rtc: interface: Add power_off_program ops

 drivers/rtc/interface.c | 12 +++++++++
 drivers/rtc/rtc-omap.c  | 71 ++++++++++++++++++++++++++++++++++++-------------
 include/linux/rtc.h     |  2 ++
 3 files changed, 66 insertions(+), 19 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  2018-07-10  6:50 [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode Keerthy
@ 2018-07-10  6:50 ` Keerthy
  2018-07-11 13:54   ` Johan Hovold
  2018-07-10  6:50 ` [PATCH v3 2/4] rtc: OMAP: Add support for rtc-only mode Keerthy
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Keerthy @ 2018-07-10  6:50 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni
  Cc: t-kristo, j-keerthy, linux-rtc, linux-omap, linux-kernel, johan

Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
over try again.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 drivers/rtc/rtc-omap.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 323ff55..14f2241 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -441,11 +441,12 @@ static void omap_rtc_power_off(void)
 	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
 	rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
 
-	/* set alarm two seconds from now */
+again:
+	/* set alarm one second from now */
 	omap_rtc_read_time_raw(rtc, &tm);
 	bcd2tm(&tm);
 	rtc_tm_to_time(&tm, &now);
-	rtc_time_to_tm(now + 2, &tm);
+	rtc_time_to_tm(now + 1, &tm);
 
 	if (tm2bcd(&tm) < 0) {
 		dev_err(&rtc->rtc->dev, "power off failed\n");
@@ -455,6 +456,10 @@ static void omap_rtc_power_off(void)
 
 	rtc_wait_not_busy(rtc);
 
+	/* Our calculations started right before the rollover, try again */
+	if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
+		goto again;
+
 	rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec);
 	rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min);
 	rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/4] rtc: OMAP: Add support for rtc-only mode
  2018-07-10  6:50 [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode Keerthy
  2018-07-10  6:50 ` [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec Keerthy
@ 2018-07-10  6:50 ` Keerthy
  2018-07-10  6:50 ` [PATCH v3 3/4] rtc: omap: use of_device_is_system_power_controller function Keerthy
  2018-07-10  6:50 ` [PATCH v3 4/4] rtc: interface: Add power_off_program to rtc_class_ops Keerthy
  3 siblings, 0 replies; 7+ messages in thread
From: Keerthy @ 2018-07-10  6:50 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni
  Cc: t-kristo, j-keerthy, linux-rtc, linux-omap, linux-kernel, johan

Prepare rtc driver for rtc-only with DDR in self-refresh mode.
omap_rtc_power_off now should cater to two features:

1) RTC plus DDR in self-refresh is power a saving mode where in the
entire system including the different voltage rails from PMIC are
shutdown except the ones feeding on to RTC and DDR. DDR is kept in
self-refresh hence the contents are preserved. RTC ALARM2 is connected
to PMIC_EN line once we the ALARM2 is triggered we enter the mode with
DDR in self-refresh and RTC Ticking. After a predetermined time an RTC
ALARM1 triggers waking up the system[1]. The control goes to bootloader.
The bootloader then checks RTC scratchpad registers to confirm it was an
rtc_only wakeup and follows a different path, configure bare minimal
clocks for ddr and then jumps to the resume address in another RTC
scratchpad registers and transfers the control to Kernel. Kernel then
restores the saved context. omap_rtc_power_off_program does the ALARM2
programming part.

     [1] http://www.ti.com/lit/ug/spruhl7h/spruhl7h.pdf Page 2884

2) Power-off: This is usual poweroff mode. omap_rtc_power_off calls the
above omap_rtc_power_off_program function and in addition to that
programs the OMAP_RTC_PMIC_REG for any external wake ups for PMIC like
the pushbutton and shuts off the PMIC.

Hence the split in omap_rtc_power_off.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 drivers/rtc/rtc-omap.c | 58 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 43 insertions(+), 15 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 14f2241..af46140 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -415,28 +415,23 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 
 static struct omap_rtc *omap_rtc_power_off_rtc;
 
-/*
- * omap_rtc_poweroff: RTC-controlled power off
- *
- * The RTC can be used to control an external PMIC via the pmic_power_en pin,
- * which can be configured to transition to OFF on ALARM2 events.
- *
- * Notes:
- * The two-second alarm offset is the shortest offset possible as the alarm
- * registers must be set before the next timer update and the offset
- * calculation is too heavy for everything to be done within a single access
- * period (~15 us).
- *
- * Called with local interrupts disabled.
+/**
+ * omap_rtc_power_off_program: Set the pmic power off sequence. The RTC
+ * generates pmic_pwr_enable control, which can be used to control an external
+ * PMIC.
  */
-static void omap_rtc_power_off(void)
+static int omap_rtc_power_off_program(struct device *dev)
 {
 	struct omap_rtc *rtc = omap_rtc_power_off_rtc;
 	struct rtc_time tm;
 	unsigned long now;
+	int seconds;
 	u32 val;
 
 	rtc->type->unlock(rtc);
+	/* Clear any existing ALARM2 event */
+	rtc_writel(rtc, OMAP_RTC_STATUS_REG, OMAP_RTC_STATUS_ALARM2);
+
 	/* enable pmic_power_en control */
 	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
 	rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
@@ -444,6 +439,7 @@ static void omap_rtc_power_off(void)
 again:
 	/* set alarm one second from now */
 	omap_rtc_read_time_raw(rtc, &tm);
+	seconds = tm.tm_sec;
 	bcd2tm(&tm);
 	rtc_tm_to_time(&tm, &now);
 	rtc_time_to_tm(now + 1, &tm);
@@ -451,7 +447,7 @@ static void omap_rtc_power_off(void)
 	if (tm2bcd(&tm) < 0) {
 		dev_err(&rtc->rtc->dev, "power off failed\n");
 		rtc->type->lock(rtc);
-		return;
+		return -EINVAL;
 	}
 
 	rtc_wait_not_busy(rtc);
@@ -477,6 +473,38 @@ static void omap_rtc_power_off(void)
 			val | OMAP_RTC_INTERRUPTS_IT_ALARM2);
 	rtc->type->lock(rtc);
 
+	return 0;
+}
+
+/*
+ * omap_rtc_poweroff: RTC-controlled power off
+ *
+ * The RTC can be used to control an external PMIC via the pmic_power_en pin,
+ * which can be configured to transition to OFF on ALARM2 events.
+ *
+ * Notes:
+ * The one-second alarm offset is the shortest offset possible as the alarm
+ * registers must be set before the next timer update and the offset
+ * calculation is too heavy for everything to be done within a single access
+ * period (~15 us).
+ *
+ * Called with local interrupts disabled.
+ */
+static void omap_rtc_power_off(void)
+{
+	struct rtc_device *rtc = omap_rtc_power_off_rtc->rtc;
+	u32 val;
+
+	omap_rtc_power_off_program(rtc->dev.parent);
+
+	/* Set PMIC power enable and EXT_WAKEUP in case PB power on is used */
+	omap_rtc_power_off_rtc->type->unlock(omap_rtc_power_off_rtc);
+	val = rtc_readl(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG);
+	val |= OMAP_RTC_PMIC_POWER_EN_EN | OMAP_RTC_PMIC_EXT_WKUP_POL(0) |
+			OMAP_RTC_PMIC_EXT_WKUP_EN(0);
+	rtc_writel(omap_rtc_power_off_rtc, OMAP_RTC_PMIC_REG, val);
+	omap_rtc_power_off_rtc->type->lock(omap_rtc_power_off_rtc);
+
 	/*
 	 * Wait for alarm to trigger (within two seconds) and external PMIC to
 	 * power off the system. Add a 500 ms margin for external latencies
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 3/4] rtc: omap: use of_device_is_system_power_controller function
  2018-07-10  6:50 [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode Keerthy
  2018-07-10  6:50 ` [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec Keerthy
  2018-07-10  6:50 ` [PATCH v3 2/4] rtc: OMAP: Add support for rtc-only mode Keerthy
@ 2018-07-10  6:50 ` Keerthy
  2018-07-10  6:50 ` [PATCH v3 4/4] rtc: interface: Add power_off_program to rtc_class_ops Keerthy
  3 siblings, 0 replies; 7+ messages in thread
From: Keerthy @ 2018-07-10  6:50 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni
  Cc: t-kristo, j-keerthy, linux-rtc, linux-omap, linux-kernel, johan

Use of_device_is_system_power_controller instead of manually reading
the system-power-controller property from the device tree node.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---
 drivers/rtc/rtc-omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index af46140..75a12eb 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -754,8 +754,7 @@ static int omap_rtc_probe(struct platform_device *pdev)
 	if (of_id) {
 		rtc->type = of_id->data;
 		rtc->is_pmic_controller = rtc->type->has_pmic_mode &&
-				of_property_read_bool(pdev->dev.of_node,
-						"system-power-controller");
+			of_device_is_system_power_controller(pdev->dev.of_node);
 	} else {
 		id_entry = platform_get_device_id(pdev);
 		rtc->type = (void *)id_entry->driver_data;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 4/4] rtc: interface: Add power_off_program to rtc_class_ops
  2018-07-10  6:50 [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode Keerthy
                   ` (2 preceding siblings ...)
  2018-07-10  6:50 ` [PATCH v3 3/4] rtc: omap: use of_device_is_system_power_controller function Keerthy
@ 2018-07-10  6:50 ` Keerthy
  3 siblings, 0 replies; 7+ messages in thread
From: Keerthy @ 2018-07-10  6:50 UTC (permalink / raw)
  To: a.zummo, alexandre.belloni
  Cc: t-kristo, j-keerthy, linux-rtc, linux-omap, linux-kernel, johan

Add an interface function to set up the rtc for a power_off
mode.

Signed-off-by: Keerthy <j-keerthy@ti.com>
---

Alexandre,

If you feel power_off_program will be very use case specific then
I can name this as custom_rtc_program so that even other rtc
drivers if need be can use this for a custom programming.

- Keerthy

 drivers/rtc/interface.c | 12 ++++++++++++
 drivers/rtc/rtc-omap.c  |  1 +
 include/linux/rtc.h     |  2 ++
 3 files changed, 15 insertions(+)

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 6d4012d..c19668b9 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -1139,3 +1139,15 @@ int rtc_set_offset(struct rtc_device *rtc, long offset)
 	trace_rtc_set_offset(offset, ret);
 	return ret;
 }
+
+/**
+ * rtc_power_off_program - Some of the rtc are hooked on to PMIC_EN
+ * line and can be used to power off the SoC.
+ *
+ * Kernel interface to program rtc to power off
+ */
+int rtc_power_off_program(struct rtc_device *rtc)
+{
+	return rtc->ops->power_off_program(rtc->dev.parent);
+}
+EXPORT_SYMBOL_GPL(rtc_power_off_program);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 75a12eb..a1f9dde 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -519,6 +519,7 @@ static void omap_rtc_power_off(void)
 	.read_alarm	= omap_rtc_read_alarm,
 	.set_alarm	= omap_rtc_set_alarm,
 	.alarm_irq_enable = omap_rtc_alarm_irq_enable,
+	.power_off_program = omap_rtc_power_off_program,
 };
 
 static const struct omap_rtc_device_type omap_rtc_default_type = {
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 6268208..3fc640c 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -85,6 +85,7 @@ struct rtc_class_ops {
 	int (*alarm_irq_enable)(struct device *, unsigned int enabled);
 	int (*read_offset)(struct device *, long *offset);
 	int (*set_offset)(struct device *, long offset);
+	int (*power_off_program)(struct device *dev);
 };
 
 typedef struct rtc_task {
@@ -229,6 +230,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer *timer,
 int rtc_read_offset(struct rtc_device *rtc, long *offset);
 int rtc_set_offset(struct rtc_device *rtc, long offset);
 void rtc_timer_do_work(struct work_struct *work);
+int rtc_power_off_program(struct rtc_device *rtc);
 
 static inline bool is_leap_year(unsigned int year)
 {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  2018-07-10  6:50 ` [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec Keerthy
@ 2018-07-11 13:54   ` Johan Hovold
  2018-07-11 16:16     ` J, KEERTHY
  0 siblings, 1 reply; 7+ messages in thread
From: Johan Hovold @ 2018-07-11 13:54 UTC (permalink / raw)
  To: Keerthy
  Cc: a.zummo, alexandre.belloni, t-kristo, linux-rtc, linux-omap,
	linux-kernel, johan

On Tue, Jul 10, 2018 at 12:20:49PM +0530, Keerthy wrote:
> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
> over try again.
> 
> Signed-off-by: Keerthy <j-keerthy@ti.com>
> ---
>  drivers/rtc/rtc-omap.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
> index 323ff55..14f2241 100644
> --- a/drivers/rtc/rtc-omap.c
> +++ b/drivers/rtc/rtc-omap.c
> @@ -441,11 +441,12 @@ static void omap_rtc_power_off(void)
>  	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>  	rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>  
> -	/* set alarm two seconds from now */
> +again:
> +	/* set alarm one second from now */
>  	omap_rtc_read_time_raw(rtc, &tm);
>  	bcd2tm(&tm);
>  	rtc_tm_to_time(&tm, &now);
> -	rtc_time_to_tm(now + 2, &tm);
> +	rtc_time_to_tm(now + 1, &tm);
>  
>  	if (tm2bcd(&tm) < 0) {
>  		dev_err(&rtc->rtc->dev, "power off failed\n");
> @@ -455,6 +456,10 @@ static void omap_rtc_power_off(void)
>  
>  	rtc_wait_not_busy(rtc);
>  
> +	/* Our calculations started right before the rollover, try again */
> +	if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
> +		goto again;

First, this doesn't even compile.

Second, nothing is preventing the rollover from happening here after the
check. 

> +
>  	rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec);
>  	rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min);
>  	rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour);

Johan

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec
  2018-07-11 13:54   ` Johan Hovold
@ 2018-07-11 16:16     ` J, KEERTHY
  0 siblings, 0 replies; 7+ messages in thread
From: J, KEERTHY @ 2018-07-11 16:16 UTC (permalink / raw)
  To: Johan Hovold
  Cc: a.zummo, alexandre.belloni, t-kristo, linux-rtc, linux-omap,
	linux-kernel



On 7/11/2018 7:24 PM, Johan Hovold wrote:
> On Tue, Jul 10, 2018 at 12:20:49PM +0530, Keerthy wrote:
>> Cut down the shutdown time from 2 seconds to 1 sec. In case of roll
>> over try again.
>>
>> Signed-off-by: Keerthy <j-keerthy@ti.com>
>> ---
>>   drivers/rtc/rtc-omap.c | 9 +++++++--
>>   1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
>> index 323ff55..14f2241 100644
>> --- a/drivers/rtc/rtc-omap.c
>> +++ b/drivers/rtc/rtc-omap.c
>> @@ -441,11 +441,12 @@ static void omap_rtc_power_off(void)
>>   	val = rtc_readl(rtc, OMAP_RTC_PMIC_REG);
>>   	rtc_writel(rtc, OMAP_RTC_PMIC_REG, val | OMAP_RTC_PMIC_POWER_EN_EN);
>>   
>> -	/* set alarm two seconds from now */
>> +again:
>> +	/* set alarm one second from now */
>>   	omap_rtc_read_time_raw(rtc, &tm);
>>   	bcd2tm(&tm);
>>   	rtc_tm_to_time(&tm, &now);
>> -	rtc_time_to_tm(now + 2, &tm);
>> +	rtc_time_to_tm(now + 1, &tm);
>>   
>>   	if (tm2bcd(&tm) < 0) {
>>   		dev_err(&rtc->rtc->dev, "power off failed\n");
>> @@ -455,6 +456,10 @@ static void omap_rtc_power_off(void)
>>   
>>   	rtc_wait_not_busy(rtc);
>>   
>> +	/* Our calculations started right before the rollover, try again */
>> +	if (seconds != rtc_read(omap_rtc_power_off_rtc, OMAP_RTC_SECONDS_REG))
>> +		goto again;
> 
> First, this doesn't even compile.

My bad. seconds got introduced in patch 2 and i did not compile test 
this one individually. Apologies for that.

> 
> Second, nothing is preventing the rollover from happening here after the
> check.

Okay. That window cannot be ignored. So 'now + 2' will surely solve 
that. I will stick to that.

> 
>> +
>>   	rtc_write(rtc, OMAP_RTC_ALARM2_SECONDS_REG, tm.tm_sec);
>>   	rtc_write(rtc, OMAP_RTC_ALARM2_MINUTES_REG, tm.tm_min);
>>   	rtc_write(rtc, OMAP_RTC_ALARM2_HOURS_REG, tm.tm_hour);
> 
> Johan
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-07-11 16:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-10  6:50 [PATCH v3 0/4] rtc: OMAP: Add support for rtc-only mode Keerthy
2018-07-10  6:50 ` [PATCH v3 1/4] rtc: omap: Cut down the shutdown time from 2 seconds to 1 sec Keerthy
2018-07-11 13:54   ` Johan Hovold
2018-07-11 16:16     ` J, KEERTHY
2018-07-10  6:50 ` [PATCH v3 2/4] rtc: OMAP: Add support for rtc-only mode Keerthy
2018-07-10  6:50 ` [PATCH v3 3/4] rtc: omap: use of_device_is_system_power_controller function Keerthy
2018-07-10  6:50 ` [PATCH v3 4/4] rtc: interface: Add power_off_program to rtc_class_ops Keerthy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).