* [PATCH v2 01/10] dt-bindings: ptp: Document the TSCSS on Qualcomm SA8775P and QCS8300 SoCs
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 02/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 SA8775P and QCS8300 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>
---
.../bindings/ptp/qcom,sa8775p-tscss.yaml | 169 +++++++++++++++++++++
1 file changed, 169 insertions(+)
diff --git a/Documentation/devicetree/bindings/ptp/qcom,sa8775p-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,sa8775p-tscss.yaml
new file mode 100644
index 000000000000..b3e3a7cd7166
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/qcom,sa8775p-tscss.yaml
@@ -0,0 +1,169 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ptp/qcom,sa8775p-tscss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Timestamp Counter Subsystem (TSCSS) on Qualcomm SA8775P and QCS8300
+
+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 Timestamp 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 captures TSC timestamps for external hardware events. Each
+ ETU slice binds a slice number to an external event selector, and a
+ single summary interrupt is raised for any ETU slice event.
+
+properties:
+ compatible:
+ oneOf:
+ - const: qcom,sa8775p-tscss
+ - items:
+ - const: qcom,qcs8300-tscss
+ - const: qcom,sa8775p-tscss
+
+ reg:
+ minItems: 1
+ maxItems: 2
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: tsc
+ - const: etu
+
+ clocks:
+ items:
+ - description: TSC AHB configuration clock.
+ - description: TSC global counter clock.
+ - description: TSC ETU clock.
+
+ clock-names:
+ items:
+ - const: ahb
+ - const: cntr
+ - const: etu
+
+ interrupts:
+ items:
+ - description:
+ Summary interrupt raised based on an external event for any
+ of the ETU slices.
+
+ interrupt-names:
+ items:
+ - const: etu_summary
+
+ pinctrl-names:
+ minItems: 1
+ maxItems: 16
+ items:
+ pattern: "^slice[0-9]+$"
+
+ qcom,etu-slice:
+ description:
+ ETU slice number for each entry in pinctrl-<n>, pinctrl-names and
+ qcom,etu-event-sel.
+ minItems: 1
+ maxItems: 16
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ qcom,etu-event-sel:
+ description:
+ External event selection value for each ETU slice listed in
+ qcom,etu-slice.
+ minItems: 1
+ maxItems: 16
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+
+allOf:
+ - if:
+ properties:
+ reg-names:
+ contains:
+ const: etu
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ required:
+ - interrupts
+ - interrupt-names
+ - pinctrl-names
+ - qcom,etu-slice
+ - qcom,etu-event-sel
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ptp@1c80000 {
+ compatible = "qcom,sa8775p-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+
+ 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>;
+ 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>;
+
+ ptp@1c80000 {
+ compatible = "qcom,sa8775p-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>,
+ <0x0 0x01c90000 0x0 0x10000>;
+ reg-names = "tsc", "etu";
+
+ 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>;
+ assigned-clock-rates = <15625000>;
+
+ interrupts = <GIC_SPI 766 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "etu_summary";
+
+ pinctrl-0 = <&cci_timer0>;
+ pinctrl-1 = <&cci_timer1>;
+ pinctrl-names = "slice1", "slice2";
+
+ qcom,etu-slice = <1 2>;
+ qcom,etu-event-sel = <1 2>;
+ };
+ };
+...
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 02/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
2026-11-08 13:18 ` [PATCH v2 01/10] dt-bindings: ptp: Document the TSCSS on Qualcomm SA8775P and QCS8300 SoCs Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 03/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm Nord and Shikra SoCs Imran Shaik
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 | 170 +++++++++++++++++++++
1 file changed, 170 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 000000000000..52a063ec4b78
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/qcom,qdu1000-tscss.yaml
@@ -0,0 +1,170 @@
+# 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 Timestamp 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 captures TSC timestamps for external hardware events. Each
+ ETU slice binds a slice number to an external event selector, and
+ generates its own interrupt when that event is triggered.
+
+properties:
+ compatible:
+ const: qcom,qdu1000-tscss
+
+ reg:
+ minItems: 1
+ maxItems: 2
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: tsc
+ - const: etu
+
+ clocks:
+ items:
+ - description: TSC AHB configuration clock.
+ - description: TSC global counter clock.
+ - description: TSC ETU clock.
+
+ clock-names:
+ items:
+ - const: ahb
+ - const: cntr
+ - const: etu
+
+ interrupts:
+ minItems: 1
+ maxItems: 16
+ description:
+ Per slice interrupt raised based on an external event mapped to
+ that ETU slice.
+
+ interrupt-names:
+ minItems: 1
+ maxItems: 16
+ items:
+ pattern: "^slice[0-9]+$"
+
+ pinctrl-names:
+ minItems: 1
+ maxItems: 16
+ items:
+ pattern: "^slice[0-9]+$"
+
+ qcom,etu-slice:
+ description:
+ ETU slice number for each entry in interrupts, interrupt-names,
+ pinctrl-<n>, pinctrl-names and qcom,etu-event-sel.
+ minItems: 1
+ maxItems: 16
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ qcom,etu-event-sel:
+ description:
+ External event selection value for each ETU slice listed in
+ qcom,etu-slice.
+ minItems: 1
+ maxItems: 16
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+
+allOf:
+ - if:
+ properties:
+ reg-names:
+ contains:
+ const: etu
+ then:
+ properties:
+ reg:
+ minItems: 2
+ maxItems: 2
+ required:
+ - interrupts
+ - interrupt-names
+ - pinctrl-names
+ - qcom,etu-slice
+ - qcom,etu-event-sel
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/qcom,qdu1000-gcc.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ptp@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>,
+ <&gcc GCC_TSC_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+ 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>;
+
+ ptp@1da0000 {
+ compatible = "qcom,qdu1000-tscss";
+ reg = <0x0 0x01da0000 0x0 0x2000>,
+ <0x0 0x01db0000 0x0 0x10000>;
+ reg-names = "tsc", "etu";
+
+ 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>;
+ assigned-clock-rates = <500000000>;
+
+ interrupts = <GIC_SPI 329 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 333 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 334 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "slice1", "slice5", "slice6";
+
+ pinctrl-0 = <&tod_pps>;
+ pinctrl-1 = <&gps_pps>;
+ pinctrl-2 = <&hardsync_pps>;
+ pinctrl-names = "slice1", "slice5", "slice6";
+
+ qcom,etu-slice = <1 5 6>;
+ qcom,etu-event-sel = <1 3 2>;
+ };
+ };
+...
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 03/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm Nord and Shikra SoCs
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
2026-11-08 13:18 ` [PATCH v2 01/10] dt-bindings: ptp: Document the TSCSS on Qualcomm SA8775P and QCS8300 SoCs Imran Shaik
2026-11-08 13:18 ` [PATCH v2 02/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm QDU1000 SoC Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 04/10] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 Nord and Shikra 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.
Nord additionally has a timer register region used to generate a
periodic pulse in sync with the TSC counter.
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,nord-tscss.yaml | 186 +++++++++++++++++++++
1 file changed, 186 insertions(+)
diff --git a/Documentation/devicetree/bindings/ptp/qcom,nord-tscss.yaml b/Documentation/devicetree/bindings/ptp/qcom,nord-tscss.yaml
new file mode 100644
index 000000000000..9d49e66a35c9
--- /dev/null
+++ b/Documentation/devicetree/bindings/ptp/qcom,nord-tscss.yaml
@@ -0,0 +1,186 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/ptp/qcom,nord-tscss.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Timestamp Counter Subsystem (TSCSS) on Qualcomm Nord and Shikra
+
+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 Timestamp 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 captures TSC timestamps for external hardware events. Each
+ ETU slice binds a slice number to an external event selector, and a
+ single summary interrupt is raised for any ETU slice event.
+
+ Nord additionally has a timer register region used to generate a
+ periodic pulse in sync with the TSC counter.
+
+properties:
+ compatible:
+ oneOf:
+ - const: qcom,nord-tscss
+ - items:
+ - const: qcom,shikra-tscss
+ - const: qcom,nord-tscss
+
+ reg:
+ minItems: 1
+ maxItems: 3
+
+ reg-names:
+ minItems: 1
+ items:
+ - const: tsc
+ - const: etu
+ - const: timer
+
+ clocks:
+ items:
+ - description: TSC AHB configuration clock.
+ - description: TSC global counter clock.
+ - description: TSC ETU clock.
+
+ clock-names:
+ items:
+ - const: ahb
+ - const: cntr
+ - const: etu
+
+ interrupts:
+ items:
+ - description:
+ Summary interrupt raised based on an external event for any
+ of the ETU slices.
+
+ interrupt-names:
+ items:
+ - const: etu_summary
+
+ pinctrl-names:
+ minItems: 1
+ maxItems: 32
+ items:
+ pattern: "^slice[0-9]+$"
+
+ qcom,etu-slice:
+ description:
+ ETU slice number for each entry in pinctrl-<n>, pinctrl-names and
+ qcom,etu-event-sel.
+ minItems: 1
+ maxItems: 32
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+ qcom,etu-event-sel:
+ description:
+ External event selection value for each ETU slice listed in
+ qcom,etu-slice.
+ minItems: 1
+ maxItems: 32
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+
+required:
+ - compatible
+ - reg
+ - reg-names
+ - clocks
+ - clock-names
+
+allOf:
+ - if:
+ properties:
+ reg-names:
+ contains:
+ const: etu
+ then:
+ required:
+ - interrupts
+ - interrupt-names
+ - pinctrl-names
+ - qcom,etu-slice
+ - qcom,etu-event-sel
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: qcom,shikra-tscss
+ then:
+ properties:
+ reg-names:
+ minItems: 1
+ items:
+ - const: tsc
+ - const: etu
+ pinctrl-names:
+ maxItems: 8
+ qcom,etu-slice:
+ maxItems: 8
+ qcom,etu-event-sel:
+ maxItems: 8
+
+additionalProperties: false
+
+examples:
+ - |
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ptp@1c80000 {
+ compatible = "qcom,nord-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+
+ clocks = <&gcc_tscss_ahb_clk>,
+ <&gcc_tscss_cntr_clk>,
+ <&gcc_tscss_etu_clk>;
+ clock-names = "ahb", "cntr", "etu";
+
+ assigned-clocks = <&gcc_tscss_cntr_clk>;
+ assigned-clock-rates = <250000000>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+ soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ptp@1c80000 {
+ compatible = "qcom,nord-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>,
+ <0x0 0x01ca0000 0x0 0x20000>,
+ <0x0 0x01c87000 0x0 0x1000>;
+ reg-names = "tsc", "etu", "timer";
+
+ clocks = <&gcc_tscss_ahb_clk>,
+ <&gcc_tscss_cntr_clk>,
+ <&gcc_tscss_etu_clk>;
+ clock-names = "ahb", "cntr", "etu";
+
+ assigned-clocks = <&gcc_tscss_cntr_clk>;
+ assigned-clock-rates = <250000000>;
+
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "etu_summary";
+
+ pinctrl-0 = <&cci_timer0>;
+ pinctrl-1 = <&cci_timer1>;
+ pinctrl-names = "slice1", "slice2";
+
+ qcom,etu-slice = <1 2>;
+ qcom,etu-event-sel = <1 2>;
+ };
+ };
+...
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 04/10] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (2 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 03/10] dt-bindings: ptp: Document TSCSS hardware on Qualcomm Nord and Shikra SoCs Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 05/10] arm64: defconfig: Enable Qualcomm TSC driver Imran Shaik
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 SA8775P, QDU1000 and Nord 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 | 11 +
drivers/ptp/Makefile | 1 +
drivers/ptp/ptp_qcom_tsc.c | 598 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 610 insertions(+)
diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig
index feb50f8cc406..91bc347b2c50 100644
--- a/drivers/ptp/Kconfig
+++ b/drivers/ptp/Kconfig
@@ -264,4 +264,15 @@ 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 ARCH_QCOM || COMPILE_TEST
+ 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 bdc47e284f14..ff029323e98f 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 000000000000..82ddbdd63389
--- /dev/null
+++ b/drivers/ptp/ptp_qcom_tsc.c
@@ -0,0 +1,598 @@
+// 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)
+
+/* Dynamic (continuous) drift correction, used on Nord/Shikra */
+#define DRIFT_STATUS BIT(1)
+#define DRIFT_DYNAMIC_EN BIT(2)
+#define DYNAMIC_DRIFT_SUBPERIOD_MASK GENMASK(27, 0)
+#define DYNAMIC_DRIFT_MIN_SUBPERIOD 6
+#define DYNAMIC_DRIFT_INCR_VAL 8
+#define DYNAMIC_DRIFT_POLL_US 10
+#define DYNAMIC_DRIFT_DISABLE_TIMEOUT_US 1000
+
+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 drift_correct_duration_2;
+ u32 drift_correct_cmd_2;
+ 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
+ * @dynamic_drift_correction: hardware supports continuous drift correction,
+ * instead of a one-shot jump/swallow 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;
+ bool dynamic_drift_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;
+ bool clocks_enabled;
+ 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);
+
+ if (!tsc->clocks_enabled) {
+ mutex_unlock(&tsc->lock);
+ return -EINVAL;
+ }
+
+ ret = qcom_tsc_read_time(tsc, ts);
+ mutex_unlock(&tsc->lock);
+
+ return ret;
+}
+
+static 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 void qcom_tsc_clk_disable(void *data)
+{
+ clk_disable_unprepare(data);
+}
+
+static int qcom_tsc_enable_clocks(struct qcom_tsc *tsc)
+{
+ int ret;
+
+ if (tsc->clocks_enabled)
+ return 0;
+
+ ret = clk_prepare_enable(tsc->ahb_clk);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(tsc->dev, qcom_tsc_clk_disable, tsc->ahb_clk);
+ if (ret)
+ return ret;
+
+ ret = clk_prepare_enable(tsc->cntr_clk);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(tsc->dev, qcom_tsc_clk_disable, tsc->cntr_clk);
+ if (ret)
+ return ret;
+
+ tsc->clocks_enabled = true;
+
+ return 0;
+}
+
+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);
+
+ ret = qcom_tsc_enable_clocks(tsc);
+ if (ret) {
+ mutex_unlock(&tsc->lock);
+ return ret;
+ }
+
+ 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 &= ~PULSE_WIDTH_MASK;
+ 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);
+
+ if (!tsc->clocks_enabled) {
+ mutex_unlock(&tsc->lock);
+ return -EINVAL;
+ }
+
+ 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)
+ return 0;
+
+ 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 bool qcom_tsc_dynamic_drift_type_matches(u32 duration, bool neg_adj)
+{
+ return !(duration & DRIFT_JUMP_SWALLOW) == neg_adj;
+}
+
+static void qcom_tsc_set_dynamic_drift_enable(struct qcom_tsc *tsc, u32 cmd, bool enable)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+
+ if (enable)
+ cmd |= DRIFT_DYNAMIC_EN;
+ else
+ cmd &= ~DRIFT_DYNAMIC_EN;
+
+ writel_relaxed(cmd, tsc->base + regs->drift_correct_cmd);
+}
+
+static int qcom_tsc_disable_dynamic_drift(struct qcom_tsc *tsc, u32 cmd)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+
+ qcom_tsc_set_dynamic_drift_enable(tsc, cmd, false);
+
+ return readl_poll_timeout(tsc->base + regs->drift_correct_cmd, cmd,
+ !(cmd & DRIFT_STATUS), DYNAMIC_DRIFT_POLL_US,
+ DYNAMIC_DRIFT_DISABLE_TIMEOUT_US);
+}
+
+static void qcom_tsc_program_dynamic_drift(struct qcom_tsc *tsc, u32 duration,
+ bool neg_adj, u32 subperiod)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+
+ if (neg_adj)
+ duration &= ~DRIFT_JUMP_SWALLOW;
+ else
+ duration |= DRIFT_JUMP_SWALLOW;
+
+ writel_relaxed(duration, tsc->base + regs->drift_correct_duration);
+ writel_relaxed(DYNAMIC_DRIFT_INCR_VAL, tsc->base + regs->drift_correct_incr_val);
+ writel_relaxed(FIELD_PREP(DYNAMIC_DRIFT_SUBPERIOD_MASK, subperiod),
+ tsc->base + regs->drift_correct_duration_2);
+}
+
+/*
+ * Unlike qcom_tsc_drift_correction()'s one-shot jump/swallow correction,
+ * hardware supporting dynamic drift correction keeps the correction
+ * continuously active across adjfine() calls. The subperiod can be updated
+ * in place while active, as long as the correction direction (jump vs
+ * swallow) is unchanged; otherwise the correction must be disabled and
+ * reprogrammed before being re-enabled.
+ */
+static int qcom_tsc_dynamic_drift_correction(struct qcom_tsc *tsc, long scaled_ppm)
+{
+ const struct qcom_tsc_regs *regs = tsc->soc->reg_layout;
+ long ppb = scaled_ppm_to_ppb(scaled_ppm);
+ bool neg_adj = ppb < 0;
+ u32 duration, cmd, subperiod;
+ int ret;
+
+ if (neg_adj)
+ ppb = -ppb;
+
+ cmd = readl_relaxed(tsc->base + regs->drift_correct_cmd);
+
+ if (ppb == 0) {
+ if (cmd & DRIFT_STATUS)
+ return qcom_tsc_disable_dynamic_drift(tsc, cmd);
+
+ return 0;
+ }
+
+ subperiod = NSEC_PER_SEC / ppb;
+ subperiod = clamp_val(subperiod, DYNAMIC_DRIFT_MIN_SUBPERIOD, DYNAMIC_DRIFT_SUBPERIOD_MASK);
+
+ duration = readl_relaxed(tsc->base + regs->drift_correct_duration);
+
+ if ((cmd & DRIFT_STATUS) && qcom_tsc_dynamic_drift_type_matches(duration, neg_adj)) {
+ writel_relaxed(FIELD_PREP(DYNAMIC_DRIFT_SUBPERIOD_MASK, subperiod),
+ tsc->base + regs->drift_correct_duration_2);
+ return 0;
+ }
+
+ if (cmd & DRIFT_STATUS) {
+ ret = qcom_tsc_disable_dynamic_drift(tsc, cmd);
+ if (ret)
+ return ret;
+
+ cmd = readl_relaxed(tsc->base + regs->drift_correct_cmd);
+ }
+
+ qcom_tsc_program_dynamic_drift(tsc, duration, neg_adj, subperiod);
+ qcom_tsc_set_dynamic_drift_enable(tsc, cmd, true);
+
+ return 0;
+}
+
+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;
+
+ mutex_lock(&tsc->lock);
+
+ if (!tsc->clocks_enabled) {
+ mutex_unlock(&tsc->lock);
+ return -EINVAL;
+ }
+
+ if (tsc->soc->dynamic_drift_correction)
+ ret = qcom_tsc_dynamic_drift_correction(tsc, scaled_ppm);
+ else
+ 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_regs qcom_tsc_layout_v2 = {
+ .control_cntcr = 0x0,
+ .control_cntcv_lo = 0x8,
+ .control_cntcv_hi = 0xc,
+ .drift_correct_incr_val = 0x2c,
+ .drift_correct_duration = 0x30,
+ .drift_correct_duration_2 = 0x34,
+ .drift_correct_cmd = 0x38,
+ .drift_correct_cmd_2 = 0x3c,
+ .rollover_val = 0x44,
+ .offset_lo = 0x50,
+ .offset_hi = 0x54,
+ .read_cntcv_lo = 0x1000,
+ .read_cntcv_hi = 0x1004,
+};
+
+static const struct qcom_tsc_soc_data qcom_tsc_sa8775p = {
+ .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 qcom_tsc_soc_data qcom_tsc_nord = {
+ .reg_layout = &qcom_tsc_layout_v2,
+ .rollover = false,
+ .offset_correction = true,
+ .dynamic_drift_correction = true,
+ .pulse_width = 3,
+ .cntr_res = 4,
+};
+
+static const struct of_device_id qcom_tsc_of_match[] = {
+ { .compatible = "qcom,sa8775p-tscss", .data = &qcom_tsc_sa8775p },
+ { .compatible = "qcom,qdu1000-tscss", .data = &qcom_tsc_qdu1000 },
+ { .compatible = "qcom,nord-tscss", .data = &qcom_tsc_nord },
+ { }
+};
+MODULE_DEVICE_TABLE(of, qcom_tsc_of_match);
+
+static int qcom_ptp_tsc_probe(struct platform_device *pdev)
+{
+ const struct qcom_tsc_soc_data *soc;
+ struct qcom_tsc *tsc;
+ 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;
+
+ tsc->base = devm_platform_ioremap_resource_byname(pdev, "tsc");
+ if (IS_ERR(tsc->base))
+ return PTR_ERR(tsc->base);
+
+ /* Both clocks are enabled on first use, when the counter is set */
+ tsc->ahb_clk = devm_clk_get(&pdev->dev, "ahb");
+ if (IS_ERR(tsc->ahb_clk))
+ return PTR_ERR(tsc->ahb_clk);
+
+ tsc->cntr_clk = devm_clk_get(&pdev->dev, "cntr");
+ if (IS_ERR(tsc->cntr_clk))
+ return PTR_ERR(tsc->cntr_clk);
+
+ tsc->ptp_info = qcom_ptp_info;
+
+ tsc->ptp = ptp_clock_register(&tsc->ptp_info, &pdev->dev);
+ if (IS_ERR(tsc->ptp))
+ return dev_err_probe(&pdev->dev, PTR_ERR(tsc->ptp),
+ "Failed to register ptp clock\n");
+
+ platform_set_drvdata(pdev, tsc);
+
+ return 0;
+}
+
+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 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 [flat|nested] 11+ messages in thread* [PATCH v2 05/10] arm64: defconfig: Enable Qualcomm TSC driver
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (3 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 04/10] ptp: qcom: Add PTP driver for the Qualcomm TSC hardware Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 06/10] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 7b4985b29b21..9af55787b236 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -689,6 +689,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 [flat|nested] 11+ messages in thread* [PATCH v2 06/10] arm64: dts: qcom: lemans: Add support for TSCSS node
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (4 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 05/10] arm64: defconfig: Enable Qualcomm TSC driver Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 07/10] arm64: dts: qcom: monaco: " Imran Shaik
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi
index 1fdb72fa5518..4c76c820cacb 100644
--- a/arch/arm64/boot/dts/qcom/lemans.dtsi
+++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -3022,6 +3022,18 @@ pcie1_phy: phy@1c14000 {
status = "disabled";
};
+ ptp@1c80000 {
+ compatible = "qcom,sa8775p-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+ 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>;
+ 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 [flat|nested] 11+ messages in thread* [PATCH v2 07/10] arm64: dts: qcom: monaco: Add support for TSCSS node
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (5 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 06/10] arm64: dts: qcom: lemans: Add support for TSCSS node Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 08/10] arm64: dts: qcom: qdu1000: " Imran Shaik
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 Monaco
SoCs.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/monaco.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi
index 35fbee63d4c6..b87ba4b3a5a6 100644
--- a/arch/arm64/boot/dts/qcom/monaco.dtsi
+++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -2628,6 +2628,18 @@ pcie1_phy: phy@1c14000 {
status = "disabled";
};
+ ptp@1c80000 {
+ compatible = "qcom,qcs8300-tscss", "qcom,sa8775p-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+ 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>;
+ assigned-clock-rates = <15625000>;
+ };
+
ufs_mem_hc: ufs@1d84000 {
compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
reg = <0x0 0x01d84000 0x0 0x3000>;
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 08/10] arm64: dts: qcom: qdu1000: Add support for TSCSS node
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (6 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 07/10] arm64: dts: qcom: monaco: " Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 09/10] arm64: dts: qcom: shikra: " Imran Shaik
2026-11-08 13:18 ` [PATCH v2 10/10] arm64: dts: qcom: nord: " Imran Shaik
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
index 3a25b5100836..0f4028c41b2f 100644
--- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
@@ -877,6 +877,19 @@ system_noc: interconnect@1640000 {
#interconnect-cells = <2>;
};
+ ptp@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>,
+ <&gcc GCC_TSC_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+ 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 [flat|nested] 11+ messages in thread* [PATCH v2 09/10] arm64: dts: qcom: shikra: Add support for TSCSS node
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (7 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 08/10] arm64: dts: qcom: qdu1000: " Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
2026-11-08 13:18 ` [PATCH v2 10/10] arm64: dts: qcom: nord: " Imran Shaik
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 Shikra
SoCs.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/shikra.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index 2623e139196f..09aabbf447e0 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -2481,6 +2481,18 @@ compute-cb@6 {
};
};
+ ptp@4b00000 {
+ compatible = "qcom,shikra-tscss", "qcom,nord-tscss";
+ reg = <0x0 0x04b00000 0x0 0x2000>;
+ reg-names = "tsc";
+ clocks = <&gcc GCC_TSCSS_AHB_CLK>,
+ <&gcc GCC_TSCSS_CNTR_CLK>,
+ <&gcc GCC_TSCSS_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+ assigned-clocks = <&gcc GCC_TSCSS_CNTR_CLK>;
+ assigned-clock-rates = <250000000>;
+ };
+
usb_2: usb@4c00000 {
compatible = "qcom,shikra-dwc3", "qcom,snps-dwc3";
reg = <0x0 0x04c00000 0x0 0xfc100>;
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread* [PATCH v2 10/10] arm64: dts: qcom: nord: Add support for TSCSS node
2026-11-08 13:18 [PATCH v2 00/10] Add support for Qualcomm TSCSS hardware Imran Shaik
` (8 preceding siblings ...)
2026-11-08 13:18 ` [PATCH v2 09/10] arm64: dts: qcom: shikra: " Imran Shaik
@ 2026-11-08 13:18 ` Imran Shaik
9 siblings, 0 replies; 11+ messages in thread
From: Imran Shaik @ 2026-11-08 13:18 UTC (permalink / raw)
To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Richard Cochran,
Andrew Lunn, David S. Miller, Jakub Kicinski, Paolo Abeni,
Bjorn Andersson, Konrad Dybcio, Eric Dumazet, Abel Vesa,
Eric Dumazet
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 Nord
SoCs.
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
arch/arm64/boot/dts/qcom/nord-embedded.dtsi | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/nord-embedded.dtsi b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi
index 1ab7d9bc3cfe..1d5f27336f73 100644
--- a/arch/arm64/boot/dts/qcom/nord-embedded.dtsi
+++ b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi
@@ -736,6 +736,20 @@ pcie_data_inbound: interconnect@1c00000 {
qcom,bcm-voters = <&apps_bcm_voter>;
};
+ ptp@1c80000 {
+ compatible = "qcom,nord-tscss";
+ reg = <0x0 0x01c80000 0x0 0x2000>;
+ reg-names = "tsc";
+
+ clocks = <&segcc SE_GCC_TSCSS_AHB_CLK>,
+ <&segcc SE_GCC_TSCSS_CNTR_CLK>,
+ <&segcc SE_GCC_TSCSS_ETU_CLK>;
+ clock-names = "ahb", "cntr", "etu";
+
+ assigned-clocks = <&segcc SE_GCC_TSCSS_CNTR_CLK>;
+ assigned-clock-rates = <250000000>;
+ };
+
ufs_mem_phy: phy@1d40000 {
compatible = "qcom,nord-qmp-ufs-phy",
"qcom,sm8650-qmp-ufs-phy";
--
2.34.1
^ permalink raw reply [flat|nested] 11+ messages in thread