All of lore.kernel.org
 help / color / mirror / Atom feed
From: Valentin Caron <valentin.caron@foss.st.com>
To: Alessandro Zummo <a.zummo@towertech.it>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez@foss.st.com>,
	Amelie Delaunay <amelie.delaunay@foss.st.com>,
	Valentin Caron <valentin.caron@foss.st.com>,
	<linux-rtc@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH 3/6] rtc: stm32: add Low Speed Clock Output (LSCO) support
Date: Wed, 4 May 2022 15:06:14 +0200	[thread overview]
Message-ID: <20220504130617.331290-2-valentin.caron@foss.st.com> (raw)
In-Reply-To: <20220504130233.330983-1-valentin.caron@foss.st.com>

From: Amelie Delaunay <amelie.delaunay@foss.st.com>

STM32 RTC is now registered as a clock provider.
It provides rtc_lsco clock, that means RTC_LSCO is output on either
RTC_OUT1 or RTC_OUT2_RMP, depending on st,lsco DT property
(PC13 or PI8 on stm32mp15), (PC13 or PI1 on stm32mp13).

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
---
 drivers/rtc/Kconfig     |   1 +
 drivers/rtc/rtc-stm32.c | 133 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 41c65b4d2baf..2e8021d7c98a 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1888,6 +1888,7 @@ config RTC_DRV_R7301
 config RTC_DRV_STM32
 	tristate "STM32 RTC"
 	select REGMAP_MMIO
+	depends on COMMON_CLK
 	depends on ARCH_STM32 || COMPILE_TEST
 	help
 	   If you say yes here you get support for the STM32 On-Chip
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index ac9e228b56d0..ace041eb44b8 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -6,6 +6,7 @@
 
 #include <linux/bcd.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/mfd/syscon.h>
@@ -15,6 +16,8 @@
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
+#include <dt-bindings/rtc/rtc-stm32.h>
+
 #define DRIVER_NAME "stm32_rtc"
 
 /* STM32_RTC_TR bit fields  */
@@ -39,6 +42,11 @@
 #define STM32_RTC_CR_FMT		BIT(6)
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
+#define STM32_RTC_CR_COSEL		BIT(19)
+#define STM32_RTC_CR_OSEL		GENMASK(22, 21)
+#define STM32_RTC_CR_COE		BIT(23)
+#define STM32_RTC_CR_TAMPOE		BIT(26)
+#define STM32_RTC_CR_OUT2EN		BIT(31)
 
 /* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
@@ -75,6 +83,12 @@
 /* STM32_RTC_SR/_SCR bit fields */
 #define STM32_RTC_SR_ALRA		BIT(0)
 
+/* STM32_RTC_CFGR bit fields */
+#define STM32_RTC_CFGR_OUT2_RMP		BIT(0)
+#define STM32_RTC_CFGR_LSCOEN		GENMASK(2, 1)
+#define STM32_RTC_CFGR_LSCOEN_OUT1	1
+#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP	2
+
 /* STM32_RTC_VERR bit fields */
 #define STM32_RTC_VERR_MINREV_SHIFT	0
 #define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
@@ -89,6 +103,9 @@
 /* Max STM32 RTC register offset is 0x3FC */
 #define UNDEF_REG			0xFFFF
 
+/* Frequency of HSE clock (Hz) */
+#define STM32_RTC_HSE_FREQ 32768
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
@@ -101,6 +118,7 @@ struct stm32_rtc_registers {
 	u16 wpr;
 	u16 sr;
 	u16 scr;
+	u16 cfgr;
 	u16 verr;
 };
 
@@ -115,6 +133,7 @@ struct stm32_rtc_data {
 	bool has_pclk;
 	bool need_dbp;
 	bool has_wakeirq;
+	bool has_lsco;
 };
 
 struct stm32_rtc {
@@ -128,8 +147,88 @@ struct stm32_rtc {
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
 	int wakeirq_alarm;
+	int lsco;
+	struct clk *clk_lsco;
 };
 
+/*
+ *  -------------------------------------------------------------------------
+ * | TAMPOE | OSEL[1:0] | COE | OUT2EN |     RTC_OUT1     |     RTC_OUT2     |
+ * |	    |           |     |        |                  | or RTC_OUT2_RMP  |
+ * |-------------------------------------------------------------------------|
+ * |    0   |     00    |  0  | 0 or 1 |         -        |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * |    0   |     00    |  1  |    0   |      CALIB       |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  0  |    0   |     TAMPALRM     |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * |    0   |     00    |  1  |    1   |         -        |      CALIB       |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  0  |    1   |         -        |     TAMPALRM     |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  1  |    1   |     TAMPALRM     |      CALIB       |
+ *  -------------------------------------------------------------------------
+ */
+static int stm32_rtc_clk_lsco_check_availability(struct stm32_rtc *rtc)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int cr = readl_relaxed(rtc->base + regs.cr);
+	unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+	unsigned int calib = STM32_RTC_CR_COE;
+	unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
+
+	switch (rtc->lsco) {
+	case RTC_OUT1:
+		if ((!(cr & STM32_RTC_CR_OUT2EN) &&
+		     ((cr & calib) || cr & tampalrm)) ||
+		     ((cr & calib) && (cr & tampalrm)))
+			return -EBUSY;
+		break;
+	case RTC_OUT2_RMP:
+		if ((cr & STM32_RTC_CR_OUT2EN) &&
+		    (cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
+		    ((cr & calib) || (cr & tampalrm)))
+			return -EBUSY;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* LSCO can only work if RTC clock source is HSE */
+	if (clk_get_rate(rtc->rtc_ck) != STM32_RTC_HSE_FREQ)
+		return -ERANGE;
+
+	return 0;
+}
+
+static int stm32_rtc_clk_lsco_register(struct platform_device *pdev)
+{
+	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	u8 lscoen;
+	int ret;
+
+	ret = stm32_rtc_clk_lsco_check_availability(rtc);
+	if (ret)
+		return ret;
+
+	lscoen = (rtc->lsco == RTC_OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 :
+					   STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
+
+	rtc->clk_lsco = clk_register_gate(&pdev->dev, "rtc_lsco",
+					  __clk_get_name(rtc->rtc_ck),
+					  CLK_IS_CRITICAL,
+					  rtc->base + regs.cfgr, lscoen,
+					  0, NULL);
+	if (IS_ERR(rtc->clk_lsco))
+		return PTR_ERR(rtc->clk_lsco);
+
+	of_clk_add_provider(pdev->dev.of_node,
+			    of_clk_src_simple_get, rtc->clk_lsco);
+
+	return 0;
+}
+
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
@@ -145,6 +244,15 @@ static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 }
 
+static void stm32_rtc_clk_lsco_disable(struct platform_device *pdev)
+{
+	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+
+	writel_relaxed(cfgr &= ~STM32_RTC_CFGR_LSCOEN, rtc->base + regs.cfgr);
+}
+
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
@@ -548,6 +656,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
 	.has_wakeirq = false,
+	.has_lsco = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -558,6 +667,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.wpr = 0x24,
 		.sr = 0x0C, /* set to ISR offset to ease alarm management */
 		.scr = UNDEF_REG,
+		.cfgr = UNDEF_REG,
 		.verr = UNDEF_REG,
 	},
 	.events = {
@@ -570,6 +680,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
 	.has_wakeirq = false,
+	.has_lsco = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -580,6 +691,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.wpr = 0x24,
 		.sr = 0x0C, /* set to ISR offset to ease alarm management */
 		.scr = UNDEF_REG,
+		.cfgr = UNDEF_REG,
 		.verr = UNDEF_REG,
 	},
 	.events = {
@@ -601,6 +713,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
 	.has_pclk = true,
 	.need_dbp = false,
 	.has_wakeirq = true,
+	.has_lsco = true,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -611,6 +724,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
 		.wpr = 0x24,
 		.sr = 0x50,
 		.scr = 0x5C,
+		.cfgr = 0x60,
 		.verr = 0x3F4,
 	},
 	.events = {
@@ -814,6 +928,22 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	if (rtc->data->has_lsco) {
+		ret = of_property_read_s32(pdev->dev.of_node,
+					   "st,lsco", &rtc->lsco);
+		if (!ret) {
+			ret = stm32_rtc_clk_lsco_register(pdev);
+			if (ret)
+				dev_warn(&pdev->dev,
+					 "LSCO clock registration failed: %d\n",
+					 ret);
+		} else {
+			stm32_rtc_clk_lsco_disable(pdev);
+			rtc->lsco = ret;
+			dev_dbg(&pdev->dev, "No LSCO clock: %d\n", ret);
+		}
+	}
+
 	/*
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
@@ -852,6 +982,9 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int cr;
 
+	if (!IS_ERR_OR_NULL(rtc->clk_lsco))
+		clk_unregister_gate(rtc->clk_lsco);
+
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
 	cr = readl_relaxed(rtc->base + regs->cr);
-- 
2.25.1


WARNING: multiple messages have this Message-ID (diff)
From: Valentin Caron <valentin.caron@foss.st.com>
To: Alessandro Zummo <a.zummo@towertech.it>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Rob Herring <robh+dt@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez@foss.st.com>,
	Amelie Delaunay <amelie.delaunay@foss.st.com>,
	Valentin Caron <valentin.caron@foss.st.com>,
	<linux-rtc@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-kernel@vger.kernel.org>
Subject: [PATCH 3/6] rtc: stm32: add Low Speed Clock Output (LSCO) support
Date: Wed, 4 May 2022 15:06:14 +0200	[thread overview]
Message-ID: <20220504130617.331290-2-valentin.caron@foss.st.com> (raw)
In-Reply-To: <20220504130233.330983-1-valentin.caron@foss.st.com>

From: Amelie Delaunay <amelie.delaunay@foss.st.com>

STM32 RTC is now registered as a clock provider.
It provides rtc_lsco clock, that means RTC_LSCO is output on either
RTC_OUT1 or RTC_OUT2_RMP, depending on st,lsco DT property
(PC13 or PI8 on stm32mp15), (PC13 or PI1 on stm32mp13).

Signed-off-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron@foss.st.com>
---
 drivers/rtc/Kconfig     |   1 +
 drivers/rtc/rtc-stm32.c | 133 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 134 insertions(+)

diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 41c65b4d2baf..2e8021d7c98a 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -1888,6 +1888,7 @@ config RTC_DRV_R7301
 config RTC_DRV_STM32
 	tristate "STM32 RTC"
 	select REGMAP_MMIO
+	depends on COMMON_CLK
 	depends on ARCH_STM32 || COMPILE_TEST
 	help
 	   If you say yes here you get support for the STM32 On-Chip
diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c
index ac9e228b56d0..ace041eb44b8 100644
--- a/drivers/rtc/rtc-stm32.c
+++ b/drivers/rtc/rtc-stm32.c
@@ -6,6 +6,7 @@
 
 #include <linux/bcd.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/mfd/syscon.h>
@@ -15,6 +16,8 @@
 #include <linux/regmap.h>
 #include <linux/rtc.h>
 
+#include <dt-bindings/rtc/rtc-stm32.h>
+
 #define DRIVER_NAME "stm32_rtc"
 
 /* STM32_RTC_TR bit fields  */
@@ -39,6 +42,11 @@
 #define STM32_RTC_CR_FMT		BIT(6)
 #define STM32_RTC_CR_ALRAE		BIT(8)
 #define STM32_RTC_CR_ALRAIE		BIT(12)
+#define STM32_RTC_CR_COSEL		BIT(19)
+#define STM32_RTC_CR_OSEL		GENMASK(22, 21)
+#define STM32_RTC_CR_COE		BIT(23)
+#define STM32_RTC_CR_TAMPOE		BIT(26)
+#define STM32_RTC_CR_OUT2EN		BIT(31)
 
 /* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
 #define STM32_RTC_ISR_ALRAWF		BIT(0)
@@ -75,6 +83,12 @@
 /* STM32_RTC_SR/_SCR bit fields */
 #define STM32_RTC_SR_ALRA		BIT(0)
 
+/* STM32_RTC_CFGR bit fields */
+#define STM32_RTC_CFGR_OUT2_RMP		BIT(0)
+#define STM32_RTC_CFGR_LSCOEN		GENMASK(2, 1)
+#define STM32_RTC_CFGR_LSCOEN_OUT1	1
+#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP	2
+
 /* STM32_RTC_VERR bit fields */
 #define STM32_RTC_VERR_MINREV_SHIFT	0
 #define STM32_RTC_VERR_MINREV		GENMASK(3, 0)
@@ -89,6 +103,9 @@
 /* Max STM32 RTC register offset is 0x3FC */
 #define UNDEF_REG			0xFFFF
 
+/* Frequency of HSE clock (Hz) */
+#define STM32_RTC_HSE_FREQ 32768
+
 struct stm32_rtc;
 
 struct stm32_rtc_registers {
@@ -101,6 +118,7 @@ struct stm32_rtc_registers {
 	u16 wpr;
 	u16 sr;
 	u16 scr;
+	u16 cfgr;
 	u16 verr;
 };
 
@@ -115,6 +133,7 @@ struct stm32_rtc_data {
 	bool has_pclk;
 	bool need_dbp;
 	bool has_wakeirq;
+	bool has_lsco;
 };
 
 struct stm32_rtc {
@@ -128,8 +147,88 @@ struct stm32_rtc {
 	const struct stm32_rtc_data *data;
 	int irq_alarm;
 	int wakeirq_alarm;
+	int lsco;
+	struct clk *clk_lsco;
 };
 
+/*
+ *  -------------------------------------------------------------------------
+ * | TAMPOE | OSEL[1:0] | COE | OUT2EN |     RTC_OUT1     |     RTC_OUT2     |
+ * |	    |           |     |        |                  | or RTC_OUT2_RMP  |
+ * |-------------------------------------------------------------------------|
+ * |    0   |     00    |  0  | 0 or 1 |         -        |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * |    0   |     00    |  1  |    0   |      CALIB       |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  0  |    0   |     TAMPALRM     |         -        |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * |    0   |     00    |  1  |    1   |         -        |      CALIB       |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  0  |    1   |         -        |     TAMPALRM     |
+ * |--------|-----------|-----|--------|------------------|------------------|
+ * | 0 or 1 |    !=00   |  1  |    1   |     TAMPALRM     |      CALIB       |
+ *  -------------------------------------------------------------------------
+ */
+static int stm32_rtc_clk_lsco_check_availability(struct stm32_rtc *rtc)
+{
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int cr = readl_relaxed(rtc->base + regs.cr);
+	unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+	unsigned int calib = STM32_RTC_CR_COE;
+	unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
+
+	switch (rtc->lsco) {
+	case RTC_OUT1:
+		if ((!(cr & STM32_RTC_CR_OUT2EN) &&
+		     ((cr & calib) || cr & tampalrm)) ||
+		     ((cr & calib) && (cr & tampalrm)))
+			return -EBUSY;
+		break;
+	case RTC_OUT2_RMP:
+		if ((cr & STM32_RTC_CR_OUT2EN) &&
+		    (cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
+		    ((cr & calib) || (cr & tampalrm)))
+			return -EBUSY;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* LSCO can only work if RTC clock source is HSE */
+	if (clk_get_rate(rtc->rtc_ck) != STM32_RTC_HSE_FREQ)
+		return -ERANGE;
+
+	return 0;
+}
+
+static int stm32_rtc_clk_lsco_register(struct platform_device *pdev)
+{
+	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	u8 lscoen;
+	int ret;
+
+	ret = stm32_rtc_clk_lsco_check_availability(rtc);
+	if (ret)
+		return ret;
+
+	lscoen = (rtc->lsco == RTC_OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 :
+					   STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
+
+	rtc->clk_lsco = clk_register_gate(&pdev->dev, "rtc_lsco",
+					  __clk_get_name(rtc->rtc_ck),
+					  CLK_IS_CRITICAL,
+					  rtc->base + regs.cfgr, lscoen,
+					  0, NULL);
+	if (IS_ERR(rtc->clk_lsco))
+		return PTR_ERR(rtc->clk_lsco);
+
+	of_clk_add_provider(pdev->dev.of_node,
+			    of_clk_src_simple_get, rtc->clk_lsco);
+
+	return 0;
+}
+
 static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc)
 {
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
@@ -145,6 +244,15 @@ static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc)
 	writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + regs->wpr);
 }
 
+static void stm32_rtc_clk_lsco_disable(struct platform_device *pdev)
+{
+	struct stm32_rtc *rtc = platform_get_drvdata(pdev);
+	struct stm32_rtc_registers regs = rtc->data->regs;
+	unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
+
+	writel_relaxed(cfgr &= ~STM32_RTC_CFGR_LSCOEN, rtc->base + regs.cfgr);
+}
+
 static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc)
 {
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
@@ -548,6 +656,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 	.has_pclk = false,
 	.need_dbp = true,
 	.has_wakeirq = false,
+	.has_lsco = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -558,6 +667,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
 		.wpr = 0x24,
 		.sr = 0x0C, /* set to ISR offset to ease alarm management */
 		.scr = UNDEF_REG,
+		.cfgr = UNDEF_REG,
 		.verr = UNDEF_REG,
 	},
 	.events = {
@@ -570,6 +680,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 	.has_pclk = true,
 	.need_dbp = true,
 	.has_wakeirq = false,
+	.has_lsco = false,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -580,6 +691,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
 		.wpr = 0x24,
 		.sr = 0x0C, /* set to ISR offset to ease alarm management */
 		.scr = UNDEF_REG,
+		.cfgr = UNDEF_REG,
 		.verr = UNDEF_REG,
 	},
 	.events = {
@@ -601,6 +713,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
 	.has_pclk = true,
 	.need_dbp = false,
 	.has_wakeirq = true,
+	.has_lsco = true,
 	.regs = {
 		.tr = 0x00,
 		.dr = 0x04,
@@ -611,6 +724,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
 		.wpr = 0x24,
 		.sr = 0x50,
 		.scr = 0x5C,
+		.cfgr = 0x60,
 		.verr = 0x3F4,
 	},
 	.events = {
@@ -814,6 +928,22 @@ static int stm32_rtc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	if (rtc->data->has_lsco) {
+		ret = of_property_read_s32(pdev->dev.of_node,
+					   "st,lsco", &rtc->lsco);
+		if (!ret) {
+			ret = stm32_rtc_clk_lsco_register(pdev);
+			if (ret)
+				dev_warn(&pdev->dev,
+					 "LSCO clock registration failed: %d\n",
+					 ret);
+		} else {
+			stm32_rtc_clk_lsco_disable(pdev);
+			rtc->lsco = ret;
+			dev_dbg(&pdev->dev, "No LSCO clock: %d\n", ret);
+		}
+	}
+
 	/*
 	 * If INITS flag is reset (calendar year field set to 0x00), calendar
 	 * must be initialized
@@ -852,6 +982,9 @@ static int stm32_rtc_remove(struct platform_device *pdev)
 	const struct stm32_rtc_registers *regs = &rtc->data->regs;
 	unsigned int cr;
 
+	if (!IS_ERR_OR_NULL(rtc->clk_lsco))
+		clk_unregister_gate(rtc->clk_lsco);
+
 	/* Disable interrupts */
 	stm32_rtc_wpr_unlock(rtc);
 	cr = readl_relaxed(rtc->base + regs->cr);
-- 
2.25.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2022-05-04 13:07 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-04 13:02 [PATCH 0/6] rtc: stm32: add alarm out and LSCO features Valentin Caron
2022-05-04 13:02 ` Valentin Caron
2022-05-04 13:02 ` [PATCH 1/6] dt-bindings: rtc: stm32: add st,lsco optional property to select output Valentin Caron
2022-05-04 13:02   ` [PATCH 1/6] dt-bindings: rtc: stm32: add st, lsco " Valentin Caron
2022-05-16 23:52   ` [PATCH 1/6] dt-bindings: rtc: stm32: add st,lsco " Rob Herring
2022-05-16 23:52     ` Rob Herring
2022-05-04 13:06 ` [PATCH 2/6] dt-bindings: rtc: stm32: add alarm A out " Valentin Caron
2022-05-04 13:06   ` Valentin Caron
2022-05-04 15:42   ` Rob Herring
2022-05-04 15:42     ` Rob Herring
2022-05-04 20:27   ` Alexandre Belloni
2022-05-04 20:27     ` Alexandre Belloni
2022-05-23 12:34     ` Valentin CARON
2022-05-23 12:34       ` Valentin CARON
2022-06-24  8:35       ` Valentin CARON
2022-06-24  8:35         ` Valentin CARON
2022-07-22 16:02       ` Alexandre Belloni
2022-07-22 16:02         ` Alexandre Belloni
2022-05-04 13:06 ` Valentin Caron [this message]
2022-05-04 13:06   ` [PATCH 3/6] rtc: stm32: add Low Speed Clock Output (LSCO) support Valentin Caron
2022-05-04 13:06 ` [PATCH 4/6] rtc: stm32: add alarm A out feature Valentin Caron
2022-05-04 13:06   ` Valentin Caron
2022-05-04 13:06 ` [PATCH 5/6] ARM: dts: stm32: add RTC LSCO support on stm32mp157c-dk2 Valentin Caron
2022-05-04 13:06   ` Valentin Caron
2022-05-04 13:06 ` [PATCH 6/6] ARM: dts: stm32: add RTC LSCO support on stm32mp135f-dk Valentin Caron
2022-05-04 13:06   ` Valentin Caron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220504130617.331290-2-valentin.caron@foss.st.com \
    --to=valentin.caron@foss.st.com \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=amelie.delaunay@foss.st.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gabriel.fernandez@foss.st.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.