* [PATCH 0/6] Add support for Qualcomm TSCSS hardware
@ 2026-07-27 14:10 Imran Shaik
2026-07-27 14:10 ` [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs Imran Shaik
` (5 more replies)
0 siblings, 6 replies; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
This series introduces support for the Qualcomm Timestamp Counter Subsystem
(TSCSS) hardware, a time synchronization subsystem present on Qualcomm
Lemans, Monaco and QDU1000 SoCs.
TSCSS is composed of two main hardware blocks:
- Timestamp Counter (TSC): a free-running hardware counter that provides
continuous timekeeping for the SoC, and is functional with a GCC TSC AHB
config clock and a global counter clock. The TSC counter resolution and
supported functionalities vary across SoC variants.
- Event Timestamp Unit (ETU): an optional block that captures TSC counter
timestamps against external hardware events. Each ETU slice binds a
slice identifier to an external event selector, and the ETU additionally
requires its own clock, pinctrl along with either a per-slice interrupt
(QDU1000) or a single summary interrupt across all ETU slices (Lemans
and Monaco).
+------------------------------------------------+ +------------------+
| Global clock controller - TSC AHB/CNTR/ETU CLK | | EVENT_IN[0:15] |
+------------------------------------------------+ +------------------+
| |
v v
+----------------------------------------------------------------------+
| Timestamp Counter Subsystem (TSCSS) |
| |
| +----------------------------------------------+ |
| +------------+ | Event Timestamp Unit (ETU) | |
| | Timestamp | | 0x01C90000-0x01C9FFFF | |
| | Counter | | +------------------------------------------+ | |
| | (TSC) | | | ETU Slices | | |
| | | | | [Slice 0] [Slice 1] [...] [Slice 15] | | |
| | 0x1C80000 | | | 0x1C90000 0x1C91000 0x1C9F000 | | |
| +------------+ | | | | |
| | +-----------+------------------------------+ | |
| +-------------|--------------------+-----------+ |
| | | |
+---------------------------------|--------------------|---------------+
| |
v v
+----------------------------------------+
| per-slice IRQ (OR) summary IRQ |
| (QDU1000) (Lemans) |
+----------------------------------------+
|
v
+-----------------------------+
| Interrupt Controller |
+-----------------------------+
The address offsets shown in the diagram above are specific to Qualcomm
Lemans SoC.
This series currently covers only the TSC block driver functionality; ETU
driver support will follow in a later series.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
Imran Shaik (6):
dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs
dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
arm64: defconfig: Enable Qualcomm TSC driver
arm64: dts: qcom: lemans: Add support for TSCSS node
arm64: dts: qcom: qdu1000: Add support for TSCSS node
.../devicetree/bindings/ptp/qcom,lemans-tscss.yaml | 198 ++++++++++
.../bindings/ptp/qcom,qdu1000-tscss.yaml | 187 ++++++++++
arch/arm64/boot/dts/qcom/lemans.dtsi | 11 +
arch/arm64/boot/dts/qcom/qdu1000.dtsi | 11 +
arch/arm64/configs/defconfig | 1 +
drivers/ptp/Kconfig | 10 +
drivers/ptp/Makefile | 1 +
drivers/ptp/ptp_qcom_tsc.c | 413 +++++++++++++++++++++
8 files changed, 832 insertions(+)
---
base-commit: c5e32e86ca02b003f86e095d379b38148999293d
change-id: 20260705-tscss-441d844c1ee7
Best regards,
--
Imran Shaik <imran.shaik@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
@ 2026-07-27 14:10 ` Imran Shaik
2026-07-27 15:50 ` Krzysztof Kozlowski
2026-07-27 14:10 ` [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
` (4 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Add Devicetree bindings for the Timestamp Counter Subsystem (TSCSS) found
on Qualcomm Lemans and Monaco SoCs.
TSCSS is a time synchronization subsystem composed of two main blocks:
Timestamp Counter (TSC) and Event Timestamp Unit (ETU). The TSC block
provides a continuously running counter used for timekeeping, while the
ETU captures timestamps for external hardware event triggers.
Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
.../devicetree/bindings/ptp/qcom,lemans-tscss.yaml | 198 +++++++++++++++++++++
1 file changed, 198 insertions(+)
diff --git a/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4cbe4b00ff7dcacbd8cc111e2b4b61ebce7104aa
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ptp/qcom,lemans-tscss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Timestamp Counter Subsystem (TSCSS) on Qualcomm Lemans and Monaco SoCs
+
+maintainers:
+ - Imran Shaik <imran.shaik@oss.qualcomm.com>
+ - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+ Qualcomm TSCSS is a time synchronization subsystem composed of two main
+ blocks - the Time Stamp Counter (TSC) and the Event Timestamp Unit (ETU).
+
+ The TSC block is a timestamp generator that maintains a running counter used
+ for system timekeeping, and is functional with just the AHB and counter
+ clocks.
+ The ETU block is optional and captures TSC timestamps for external
+ hardware events, each ETU slice binding a slice identifier to an external
+ event selector. Support for the ETU block requires the additional ETU
+ clock along with the summary interrupt and slice subnodes.
+
+properties:
+ compatible:
+ oneOf:
+ - const: qcom,lemans-tscss
+ - items:
+ - const: qcom,monaco-tscss
+ - const: qcom,lemans-tscss
+
+ reg:
+ maxItems: 1
+
+ reg-names:
+ items:
+ - const: tsc
+
+ clocks:
+ minItems: 2
+ items:
+ - description: TSC AHB configuration clock.
+ - description: TSC global counter clock.
+ - description: TSC ETU clock.
+
+ clock-names:
+ minItems: 2
+ items:
+ - const: ahb
+ - const: cntr
+ - const: etu
+
+ interrupts:
+ description: Summary interrupt raised based on external event for any of the ETU slices.
+ maxItems: 1
+
+ interrupt-names:
+ items:
+ - const: etu_summary
+
+ assigned-clocks: true
+ assigned-clock-rates: true
+
+ "#address-cells":
+ const: 2
+
+ "#size-cells":
+ const: 2
+
+ ranges: true
+
+patternProperties:
+ "^etu-slice@[0-9a-f]+$":
+ type: object
+ description: ETU slice configuration
+ properties:
+ reg:
+ maxItems: 1
+
+ pinctrl-0: true
+
+ pinctrl-names:
+ items:
+ - const: default
+
+ qcom,etu-event-sel:
+ description: Event selection value for this slice.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ qcom,etu-slice:
+ description: ETU slice identifier.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ required:
+ - reg
+ - qcom,etu-event-sel
+ - qcom,etu-slice
+ - pinctrl-0
+ - pinctrl-names
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+
+allOf:
+ - if:
+ properties:
+ clock-names:
+ contains:
+ const: etu
+ then:
+ properties:
+ clocks:
+ minItems: 3
+ clock-names:
+ minItems: 3
+ required:
+ - interrupts
+ - interrupt-names
+ - "#address-cells"
+ - "#size-cells"
+ - ranges
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tscss@1c80000 {
+ compatible = "qcom,lemans-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+
+ clocks = <&gcc GCC_TSCSS_AHB_CLK>,
+ <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
+ clock-names = "ahb", "cntr";
+
+ assigned-clocks = <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
+ assigned-clock-rates = <15625000>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tscss@1c80000 {
+ compatible = "qcom,lemans-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_TSCSS_AHB_CLK>,
+ <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>,
+ <&gcc GCC_TSCSS_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+
+ assigned-clocks = <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>,
+ <&gcc GCC_TSCSS_ETU_CLK>;
+ assigned-clock-rates = <15625000>, <15625000>;
+
+ interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "etu_summary";
+
+ etu-slice@1c91000 {
+ reg = <0x0 0x01c91000 0x0 0x1000>;
+ pinctrl-0 = <&cci_timer0>;
+ pinctrl-names = "default";
+ qcom,etu-event-sel = <1>;
+ qcom,etu-slice = <1>;
+ };
+
+ etu-slice@1c92000 {
+ reg = <0x0 0x01c92000 0x0 0x1000>;
+ pinctrl-0 = <&cci_timer1>;
+ pinctrl-names = "default";
+ qcom,etu-event-sel = <2>;
+ qcom,etu-slice = <2>;
+ };
+ };
+ };
+...
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
2026-07-27 14:10 ` [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs Imran Shaik
@ 2026-07-27 14:10 ` Imran Shaik
2026-07-27 15:51 ` Krzysztof Kozlowski
2026-07-28 14:12 ` sashiko-bot
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
` (3 subsequent siblings)
5 siblings, 2 replies; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Add Devicetree bindings for the Timestamp Counter Subsystem (TSCSS) found
on Qualcomm QDU1000 SoC.
TSCSS is a time synchronization subsystem composed of two main blocks:
Timestamp Counter (TSC) and Event Timestamp Unit (ETU). The TSC block
provides a continuously running counter used for timekeeping, while the
ETU captures timestamps for external hardware event triggers.
Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
.../bindings/ptp/qcom,qdu1000-tscss.yaml | 187 +++++++++++++++++++++
1 file changed, 187 insertions(+)
diff --git a/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..39387614ef8939b7840df2f0d5640b9e142fb4e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ptp/qcom,qdu1000-tscss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Timestamp Counter Subsystem (TSCSS) on Qualcomm QDU1000 SoC
+
+maintainers:
+ - Imran Shaik <imran.shaik@oss.qualcomm.com>
+ - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+ Qualcomm TSCSS is a time synchronization subsystem composed of two main
+ blocks - the Time Stamp Counter (TSC) and the Event Timestamp Unit (ETU).
+
+ The TSC block is a timestamp generator that maintains a running counter used
+ for system timekeeping, and is functional with just the AHB and counter
+ clocks.
+ The ETU block is optional and captures TSC timestamps for external
+ hardware events, each ETU slice binding a slice identifier to an external
+ event selector. Support for the ETU block requires the additional ETU
+ clock along with the per slice interrupt and slice subnodes.
+
+properties:
+ compatible:
+ const: qcom,qdu1000-tscss
+
+ reg:
+ maxItems: 1
+
+ reg-names:
+ items:
+ - const: tsc
+
+ clocks:
+ minItems: 2
+ items:
+ - description: TSC AHB configuration clock.
+ - description: TSC global counter clock.
+ - description: TSC ETU clock.
+
+ clock-names:
+ minItems: 2
+ items:
+ - const: ahb
+ - const: cntr
+ - const: etu
+
+ assigned-clocks: true
+ assigned-clock-rates: true
+
+ "#address-cells":
+ const: 2
+
+ "#size-cells":
+ const: 2
+
+ ranges: true
+
+patternProperties:
+ "^etu-slice@[0-9a-f]+$":
+ type: object
+ description: ETU slice configuration
+ properties:
+ reg:
+ maxItems: 1
+
+ pinctrl-0: true
+
+ pinctrl-names:
+ items:
+ - const: default
+
+ interrupts:
+ description: Per slice interrupt generated by ETU based on external event trigger.
+ maxItems: 1
+
+ qcom,etu-event-sel:
+ description: Event selection value for this slice.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ qcom,etu-slice:
+ description: ETU slice identifier.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+ required:
+ - reg
+ - interrupts
+ - qcom,etu-event-sel
+ - qcom,etu-slice
+ - pinctrl-0
+ - pinctrl-names
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+
+allOf:
+ - if:
+ properties:
+ clock-names:
+ contains:
+ const: etu
+ then:
+ properties:
+ clocks:
+ minItems: 3
+ clock-names:
+ minItems: 3
+ required:
+ - "#address-cells"
+ - "#size-cells"
+ - ranges
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,qdu1000-gcc.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tscss@1da0000 {
+ compatible = "qcom,qdu1000-tscss";
+ reg = <0x0 0x01da0000 0x0 0x2000>;
+ reg-names = "tsc";
+
+ clocks = <&gcc GCC_TSC_CFG_AHB_CLK>,
+ <&gcc GCC_TSC_CNTR_CLK>;
+ clock-names = "ahb", "cntr";
+ assigned-clocks = <&gcc GCC_TSC_CNTR_CLK>;
+ assigned-clock-rates = <500000000>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/clock/qcom,qdu1000-gcc.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tscss@1da0000 {
+ compatible = "qcom,qdu1000-tscss";
+ reg = <0x0 0x01da0000 0x0 0x2000>;
+ reg-names = "tsc";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ clocks = <&gcc GCC_TSC_CFG_AHB_CLK>,
+ <&gcc GCC_TSC_CNTR_CLK>,
+ <&gcc GCC_TSC_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+
+ assigned-clocks = <&gcc GCC_TSC_CNTR_CLK>,
+ <&gcc GCC_TSC_ETU_CLK>;
+ assigned-clock-rates = <500000000>, <500000000>;
+
+ etu-slice@1db1000 {
+ reg = <0x0 0x01db1000 0x0 0x1000>;
+ interrupts = <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&cci_timer0>;
+ pinctrl-names = "default";
+ qcom,etu-event-sel = <1>;
+ qcom,etu-slice = <1>;
+ };
+
+ etu-slice@1db2000 {
+ reg = <0x0 0x01db2000 0x0 0x1000>;
+ interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>;
+ pinctrl-0 = <&cci_timer1>;
+ pinctrl-names = "default";
+ qcom,etu-event-sel = <2>;
+ qcom,etu-slice = <2>;
+ };
+ };
+ };
+...
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
2026-07-27 14:10 ` [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs Imran Shaik
2026-07-27 14:10 ` [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
@ 2026-07-27 14:10 ` Imran Shaik
2026-07-27 15:53 ` Krzysztof Kozlowski
` (2 more replies)
2026-07-27 14:11 ` [PATCH 4/6] arm64: defconfig: Enable Qualcomm TSC driver Imran Shaik
` (2 subsequent siblings)
5 siblings, 3 replies; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:10 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Add a PTP Hardware Clock driver for the Qualcomm Timestamp Counter (TSC)
hardware found on Qualcomm Lemans and QDU1000 SoCs. The TSC is a free
running hardware counter used for time synchronization, clocked by an AHB
configuration clock and a global counter clock, with the counter resolution
varying across SoCs.
Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
drivers/ptp/Kconfig | 10 ++
drivers/ptp/Makefile | 1 +
drivers/ptp/ptp_qcom_tsc.c | 413 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 424 insertions(+)
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index b93640ca08b7286fd4298519a17d1daf19056498..d3ceb1ee01a505cdd0bd056649d245308fc9f140 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -263,4 +263,14 @@ config PTP_NETC_V4_TIMER
synchronization. It also supports periodic output signal (e.g. PPS)
and external trigger timestamping.
+config PTP_QCOM_TSC
+ tristate "Qualcomm TSC as PTP clock"
+ depends on COMMON_CLK && PTP_1588_CLOCK
+ help
+ This driver adds support for using the Qualcomm Timestamp Counter
+ Subsystem (TSCSS) as a PTP clock.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ptp_qcom_tsc.
+
endmenu
diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile
index bdc47e284f14e7e77460ccf4ea30ab20c6df4fe4..ff029323e98f5e7ced55b5000e8555929a6e8e54 100644
--- a/drivers/ptp/Makefile
+++ b/drivers/ptp/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_PTP_1588_CLOCK_OCP) += ptp_ocp.o
obj-$(CONFIG_PTP_DFL_TOD) += ptp_dfl_tod.o
obj-$(CONFIG_PTP_S390) += ptp_s390.o
obj-$(CONFIG_PTP_NETC_V4_TIMER) += ptp_netc.o
+obj-$(CONFIG_PTP_QCOM_TSC) += ptp_qcom_tsc.o
diff --git a/drivers/ptp/ptp_qcom_tsc.c b/drivers/ptp/ptp_qcom_tsc.c
new file mode 100644
index 0000000000000000000000000000000000000000..b29248150388f32f2c2d211f69c11599dc743d78
--- /dev/null
+++ b/drivers/ptp/ptp_qcom_tsc.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/platform_device.h>
+
+#define ROLLOVER_VAL 999999999
+#define NSEC_SHIFT 32
+#define PULSE_WIDTH_MASK GENMASK(7, 6)
+#define DRIFT_MAX_RES 0x1FFFF
+#define DRIFT_JUMP_SWALLOW BIT(31)
+#define DRIFT_PERIOD_MASK GENMASK(28, 12)
+#define DRIFT_SUBPERIOD_MASK GENMASK(11, 0)
+#define DRIFT_INTERVAL_US 10
+#define DRIFT_MIN_TIMEOUT_US 5000
+
+#define DRIFT_TIMEOUT_US(period, subperiod, cntr_res) \
+ max_t(u64, div_u64((u64)(period) * (subperiod) * (cntr_res), NSEC_PER_USEC), \
+ DRIFT_MIN_TIMEOUT_US)
+
+struct qcom_tsc_regs {
+ u32 control_cntcr;
+ u32 control_cntcv_lo;
+ u32 control_cntcv_hi;
+ u32 drift_correct_incr_val;
+ u32 drift_correct_duration;
+ u32 drift_correct_cmd;
+ u32 rollover_val;
+ u32 offset_lo;
+ u32 offset_hi;
+ u32 read_cntcv_lo;
+ u32 read_cntcv_hi;
+};
+
+/**
+ * struct qcom_tsc_soc_data - SoC specific TSC hardware capabilities
+ *
+ * @rollover: indicates the counter uses sec/nsec split
+ * @offset_correction: hardware supports one-shot offset correction
+ * @pulse_width: valid pulse width in cycles for drift correction
+ * @cntr_res: TSC counter resolution in nsec
+ * @reg_layout: register layout for this SoC/version
+ */
+struct qcom_tsc_soc_data {
+ bool rollover;
+ bool offset_correction;
+ int pulse_width;
+ int cntr_res;
+ const struct qcom_tsc_regs *reg_layout;
+};
+
+struct qcom_tsc {
+ struct device *dev;
+ void __iomem *base;
+ const struct qcom_tsc_soc_data *soc;
+ struct clk *ahb_clk;
+ struct clk *cntr_clk;
+ struct clk *etu_clk;
+ struct ptp_clock *ptp;
+ struct ptp_clock_info ptp_info;
+ /* Mutex to protect operations from being interrupted */
+ struct mutex lock;
+};
+
+static bool qcom_tsc_is_enabled(struct qcom_tsc *tsc)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+
+ return readl_relaxed(tsc->base + regs->control_cntcr) & BIT(0);
+}
+
+static int qcom_tsc_read_time(struct qcom_tsc *tsc, struct timespec64 *ts)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+ u32 hi, lo;
+
+ if (!qcom_tsc_is_enabled(tsc))
+ return -EINVAL;
+
+ hi = readl_relaxed(tsc->base + regs->read_cntcv_hi);
+ lo = readl_relaxed(tsc->base + regs->read_cntcv_lo);
+
+ if (tsc->soc->rollover) {
+ ts->tv_sec = hi;
+ ts->tv_nsec = lo;
+ } else {
+ u64 ns = ((u64)hi << NSEC_SHIFT) | lo;
+
+ *ts = ns_to_timespec64(ns);
+ }
+
+ return 0;
+}
+
+static int qcom_tsc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
+{
+ struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
+ int ret;
+
+ mutex_lock(&tsc->lock);
+ ret = qcom_tsc_read_time(tsc, ts);
+ mutex_unlock(&tsc->lock);
+
+ return ret;
+}
+
+static inline void qcom_tsc_split_ts(struct qcom_tsc *tsc, struct timespec64 ts, u32 *hi, u32 *lo)
+{
+ if (tsc->soc->rollover) {
+ *hi = ts.tv_sec;
+ *lo = ts.tv_nsec;
+ } else {
+ u64 ns = timespec64_to_ns(&ts);
+
+ *lo = lower_32_bits(ns);
+ *hi = upper_32_bits(ns);
+ }
+}
+
+static int qcom_tsc_update_counter(struct qcom_tsc *tsc, struct timespec64 ts)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+ u32 regval, hi, lo;
+
+ qcom_tsc_split_ts(tsc, ts, &hi, &lo);
+
+ writel_relaxed(lo, tsc->base + regs->control_cntcv_lo);
+ writel_relaxed(hi, tsc->base + regs->control_cntcv_hi);
+
+ regval = readl_relaxed(tsc->base + regs->control_cntcr);
+ regval |= BIT(0);
+ writel_relaxed(regval, tsc->base + regs->control_cntcr);
+
+ return 0;
+}
+
+static int qcom_tsc_update_offset(struct qcom_tsc *tsc, const struct timespec64 ts)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+ struct timespec64 tod;
+ u32 regval, hi, lo;
+ int ret;
+
+ if (tsc->soc->offset_correction) {
+ qcom_tsc_split_ts(tsc, ts, &hi, &lo);
+
+ writel_relaxed(lo, tsc->base + regs->offset_lo);
+ writel_relaxed(hi, tsc->base + regs->offset_hi);
+
+ return 0;
+ }
+
+ /*
+ * No hardware offset correction support: disable and reload the
+ * counter with the corrected time, as recommended by the hardware
+ * design team.
+ */
+ ret = qcom_tsc_read_time(tsc, &tod);
+ if (ret)
+ return ret;
+
+ regval = readl_relaxed(tsc->base + regs->control_cntcr);
+ regval &= ~BIT(0);
+ writel_relaxed(regval, tsc->base + regs->control_cntcr);
+
+ return qcom_tsc_update_counter(tsc, timespec64_add(tod, ts));
+}
+
+static int qcom_tsc_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
+{
+ struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+ struct timespec64 tod;
+ u32 regval;
+ int ret;
+
+ mutex_lock(&tsc->lock);
+
+ if (qcom_tsc_is_enabled(tsc)) {
+ qcom_tsc_read_time(tsc, &tod);
+ ret = qcom_tsc_update_offset(tsc, timespec64_sub(*ts, tod));
+ mutex_unlock(&tsc->lock);
+ return ret;
+ }
+
+ /* Configure and enable the TSC counter */
+ regval = readl_relaxed(tsc->base + regs->control_cntcr);
+ regval |= FIELD_PREP(PULSE_WIDTH_MASK, tsc->soc->pulse_width);
+ writel_relaxed(regval, tsc->base + regs->control_cntcr);
+
+ if (tsc->soc->rollover)
+ writel_relaxed(ROLLOVER_VAL, tsc->base + regs->rollover_val);
+
+ ret = qcom_tsc_update_counter(tsc, *ts);
+ mutex_unlock(&tsc->lock);
+
+ return ret;
+}
+
+static int qcom_tsc_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+ struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
+ int ret;
+
+ mutex_lock(&tsc->lock);
+ ret = qcom_tsc_update_offset(tsc, ns_to_timespec64(delta));
+ mutex_unlock(&tsc->lock);
+
+ return ret;
+}
+
+static int qcom_tsc_drift_correction(struct qcom_tsc *tsc, long scaled_ppm)
+{
+ const struct qcom_tsc_soc_data *soc = tsc->soc;
+ const struct qcom_tsc_regs *regs = soc->reg_layout;
+ long ppb = scaled_ppm_to_ppb(scaled_ppm);
+ u64 period, incval = 0;
+ u32 regval = 0, subperiod;
+
+ if (ppb < 0) {
+ ppb = -ppb;
+ regval &= ~DRIFT_JUMP_SWALLOW;
+
+ period = div_u64(ppb, soc->cntr_res);
+ if (period >= DRIFT_MAX_RES)
+ period = DRIFT_MAX_RES;
+ } else {
+ regval |= DRIFT_JUMP_SWALLOW;
+
+ period = div_u64(ppb, soc->cntr_res);
+ if (period >= DRIFT_MAX_RES) {
+ period = DRIFT_MAX_RES;
+ incval = soc->cntr_res * 2;
+ } else if (ppb < soc->cntr_res) {
+ incval = soc->cntr_res + ppb;
+ period = 1;
+ } else {
+ incval = soc->cntr_res * 2;
+ }
+ }
+
+ subperiod = soc->pulse_width * 2;
+ regval |= FIELD_PREP(DRIFT_SUBPERIOD_MASK, subperiod);
+ regval |= FIELD_PREP(DRIFT_PERIOD_MASK, period);
+
+ /* Update jump/swallow, period, subperiod */
+ writel_relaxed(regval, tsc->base + regs->drift_correct_duration);
+
+ writel_relaxed(incval, tsc->base + regs->drift_correct_incr_val);
+
+ /* Trigger the drift correction */
+ regval = readl_relaxed(tsc->base + regs->drift_correct_cmd);
+ regval |= BIT(0);
+ writel_relaxed(regval, tsc->base + regs->drift_correct_cmd);
+
+ return readl_poll_timeout(tsc->base + regs->drift_correct_cmd, regval,
+ !(regval & BIT(1)), DRIFT_INTERVAL_US,
+ DRIFT_TIMEOUT_US(period, subperiod, soc->cntr_res));
+}
+
+static int qcom_tsc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+{
+ struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
+ int ret;
+
+ if (scaled_ppm == 0)
+ return 0;
+
+ mutex_lock(&tsc->lock);
+ ret = qcom_tsc_drift_correction(tsc, scaled_ppm);
+ mutex_unlock(&tsc->lock);
+
+ return ret;
+}
+
+static struct ptp_clock_info qcom_ptp_info = {
+ .owner = THIS_MODULE,
+ .name = "PTP_QCOM_TSC",
+ .max_adj = 9999999,
+ .adjfine = qcom_tsc_adjfine,
+ .adjtime = qcom_tsc_adjtime,
+ .gettime64 = qcom_tsc_gettime,
+ .settime64 = qcom_tsc_settime,
+};
+
+static const struct qcom_tsc_regs qcom_tsc_layout = {
+ .control_cntcr = 0x0,
+ .control_cntcv_lo = 0x8,
+ .control_cntcv_hi = 0xc,
+ .drift_correct_incr_val = 0x2c,
+ .drift_correct_duration = 0x30,
+ .drift_correct_cmd = 0x34,
+ .rollover_val = 0x3c,
+ .offset_lo = 0x50,
+ .offset_hi = 0x54,
+ .read_cntcv_lo = 0x1000,
+ .read_cntcv_hi = 0x1004,
+};
+
+static const struct qcom_tsc_soc_data qcom_tsc_lemans = {
+ .reg_layout = &qcom_tsc_layout,
+ .rollover = false,
+ .offset_correction = false,
+ .pulse_width = 2,
+ .cntr_res = 64,
+};
+
+static const struct qcom_tsc_soc_data qcom_tsc_qdu1000 = {
+ .reg_layout = &qcom_tsc_layout,
+ .rollover = true,
+ .offset_correction = true,
+ .pulse_width = 3,
+ .cntr_res = 2,
+};
+
+static const struct of_device_id qcom_tsc_of_match[] = {
+ { .compatible = "qcom,lemans-tscss", .data = &qcom_tsc_lemans },
+ { .compatible = "qcom,qdu1000-tscss", .data = &qcom_tsc_qdu1000 },
+ { }
+};
+MODULE_DEVICE_TABLE(of, qcom_tsc_of_match);
+
+static void qcom_ptp_tsc_remove(struct platform_device *pdev)
+{
+ struct qcom_tsc *tsc = platform_get_drvdata(pdev);
+
+ if (tsc && tsc->ptp) {
+ ptp_clock_unregister(tsc->ptp);
+ tsc->ptp = NULL;
+ }
+}
+
+static int qcom_ptp_tsc_probe(struct platform_device *pdev)
+{
+ const struct qcom_tsc_soc_data *soc;
+ struct qcom_tsc *tsc;
+ struct resource *r_mem;
+ int ret;
+
+ soc = of_device_get_match_data(&pdev->dev);
+ if (!soc)
+ return -ENODEV;
+
+ tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL);
+ if (!tsc)
+ return -ENOMEM;
+
+ tsc->dev = &pdev->dev;
+ tsc->soc = soc;
+
+ ret = devm_mutex_init(&pdev->dev, &tsc->lock);
+ if (ret)
+ return ret;
+
+ r_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tsc");
+ if (!r_mem) {
+ dev_err(&pdev->dev, "no IO resource defined\n");
+ return -ENXIO;
+ }
+
+ tsc->base = devm_ioremap_resource(&pdev->dev, r_mem);
+ if (IS_ERR(tsc->base))
+ return PTR_ERR(tsc->base);
+
+ tsc->ahb_clk = devm_clk_get_enabled(&pdev->dev, "ahb");
+ if (IS_ERR(tsc->ahb_clk))
+ return PTR_ERR(tsc->ahb_clk);
+
+ tsc->cntr_clk = devm_clk_get_enabled(&pdev->dev, "cntr");
+ if (IS_ERR(tsc->cntr_clk))
+ return PTR_ERR(tsc->cntr_clk);
+
+ /* ETU clock is optional, only required when the ETU block is used */
+ tsc->etu_clk = devm_clk_get_optional_enabled(&pdev->dev, "etu");
+ if (IS_ERR(tsc->etu_clk))
+ return PTR_ERR(tsc->etu_clk);
+
+ tsc->ptp_info = qcom_ptp_info;
+
+ tsc->ptp = ptp_clock_register(&tsc->ptp_info, &pdev->dev);
+ if (IS_ERR(tsc->ptp)) {
+ ret = PTR_ERR(tsc->ptp);
+ dev_err(&pdev->dev, "Failed to register ptp clock\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, tsc);
+
+ return 0;
+}
+
+static struct platform_driver qcom_ptp_tsc_driver = {
+ .probe = qcom_ptp_tsc_probe,
+ .remove = qcom_ptp_tsc_remove,
+ .driver = {
+ .name = "qcom_ptp_tsc",
+ .of_match_table = qcom_tsc_of_match,
+ },
+};
+module_platform_driver(qcom_ptp_tsc_driver);
+
+MODULE_DESCRIPTION("PTP QCOM TSC driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 4/6] arm64: defconfig: Enable Qualcomm TSC driver
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
` (2 preceding siblings ...)
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
@ 2026-07-27 14:11 ` Imran Shaik
2026-07-27 14:11 ` [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
2026-07-27 14:11 ` [PATCH 6/6] arm64: dts: qcom: qdu1000: " Imran Shaik
5 siblings, 0 replies; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:11 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Enable PTP_QCOM_TSC as a module to support the Timestamp Counter (TSC)
synchronization functionality on Qualcomm Lemans, Monaco and QDU1000
platforms.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 6ec8d3a69c98e0da38465010d11166bb0e058f4a..73435e5f8877d2356ae1f2520c7c87a72d503a2b 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -683,6 +683,7 @@ CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
CONFIG_SPMI_APPLE=m
CONFIG_SPMI_MTK_PMIF=m
+CONFIG_PTP_QCOM_TSC=m
CONFIG_PINCTRL_APPLE_GPIO=m
CONFIG_PINCTRL_DA9062=m
CONFIG_PINCTRL_MAX77620=y
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
` (3 preceding siblings ...)
2026-07-27 14:11 ` [PATCH 4/6] arm64: defconfig: Enable Qualcomm TSC driver Imran Shaik
@ 2026-07-27 14:11 ` Imran Shaik
2026-07-27 14:44 ` Konrad Dybcio
2026-07-28 14:12 ` sashiko-bot
2026-07-27 14:11 ` [PATCH 6/6] arm64: dts: qcom: qdu1000: " Imran Shaik
5 siblings, 2 replies; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:11 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Add Timestamp Counter Subsystem (TSCSS) node support on Qualcomm Lemans
SoCs.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/lemans.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 3b0539e27b5192582e0bc9ea248f1c0382e05030..e225292a1e41a5a313aca188ca04bb12474995e8 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -3023,6 +3023,17 @@ pcie1_phy: phy@1c14000 {
status = "disabled";
};
+ tscss@1c80000 {
+ compatible = "qcom,lemans-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+ clocks = <&gcc GCC_TSCSS_AHB_CLK>,
+ <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
+ clock-names = "ahb", "cntr";
+ assigned-clocks = <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
+ assigned-clock-rates = <15625000>;
+ };
+
ufs_mem_hc: ufshc@1d84000 {
compatible = "qcom,sa8775p-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
reg = <0x0 0x01d84000 0x0 0x3000>;
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 6/6] arm64: dts: qcom: qdu1000: Add support for TSCSS node
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
` (4 preceding siblings ...)
2026-07-27 14:11 ` [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
@ 2026-07-27 14:11 ` Imran Shaik
2026-07-27 15:54 ` Krzysztof Kozlowski
5 siblings, 1 reply; 16+ messages in thread
From: Imran Shaik @ 2026-07-27 14:11 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev, Imran Shaik
Add Timestamp Counter Subsystem (TSCSS) node support on Qualcomm QDU1000
SoCs.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/qdu1000.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
index 26cc86d12f725682ebbbb9be22829bb7c6be7fd4..8979c18225184a318284131639f24c698e59f166 100644
--- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
@@ -876,6 +876,17 @@ system_noc: interconnect@1640000 {
#interconnect-cells = <2>;
};
+ tscss@1da0000 {
+ compatible = "qcom,qdu1000-tscss";
+ reg = <0x0 0x01da0000 0x0 0x2000>;
+ reg-names = "tsc";
+ clocks = <&gcc GCC_TSC_CFG_AHB_CLK>,
+ <&gcc GCC_TSC_CNTR_CLK>;
+ clock-names = "ahb", "cntr";
+ assigned-clocks = <&gcc GCC_TSC_CNTR_CLK>;
+ assigned-clock-rates = <500000000>;
+ };
+
tcsr_mutex: hwlock@1f40000 {
compatible = "qcom,tcsr-mutex";
reg = <0x0 0x1f40000 0x0 0x20000>;
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node
2026-07-27 14:11 ` [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
@ 2026-07-27 14:44 ` Konrad Dybcio
2026-07-28 14:12 ` sashiko-bot
1 sibling, 0 replies; 16+ messages in thread
From: Konrad Dybcio @ 2026-07-27 14:44 UTC (permalink / raw)
To: Imran Shaik, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev
On 7/27/26 4:11 PM, Imran Shaik wrote:
> Add Timestamp Counter Subsystem (TSCSS) node support on Qualcomm Lemans
> SoCs.
>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/lemans.dtsi | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
> index 3b0539e27b5192582e0bc9ea248f1c0382e05030..e225292a1e41a5a313aca188ca04bb12474995e8 100644
> --- a/arch/arm64/boot/dts/qcom/lemans.dtsi
> +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
> @@ -3023,6 +3023,17 @@ pcie1_phy: phy@1c14000 {
> status = "disabled";
> };
>
> + tscss@1c80000 {
> + compatible = "qcom,lemans-tscss";
> + reg = <0x0 0x01c80000 0x0 0x2000>;
> + reg-names = "tsc";
> + clocks = <&gcc GCC_TSCSS_AHB_CLK>,
> + <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
> + clock-names = "ahb", "cntr";
> + assigned-clocks = <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
> + assigned-clock-rates = <15625000>;
I'm guessing this will only ever require a single rate - do we
need power-domains pointing to one of the RPMHPDs and a
required-opps reference to match?
Konrad
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs
2026-07-27 14:10 ` [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs Imran Shaik
@ 2026-07-27 15:50 ` Krzysztof Kozlowski
0 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-27 15:50 UTC (permalink / raw)
To: Imran Shaik, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev
On 27/07/2026 16:10, Imran Shaik wrote:
> Add Devicetree bindings for the Timestamp Counter Subsystem (TSCSS) found
> on Qualcomm Lemans and Monaco SoCs.
>
> TSCSS is a time synchronization subsystem composed of two main blocks:
> Timestamp Counter (TSC) and Event Timestamp Unit (ETU). The TSC block
> provides a continuously running counter used for timekeeping, while the
> ETU captures timestamps for external hardware event triggers.
>
> Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
> .../devicetree/bindings/ptp/qcom,lemans-tscss.yaml | 198 +++++++++++++++++++++
> 1 file changed, 198 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..4cbe4b00ff7dcacbd8cc111e2b4b61ebce7104aa
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ptp/qcom,lemans-tscss.yaml
> @@ -0,0 +1,198 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ptp/qcom,lemans-tscss.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Timestamp Counter Subsystem (TSCSS) on Qualcomm Lemans and Monaco SoCs
> +
> +maintainers:
> + - Imran Shaik <imran.shaik@oss.qualcomm.com>
> + - Taniya Das <taniya.das@oss.qualcomm.com>
> +
> +description: |
> + Qualcomm TSCSS is a time synchronization subsystem composed of two main
> + blocks - the Time Stamp Counter (TSC) and the Event Timestamp Unit (ETU).
> +
> + The TSC block is a timestamp generator that maintains a running counter used
> + for system timekeeping, and is functional with just the AHB and counter
> + clocks.
> + The ETU block is optional and captures TSC timestamps for external
> + hardware events, each ETU slice binding a slice identifier to an external
> + event selector. Support for the ETU block requires the additional ETU
> + clock along with the summary interrupt and slice subnodes.
> +
> +properties:
> + compatible:
> + oneOf:
> + - const: qcom,lemans-tscss
There is no such SoC upstream.
> + - items:
> + - const: qcom,monaco-tscss
Neither this one.
> + - const: qcom,lemans-tscss
> +
> + reg:
> + maxItems: 1
> +
> + reg-names:
> + items:
> + - const: tsc
Drop names, not really useful.
> +
> + clocks:
> + minItems: 2
> + items:
> + - description: TSC AHB configuration clock.
> + - description: TSC global counter clock.
> + - description: TSC ETU clock.
> +
> + clock-names:
> + minItems: 2
Why is this flexible?
> + items:
> + - const: ahb
> + - const: cntr
> + - const: etu
> +
> + interrupts:
> + description: Summary interrupt raised based on external event for any of the ETU slices.
Please follow Linux coding style.
> + maxItems: 1
> +
> + interrupt-names:
> + items:
> + - const: etu_summary
> +
> + assigned-clocks: true
> + assigned-clock-rates: true
Drop. From where did you take it?
> +
> + "#address-cells":
> + const: 2
> +
> + "#size-cells":
> + const: 2
> +
> + ranges: true
> +
> +patternProperties:
> + "^etu-slice@[0-9a-f]+$":
> + type: object
> + description: ETU slice configuration
> + properties:
> + reg:
> + maxItems: 1
> +
> + pinctrl-0: true
> +
> + pinctrl-names:
> + items:
> + - const: default
Heh? Which code do you copy?
> +
> + qcom,etu-event-sel:
> + description: Event selection value for this slice.
> + $ref: /schemas/types.yaml#/definitions/uint32
> +
> + qcom,etu-slice:
> + description: ETU slice identifier.
You do not get identifiers. Please read writing bindings.
> + $ref: /schemas/types.yaml#/definitions/uint32
> +
> + required:
> + - reg
> + - qcom,etu-event-sel
> + - qcom,etu-slice
> + - pinctrl-0
> + - pinctrl-names
> + unevaluatedProperties: false
Please read writing bindings.
> +
> +required:
> + - compatible
> + - reg
> + - reg-names
> + - clocks
> + - clock-names
> +
> +allOf:
> + - if:
> + properties:
> + clock-names:
> + contains:
> + const: etu
etu is third clock, what is the point of it?
> + then:
> + properties:
> + clocks:
> + minItems: 3
> + clock-names:
> + minItems: 3
> + required:
> + - interrupts
> + - interrupt-names
> + - "#address-cells"
> + - "#size-cells"
> + - ranges
> +
> +unevaluatedProperties: false
Please read writing bindings.
> +
> +examples:
> + - |
> + #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + tscss@1c80000 {
> + compatible = "qcom,lemans-tscss";
> + reg = <0x0 0x01c80000 0x0 0x2000>;
> + reg-names = "tsc";
> +
> + clocks = <&gcc GCC_TSCSS_AHB_CLK>,
> + <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
> + clock-names = "ahb", "cntr";
> +
> + assigned-clocks = <&gcc GCC_TSCSS_GLOBAL_CNTR_CLK>;
> + assigned-clock-rates = <15625000>;
> + };
> + };
> +
> + - |
> + #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> + soc {
> + #address-cells = <2>;
> + #size-cells = <2>;
> +
> + tscss@1c80000 {
This is the same node as previous.
I don't understand this DTS.
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
If you cannot find a name matching your device, please check in kernel
sources for similar cases or you can grow the spec (via pull request to
DT spec repo).
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
2026-07-27 14:10 ` [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
@ 2026-07-27 15:51 ` Krzysztof Kozlowski
2026-07-28 14:12 ` sashiko-bot
1 sibling, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-27 15:51 UTC (permalink / raw)
To: Imran Shaik, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev
On 27/07/2026 16:10, Imran Shaik wrote:
> Add Devicetree bindings for the Timestamp Counter Subsystem (TSCSS) found
> on Qualcomm QDU1000 SoC.
>
> TSCSS is a time synchronization subsystem composed of two main blocks:
> Timestamp Counter (TSC) and Event Timestamp Unit (ETU). The TSC block
> provides a continuously running counter used for timekeeping, while the
> ETU captures timestamps for external hardware event triggers.
>
> Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
> .../bindings/ptp/qcom,qdu1000-tscss.yaml | 187 +++++++++++++++++++++
> 1 file changed, 187 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
> new file mode 100644
> index 0000000000000000000000000000000000000000..39387614ef8939b7840df2f0d5640b9e142fb4e5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
> @@ -0,0 +1,187 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/ptp/qcom,qdu1000-tscss.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Timestamp Counter Subsystem (TSCSS) on Qualcomm QDU1000 SoC
> +
> +maintainers:
> + - Imran Shaik <imran.shaik@oss.qualcomm.com>
> + - Taniya Das <taniya.das@oss.qualcomm.com>
> +
> +description: |
> + Qualcomm TSCSS is a time synchronization subsystem composed of two main
> + blocks - the Time Stamp Counter (TSC) and the Event Timestamp Unit (ETU).
> +
> + The TSC block is a timestamp generator that maintains a running counter used
> + for system timekeeping, and is functional with just the AHB and counter
> + clocks.
> + The ETU block is optional and captures TSC timestamps for external
> + hardware events, each ETU slice binding a slice identifier to an external
> + event selector. Support for the ETU block requires the additional ETU
> + clock along with the per slice interrupt and slice subnodes.
> +
> +properties:
> + compatible:
> + const: qcom,qdu1000-tscss
Why do you create a new file with exactly the same binding?
Anyway, all comments apply.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
@ 2026-07-27 15:53 ` Krzysztof Kozlowski
2026-07-27 23:20 ` Jakub Kicinski
2026-07-28 14:12 ` sashiko-bot
2 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-27 15:53 UTC (permalink / raw)
To: Imran Shaik, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev
On 27/07/2026 16:10, Imran Shaik wrote:
> Add a PTP Hardware Clock driver for the Qualcomm Timestamp Counter (TSC)
> hardware found on Qualcomm Lemans and QDU1000 SoCs. The TSC is a free
> running hardware counter used for time synchronization, clocked by an AHB
> configuration clock and a global counter clock, with the counter resolution
> varying across SoCs.
>
> Co-developed-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Taniya Das <taniya.das@oss.qualcomm.com>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
> drivers/ptp/Kconfig | 10 ++
> drivers/ptp/Makefile | 1 +
> drivers/ptp/ptp_qcom_tsc.c | 413 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 424 insertions(+)
>
> diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
> index b93640ca08b7286fd4298519a17d1daf19056498..d3ceb1ee01a505cdd0bd056649d245308fc9f140 100644
> --- a/drivers/ptp/Kconfig
> +++ b/drivers/ptp/Kconfig
> @@ -263,4 +263,14 @@ config PTP_NETC_V4_TIMER
> synchronization. It also supports periodic output signal (e.g. PPS)
> and external trigger timestamping.
>
> +config PTP_QCOM_TSC
> + tristate "Qualcomm TSC as PTP clock"
Missing depensd on ARCH_QCOM
> + depends on COMMON_CLK && PTP_1588_CLOCK
> + help
> + This driver adds support for using the Qualcomm Timestamp Counter
> + Subsystem (TSCSS) as a PTP clock.
> +
> + To compile this driver as a module, choose M here: the module
> + will be called ptp_qcom_tsc.
> +
> endmenu
...
> +
> +static const struct of_device_id qcom_tsc_of_match[] = {
> + { .compatible = "qcom,lemans-tscss", .data = &qcom_tsc_lemans },
> + { .compatible = "qcom,qdu1000-tscss", .data = &qcom_tsc_qdu1000 },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, qcom_tsc_of_match);
> +
> +static void qcom_ptp_tsc_remove(struct platform_device *pdev)
Completely broken order of ID table, remove() and probe(). Remove ALWAYS
follows probe. Table is next to them. Please look at other drivers.
> +{
> + struct qcom_tsc *tsc = platform_get_drvdata(pdev);
> +
> + if (tsc && tsc->ptp) {
> + ptp_clock_unregister(tsc->ptp);
> + tsc->ptp = NULL;
> + }
> +}
> +
> +static int qcom_ptp_tsc_probe(struct platform_device *pdev)
> +{
> + const struct qcom_tsc_soc_data *soc;
> + struct qcom_tsc *tsc;
> + struct resource *r_mem;
> + int ret;
> +
> + soc = of_device_get_match_data(&pdev->dev);
> + if (!soc)
> + return -ENODEV;
> +
> + tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL);
> + if (!tsc)
> + return -ENOMEM;
> +
> + tsc->dev = &pdev->dev;
> + tsc->soc = soc;
> +
> + ret = devm_mutex_init(&pdev->dev, &tsc->lock);
> + if (ret)
> + return ret;
> +
> + r_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tsc");
> + if (!r_mem) {
> + dev_err(&pdev->dev, "no IO resource defined\n");
> + return -ENXIO;
> + }
> +
> + tsc->base = devm_ioremap_resource(&pdev->dev, r_mem);
> + if (IS_ERR(tsc->base))
> + return PTR_ERR(tsc->base);
> +
> + tsc->ahb_clk = devm_clk_get_enabled(&pdev->dev, "ahb");
> + if (IS_ERR(tsc->ahb_clk))
> + return PTR_ERR(tsc->ahb_clk);
> +
> + tsc->cntr_clk = devm_clk_get_enabled(&pdev->dev, "cntr");
> + if (IS_ERR(tsc->cntr_clk))
> + return PTR_ERR(tsc->cntr_clk);
> +
> + /* ETU clock is optional, only required when the ETU block is used */
> + tsc->etu_clk = devm_clk_get_optional_enabled(&pdev->dev, "etu");
> + if (IS_ERR(tsc->etu_clk))
> + return PTR_ERR(tsc->etu_clk);
> +
> + tsc->ptp_info = qcom_ptp_info;
> +
> + tsc->ptp = ptp_clock_register(&tsc->ptp_info, &pdev->dev);
> + if (IS_ERR(tsc->ptp)) {
> + ret = PTR_ERR(tsc->ptp);
> + dev_err(&pdev->dev, "Failed to register ptp clock\n");
> + return ret;
Why aren't you using dev_err_probe?
> + }
> +
> + platform_set_drvdata(pdev, tsc);
> +
> + return 0;
> +}
> +
> +static struct platform_driver qcom_ptp_tsc_driver = {
> + .probe = qcom_ptp_tsc_probe,
> + .remove = qcom_ptp_tsc_remove,
> + .driver = {
> + .name = "qcom_ptp_tsc",
> + .of_match_table = qcom_tsc_of_match,
> + },
> +};
> +module_platform_driver(qcom_ptp_tsc_driver);
> +
> +MODULE_DESCRIPTION("PTP QCOM TSC driver");
> +MODULE_LICENSE("GPL");
>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 6/6] arm64: dts: qcom: qdu1000: Add support for TSCSS node
2026-07-27 14:11 ` [PATCH 6/6] arm64: dts: qcom: qdu1000: " Imran Shaik
@ 2026-07-27 15:54 ` Krzysztof Kozlowski
0 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-07-27 15:54 UTC (permalink / raw)
To: Imran Shaik, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Bjorn Andersson, Konrad Dybcio
Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm,
devicetree, linux-kernel, netdev
On 27/07/2026 16:11, Imran Shaik wrote:
> Add Timestamp Counter Subsystem (TSCSS) node support on Qualcomm QDU1000
> SoCs.
>
> Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
> ---
> arch/arm64/boot/dts/qcom/qdu1000.dtsi | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
> index 26cc86d12f725682ebbbb9be22829bb7c6be7fd4..8979c18225184a318284131639f24c698e59f166 100644
> --- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi
> +++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
> @@ -876,6 +876,17 @@ system_noc: interconnect@1640000 {
> #interconnect-cells = <2>;
> };
>
> + tscss@1da0000 {
Node names should be generic. See also an explanation and list of
examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
If you cannot find a name matching your device, please check in kernel
sources for similar cases or you can grow the spec (via pull request to
DT spec repo).
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
2026-07-27 15:53 ` Krzysztof Kozlowski
@ 2026-07-27 23:20 ` Jakub Kicinski
2026-07-28 14:12 ` sashiko-bot
2 siblings, 0 replies; 16+ messages in thread
From: Jakub Kicinski @ 2026-07-27 23:20 UTC (permalink / raw)
To: Imran Shaik
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Ajit Pandey, Taniya Das,
Jagadeesh Kona, linux-arm-msm, devicetree, linux-kernel, netdev
On Mon, 27 Jul 2026 19:40:59 +0530 Imran Shaik wrote:
> +static inline void qcom_tsc_split_ts(struct qcom_tsc *tsc, struct timespec64 ts, u32 *hi, u32 *lo)
> +{
> + if (tsc->soc->rollover) {
> + *hi = ts.tv_sec;
> + *lo = ts.tv_nsec;
> + } else {
> + u64 ns = timespec64_to_ns(&ts);
> +
> + *lo = lower_32_bits(ns);
> + *hi = upper_32_bits(ns);
> + }
> +}
Are you sure the compiler doesn't inline this trivial function with 2
callers even without the inline keyword. Compilers seem to inline as
much as possible these days.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
2026-07-27 14:10 ` [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
2026-07-27 15:51 ` Krzysztof Kozlowski
@ 2026-07-28 14:12 ` sashiko-bot
1 sibling, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-07-28 14:12 UTC (permalink / raw)
To: Imran Shaik; +Cc: robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The DT binding schema fails to forbid ETU slice subnodes and related address properties when the ETU clock is missing.
--
--- Patch [2]: [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC ---
commit fa3eee253cb3594f0f82d586d18506452f967b6b
Author: Imran Shaik <imran.shaik@oss.qualcomm.com>
dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
This commit adds Devicetree bindings for the Timestamp Counter Subsystem
(TSCSS) found on the Qualcomm QDU1000 SoC. It defines the required properties
for the core TSC block as well as the optional Event Timestamp Unit (ETU)
block and its slice subnodes.
> diff --git a/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
> new file mode 100644
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
[ ... ]
> +allOf:
> + - if:
> + properties:
> + clock-names:
> + contains:
> + const: etu
> + then:
> + properties:
> + clocks:
> + minItems: 3
> + clock-names:
> + minItems: 3
> + required:
> + - "#address-cells"
> + - "#size-cells"
> + - ranges
[Severity: Low]
Does this conditional block need an 'else' clause to forbid the ETU slice
subnodes and related address properties when the ETU clock is missing?
The commit message notes that support for the ETU block requires the ETU
clock along with the slice subnodes. Without an 'else' block explicitly
setting '#address-cells', 'ranges', and 'patternProperties:
"^etu-slice@[0-9a-f]+$"' to false, a device tree could configure ETU
slices while omitting the required ETU clock and still incorrectly pass
schema validation.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727-tscss-v1-0-beed14e72510@oss.qualcomm.com?part=2
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
2026-07-27 15:53 ` Krzysztof Kozlowski
2026-07-27 23:20 ` Jakub Kicinski
@ 2026-07-28 14:12 ` sashiko-bot
2 siblings, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-07-28 14:12 UTC (permalink / raw)
To: Imran Shaik; +Cc: devicetree, robh, conor+dt
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] The `adjfine` implementation improperly applies a one-shot phase shift and fails to clear adjustments on zero, rather than configuring continuous frequency modification.
- [High] The hardware fallback path for `adjtime` physically stops the hardware counter, causing lost ticks and non-deterministic negative phase drift.
- [High] Sequential 32-bit reads of the 64-bit hardware counter lack a retry loop, exposing severe backwards time jumps during rollover.
- [High] The `adjfine` drift calculation silently drops small negative adjustments by computing a period of zero.
- [Medium] The `PULSE_WIDTH_MASK` configuration in `qcom_tsc_settime()` is corrupted by a missing bitwise clear before applying `FIELD_PREP`.
--
--- Patch [3]: [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware ---
commit df14ad1f19420dd656de996ed9674c4b2511975f
Author: Imran Shaik <imran.shaik@oss.qualcomm.com>
ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
Add a PTP Hardware Clock driver for the Qualcomm Timestamp Counter (TSC)
hardware found on Qualcomm Lemans and QDU1000 SoCs. The TSC is a free
running hardware counter used for time synchronization, clocked by an AHB
configuration clock and a global counter clock.
> diff --git a/drivers/ptp/ptp_qcom_tsc.c b/drivers/ptp/ptp_qcom_tsc.c
> new file mode 100644
> index 0000000000000..b29248150388f
> --- /dev/null
> +++ b/drivers/ptp/ptp_qcom_tsc.c
[ ... ]
> +static int qcom_tsc_read_time(struct qcom_tsc *tsc, struct timespec64 *ts)
> +{
> + const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
> + u32 hi, lo;
> +
> + if (!qcom_tsc_is_enabled(tsc))
> + return -EINVAL;
> +
> + hi = readl_relaxed(tsc->base + regs->read_cntcv_hi);
> + lo = readl_relaxed(tsc->base + regs->read_cntcv_lo);
[Severity: High]
Does this sequential read risk returning backward time jumps during rollover?
If the lower 32-bit register rolls over between reading the upper and
lower registers, could this return a stale upper half combined with a
wrapped lower half? Is a retry loop needed here to ensure consistency?
> +
> + if (tsc->soc->rollover) {
> + ts->tv_sec = hi;
> + ts->tv_nsec = lo;
> + } else {
> + u64 ns = ((u64)hi << NSEC_SHIFT) | lo;
> +
> + *ts = ns_to_timespec64(ns);
> + }
> +
> + return 0;
> +}
[ ... ]
> +static int qcom_tsc_update_offset(struct qcom_tsc *tsc, const struct timespec64 ts)
> +{
> + const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
> + struct timespec64 tod;
> + u32 regval, hi, lo;
> + int ret;
> +
> + if (tsc->soc->offset_correction) {
> + qcom_tsc_split_ts(tsc, ts, &hi, &lo);
> +
> + writel_relaxed(lo, tsc->base + regs->offset_lo);
> + writel_relaxed(hi, tsc->base + regs->offset_hi);
> +
> + return 0;
> + }
> +
> + /*
> + * No hardware offset correction support: disable and reload the
> + * counter with the corrected time, as recommended by the hardware
> + * design team.
> + */
> + ret = qcom_tsc_read_time(tsc, &tod);
> + if (ret)
> + return ret;
> +
> + regval = readl_relaxed(tsc->base + regs->control_cntcr);
> + regval &= ~BIT(0);
> + writel_relaxed(regval, tsc->base + regs->control_cntcr);
[Severity: High]
Does disabling the counter during the update permanently lose hardware ticks?
When the software update occurs on SoCs without hardware offset correction,
the time elapsed between reading the time and disabling the counter seems to
be permanently dropped. Could this introduce negative drift and jitter on
each call to adjtime?
> +
> + return qcom_tsc_update_counter(tsc, timespec64_add(tod, ts));
> +}
[ ... ]
> +static int qcom_tsc_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts)
> +{
> + struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
> + const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
> + struct timespec64 tod;
> + u32 regval;
> + int ret;
> +
> + mutex_lock(&tsc->lock);
> +
> + if (qcom_tsc_is_enabled(tsc)) {
> + qcom_tsc_read_time(tsc, &tod);
> + ret = qcom_tsc_update_offset(tsc, timespec64_sub(*ts, tod));
> + mutex_unlock(&tsc->lock);
> + return ret;
> + }
> +
> + /* Configure and enable the TSC counter */
> + regval = readl_relaxed(tsc->base + regs->control_cntcr);
> + regval |= FIELD_PREP(PULSE_WIDTH_MASK, tsc->soc->pulse_width);
> + writel_relaxed(regval, tsc->base + regs->control_cntcr);
[Severity: Medium]
Should the PULSE_WIDTH_MASK bits be cleared before applying the bitwise OR?
If there are previous bits set in this field, could the bitwise OR without
a preceding bitwise clear leave those bits set and corrupt the pulse width
configuration?
> +
> + if (tsc->soc->rollover)
> + writel_relaxed(ROLLOVER_VAL, tsc->base + regs->rollover_val);
> +
> + ret = qcom_tsc_update_counter(tsc, *ts);
> + mutex_unlock(&tsc->lock);
> +
> + return ret;
> +}
[ ... ]
> +static int qcom_tsc_drift_correction(struct qcom_tsc *tsc, long scaled_ppm)
> +{
> + const struct qcom_tsc_soc_data *soc = tsc->soc;
> + const struct qcom_tsc_regs *regs = soc->reg_layout;
> + long ppb = scaled_ppm_to_ppb(scaled_ppm);
> + u64 period, incval = 0;
> + u32 regval = 0, subperiod;
> +
> + if (ppb < 0) {
> + ppb = -ppb;
> + regval &= ~DRIFT_JUMP_SWALLOW;
> +
> + period = div_u64(ppb, soc->cntr_res);
> + if (period >= DRIFT_MAX_RES)
> + period = DRIFT_MAX_RES;
> + } else {
[Severity: High]
Does this calculation silently drop small negative adjustments?
When ppb is less than zero and its absolute value is smaller than
soc->cntr_res, div_u64 will evaluate to 0.
Since the negative branch lacks the fallback to period = 1 that the positive
branch has, does this result in a period of 0 being written to hardware for
fine-grained negative frequency adjustments?
> + regval |= DRIFT_JUMP_SWALLOW;
> +
> + period = div_u64(ppb, soc->cntr_res);
> + if (period >= DRIFT_MAX_RES) {
> + period = DRIFT_MAX_RES;
> + incval = soc->cntr_res * 2;
> + } else if (ppb < soc->cntr_res) {
> + incval = soc->cntr_res + ppb;
> + period = 1;
> + } else {
> + incval = soc->cntr_res * 2;
> + }
> + }
> +
> + subperiod = soc->pulse_width * 2;
> + regval |= FIELD_PREP(DRIFT_SUBPERIOD_MASK, subperiod);
> + regval |= FIELD_PREP(DRIFT_PERIOD_MASK, period);
> +
> + /* Update jump/swallow, period, subperiod */
> + writel_relaxed(regval, tsc->base + regs->drift_correct_duration);
> +
> + writel_relaxed(incval, tsc->base + regs->drift_correct_incr_val);
> +
> + /* Trigger the drift correction */
> + regval = readl_relaxed(tsc->base + regs->drift_correct_cmd);
> + regval |= BIT(0);
> + writel_relaxed(regval, tsc->base + regs->drift_correct_cmd);
> +
> + return readl_poll_timeout(tsc->base + regs->drift_correct_cmd, regval,
> + !(regval & BIT(1)), DRIFT_INTERVAL_US,
> + DRIFT_TIMEOUT_US(period, subperiod, soc->cntr_res));
> +}
[Severity: High]
Does this trigger a one-shot phase shift instead of continuous drift correction?
The ptp daemon expects adjfine to configure a continuous hardware clock rate
adjustment. Since this block triggers a correction and polls for completion,
does the hardware just return to its nominal rate afterwards?
Will the ptp synchronization servo fail to stabilize if the frequency is not
actually adjusted continuously?
> +
> +static int qcom_tsc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
> +{
> + struct qcom_tsc *tsc = container_of(ptp, struct qcom_tsc, ptp_info);
> + int ret;
> +
> + if (scaled_ppm == 0)
> + return 0;
[Severity: High]
Does an early exit on zero scaled_ppm leave the hardware at its previous rate?
When the ptp daemon attempts to clear adjustments by passing 0, returning
early prevents any hardware commands from halting ongoing adjustments. Should
this reset the hardware to its nominal frequency before returning?
> +
> + mutex_lock(&tsc->lock);
> + ret = qcom_tsc_drift_correction(tsc, scaled_ppm);
> + mutex_unlock(&tsc->lock);
> +
> + return ret;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727-tscss-v1-0-beed14e72510@oss.qualcomm.com?part=3
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node
2026-07-27 14:11 ` [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
2026-07-27 14:44 ` Konrad Dybcio
@ 2026-07-28 14:12 ` sashiko-bot
1 sibling, 0 replies; 16+ messages in thread
From: sashiko-bot @ 2026-07-28 14:12 UTC (permalink / raw)
To: Imran Shaik; +Cc: conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The Devicetree compatible string for the TSCSS node uses the internal SoC codename 'lemans' rather than the official part number 'sa8775p'.
--
--- Patch [5]: [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node ---
commit 534c460b6703617b947d74b06656ce6dd2f6d6c4
Author: Imran Shaik <imran.shaik@oss.qualcomm.com>
arm64: dts: qcom: lemans: Add support for TSCSS node
This commit adds Timestamp Counter Subsystem (TSCSS) node support on
Qualcomm Lemans SoCs.
> diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
> --- a/arch/arm64/boot/dts/qcom/lemans.dtsi
> +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
[ ... ]
> @@ -3023,6 +3023,17 @@ pcie1_phy: phy@1c14000 {
> status = "disabled";
> };
>
> + tscss@1c80000 {
> + compatible = "qcom,lemans-tscss";
[Severity: Low]
This isn't a bug, but would it be better to use the official commercial part
number "qcom,sa8775p-tscss" for this compatible string rather than the internal
SoC codename "lemans"?
Other IP blocks in this file appear to use the "qcom,sa8775p-*" pattern.
For example, the UFS host controller just below this node uses
"qcom,sa8775p-ufshc". Staying consistent with the part number helps maintain
the Devicetree ABI standards.
> + reg = <0x0 0x01c80000 0x0 0x2000>;
> + reg-names = "tsc";
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260727-tscss-v1-0-beed14e72510@oss.qualcomm.com?part=5
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-07-28 14:12 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-27 14:10 [PATCH 0/6] Add support for Qualcomm TSCSS hardware Imran Shaik
2026-07-27 14:10 ` [PATCH 1/6] dt-bindings: ptp: Document the TSCSS on Qualcomm Lemans and Monaco SoCs Imran Shaik
2026-07-27 15:50 ` Krzysztof Kozlowski
2026-07-27 14:10 ` [PATCH 2/6] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
2026-07-27 15:51 ` Krzysztof Kozlowski
2026-07-28 14:12 ` sashiko-bot
2026-07-27 14:10 ` [PATCH 3/6] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
2026-07-27 15:53 ` Krzysztof Kozlowski
2026-07-27 23:20 ` Jakub Kicinski
2026-07-28 14:12 ` sashiko-bot
2026-07-27 14:11 ` [PATCH 4/6] arm64: defconfig: Enable Qualcomm TSC driver Imran Shaik
2026-07-27 14:11 ` [PATCH 5/6] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
2026-07-27 14:44 ` Konrad Dybcio
2026-07-28 14:12 ` sashiko-bot
2026-07-27 14:11 ` [PATCH 6/6] arm64: dts: qcom: qdu1000: " Imran Shaik
2026-07-27 15:54 ` Krzysztof Kozlowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox