All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Introduce STM32MP1 RTC
@ 2018-04-19 13:34 ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

Amelie Delaunay (3):
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 272 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 70 deletions(-)

-- 
2.7.4

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

* [PATCH 0/3] Introduce STM32MP1 RTC
@ 2018-04-19 13:34 ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

Amelie Delaunay (3):
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 272 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 70 deletions(-)

-- 
2.7.4

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

* [PATCH 0/3] Introduce STM32MP1 RTC
@ 2018-04-19 13:34 ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

This series introduces STM32MP1 RTC.
On STM32MP1:
- two clocks are needed, plck and rtc_ck;
- to wakeup the system, a wakeup alarm interrupt is needed;
- some registers or bits have moved, but the operation is the same;
- the Backup Domain Protection (DBP) is not managed by RTC driver.

Amelie Delaunay (3):
  rtc: stm32: rework register management to prepare other version of RTC
  dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  rtc: stm32: add stm32mp1 rtc support

 .../devicetree/bindings/rtc/st,stm32-rtc.txt       |  27 +-
 drivers/rtc/rtc-stm32.c                            | 272 ++++++++++++++++-----
 2 files changed, 229 insertions(+), 70 deletions(-)

-- 
2.7.4

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

* [PATCH 1/3] rtc: stm32: rework register management to prepare other version of RTC
  2018-04-19 13:34 ` Amelie Delaunay
  (?)
@ 2018-04-19 13:34   ` Amelie Delaunay
  -1 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 188 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 129 insertions(+), 59 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..52ee027 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs.wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs.wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs.wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs.isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs.isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs.isr);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts.alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts.alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs.tr);
+	dr = readl_relaxed(rtc->base + regs.dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs.tr);
+	writel_relaxed(dr, rtc->base + regs.dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs.alrmar);
+	cr = readl_relaxed(rtc->base + regs.cr);
+	status = readl_relaxed(rtc->base + regs.isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts.alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts.alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs.dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs.tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs.alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs.isr) & ~flags,
+		       rtc->base + regs.isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	struct stm32_rtc_registers regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -641,7 +710,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +735,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH 1/3] rtc: stm32: rework register management to prepare other version of RTC
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 188 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 129 insertions(+), 59 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..52ee027 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs.wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs.wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs.wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs.isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs.isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs.isr);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts.alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts.alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs.tr);
+	dr = readl_relaxed(rtc->base + regs.dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs.tr);
+	writel_relaxed(dr, rtc->base + regs.dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs.alrmar);
+	cr = readl_relaxed(rtc->base + regs.cr);
+	status = readl_relaxed(rtc->base + regs.isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts.alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts.alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs.dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs.tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs.alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs.isr) & ~flags,
+		       rtc->base + regs.isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	struct stm32_rtc_registers regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -641,7 +710,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +735,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH 1/3] rtc: stm32: rework register management to prepare other version of RTC
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

This patch reworks register/bits management because next version of RTC
uses the same way of working but with different register's offset or bits
moved in new registers.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 188 +++++++++++++++++++++++++++++++++---------------
 1 file changed, 129 insertions(+), 59 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index de49b5b..52ee027 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -16,15 +16,6 @@
 
 #define DRIVER_NAME "stm32_rtc"
 
-/* STM32 RTC registers */
-#define STM32_RTC_TR		0x00
-#define STM32_RTC_DR		0x04
-#define STM32_RTC_CR		0x08
-#define STM32_RTC_ISR		0x0C
-#define STM32_RTC_PRER		0x10
-#define STM32_RTC_ALRMAR	0x1C
-#define STM32_RTC_WPR		0x24
-
 /* STM32_RTC_TR bit fields  */
 #define STM32_RTC_TR_SEC_SHIFT		0
 #define STM32_RTC_TR_SEC		GENMASK(6, 0)
@@ -85,7 +76,26 @@
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+struct stm32_rtc;
+
+struct stm32_rtc_registers {
+	u8 tr;
+	u8 dr;
+	u8 cr;
+	u8 isr;
+	u8 prer;
+	u8 alrmar;
+	u8 wpr;
+};
+
+struct stm32_rtc_events {
+	u32 alra;
+};
+
 struct stm32_rtc_data {
+	const struct stm32_rtc_registers regs;
+	const struct stm32_rtc_events events;
+	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
 };
@@ -96,30 +106,35 @@ struct stm32_rtc {
 	struct regmap *dbp;
 	unsigned int dbp_reg;
 	unsigned int dbp_mask;
-	struct stm32_rtc_data *data;
 	struct clk *pclk;
 	struct clk *rtc_ck;
+	const struct stm32_rtc_data *data;
 	int irq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR);
-	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + regs.wpr);
+	writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + regs.wpr);
 }
 
 static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 {
-	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs.wpr);
 }
 
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	if (!(isr & STM32_RTC_ISR_INITF)) {
 		isr |= STM32_RTC_ISR_INIT;
-		writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+		writel_relaxed(isr, rtc->base + regs.isr);
 
 		/*
 		 * It takes around 2 rtc_ck clock cycles to enter in
@@ -128,7 +143,7 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 		 * 1MHz, we poll every 10 us with a timeout of 100ms.
 		 */
 		return readl_relaxed_poll_timeout_atomic(
-					rtc->base + STM32_RTC_ISR,
+					rtc->base + regs.isr,
 					isr, (isr & STM32_RTC_ISR_INITF),
 					10, 100000);
 	}
@@ -138,40 +153,50 @@ static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 
 static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_INIT;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 }
 
 static int stm32_rtc_wait_sync(struct stm32_rtc *rtc)
 {
-	unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int isr = readl_relaxed(rtc->base + regs.isr);
 
 	isr &= ~STM32_RTC_ISR_RSF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	writel_relaxed(isr, rtc->base + regs.isr);
 
 	/*
 	 * Wait for RSF to be set to ensure the calendar registers are
 	 * synchronised, it takes around 2 rtc_ck clock cycles
 	 */
-	return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	return readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						 isr,
 						 (isr & STM32_RTC_ISR_RSF),
 						 10, 100000);
 }
 
+static void stm32_rtc_clear_event_flags(struct stm32_rtc *rtc,
+					unsigned int flags)
+{
+	rtc->data->clear_events(rtc, flags);
+}
+
 static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 {
 	struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id;
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int status, cr;
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	status = readl_relaxed(rtc->base + regs.isr);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
-	if ((isr & STM32_RTC_ISR_ALRAF) &&
+	if ((status & evts.alra) &&
 	    (cr & STM32_RTC_CR_ALRAIE)) {
 		/* Alarm A flag - Alarm interrupt */
 		dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n");
@@ -179,9 +204,8 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 		/* Pass event to the kernel */
 		rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
 
-		/* Clear event flag, otherwise new events won't be received */
-		writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF,
-			       rtc->base + STM32_RTC_ISR);
+		/* Clear event flags, otherwise new events won't be received */
+		stm32_rtc_clear_event_flags(rtc, evts.alra);
 	}
 
 	mutex_unlock(&rtc->rtc_dev->ops_lock);
@@ -228,11 +252,12 @@ static void bcd2tm(struct rtc_time *tm)
 static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 
 	/* Time and Date in BCD format */
-	tr = readl_relaxed(rtc->base + STM32_RTC_TR);
-	dr = readl_relaxed(rtc->base + STM32_RTC_DR);
+	tr = readl_relaxed(rtc->base + regs.tr);
+	dr = readl_relaxed(rtc->base + regs.dr);
 
 	tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT;
 	tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT;
@@ -253,6 +278,7 @@ static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int tr, dr;
 	int ret = 0;
 
@@ -277,8 +303,8 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 		goto end;
 	}
 
-	writel_relaxed(tr, rtc->base + STM32_RTC_TR);
-	writel_relaxed(dr, rtc->base + STM32_RTC_DR);
+	writel_relaxed(tr, rtc->base + regs.tr);
+	writel_relaxed(dr, rtc->base + regs.dr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -292,12 +318,14 @@ static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm)
 static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
 	struct rtc_time *tm = &alrm->time;
-	unsigned int alrmar, cr, isr;
+	unsigned int alrmar, cr, status;
 
-	alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
+	alrmar = readl_relaxed(rtc->base + regs.alrmar);
+	cr = readl_relaxed(rtc->base + regs.cr);
+	status = readl_relaxed(rtc->base + regs.isr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -350,7 +378,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	bcd2tm(tm);
 
 	alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0;
-	alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0;
+	alrm->pending = (status & evts.alra) ? 1 : 0;
 
 	return 0;
 }
@@ -358,9 +386,11 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
-	unsigned int isr, cr;
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	struct stm32_rtc_events evts = rtc->data->events;
+	unsigned int cr;
 
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 
 	stm32_rtc_wpr_unlock(rtc);
 
@@ -369,12 +399,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 		cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
 	else
 		cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE);
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
-	/* Clear event flag, otherwise new events won't be received */
-	isr = readl_relaxed(rtc->base + STM32_RTC_ISR);
-	isr &= ~STM32_RTC_ISR_ALRAF;
-	writel_relaxed(isr, rtc->base + STM32_RTC_ISR);
+	/* Clear event flags, otherwise new events won't be received */
+	stm32_rtc_clear_event_flags(rtc, evts.alra);
 
 	stm32_rtc_wpr_lock(rtc);
 
@@ -383,9 +411,10 @@ static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
 static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec;
-	unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR);
-	unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR);
+	unsigned int dr = readl_relaxed(rtc->base + regs.dr);
+	unsigned int tr = readl_relaxed(rtc->base + regs.tr);
 
 	cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT;
 	cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT;
@@ -419,6 +448,7 @@ static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm)
 static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
 	struct stm32_rtc *rtc = dev_get_drvdata(dev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	struct rtc_time *tm = &alrm->time;
 	unsigned int cr, isr, alrmar;
 	int ret = 0;
@@ -450,15 +480,15 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	stm32_rtc_wpr_unlock(rtc);
 
 	/* Disable Alarm */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	/*
 	 * Poll Alarm write flag to be sure that Alarm update is allowed: it
 	 * takes around 2 rtc_ck clock cycles
 	 */
-	ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR,
+	ret = readl_relaxed_poll_timeout_atomic(rtc->base + regs.isr,
 						isr,
 						(isr & STM32_RTC_ISR_ALRAWF),
 						10, 100000);
@@ -469,7 +499,7 @@ static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 	}
 
 	/* Write to Alarm register */
-	writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR);
+	writel_relaxed(alrmar, rtc->base + regs.alrmar);
 
 	if (alrm->enabled)
 		stm32_rtc_alarm_irq_enable(dev, 1);
@@ -490,14 +520,50 @@ static const struct rtc_class_ops stm32_rtc_ops = {
 	.alarm_irq_enable = stm32_rtc_alarm_irq_enable,
 };
 
+static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
+				   unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 0 in RTC_ISR */
+	writel_relaxed(readl_relaxed(rtc->base + regs.isr) & ~flags,
+		       rtc->base + regs.isr);
+}
+
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x08,
+		.isr = 0x0C,
+		.prer = 0x10,
+		.alrmar = 0x1C,
+		.wpr = 0x24,
+	},
+	.events = {
+		.alra = STM32_RTC_ISR_ALRAF,
+	},
+	.clear_events = stm32_rtc_clear_events,
 };
 
 static const struct of_device_id stm32_rtc_of_match[] = {
@@ -510,6 +576,7 @@ MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
 static int stm32_rtc_init(struct platform_device *pdev,
 			  struct stm32_rtc *rtc)
 {
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr;
 	unsigned int rate;
 	int ret = 0;
@@ -550,14 +617,14 @@ static int stm32_rtc_init(struct platform_device *pdev,
 	}
 
 	prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 	prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A;
-	writel_relaxed(prer, rtc->base + STM32_RTC_PRER);
+	writel_relaxed(prer, rtc->base + regs.prer);
 
 	/* Force 24h time format */
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_FMT;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 
 	stm32_rtc_exit_init_mode(rtc);
 
@@ -571,6 +638,7 @@ static int stm32_rtc_init(struct platform_device *pdev,
 static int stm32_rtc_probe(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc;
+	struct stm32_rtc_registers regs;
 	struct resource *res;
 	int ret;
 
@@ -585,6 +653,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	rtc->data = (struct stm32_rtc_data *)
 		    of_device_get_match_data(&pdev->dev);
+	regs = rtc->data->regs;
 
 	if (rtc->data->need_dbp) {
 		rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
@@ -641,7 +710,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 
 	/*
 	 * After a system reset, RTC_ISR.INITS flag can be read to check if
-	 * the calendar has been initalized or not. INITS flag is reset by a
+	 * the calendar has been initialized or not. INITS flag is reset by a
 	 * power-on reset (no vbat, no power-supply). It is not reset if
 	 * rtc_ck parent clock has changed (so RTC prescalers need to be
 	 * changed). That's why we cannot rely on this flag to know if RTC
@@ -666,7 +735,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 			 "alarm won't be able to wake up the system");
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
-			&stm32_rtc_ops, THIS_MODULE);
+						&stm32_rtc_ops, THIS_MODULE);
 	if (IS_ERR(rtc->rtc_dev)) {
 		ret = PTR_ERR(rtc->rtc_dev);
 		dev_err(&pdev->dev, "rtc device registration failed, err=%d\n",
@@ -688,7 +757,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
 	 */
-	if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS))
+	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
 	return 0;
@@ -708,13 +777,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 static int stm32_rtc_remove(struct platform_device *pdev)
 {
 	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
 	unsigned int cr;
 
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
-	cr = readl_relaxed(rtc->base + STM32_RTC_CR);
+	cr = readl_relaxed(rtc->base + regs.cr);
 	cr &= ~STM32_RTC_CR_ALRAIE;
-	writel_relaxed(cr, rtc->base + STM32_RTC_CR);
+	writel_relaxed(cr, rtc->base + regs.cr);
 	stm32_rtc_wpr_lock(rtc);
 
 	clk_disable_unprepare(rtc->rtc_ck);
-- 
2.7.4

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

* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  2018-04-19 13:34 ` Amelie Delaunay
  (?)
@ 2018-04-19 13:34   ` Amelie Delaunay
  -1 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..f1c2080 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,31 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
+	      depending on the device is compatible with stm32(f4/f7), stm32h7
+	      or stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
+    It is required on stm32(f4/f7/h7/mp1).
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
+    It is required on stm32(f4/f7/h7).
 - interrupts: rtc alarm interrupt.
+- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
+  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
+    It is required on stm32mp1.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +54,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc@5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..f1c2080 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,31 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
+	      depending on the device is compatible with stm32(f4/f7), stm32h7
+	      or stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
+    It is required on stm32(f4/f7/h7/mp1).
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
+    It is required on stm32(f4/f7/h7).
 - interrupts: rtc alarm interrupt.
+- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
+  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
+    It is required on stm32mp1.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +54,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc@5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
doesn't require to disable backup domain write protection, and rtc_ck
parent clock assignment isn't allowed.
To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
alarm interrupt.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
index 00f8b5d..f1c2080 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
@@ -1,25 +1,31 @@
 STM32 Real Time Clock
 
 Required properties:
-- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
-  the device is compatible with stm32(f4/f7) or stm32h7.
+- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
+	      depending on the device is compatible with stm32(f4/f7), stm32h7
+	      or stm32mp1.
 - reg: address range of rtc register set.
 - clocks: can use up to two clocks, depending on part used:
   - "rtc_ck": RTC clock source.
-    It is required on stm32(f4/f7) and stm32h7.
+    It is required on stm32(f4/f7/h7/mp1).
   - "pclk": RTC APB interface clock.
     It is not present on stm32(f4/f7).
-    It is required on stm32h7.
+    It is required on stm32(h7/mp1).
 - clock-names: must be "rtc_ck" and "pclk".
-    It is required only on stm32h7.
+    It is required on stm32(h7/mp1).
 - interrupt-parent: phandle for the interrupt controller.
+    It is required on stm32(f4/f7/h7).
 - interrupts: rtc alarm interrupt.
+- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
+  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
+    It is required on stm32mp1.
 - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
   access control register at offset, and change the dbp (Disable Backup
   Protection) bit represented by the mask, mandatory to disable/enable backup
   domain (RTC registers) write protection.
+    It is required on stm32(f4/f7/h7).
 
-Optional properties (to override default rtc_ck parent clock):
+Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
 - assigned-clocks: reference to the rtc_ck clock entry.
 - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
 
@@ -48,3 +54,12 @@ Example:
 		interrupt-names = "alarm";
 		st,syscfg = <&pwrcfg 0x00 0x100>;
 	};
+
+	rtc: rtc at 5c004000 {
+		compatible = "st,stm32mp1-rtc";
+		reg = <0x5c004000 0x400>;
+		clocks = <&rcc RTCAPB>, <&rcc RTC>;
+		clock-names = "pclk", "rtc_ck";
+		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
+				      <&exti 19 1>;
+	};
-- 
2.7.4

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

* [PATCH 3/3] rtc: stm32: add stm32mp1 rtc support
  2018-04-19 13:34 ` Amelie Delaunay
  (?)
@ 2018-04-19 13:34   ` Amelie Delaunay
  -1 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 88 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 52ee027..45e0175 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,11 +72,22 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+#define UNDEF_REG ~0
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
@@ -86,6 +98,9 @@ struct stm32_rtc_registers {
 	u8 prer;
 	u8 alrmar;
 	u8 wpr;
+	u8 sr;
+	u8 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +113,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +126,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +210,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 	cr = readl_relaxed(rtc->base + regs.cr);
 
 	if ((status & evts.alra) &&
@@ -325,7 +342,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs.alrmar);
 	cr = readl_relaxed(rtc->base + regs.cr);
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +550,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +559,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +572,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +581,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +591,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +784,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +824,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs.verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs.verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +841,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +868,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* [PATCH 3/3] rtc: stm32: add stm32mp1 rtc support
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: Alessandro Zummo, Alexandre Belloni, Rob Herring, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue
  Cc: linux-rtc, devicetree, linux-arm-kernel, linux-kernel, Amelie Delaunay

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 88 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 52ee027..45e0175 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,11 +72,22 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+#define UNDEF_REG ~0
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
@@ -86,6 +98,9 @@ struct stm32_rtc_registers {
 	u8 prer;
 	u8 alrmar;
 	u8 wpr;
+	u8 sr;
+	u8 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +113,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +126,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +210,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 	cr = readl_relaxed(rtc->base + regs.cr);
 
 	if ((status & evts.alra) &&
@@ -325,7 +342,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs.alrmar);
 	cr = readl_relaxed(rtc->base + regs.cr);
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +550,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +559,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +572,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +581,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +591,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +784,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +824,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs.verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs.verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +841,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +868,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* [PATCH 3/3] rtc: stm32: add stm32mp1 rtc support
@ 2018-04-19 13:34   ` Amelie Delaunay
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie Delaunay @ 2018-04-19 13:34 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support for stm32mp1 RTC.
Some common registers with previous RTC version have a different offset.
It is the case for Control Register (CR) and ALaRMA Register (ALRMAR).
There are also new registers regarding event flags: now, Alarm event flag
is in Status Register (SR) and write 1 in Status Clear Register (SCR) is
required to clear the event.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/rtc/rtc-stm32.c | 88 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index 52ee027..45e0175 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -11,6 +11,7 @@
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_wakeirq.h>
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
@@ -39,7 +40,7 @@
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
 
-/* STM32_RTC_ISR bit fields */
+/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
 #define STM32_RTC_ISR_INITS		BIT(4)
 #define STM32_RTC_ISR_RSF		BIT(5)
@@ -71,11 +72,22 @@
 #define STM32_RTC_ALRMXR_WDAY		GENMASK(27, 24)
 #define STM32_RTC_ALRMXR_DATE_MASK	BIT(31)
 
+/* STM32_RTC_SR/_SCR bit fields */
+#define STM32_RTC_SR_ALRA		BIT(0)
+
+/* STM32_RTC_VERR bit fields */
+#define STM32_RTC_VERR_MINREV_SHIFT	0
+#define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
+#define STM32_RTC_VERR_MAJREV_SHIFT	4
+#define STM32_RTC_VERR_MAJREV		GENMASK(7, 4)
+
 /* STM32_RTC_WPR key constants */
 #define RTC_WPR_1ST_KEY			0xCA
 #define RTC_WPR_2ND_KEY			0x53
 #define RTC_WPR_WRONG_KEY		0xFF
 
+#define UNDEF_REG ~0
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
@@ -86,6 +98,9 @@ struct stm32_rtc_registers {
 	u8 prer;
 	u8 alrmar;
 	u8 wpr;
+	u8 sr;
+	u8 scr;
+	u16 verr;
 };
 
 struct stm32_rtc_events {
@@ -98,6 +113,7 @@ struct stm32_rtc_data {
 	void (*clear_events)(struct stm32_rtc *rtc, unsigned int flags);
 	bool has_pclk;
 	bool need_dbp;
+	bool has_wakeirq;
 };
 
 struct stm32_rtc {
@@ -110,6 +126,7 @@ struct stm32_rtc {
 	struct clk *rtc_ck;
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
+	int wakeirq_alarm;
 };
 
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
@@ -193,7 +210,7 @@ static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id)
 
 	mutex_lock(&rtc->rtc_dev->ops_lock);
 
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 	cr = readl_relaxed(rtc->base + regs.cr);
 
 	if ((status & evts.alra) &&
@@ -325,7 +342,7 @@ static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 
 	alrmar = readl_relaxed(rtc->base + regs.alrmar);
 	cr = readl_relaxed(rtc->base + regs.cr);
-	status = readl_relaxed(rtc->base + regs.isr);
+	status = readl_relaxed(rtc->base + regs.sr);
 
 	if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) {
 		/*
@@ -533,6 +550,7 @@ static void stm32_rtc_clear_events(struct stm32_rtc *rtc,
 static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -541,6 +559,9 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -551,6 +572,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
+	.has_wakeirq = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -559,6 +581,9 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.prer = 0x10,
 		.alrmar = 0x1C,
 		.wpr = 0x24,
+		.sr = 0x0C, /* set to ISR offset to ease alarm management */
+		.scr = UNDEF_REG,
+		.verr = UNDEF_REG,
 	},
 	.events = {
 		.alra = STM32_RTC_ISR_ALRAF,
@@ -566,9 +591,41 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.clear_events = stm32_rtc_clear_events,
 };
 
+static void stm32mp1_rtc_clear_events(struct stm32_rtc *rtc,
+				      unsigned int flags)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+
+	/* Flags are cleared by writing 1 in RTC_SCR */
+	writel_relaxed(flags, rtc->base + regs.scr);
+}
+
+static const struct stm32_rtc_data stm32mp1_data = {
+	.has_pclk = true,
+	.need_dbp = false,
+	.has_wakeirq = true,
+	.regs = {
+		.tr = 0x00,
+		.dr = 0x04,
+		.cr = 0x18,
+		.isr = 0x0C, /* named RTC_ICSR on stm32mp1 */
+		.prer = 0x10,
+		.alrmar = 0x40,
+		.wpr = 0x24,
+		.sr = 0x50,
+		.scr = 0x5C,
+		.verr = 0x3F4,
+	},
+	.events = {
+		.alra = STM32_RTC_SR_ALRA,
+	},
+	.clear_events = stm32mp1_rtc_clear_events,
+};
+
 static const struct of_device_id stm32_rtc_of_match[] = {
 	{ .compatible = "st,stm32-rtc", .data = &stm32_rtc_data },
 	{ .compatible = "st,stm32h7-rtc", .data = &stm32h7_rtc_data },
+	{ .compatible = "st,stm32mp1-rtc", .data = &stm32mp1_data },
 	{}
 };
 MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
@@ -727,12 +784,19 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	platform_set_drvdata(pdev, rtc);
-
 	ret = device_init_wakeup(&pdev->dev, true);
+	if (rtc->data->has_wakeirq) {
+		rtc->wakeirq_alarm = platform_get_irq(pdev, 1);
+		if (rtc->wakeirq_alarm <= 0)
+			ret = rtc->wakeirq_alarm;
+		else
+			ret = dev_pm_set_dedicated_wake_irq(&pdev->dev,
+							    rtc->wakeirq_alarm);
+	}
 	if (ret)
-		dev_warn(&pdev->dev,
-			 "alarm won't be able to wake up the system");
+		dev_warn(&pdev->dev, "alarm can't wake up the system: %d", ret);
+
+	platform_set_drvdata(pdev, rtc);
 
 	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
 						&stm32_rtc_ops, THIS_MODULE);
@@ -760,6 +824,14 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (!(readl_relaxed(rtc->base + regs.isr) & STM32_RTC_ISR_INITS))
 		dev_warn(&pdev->dev, "Date/Time must be initialized\n");
 
+	if (regs.verr != UNDEF_REG) {
+		u32 ver = readl_relaxed(rtc->base + regs.verr);
+
+		dev_info(&pdev->dev, "registered rev:%d.%d\n",
+			 (ver >> STM32_RTC_VERR_MAJREV_SHIFT) & 0xF,
+			 (ver >> STM32_RTC_VERR_MINREV_SHIFT) & 0xF);
+	}
+
 	return 0;
 err:
 	if (rtc->data->has_pclk)
@@ -769,6 +841,7 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return ret;
@@ -795,6 +868,7 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	if (rtc->data->need_dbp)
 		regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0);
 
+	dev_pm_clear_wake_irq(&pdev->dev);
 	device_init_wakeup(&pdev->dev, false);
 
 	return 0;
-- 
2.7.4

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

* Re: [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  2018-04-19 13:34   ` Amelie Delaunay
@ 2018-04-27  3:01     ` Rob Herring
  -1 siblings, 0 replies; 18+ messages in thread
From: Rob Herring @ 2018-04-27  3:01 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Alessandro Zummo, Alexandre Belloni, Mark Rutland,
	Maxime Coquelin, Alexandre Torgue, linux-rtc, devicetree,
	linux-arm-kernel, linux-kernel

On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
> doesn't require to disable backup domain write protection, and rtc_ck
> parent clock assignment isn't allowed.
> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
> alarm interrupt.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
> ---
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> index 00f8b5d..f1c2080 100644
> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> @@ -1,25 +1,31 @@
>  STM32 Real Time Clock
>  
>  Required properties:
> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
> -  the device is compatible with stm32(f4/f7) or stm32h7.
> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
> +	      depending on the device is compatible with stm32(f4/f7), stm32h7
> +	      or stm32mp1.

One compatible per line please.

>  - reg: address range of rtc register set.
>  - clocks: can use up to two clocks, depending on part used:
>    - "rtc_ck": RTC clock source.
> -    It is required on stm32(f4/f7) and stm32h7.
> +    It is required on stm32(f4/f7/h7/mp1).

IOW, required for all?

>    - "pclk": RTC APB interface clock.
>      It is not present on stm32(f4/f7).
> -    It is required on stm32h7.
> +    It is required on stm32(h7/mp1).
>  - clock-names: must be "rtc_ck" and "pclk".
> -    It is required only on stm32h7.
> +    It is required on stm32(h7/mp1).
>  - interrupt-parent: phandle for the interrupt controller.
> +    It is required on stm32(f4/f7/h7).
>  - interrupts: rtc alarm interrupt.
> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
> +  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
> +    It is required on stm32mp1.

Just document 'interrupts'. interrupts-extended is implicitly supported 
and what the interrupts are connected to is outside the scope of this 
binding.

>  - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>    access control register at offset, and change the dbp (Disable Backup
>    Protection) bit represented by the mask, mandatory to disable/enable backup
>    domain (RTC registers) write protection.
> +    It is required on stm32(f4/f7/h7).
>  
> -Optional properties (to override default rtc_ck parent clock):
> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>  - assigned-clocks: reference to the rtc_ck clock entry.
>  - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>  
> @@ -48,3 +54,12 @@ Example:
>  		interrupt-names = "alarm";
>  		st,syscfg = <&pwrcfg 0x00 0x100>;
>  	};
> +
> +	rtc: rtc@5c004000 {
> +		compatible = "st,stm32mp1-rtc";
> +		reg = <0x5c004000 0x400>;
> +		clocks = <&rcc RTCAPB>, <&rcc RTC>;
> +		clock-names = "pclk", "rtc_ck";
> +		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
> +				      <&exti 19 1>;
> +	};
> -- 
> 2.7.4
> 

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

* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-04-27  3:01     ` Rob Herring
  0 siblings, 0 replies; 18+ messages in thread
From: Rob Herring @ 2018-04-27  3:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
> doesn't require to disable backup domain write protection, and rtc_ck
> parent clock assignment isn't allowed.
> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
> alarm interrupt.
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
> ---
>  .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> index 00f8b5d..f1c2080 100644
> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
> @@ -1,25 +1,31 @@
>  STM32 Real Time Clock
>  
>  Required properties:
> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
> -  the device is compatible with stm32(f4/f7) or stm32h7.
> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
> +	      depending on the device is compatible with stm32(f4/f7), stm32h7
> +	      or stm32mp1.

One compatible per line please.

>  - reg: address range of rtc register set.
>  - clocks: can use up to two clocks, depending on part used:
>    - "rtc_ck": RTC clock source.
> -    It is required on stm32(f4/f7) and stm32h7.
> +    It is required on stm32(f4/f7/h7/mp1).

IOW, required for all?

>    - "pclk": RTC APB interface clock.
>      It is not present on stm32(f4/f7).
> -    It is required on stm32h7.
> +    It is required on stm32(h7/mp1).
>  - clock-names: must be "rtc_ck" and "pclk".
> -    It is required only on stm32h7.
> +    It is required on stm32(h7/mp1).
>  - interrupt-parent: phandle for the interrupt controller.
> +    It is required on stm32(f4/f7/h7).
>  - interrupts: rtc alarm interrupt.
> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
> +  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
> +    It is required on stm32mp1.

Just document 'interrupts'. interrupts-extended is implicitly supported 
and what the interrupts are connected to is outside the scope of this 
binding.

>  - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>    access control register at offset, and change the dbp (Disable Backup
>    Protection) bit represented by the mask, mandatory to disable/enable backup
>    domain (RTC registers) write protection.
> +    It is required on stm32(f4/f7/h7).
>  
> -Optional properties (to override default rtc_ck parent clock):
> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>  - assigned-clocks: reference to the rtc_ck clock entry.
>  - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>  
> @@ -48,3 +54,12 @@ Example:
>  		interrupt-names = "alarm";
>  		st,syscfg = <&pwrcfg 0x00 0x100>;
>  	};
> +
> +	rtc: rtc at 5c004000 {
> +		compatible = "st,stm32mp1-rtc";
> +		reg = <0x5c004000 0x400>;
> +		clocks = <&rcc RTCAPB>, <&rcc RTC>;
> +		clock-names = "pclk", "rtc_ck";
> +		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
> +				      <&exti 19 1>;
> +	};
> -- 
> 2.7.4
> 

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

* Re: [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
  2018-04-27  3:01     ` Rob Herring
  (?)
  (?)
@ 2018-05-09  7:25       ` Amelie DELAUNAY
  -1 siblings, 0 replies; 18+ messages in thread
From: Amelie DELAUNAY @ 2018-05-09  7:25 UTC (permalink / raw)
  To: Rob Herring
  Cc: Alessandro Zummo, Alexandre Belloni, Mark Rutland,
	Maxime Coquelin, Alexandre TORGUE, linux-rtc, devicetree,
	linux-arm-kernel, linux-kernel



On 04/27/2018 05:01 AM, Rob Herring wrote:
> On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
>> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
>> doesn't require to disable backup domain write protection, and rtc_ck
>> parent clock assignment isn't allowed.
>> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
>> alarm interrupt.
>>
>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>> ---
>>   .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
>>   1 file changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> index 00f8b5d..f1c2080 100644
>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> @@ -1,25 +1,31 @@
>>   STM32 Real Time Clock
>>   
>>   Required properties:
>> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
>> -  the device is compatible with stm32(f4/f7) or stm32h7.
>> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
>> +	      depending on the device is compatible with stm32(f4/f7), stm32h7
>> +	      or stm32mp1.
> 
> One compatible per line please.
> 
>>   - reg: address range of rtc register set.
>>   - clocks: can use up to two clocks, depending on part used:
>>     - "rtc_ck": RTC clock source.
>> -    It is required on stm32(f4/f7) and stm32h7.
>> +    It is required on stm32(f4/f7/h7/mp1).
> 
> IOW, required for all?
> 

Yes, so, I'll remove the comment as it is required for all.

>>     - "pclk": RTC APB interface clock.
>>       It is not present on stm32(f4/f7).
>> -    It is required on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - clock-names: must be "rtc_ck" and "pclk".
>> -    It is required only on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - interrupt-parent: phandle for the interrupt controller.
>> +    It is required on stm32(f4/f7/h7).
>>   - interrupts: rtc alarm interrupt.
>> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
>> +  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
>> +    It is required on stm32mp1.
> 
> Just document 'interrupts'. interrupts-extended is implicitly supported
> and what the interrupts are connected to is outside the scope of this
> binding.
> 

OK, I'll clean this.

>>   - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>>     access control register at offset, and change the dbp (Disable Backup
>>     Protection) bit represented by the mask, mandatory to disable/enable backup
>>     domain (RTC registers) write protection.
>> +    It is required on stm32(f4/f7/h7).
>>   
>> -Optional properties (to override default rtc_ck parent clock):
>> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>>   - assigned-clocks: reference to the rtc_ck clock entry.
>>   - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>>   
>> @@ -48,3 +54,12 @@ Example:
>>   		interrupt-names = "alarm";
>>   		st,syscfg = <&pwrcfg 0x00 0x100>;
>>   	};
>> +
>> +	rtc: rtc@5c004000 {
>> +		compatible = "st,stm32mp1-rtc";
>> +		reg = <0x5c004000 0x400>;
>> +		clocks = <&rcc RTCAPB>, <&rcc RTC>;
>> +		clock-names = "pclk", "rtc_ck";
>> +		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
>> +				      <&exti 19 1>;
>> +	};
>> -- 
>> 2.7.4
>>

Thanks,
Amelie

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

* Re: [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-09  7:25       ` Amelie DELAUNAY
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie DELAUNAY @ 2018-05-09  7:25 UTC (permalink / raw)
  To: Rob Herring
  Cc: Alessandro Zummo, Alexandre Belloni, Mark Rutland,
	Maxime Coquelin, Alexandre TORGUE, linux-rtc, devicetree,
	linux-arm-kernel, linux-kernel

DQoNCk9uIDA0LzI3LzIwMTggMDU6MDEgQU0sIFJvYiBIZXJyaW5nIHdyb3RlOg0KPiBPbiBUaHUs
IEFwciAxOSwgMjAxOCBhdCAwMzozNDowNFBNICswMjAwLCBBbWVsaWUgRGVsYXVuYXkgd3JvdGU6
DQo+PiBSVEMgZW1iZWRkZWQgaW4gc3RtMzJtcDEgU29DIGlzIHNsaWdodGx5IGRpZmZlcmVudCBm
cm9tIHN0bTMyaDcgb25lLCBpdA0KPj4gZG9lc24ndCByZXF1aXJlIHRvIGRpc2FibGUgYmFja3Vw
IGRvbWFpbiB3cml0ZSBwcm90ZWN0aW9uLCBhbmQgcnRjX2NrDQo+PiBwYXJlbnQgY2xvY2sgYXNz
aWdubWVudCBpc24ndCBhbGxvd2VkLg0KPj4gVG8gc3VtIHVwLCBzdG0zMm1wMSBSVEMgcmVxdWly
ZXMgMiBjbG9ja3MsIHBjbGsgYW5kIHJ0Y19jaywgYW5kIGFuIFJUQw0KPj4gYWxhcm0gaW50ZXJy
dXB0Lg0KPj4NCj4+IFNpZ25lZC1vZmYtYnk6IEFtZWxpZSBEZWxhdW5heSA8YW1lbGllLmRlbGF1
bmF5QHN0LmNvbT4NCj4+IC0tLQ0KPj4gICAuLi4vZGV2aWNldHJlZS9iaW5kaW5ncy9ydGMvc3Qs
c3RtMzItcnRjLnR4dCAgICAgICB8IDI3ICsrKysrKysrKysrKysrKysrLS0tLS0NCj4+ICAgMSBm
aWxlIGNoYW5nZWQsIDIxIGluc2VydGlvbnMoKyksIDYgZGVsZXRpb25zKC0pDQo+Pg0KPj4gZGlm
ZiAtLWdpdCBhL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9ydGMvc3Qsc3RtMzIt
cnRjLnR4dCBiL0RvY3VtZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9ydGMvc3Qsc3RtMzIt
cnRjLnR4dA0KPj4gaW5kZXggMDBmOGI1ZC4uZjFjMjA4MCAxMDA2NDQNCj4+IC0tLSBhL0RvY3Vt
ZW50YXRpb24vZGV2aWNldHJlZS9iaW5kaW5ncy9ydGMvc3Qsc3RtMzItcnRjLnR4dA0KPj4gKysr
IGIvRG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3J0Yy9zdCxzdG0zMi1ydGMudHh0
DQo+PiBAQCAtMSwyNSArMSwzMSBAQA0KPj4gICBTVE0zMiBSZWFsIFRpbWUgQ2xvY2sNCj4+ICAg
DQo+PiAgIFJlcXVpcmVkIHByb3BlcnRpZXM6DQo+PiAtLSBjb21wYXRpYmxlOiBjYW4gYmUgZWl0
aGVyICJzdCxzdG0zMi1ydGMiIG9yICJzdCxzdG0zMmg3LXJ0YyIsIGRlcGVuZGluZyBvbg0KPj4g
LSAgdGhlIGRldmljZSBpcyBjb21wYXRpYmxlIHdpdGggc3RtMzIoZjQvZjcpIG9yIHN0bTMyaDcu
DQo+PiArLSBjb21wYXRpYmxlOiBjYW4gYmUgInN0LHN0bTMyLXJ0YyIsICJzdCxzdG0zMmg3LXJ0
YyIgb3IgInN0LHN0bTMybXAxLXJ0YyIsDQo+PiArCSAgICAgIGRlcGVuZGluZyBvbiB0aGUgZGV2
aWNlIGlzIGNvbXBhdGlibGUgd2l0aCBzdG0zMihmNC9mNyksIHN0bTMyaDcNCj4+ICsJICAgICAg
b3Igc3RtMzJtcDEuDQo+IA0KPiBPbmUgY29tcGF0aWJsZSBwZXIgbGluZSBwbGVhc2UuDQo+IA0K
Pj4gICAtIHJlZzogYWRkcmVzcyByYW5nZSBvZiBydGMgcmVnaXN0ZXIgc2V0Lg0KPj4gICAtIGNs
b2NrczogY2FuIHVzZSB1cCB0byB0d28gY2xvY2tzLCBkZXBlbmRpbmcgb24gcGFydCB1c2VkOg0K
Pj4gICAgIC0gInJ0Y19jayI6IFJUQyBjbG9jayBzb3VyY2UuDQo+PiAtICAgIEl0IGlzIHJlcXVp
cmVkIG9uIHN0bTMyKGY0L2Y3KSBhbmQgc3RtMzJoNy4NCj4+ICsgICAgSXQgaXMgcmVxdWlyZWQg
b24gc3RtMzIoZjQvZjcvaDcvbXAxKS4NCj4gDQo+IElPVywgcmVxdWlyZWQgZm9yIGFsbD8NCj4g
DQoNClllcywgc28sIEknbGwgcmVtb3ZlIHRoZSBjb21tZW50IGFzIGl0IGlzIHJlcXVpcmVkIGZv
ciBhbGwuDQoNCj4+ICAgICAtICJwY2xrIjogUlRDIEFQQiBpbnRlcmZhY2UgY2xvY2suDQo+PiAg
ICAgICBJdCBpcyBub3QgcHJlc2VudCBvbiBzdG0zMihmNC9mNykuDQo+PiAtICAgIEl0IGlzIHJl
cXVpcmVkIG9uIHN0bTMyaDcuDQo+PiArICAgIEl0IGlzIHJlcXVpcmVkIG9uIHN0bTMyKGg3L21w
MSkuDQo+PiAgIC0gY2xvY2stbmFtZXM6IG11c3QgYmUgInJ0Y19jayIgYW5kICJwY2xrIi4NCj4+
IC0gICAgSXQgaXMgcmVxdWlyZWQgb25seSBvbiBzdG0zMmg3Lg0KPj4gKyAgICBJdCBpcyByZXF1
aXJlZCBvbiBzdG0zMihoNy9tcDEpLg0KPj4gICAtIGludGVycnVwdC1wYXJlbnQ6IHBoYW5kbGUg
Zm9yIHRoZSBpbnRlcnJ1cHQgY29udHJvbGxlci4NCj4+ICsgICAgSXQgaXMgcmVxdWlyZWQgb24g
c3RtMzIoZjQvZjcvaDcpLg0KPj4gICAtIGludGVycnVwdHM6IHJ0YyBhbGFybSBpbnRlcnJ1cHQu
DQo+PiArLSBpbnRlcnJ1cHRzLWV4dGVuZGVkOiByZXBsYWNlIGludGVycnVwdHMgcHJvcGVydHkg
b24gc3RtMzJtcDEsIHRvIHNwZWNpZnkgcnRjDQo+PiArICBhbGFybSB3YWtldXAgaW50ZXJydXB0
LCB3aGljaCBpcyBvbiBleHRpIGludGVycnVwdCBjb250cm9sbGVyIGluc3RlYWQgb2YgZ2ljLg0K
Pj4gKyAgICBJdCBpcyByZXF1aXJlZCBvbiBzdG0zMm1wMS4NCj4gDQo+IEp1c3QgZG9jdW1lbnQg
J2ludGVycnVwdHMnLiBpbnRlcnJ1cHRzLWV4dGVuZGVkIGlzIGltcGxpY2l0bHkgc3VwcG9ydGVk
DQo+IGFuZCB3aGF0IHRoZSBpbnRlcnJ1cHRzIGFyZSBjb25uZWN0ZWQgdG8gaXMgb3V0c2lkZSB0
aGUgc2NvcGUgb2YgdGhpcw0KPiBiaW5kaW5nLg0KPiANCg0KT0ssIEknbGwgY2xlYW4gdGhpcy4N
Cg0KPj4gICAtIHN0LHN5c2NmZzogcGhhbmRsZS9vZmZzZXQvbWFzayB0cmlwbGV0LiBUaGUgcGhh
bmRsZSB0byBwd3JjZmcgdXNlZCB0bw0KPj4gICAgIGFjY2VzcyBjb250cm9sIHJlZ2lzdGVyIGF0
IG9mZnNldCwgYW5kIGNoYW5nZSB0aGUgZGJwIChEaXNhYmxlIEJhY2t1cA0KPj4gICAgIFByb3Rl
Y3Rpb24pIGJpdCByZXByZXNlbnRlZCBieSB0aGUgbWFzaywgbWFuZGF0b3J5IHRvIGRpc2FibGUv
ZW5hYmxlIGJhY2t1cA0KPj4gICAgIGRvbWFpbiAoUlRDIHJlZ2lzdGVycykgd3JpdGUgcHJvdGVj
dGlvbi4NCj4+ICsgICAgSXQgaXMgcmVxdWlyZWQgb24gc3RtMzIoZjQvZjcvaDcpLg0KPj4gICAN
Cj4+IC1PcHRpb25hbCBwcm9wZXJ0aWVzICh0byBvdmVycmlkZSBkZWZhdWx0IHJ0Y19jayBwYXJl
bnQgY2xvY2spOg0KPj4gK09wdGlvbmFsIHByb3BlcnRpZXMgKHRvIG92ZXJyaWRlIGRlZmF1bHQg
cnRjX2NrIHBhcmVudCBjbG9jayBvbiBzdG0zMihmNC9mNy9oNyk6DQo+PiAgIC0gYXNzaWduZWQt
Y2xvY2tzOiByZWZlcmVuY2UgdG8gdGhlIHJ0Y19jayBjbG9jayBlbnRyeS4NCj4+ICAgLSBhc3Np
Z25lZC1jbG9jay1wYXJlbnRzOiBwaGFuZGxlIG9mIHRoZSBuZXcgcGFyZW50IGNsb2NrIG9mIHJ0
Y19jay4NCj4+ICAgDQo+PiBAQCAtNDgsMyArNTQsMTIgQEAgRXhhbXBsZToNCj4+ICAgCQlpbnRl
cnJ1cHQtbmFtZXMgPSAiYWxhcm0iOw0KPj4gICAJCXN0LHN5c2NmZyA9IDwmcHdyY2ZnIDB4MDAg
MHgxMDA+Ow0KPj4gICAJfTsNCj4+ICsNCj4+ICsJcnRjOiBydGNANWMwMDQwMDAgew0KPj4gKwkJ
Y29tcGF0aWJsZSA9ICJzdCxzdG0zMm1wMS1ydGMiOw0KPj4gKwkJcmVnID0gPDB4NWMwMDQwMDAg
MHg0MDA+Ow0KPj4gKwkJY2xvY2tzID0gPCZyY2MgUlRDQVBCPiwgPCZyY2MgUlRDPjsNCj4+ICsJ
CWNsb2NrLW5hbWVzID0gInBjbGsiLCAicnRjX2NrIjsNCj4+ICsJCWludGVycnVwdHMtZXh0ZW5k
ZWQgPSA8JmludGMgR0lDX1NQSSAzIElSUV9UWVBFX05PTkU+LA0KPj4gKwkJCQkgICAgICA8JmV4
dGkgMTkgMT47DQo+PiArCX07DQo+PiAtLSANCj4+IDIuNy40DQo+Pg0KDQpUaGFua3MsDQpBbWVs
aWU=

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

* Re: [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-09  7:25       ` Amelie DELAUNAY
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie DELAUNAY @ 2018-05-09  7:25 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Alessandro Zummo, Alexandre TORGUE, devicetree,
	linux-kernel, Alexandre Belloni, Maxime Coquelin,
	linux-arm-kernel, linux-rtc



On 04/27/2018 05:01 AM, Rob Herring wrote:
> On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
>> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
>> doesn't require to disable backup domain write protection, and rtc_ck
>> parent clock assignment isn't allowed.
>> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
>> alarm interrupt.
>>
>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>> ---
>>   .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
>>   1 file changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> index 00f8b5d..f1c2080 100644
>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> @@ -1,25 +1,31 @@
>>   STM32 Real Time Clock
>>   
>>   Required properties:
>> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
>> -  the device is compatible with stm32(f4/f7) or stm32h7.
>> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
>> +	      depending on the device is compatible with stm32(f4/f7), stm32h7
>> +	      or stm32mp1.
> 
> One compatible per line please.
> 
>>   - reg: address range of rtc register set.
>>   - clocks: can use up to two clocks, depending on part used:
>>     - "rtc_ck": RTC clock source.
>> -    It is required on stm32(f4/f7) and stm32h7.
>> +    It is required on stm32(f4/f7/h7/mp1).
> 
> IOW, required for all?
> 

Yes, so, I'll remove the comment as it is required for all.

>>     - "pclk": RTC APB interface clock.
>>       It is not present on stm32(f4/f7).
>> -    It is required on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - clock-names: must be "rtc_ck" and "pclk".
>> -    It is required only on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - interrupt-parent: phandle for the interrupt controller.
>> +    It is required on stm32(f4/f7/h7).
>>   - interrupts: rtc alarm interrupt.
>> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
>> +  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
>> +    It is required on stm32mp1.
> 
> Just document 'interrupts'. interrupts-extended is implicitly supported
> and what the interrupts are connected to is outside the scope of this
> binding.
> 

OK, I'll clean this.

>>   - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>>     access control register at offset, and change the dbp (Disable Backup
>>     Protection) bit represented by the mask, mandatory to disable/enable backup
>>     domain (RTC registers) write protection.
>> +    It is required on stm32(f4/f7/h7).
>>   
>> -Optional properties (to override default rtc_ck parent clock):
>> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>>   - assigned-clocks: reference to the rtc_ck clock entry.
>>   - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>>   
>> @@ -48,3 +54,12 @@ Example:
>>   		interrupt-names = "alarm";
>>   		st,syscfg = <&pwrcfg 0x00 0x100>;
>>   	};
>> +
>> +	rtc: rtc@5c004000 {
>> +		compatible = "st,stm32mp1-rtc";
>> +		reg = <0x5c004000 0x400>;
>> +		clocks = <&rcc RTCAPB>, <&rcc RTC>;
>> +		clock-names = "pclk", "rtc_ck";
>> +		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
>> +				      <&exti 19 1>;
>> +	};
>> -- 
>> 2.7.4
>>

Thanks,
Amelie

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

* [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc
@ 2018-05-09  7:25       ` Amelie DELAUNAY
  0 siblings, 0 replies; 18+ messages in thread
From: Amelie DELAUNAY @ 2018-05-09  7:25 UTC (permalink / raw)
  To: linux-arm-kernel



On 04/27/2018 05:01 AM, Rob Herring wrote:
> On Thu, Apr 19, 2018 at 03:34:04PM +0200, Amelie Delaunay wrote:
>> RTC embedded in stm32mp1 SoC is slightly different from stm32h7 one, it
>> doesn't require to disable backup domain write protection, and rtc_ck
>> parent clock assignment isn't allowed.
>> To sum up, stm32mp1 RTC requires 2 clocks, pclk and rtc_ck, and an RTC
>> alarm interrupt.
>>
>> Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
>> ---
>>   .../devicetree/bindings/rtc/st,stm32-rtc.txt       | 27 +++++++++++++++++-----
>>   1 file changed, 21 insertions(+), 6 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> index 00f8b5d..f1c2080 100644
>> --- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> +++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.txt
>> @@ -1,25 +1,31 @@
>>   STM32 Real Time Clock
>>   
>>   Required properties:
>> -- compatible: can be either "st,stm32-rtc" or "st,stm32h7-rtc", depending on
>> -  the device is compatible with stm32(f4/f7) or stm32h7.
>> +- compatible: can be "st,stm32-rtc", "st,stm32h7-rtc" or "st,stm32mp1-rtc",
>> +	      depending on the device is compatible with stm32(f4/f7), stm32h7
>> +	      or stm32mp1.
> 
> One compatible per line please.
> 
>>   - reg: address range of rtc register set.
>>   - clocks: can use up to two clocks, depending on part used:
>>     - "rtc_ck": RTC clock source.
>> -    It is required on stm32(f4/f7) and stm32h7.
>> +    It is required on stm32(f4/f7/h7/mp1).
> 
> IOW, required for all?
> 

Yes, so, I'll remove the comment as it is required for all.

>>     - "pclk": RTC APB interface clock.
>>       It is not present on stm32(f4/f7).
>> -    It is required on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - clock-names: must be "rtc_ck" and "pclk".
>> -    It is required only on stm32h7.
>> +    It is required on stm32(h7/mp1).
>>   - interrupt-parent: phandle for the interrupt controller.
>> +    It is required on stm32(f4/f7/h7).
>>   - interrupts: rtc alarm interrupt.
>> +- interrupts-extended: replace interrupts property on stm32mp1, to specify rtc
>> +  alarm wakeup interrupt, which is on exti interrupt controller instead of gic.
>> +    It is required on stm32mp1.
> 
> Just document 'interrupts'. interrupts-extended is implicitly supported
> and what the interrupts are connected to is outside the scope of this
> binding.
> 

OK, I'll clean this.

>>   - st,syscfg: phandle/offset/mask triplet. The phandle to pwrcfg used to
>>     access control register at offset, and change the dbp (Disable Backup
>>     Protection) bit represented by the mask, mandatory to disable/enable backup
>>     domain (RTC registers) write protection.
>> +    It is required on stm32(f4/f7/h7).
>>   
>> -Optional properties (to override default rtc_ck parent clock):
>> +Optional properties (to override default rtc_ck parent clock on stm32(f4/f7/h7):
>>   - assigned-clocks: reference to the rtc_ck clock entry.
>>   - assigned-clock-parents: phandle of the new parent clock of rtc_ck.
>>   
>> @@ -48,3 +54,12 @@ Example:
>>   		interrupt-names = "alarm";
>>   		st,syscfg = <&pwrcfg 0x00 0x100>;
>>   	};
>> +
>> +	rtc: rtc at 5c004000 {
>> +		compatible = "st,stm32mp1-rtc";
>> +		reg = <0x5c004000 0x400>;
>> +		clocks = <&rcc RTCAPB>, <&rcc RTC>;
>> +		clock-names = "pclk", "rtc_ck";
>> +		interrupts-extended = <&intc GIC_SPI 3 IRQ_TYPE_NONE>,
>> +				      <&exti 19 1>;
>> +	};
>> -- 
>> 2.7.4
>>

Thanks,
Amelie

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

end of thread, other threads:[~2018-05-09  7:26 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-19 13:34 [PATCH 0/3] Introduce STM32MP1 RTC Amelie Delaunay
2018-04-19 13:34 ` Amelie Delaunay
2018-04-19 13:34 ` Amelie Delaunay
2018-04-19 13:34 ` [PATCH 1/3] rtc: stm32: rework register management to prepare other version of RTC Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay
2018-04-19 13:34 ` [PATCH 2/3] dt-bindings: rtc: update stm32-rtc documentation for stm32mp1 rtc Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay
2018-04-27  3:01   ` Rob Herring
2018-04-27  3:01     ` Rob Herring
2018-05-09  7:25     ` Amelie DELAUNAY
2018-05-09  7:25       ` Amelie DELAUNAY
2018-05-09  7:25       ` Amelie DELAUNAY
2018-05-09  7:25       ` Amelie DELAUNAY
2018-04-19 13:34 ` [PATCH 3/3] rtc: stm32: add stm32mp1 rtc support Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay
2018-04-19 13:34   ` Amelie Delaunay

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.