* [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs
@ 2025-02-28 8:18 Ciprian Costea
2025-02-28 8:18 ` [PATCH v8 1/4] dt-bindings: rtc: add schema for NXP " Ciprian Costea
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Ciprian Costea @ 2025-02-28 8:18 UTC (permalink / raw)
To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Catalin Marinas, Will Deacon
Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel,
NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz,
Enric Balletbo, Ciprian Marian Costea
From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
This patch series add support for the NXP RTC hardware module present on
S32G2/S32G3 SoCs.
RTC tracks clock time during system suspend. It is used as a time-based
wakeup source for the S32G2/S32G3 SoCs.
RTC is not battery-powered and it is not kept alive during system reset.
Following is an example of Suspend to RAM trigger on S32G2/S32G3 SoCs,
using userspace tools such as rtcwake:
# rtcwake -s 120 -m mem
# rtcwake: assuming RTC uses UTC ...
# rtcwake: wakeup from "mem" using /dev/rtc0 at Wed Feb 6 06:28:36 2036
#
Changes in V8:
- Added description of uncommon S32G RTC hardware behaviour on resume.
Changes in V7:
- Changed 'ioread32/iowrite32' calls to more common 'readl/writel'.
- Removed calculations performed in 'suspend' and 'resume' routines by
using RTC API ('APIVAL') functionality instead of relying on setting
'RTCVAL'.
- Simplified 'set_alarm' and 'read_time/read_alarm' by usage of
RTC APIVAL functionality and relying on kernel system time.
- Added comment about the available RTC hardware frequency divisors in the
RTC driver.
- Used both available frequency divisors to increase the RTC rollover
time.
- Removed a redundant error check on 'priv->irq'.
Changes in V6:
- Fixed a coding style issue regarding kernel doc reported by kernel test robot
- Refactored small sections from the S32G RTC driver without impacting
functionality
- Fixed an error probe path issue on S32G RTC driver.
- Added 'rtc' schema in S32G-RTC bindings
Changes in V5:
- Removed rollover support.
- Removed clock switching support between Runtime and Suspend. A clock source
which is always available has been used instead.
- Enabled 512 value RTC hardware frequency divisor to achieve higher rollover
time
- Removed unneeded 'remove' callback.
- Decreased driver print verbosity on error paths.
- Provided 'clock-names' actual names in bindings documentation
- Remove __maybe_unused notations. Used the DEFINE_SIMPLE_DEV_PM_OPS() and
pm_sleep_ptr() macros to handle the .suspend/.resume callbacks.
- Fixed some alignment issues.
Changes in V4:
- Dropped 'assigned-*' clock management approach. Simplified RTC Runtime
and Suspend/Standby clock configuration.
- Simplified error paths on probe function
- Removed node label from bindings example
- Several cosmetic coding style fixes
Changes in V3:
- Removed 'nxp,s32g3-rtc' compatible string
- Change to 'remove' callback from 'remove_new'
- Used 'dev.parent' from 'struct rtc_device' instead of defining a
specific 'struct device' in driver data
- Fixed several errors reported by kernel test robot
- Removed 'assigned-clocks', 'assigned-clock-parents' and
'assigned-clock-rates' from required properties in the binding
documentation.
- Refactored S32G RTC driver such that a default clock source and
divisors configuration will be applied in case 'assigned-clocks' and
'assigned-clock-parents' properties are missing.
Changes in V2:
- Removed 'clksel' support from dts bindings. Used clock parents support
from CCF to better illustrate the RTC hardware IP from S32G2/S32G3.
- Removed frequency dividers support from dts bindings. Used assigned
clock frequencies support from CCF instead.
- Reduced the interval while RTC is voluntarily disabled to a simple
register write in order to avoid any race condition between a possbile
rollover and 'suspend' callback execution flow.
- Updated bindings documentation with respect to clocking support.
- Fixed a potential unused variable warning reported by kernel test robot.
- Updated to usage of 'devm_rtc_allocate_device' and 'devm_rtc_register_device'
instead of deprecated 'devm_rtc_device_register'.
Ciprian Marian Costea (4):
dt-bindings: rtc: add schema for NXP S32G2/S32G3 SoCs
rtc: s32g: add NXP S32G2/S32G3 SoC support
arm64: defconfig: add S32G RTC module support
MAINTAINERS: add NXP S32G RTC driver
.../devicetree/bindings/rtc/nxp,s32g-rtc.yaml | 72 ++++
MAINTAINERS | 2 +
arch/arm64/configs/defconfig | 1 +
drivers/rtc/Kconfig | 11 +
drivers/rtc/Makefile | 1 +
drivers/rtc/rtc-s32g.c | 386 ++++++++++++++++++
6 files changed, 473 insertions(+)
create mode 100644 Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml
create mode 100644 drivers/rtc/rtc-s32g.c
--
2.45.2
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v8 1/4] dt-bindings: rtc: add schema for NXP S32G2/S32G3 SoCs 2025-02-28 8:18 [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea @ 2025-02-28 8:18 ` Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea ` (2 subsequent siblings) 3 siblings, 0 replies; 8+ messages in thread From: Ciprian Costea @ 2025-02-28 8:18 UTC (permalink / raw) To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea, Bogdan-Gabriel Roman, Ghennadi Procopciuc From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> RTC tracks clock time during system suspend and it is used as a wakeup source on S32G2/S32G3 architecture. RTC from S32G2/S32G3 is not battery-powered and it is not kept alive during system reset. Co-developed-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman@nxp.com> Signed-off-by: Bogdan-Gabriel Roman <bogdan-gabriel.roman@nxp.com> Co-developed-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> Reviewed-by: Rob Herring (Arm) <robh@kernel.org> --- .../devicetree/bindings/rtc/nxp,s32g-rtc.yaml | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml diff --git a/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml b/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml new file mode 100644 index 000000000000..40fd2fa298fe --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/nxp,s32g-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP S32G2/S32G3 Real Time Clock (RTC) + +maintainers: + - Bogdan Hamciuc <bogdan.hamciuc@nxp.com> + - Ciprian Marian Costea <ciprianmarian.costea@nxp.com> + +description: + RTC hardware module present on S32G2/S32G3 SoCs is used as a wakeup source. + It is not kept alive during system reset and it is not battery-powered. + +allOf: + - $ref: rtc.yaml# + +properties: + compatible: + oneOf: + - enum: + - nxp,s32g2-rtc + - items: + - const: nxp,s32g3-rtc + - const: nxp,s32g2-rtc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: ipg clock drives the access to the RTC iomapped registers + - description: Clock source for the RTC module. Can be selected between + 4 different clock sources using an integrated hardware mux. + On S32G2/S32G3 SoCs, 'source0' is the SIRC clock (~32KHz) and it is + available during standby and runtime. 'source1' is reserved and cannot + be used. 'source2' is the FIRC clock and it is only available during + runtime providing a better resolution (~48MHz). 'source3' is an external + RTC clock source which can be additionally added in hardware. + + clock-names: + items: + - const: ipg + - enum: [ source0, source1, source2, source3 ] + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + + rtc@40060000 { + compatible = "nxp,s32g3-rtc", + "nxp,s32g2-rtc"; + reg = <0x40060000 0x1000>; + interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clks 54>, <&clks 55>; + clock-names = "ipg", "source0"; + }; -- 2.45.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support 2025-02-28 8:18 [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 1/4] dt-bindings: rtc: add schema for NXP " Ciprian Costea @ 2025-02-28 8:18 ` Ciprian Costea 2025-02-28 15:37 ` Frank Li ` (2 more replies) 2025-02-28 8:18 ` [PATCH v8 3/4] arm64: defconfig: add S32G RTC module support Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 4/4] MAINTAINERS: add NXP S32G RTC driver Ciprian Costea 3 siblings, 3 replies; 8+ messages in thread From: Ciprian Costea @ 2025-02-28 8:18 UTC (permalink / raw) To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea, Bogdan Hamciuc, Ghennadi Procopciuc From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> Add a RTC driver for NXP S32G2/S32G3 SoCs. RTC tracks clock time during system suspend. It can be a wakeup source for the S32G2/S32G3 SoC based boards. The RTC module from S32G2/S32G3 is not battery-powered and it is not kept alive during system reset. Co-developed-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com> Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com> Co-developed-by: Ghennadi Procopciuc <Ghennadi.Procopciuc@nxp.com> Signed-off-by: Ghennadi Procopciuc <Ghennadi.Procopciuc@nxp.com> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> --- drivers/rtc/Kconfig | 11 ++ drivers/rtc/Makefile | 1 + drivers/rtc/rtc-s32g.c | 386 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 398 insertions(+) create mode 100644 drivers/rtc/rtc-s32g.c diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 0bbbf778ecfa..510dc2db745d 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -2103,4 +2103,15 @@ config RTC_DRV_AMLOGIC_A4 This driver can also be built as a module. If so, the module will be called "rtc-amlogic-a4". +config RTC_DRV_S32G + tristate "RTC driver for S32G2/S32G3 SoCs" + depends on ARCH_S32 || COMPILE_TEST + depends on COMMON_CLK + help + Say yes to enable RTC driver for platforms based on the + S32G2/S32G3 SoC family. + + This RTC module can be used as a wakeup source. + Please note that it is not battery-powered. + endif # RTC_CLASS diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 489b4ab07068..e4b616ecd5ce 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -161,6 +161,7 @@ obj-$(CONFIG_RTC_DRV_RX8111) += rtc-rx8111.o obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o obj-$(CONFIG_RTC_DRV_RZN1) += rtc-rzn1.o obj-$(CONFIG_RTC_DRV_RENESAS_RTCA3) += rtc-renesas-rtca3.o +obj-$(CONFIG_RTC_DRV_S32G) += rtc-s32g.o obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o diff --git a/drivers/rtc/rtc-s32g.c b/drivers/rtc/rtc-s32g.c new file mode 100644 index 000000000000..251d86ab3046 --- /dev/null +++ b/drivers/rtc/rtc-s32g.c @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2025 NXP + */ + +#include <linux/clk.h> +#include <linux/iopoll.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/rtc.h> + +#define RTCC_OFFSET 0x4ul +#define RTCS_OFFSET 0x8ul +#define APIVAL_OFFSET 0x10ul + +/* RTCC fields */ +#define RTCC_CNTEN BIT(31) +#define RTCC_APIEN BIT(15) +#define RTCC_APIIE BIT(14) +#define RTCC_CLKSEL_MASK GENMASK(13, 12) +#define RTCC_DIV512EN BIT(11) +#define RTCC_DIV32EN BIT(10) + +/* RTCS fields */ +#define RTCS_INV_API BIT(17) +#define RTCS_APIF BIT(13) + +#define APIVAL_MAX_VAL GENMASK(31, 0) +#define RTC_SYNCH_TIMEOUT (100 * USEC_PER_MSEC) + +/* + * S32G2 and S32G3 SoCs have RTC clock source1 reserved and + * should not be used. + */ +#define RTC_CLK_SRC1_RESERVED BIT(1) + +/* + * S32G RTC module has a 512 value and a 32 value hardware frequency + * divisors (DIV512 and DIV32) which could be used to achieve higher + * counter ranges by lowering the RTC frequency. + */ +enum { + DIV1 = 1, + DIV32 = 32, + DIV512 = 512, + DIV512_32 = 16384 +}; + +static const char *const rtc_clk_src[] = { + "source0", + "source1", + "source2", + "source3" +}; + +struct rtc_priv { + struct rtc_device *rdev; + void __iomem *rtc_base; + struct clk *ipg; + struct clk *clk_src; + const struct rtc_soc_data *rtc_data; + u64 rtc_hz; + time64_t sleep_sec; + int irq; + u32 clk_src_idx; +}; + +struct rtc_soc_data { + u32 clk_div; + u32 reserved_clk_mask; +}; + +static const struct rtc_soc_data rtc_s32g2_data = { + .clk_div = DIV512_32, + .reserved_clk_mask = RTC_CLK_SRC1_RESERVED, +}; + +static irqreturn_t s32g_rtc_handler(int irq, void *dev) +{ + struct rtc_priv *priv = platform_get_drvdata(dev); + u32 status; + + status = readl(priv->rtc_base + RTCS_OFFSET); + + if (status & RTCS_APIF) { + writel(0x0, priv->rtc_base + APIVAL_OFFSET); + writel(status | RTCS_APIF, priv->rtc_base + RTCS_OFFSET); + } + + rtc_update_irq(priv->rdev, 1, RTC_IRQF | RTC_AF); + + return IRQ_HANDLED; +} + +/* + * The function is not really getting time from the RTC since the S32G RTC + * has several limitations. Thus, to setup alarm use system time. + */ +static int s32g_rtc_read_time(struct device *dev, + struct rtc_time *tm) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + time64_t sec; + + if (check_add_overflow(ktime_get_real_seconds(), + priv->sleep_sec, &sec)) + return -ERANGE; + + rtc_time64_to_tm(sec, tm); + + return 0; +} + +static int s32g_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + u32 rtcc, rtcs; + + rtcc = readl(priv->rtc_base + RTCC_OFFSET); + rtcs = readl(priv->rtc_base + RTCS_OFFSET); + + alrm->enabled = rtcc & RTCC_APIIE; + if (alrm->enabled) + alrm->pending = !(rtcs & RTCS_APIF); + + return 0; +} + +static int s32g_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + u32 rtcc; + + /* RTC API functionality is used both for triggering interrupts + * and as a wakeup event. Hence it should always be enabled. + */ + rtcc = readl(priv->rtc_base + RTCC_OFFSET); + rtcc |= RTCC_APIEN | RTCC_APIIE; + writel(rtcc, priv->rtc_base + RTCC_OFFSET); + + return 0; +} + +static int s32g_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + unsigned long long cycles; + long long t_offset; + time64_t alrm_time; + u32 rtcs; + int ret; + + alrm_time = rtc_tm_to_time64(&alrm->time); + t_offset = alrm_time - ktime_get_real_seconds() - priv->sleep_sec; + if (t_offset < 0) + return -ERANGE; + + cycles = t_offset * priv->rtc_hz; + if (cycles > APIVAL_MAX_VAL) + return -ERANGE; + + /* APIVAL could have been reset from the IRQ handler. + * Hence, we wait in case there is a synchronization process. + */ + ret = read_poll_timeout(readl, rtcs, !(rtcs & RTCS_INV_API), + 0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET); + if (ret) + return ret; + + writel(cycles, priv->rtc_base + APIVAL_OFFSET); + + return read_poll_timeout(readl, rtcs, !(rtcs & RTCS_INV_API), + 0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET); +} + +/* + * Disable the 32-bit free running counter. + * This allows Clock Source and Divisors selection + * to be performed without causing synchronization issues. + */ +static void s32g_rtc_disable(struct rtc_priv *priv) +{ + u32 rtcc = readl(priv->rtc_base + RTCC_OFFSET); + + rtcc &= ~RTCC_CNTEN; + writel(rtcc, priv->rtc_base + RTCC_OFFSET); +} + +static void s32g_rtc_enable(struct rtc_priv *priv) +{ + u32 rtcc = readl(priv->rtc_base + RTCC_OFFSET); + + rtcc |= RTCC_CNTEN; + writel(rtcc, priv->rtc_base + RTCC_OFFSET); +} + +static int rtc_clk_src_setup(struct rtc_priv *priv) +{ + u32 rtcc; + + if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx)) + return -EOPNOTSUPP; + + rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); + + switch (priv->rtc_data->clk_div) { + case DIV512_32: + rtcc |= RTCC_DIV512EN; + rtcc |= RTCC_DIV32EN; + break; + case DIV512: + rtcc |= RTCC_DIV512EN; + break; + case DIV32: + rtcc |= RTCC_DIV32EN; + break; + case DIV1: + break; + default: + return -EINVAL; + } + + rtcc |= RTCC_APIEN | RTCC_APIIE; + /* + * Make sure the CNTEN is 0 before we configure + * the clock source and dividers. + */ + s32g_rtc_disable(priv); + writel(rtcc, priv->rtc_base + RTCC_OFFSET); + s32g_rtc_enable(priv); + + return 0; +} + +static const struct rtc_class_ops rtc_ops = { + .read_time = s32g_rtc_read_time, + .read_alarm = s32g_rtc_read_alarm, + .set_alarm = s32g_rtc_set_alarm, + .alarm_irq_enable = s32g_rtc_alarm_irq_enable, +}; + +static int rtc_clk_dts_setup(struct rtc_priv *priv, + struct device *dev) +{ + u32 i; + + priv->ipg = devm_clk_get_enabled(dev, "ipg"); + if (IS_ERR(priv->ipg)) + return dev_err_probe(dev, PTR_ERR(priv->ipg), + "Failed to get 'ipg' clock\n"); + + for (i = 0; i < ARRAY_SIZE(rtc_clk_src); i++) { + priv->clk_src = devm_clk_get_enabled(dev, rtc_clk_src[i]); + if (!IS_ERR(priv->clk_src)) { + priv->clk_src_idx = i; + break; + } + } + + if (IS_ERR(priv->clk_src)) + return dev_err_probe(dev, PTR_ERR(priv->clk_src), + "Failed to get rtc module clock source\n"); + + return 0; +} + +static int s32g_rtc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rtc_priv *priv; + unsigned long rtc_hz; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->rtc_data = of_device_get_match_data(dev); + if (!priv->rtc_data) + return -ENODEV; + + priv->rtc_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->rtc_base)) + return PTR_ERR(priv->rtc_base); + + device_init_wakeup(dev, true); + + ret = rtc_clk_dts_setup(priv, dev); + if (ret) + return ret; + + priv->rdev = devm_rtc_allocate_device(dev); + if (IS_ERR(priv->rdev)) + return PTR_ERR(priv->rdev); + + ret = rtc_clk_src_setup(priv); + if (ret) + return ret; + + priv->irq = platform_get_irq(pdev, 0); + if (priv->irq < 0) { + ret = priv->irq; + goto disable_rtc; + } + + rtc_hz = clk_get_rate(priv->clk_src); + if (!rtc_hz) { + dev_err(dev, "Failed to get RTC frequency\n"); + ret = -EINVAL; + goto disable_rtc; + } + + priv->rtc_hz = rtc_hz / priv->rtc_data->clk_div; + if (rtc_hz % priv->rtc_data->clk_div) + priv->rtc_hz++; + + platform_set_drvdata(pdev, priv); + priv->rdev->ops = &rtc_ops; + + ret = devm_request_irq(dev, priv->irq, + s32g_rtc_handler, 0, dev_name(dev), pdev); + if (ret) { + dev_err(dev, "Request interrupt %d failed, error: %d\n", + priv->irq, ret); + goto disable_rtc; + } + + ret = devm_rtc_register_device(priv->rdev); + if (ret) + goto disable_rtc; + + return 0; + +disable_rtc: + s32g_rtc_disable(priv); + return ret; +} + +static int s32g_rtc_suspend(struct device *dev) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + u32 apival = readl(priv->rtc_base + APIVAL_OFFSET); + + if (check_add_overflow(priv->sleep_sec, div64_u64(apival, priv->rtc_hz), + &priv->sleep_sec)) { + dev_warn(dev, "Overflow on sleep cycles occurred. Resetting to 0.\n"); + priv->sleep_sec = 0; + } + + return 0; +} + +static int s32g_rtc_resume(struct device *dev) +{ + struct rtc_priv *priv = dev_get_drvdata(dev); + + /* The transition from resume to run is a reset event. + * This leads to the RTC registers being reset after resume from + * suspend. It is uncommon, but this behaviour has been observed + * on S32G RTC after issueing a Suspend to RAM operation. + * Thus, reconfigure RTC registers on the resume path. + */ + return rtc_clk_src_setup(priv); +} + +static const struct of_device_id rtc_dt_ids[] = { + { .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data}, + { /* sentinel */ }, +}; + +static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops, + s32g_rtc_suspend, s32g_rtc_resume); + +static struct platform_driver s32g_rtc_driver = { + .driver = { + .name = "s32g-rtc", + .pm = pm_sleep_ptr(&s32g_rtc_pm_ops), + .of_match_table = rtc_dt_ids, + }, + .probe = s32g_rtc_probe, +}; +module_platform_driver(s32g_rtc_driver); + +MODULE_AUTHOR("NXP"); +MODULE_DESCRIPTION("NXP RTC driver for S32G2/S32G3"); +MODULE_LICENSE("GPL"); -- 2.45.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea @ 2025-02-28 15:37 ` Frank Li 2025-03-05 18:16 ` kernel test robot 2025-03-06 14:47 ` kernel test robot 2 siblings, 0 replies; 8+ messages in thread From: Frank Li @ 2025-02-28 15:37 UTC (permalink / raw) To: Ciprian Costea Cc: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon, linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Bogdan Hamciuc, Ghennadi Procopciuc On Fri, Feb 28, 2025 at 10:18:10AM +0200, Ciprian Costea wrote: > From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > > Add a RTC driver for NXP S32G2/S32G3 SoCs. > > RTC tracks clock time during system suspend. It can be a wakeup source > for the S32G2/S32G3 SoC based boards. > > The RTC module from S32G2/S32G3 is not battery-powered and it is not kept > alive during system reset. > > Co-developed-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com> > Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com> > Co-developed-by: Ghennadi Procopciuc <Ghennadi.Procopciuc@nxp.com> > Signed-off-by: Ghennadi Procopciuc <Ghennadi.Procopciuc@nxp.com> > Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/rtc/Kconfig | 11 ++ > drivers/rtc/Makefile | 1 + > drivers/rtc/rtc-s32g.c | 386 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 398 insertions(+) > create mode 100644 drivers/rtc/rtc-s32g.c > > diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig > index 0bbbf778ecfa..510dc2db745d 100644 > --- a/drivers/rtc/Kconfig > +++ b/drivers/rtc/Kconfig > @@ -2103,4 +2103,15 @@ config RTC_DRV_AMLOGIC_A4 > This driver can also be built as a module. If so, the module > will be called "rtc-amlogic-a4". > > +config RTC_DRV_S32G > + tristate "RTC driver for S32G2/S32G3 SoCs" > + depends on ARCH_S32 || COMPILE_TEST > + depends on COMMON_CLK > + help > + Say yes to enable RTC driver for platforms based on the > + S32G2/S32G3 SoC family. > + > + This RTC module can be used as a wakeup source. > + Please note that it is not battery-powered. > + > endif # RTC_CLASS > diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile > index 489b4ab07068..e4b616ecd5ce 100644 > --- a/drivers/rtc/Makefile > +++ b/drivers/rtc/Makefile > @@ -161,6 +161,7 @@ obj-$(CONFIG_RTC_DRV_RX8111) += rtc-rx8111.o > obj-$(CONFIG_RTC_DRV_RX8581) += rtc-rx8581.o > obj-$(CONFIG_RTC_DRV_RZN1) += rtc-rzn1.o > obj-$(CONFIG_RTC_DRV_RENESAS_RTCA3) += rtc-renesas-rtca3.o > +obj-$(CONFIG_RTC_DRV_S32G) += rtc-s32g.o > obj-$(CONFIG_RTC_DRV_S35390A) += rtc-s35390a.o > obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o > obj-$(CONFIG_RTC_DRV_S5M) += rtc-s5m.o > diff --git a/drivers/rtc/rtc-s32g.c b/drivers/rtc/rtc-s32g.c > new file mode 100644 > index 000000000000..251d86ab3046 > --- /dev/null > +++ b/drivers/rtc/rtc-s32g.c > @@ -0,0 +1,386 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright 2025 NXP > + */ > + > +#include <linux/clk.h> > +#include <linux/iopoll.h> > +#include <linux/of_irq.h> > +#include <linux/platform_device.h> > +#include <linux/rtc.h> > + > +#define RTCC_OFFSET 0x4ul > +#define RTCS_OFFSET 0x8ul > +#define APIVAL_OFFSET 0x10ul > + > +/* RTCC fields */ > +#define RTCC_CNTEN BIT(31) > +#define RTCC_APIEN BIT(15) > +#define RTCC_APIIE BIT(14) > +#define RTCC_CLKSEL_MASK GENMASK(13, 12) > +#define RTCC_DIV512EN BIT(11) > +#define RTCC_DIV32EN BIT(10) > + > +/* RTCS fields */ > +#define RTCS_INV_API BIT(17) > +#define RTCS_APIF BIT(13) > + > +#define APIVAL_MAX_VAL GENMASK(31, 0) > +#define RTC_SYNCH_TIMEOUT (100 * USEC_PER_MSEC) > + > +/* > + * S32G2 and S32G3 SoCs have RTC clock source1 reserved and > + * should not be used. > + */ > +#define RTC_CLK_SRC1_RESERVED BIT(1) > + > +/* > + * S32G RTC module has a 512 value and a 32 value hardware frequency > + * divisors (DIV512 and DIV32) which could be used to achieve higher > + * counter ranges by lowering the RTC frequency. > + */ > +enum { > + DIV1 = 1, > + DIV32 = 32, > + DIV512 = 512, > + DIV512_32 = 16384 > +}; > + > +static const char *const rtc_clk_src[] = { > + "source0", > + "source1", > + "source2", > + "source3" > +}; > + > +struct rtc_priv { > + struct rtc_device *rdev; > + void __iomem *rtc_base; > + struct clk *ipg; > + struct clk *clk_src; > + const struct rtc_soc_data *rtc_data; > + u64 rtc_hz; > + time64_t sleep_sec; > + int irq; > + u32 clk_src_idx; > +}; > + > +struct rtc_soc_data { > + u32 clk_div; > + u32 reserved_clk_mask; > +}; > + > +static const struct rtc_soc_data rtc_s32g2_data = { > + .clk_div = DIV512_32, > + .reserved_clk_mask = RTC_CLK_SRC1_RESERVED, > +}; > + > +static irqreturn_t s32g_rtc_handler(int irq, void *dev) > +{ > + struct rtc_priv *priv = platform_get_drvdata(dev); > + u32 status; > + > + status = readl(priv->rtc_base + RTCS_OFFSET); > + > + if (status & RTCS_APIF) { > + writel(0x0, priv->rtc_base + APIVAL_OFFSET); > + writel(status | RTCS_APIF, priv->rtc_base + RTCS_OFFSET); > + } > + > + rtc_update_irq(priv->rdev, 1, RTC_IRQF | RTC_AF); > + > + return IRQ_HANDLED; > +} > + > +/* > + * The function is not really getting time from the RTC since the S32G RTC > + * has several limitations. Thus, to setup alarm use system time. > + */ > +static int s32g_rtc_read_time(struct device *dev, > + struct rtc_time *tm) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + time64_t sec; > + > + if (check_add_overflow(ktime_get_real_seconds(), > + priv->sleep_sec, &sec)) > + return -ERANGE; > + > + rtc_time64_to_tm(sec, tm); > + > + return 0; > +} > + > +static int s32g_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + u32 rtcc, rtcs; > + > + rtcc = readl(priv->rtc_base + RTCC_OFFSET); > + rtcs = readl(priv->rtc_base + RTCS_OFFSET); > + > + alrm->enabled = rtcc & RTCC_APIIE; > + if (alrm->enabled) > + alrm->pending = !(rtcs & RTCS_APIF); > + > + return 0; > +} > + > +static int s32g_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + u32 rtcc; > + > + /* RTC API functionality is used both for triggering interrupts > + * and as a wakeup event. Hence it should always be enabled. > + */ > + rtcc = readl(priv->rtc_base + RTCC_OFFSET); > + rtcc |= RTCC_APIEN | RTCC_APIIE; > + writel(rtcc, priv->rtc_base + RTCC_OFFSET); > + > + return 0; > +} > + > +static int s32g_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + unsigned long long cycles; > + long long t_offset; > + time64_t alrm_time; > + u32 rtcs; > + int ret; > + > + alrm_time = rtc_tm_to_time64(&alrm->time); > + t_offset = alrm_time - ktime_get_real_seconds() - priv->sleep_sec; > + if (t_offset < 0) > + return -ERANGE; > + > + cycles = t_offset * priv->rtc_hz; > + if (cycles > APIVAL_MAX_VAL) > + return -ERANGE; > + > + /* APIVAL could have been reset from the IRQ handler. > + * Hence, we wait in case there is a synchronization process. > + */ > + ret = read_poll_timeout(readl, rtcs, !(rtcs & RTCS_INV_API), > + 0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET); > + if (ret) > + return ret; > + > + writel(cycles, priv->rtc_base + APIVAL_OFFSET); > + > + return read_poll_timeout(readl, rtcs, !(rtcs & RTCS_INV_API), > + 0, RTC_SYNCH_TIMEOUT, false, priv->rtc_base + RTCS_OFFSET); > +} > + > +/* > + * Disable the 32-bit free running counter. > + * This allows Clock Source and Divisors selection > + * to be performed without causing synchronization issues. > + */ > +static void s32g_rtc_disable(struct rtc_priv *priv) > +{ > + u32 rtcc = readl(priv->rtc_base + RTCC_OFFSET); > + > + rtcc &= ~RTCC_CNTEN; > + writel(rtcc, priv->rtc_base + RTCC_OFFSET); > +} > + > +static void s32g_rtc_enable(struct rtc_priv *priv) > +{ > + u32 rtcc = readl(priv->rtc_base + RTCC_OFFSET); > + > + rtcc |= RTCC_CNTEN; > + writel(rtcc, priv->rtc_base + RTCC_OFFSET); > +} > + > +static int rtc_clk_src_setup(struct rtc_priv *priv) > +{ > + u32 rtcc; > + > + if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx)) > + return -EOPNOTSUPP; > + > + rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); > + > + switch (priv->rtc_data->clk_div) { > + case DIV512_32: > + rtcc |= RTCC_DIV512EN; > + rtcc |= RTCC_DIV32EN; > + break; > + case DIV512: > + rtcc |= RTCC_DIV512EN; > + break; > + case DIV32: > + rtcc |= RTCC_DIV32EN; > + break; > + case DIV1: > + break; > + default: > + return -EINVAL; > + } > + > + rtcc |= RTCC_APIEN | RTCC_APIIE; > + /* > + * Make sure the CNTEN is 0 before we configure > + * the clock source and dividers. > + */ > + s32g_rtc_disable(priv); > + writel(rtcc, priv->rtc_base + RTCC_OFFSET); > + s32g_rtc_enable(priv); > + > + return 0; > +} > + > +static const struct rtc_class_ops rtc_ops = { > + .read_time = s32g_rtc_read_time, > + .read_alarm = s32g_rtc_read_alarm, > + .set_alarm = s32g_rtc_set_alarm, > + .alarm_irq_enable = s32g_rtc_alarm_irq_enable, > +}; > + > +static int rtc_clk_dts_setup(struct rtc_priv *priv, > + struct device *dev) > +{ > + u32 i; > + > + priv->ipg = devm_clk_get_enabled(dev, "ipg"); > + if (IS_ERR(priv->ipg)) > + return dev_err_probe(dev, PTR_ERR(priv->ipg), > + "Failed to get 'ipg' clock\n"); > + > + for (i = 0; i < ARRAY_SIZE(rtc_clk_src); i++) { > + priv->clk_src = devm_clk_get_enabled(dev, rtc_clk_src[i]); > + if (!IS_ERR(priv->clk_src)) { > + priv->clk_src_idx = i; > + break; > + } > + } > + > + if (IS_ERR(priv->clk_src)) > + return dev_err_probe(dev, PTR_ERR(priv->clk_src), > + "Failed to get rtc module clock source\n"); > + > + return 0; > +} > + > +static int s32g_rtc_probe(struct platform_device *pdev) > +{ > + struct device *dev = &pdev->dev; > + struct rtc_priv *priv; > + unsigned long rtc_hz; > + int ret; > + > + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); > + if (!priv) > + return -ENOMEM; > + > + priv->rtc_data = of_device_get_match_data(dev); > + if (!priv->rtc_data) > + return -ENODEV; > + > + priv->rtc_base = devm_platform_ioremap_resource(pdev, 0); > + if (IS_ERR(priv->rtc_base)) > + return PTR_ERR(priv->rtc_base); > + > + device_init_wakeup(dev, true); > + > + ret = rtc_clk_dts_setup(priv, dev); > + if (ret) > + return ret; > + > + priv->rdev = devm_rtc_allocate_device(dev); > + if (IS_ERR(priv->rdev)) > + return PTR_ERR(priv->rdev); > + > + ret = rtc_clk_src_setup(priv); > + if (ret) > + return ret; > + > + priv->irq = platform_get_irq(pdev, 0); > + if (priv->irq < 0) { > + ret = priv->irq; > + goto disable_rtc; > + } > + > + rtc_hz = clk_get_rate(priv->clk_src); > + if (!rtc_hz) { > + dev_err(dev, "Failed to get RTC frequency\n"); > + ret = -EINVAL; > + goto disable_rtc; > + } > + > + priv->rtc_hz = rtc_hz / priv->rtc_data->clk_div; > + if (rtc_hz % priv->rtc_data->clk_div) > + priv->rtc_hz++; > + > + platform_set_drvdata(pdev, priv); > + priv->rdev->ops = &rtc_ops; > + > + ret = devm_request_irq(dev, priv->irq, > + s32g_rtc_handler, 0, dev_name(dev), pdev); > + if (ret) { > + dev_err(dev, "Request interrupt %d failed, error: %d\n", > + priv->irq, ret); > + goto disable_rtc; > + } > + > + ret = devm_rtc_register_device(priv->rdev); > + if (ret) > + goto disable_rtc; > + > + return 0; > + > +disable_rtc: > + s32g_rtc_disable(priv); > + return ret; > +} > + > +static int s32g_rtc_suspend(struct device *dev) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + u32 apival = readl(priv->rtc_base + APIVAL_OFFSET); > + > + if (check_add_overflow(priv->sleep_sec, div64_u64(apival, priv->rtc_hz), > + &priv->sleep_sec)) { > + dev_warn(dev, "Overflow on sleep cycles occurred. Resetting to 0.\n"); > + priv->sleep_sec = 0; > + } > + > + return 0; > +} > + > +static int s32g_rtc_resume(struct device *dev) > +{ > + struct rtc_priv *priv = dev_get_drvdata(dev); > + > + /* The transition from resume to run is a reset event. > + * This leads to the RTC registers being reset after resume from > + * suspend. It is uncommon, but this behaviour has been observed > + * on S32G RTC after issueing a Suspend to RAM operation. > + * Thus, reconfigure RTC registers on the resume path. > + */ > + return rtc_clk_src_setup(priv); > +} > + > +static const struct of_device_id rtc_dt_ids[] = { > + { .compatible = "nxp,s32g2-rtc", .data = &rtc_s32g2_data}, > + { /* sentinel */ }, > +}; > + > +static DEFINE_SIMPLE_DEV_PM_OPS(s32g_rtc_pm_ops, > + s32g_rtc_suspend, s32g_rtc_resume); > + > +static struct platform_driver s32g_rtc_driver = { > + .driver = { > + .name = "s32g-rtc", > + .pm = pm_sleep_ptr(&s32g_rtc_pm_ops), > + .of_match_table = rtc_dt_ids, > + }, > + .probe = s32g_rtc_probe, > +}; > +module_platform_driver(s32g_rtc_driver); > + > +MODULE_AUTHOR("NXP"); > +MODULE_DESCRIPTION("NXP RTC driver for S32G2/S32G3"); > +MODULE_LICENSE("GPL"); > -- > 2.45.2 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea 2025-02-28 15:37 ` Frank Li @ 2025-03-05 18:16 ` kernel test robot 2025-03-06 14:47 ` kernel test robot 2 siblings, 0 replies; 8+ messages in thread From: kernel test robot @ 2025-03-05 18:16 UTC (permalink / raw) To: Ciprian Costea, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: oe-kbuild-all, linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea, Bogdan Hamciuc, Ghennadi Procopciuc Hi Ciprian, kernel test robot noticed the following build errors: [auto build test ERROR on robh/for-next] [also build test ERROR on arm64/for-next/core krzk-dt/for-next linus/master v6.14-rc5 next-20250305] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ciprian-Costea/dt-bindings-rtc-add-schema-for-NXP-S32G2-S32G3-SoCs/20250228-162229 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next patch link: https://lore.kernel.org/r/20250228081812.3115478-3-ciprianmarian.costea%40oss.nxp.com patch subject: [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support config: sparc-allmodconfig (https://download.01.org/0day-ci/archive/20250306/202503060247.j7Mbl9vb-lkp@intel.com/config) compiler: sparc64-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250306/202503060247.j7Mbl9vb-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503060247.j7Mbl9vb-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/rtc/rtc-s32g.c: In function 'rtc_clk_src_setup': >> drivers/rtc/rtc-s32g.c:204:16: error: implicit declaration of function 'FIELD_PREP' [-Wimplicit-function-declaration] 204 | rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); | ^~~~~~~~~~ vim +/FIELD_PREP +204 drivers/rtc/rtc-s32g.c 196 197 static int rtc_clk_src_setup(struct rtc_priv *priv) 198 { 199 u32 rtcc; 200 201 if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx)) 202 return -EOPNOTSUPP; 203 > 204 rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); 205 206 switch (priv->rtc_data->clk_div) { 207 case DIV512_32: 208 rtcc |= RTCC_DIV512EN; 209 rtcc |= RTCC_DIV32EN; 210 break; 211 case DIV512: 212 rtcc |= RTCC_DIV512EN; 213 break; 214 case DIV32: 215 rtcc |= RTCC_DIV32EN; 216 break; 217 case DIV1: 218 break; 219 default: 220 return -EINVAL; 221 } 222 223 rtcc |= RTCC_APIEN | RTCC_APIIE; 224 /* 225 * Make sure the CNTEN is 0 before we configure 226 * the clock source and dividers. 227 */ 228 s32g_rtc_disable(priv); 229 writel(rtcc, priv->rtc_base + RTCC_OFFSET); 230 s32g_rtc_enable(priv); 231 232 return 0; 233 } 234 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea 2025-02-28 15:37 ` Frank Li 2025-03-05 18:16 ` kernel test robot @ 2025-03-06 14:47 ` kernel test robot 2 siblings, 0 replies; 8+ messages in thread From: kernel test robot @ 2025-03-06 14:47 UTC (permalink / raw) To: Ciprian Costea, Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: llvm, oe-kbuild-all, linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea, Bogdan Hamciuc, Ghennadi Procopciuc Hi Ciprian, kernel test robot noticed the following build errors: [auto build test ERROR on robh/for-next] [also build test ERROR on arm64/for-next/core krzk-dt/for-next linus/master v6.14-rc5 next-20250306] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ciprian-Costea/dt-bindings-rtc-add-schema-for-NXP-S32G2-S32G3-SoCs/20250228-162229 base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next patch link: https://lore.kernel.org/r/20250228081812.3115478-3-ciprianmarian.costea%40oss.nxp.com patch subject: [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support config: hexagon-allyesconfig (https://download.01.org/0day-ci/archive/20250306/202503062204.QeQoZBYt-lkp@intel.com/config) compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250306/202503062204.QeQoZBYt-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503062204.QeQoZBYt-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/rtc/rtc-s32g.c:204:9: error: call to undeclared function 'FIELD_PREP'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 204 | rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); | ^ 1 error generated. vim +/FIELD_PREP +204 drivers/rtc/rtc-s32g.c 196 197 static int rtc_clk_src_setup(struct rtc_priv *priv) 198 { 199 u32 rtcc; 200 201 if (priv->rtc_data->reserved_clk_mask & (1 << priv->clk_src_idx)) 202 return -EOPNOTSUPP; 203 > 204 rtcc = FIELD_PREP(RTCC_CLKSEL_MASK, priv->clk_src_idx); 205 206 switch (priv->rtc_data->clk_div) { 207 case DIV512_32: 208 rtcc |= RTCC_DIV512EN; 209 rtcc |= RTCC_DIV32EN; 210 break; 211 case DIV512: 212 rtcc |= RTCC_DIV512EN; 213 break; 214 case DIV32: 215 rtcc |= RTCC_DIV32EN; 216 break; 217 case DIV1: 218 break; 219 default: 220 return -EINVAL; 221 } 222 223 rtcc |= RTCC_APIEN | RTCC_APIIE; 224 /* 225 * Make sure the CNTEN is 0 before we configure 226 * the clock source and dividers. 227 */ 228 s32g_rtc_disable(priv); 229 writel(rtcc, priv->rtc_base + RTCC_OFFSET); 230 s32g_rtc_enable(priv); 231 232 return 0; 233 } 234 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v8 3/4] arm64: defconfig: add S32G RTC module support 2025-02-28 8:18 [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 1/4] dt-bindings: rtc: add schema for NXP " Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea @ 2025-02-28 8:18 ` Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 4/4] MAINTAINERS: add NXP S32G RTC driver Ciprian Costea 3 siblings, 0 replies; 8+ messages in thread From: Ciprian Costea @ 2025-02-28 8:18 UTC (permalink / raw) To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> The RTC hardware module present on S32G based SoCs tracks clock time during system suspend and it is used as a wakeup source on S32G2/S32G3 architecture. Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> --- arch/arm64/configs/defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index cb7da4415599..c24b88b0206e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1227,6 +1227,7 @@ CONFIG_RTC_DRV_DA9063=m CONFIG_RTC_DRV_EFI=y CONFIG_RTC_DRV_CROS_EC=y CONFIG_RTC_DRV_FSL_FTM_ALARM=m +CONFIG_RTC_DRV_S32G=m CONFIG_RTC_DRV_S3C=y CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_SUN6I=y -- 2.45.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v8 4/4] MAINTAINERS: add NXP S32G RTC driver 2025-02-28 8:18 [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea ` (2 preceding siblings ...) 2025-02-28 8:18 ` [PATCH v8 3/4] arm64: defconfig: add S32G RTC module support Ciprian Costea @ 2025-02-28 8:18 ` Ciprian Costea 3 siblings, 0 replies; 8+ messages in thread From: Ciprian Costea @ 2025-02-28 8:18 UTC (permalink / raw) To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Catalin Marinas, Will Deacon Cc: linux-rtc, devicetree, linux-kernel, linux-arm-kernel, NXP S32 Linux, imx, Christophe Lizzi, Alberto Ruiz, Enric Balletbo, Ciprian Marian Costea From: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> Add the NXP S32G RTC driver as maintained so further patches on this driver can be reviewed under this architecture. Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com> --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 873aa2cce4d7..515ed8115922 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2873,8 +2873,10 @@ R: Ghennadi Procopciuc <ghennadi.procopciuc@oss.nxp.com> R: NXP S32 Linux Team <s32@nxp.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: Documentation/devicetree/bindings/rtc/nxp,s32g-rtc.yaml F: arch/arm64/boot/dts/freescale/s32g*.dts* F: drivers/pinctrl/nxp/ +F: drivers/rtc/rtc-s32g.c ARM/NXP S32G/S32R DWMAC ETHERNET DRIVER M: Jan Petrous <jan.petrous@oss.nxp.com> -- 2.45.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-03-06 14:49 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-02-28 8:18 [PATCH v8 0/4] add NXP RTC driver support for S32G2/S32G3 SoCs Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 1/4] dt-bindings: rtc: add schema for NXP " Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 2/4] rtc: s32g: add NXP S32G2/S32G3 SoC support Ciprian Costea 2025-02-28 15:37 ` Frank Li 2025-03-05 18:16 ` kernel test robot 2025-03-06 14:47 ` kernel test robot 2025-02-28 8:18 ` [PATCH v8 3/4] arm64: defconfig: add S32G RTC module support Ciprian Costea 2025-02-28 8:18 ` [PATCH v8 4/4] MAINTAINERS: add NXP S32G RTC driver Ciprian Costea
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).