From nobody Sun Feb 8 07:21:46 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 280643016F3; Fri, 14 Nov 2025 09:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763111119; cv=none; b=eYi+j5jJWxYsCv9NZa/Jnw9ewTTTUAyAjFmhVSuCCW+BtatTGBZoPbgvXKThJ9V2THERmduAmpSzu6lI0okuaeMOFTsonamHyywQdzifwqGgD2NfY2ctYqMinkdInAxh5f2G4Bdi6ApbVuPp+Yy/jEkWoJ8kAnS0+8cPLWuG+xY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763111119; c=relaxed/simple; bh=W7vUfPCV2Re/veTEIy+aVEgUW5W4B2HZP9kA/zEvAj4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=feaYf1DUzrYm1ql4L48gvG3vq7xFD57Gfy2eVt3CG82xPep1xLYaiasG/KmmMTfWxhW1J1poSS3BJS5IjzrwG2esl/b9K5F+N34G9nBdscgJk4x8a+2HH33BiXhti/uva9Dwk77d292HfIFdDXM/MUJ9fWLQZ+DC22bmdR+x7GE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=MLJdKTo6; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="MLJdKTo6" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 5AE94nDnA1317727, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1763111089; bh=pgqUg7zLChDO/mQrSOJjX/Mltbn53Zs1aEEpfPEnjmg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=MLJdKTo6w+xwuEKCE9e0RhHH78QSUaW64fjdMx40xxPTCsnqfNMjitzUSm0VXFIIA hk5CtsOZUfnNU6SvN6SI+X6Vl0ve70bRvNEfl00jMNVdtyxSROD6hA6VgRnJJ3Ro6D zMprph3sK+uauxK46eiLHT3+AFFd4RM0EV881nfeukg9ZWw4ln7dxlJ5pvVHnVCrrs DxTpJ7Aj+LfBrEllHbDCtQeGTEhY63UPBf+TsbfzCprZWCffVkisIujeZymA+Ju9UW cEtrb/mOLW5WqGOWNwnvn0D2v7/H106SuSPQKbx+Wo+OayXgjGgb+nhBytBnycf0G/ +gBsLeEJuoZUQ== Received: from mail.realtek.com (rtkexhmbs04.realtek.com.tw[10.21.1.54]) by rtits2.realtek.com.tw (8.15.2/3.21/5.94) with ESMTPS id 5AE94nDnA1317727 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 14 Nov 2025 17:04:49 +0800 Received: from RTKEXHMBS01.realtek.com.tw (172.21.6.40) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.27; Fri, 14 Nov 2025 17:04:50 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS01.realtek.com.tw (172.21.6.40) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.27; Fri, 14 Nov 2025 17:04:49 +0800 Received: from ww-haowen.ting (172.21.177.97) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.1544.27 via Frontend Transport; Fri, 14 Nov 2025 17:04:49 +0800 From: Hao-Wen Ting To: , CC: , , , , , , , , , , , , , , Subject: [PATCH v2 1/2] dt-bindings: timer: Add Realtek SYSTIMER binding Date: Fri, 14 Nov 2025 17:04:47 +0800 Message-ID: <20251114090448.285685-2-haowen.ting@realtek.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251114090448.285685-1-haowen.ting@realtek.com> References: <20251114090448.285685-1-haowen.ting@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add device tree binding documentation for the Realtek SYSTIMER, a 64-bit timer that can be used as a tick broadcast timer on multi-core Realtek SoCs. The SYSTIMER remains active during deep CPU idle states where local timers are powered off, allowing all CPUs to enter power-cut idle states simultaneously for improved power efficiency. The timer operates at a fixed 1MHz frequency and supports oneshot mode for tick broadcast functionality. Signed-off-by: Hao-Wen Ting --- .../bindings/timer/realtek,systimer.yaml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 Documentation/devicetree/bindings/timer/realtek,systime= r.yaml diff --git a/Documentation/devicetree/bindings/timer/realtek,systimer.yaml = b/Documentation/devicetree/bindings/timer/realtek,systimer.yaml new file mode 100644 index 000000000000..8e68158c68f8 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/realtek,systimer.yaml @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/realtek,systimer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek System Timer + +maintainers: + - Hao-Wen Ting + +description: | + The Realtek SYSTIMER (System Timer) is a 64-bit timer that can be used as + a tick broadcast timer on multi-core Realtek SoCs. It remains active dur= ing + deep CPU idle states where local timers are powered off, allowing all CP= Us + to enter power-cut idle states simultaneously for better power efficienc= y. + + The timer operates at a fixed 1MHz frequency and supports oneshot mode + for tick broadcast functionality. + +properties: + compatible: + enum: + - realtek,rtd1625-systimer + - realtek,rtd1635-systimer + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + + timer@89420 { + compatible =3D "realtek,rtd1625-systimer"; + reg =3D <0x89420 0x18>; + interrupts =3D ; + }; --=20 2.34.1 From nobody Sun Feb 8 07:21:46 2026 Received: from rtits2.realtek.com.tw (rtits2.realtek.com [211.75.126.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 27FF43016F2; Fri, 14 Nov 2025 09:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=211.75.126.72 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763111119; cv=none; b=uNe2oI6BYrZeTZAKfubZK2ZlT9NYl+Bo2AhYu0YVPwlIZgg45KTLN5eXir82oc6xeLtVT+XUY0wV2GBi9dI/5wENBX556WbrVkCjh/X7hhsYaqUwnaf0BmB/+GitCWae96U7FcAYSgpJSYlYwPHZqrZAaIFE5ACxggqe+W++7M0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763111119; c=relaxed/simple; bh=z0WW/m0C/QNHL4G9AQIbN9vheNHzjlds8EnA2fjmysc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ZMis/5aVXfjCM4sSS2I8VyHi0iQuicCG9tsnnUMlPe9y4Nq2/Wd+iSjLcV6B2L/Emn2OsVX+RL9oIY/VDAsywxHRvBjQkLCZGCuL6rbPTiFKZwlPSxgmIKAMfhYX3BBUnlMEO4azKisjZQllBT3JxTSs4Bild9/mLL4ONaSVS4k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com; spf=pass smtp.mailfrom=realtek.com; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b=FwDe360d; arc=none smtp.client-ip=211.75.126.72 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=realtek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=realtek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=realtek.com header.i=@realtek.com header.b="FwDe360d" X-SpamFilter-By: ArmorX SpamTrap 5.80 with qID 5AE94n7C21317729, This message is accepted by code: ctloc85258 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=realtek.com; s=dkim; t=1763111089; bh=kYHxL6H7m3sW8nlusCCTkG1Vsra7Y4DSjNZfnC7YCow=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Content-Type; b=FwDe360dJTiiA/raWm2ZbxZlWNmNmYLupIkeu+1tV6yS0QR+nuZKtEzJJjFabIB2u YhIaTGAKLntkPKGJG2AW1gJ+6QyAo4fqR2fPc9EJ7EQpivfV3VXj1iyAJEDhV8S+xU sABZrXjC7/CQHcjLrYrjPlluaYcgzy/y2sbmJEwBpfjv+fP9omz1taXsPiJL20hzxx 8OBwhIxNflr8svj1qU595wLeKxwV23xhwi5ci0sVYNc1NXY6nZDh+3CYbBmcHzqdE7 PzrjwQketcHIo5tpFQnaTINqKXmB60Y4p7XtrJkSxAFeY0JEUIQPYx8s6gxF0HXZ6O l/xIAsq+BSp8A== Received: from mail.realtek.com (rtkexhmbs04.realtek.com.tw[10.21.1.54]) by rtits2.realtek.com.tw (8.15.2/3.21/5.94) with ESMTPS id 5AE94n7C21317729 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 14 Nov 2025 17:04:49 +0800 Received: from RTKEXHMBS01.realtek.com.tw (172.21.6.40) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.27; Fri, 14 Nov 2025 17:04:50 +0800 Received: from RTKEXHMBS04.realtek.com.tw (10.21.1.54) by RTKEXHMBS01.realtek.com.tw (172.21.6.40) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.27; Fri, 14 Nov 2025 17:04:49 +0800 Received: from ww-haowen.ting (172.21.177.97) by RTKEXHMBS04.realtek.com.tw (10.21.1.54) with Microsoft SMTP Server id 15.2.1544.27 via Frontend Transport; Fri, 14 Nov 2025 17:04:49 +0800 From: Hao-Wen Ting To: , CC: , , , , , , , , , , , , , , Subject: [PATCH v2 2/2] clocksource: Add Realtek systimer as tick broadcast driver Date: Fri, 14 Nov 2025 17:04:48 +0800 Message-ID: <20251114090448.285685-3-haowen.ting@realtek.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20251114090448.285685-1-haowen.ting@realtek.com> References: <20251114090448.285685-1-haowen.ting@realtek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add a tick broadcast timer driver for Realtek SoCs. On Realtek platforms, CPUs can enter deep idle states (C-states) where the local timer is stopped and powered off. Without a global tick broadcast timer, one CPU must remain awake to wake up the others, preventing all CPUs from entering deep idle simultaneously. This driver provides a tick broadcast timer which remains active during deep idle states. This allows all CPUs to enter power-cut idle states simultaneously, significantly reducing overall power consumption. The timer operates at 1MHz and supports oneshot mode. Signed-off-by: Hao-Wen Ting --- MAINTAINERS | 5 + drivers/clocksource/Kconfig | 10 ++ drivers/clocksource/Makefile | 1 + drivers/clocksource/timer-realtek.c | 172 ++++++++++++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 drivers/clocksource/timer-realtek.c diff --git a/MAINTAINERS b/MAINTAINERS index c7a116b795d5..90f511bb4982 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21670,6 +21670,11 @@ S: Maintained F: Documentation/devicetree/bindings/spi/realtek,rtl9301-snand.yaml F: drivers/spi/spi-realtek-rtl-snand.c =20 +REALTEK SYSTIMER DRIVER +M: Hao-Wen Ting +S: Maintained +F: drivers/clocksource/timer-realtek.c + REALTEK WIRELESS DRIVER (rtlwifi family) M: Ping-Ke Shih L: linux-wireless@vger.kernel.org diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index ffcd23668763..0c1835b48a18 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -782,4 +782,14 @@ config NXP_STM_TIMER Enables the support for NXP System Timer Module found in the s32g NXP platform series. =20 +config RTK_SYSTIMER + bool "Realtek SYSTIMER support" + depends on ARM || ARM64 + select TIMER_OF + help + This enables the global tick-broadcast timer on Realtek platforms. + If your Realtek platform supports power-cut level CPU idle states, + enabling this timer allows all CPUs to enter power-cut simultaneously + to achieve lower power consumption. + endmenu diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index ec4452ee958f..b46376af6b49 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -95,3 +95,4 @@ obj-$(CONFIG_CLKSRC_LOONGSON1_PWM) +=3D timer-loongson1-p= wm.o obj-$(CONFIG_EP93XX_TIMER) +=3D timer-ep93xx.o obj-$(CONFIG_RALINK_TIMER) +=3D timer-ralink.o obj-$(CONFIG_NXP_STM_TIMER) +=3D timer-nxp-stm.o +obj-$(CONFIG_RTK_SYSTIMER) +=3D timer-realtek.o diff --git a/drivers/clocksource/timer-realtek.c b/drivers/clocksource/time= r-realtek.c new file mode 100644 index 000000000000..f484fd97e964 --- /dev/null +++ b/drivers/clocksource/timer-realtek.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 Realtek Semiconductor Corp. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include "timer-of.h" + +#define ENBL 1 +#define DSBL 0 + +#define SYSTIMER_RATE 1000000 +#define SYSTIMER_MIN_DELTA 0x64 +#define SYSTIMER_MAX_DELTA ULONG_MAX + +/* SYSTIMER Register Offset (RTK Internal Use) */ +#define TS_LW_OFST 0x0 +#define TS_HW_OFST 0x4 +#define TS_CMP_VAL_LW_OFST 0x8 +#define TS_CMP_VAL_HW_OFST 0xC +#define TS_CMP_CTRL_OFST 0x10 +#define TS_CMP_STAT_OFST 0x14 + +/* SYSTIMER CMP CTRL REG Mask */ +#define TS_CMP_EN_MASK 0x1 +#define TS_WR_EN0_MASK 0x2 + +static void __iomem *systimer_base; + +static u64 rtk_ts64_read(void) +{ + u64 ts; + u32 low, high; + + /* Caution: Read LSB word (TS_LW_OFST) first then MSB (TS_HW_OFST) */ + low =3D readl(systimer_base + TS_LW_OFST); + high =3D readl(systimer_base + TS_HW_OFST); + + pr_debug("64bit-TS:HW=3D0x%08x,LW=3D0x%08x\n", high, low); + ts =3D ((u64)high << 32) | low; + + return ts; +} + +static void rtk_cmp_value_write(u64 value) +{ + u32 high, low; + + low =3D value & 0xFFFFFFFF; + high =3D value >> 32; + pr_debug("Write 64bit-CMP:HW=3D0x%08x,LW=3D0x%08x\n", high, low); + + writel(high, systimer_base + TS_CMP_VAL_HW_OFST); + writel(low, systimer_base + TS_CMP_VAL_LW_OFST); +} + +static inline void rtk_cmp_en_write(bool cmp_en) +{ + u32 val; + + val =3D TS_WR_EN0_MASK; + if (cmp_en =3D=3D ENBL) + val |=3D TS_CMP_EN_MASK; + + writel(val, systimer_base + TS_CMP_CTRL_OFST); + pr_debug("Write TS CMP CTRL =3D 0x%08x\n", val); +} + +static int rtk_syst_clkevt_next_ktime(ktime_t expires, + struct clock_event_device *clkevt) +{ + u64 cmp_val; + unsigned long flags; + ktime_t now =3D ktime_get(); + s64 delta_ns =3D ktime_to_ns(ktime_sub(expires, now)); + u64 delta_us =3D delta_ns / 1000; + + pr_debug("delta_ns =3D %lld, clkevt.min_delta_ns =3D %llu\n", + delta_ns, clkevt->min_delta_ns); + + if (delta_ns <=3D (s64)clkevt->min_delta_ns) { + delta_ns =3D clkevt->min_delta_ns; + delta_us =3D delta_ns / 1000; + pr_debug("Clamping delta_ns to min_delta_ns\n"); + } + + rtk_cmp_en_write(DSBL); + local_irq_save(flags); + cmp_val =3D rtk_ts64_read(); + + /* Set CMP value to current timestamp plus delta_us */ + rtk_cmp_value_write(cmp_val + delta_us); + rtk_cmp_en_write(ENBL); + local_irq_restore(flags); + return 0; +} + +static irqreturn_t rtk_ts_match_intr_handler(int irq, void *dev_id) +{ + u32 val; + void __iomem *reg_base; + struct clock_event_device *clkevt =3D dev_id; + + /* Disable TS CMP Match */ + rtk_cmp_en_write(DSBL); + + /* Clear TS CMP INTR */ + reg_base =3D systimer_base + TS_CMP_STAT_OFST; + val =3D readl(reg_base) & TS_CMP_EN_MASK; + writel(val | TS_CMP_EN_MASK, reg_base); + + clkevt->event_handler(clkevt); + + return IRQ_HANDLED; +} + +static int rtk_syst_shutdown(struct clock_event_device *clkevt) +{ + void __iomem *reg_base; + u64 cmp_val =3D 0; + + /* Disable TS CMP Match */ + rtk_cmp_en_write(DSBL); + /* Set compare value to 0 */ + rtk_cmp_value_write(cmp_val); + + /* Clear TS CMP INTR */ + reg_base =3D systimer_base + TS_CMP_STAT_OFST; + writel(TS_CMP_EN_MASK, reg_base); + return 0; +} + +static struct timer_of _to =3D { + .flags =3D TIMER_OF_IRQ | TIMER_OF_BASE, + + .clkevt =3D { + .name =3D "rtk-clkevt", + .rating =3D 300, + .cpumask =3D cpu_possible_mask, + .features =3D CLOCK_EVT_FEAT_DYNIRQ | + CLOCK_EVT_FEAT_ONESHOT | + CLOCK_EVT_FEAT_KTIME, + .set_next_ktime =3D rtk_syst_clkevt_next_ktime, + .set_state_oneshot =3D rtk_syst_shutdown, + .set_state_shutdown =3D rtk_syst_shutdown + }, + + .of_irq =3D { + .flags =3D IRQF_TIMER | IRQF_IRQPOLL, + .handler =3D rtk_ts_match_intr_handler + }, +}; + +static int __init rtk_systimer_init(struct device_node *node) +{ + int ret; + + ret =3D timer_of_init(node, &_to); + if (ret) + return ret; + + systimer_base =3D timer_of_base(&_to); + clockevents_config_and_register(&_to.clkevt, SYSTIMER_RATE, + SYSTIMER_MIN_DELTA, SYSTIMER_MAX_DELTA); + + return 0; +} + +TIMER_OF_DECLARE(rtk_systimer, "realtek,rtd1625-systimer", rtk_systimer_in= it); --=20 2.34.1