Skip to content

Commit bb7b0df

Browse files
VCASTMalexandrebelloni
authored andcommitted
rtc: stm32: add Low Speed Clock Output (LSCO) support
RTC is able to output on a pin the "LSE" internal clock. 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 pinmux DT property. The clock is marked as CLK_IGNORE_UNUSED and CLK_IS_CRITICAL because RTC_LSCO can be early required by devices needed it to init. Add LSCO in pinmux functions. Add "stm32_rtc_clean_outs" to disable LSCO. As RTC is part of "backup" power domain, it is not reset during shutdown or reboot. So force LSCO disable at probe. Co-developed-by: Amelie Delaunay <[email protected]> Signed-off-by: Amelie Delaunay <[email protected]> Signed-off-by: Valentin Caron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 16ad2bc commit bb7b0df

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

drivers/rtc/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,7 @@ config RTC_DRV_STM32
19281928
select PINMUX
19291929
select PINCONF
19301930
select GENERIC_PINCONF
1931+
depends on COMMON_CLK
19311932
help
19321933
If you say yes here you get support for the STM32 On-Chip
19331934
Real Time Clock.

drivers/rtc/rtc-stm32.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/bcd.h>
88
#include <linux/bitfield.h>
99
#include <linux/clk.h>
10+
#include <linux/clk-provider.h>
1011
#include <linux/errno.h>
1112
#include <linux/iopoll.h>
1213
#include <linux/ioport.h>
@@ -45,6 +46,10 @@
4546
#define STM32_RTC_CR_FMT BIT(6)
4647
#define STM32_RTC_CR_ALRAE BIT(8)
4748
#define STM32_RTC_CR_ALRAIE BIT(12)
49+
#define STM32_RTC_CR_OSEL GENMASK(22, 21)
50+
#define STM32_RTC_CR_COE BIT(23)
51+
#define STM32_RTC_CR_TAMPOE BIT(26)
52+
#define STM32_RTC_CR_OUT2EN BIT(31)
4853

4954
/* STM32_RTC_ISR/STM32_RTC_ICSR bit fields */
5055
#define STM32_RTC_ISR_ALRAWF BIT(0)
@@ -81,6 +86,12 @@
8186
/* STM32_RTC_SR/_SCR bit fields */
8287
#define STM32_RTC_SR_ALRA BIT(0)
8388

89+
/* STM32_RTC_CFGR bit fields */
90+
#define STM32_RTC_CFGR_OUT2_RMP BIT(0)
91+
#define STM32_RTC_CFGR_LSCOEN GENMASK(2, 1)
92+
#define STM32_RTC_CFGR_LSCOEN_OUT1 1
93+
#define STM32_RTC_CFGR_LSCOEN_OUT2_RMP 2
94+
8495
/* STM32_RTC_VERR bit fields */
8596
#define STM32_RTC_VERR_MINREV_SHIFT 0
8697
#define STM32_RTC_VERR_MINREV GENMASK(3, 0)
@@ -130,6 +141,7 @@ struct stm32_rtc_registers {
130141
u16 wpr;
131142
u16 sr;
132143
u16 scr;
144+
u16 cfgr;
133145
u16 verr;
134146
};
135147

@@ -145,6 +157,7 @@ struct stm32_rtc_data {
145157
bool need_dbp;
146158
bool need_accuracy;
147159
bool rif_protected;
160+
bool has_lsco;
148161
};
149162

150163
struct stm32_rtc {
@@ -157,6 +170,7 @@ struct stm32_rtc {
157170
struct clk *rtc_ck;
158171
const struct stm32_rtc_data *data;
159172
int irq_alarm;
173+
struct clk *clk_lsco;
160174
};
161175

162176
struct stm32_rtc_rif_resource {
@@ -231,7 +245,68 @@ struct stm32_rtc_pinmux_func {
231245
int (*action)(struct pinctrl_dev *pctl_dev, unsigned int pin);
232246
};
233247

248+
static int stm32_rtc_pinmux_lsco_available(struct pinctrl_dev *pctldev, unsigned int pin)
249+
{
250+
struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
251+
struct stm32_rtc_registers regs = rtc->data->regs;
252+
unsigned int cr = readl_relaxed(rtc->base + regs.cr);
253+
unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
254+
unsigned int calib = STM32_RTC_CR_COE;
255+
unsigned int tampalrm = STM32_RTC_CR_TAMPOE | STM32_RTC_CR_OSEL;
256+
257+
switch (pin) {
258+
case OUT1:
259+
if ((!(cr & STM32_RTC_CR_OUT2EN) &&
260+
((cr & calib) || cr & tampalrm)) ||
261+
((cr & calib) && (cr & tampalrm)))
262+
return -EBUSY;
263+
break;
264+
case OUT2_RMP:
265+
if ((cr & STM32_RTC_CR_OUT2EN) &&
266+
(cfgr & STM32_RTC_CFGR_OUT2_RMP) &&
267+
((cr & calib) || (cr & tampalrm)))
268+
return -EBUSY;
269+
break;
270+
default:
271+
return -EINVAL;
272+
}
273+
274+
if (clk_get_rate(rtc->rtc_ck) != 32768)
275+
return -ERANGE;
276+
277+
return 0;
278+
}
279+
280+
static int stm32_rtc_pinmux_action_lsco(struct pinctrl_dev *pctldev, unsigned int pin)
281+
{
282+
struct stm32_rtc *rtc = pinctrl_dev_get_drvdata(pctldev);
283+
struct stm32_rtc_registers regs = rtc->data->regs;
284+
struct device *dev = rtc->rtc_dev->dev.parent;
285+
u8 lscoen;
286+
int ret;
287+
288+
if (!rtc->data->has_lsco)
289+
return -EPERM;
290+
291+
ret = stm32_rtc_pinmux_lsco_available(pctldev, pin);
292+
if (ret)
293+
return ret;
294+
295+
lscoen = (pin == OUT1) ? STM32_RTC_CFGR_LSCOEN_OUT1 : STM32_RTC_CFGR_LSCOEN_OUT2_RMP;
296+
297+
rtc->clk_lsco = clk_register_gate(dev, "rtc_lsco", __clk_get_name(rtc->rtc_ck),
298+
CLK_IGNORE_UNUSED | CLK_IS_CRITICAL,
299+
rtc->base + regs.cfgr, lscoen, 0, NULL);
300+
if (IS_ERR(rtc->clk_lsco))
301+
return PTR_ERR(rtc->clk_lsco);
302+
303+
of_clk_add_provider(dev->of_node, of_clk_src_simple_get, rtc->clk_lsco);
304+
305+
return 0;
306+
}
307+
234308
static const struct stm32_rtc_pinmux_func stm32_rtc_pinmux_functions[] = {
309+
STM32_RTC_PINMUX("lsco", &stm32_rtc_pinmux_action_lsco, "out1", "out2_rmp"),
235310
};
236311

237312
static int stm32_rtc_pinmux_get_functions_count(struct pinctrl_dev *pctldev)
@@ -687,6 +762,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
687762
.need_dbp = true,
688763
.need_accuracy = false,
689764
.rif_protected = false,
765+
.has_lsco = false,
690766
.regs = {
691767
.tr = 0x00,
692768
.dr = 0x04,
@@ -697,6 +773,7 @@ static const struct stm32_rtc_data stm32_rtc_data = {
697773
.wpr = 0x24,
698774
.sr = 0x0C, /* set to ISR offset to ease alarm management */
699775
.scr = UNDEF_REG,
776+
.cfgr = UNDEF_REG,
700777
.verr = UNDEF_REG,
701778
},
702779
.events = {
@@ -710,6 +787,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
710787
.need_dbp = true,
711788
.need_accuracy = false,
712789
.rif_protected = false,
790+
.has_lsco = false,
713791
.regs = {
714792
.tr = 0x00,
715793
.dr = 0x04,
@@ -720,6 +798,7 @@ static const struct stm32_rtc_data stm32h7_rtc_data = {
720798
.wpr = 0x24,
721799
.sr = 0x0C, /* set to ISR offset to ease alarm management */
722800
.scr = UNDEF_REG,
801+
.cfgr = UNDEF_REG,
723802
.verr = UNDEF_REG,
724803
},
725804
.events = {
@@ -742,6 +821,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
742821
.need_dbp = false,
743822
.need_accuracy = true,
744823
.rif_protected = false,
824+
.has_lsco = true,
745825
.regs = {
746826
.tr = 0x00,
747827
.dr = 0x04,
@@ -752,6 +832,7 @@ static const struct stm32_rtc_data stm32mp1_data = {
752832
.wpr = 0x24,
753833
.sr = 0x50,
754834
.scr = 0x5C,
835+
.cfgr = 0x60,
755836
.verr = 0x3F4,
756837
},
757838
.events = {
@@ -765,6 +846,7 @@ static const struct stm32_rtc_data stm32mp25_data = {
765846
.need_dbp = false,
766847
.need_accuracy = true,
767848
.rif_protected = true,
849+
.has_lsco = true,
768850
.regs = {
769851
.tr = 0x00,
770852
.dr = 0x04,
@@ -775,6 +857,7 @@ static const struct stm32_rtc_data stm32mp25_data = {
775857
.wpr = 0x24,
776858
.sr = 0x50,
777859
.scr = 0x5C,
860+
.cfgr = 0x60,
778861
.verr = 0x3F4,
779862
},
780863
.events = {
@@ -792,6 +875,19 @@ static const struct of_device_id stm32_rtc_of_match[] = {
792875
};
793876
MODULE_DEVICE_TABLE(of, stm32_rtc_of_match);
794877

878+
static void stm32_rtc_clean_outs(struct stm32_rtc *rtc)
879+
{
880+
struct stm32_rtc_registers regs = rtc->data->regs;
881+
882+
if (regs.cfgr != UNDEF_REG) {
883+
unsigned int cfgr = readl_relaxed(rtc->base + regs.cfgr);
884+
885+
cfgr &= ~STM32_RTC_CFGR_LSCOEN;
886+
cfgr &= ~STM32_RTC_CFGR_OUT2_RMP;
887+
writel_relaxed(cfgr, rtc->base + regs.cfgr);
888+
}
889+
}
890+
795891
static int stm32_rtc_check_rif(struct stm32_rtc *stm32_rtc,
796892
struct stm32_rtc_rif_resource res)
797893
{
@@ -1024,6 +1120,8 @@ static int stm32_rtc_probe(struct platform_device *pdev)
10241120
goto err;
10251121
}
10261122

1123+
stm32_rtc_clean_outs(rtc);
1124+
10271125
ret = devm_pinctrl_register_and_init(&pdev->dev, &stm32_rtc_pdesc, rtc, &pctl);
10281126
if (ret)
10291127
return dev_err_probe(&pdev->dev, ret, "pinctrl register failed");
@@ -1070,6 +1168,9 @@ static void stm32_rtc_remove(struct platform_device *pdev)
10701168
const struct stm32_rtc_registers *regs = &rtc->data->regs;
10711169
unsigned int cr;
10721170

1171+
if (!IS_ERR_OR_NULL(rtc->clk_lsco))
1172+
clk_unregister_gate(rtc->clk_lsco);
1173+
10731174
/* Disable interrupts */
10741175
stm32_rtc_wpr_unlock(rtc);
10751176
cr = readl_relaxed(rtc->base + regs->cr);

0 commit comments

Comments
 (0)