From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97C89391505 for ; Tue, 16 Jun 2026 20:26:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641618; cv=none; b=UgQHDFk9BL3eowUQzW7ZX7S6iWmGHW4cqUvDTHbT6/crAcACzNaDEOrSmUbP40fka8B12I33DRsE3DdiN+rPhDS1fvQkGerMmQ5w9ayLfTQAT0qQpAgMnbaexkmipbZ5Z/YwRblaBsnrOwfdjlGQroDEYkIUx0oy2ROTBEnqvkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641618; c=relaxed/simple; bh=EhdBvdiVrO8rOSTQ2CUBEIa8UYk8Rkh7tz54zYD05Qk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PJmMBYvgOZ8pqgnXpAw9SOTE19uRisWZYEI+F8on4qYQBFaulG8jqhZosbXL44kMquvPZxAKMgnX8JJMeOPM5F1m6PD0YtkkirQSxEEBhzOo9Bs5zMNVNNlhNfbps5AzqsKHcil6j1P+EMYgBZ7TMyyPYNXrTBvSeiHThic8IH0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ppebw2p6; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ppebw2p6" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4921e4dd62dso2252355e9.0 for ; Tue, 16 Jun 2026 13:26:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641615; x=1782246415; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=rUmYrMa2a929oow4K0kGQmeQ8euSAQ5ozU/DAB8krW0=; b=Ppebw2p6oIspHkcwKFZz7vGTl98SWlkOsxl0g9qzkcn7e+8DshTFNRQK2WC56yigXH iY1olUjbaoouEwN9hW6V8cnpCdCMwq2y8LKPfCXfhTV65iglbErrkPhMB8EqJy8Ueias Yl43eQz/F11fReOMb+Y1RlM0rZgwT/s3vpEzmS01ynFdSmW3ULNgxUv2xwhsXEYrRmXx W8FjuPAkG5ju05tbCrZvotFjo4lV3/wXNMviGU40nXPPd4W9HeU4GStMF6bZ68UKJOjL SAw2lT+eXztOTdy4w8fujomWWrnmUTN7tlKxexLh7nLFCPlrGO+Pl/fhZb25g6koyWHi fdKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641615; x=1782246415; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=rUmYrMa2a929oow4K0kGQmeQ8euSAQ5ozU/DAB8krW0=; b=iJw243vBh5a1VhQV2rJx1GfJKdM8jRaJmOJVFxSe8FaBVnTOxOCSoOHtzM5OG9rwWO GZtPdy+Zd0V1IoYFCFqOe1GVLJhH4yykuiJZamTvT7zC7dZFnIvaoP9w7FW2bUuEnXnx i+RwcKwr9sIWY0WS6qz5yNCKTuG1wtENyPhRwh1YaEyhxRe4VErusbMBq7EnjrzFKoFz LVn2cch3KEcuR+RAksZWC6nCaRYrd51QdRumRXBwPWIbigmpwakUoNV9VjyBLZCgrOd9 AH+80eappCBdQrFnffMNW9qt++xIaQyDpooZgLNCLie0O9p1Pd3K4faZ8y/DHXo55FEW DJiQ== X-Forwarded-Encrypted: i=1; AFNElJ+VZGYXuZe2PWU9MeYtCAgAGqh8ZiPwqJaCIEIl2YluINs0vwGy1zh38YpONULCg+sOpSVws8b7/WqtGHk=@vger.kernel.org X-Gm-Message-State: AOJu0YzXu8/cAC18z1nxrE3P1A1LyFK8ek8bLlRpqvJxfeGVGBi4g54T pgs5gmegeGA5fLri1Bx0gxAuPqsVLfma6k//5XiMS22u28Wp6ZzP1xlt X-Gm-Gg: Acq92OGMtTvhyqYgek78XBEc3lT8lwR96esKbKL+JU0WdHJQ8CsjyK7Km4oMTmrofDq D6WvUcisLNDFEVMhsI2bghpYThzU5y+kkEeFduwNWhz2nJCLkyBviQZ5dWV18a43Naqb68yGk3E /fQlafKFBjXZozjVFJhYmiDUiwM/spzztamDkwkBxhVTtpY/OPhndtIYq/X2bXkZaJ5lcPXedEs m1niOWfwYCegbVBGqEb5/upZDYngvT3vzEFGHyFgSfN5nWlIbBeb9HDlCbFrk99upZ13PgBkHnn TQbRAOSmt48NRVAi1nkn8zS3Z1mQ8XCdndAk4l/rd9u/+ymtHksQW37Ilu2JUtFvdG4tUulJd6q sfXedV6AtcAFPlJoGSC6z0hMfY5+ZUVxLqvk8gDtp8gNXi8xhH4oMEX2n3QjwO+/wH6qm9nOChd Mj7s3S9JedTOKzmXDpGMRMxkKM+E4CHOjzoA== X-Received: by 2002:a05:600c:8b83:b0:489:32b:ac0b with SMTP id 5b1f17b1804b1-492340c5eb5mr3321645e9.6.1781641614915; Tue, 16 Jun 2026 13:26:54 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.26.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:26:54 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:21 +0300 Subject: [PATCH RFC v4 01/12] dt-bindings: clk: zte: Add zx297520v3 top clock and reset bindings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-1-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9380; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=EhdBvdiVrO8rOSTQ2CUBEIa8UYk8Rkh7tz54zYD05Qk=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGN3MQD58npdh76POdP4gdkZzPN/KGEJEmI DYwcSBZmKiJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiJxMQ//dg9SlBJQ1UP2n6iVcOpfOYchqn0lSiV O33z7NFotUzB5JIjX7aZqEfFOvjPZIgRXhmn0vJCLhT0janHH6Un//79duLKb22k0ZVlnZjI9ph xFJ5egU9kU4rWhDF7W9AiWqcrMGQDFThWiPW7lyPmOzUeqJYqu76ucPFfA01ovE2ZWIOSj6tNZf ownA4vjBzzeZis802xJ3fUaPbQ0Vwswb5UiZ1c5v2/4S8igElO71YnGOjtR+KKUQRJ74VGTMZfp dV3VYbQem/KSJh6dyH8y0lmjizSKzaf81TYGByRa+zOdRuEx/MvnEzqmPUwMizrerCHNXhXqFTN SbqJD2ivCCOgwamCO9N6pG5aYJ+sjAAc3Hbda55icVQH/p/oeNvQH5rGVYdrc6nxQ+jRbGIEt9A DBJ4zxALEoP3KqTfh7SjKFpjOhHpVw/88QxTwUBPyIp0lDSUb7jwckOmLi1p9T1d6bgGT/Yq+Dv Oz4yqmQ4B5dFvac0NkSO6xCn6LQ8Fd6sLNS0G05rK8D3Ke1mTdC8EnOKwAIg5K4A/90XHJQNd1+ y88DdUKEJHs/Ccz6JL6rIkay4FFUc7+rRX9YK900ht8pdRPG69B18d2cjCNhlQpeiqt0zT99esF JxsL6QEg/7iNIC+QnsY7meeb8P0joAavw1beIVyeD0JWipZ65diM= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 These SoCs have 3 clock and reset controllers: Top, Matrix and LSP. The separation of concerns between Top and Matrix and the interface between them is poorly defined in the hardware, so the bindings list all potential PLL clocks that might be passed between them. Generally every device has two clocks (one work clock, and one that connects it to the bus, I call it PCLK), two reset bits (I don't know what the difference is - sometimes asserting one is enough to reset the device, sometimes both need to be asserted). PCLK and WCLK are controlled by individual gates. Some devices have a mux and/or a divider for their work clock. Some devices, like the GPIO controller, only have reset bits and no clocks. The top clock controller is fed by a 26mhz external oscillator and has 4 PLLs to generate other clock rates. ZTE's kernel mostly relies on the boot ROM to set up PLLs, but one LTE-Related PLL is not configured on some boards. Therefore my driver contains code to program PLLs. It produces identical settings as the boot ROM for the pre-programmed frequencies. Not all clocks will have an explicit user in the end. I am defining a lot of them simply to shut them off. The boot loader sets up a few of the proprietary timers, which will send regular IRQs (although the kernel of course doesn't need to listen to them). I don't plan to add a driver for the proprietary timer as I see no use for them - the ARM arch timer works just fine. I will add a driver for the very similar proprietary watchdog though. The clock list in this patch is pretty complete but not exhaustive. There are other bits that are enabled, but I couldn't deduce what they are controlling by trial and error. Some of them seem to do nothing. Others cause an instant hang of the board when disabled. It is quite likely that a handful more clocks will be added in the future, but not a large number. Signed-off-by: Stefan D=C3=B6singer --- .../bindings/clock/zte,zx297520v3-topclk.yaml | 70 ++++++++++++ MAINTAINERS | 2 + include/dt-bindings/clock/zte,zx297520v3-clk.h | 118 +++++++++++++++++= ++++ 3 files changed, 190 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-topclk.= yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-topclk.yaml new file mode 100644 index 000000000000..374f63891288 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-topclk.yaml @@ -0,0 +1,70 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-topclk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC top clock and reset controller + +maintainers: + - Stefan D=C3=B6singer + +description: | + The zx297520v3's top clock controller generates clocks for core devices = on the + board like the main bus, USB and timers. In addition to clocks it has re= set + controls for peripherals, a global board reset and watchdog reset contro= ls. + + The controller has two clock inputs: a 26 MHz and a 32 KHz external + oscillator. They need to be provided as input clocks. The controller pro= vides + clocks to the downstream Matrix clock controller. + + All available clocks are defined as preprocessor macros in the + 'dt-bindings/clock/zte,zx297520v3-clk.h' header. + +properties: + compatible: + items: + - const: zte,zx297520v3-topclk + - const: syscon + + reg: + maxItems: 1 + + clocks: + items: + - description: 26 MHz external oscillator + - description: 32 KHz external oscillator + + clock-names: + items: + - const: osc26m + - const: osc32k + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + clock-controller@13b000 { + compatible =3D "zte,zx297520v3-topclk", "syscon"; + reg =3D <0x0013b000 0x400>; + clocks =3D <&osc26m>, <&osc32k>; + clock-names =3D "osc26m", "osc32k"; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index 8629ed2aa82f..0cc1ede3c80c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3867,8 +3867,10 @@ L: linux-arm-kernel@lists.infradead.org (moderated f= or non-subscribers) S: Odd fixes F: Documentation/arch/arm/zte/ F: Documentation/devicetree/bindings/arm/zte.yaml +F: Documentation/devicetree/zte,zx297520v3-* F: arch/arm/boot/dts/zte/ F: arch/arm/mach-zte/ +F: include/dt-bindings/clock/zte,zx297520v3-clk.h =20 ARM/ZYNQ ARCHITECTURE M: Michal Simek diff --git a/include/dt-bindings/clock/zte,zx297520v3-clk.h b/include/dt-bi= ndings/clock/zte,zx297520v3-clk.h new file mode 100644 index 000000000000..cf436ff20dfe --- /dev/null +++ b/include/dt-bindings/clock/zte,zx297520v3-clk.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) Stefan D=C3=B6singer. + */ + +#ifndef __DT_BINDINGS_CLOCK_ZX297520V3_H +#define __DT_BINDINGS_CLOCK_ZX297520V3_H + +#define ZX297520V3_M0_WCLK 1 +#define ZX297520V3_SRAM1_PCLK 2 +#define ZX297520V3_SRAM2_PCLK 3 +#define ZX297520V3_UART0_WCLK 4 +#define ZX297520V3_UART0_PCLK 5 +#define ZX297520V3_I2C0_WCLK 6 +#define ZX297520V3_I2C0_PCLK 7 +#define ZX297520V3_RTC_WCLK 8 +#define ZX297520V3_RTC_PCLK 9 +#define ZX297520V3_LPM_GSM_WCLK 10 +#define ZX297520V3_LPM_GSM_PCLK 11 +#define ZX297520V3_LPM_LTE_WCLK 12 +#define ZX297520V3_LPM_LTE_PCLK 13 +#define ZX297520V3_LPM_TD_WCLK 14 +#define ZX297520V3_LPM_TD_PCLK 15 +#define ZX297520V3_LPM_W_WCLK 16 +#define ZX297520V3_LPM_W_PCLK 17 +#define ZX297520V3_TIMER_T08_WCLK 18 +#define ZX297520V3_TIMER_T08_PCLK 19 +#define ZX297520V3_TIMER_T09_WCLK 20 +#define ZX297520V3_TIMER_T09_PCLK 21 +#define ZX297520V3_MPLL 22 +#define ZX297520V3_MPLL_D2 23 +#define ZX297520V3_MPLL_D3 24 +#define ZX297520V3_MPLL_D4 25 +#define ZX297520V3_MPLL_D5 26 +#define ZX297520V3_MPLL_D6 27 +#define ZX297520V3_MPLL_D8 28 +#define ZX297520V3_MPLL_D12 29 +#define ZX297520V3_MPLL_D16 30 +#define ZX297520V3_MPLL_D26 31 +#define ZX297520V3_UPLL 32 +#define ZX297520V3_UPLL_D2 33 +#define ZX297520V3_UPLL_D3 34 +#define ZX297520V3_UPLL_D4 35 +#define ZX297520V3_UPLL_D5 36 +#define ZX297520V3_UPLL_D6 37 +#define ZX297520V3_UPLL_D8 38 +#define ZX297520V3_UPLL_D12 39 +#define ZX297520V3_UPLL_D16 40 +#define ZX297520V3_DPLL 41 +#define ZX297520V3_DPLL_D2 42 +#define ZX297520V3_DPLL_D3 43 +#define ZX297520V3_DPLL_D4 44 +#define ZX297520V3_DPLL_D5 45 +#define ZX297520V3_DPLL_D6 46 +#define ZX297520V3_DPLL_D8 47 +#define ZX297520V3_DPLL_D12 48 +#define ZX297520V3_DPLL_D16 49 +#define ZX297520V3_GPLL 50 +#define ZX297520V3_GPLL_D2 51 +#define ZX297520V3_GPLL_D3 52 +#define ZX297520V3_GPLL_D4 53 +#define ZX297520V3_GPLL_D5 54 +#define ZX297520V3_GPLL_D6 55 +#define ZX297520V3_GPLL_D8 56 +#define ZX297520V3_GPLL_D12 57 +#define ZX297520V3_GPLL_D16 58 +#define ZX297520V3_PMM_WCLK 59 +#define ZX297520V3_PMM_PCLK 60 +#define ZX297520V3_OUT0_WCLK 61 +#define ZX297520V3_OUT1_WCLK 62 +#define ZX297520V3_OUT2_WCLK 63 +#define ZX297520V3_OUT32K_WCLK 64 +#define ZX297520V3_RMIIPHY_WCLK 65 +#define ZX297520V3_TIMER_T12_WCLK 66 +#define ZX297520V3_TIMER_T12_PCLK 67 +#define ZX297520V3_TIMER_T13_WCLK 68 +#define ZX297520V3_TIMER_T13_PCLK 69 +#define ZX297520V3_TIMER_T14_WCLK 70 +#define ZX297520V3_TIMER_T14_PCLK 71 +#define ZX297520V3_TIMER_T15_WCLK 72 +#define ZX297520V3_TIMER_T15_PCLK 73 +#define ZX297520V3_TIMER_T16_WCLK 74 +#define ZX297520V3_TIMER_T16_PCLK 75 +#define ZX297520V3_TIMER_T17_WCLK 76 +#define ZX297520V3_TIMER_T17_PCLK 77 +#define ZX297520V3_WDT_T18_WCLK 78 +#define ZX297520V3_WDT_T18_PCLK 79 +#define ZX297520V3_USIM1_WCLK 80 +#define ZX297520V3_USIM1_PCLK 81 +#define ZX297520V3_AHB_WCLK 82 +#define ZX297520V3_AHB_PCLK 83 +#define ZX297520V3_USB_WCLK 84 +#define ZX297520V3_USB_PCLK 85 +#define ZX297520V3_HSIC_WCLK 86 +#define ZX297520V3_HSIC_PCLK 87 + +#define ZX297520V3_ZSP_RESET 0 +#define ZX297520V3_UART0_RESET 1 +#define ZX297520V3_I2C0_RESET 2 +#define ZX297520V3_RTC_RESET 3 +#define ZX297520V3_TIMER_T08_RESET 4 +#define ZX297520V3_TIMER_T09_RESET 5 +#define ZX297520V3_PMM_RESET 6 +#define ZX297520V3_GPIO_RESET 7 +#define ZX297520V3_GPIO8_RESET 8 +#define ZX297520V3_TIMER_T12_RESET 9 +#define ZX297520V3_TIMER_T13_RESET 10 +#define ZX297520V3_TIMER_T14_RESET 11 +#define ZX297520V3_TIMER_T15_RESET 12 +#define ZX297520V3_TIMER_T16_RESET 13 +#define ZX297520V3_TIMER_T17_RESET 14 +#define ZX297520V3_WDT_T18_RESET 15 +#define ZX297520V3_USIM1_RESET 16 +#define ZX297520V3_AHB_RESET 17 +#define ZX297520V3_USB_RESET 18 +#define ZX297520V3_HSIC_RESET 19 + +#endif /* __DT_BINDINGS_CLOCK_ZX297520V3_H */ --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A79CC3914E4 for ; Tue, 16 Jun 2026 20:27:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641622; cv=none; b=oPEuVi+JTsU5LDAkkiDK0mID/VIh549akx//jys/XGoE9OeA3LW8bQhoVmrTmFl4XlCbS0HDdkhG4jcclyzrwsWXoiwWtdKN3ZJ9tKLVgWqeHZfXVXAz+oxrYozOyV6GNKj+Och7DUIZbmKB0Ppc5asbdyS3WK6Hke1oii40XM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641622; c=relaxed/simple; bh=5Z4ESOVeKBRM0YFOt39SoxPXZhq0x1sOAoH1jrCCjuQ=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SfP/Di5EMT8Xg3zdXVd0wAg1Y0CMrXLex+bCCxEKDo+p++y1CNZoJD9x2ZAmJ64NCnUAvfjEhu4dF0BoiPH9vSKdBiMKVUkePTzDa94HZgALSU0B4qtxOtak9d9UWiEdUlUbGqGIYj1hNcXUlNnViuMKe3LfijRIA+hngO8w+Cw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=k4V2bA3P; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k4V2bA3P" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-490b4a8e28bso38249865e9.1 for ; Tue, 16 Jun 2026 13:27:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641619; x=1782246419; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=7yt9uNKNQQM+kBZ7grL85coaaAADfms7lZW+K+UY64U=; b=k4V2bA3PsVjMwsLDb3QE2rGFas2X6St3ZFv1FzgTdp0d2/ZxnZRD4Q3Wv1te2+YNY5 3flKdtbmO7jTBLrOj6GKv1vnRZe+H7B7yE65qVL/mAwAkh6UHj+e9HD4fgMbNPrk+tvY IL0I8aadG/2L93VfBSa4Wjp6fS5H+p38KYUS1myjXl6GgzDYQ9xrwrMDmllCbyS5cKay JB79KTzxaRmwebYEH3Ci360+fBC9cHcnSZP4PkVhQ4Ef6Tz95z4Keh7leIUepjybocjR ZzcuFeTpJIX1iarhsqm/DbN4fbAxn4TU1Ajqsuuz1ipxqIb2fSnrg+NpJJO2O2vJ+Nf8 CEqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641619; x=1782246419; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=7yt9uNKNQQM+kBZ7grL85coaaAADfms7lZW+K+UY64U=; b=mzBRijHFcj1S586z9zhxJL5/6pvrq8ynsHZT2in1JsQb2WGF/EnAj3tIQIBA0YUhcZ aBJAFU85HaA3F2DGksC/DYB5EHqHhaYPg5sy1Ev+g0NqSuB8S8LYR7ecMgSpkK+WVEP6 A04NftkkQ0nV+UljH390wdXw9k+rH3/hrmtfZUbUzh0nxAYoqDpLcNDsUmUpYWjGmoeh NYfT+ZoggnS4whMX3hgfkQaurHP9owHtVG17pG6sBSQLcbBehN4ubjbYnKvifipTMMLk 3EcM/Nsn3zO0hpToiQ9J6/x3zwD5nd568eDKBz0GD26MslNt/BXxrgOaAUGeR/CQ1kGu V4qw== X-Forwarded-Encrypted: i=1; AFNElJ8bZQboVxnwcXScquqSzJCg8I+wieM5RwTawRPL+sld6SQp5g357sUX/MYw1/VSy1OAj+Su4NNQhHaUJ4Q=@vger.kernel.org X-Gm-Message-State: AOJu0YzDXZIY9/ttdGN51GNXb4AZxr7LcapPXh0i8558Q6EwLnQVBkqv zlkYFpmLwv08aG4jLSDmkuRd2VusigfD3dPILNo/vbP9C4yx1wMSEe4v X-Gm-Gg: Acq92OEVRI38ZB/4oa7Uo55UIphhO6/qmytdvIE1ma6rFEkKIjQQJqQNZ8rlK7UM19O S9vAai66NIHN+IEEIxA18VQjlKdVKE76oKiLGx8cDgaeDpkL2S3kkVCGEzOs27Z1TWHw+nSJlJQ s9HXsVcyD3od9xP8EniVhGl5QbxMyv7hrr46LRnmbjqdL4Wyap9esqfD/bPiFlqGoTT07TvcgOi PpgUuDBXgDRY6nGvs+0+YiDh2Ma+mXaSJScd+tTj/1JaAVRXIrlRa4oE0ZaZP1I210wCCLHdv5K TWEXXKhhscxdC6t+c7HbwkTmS0lNAwLMDn3m998fuKsioThepU2FEUadwicmgMHggSiTKJsNNc8 UGHU77PL0VJi1ANfKep6CI5rEuxhx4Or106sZ3S1F6XOxJAkkvj6tu/vfIz+YWbiCb2GQiiDF60 tRNsqt4lNGm6qJZb2TDCensJLEN1zMBWvLAA== X-Received: by 2002:a05:600c:4ec6:b0:490:c2a3:3303 with SMTP id 5b1f17b1804b1-49233430b4dmr14621755e9.34.1781641618726; Tue, 16 Jun 2026 13:26:58 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.26.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:26:58 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:22 +0300 Subject: [PATCH RFC v4 02/12] dt-bindings: clk: zte: Add zx297520v3 matrix clock and reset bindings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-2-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=10152; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=5Z4ESOVeKBRM0YFOt39SoxPXZhq0x1sOAoH1jrCCjuQ=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGZ3Pvb1vAq2QAxdCQPA8eAkCflR7CQUt1b bR1Tnva0UuJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiIDkw/9EcbUbRCCHOEqijrZntbfrjBdM3qtngx A9apGk3oJQpChnZrsYoCBhDM96phrgdola5U1Hi8wnyMKDe2H9dwdlRUmttVQRTdT++PMBvNhop CU/F7bcY4oxRCI4mJxYx+rPcVn0bt8EbNDFk21cEVT+MFbSLj0xWeldYxRVQOWi9E9E3IqeOy0D vx9SbWI4WX7T8AtN/Ao2d7kQGqIkvZlK1cr1myjCULarE2VjxZwe/89tMWjElRtvSEeEk3C8xYJ qIlTd0BArhtPwfvqKKs5Mbk54ExKvNyL9Xam70zXAUcRhExuAkiVotn8+8j76E91hzO7FLqiKhC LKny5xHEw35WZ6M68D2G3pncDExnvDJtahbLvNFWbD7XDAjqd3j57HZDvggkH+f1hVrP1Pjk6ic rk8tS6OvVxoktiVwNi/ihjEutXTGJ4GKkpsbiMD803fc5H9g8a0cVFFVyMitPCphFszx2rgH+Cs XCG1w4BjEogN7qKk2d4hMvSQMYbRQ/KqwZtoZldwp5qFC9plkc9PcBSwz1SBS56eqOyMFWX00Yv rgIA7ooSt0DMlcxRQv+9Pm6derKpubHqgi7Rm+dEpmcQjBKWjaXj27UulXfT58OVSpUJTsIPCqn 5OFFnU5E+Ce6sptyO5Ejabyh/yppJFjlOpbO7ybk6Jm6OWbNFSnM= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 I split matrixclk into its own controller again because syscon/regmap deals poorly with device nodes that have more than one memory region. As a consequence I am passing all PLL outputs generated on Topclk down to Matrixclk. The syscon is used to generate the regmap shared between the clock and auxiliary reset drivers. The register space also contains at least one extra block of functionality, hardware spinlocks, that I expect will be necessary to communicate correctly with the LTE DSP firmware blob. Signed-off-by: Stefan D=C3=B6singer --- .../bindings/clock/zte,zx297520v3-matrixclk.yaml | 180 +++++++++++++++++= ++++ include/dt-bindings/clock/zte,zx297520v3-clk.h | 45 ++++++ 2 files changed, 225 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixc= lk.yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixclk.= yaml new file mode 100644 index 000000000000..4363ed9be76f --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-matrixclk.yaml @@ -0,0 +1,180 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-matrixclk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC matrix clock and reset controller + +maintainers: + - Stefan D=C3=B6singer + +description: | + This controller controls high speed devices on the zx297520v3 board: The= CPU, + RAM, SDIO and Ethernet clocks and resets are found here. This controller + requires PLL-generated clocks from Topclk as well as the fixed 26 MHz an= d 32 + KHz oscillators found on this board. + + Other helper controls are found on this hardware too: It contains a mail= box + interface to read RAM properties and hardware spinlock registers. + + All available clocks are defined as preprocessor macros in the + 'dt-bindings/clock/zte,zx297520v3-clk.h' header. + +properties: + compatible: + items: + - const: zte,zx297520v3-matrixclk + - const: syscon + + reg: + maxItems: 1 + + clocks: + items: + - description: 26 MHz external oscillator + - description: 32 KHz external oscillator + - description: Main PLL output from topclk (usually 624 MHz) + - description: Main PLL subdivision factor 2 + - description: Main PLL subdivision factor 3 + - description: Main PLL subdivision factor 4 + - description: Main PLL subdivision factor 5 + - description: Main PLL subdivision factor 6 + - description: Main PLL subdivision factor 8 + - description: Main PLL subdivision factor 12 + - description: Main PLL subdivision factor 16 + - description: Main PLL subdivision factor 26 + - description: Upll output from topclk (Usually 480 MHz) + - description: Upll subdivision factor 2 + - description: Upll subdivision factor 3 + - description: Upll subdivision factor 4 + - description: Upll subdivision factor 5 + - description: Upll subdivision factor 6 + - description: Upll subdivision factor 8 + - description: Upll subdivision factor 12 + - description: Upll subdivision factor 16 + - description: Dpll output from topclk (usually 492.88 MHz) + - description: Dpll subdivision factor 2 + - description: Dpll subdivision factor 3 + - description: Dpll subdivision factor 4 + - description: Dpll subdivision factor 5 + - description: Dpll subdivision factor 6 + - description: Dpll subdivision factor 8 + - description: Dpll subdivision factor 12 + - description: Dpll subdivision factor 16 + - description: Gpll output from topclk (usually 200 MHz) + - description: Gpll subdivision factor 2 + - description: Gpll subdivision factor 3 + - description: Gpll subdivision factor 4 + - description: Gpll subdivision factor 5 + - description: Gpll subdivision factor 6 + - description: Gpll subdivision factor 8 + - description: Gpll subdivision factor 12 + - description: Gpll subdivision factor 16 + + clock-names: + items: + - const: osc26m + - const: osc32k + - const: mpll + - const: mpll_d2 + - const: mpll_d3 + - const: mpll_d4 + - const: mpll_d5 + - const: mpll_d6 + - const: mpll_d8 + - const: mpll_d12 + - const: mpll_d16 + - const: mpll_d26 + - const: upll + - const: upll_d2 + - const: upll_d3 + - const: upll_d4 + - const: upll_d5 + - const: upll_d6 + - const: upll_d8 + - const: upll_d12 + - const: upll_d16 + - const: dpll + - const: dpll_d2 + - const: dpll_d3 + - const: dpll_d4 + - const: dpll_d5 + - const: dpll_d6 + - const: dpll_d8 + - const: dpll_d12 + - const: dpll_d16 + - const: gpll + - const: gpll_d2 + - const: gpll_d3 + - const: gpll_d4 + - const: gpll_d5 + - const: gpll_d6 + - const: gpll_d8 + - const: gpll_d12 + - const: gpll_d16 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + topclk: clock-controller@13b000 { + compatible =3D "zte,zx297520v3-topclk", "syscon"; + reg =3D <0x0013b000 0x400>; + clocks =3D <&osc26m>, <&osc32k>; + clock-names =3D "osc26m", "osc32k"; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + }; + + clock-controller@1306000 { + compatible =3D "zte,zx297520v3-matrixclk", "syscon"; + reg =3D <0x01306000 0x400>; + clocks =3D <&osc26m>, <&osc32k>, + <&topclk ZX297520V3_MPLL>, <&topclk ZX297520V3_MPLL_D2>, + <&topclk ZX297520V3_MPLL_D3>, <&topclk ZX297520V3_MPLL_D4= >, + <&topclk ZX297520V3_MPLL_D5>, <&topclk ZX297520V3_MPLL_D6= >, + <&topclk ZX297520V3_MPLL_D8>, <&topclk ZX297520V3_MPLL_D1= 2>, + <&topclk ZX297520V3_MPLL_D16>, <&topclk ZX297520V3_MPLL_D= 26>, + <&topclk ZX297520V3_UPLL>, <&topclk ZX297520V3_UPLL_D2>, + <&topclk ZX297520V3_UPLL_D3>, <&topclk ZX297520V3_UPLL_D4= >, + <&topclk ZX297520V3_UPLL_D5>, <&topclk ZX297520V3_UPLL_D6= >, + <&topclk ZX297520V3_UPLL_D8>, <&topclk ZX297520V3_UPLL_D1= 2>, + <&topclk ZX297520V3_UPLL_D16>, + <&topclk ZX297520V3_DPLL>, <&topclk ZX297520V3_DPLL_D2>, + <&topclk ZX297520V3_DPLL_D3>, <&topclk ZX297520V3_DPLL_D4= >, + <&topclk ZX297520V3_DPLL_D5>, <&topclk ZX297520V3_DPLL_D6= >, + <&topclk ZX297520V3_DPLL_D8>, <&topclk ZX297520V3_DPLL_D1= 2>, + <&topclk ZX297520V3_DPLL_D16>, + <&topclk ZX297520V3_GPLL>, <&topclk ZX297520V3_GPLL_D2>, + <&topclk ZX297520V3_GPLL_D3>, <&topclk ZX297520V3_GPLL_D4= >, + <&topclk ZX297520V3_GPLL_D5>, <&topclk ZX297520V3_GPLL_D6= >, + <&topclk ZX297520V3_GPLL_D8>, <&topclk ZX297520V3_GPLL_D1= 2>, + <&topclk ZX297520V3_GPLL_D16>; + clock-names =3D "osc26m", "osc32k", "mpll", "mpll_d2", "mpll_d3", + "mpll_d4", "mpll_d5", "mpll_d6", "mpll_d8", "mpll_d1= 2", + "mpll_d16", "mpll_d26", "upll", "upll_d2", "upll_d3", + "upll_d4", "upll_d5", "upll_d6", "upll_d8", "upll_d1= 2", + "upll_d16", "dpll", "dpll_d2", "dpll_d3", "dpll_d4", + "dpll_d5", "dpll_d6", "dpll_d8", "dpll_d12", "dpll_d= 16", + "gpll", "gpll_d2", "gpll_d3", "gpll_d4", "gpll_d5", + "gpll_d6", "gpll_d8", "gpll_d12", "gpll_d16"; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + }; diff --git a/include/dt-bindings/clock/zte,zx297520v3-clk.h b/include/dt-bi= ndings/clock/zte,zx297520v3-clk.h index cf436ff20dfe..815e8ceeb64e 100644 --- a/include/dt-bindings/clock/zte,zx297520v3-clk.h +++ b/include/dt-bindings/clock/zte,zx297520v3-clk.h @@ -115,4 +115,49 @@ #define ZX297520V3_USB_RESET 18 #define ZX297520V3_HSIC_RESET 19 =20 +#define ZX297520V3_CPU_WCLK 1 +#define ZX297520V3_CPU_PCLK 2 +#define ZX297520V3_ZSP_WCLK 3 +#define ZX297520V3_EDCP_WCLK 4 +#define ZX297520V3_EDCP_PCLK 5 +#define ZX297520V3_SD0_WCLK 6 +#define ZX297520V3_SD0_PCLK 7 +#define ZX297520V3_SD0_CDET 8 +#define ZX297520V3_SD1_WCLK 9 +#define ZX297520V3_SD1_PCLK 10 +#define ZX297520V3_SD1_CDET 11 +#define ZX297520V3_NAND_WCLK 12 +#define ZX297520V3_NAND_PCLK 13 +#define ZX297520V3_DMA_PCLK 14 +#define ZX297520V3_MBOX_PCLK 15 +#define ZX297520V3_PDCFG_WCLK 16 +#define ZX297520V3_PDCFG_PCLK 17 +#define ZX297520V3_SSC_WCLK 18 +#define ZX297520V3_SSC_PCLK 19 +#define ZX297520V3_GMAC_WCLK 20 +#define ZX297520V3_GMAC_PCLK 21 +#define ZX297520V3_GMAC_AHB 22 +#define ZX297520V3_VOU_WCLK 23 +#define ZX297520V3_VOU_PCLK 24 +#define ZX297520V3_LSP_MPLL_D5_WCLK 25 +#define ZX297520V3_LSP_MPLL_D4_WCLK 26 +#define ZX297520V3_LSP_MPLL_D6_WCLK 27 +#define ZX297520V3_LSP_MPLL_D8_WCLK 28 +#define ZX297520V3_LSP_MPLL_D12_WCLK 29 +#define ZX297520V3_LSP_OSC26M_WCLK 30 +#define ZX297520V3_LSP_OSC32K_WCLK 31 +#define ZX297520V3_LSP_PCLK 32 +#define ZX297520V3_LSP_TDM_WCLK 33 +#define ZX297520V3_LSP_DPLL_D4_WCLK 34 + +#define ZX297520V3_CPU_RESET 0 +#define ZX297520V3_EDCP_RESET 1 +#define ZX297520V3_SD0_RESET 2 +#define ZX297520V3_SD1_RESET 3 +#define ZX297520V3_NAND_RESET 4 +#define ZX297520V3_PDCFG_RESET 5 +#define ZX297520V3_SSC_RESET 6 +#define ZX297520V3_GMAC_RESET 7 +#define ZX297520V3_VOU_RESET 8 + #endif /* __DT_BINDINGS_CLOCK_ZX297520V3_H */ --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84355393DE0 for ; Tue, 16 Jun 2026 20:27:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641626; cv=none; b=oSbyijHoYbapnNHXdNbxMHp0wcWrWHU0u6yNu5NsJASfGslkRjLVxcw1mlanerAJu2A2xAGVI/KQ6BkDQY8fT0RXOCzFew/Ixk++VF7mG0d39NKGW4WllwZnvMlHgCBXjkipMcKsLTkGpoaKIfO6+MCVlqbMTytxKTkROxvCBJg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641626; c=relaxed/simple; bh=uRtL3tXTNxFSsXIeunxk1WnL31X8l1JDXBwiyONwhLk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jDtc7Kk2cKv5pDM994wqHUNYp5V/oM0I54Q6HoEB1oKmZaKki9t6u3eqspkm0D5xEnX8m4MVMA67MDBkk6smCn6mMuA7s7HR6V7Ck+ekTUt7qfccdUbJSdFDw4kLfWHbQPcVRGdwmpAwfQKseior+95gillNzJ2DqatqU1P25gg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=neWfC2aZ; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="neWfC2aZ" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-492329c5514so1256185e9.1 for ; Tue, 16 Jun 2026 13:27:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641623; x=1782246423; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=N1Y7VWEFPR+VTtT3NJmqQWRzBo4PZWm5r9ohgpgGtBQ=; b=neWfC2aZgrMwuB8RMzxNEqfLRGqUw8YVrLaBf1LyGupbqQ0zhi5XaIRbNiZREN2Aw4 1ZmES0mECfcx23Hd5Q37JpSHsLMT0eMfGr5XSbwozNzMAFUI6cEleCLocQWDsnX+Kzao +UCxQb1xkId3cdFLtTmBQq99zvXAJAmFM6TBXw5/gLY5u5DDXFX1C5PKNBpQGskYRk5C vX+uULpkKfSQY3NeZb1vAHfe/9SO07hA3IPUaEpcKXB1QsnKUTKgR7eJIPW/67X6vkXs CNSaELz3MVf/cFN1LjPilKxNP8vaLiNcPlRhtFhnUyT5qKM26nOXl/yniouBVuTrDrZa lybQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641623; x=1782246423; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=N1Y7VWEFPR+VTtT3NJmqQWRzBo4PZWm5r9ohgpgGtBQ=; b=UIv7T+lFNloL47y1RTaOSyXdAQp2QZpngjUDjnu208qtAaMz3KeQdqbtDS/nc2jnCw E7Z9FoIM+0ptFYmg4515HK4O+6PtnAjyIrNU1Y7tLcOFaI0fFVp8OwTNeDl8GEPXxVvY Vdtmb8DAsM1XuCRJW3/+7/jQlgULZS1B3L9QSOuxrpI18+Uolh3WOjSLx83S6rK0Ey8k eyKh7mNwhQyyxkINi0YCrh4vKfPLnby5PYwW1vSfbT9rZMr1CiW0C13S/ZI6qyynb1rp IacqaaV6oAbGb2oxG0CK+BEJouD2MoyvKGVpREp62uRZm72tCe6LL+gnoFfzDZf6oIOy Ephw== X-Forwarded-Encrypted: i=1; AFNElJ+qsUE32/8Mx4Qfeyrhkdn8MlRyLu+4jIMlmeL8c+/VcqdBz/TvOPaPW3KnxRsiQ0UbwyIOSeKQ7gLq+mI=@vger.kernel.org X-Gm-Message-State: AOJu0YztczgMpBnc5ljYaFSdvmjvHpB31HP6p8oKNz3mLbJjIoAxvpOF qE+zvP+WpoOtTzOyBaCr/qldO7HO/oljTT+28Sk/hcabIzqXXVx2P03t X-Gm-Gg: Acq92OGAmD/SFqERWN4rrlmHJCZCS4j3EZYK6I4HRVzPdVMTjCvmiVkZua+mimIN5d3 D+SSXaeWTDhQo0A4Ec3On0GCTPnKmOx06yln+XupXD2+QplgHSprlqeZDzPB9MIJoKPIagL4zdY Dp7K6w5PhEaTG3/EOFYzGO54niiHautmfSVDYn5ea2+XzE5RUjzW2rmdCZHbXvqHFOSLw6uJyo+ EN7phP6k3hfp3lyW437p00FsBd40y82CcXJdjtVnsKs2NizKDEEcq8xkONHGkxQxm+p9h+vYycc W3CMgWuU53ohHI26zft3EOHOnYDxk/I4xSD1qZ5SPompqGwGZqDPMaKMYGK6ouDrtnuiyPEakMJ zufL8NEqPPCYiNXCVAr81vW+NQ0pwGfCGwttumhzMZirmOXAOyzMag0tJzX1Mi/LNDdaq6FsUri Ag7yIXEBd+aHVz4r/iuXouV22T9Cn2RoTKfxzvFYImNheF X-Received: by 2002:a05:600c:c178:b0:490:c1cb:48f4 with SMTP id 5b1f17b1804b1-492340e76camr3368855e9.12.1781641622717; Tue, 16 Jun 2026 13:27:02 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.26.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:02 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:23 +0300 Subject: [PATCH RFC v4 03/12] dt-bindings: clk: zte: Add zx297520v3 LSP clock and reset bindings Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-3-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9172; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=uRtL3tXTNxFSsXIeunxk1WnL31X8l1JDXBwiyONwhLk=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGnvcq6tfQFw4fbpiGVAhHG8grApZMUdDUI rdKTTUDY4SJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiLy7w//Vn8KOlR9kFU4wiu7vQgPoLA+Jj3qoY4 reoGxqevBcOKtJql+ac2AaQNrfLncREb7f7rnAVegOpGWpPMxvcQaY5mVjSqAUlCW8wuuSa9ev3 3qMRCu2eD2UX1zY46nbjLz04qC3mzSmF16yS9NNDBavCZLNUdjDlwpo8bByLihq/C4h9Kjz2eYc MG0wNJs+P2pyevflaKATcGtqOA8omDd3K6UkDvTerSisOSPLoNwogBT5qYn7nOIE2ErOuHxCY+6 OMDyIn8yEVY2jjI0bq3RwhjoLKWlH/tWczF4RueWV4YQFl6TXptPKaDDA+nqEtIXuiB+VJI1ChT T4+AurmnAe7WiaWUpDUCGIsFdDDrZjU35G6NZazAPnZkHxNY7YYQHCAOJe525sGQ54ecbZTjsom K0Jxr3QneEnDe+U7000SR7YOVazl6LM3NAxBj072N7+JT1XzXR/rkeqV06yNcAyZQBD+mCk0JHm ompM/+C6mHQ6ao6Mv4KAhtgByy7WaFA2fEYvpdsQ+37mPttUMxjmA6qka8FwmApZyKvZwHgg9kQ GIkI6LZZGoO/Vg6HMxOZMeinL3B9Hi1H/1uFeFUzNGmiCyS8xPeNly3LqEc53an+FCm2IdRm7X4 9RQirwQhe6s/zq3y/lLE4rC1PGoRLhW1mr8OosRjDbJnMcCXBVdI= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 The clock controller of the Low Speed Peripherals is relatively clean. One register per device with gates, muxes and resets and for some devices a divider. There are even bits in the top controller to control propagation of clock lines down to LSP. The clocks are sorted by register address and I am convinced that the device list is complete. There are however a few more registers that are likely helper controls for the I2S and TDM devices. Signed-off-by: Stefan D=C3=B6singer --- Patch changelog: v5: Order properties compatible->reg->clocks->clock->names->#cells --- .../bindings/clock/zte,zx297520v3-lspclk.yaml | 130 +++++++++++++++++= ++++ include/dt-bindings/clock/zte,zx297520v3-clk.h | 56 +++++++++ 2 files changed, 186 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspclk.= yaml b/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspclk.yaml new file mode 100644 index 000000000000..096295edb6e2 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/zte,zx297520v3-lspclk.yaml @@ -0,0 +1,130 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/zte,zx297520v3-lspclk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ZTE zx297520v3 SoC LSP clock and reset controller + +maintainers: + - Stefan D=C3=B6singer + +description: | + This clock and reset controller controls low speed peripherals on the bo= ard. + This is a relatively isolated subsystem containing UART, I2C, I2S and SPI + devices. The clock controller is responsible for bringing the devices ou= t of + reset and enabling their clocks as needed. + + The controller receives its clock signal from the matrix controller and = need + to be declared as clock inputs. + + All available clocks are defined as preprocessor macros in the + 'dt-bindings/clock/zte,zx297520v3-clk.h' header. + +properties: + compatible: + const: zte,zx297520v3-lspclk + + reg: + maxItems: 1 + + clocks: + items: + - description: Main PLL divided by 5 output from matrixclk (124.8 MH= z) + - description: Main PLL divided by 4 output from matrixclk (156 MHz) + - description: Main PLL divided by 6 output from matrixclk (104 MHz) + - description: Main PLL divided by 8 output from matrixclk (78 MHz) + - description: Main PLL divided by 12 output from matrixclk (52 MHz) + - description: Main oscillator output from matrixclk (26 MHz) + - description: Timer oscillator output from matrixclk (32 KHz) + - description: LSP pclk output from matrixclk (26 MHz) + - description: TDM wclk mux output from matrixclk + - description: DPLL divided by 4 output from matrixclk (122.88 MHz) + + clock-names: + items: + - const: mpll_d5 + - const: mpll_d4 + - const: mpll_d6 + - const: mpll_d8 + - const: mpll_d12 + - const: osc26m + - const: osc32k + - const: pclk + - const: tdm_wclk + - const: dpll_d4 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + matrixclk: clock-controller@1306000 { + compatible =3D "zte,zx297520v3-matrixclk", "syscon"; + reg =3D <0x01306000 0x400>; + clocks =3D <&osc26m>, <&osc32k>, + <&topclk ZX297520V3_MPLL>, <&topclk ZX297520V3_MPLL_D2>, + <&topclk ZX297520V3_MPLL_D3>, <&topclk ZX297520V3_MPLL_D4= >, + <&topclk ZX297520V3_MPLL_D5>, <&topclk ZX297520V3_MPLL_D6= >, + <&topclk ZX297520V3_MPLL_D8>, <&topclk ZX297520V3_MPLL_D1= 2>, + <&topclk ZX297520V3_MPLL_D16>, <&topclk ZX297520V3_MPLL_D= 26>, + <&topclk ZX297520V3_UPLL>, <&topclk ZX297520V3_UPLL_D2>, + <&topclk ZX297520V3_UPLL_D3>, <&topclk ZX297520V3_UPLL_D4= >, + <&topclk ZX297520V3_UPLL_D5>, <&topclk ZX297520V3_UPLL_D6= >, + <&topclk ZX297520V3_UPLL_D8>, <&topclk ZX297520V3_UPLL_D1= 2>, + <&topclk ZX297520V3_UPLL_D16>, + <&topclk ZX297520V3_DPLL>, <&topclk ZX297520V3_DPLL_D2>, + <&topclk ZX297520V3_DPLL_D3>, <&topclk ZX297520V3_DPLL_D4= >, + <&topclk ZX297520V3_DPLL_D5>, <&topclk ZX297520V3_DPLL_D6= >, + <&topclk ZX297520V3_DPLL_D8>, <&topclk ZX297520V3_DPLL_D1= 2>, + <&topclk ZX297520V3_DPLL_D16>, + <&topclk ZX297520V3_GPLL>, <&topclk ZX297520V3_GPLL_D2>, + <&topclk ZX297520V3_GPLL_D3>, <&topclk ZX297520V3_GPLL_D4= >, + <&topclk ZX297520V3_GPLL_D5>, <&topclk ZX297520V3_GPLL_D6= >, + <&topclk ZX297520V3_GPLL_D8>, <&topclk ZX297520V3_GPLL_D1= 2>, + <&topclk ZX297520V3_GPLL_D16>; + clock-names =3D "osc26m", "osc32k", "mpll", "mpll_d2", "mpll_d3", + "mpll_d4", "mpll_d5", "mpll_d6", "mpll_d8", "mpll_d1= 2", + "mpll_d16", "mpll_d26", "upll", "upll_d2", "upll_d3", + "upll_d4", "upll_d5", "upll_d6", "upll_d8", "upll_d1= 2", + "upll_d16", "dpll", "dpll_d2", "dpll_d3", "dpll_d4", + "dpll_d5", "dpll_d6", "dpll_d8", "dpll_d12", "dpll_d= 16", + "gpll", "gpll_d2", "gpll_d3", "gpll_d4", "gpll_d5", + "gpll_d6", "gpll_d8", "gpll_d12", "gpll_d16"; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + }; + + clock-controller@1400000 { + compatible =3D "zte,zx297520v3-lspclk"; + reg =3D <0x01400000 0x100>; + clocks =3D <&matrixclk ZX297520V3_LSP_MPLL_D5_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D4_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D6_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D8_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D12_WCLK>, + <&matrixclk ZX297520V3_LSP_OSC26M_WCLK>, + <&matrixclk ZX297520V3_LSP_OSC32K_WCLK>, + <&matrixclk ZX297520V3_LSP_PCLK>, + <&matrixclk ZX297520V3_LSP_TDM_WCLK>, + <&matrixclk ZX297520V3_LSP_DPLL_D4_WCLK>; + clock-names =3D "mpll_d5", "mpll_d4", "mpll_d6", "mpll_d8", "mpll_= d12", + "osc26m", "osc32k", "pclk", "tdm_wclk", "dpll_d4"; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + }; diff --git a/include/dt-bindings/clock/zte,zx297520v3-clk.h b/include/dt-bi= ndings/clock/zte,zx297520v3-clk.h index 815e8ceeb64e..57387529a708 100644 --- a/include/dt-bindings/clock/zte,zx297520v3-clk.h +++ b/include/dt-bindings/clock/zte,zx297520v3-clk.h @@ -160,4 +160,60 @@ #define ZX297520V3_GMAC_RESET 7 #define ZX297520V3_VOU_RESET 8 =20 +#define ZX297520V3_TIMER_L1_WCLK 1 +#define ZX297520V3_TIMER_L1_PCLK 2 +#define ZX297520V3_WDT_L2_WCLK 3 +#define ZX297520V3_WDT_L2_PCLK 4 +#define ZX297520V3_WDT_L3_WCLK 5 +#define ZX297520V3_WDT_L3_PCLK 6 +#define ZX297520V3_PWM_WCLK 7 +#define ZX297520V3_PWM_PCLK 8 +#define ZX297520V3_I2S0_WCLK 9 +#define ZX297520V3_I2S0_PCLK 10 +#define ZX297520V3_I2S1_WCLK 11 +#define ZX297520V3_I2S1_PCLK 12 +#define ZX297520V3_QSPI_WCLK 13 +#define ZX297520V3_QSPI_PCLK 14 +#define ZX297520V3_UART1_WCLK 15 +#define ZX297520V3_UART1_PCLK 16 +#define ZX297520V3_I2C1_WCLK 17 +#define ZX297520V3_I2C1_PCLK 18 +#define ZX297520V3_SPI0_WCLK 19 +#define ZX297520V3_SPI0_PCLK 20 +#define ZX297520V3_TIMER_LB_WCLK 21 +#define ZX297520V3_TIMER_LB_PCLK 22 +#define ZX297520V3_TIMER_LC_WCLK 23 +#define ZX297520V3_TIMER_LC_PCLK 24 +#define ZX297520V3_UART2_WCLK 25 +#define ZX297520V3_UART2_PCLK 26 +#define ZX297520V3_WDT_LE_WCLK 27 +#define ZX297520V3_WDT_LE_PCLK 28 +#define ZX297520V3_TIMER_LF_WCLK 29 +#define ZX297520V3_TIMER_LF_PCLK 30 +#define ZX297520V3_SPI1_WCLK 31 +#define ZX297520V3_SPI1_PCLK 32 +#define ZX297520V3_TIMER_L11_WCLK 33 +#define ZX297520V3_TIMER_L11_PCLK 34 +#define ZX297520V3_TDM_WCLK 35 +#define ZX297520V3_TDM_PCLK 36 + +#define ZX297520V3_TIMER_L1_RESET 0 +#define ZX297520V3_WDT_L2_RESET 1 +#define ZX297520V3_WDT_L3_RESET 2 +#define ZX297520V3_PWM_RESET 3 +#define ZX297520V3_I2S0_RESET 4 +#define ZX297520V3_I2S1_RESET 5 +#define ZX297520V3_QSPI_RESET 6 +#define ZX297520V3_UART1_RESET 7 +#define ZX297520V3_I2C1_RESET 8 +#define ZX297520V3_SPI0_RESET 9 +#define ZX297520V3_TIMER_LB_RESET 10 +#define ZX297520V3_TIMER_LC_RESET 11 +#define ZX297520V3_UART2_RESET 12 +#define ZX297520V3_WDT_LE_RESET 13 +#define ZX297520V3_TIMER_LF_RESET 14 +#define ZX297520V3_SPI1_RESET 15 +#define ZX297520V3_TIMER_L11_RESET 16 +#define ZX297520V3_TDM_RESET 17 + #endif /* __DT_BINDINGS_CLOCK_ZX297520V3_H */ --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B8F22392829 for ; Tue, 16 Jun 2026 20:27:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641631; cv=none; b=Pw/QHvmnLMxzNWXgIkF54nNNU2zH/HnZD2ZXQwz4kzQnHWfGEpv828edv2J0wO+lXdzWajGyeoYBHOi0z8ez9ri6Je4H50HeMPPFLReAr4iuvCAHGzIRLRFcFh0dyUDL8iywO9FuttiEImWn++bwJSmumaRzyZj3fZt//86f/bs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641631; c=relaxed/simple; bh=qum6l8+tCrrqR02yHwh3t4yH0w6TRVXfiZs3oZFSBbY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Si3WMtWTzQ/ycg0tyfbBAStWJK/xlzYajdSqNgup6xMysr7Pqkew5PbcI/oT9FBXoH/QrEXtA4p8saUTNfRAbNhu7C3k55kklS9mo+hJXNKmagpZR9ehV4Qe7D/UBNUurNTOGsdWQ2Xu4ngIDs7KUYO0PCsV5+XsGH0JL4xOjwo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=rQNMKkw8; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="rQNMKkw8" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-491b390f9e9so42441105e9.0 for ; Tue, 16 Jun 2026 13:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641627; x=1782246427; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=NXBv0LTahcDV/Iaq6s1n4lHcOX1JeaCaC/1W6Jb31AA=; b=rQNMKkw85CF3QiFCl9TOwTXKjzHrxC4qKkg/vnxdEhzgBUhTsOI1ddtzKNh75P6xMN OZL91FL5+doMeTe+aL2at1TbkGv9uhugj73qGdwryVgj/Wn8kW/yBlkH4FwlqcvsGCTy pKd9fAAVmYBMFdViiWUgBZh0Vgxenrd9vnoCUqVENALbbgO4g2epJMwSqhC0ts5rcmXk DVWcL70CoVjEXY08QpKhukagFDPZmVkGisowfM6Czg7UsdgcCvufyldEDnKtKK+kdvBi /TytnNsaxcHMPyTal9ekgKqJm8CQk3q6aCehJIyGqcVY8DPmWBixLu6n8vA1Fm6SQNeH Nj7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641627; x=1782246427; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=NXBv0LTahcDV/Iaq6s1n4lHcOX1JeaCaC/1W6Jb31AA=; b=CjcoiZE9FgH/4s6qyijdbj4cRfqyqAjYUaa5TY1gu9KIUXFR4LnLQ13YQUESpdMio7 ZeIxuJSlXKEmXrSQxYKHAkE5tP5+GfH5r33qohzTwrKkIDrZMyK6e1nNggX8JWLovxxK URyvuJ+f97fS9C7qvmts94luvYnClUH75hDdk6qKwRx3gLYNG8HnNlN6JGO7OFi+QBj0 FlU8LMZiJeZyrouoznSzK3XoGQGJ8gzt4bWBPNqedFEur1vF+Y6utZ5yMEc9PkoxWAV9 HM+Y+nxMQutEt2MAj/5klyI8FBs5+kkG5vrovVZpFeSTJZPwgG7H/YTAz1NPWGw712IO R3JA== X-Forwarded-Encrypted: i=1; AFNElJ//ZzgB2yJILKi9N9Rrw/NVqQJINuPz43kleaaT1AMfput9XT6g26dEVDN9pnNAxk7CX9sNGKcnxWlzW4Y=@vger.kernel.org X-Gm-Message-State: AOJu0Yw2uLotDlBT2KRJJXz+t9hvF/fz8tlxytWaVQsEdSgZfbXtCSaK dk3qeVvBmuR/FxN8BR6aMjfhlHxM1X+tq6+C8IT723Lgie+LxUBV9ZWj X-Gm-Gg: Acq92OHylT3t7SJlxt8GhM+5nEgtc3IKcXEclplOUUiKgEpLcRhdFDpJqYul0swh9DK r6lsnX/wLzMmDTSvsxUIioXgOfnocfRDrS0MXiXFEVHxFiykuXptYHvUHOEh3DadX6721M5LKIp p2EQQAbwm5y/daFxbiGFVZN1htaZFugeOu7sXQB7AnDxup8qEkh0dcvkDVgsWmU3SWuMK+9K+wA OJ3wcNDim4BylqK1Sg4Bul8v/n1tQWQyzVt/q9+GXW1Y7SNJntDs+RLlSOeuBOZqoGw/banHpo3 fTui0HThGYGrratAxwLZS8QRF7rMYwZO02Dd88Vyv4v7q+lJJeDCmrxVeDEhvUjSTkntc8cScaW bHoc5ysu0g6c8K2/7fPd5fiEyBcAn42ruZNjbtWfzkTvL5rZYpPEY7nxRZKxkHpfshAkt1vThbi V8VUdqzafBn7neEil06SKOj9H9AtaAVz7lxQ== X-Received: by 2002:a05:600c:a104:b0:490:958f:2a5e with SMTP id 5b1f17b1804b1-492333ab197mr15140435e9.13.1781641626827; Tue, 16 Jun 2026 13:27:06 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:06 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:24 +0300 Subject: [PATCH RFC v4 04/12] clk: zte: Add Clock registration infrastructure. Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-4-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11496; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=qum6l8+tCrrqR02yHwh3t4yH0w6TRVXfiZs3oZFSBbY=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGvZqzCIpbWjYc5d7M1aNl2DjTTdzYR2Kq2 ig8adoeMGKJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiKEKBAAoyvFxBhwoWKuc9d5nb7HQWGArjoDaAy 98GoacliWT6n/v5nS8F9r5cRNcr9UL/inhK80tv3dMtprYK4SWA9QHbIPlbGOWx9riFjf157yYj hnK5ynhEbEO3KmzasZAboD92Ee3cgljkUNXGw/Am9C9Ray7lO3GunuFgyGuE3bf2l8efMkJQz04 1dj0yJ0c6PzM8+7kFLS+SDrKUfGcR+fwFg2ej1eni8vUCBfdEYLLyCVKpiiqN1e2FeOzPhIUnIy T2Sr5ro82ik4vmkiaQM9F+iVdaiBQAi2V+5ouCL0DK/9oiMkWT0RZjl7LiFfv/IYZBaJMomjJ/2 OUQ+pSsl9n3O9PYcSVmCFaiN6T5ddKAcgT3tw6/r7dMZjrCe83zZzjVYaxg1p5JhwLuBSuhEowr XdtZfykGXdKmPICd7mSUXS1eK1Mr2zvqHyWZXfRqzgBmxru0YCuF3gNB+JbYckTjVt5yqQBRXB1 9HMRge3gJ82G2Qqn5D1lJLqxvMUHpC8B7MizSeTU4FRj5Os4nTlZ/BJ6+4d1vP7BEP5hIoBIM5z au+2P4sBmZCoPaR+2WbKtRleLuiZ8hNk4hwAbYGdSqb/cSY2xtvf/XziAlAxqmCS8wufNexys4w bomTXjdrfQhL+1lwANc3j/hUGSP1+3JpQMz2bWeOzsIGtM/I1QvU= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 The next patches will implement the regmap clocks and PLL driver. The actual hardware specific clock listing will live in a separate module. Signed-off-by: Stefan D=C3=B6singer --- MAINTAINERS | 1 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/zte/Kconfig | 17 +++++ drivers/clk/zte/Makefile | 5 ++ drivers/clk/zte/clk-regmap.c | 30 +++++++++ drivers/clk/zte/clk-zx.c | 157 +++++++++++++++++++++++++++++++++++++++= ++++ drivers/clk/zte/clk-zx.h | 79 ++++++++++++++++++++++ drivers/clk/zte/pll-zx.c | 19 ++++++ 9 files changed, 310 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0cc1ede3c80c..f1f0459b2c72 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3870,6 +3870,7 @@ F: Documentation/devicetree/bindings/arm/zte.yaml F: Documentation/devicetree/zte,zx297520v3-* F: arch/arm/boot/dts/zte/ F: arch/arm/mach-zte/ +F: drivers/clk/zte/ F: include/dt-bindings/clock/zte,zx297520v3-clk.h =20 ARM/ZYNQ ARCHITECTURE diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 1717ce75a907..6f0a863951ca 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -545,6 +545,7 @@ source "drivers/clk/uniphier/Kconfig" source "drivers/clk/visconti/Kconfig" source "drivers/clk/x86/Kconfig" source "drivers/clk/xilinx/Kconfig" +source "drivers/clk/zte/Kconfig" source "drivers/clk/zynqmp/Kconfig" =20 # Kunit test cases diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index cc108a75a900..13a5478f1112 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -167,5 +167,6 @@ ifeq ($(CONFIG_COMMON_CLK), y) obj-$(CONFIG_X86) +=3D x86/ endif obj-y +=3D xilinx/ +obj-$(CONFIG_COMMON_CLK_ZTE) +=3D zte/ obj-$(CONFIG_ARCH_ZYNQ) +=3D zynq/ obj-$(CONFIG_COMMON_CLK_ZYNQMP) +=3D zynqmp/ diff --git a/drivers/clk/zte/Kconfig b/drivers/clk/zte/Kconfig new file mode 100644 index 000000000000..b7b65a2172a9 --- /dev/null +++ b/drivers/clk/zte/Kconfig @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# ZTE Clock Drivers +# + +config COMMON_CLK_ZTE + tristate "Clock driver for ZTE SoCs" + depends on ARCH_ZTE || COMPILE_TEST + default ARCH_ZTE + select AUXILIARY_BUS + select MFD_SYSCON + help + This option selects common clock infrastructure for ZTE based SoCs. + You will need to enable one or more SoC specific drivers to make use + of this. + + Enable this if you are building a kernel for a ZTE designed board. diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile new file mode 100644 index 000000000000..27db07293165 --- /dev/null +++ b/drivers/clk/zte/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_COMMON_CLK_ZTE) +=3D clk-zte.o + +clk-zte-y +=3D clk-zx.o pll-zx.o clk-regmap.o diff --git a/drivers/clk/zte/clk-regmap.c b/drivers/clk/zte/clk-regmap.c new file mode 100644 index 000000000000..7908f1562f63 --- /dev/null +++ b/drivers/clk/zte/clk-regmap.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2014 MediaTek Inc. + * Copyright (c) 2018 BayLibre, SAS. + * Copyright (c) 2026 Stefan D=C3=B6singer. + * Author: Stefan D=C3=B6singer + */ + +#include "clk-zx.h" + +int zx_clk_register_gates(struct device *dev, struct regmap *regmap, + const struct zx_gate_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks) +{ + return -ENODEV; +} + +int zx_clk_register_dividers(struct device *dev, struct regmap *regmap, + const struct zx_div_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks) +{ + return -ENODEV; +} + +int zx_clk_register_muxes(struct device *dev, struct regmap *regmap, + const struct zx_mux_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks) +{ + return -ENODEV; +} diff --git a/drivers/clk/zte/clk-zx.c b/drivers/clk/zte/clk-zx.c new file mode 100644 index 000000000000..6e21c4a82a46 --- /dev/null +++ b/drivers/clk/zte/clk-zx.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan D=C3=B6singer + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +static void zx_adev_release(struct device *dev) +{ + dev_info(dev, "Aux device released.\n"); +} + +static void zx_adev_unregister(void *data) +{ + struct auxiliary_device *adev =3D data; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +int zx_clk_probe(struct platform_device *pdev) +{ + unsigned int public_clk_count =3D 1, highest_id =3D 0; + struct clk_hw_onecell_data *clocks; + struct device *dev =3D &pdev->dev; + const struct zx_clk_data *data; + struct auxiliary_device *adev; + struct regmap *map; + struct clk *clk; + unsigned int i; + int res; + + data =3D device_get_match_data(dev); + if (!data) + return -EINVAL; + + map =3D device_node_to_regmap(dev->of_node); + if (!map) + return -EINVAL; + + for (i =3D 0; i < data->num_plls; ++i) { + if (data->plls[i].id) { + unsigned int last_idx =3D data->plls[i].id + data->plls[i].num_postdivs= - 1; + + if (last_idx > highest_id) + highest_id =3D last_idx; + public_clk_count +=3D data->plls[i].num_postdivs; + } + } + for (i =3D 0; i < data->num_muxes; ++i) { + if (data->muxes[i].id) { + if (data->muxes[i].id > highest_id) + highest_id =3D data->muxes[i].id; + public_clk_count++; + } + } + for (i =3D 0; i < data->num_divs; ++i) { + if (data->divs[i].id) { + if (data->divs[i].id > highest_id) + highest_id =3D data->divs[i].id; + public_clk_count++; + } + } + for (i =3D 0; i < data->num_gates; ++i) { + if (data->gates[i].id) { + if (data->gates[i].id > highest_id) + highest_id =3D data->gates[i].id; + public_clk_count++; + } + } + + if (WARN_ON(public_clk_count !=3D highest_id + 1)) + return -EINVAL; + + clocks =3D devm_kzalloc(dev, struct_size(clocks, hws, public_clk_count), = GFP_KERNEL); + if (!clocks) + return -ENOMEM; + clocks->num =3D public_clk_count; + + for (i =3D 0; i < data->num_inputs_enable; ++i) { + clk =3D devm_clk_get_enabled(dev, data->inputs_enable[i]); + if (IS_ERR(clk)) { + return dev_err_probe(dev, PTR_ERR(clk), "Input clk %s failure\n", + data->inputs_enable[i]); + } + } + for (i =3D 0; i < data->num_inputs; ++i) { + clk =3D devm_clk_get(dev, data->inputs[i]); + if (IS_ERR(clk)) { + return dev_err_probe(dev, PTR_ERR(clk), "Input clk %s failure\n", + data->inputs[i]); + } + } + + res =3D zx_clk_register_plls(dev, map, data->plls, data->num_plls, clocks= ); + if (res) + return res; + + res =3D zx_clk_register_muxes(dev, map, data->muxes, data->num_muxes, clo= cks); + if (res) + return res; + + res =3D zx_clk_register_dividers(dev, map, data->divs, data->num_divs, cl= ocks); + if (res) + return res; + + res =3D zx_clk_register_gates(dev, map, data->gates, data->num_gates, clo= cks); + if (res) + return res; + + /* This is to catch holes in the tables rather than registration errors. = The count vs + * highest ID should catch most static issues. This check here will trigg= er if an ID is + * reused by accident. + */ + for (i =3D 1; i < public_clk_count; i++) { + if (WARN(!clocks->hws[i], "Clock %u not registered\n", i)) + return -EINVAL; + } + + res =3D devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clocks); + if (res) + return res; + + adev =3D devm_kzalloc(dev, sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + adev->name =3D data->reset_auxdev_name; + adev->dev.parent =3D dev; + adev->dev.release =3D zx_adev_release; + adev->dev.of_node =3D dev->of_node; + + res =3D auxiliary_device_init(adev); + if (res) + return dev_err_probe(dev, res, "Failed to init aux dev %s\n", adev->name= ); + + res =3D auxiliary_device_add(adev); + if (res) { + auxiliary_device_uninit(adev); + return dev_err_probe(dev, res, "Failed to add aux dev %s\n", adev->name); + } + + return devm_add_action_or_reset(dev, zx_adev_unregister, adev); +} +EXPORT_SYMBOL_NS_GPL(zx_clk_probe, "ZTE_CLK"); + +MODULE_AUTHOR("Stefan D=C3=B6singer "); +MODULE_DESCRIPTION("ZTE common clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/zte/clk-zx.h b/drivers/clk/zte/clk-zx.h new file mode 100644 index 000000000000..b39bbed2d420 --- /dev/null +++ b/drivers/clk/zte/clk-zx.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2026 Stefan D=C3=B6singer + */ + +#ifndef __DRV_CLK_ZX_H +#define __DRV_CLK_ZX_H + +#include +#include +#include + +struct zx_pll_desc { + unsigned int id; + const char *name; + const char * const *parents; + unsigned int num_parents; + unsigned long rate; + const unsigned int *postdivs; + unsigned int num_postdivs; + u16 reg; +}; + +struct zx_mux_desc { + unsigned int id; + const char *name; + const char * const *parents; + unsigned int num_parents; + u16 reg; + u8 shift, size; +}; + +struct zx_div_desc { + unsigned int id; + const char *name, *parent; + u16 reg; + u8 shift, size; +}; + +struct zx_gate_desc { + unsigned int id; + const char *name, *parent; + unsigned long flags; + u16 reg; + u8 shift; +}; + +int zx_clk_register_plls(struct device *dev, struct regmap *regmap, + const struct zx_pll_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks); +int zx_clk_register_muxes(struct device *dev, struct regmap *regmap, + const struct zx_mux_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks); +int zx_clk_register_dividers(struct device *dev, struct regmap *regmap, + const struct zx_div_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks); +int zx_clk_register_gates(struct device *dev, struct regmap *regmap, + const struct zx_gate_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks); + +struct zx_clk_data { + const char * const *inputs_enable; + unsigned int num_inputs_enable; + const char * const *inputs; + unsigned int num_inputs; + const struct zx_pll_desc *plls; + unsigned int num_plls; + const struct zx_mux_desc *muxes; + unsigned int num_muxes; + const struct zx_div_desc *divs; + unsigned int num_divs; + const struct zx_gate_desc *gates; + unsigned int num_gates; + const char *reset_auxdev_name; +}; + +int zx_clk_probe(struct platform_device *pdev); + +#endif /* __DRV_CLK_ZX_H */ diff --git a/drivers/clk/zte/pll-zx.c b/drivers/clk/zte/pll-zx.c new file mode 100644 index 000000000000..c0475d5441fb --- /dev/null +++ b/drivers/clk/zte/pll-zx.c @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan D=C3=B6singer + */ +#include +#include +#include +#include +#include +#include + +#include "clk-zx.h" + +int zx_clk_register_plls(struct device *dev, struct regmap *regmap, + const struct zx_pll_desc *desc, unsigned int num, + struct clk_hw_onecell_data *clocks) +{ + return -ENODEV; +} --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA41139524D for ; Tue, 16 Jun 2026 20:27:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641634; cv=none; b=pCWV7DiR8vnQSvNBjOsngaIqzyTEau+7vUnwI/5O6IcTfLGdXs2bmxM8jg/XivHwEDPXZ0SZBX91vCJawOqs4TfYf6ks+mzf/w0jmBOtmge5c36eLwEbeJl3kyFSn6kNulaiYdxCJx1n2GYEkqYLy3/gss8wzxQNbQUC9ZNjRVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641634; c=relaxed/simple; bh=QvJqbnmyH7U9QmsybN/X5wmIg/pXjxmut/gzJGyFBPA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Kt3PC4UGimMkFUOE4WrIy02C0GGI61PXadt5X8kj9yvP7L7MKLV7xvmcc9fRzfOhFdTA/HzA+YEKiXpR5RjKD7zS0vlZz8n68RbXWvuZJyT1rVhRM8X3cSzfPotLpmYB3O3sPIg9mhQkSaG9mGhoOdjN7oPXj6DGINMxrc7czxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JwFe7bkQ; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JwFe7bkQ" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-490b7866869so50918875e9.2 for ; Tue, 16 Jun 2026 13:27:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641631; x=1782246431; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=SEwUQa58tkGmULKISnU/FYNMvt7II1Uk9U7eRXMejuo=; b=JwFe7bkQ5HXYKiQpFudr9TLCL4/SqcmhMLitqO+DnfPAHd+kbbXy7QIlOjAivsJo1n vsM2bvBYxvBXxB410kMRkX9i86Hzh7vCRQp8cYt2aeozz6p/xT0eNMW6dpIMkuM1QTQ3 P7pQSsvTX5ij0pLaFTOocJ4jzixxVIGYS3+5rqjdKIbahb4QEDJALxqB5Sr1hJJ2OqUN 0iXcDNsd58Sa+kqcRRgRdr4t+VXWOALp0mM3/h6c+oBvxoe3bYeG/pK2eFvLIKe28Axp frNyxBIVVSjHnvDavbWsf0n4ovhGE7y+PKr9XmC4RhvxVrKP68VfsM00awMQ2GttwDFi jYzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641631; x=1782246431; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=SEwUQa58tkGmULKISnU/FYNMvt7II1Uk9U7eRXMejuo=; b=dDqMj2o2OGAPIaoF2zcnux2bSjcKkJpQjOtE5PbQJCAlYu8pZ2bt6OJCguU4iwnMev udRVPHKJbrh7lBkYsSWFfGZmciq8Y1i+bI30poBj5OBSODQQ8VB3AnfTKENF9QL99Ni0 cjiLZgVWgiJz7GFGIPwsZsYIvCndybQ2KxkSv322esqBSTyORwdT1og5ZM3abb7Y/57r TRzm8mbCwQKXFq3FgmTRPwuUokATjPNw01ktPXr+0R1MGAZNmUpQs0dX/XxZ4ztdaH1N 7fMkFxHiAf6qREP2s3N9COXM+AVMPOsCS/NAEKrpkKN3Z8fdY+uZgUx+QtMkVb03iY+5 A7DA== X-Forwarded-Encrypted: i=1; AFNElJ/Ns640PKheB2loKdzxTiT91SPMCkXpQJkxYcZKEo8QRciYutR8ojeU6vlZMMaVD4LUt5Y31qHyzfyqUPI=@vger.kernel.org X-Gm-Message-State: AOJu0Yw0+4DpuE7CWOIsAUjCQSkvlv+YqkPx70MmtKSEdY19Bok7nx9t fzCOoBmhmB5x0c8/RD1cmYqttd716UMw72Y1Ve6RbdqCZK4ah3ps+c1R X-Gm-Gg: Acq92OFmhJo2a3l4WBSL4sKfWCGlyQSvtXWBrw5zYy0LFsKw08OYS+YApc0eOSPq2uv O4Y6V31RYa96deDt8eADi5sqcIBsXSiL7BHQFDPoQij2HtMmXF9txWIgJW4yakFPombpyrRVTWY x/OeqjD8q79hW5VF2mhGGz89K7Ldw3ncqa6o1jC2PiLdx7vmTg5g/AXwNyM7jHbggsWPfGqchH1 dXrk6TjxUbUFByxrpxo7XsAosU7t7Ur9+lwp4aYTn1byIDMVy+bL35EEodTd3cLQsrYoz1GWpEW TKZQTfNF6/libEOIC3LTfAKb3vhD38Nc4OkrFvS+BXSG2uiZZ1De0DkIy8IKv/fp+a0g6l9h+pE ogD6+ZKNZ0G3pokNpIy/JVyfotKfKr9w5+U2ZZYH0PqW1wM3T6zkKiec8kUwDUN7RwOum/1efKp 7CdArjwh+DYplzDeukmhxhtmuSGiV86RyRIg== X-Received: by 2002:a05:600c:1389:b0:490:d3ef:fa4a with SMTP id 5b1f17b1804b1-49234105541mr3228625e9.14.1781641630807; Tue, 16 Jun 2026 13:27:10 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:10 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:25 +0300 Subject: [PATCH RFC v4 05/12] clk: zte: Add zx PLL support infrastructure Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-5-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=17665; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=QvJqbnmyH7U9QmsybN/X5wmIg/pXjxmut/gzJGyFBPA=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGgIvrq3kMyrg33JoYf3fWOABQTqJJ3zAn1 vW5L417Mi6JAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiK1rBAAmiED7LDGgJOvxN0xsN0JTQEtVlQrYb3 9Y2YFdJ8GQqFx/WGqXMVgMYJ0e9JzLIbyf+xW60NPtgdIObfOXiWf/ne7YS8MJA211Hmuk+23hD SspCL2Q24q5zA9Uxw8H0LaPs2C3q5tFMZfbSpnQPflv6CFyezJdCbRcIaVQlv4UewUFn+Esdi09 ZtTU/pnzgWdF4oFkogzr9cYJbsNArJ6gihmsgw+YPeLine0iyS/V+zC2TtptVKKqx6+2B4i/9yV KjIbTPPppqsKr+mkkXx94fKeEXgmTBXibq4mvgi9CK6QONfauuGfXxSXV/R+YzOppH+eJC/rTnw p8OZn0RFq/EjUA53mpA4UKtT/c0Lwvr50fvONOJrb9y88pVJFSbDxbhn5SbpvYEORXngWBffjCm 5+QnlUeixXXzC3M1XKXDE+8MyjFPQX4Pta7/l+7GIttlXYyeI8NOvYLFNQJXYzMcUgokY/iHva4 XDaVEZ/732YFXCCFbcXHkQsnj2fJtcbbHUAcnf3shMYbKB9NbExXj//XaT+z3L1eJyPKoWwlaDH GPlcZgHlfR5f/BXYa8P6Oxkyjrh/d+gG66926TkuQaSZQXoN1NezFd8sRGy7KDdPFzDfKhwsuYh L3Gx4UYHp/FoiRBPF+U+YiMunDRoW/GIJHJMq3uYCVlvuYpATLwM= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 I am guessing how much of this is reusable among other zx chips or even differently named ZTE platforms (if there are any). From reading the old zx2967 code, I think the PLL code would be reusable there, maybe with platform specific bitmasks but otherwise the same logic. Signed-off-by: Stefan D=C3=B6singer --- drivers/clk/zte/pll-zx.c | 460 +++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 459 insertions(+), 1 deletion(-) diff --git a/drivers/clk/zte/pll-zx.c b/drivers/clk/zte/pll-zx.c index c0475d5441fb..f077b6b56841 100644 --- a/drivers/clk/zte/pll-zx.c +++ b/drivers/clk/zte/pll-zx.c @@ -11,9 +11,467 @@ =20 #include "clk-zx.h" =20 +/* This code has only been tested with zx297520v3 PLLs, but from reading t= he zx296718 clock code it + * looks like PLL registers are similar. ZTE's sources explain the PLL reg= ister contents only in a + * .cmm file (A Lauterback TRACE32 script) and some unused headers in thei= r U-Boot code dump, which + * may not be accurate. When calculating the frequencies from the default = PLL configuration the + * results match the fixed rate clocks from their clock driver. + * + * The 26mhz and 32khz clocks can be easily observed with the timers. The = 104mhz output can be + * observed through the UART. One 122.88 PLL can be observed through the T= DM device. All others can + * only be indirectly infered, e.g. by comparing CPU speed or SDIO transfe= r rate between the fixed + * 26 MHz oscillator and the provided PLL frequency. + * + * The formula to calculate the clock is ((ref / refdiv) * fbdiv) / postdi= v1 / postdiv2. The masks + * are given below. There are a few control flags: + * + * Bit 31: Disables the PLL, but passes the reference through unmodified. = If POSTDIV_OUT_DISABLE + * still matters is different between PLLs. + * Bit 30: Returns if the PLL is locked + * Bit 29: Not named in ZTE's code, but can be set. There is no obvious im= pact. Lock times are + * unchanged, so it doesn't influence or bypass lock detection. It= doesn't raise any IRQs or + * influence GPIOs. + * Bit 27: Given its name it likely disables the Delta-Sigma Modulator, if= one exists at all. The + * boot ROM sets it on every PLL. Unsetting it marginally decrease= s the time it takes to + * lock to the reference clock (from ~400us to ~300us). Regardless= of this bit I could not + * make the supposed fractional part in register 2 work. + * Bit 24: Bypasses the VCO, but still applies refdiv and postdiv. Doesn't= matter if PLL_DISABLE=3D1. + */ + +#define ZX29_PLL_DISABLE BIT(31) +#define ZX29_PLL_LOCKED BIT(30) +#define ZX29_PLL_LOCK_FILTER BIT(29) +#define ZX29_PLL_DSM_DISABLE BIT(27) +#define ZX29_PLL_PARENT_MASK GENMASK(26, 25) +#define ZX29_PLL_PARENT_SHIFT 25 +#define ZX29_PLL_BYPASS BIT(24) +#define ZX29_PLL_REFDIV_MASK GENMASK(23, 18) +#define ZX29_PLL_REFDIV_SHIFT 18 +#define ZX29_PLL_FBDIV_MASK GENMASK(17, 6) +#define ZX29_PLL_FBDIV_SHIFT 6 +#define ZX29_PLL_POSTDIV1_MASK GENMASK(5, 3) +#define ZX29_PLL_POSTDIV1_SHIFT 3 +#define ZX29_PLL_POSTDIV2_MASK GENMASK(2, 0) +#define ZX29_PLL_POSTDIV2_SHIFT 0 + +/* The second register is supposed to have another 24 bit value that gets = added to fbdiv but it is + * always 0 in the preconfigured values. I could not observe any effect fr= om setting it to something + * other than 0, regardless of the DSM disable bit. It is possible that it= is only supported by + * dpll, which is a possible parent for i2s. + * + * Bits 28:25 contain more flags: + * + * Bit 27: Setting ZX29_PLL_DACAP slows down the lock time and obivates th= e speed gained from + * !DSM_DISABLE. No other effect observed. + * + * Bit 26: ZX29_PLL_4PHASE_OUT_DISABLE is set on some PLLs on boot but not= on others. It is set on + * boot on mpll and upll, but not gpll, dpll or unknownpll. I am n= ot sure what it does + * either. The SDIO devices break if they are fed from gpll with t= his flag set, but they + * work ok if they are fed from mpll without this flag set. + * + * Bit 25: ZX29_PLL_POSTDIV_OUT_DISABLE seems to disable the PLL output en= tirely. Whether it is + * bypassed by PLL_DISABLE differs between PLLs. gpll still produc= es an output clock if + * PLL_DISABLE =3D 1 and POSTDIV_DISABLE =3D 1, but produces no ou= tput if PLL_DISABLE =3D 0 and + * POSTDIV_DISABLE =3D 1. The dpll feeder ("unknownpll") at 0x100 = produces no output clock + * if both PLL_DISABLE and POSTDIV_DISABLE are set to 1. + * + * Bit 24: ZX29_PLL_VCO_OUT_DISABLE probably disables the output of the VC= O clock without + * post-VCO-dividers, but the raw VCO output is not a possible par= ent of any consumer clock, + * so I could not confirm this. It does not disable the VCO entir= ely - that's what + * PLL_DISABLE does. + * + * A spinlock should not be needed. PLLs don't share their registers with = anything else and the + * global prepare mutex and enable spinlock should be enough. Beware of co= nflicts in reg2 between + * POSTDIV_OUT_DISABLE and the fractional value in case you find out how f= ractional dividers work + * and add support for them. + */ +#define ZX29_PLL_REG2_OFFSET 4 +#define ZX29_PLL_DACAP BIT(27) +#define ZX29_PLL_4PHASE_OUT_DISABLE BIT(26) +#define ZX29_PLL_POSTDIV_OUT_DISABLE BIT(25) +#define ZX29_PLL_VCO_OUT_DISABLE BIT(24) + +/* The VCO's frequency range is limited. The stock settings run the VCO be= tween 960 and 1248 MHz. + * Ad-hoc testing with gpll suggests that at least this PLL remains stable= down to about 7 MHz and + * up to 2 GHz and produces a clock that can be used by the SDIO controlle= r. Attempting to run the + * mpll VCO at 624 MHz and setting postdiv1 =3D postdiv2 =3D 1 - which sho= uld result in the same output + * frequency - or running it at 1872 MHz with an effective post divider of= 3 crashes the CPU. Most + * likely the PLLs become unstable outside their core range and the SDIO c= ontroller is much more + * forgiving than CPU and DRAM are. + */ +#define ZX29_PLL_VCO_MAX_FREQ (1300*HZ_PER_MHZ) +#define ZX29_PLL_VCO_MIN_FREQ (900*HZ_PER_MHZ) + +struct zx29_clk_pll { + struct clk_hw hw; + struct device *dev; + struct regmap *map; + unsigned long init_rate; + u16 reg; +}; + +static inline struct zx29_clk_pll *to_zx29_clk_pll(struct clk_hw *hw) +{ + return container_of(hw, struct zx29_clk_pll, hw); +} + +static int zx29_pll_is_prepared(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + int res; + + res =3D regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_prepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + u32 val; + int res; + + res =3D regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); + if (res < 0) + return res; + + /* Lock duration is usually between 300us to 500us */ + res =3D regmap_read_poll_timeout(pll->map, pll->reg, val, val & ZX29_PLL_= LOCKED, 50, 2000); + dev_dbg(pll->dev, "%s: Enable result %u val 0x%08x\n", clk_hw_get_name(&p= ll->hw), res, val); + return res; +} + +static void zx29_pll_unprepare(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg, ZX29_PLL_DISABLE); +} + +static int zx29_pll_is_enabled(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + int res; + + res =3D regmap_test_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + if (res < 0) + return res; + + return !res; +} + +static int zx29_pll_enable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + + return regmap_clear_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static void zx29_pll_disable(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + + regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); +} + +static unsigned long zx29_pll_get_rate(const struct zx29_clk_pll *pll, uns= igned long parent_rate, + u32 setting) +{ + unsigned long refdiv, fbdiv, postdiv1, postdiv2, freq; + const char *name =3D clk_hw_get_name(&pll->hw); + u64 vco; + + refdiv =3D (setting & ZX29_PLL_REFDIV_MASK) >> ZX29_PLL_REFDIV_SHIFT; + fbdiv =3D (setting & ZX29_PLL_FBDIV_MASK) >> ZX29_PLL_FBDIV_SHIFT; + postdiv1 =3D (setting & ZX29_PLL_POSTDIV1_MASK) >> ZX29_PLL_POSTDIV1_SHIF= T; + postdiv2 =3D (setting & ZX29_PLL_POSTDIV2_MASK) >> ZX29_PLL_POSTDIV2_SHIF= T; + dev_dbg(pll->dev, "%s: reference clock %lu HZ, PLL setting 0x%08x\n", + name, parent_rate, setting); + + if (!refdiv || !postdiv1 || !postdiv2) { + dev_err(pll->dev, "%s: divide by zero (%lu, %lu, %lu)\n", name, refdiv, = postdiv1, + postdiv2); + return 0; + } + + vco =3D div_u64((u64)parent_rate * fbdiv, refdiv); + freq =3D div_u64(div_u64(vco, postdiv1), postdiv2); + dev_dbg(pll->dev, "%s: refdiv %lu fbdiv %lu\n", name, refdiv, fbdiv); + dev_dbg(pll->dev, "%s: postdiv1 %lu postdiv2 %lu\n", name, postdiv1, post= div2); + + dev_dbg(pll->dev, "%s: %lu MHZ\n", name, freq / HZ_PER_MHZ); + + return freq; +} + +static unsigned long zx29_pll_recalc_rate(struct clk_hw *hw, unsigned long= parent_rate) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + u32 val; + int res; + + res =3D regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return res; + + return zx29_pll_get_rate(pll, parent_rate, val); +} + +static u32 zx29_pll_calc_values(const struct zx29_clk_pll *pll, unsigned l= ong parent_rate, + unsigned long rate) +{ + const unsigned int postdiv1_max =3D (1 << hweight32(ZX29_PLL_POSTDIV1_MAS= K)) - 1; + const unsigned int postdiv2_max =3D (1 << hweight32(ZX29_PLL_POSTDIV2_MAS= K)) - 1; + unsigned long fbdiv, refdiv, best_fbdiv =3D 0, best_refdiv =3D 0; + u32 postdiv1 =3D 0, postdiv2 =3D 0, i, j, setting; + const char *name =3D clk_hw_get_name(&pll->hw); + long best =3D LONG_MAX; + + /* This code produces the same VCO settings that the boot loader and stoc= k firmware use for + * the standard frequencies. It has seen only very little manual testing = beyond that. + * + * The goal is to find a VCO setting that gets us as close as possible to= the desired output + * rate, while being within the VCO's operating limits and achievable wit= h the input value + * range. It is iterating over possible post-VCO diver values (1-7)*(1-7)= to look for valid + * VCO target frequencies and then looks for refdiv and fbdiv values to a= chieve the VCO + * frequency from the reference frequency. + */ + for (j =3D 1; j <=3D postdiv2_max; j++) { + for (i =3D 1; i <=3D postdiv1_max; i++) { + u64 vco =3D (u64)rate * i * j; + long out; + + if (vco > ZX29_PLL_VCO_MAX_FREQ || vco < ZX29_PLL_VCO_MIN_FREQ) + continue; + + rational_best_approximation(vco, parent_rate, + (1 << hweight32(ZX29_PLL_FBDIV_MASK)) - 1, + (1 << hweight32(ZX29_PLL_REFDIV_MASK)) - 1, + &fbdiv, &refdiv); + setting =3D fbdiv << ZX29_PLL_FBDIV_SHIFT; + setting |=3D refdiv << ZX29_PLL_REFDIV_SHIFT; + setting |=3D i << ZX29_PLL_POSTDIV1_SHIFT; + setting |=3D j << ZX29_PLL_POSTDIV2_SHIFT; + out =3D zx29_pll_get_rate(pll, parent_rate, setting); + + if (abs(out - rate) > best) + continue; + + if (abs(out - rate) < best) { + postdiv1 =3D i; + postdiv2 =3D j; + best_fbdiv =3D fbdiv; + best_refdiv =3D refdiv; + best =3D abs(out - rate); + + if (!best) + goto search_done; + } + } + } +search_done: + + if (!postdiv1) { + dev_err(pll->dev, "Did not find a setting for %lu Hz, parent %lu Hz\n", + rate, parent_rate); + return 0; + } + + dev_dbg(pll->dev, "%s: parent rate %lu\n", name, parent_rate); + dev_dbg(pll->dev, "%s: found VCO dividers %u and %u\n", name, postdiv1, p= ostdiv2); + dev_dbg(pll->dev, "%s: VCO target rate %lu\n", name, rate * postdiv1 * po= stdiv2); + + dev_dbg(pll->dev, "%s: Got fbdiv =3D %lu refdiv =3D %lu\n", name, best_fb= div, best_refdiv); + + setting =3D best_fbdiv << ZX29_PLL_FBDIV_SHIFT; + setting |=3D best_refdiv << ZX29_PLL_REFDIV_SHIFT; + setting |=3D postdiv1 << ZX29_PLL_POSTDIV1_SHIFT; + setting |=3D postdiv2 << ZX29_PLL_POSTDIV2_SHIFT; + dev_dbg(pll->dev, "%s: Final setting 0x%08x\n", name, setting); + + return setting; +} + +static int zx29_pll_determine_rate(struct clk_hw *hw, struct clk_rate_requ= est *req) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + unsigned long new_rate, parent_rate =3D clk_hw_get_rate(clk_hw_get_parent= (&pll->hw)); + u32 setting; + + setting =3D zx29_pll_calc_values(pll, parent_rate, req->rate); + if (!setting) + return -EINVAL; + + new_rate =3D zx29_pll_get_rate(pll, parent_rate, setting); + if (new_rate !=3D req->rate) { + dev_warn(pll->dev, "Did not find an exact match. Want %lu, got %lu\n", + req->rate, new_rate); + req->rate =3D new_rate; + } + + return 0; +} + +static int zx29_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + int res =3D -EINVAL; + u32 setting; + + setting =3D zx29_pll_calc_values(pll, parent_rate, rate); + if (zx29_pll_get_rate(pll, parent_rate, setting) =3D=3D rate) { + res =3D regmap_update_bits(pll->map, pll->reg, 0x00ffffff, setting); + dev_info(pll->dev, "%s: Setting rate: 0x%08x\n", clk_hw_get_name(hw), se= tting); + } + + return res; +} + +static u8 zx29_pll_get_parent(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + u32 val; + int res; + + res =3D regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return 0xff; + + val =3D (val & ZX29_PLL_PARENT_MASK) >> ZX29_PLL_PARENT_SHIFT; + dev_dbg(pll->dev, "%s: Parent 0x%x\n", clk_hw_get_name(hw), val); + + return val; +} + +static int zx29_pll_set_parent(struct clk_hw *hw, u8 index) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + u32 idx_shift =3D index << ZX29_PLL_PARENT_SHIFT; + int res; + u32 val; + + res =3D regmap_update_bits(pll->map, pll->reg, ZX29_PLL_PARENT_MASK, idx_= shift); + if (res < 0) + return res; + + res =3D regmap_read(pll->map, pll->reg, &val); + if (res < 0) + return res; + + if ((val & ZX29_PLL_PARENT_MASK) !=3D idx_shift) { + dev_err(pll->dev, "Hardware rejected PLL parent %u\n", index); + return -EINVAL; + } + return 0; +} + +static int zx29_pll_init(struct clk_hw *hw) +{ + struct zx29_clk_pll *pll =3D to_zx29_clk_pll(hw); + const char *name =3D clk_hw_get_name(hw); + int res; + + dev_dbg(pll->dev, "%s: initializing\n", name); + + /* Remove the bypass flag so we don't have to bother with it in enable/di= sable. I have + * never seen it set by the earlier boot stages anyhow. + */ + res =3D regmap_clear_bits(pll->map, pll->reg, ZX29_PLL_BYPASS); + if (res < 0) + return res; + + if (regmap_test_bits(pll->map, pll->reg, ZX29_PLL_DISABLE) > 0) { + if (pll->init_rate) { + dev_dbg(pll->dev, "%s: Setting to %lu Hz\n", name, pll->init_rate); + res =3D clk_set_rate(pll->hw.clk, pll->init_rate); + if (res) { + dev_err(pll->dev, "%s: Failed to set rate.\n", name); + return res; + } + } + + /* Set ZX29_PLL_POSTDIV_OUT_DISABLE for PLLs that have ZX29_PLL_DISABLE = for + * consistency with .enable and .prepare. This ensures that .prepare doe= sn't + * inadvertedly enable PLLs without .enable being called. + */ + res =3D regmap_set_bits(pll->map, pll->reg + ZX29_PLL_REG2_OFFSET, + ZX29_PLL_POSTDIV_OUT_DISABLE); + if (res < 0) + return res; + } + + return 0; +} + +const struct clk_ops zx29_pll_ops =3D { + .init =3D zx29_pll_init, + .is_prepared =3D zx29_pll_is_prepared, + .prepare =3D zx29_pll_prepare, + .unprepare =3D zx29_pll_unprepare, + .is_enabled =3D zx29_pll_is_enabled, + .enable =3D zx29_pll_enable, + .disable =3D zx29_pll_disable, + .recalc_rate =3D zx29_pll_recalc_rate, + .determine_rate =3D zx29_pll_determine_rate, + .get_parent =3D zx29_pll_get_parent, + .set_parent =3D zx29_pll_set_parent, + .set_rate =3D zx29_pll_set_rate, +}; + int zx_clk_register_plls(struct device *dev, struct regmap *regmap, const struct zx_pll_desc *desc, unsigned int num, struct clk_hw_onecell_data *clocks) { - return -ENODEV; + struct zx29_clk_pll *pll; + unsigned int i, f; + struct clk_hw *hw; + char plldiv[32]; + int res; + + for (i =3D 0; i < num; ++i) { + struct clk_init_data init =3D {}; + + pll =3D devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); + if (!pll) + return -ENOMEM; + + init.name =3D desc[i].name; + init.ops =3D &zx29_pll_ops; + init.parent_names =3D desc[i].parents; + init.num_parents =3D desc[i].num_parents; + pll->hw.init =3D &init; + pll->map =3D regmap; + pll->reg =3D desc[i].reg; + pll->init_rate =3D desc[i].rate; + + res =3D devm_clk_hw_register(dev, &pll->hw); + if (res) + return res; + if (desc[i].id && desc[i].postdivs && desc[i].postdivs[0] =3D=3D 1) + clocks->hws[desc[i].id] =3D &pll->hw; + + for (f =3D 0; f < desc[i].num_postdivs; ++f) { + if (desc[i].postdivs[f] =3D=3D 1) + continue; + + snprintf(plldiv, sizeof(plldiv), "%s_d%u", desc[i].name, + desc[i].postdivs[f]); + hw =3D devm_clk_hw_register_fixed_factor(dev, plldiv, desc[i].name, + 0, 1, desc[i].postdivs[f]); + if (IS_ERR(hw)) + return PTR_ERR(hw); + dev_dbg(pll->dev, "%s: %lu hz\n", clk_hw_get_name(hw), clk_hw_get_rate(= hw)); + + if (desc[i].id) + clocks->hws[desc[i].id + f] =3D hw; + } + } + + return 0; } --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7C8DC390CB7 for ; Tue, 16 Jun 2026 20:27:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641638; cv=none; b=nXWKywQYqGUO2N+DXunfWKs2BTXJVf/WkKZg0vpnnKeA9JnS1wTC+AR620O84lmz7zVJuwGvXR2eNdjEuQd9F7JCF9csN6R+uMIFmoZVGnW7S01TiANw65b4J7mrlNY3aGcel8FDZymkUNyF/XhRd4/MIw8POr7p0mQ8T7fiWEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641638; c=relaxed/simple; bh=wYgtHGRukfQ+uMOMTNkE7udfhe0qluyVy0T100d++n4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=f/fpax6p7tRt9EQoar29eHYy121lEMCBweyS1vw4XGLWe6XJrLgtcB0Ilk1lSoiRMUSlJBIYLs9kq/WAm273O/DgVOgxR1wVGZJ5eIUJ/pewixaYlu36HYJZqFOGMNK4J52bEbZtGqTjQgGOpChxM45PNNH+fBhTo7zAnTOoLKY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=sBxO7MK+; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sBxO7MK+" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4908b92904fso61479085e9.0 for ; Tue, 16 Jun 2026 13:27:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641635; x=1782246435; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=CGipdqLCxq5G0EmePkbO7V4LoprWK6DBkEcoR7sOMUQ=; b=sBxO7MK+iN7I3M16mXJoBtxpQIc4jqvyIAW59/CkcQMwADW+YDy0mcsq1T6dd98QNW pT/SkViSrb6cx/0eUihpz6FdIEQwXqTHS7awiuTFDIooX8ZTqNF9AYXHOoGGtlznpQCl ghZziH1AHoGfjX8kU5lGflHKS0wgDjPTUrP7pzX/jmnDOsg+hjb9AbcckR8uxWJoWADa 1ZFhPugzRg8K0n6aiIijETYFst9lAuOo1sjZ8pZVvPBAUjdB8ChVooIF0JdR1/gccWQ6 SGcLt08o2zJxkNOUhGRoSlJR8n7H9xeSB0wrosNFLUy7XUd5lN43Mn8PcHJKujdWciXS NP3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641635; x=1782246435; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=CGipdqLCxq5G0EmePkbO7V4LoprWK6DBkEcoR7sOMUQ=; b=euJdizrMqMG8IpMOd8pNbPjmyMWIBhYjRqntV7FgOmJkuUyx9y7Vagg2dt38AIV2AC 9kBKRlf/USeMs4NPAuCZklvGHJGtGHhzFjmeejs/RSyGdPO8NoKSXqlNRJUIYweQgmm0 /qWUs8Of1yuEguZxrffAqTFf438tr+2NU0Ye2+9zzSMVQnTQVQklW09NRzdQyAcct13j 9Yq7KN2Xg3Kv/S4rggju72Juyg+AvoGZAfR2DaX17AQHWLY61AEfxDzVAjqj8I0lgLOI SfRneavur8DQJrwHInFAhenu1oyoJlNywfsacEFKy13il2qTFWwKHuvJnBv8iB0D6aeO kZ4g== X-Forwarded-Encrypted: i=1; AFNElJ8GOh4KHnmSa7Ch9aK7fnnqEF7/wV/8FDO8Qxc7UzTQ1DeR8CSXE20nynTv+YWg1tUKbyPTp1Bn8Xce5wE=@vger.kernel.org X-Gm-Message-State: AOJu0YwMrnUqsBWlrf7tABWMGTJW6JbgzA+Dj+yEHbdOwRjFv7kTCZ73 BchU3Wzphgi1jFfhahLMS+b0AVyC/5ES5m8Cho90c+EQDFGpI9sP/Vc7 X-Gm-Gg: Acq92OGjw/BmHVVMXTwfoTRISCjE+V5916711NFigVNl4uO8y38DZveiZSGBJm7rzLX tpe7saQhdECRB+akFtNBBOD9YVY+pjATkfsHGnx5DlgpHJb8ir0l4BEzMkC/8GKzujcatoEkpx0 rhT+vpzmTvzBYO0EBVjDES6aPSEKa36SWyUKHNBkTwRpEzInBv7PaADKvmmBuMQPnDrppg0oxjB Qj8muvrX1TLfB2jYJIYAxlYEv7cA1/PcU9woasrt0ZEQ9sa/KUmy/SJNvTDJZVVzDIJAUV5b6+K WeJJZQOybP9ohXv5/SNO+ya+vfOAaV3AOeplywVFB9P+p2DZtJTqgJBFXUTrtguk2/gCPfNRR8L UzVFrmUIuwGgSsiUBNgIwycl6PABUPBqqI0J1NWjtAvn8aqI5TrDC4OPK1linto0AuCQLKR9VLt 9HB44Xcq7+qZvHEynoj0MyJSewWmJ/nJZixuTMqk7H9aNI X-Received: by 2002:a05:600c:c3ce:20b0:490:c682:e37d with SMTP id 5b1f17b1804b1-4923413c249mr1984505e9.32.1781641634917; Tue, 16 Jun 2026 13:27:14 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:14 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:26 +0300 Subject: [PATCH RFC v4 06/12] clk: zte: Add regmap based clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-6-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7393; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=wYgtHGRukfQ+uMOMTNkE7udfhe0qluyVy0T100d++n4=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGXar6sQjjyUXBAtw3LjbBqdR7RyhsyEnFt VfCX1LQt3OJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiKpbA//aKmOhY9N5dT2IVBCWEv7XQWgU/O0TjP HlG+KI3DCoTnN/nOpBdPrJWBU1FIVGNQGvvwt2BxGoUmcss7JggfoCxtP+fkZ+YaXKgFuiDIMYT FuOWMQo3gz8Jr8QTFgaKocsCtPBgWRckgFqEr7UxHWbYcrF1Zv4maJyq0XPQlCO4BmGeS0MMmWM UNI2IQsagnRBhgMZybTzz38CamhZ8IsHcqIDVE6Ta5YU8yo/Qj+7QomX1M2yIiDioTIlmCGqjt9 ppmVANKUzyfb5q+XWZhZCXzZJm2scbESYH6Zm4BusPf1lCtke2i0T2HTOCxPoSVH0gt4zxActKW F3HDeckj+6Bnyz85mGy0VpeJoWq1MHe8ct9pvMgrvI1387x7Y6LKMSJGEMamwZsoQN5iBg7ZgL/ hwtWztJlo/ZlsUrvKBQ9fkMkB5fzYI6pgCkfZrCfoRKOVQ/MkC+5Kv4ld28GM4cetbm8LMrwwpe wVWq5IGN+uaBncXKg70S/hsHDDt+N0wwj7zKZi4eWUBEa4UzxxhsC6S0WCvVVEqVdcJJUVZn2Uf ORi8iiw/92PkwJpu3g7wF7EhB1OWvDTWZ7XlWVdEZXxiGzdvcjuYPy76uVCDxa+pX/DtBIe4iW7 JqX79kd1OwqqjFsdAxrdmdxwZAhD9nTCuMdtToJaOxS+CLk6fpds= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This is based on meson/clk-regmap.c, although slightly simplified. I have kept the copyright lines at the top of the file to indicate its origin. I see that numerous clock drivers have their own incarnation of regmap based mux/div/gate clocks. If there is any version of it that is likely to be elevated to shared code liks clk-gate.c I'll copy that and try to use it as unmodified as possible. Signed-off-by: Stefan D=C3=B6singer --- drivers/clk/zte/clk-regmap.c | 223 +++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 220 insertions(+), 3 deletions(-) diff --git a/drivers/clk/zte/clk-regmap.c b/drivers/clk/zte/clk-regmap.c index 7908f1562f63..d9459417d17d 100644 --- a/drivers/clk/zte/clk-regmap.c +++ b/drivers/clk/zte/clk-regmap.c @@ -6,25 +6,242 @@ * Author: Stefan D=C3=B6singer */ =20 +#include +#include +#include + #include "clk-zx.h" =20 +struct zte_clk_regmap { + struct clk_hw hw; + struct regmap *map; + u16 reg; + u8 shift; + u8 size; +}; + +static inline struct zte_clk_regmap *to_zte_clk_regmap(struct clk_hw *hw) +{ + return container_of(hw, struct zte_clk_regmap, hw); +} + +static int zte_clk_regmap_gate_enable(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + + return regmap_set_bits(clk->map, clk->reg, BIT(clk->shift)); +} + +static void zte_clk_regmap_gate_disable(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + + regmap_clear_bits(clk->map, clk->reg, BIT(clk->shift)); +} + +static int zte_clk_regmap_gate_is_enabled(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + u32 val; + + regmap_read(clk->map, clk->reg, &val); + return !!val; +} + +static const struct clk_ops zte_clk_regmap_gate_ops =3D { + .enable =3D zte_clk_regmap_gate_enable, + .disable =3D zte_clk_regmap_gate_disable, + .is_enabled =3D zte_clk_regmap_gate_is_enabled, +}; + int zx_clk_register_gates(struct device *dev, struct regmap *regmap, const struct zx_gate_desc *desc, unsigned int num, struct clk_hw_onecell_data *clocks) { - return -ENODEV; + struct zte_clk_regmap *clk; + unsigned int i; + int res; + + for (i =3D 0; i < num; ++i) { + struct clk_init_data init =3D {}; + + clk =3D devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + + init.name =3D desc[i].name; + init.ops =3D &zte_clk_regmap_gate_ops; + init.parent_names =3D &desc[i].parent; + init.num_parents =3D 1; + init.flags =3D CLK_SET_RATE_PARENT | desc[i].flags; + clk->hw.init =3D &init; + clk->map =3D regmap; + clk->reg =3D desc[i].reg; + clk->shift =3D desc[i].shift; + clk->size =3D 1; + + res =3D devm_clk_hw_register(dev, &clk->hw); + if (res) + return dev_err_probe(dev, res, "Failed to register clk %s\n", desc[i].n= ame); + + if (desc[i].id) + clocks->hws[desc[i].id] =3D &clk->hw; + } + + return 0; +} + +static unsigned long zte_clk_regmap_div_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret =3D regmap_read(clk->map, clk->reg, &val); + if (ret) + /* Gives a hint that something is wrong */ + return 0; + + val >>=3D clk->shift; + val &=3D clk_div_mask(clk->size); + return divider_recalc_rate(hw, prate, val, NULL, 0, clk->size); } =20 +static int zte_clk_regmap_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + + return divider_determine_rate(hw, req, NULL, clk->size, 0); +} + +static int zte_clk_regmap_div_set_rate(struct clk_hw *hw, unsigned long ra= te, + unsigned long parent_rate) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret =3D divider_get_val(rate, parent_rate, NULL, clk->size, 0); + if (ret < 0) + return ret; + + val =3D (unsigned int)ret << clk->shift; + return regmap_update_bits(clk->map, clk->reg, clk_div_mask(clk->size) << = clk->shift, val); +}; + +static const struct clk_ops zte_clk_regmap_divider_ops =3D { + .recalc_rate =3D zte_clk_regmap_div_recalc_rate, + .determine_rate =3D zte_clk_regmap_div_determine_rate, + .set_rate =3D zte_clk_regmap_div_set_rate, +}; + int zx_clk_register_dividers(struct device *dev, struct regmap *regmap, const struct zx_div_desc *desc, unsigned int num, struct clk_hw_onecell_data *clocks) { - return -ENODEV; + struct zte_clk_regmap *clk; + unsigned int i; + int res; + + for (i =3D 0; i < num; ++i) { + struct clk_init_data init =3D {}; + + clk =3D devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + + init.name =3D desc[i].name; + init.ops =3D &zte_clk_regmap_divider_ops; + init.parent_names =3D &desc[i].parent; + init.num_parents =3D 1; + init.flags =3D CLK_SET_RATE_PARENT; + clk->hw.init =3D &init; + clk->map =3D regmap; + clk->reg =3D desc[i].reg; + clk->shift =3D desc[i].shift; + clk->size =3D desc[i].size; + + res =3D devm_clk_hw_register(dev, &clk->hw); + if (res) + return dev_err_probe(dev, res, "Failed to register clk %s\n", desc[i].n= ame); + + if (desc[i].id) + clocks->hws[desc[i].id] =3D &clk->hw; + } + + return 0; } =20 +static u8 zte_clk_regmap_mux_get_parent(struct clk_hw *hw) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + unsigned int val; + int ret; + + ret =3D regmap_read(clk->map, clk->reg, &val); + if (ret) + return 0xff; + + val >>=3D clk->shift; + val &=3D GENMASK(clk->size - 1, 0); + return clk_mux_val_to_index(hw, NULL, 0, val); +} + +static int zte_clk_regmap_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct zte_clk_regmap *clk =3D to_zte_clk_regmap(hw); + unsigned int val =3D clk_mux_index_to_val(NULL, 0, index); + + return regmap_update_bits(clk->map, clk->reg, + GENMASK(clk->size - 1, 0) << clk->shift, + val << clk->shift); +} + +static int zte_clk_regmap_mux_determine_rate(struct clk_hw *hw, struct clk= _rate_request *req) +{ + return clk_mux_determine_rate_flags(hw, req, 0); +} + +static const struct clk_ops zte_clk_regmap_mux_ops =3D { + .get_parent =3D zte_clk_regmap_mux_get_parent, + .set_parent =3D zte_clk_regmap_mux_set_parent, + .determine_rate =3D zte_clk_regmap_mux_determine_rate, +}; + int zx_clk_register_muxes(struct device *dev, struct regmap *regmap, const struct zx_mux_desc *desc, unsigned int num, struct clk_hw_onecell_data *clocks) { - return -ENODEV; + struct zte_clk_regmap *clk; + unsigned int i; + int res; + + for (i =3D 0; i < num; ++i) { + struct clk_init_data init =3D {}; + + clk =3D devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + + init.name =3D desc[i].name; + init.ops =3D &zte_clk_regmap_mux_ops; + init.parent_names =3D desc[i].parents; + init.num_parents =3D desc[i].num_parents; + clk->hw.init =3D &init; + clk->map =3D regmap; + clk->reg =3D desc[i].reg; + clk->shift =3D desc[i].shift; + clk->size =3D desc[i].size; + + res =3D devm_clk_hw_register(dev, &clk->hw); + if (res) + return dev_err_probe(dev, res, "Failed to register clk %s\n", desc[i].n= ame); + + if (desc[i].id) + clocks->hws[desc[i].id] =3D &clk->hw; + } + + return 0; } --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0BA6139524D for ; Tue, 16 Jun 2026 20:27:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641643; cv=none; b=jFkRZaEZ9JLRC3LGSETlXkQ56sTWN2ZSVWDRryTxaSn4tdMUyqFMGBfx4NNiNU0JRPGX059/TjbScMAETKsv6RTeCpT8KouwREdLLQ4wFyUQu99mGOk2dyP+e5WL967GtA49B6iWTXvx5J4z1fYMRACT5mUItz/sAQaYS7snHis= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641643; c=relaxed/simple; bh=rjIuDqYIiFiv2gumQf48MMHKoYVI7rxTGDOhoRAmUz0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OvpDX/wbLxFUWE4IeuaQOBc5KcMIooCJyrx5hD0e/ImgvY9GmlOw2sp8tLKXndkwgQBPKFsHmq2T95deudkhb5G5NlSMvHa3aIXhqKoFr70AUuMEMEAYAOA9vPwMwHxzDXVBSM9UITIK5BsUXonVW9xKHsE0zgHwRN2izOQJevA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A8/qjxYk; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A8/qjxYk" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4921e4dd62dso2254645e9.0 for ; Tue, 16 Jun 2026 13:27:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641639; x=1782246439; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=upbiqC+lK2g94yNc4VZoGQXV/ZRQi7zmokJItxzYO7M=; b=A8/qjxYkMVFNTIKOLkw698+GDstfeDx1E9u/Jenn6mz8zYCLssj6yl7bGq76lG0pNd nRRK9oXhXxU2hatXuRgGdTyQIMZZfPT9IxOmDpnZ9wSkA0PnzEgU0osMUnWA2tck0jIx Wx/Q0614w4IGGPRCQ9Cs6cDpfEIpMdbf0kuIFeuyr2Y/9g/uHbVZuXQuPtIYJFybUaAJ 4DA6ajf2ByRvyZ4y0A2LCH6CDhU6fg7R1B+Gy02QxnJsZFQlHoFPGCDcZzczahRc1Ilj I39MkXf46ABY/z+dz278/M9aulQcxNqK8z0SK6WRK0tX7EWILxniVI1vH6n4nCId1DUP Fm9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641639; x=1782246439; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=upbiqC+lK2g94yNc4VZoGQXV/ZRQi7zmokJItxzYO7M=; b=rSJCWY/evmc2TgH/YZwmUnjNGjwCOhHB2n6QbFs/rpH0FPWJRQ9OyiRxzspp1oYDeC sy2S2uIaf3iwCWOp8YQs5Ca+M7qcdgfkrNZfv7yleCeZBHTxXhUJ6ItGoul5bAOUaQHl N3S6rBsKgdODMKPShltFubIKO0TOph3oTqgRUjX5DmgvnQYByZIPmGYa+jtTzZf+uFig V0/nnIeSDAnkRbAsRIJI1/fr26I0sAhrbHWgclmczC+7r+mghHuAP37StVN2y8plIba1 qQBGO4JpHZ67P898AJvE6Qj3dfla/zYKyKkl7Eo1QHR0/dR8W3WFheDwxY8Hc8uTcZtg 0ADA== X-Forwarded-Encrypted: i=1; AFNElJ83DVSg6Dl5df+5CR8EhIRrX1l8cN3uzBCQooN8/m+iTbMEEvpYwwK5iz7eKU+VAoIMVSJqkUckAbt/i84=@vger.kernel.org X-Gm-Message-State: AOJu0Ywk597CrI+Fxabz/pDzUtPxzqcgaErPne4QdaSSJzeu0n8f4Mld nNeeZhgbRR/vboSVqIKIDBVWihPjiakFhTap6GMXVq8aFbCWdiyz4xn7 X-Gm-Gg: Acq92OExd0cjJGo0c1QeY17Tyx3YZ7yxauV43ffuAcFFa4JwfTGDQFM2z/o5Dn3pRtO IV99g4LPfdwrqd/Mkb5ruORF5+Ah5LmIV92iTXLk+1df35NFyxZ5a0mvqXAFuFJCdgl+q4Ybz5b mj+ceaZ+5MmRtRDuOk6zSGPmY6AK7AG5BFnxNZshwVgM2SBJs7++q3QbdKs1qwitubmq/GVbZD2 b6+3VRsOHhkBW7Rj0atl9pHxtoIE/XXCWKlJ9mPrXP+/SdiiYAIs2I6jc4PZSJgVLhp8cyFD+hB pTS21XXP7P38UmYtq2PEgSIphtV1uHqexYAYmc88tovMj2q7XV+yAv3VGYF/2MO+XaMGfEc0ZL7 +0XLhLF+Qs67SHi8sGCGs8mUTouMFH5yORugleHrKsaVuvLPfBFCyk5MMK6nawU5XnRrsMT9xF2 aL9u43iXqJefbxELfZ20rXavPuI7EPYDIjRQ== X-Received: by 2002:a05:600c:608c:b0:490:e180:2e0 with SMTP id 5b1f17b1804b1-492340bc7fbmr3838635e9.3.1781641639129; Tue, 16 Jun 2026 13:27:19 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:18 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:27 +0300 Subject: [PATCH RFC v4 07/12] clk: zte: Introduce a driver for zx297520v3 top clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-7-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=22898; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=rjIuDqYIiFiv2gumQf48MMHKoYVI7rxTGDOhoRAmUz0=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGfJFYr68VfbgIODMGSNq1J8f69BlP81ZFT lOBTgArHgmJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiKRZg/8CIZvkpBaoVIRrfXnlSIR16gZdjKTW4K Xddqu6s9Y1DaHZhUoU11d8iWykNIjlr9FpdXXkS1ZdPWroZM5dz/wlFvjHf+YUN7j1heoI/Qhdt uv5Tf9QfkGCH+3A9eSMH4EkdBfg7OO8Q7sYpLNYsc31swJ1GJElRBscENKCxtgkKG2ABNPFAaQC caCpWuqgA3Vpxe7GeSnYV8SFLR6bJsiS8IvLNbM7Wh5qz6NW6Lnqn7cHoTLH+aZzaxefTOJ0uvQ /vCyOX5y+go2YrZ5xPf5NKPtvY2fDRc0/zq9nWDINCM1qCh+/37M0QjbyrsQvEaeSroytwraLzU Oip0h6Tydh4RgJAHzvJdSg1MSVV3F+5MYjKms4eJZVsjkzZMphb3PT8GRAjjrltCGeXa5IbhOFb +YtUZ6FOALPfDDUgF9G1vYyY/zsEa3qgLDCDowxs2dunZpcZ1lRS4tOHJqm/Edxgq68FH13kMiN dBaBfTbkJ5SWHgv6NqaoyWn+pN6VtLcWfKW3h5RvY5IsUWllqG4RM0wDitZmlZG/HYB7GC/Pzzi EVFdkSNC5V5SuSCzyTRl1GmDUCnMjD36ew921mgQivK14wDwknYsCNz8R1azGc0asb1nOKfXEgV asQV2OOkED27Fj58CFVMhNzwtJgGRGT0PEPxqqKOCXwZuVwe7tTc= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This register space controls core devices: PLLs, the AHB bus, a lot of timers, the USB controller, the Cortex M0 processor that boots the board and a few other devices. For some reason the LTE coprocessor is also partially controlled by it. The main application processor and DDR memory are not found here though. The register to reboot the board is found here, as well as a register to control of watchdog expiries cause a board reset. Signed-off-by: Stefan D=C3=B6singer --- drivers/clk/zte/Kconfig | 11 + drivers/clk/zte/Makefile | 1 + drivers/clk/zte/clk-zx297520v3.c | 431 +++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 443 insertions(+) diff --git a/drivers/clk/zte/Kconfig b/drivers/clk/zte/Kconfig index b7b65a2172a9..12906212ec1e 100644 --- a/drivers/clk/zte/Kconfig +++ b/drivers/clk/zte/Kconfig @@ -15,3 +15,14 @@ config COMMON_CLK_ZTE of this. =20 Enable this if you are building a kernel for a ZTE designed board. + +config CLK_ZTE_ZX297520V3 + tristate "Clock driver for ZTE zx297520v3 based SoCs" + depends on COMMON_CLK_ZTE + default SOC_ZX297520V3 + help + This driver supports ZTE zx297520v3 basic clocks. + + Enable this if you want to build a kernel that is able to run on + boards based on this SoC. You can safely enable multiple clock + drivers. The one(s) matching the device tree will be used. diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile index 27db07293165..2c073512e919 100644 --- a/drivers/clk/zte/Makefile +++ b/drivers/clk/zte/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only =20 obj-$(CONFIG_COMMON_CLK_ZTE) +=3D clk-zte.o +obj-$(CONFIG_CLK_ZTE_ZX297520V3) +=3D clk-zx297520v3.o =20 clk-zte-y +=3D clk-zx.o pll-zx.o clk-regmap.o diff --git a/drivers/clk/zte/clk-zx297520v3.c b/drivers/clk/zte/clk-zx29752= 0v3.c new file mode 100644 index 000000000000..50263bca6e08 --- /dev/null +++ b/drivers/clk/zte/clk-zx297520v3.c @@ -0,0 +1,431 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan D=C3=B6singer + */ +#include +#include +#include +#include + +#include "clk-zx.h" + +MODULE_IMPORT_NS("ZTE_CLK"); + +/* Used for gates where we don't know the parent input(s). Assume general = bus clock. */ +static const char * const clk_unknown[] =3D { + "osc26m", +}; + +/* Used for gates where we know it is using the 26 mhz main clock. */ +static const char * const clk_main[] =3D { + "osc26m", +}; + +static const char * const zx297529v3_top_inputs[] =3D { + "osc26m", + "osc32k" +}; + +/* Top and matrix clocks are chaotic - I haven't found a consistent patter= n behind their register + * and bit locations. Generally there are two gates (pclk, wclk), one mux,= two resets and sometimes + * one divider, but exceptions apply. For some devices there is only a res= et and some general + * (parent) clocks need setup. This structure plus macro handles the somew= hat regular parts. + * + * There are some patterns that can be observed. + * mux 0x3c, div 0x48, gate 0x54 + * mux 0x40, div 0x4c, gate 0x5c + * mux 0x44, div 0x50, gate 0x60 + * + * For a 0 - 0xc - 0x18 pattern. Muxes from 0x3c to 0x44, dividers from 0x= 48 to 0x50, gates 0x54 to + * 0x60. The pattern is broken for timer t17 though. + * + * Gates have 4 bits per clock - bit 0 for wclk, bit 1 for pclk, bit 2 for= something the ZTE kernel + * calls "gate" (the bits we use here are called "en"), which I don't know= what it does, and bit 3 + * seems unused. E.g. offset 0x54 accepts all bits in 0xF77F7F7F - suggest= ing RTC, I2C0 have an + * extra gate bit. + * + * The default mpll settings multiply the 26 MHz reference clock times 24.= A mux selection of 26 MHz + * could mean using the 26 MHz oscillator directly, or passing it through = the PLL and divide by 24. + * + * If a UART is set to mpl_d6 (default 104 MHz), changing the mpll multipl= iers does affect UART + * timing as it should. This does not happen when the UART is set to 26 MH= z input or timers that + * read 26 MHz input. This suggests 26 MHz clocks use the reference clock = directly. + */ + +/* AHB: The clock mux works and impact can be tested e.g. with iperf speed= testing of the USB + * network connection. Values 2 and 3 give the same speed. + */ +static const char * const ahb_sel[] =3D { + "osc26m", + "mpll_d6", /* 104 mhz */ + "mpll_d8", /* 78 mhz */ + "mpll_d8", /* 78 mhz */ +}; + +static const char * const timer_top_sel[] =3D { + "osc32k", + "osc26m", +}; + +static const char * const uart_top_sel[] =3D { + "osc26m", + "mpll_d6", /* 104 mhz */ +}; + +/* The Cortex M0 coprocessor. It is responsible for booting the board and = runs some power management + * helper code on the stock firmware, but isn't critical. We can run custo= m code on it but currently + * do not. These bits control the speed and the values are mentioned in ZT= E's uboot. It isn't clear + * to me if this is directly responsible for the m0 clock, or if it is the= input to another clock. + * Most likely it is the latter - setting it to osc32k slows down GPIO rea= ds done on the Cortex A53 + * a lot, although the speed of the A53 and DRAM access remains unaffected. + * + * I also haven't found a gate that shuts the m0 off and allows restarting= . There don't seem to be + * resets either. + */ +static const char * const m0_sel[] =3D { + "osc26m", + "mpll_d6", /* 104 mhz */ + "mpll_d8", /* 78 mhz */ + "osc32k", /* Yes, tested. It is SLLLLOOOOOWWW. */ +}; + +/* Clk_out0/1/2/32k: These clocks are exposed on GPIOs 15, 16, 17 and 18 r= espectively. They are used + * in ZTE's camera and sound code, by directly poking into the clock regis= ters from the device + * drivers. Until the respective devices are supported they can safely be = switched off. + * + * For clk_out1 ZTE's camera code says the following: + * + * 0 -> 20 MHz + * 1 -> 40 MHz + * 2 -> 13 MHz + * 3 -> 26 MHz + * + * 0 and 1 read from upll. I confirmed their rates (upll_d24 and upll_d12)= by setting upll to a very + * low frequency and sampling the clock by GPIO reads. The outputs of 2 an= d 3 are way too high to + * test that way. Both are not reading from any PLL. I am fairly sure that= 3 is just direct osc26m + * because it perfectly matches what out2 is showing in its 26 MHz setting= . Setting 2 is an enigma. + * It is not from any PLL (disable postdiv_out on all of them and the cloc= k will keep oscillating). + * + * Probably the best way us to model this as a mux (bit 7) and divider (bi= t 6), but since this is + * not a plain val+1 divider like the rest of the divs I am leaving the di= vider out until an actual + * hardware user is found. It would need support for divider tables or fla= gs in the regmap div + * clocks. + * + * Clk_out2 is similar, but it has only one control bit in top 0x34 bit 8.= Neither setting selects + * a PLL output. When setting *0x34 =3D 0x080, clk_out1 and clk_out2 are i= n lockstep, presumably + * running at 13 MHz (clk_out1 mux select 26m, both have their divider set= to 2). 0x1c0 also runs in + * lockstep (clk_out1 select 26m, both div 1). + * + * clk_out0 has a mux in bit 5. Value 0 most likely selects osc26m. I am n= ot entirely sure about + * value 1 (which is the default), but the m0 mux has an impact on it. It = looks like a debug pin + * that exposes some core clock. + */ + +static const char * const out0_sel[] =3D { + "osc26m", + "m0_wclk", +}; + +static const char * const out1_sel[] =3D { + "upll_d12", /* 40 MHz */ + "osc26m", +}; + +/* Clk_o is similar to clk_out*, providing a clock on GPIO 20, presumably = for driving a (R)MII phy. + * The 50 MHz value is documented in a stray comment in ZTE's GMAC driver.= I tested it similarly to + * the above pins. Mux setting 0 gives half the count as setting 1 and set= ting 1 gives gpll divided + * by 4 - matching the 50 MHz suggested by the ZTE comment at the default = gpll settings. Gating gpll + * stops the clock for values 0 and 1. + * + * Settings 2 and 3 are possible, but seem to return garbage. It is genera= lly pulsing up and down, + * except if both gpll and upll are stopped. I suspect it just reads rando= m electrical fluctuation + * from other places in the board. Yes, I had a pull-down enabled when tes= ting this. + * + * This could also be a case of mux + inverse div, but since the settings = we might possibly need are + * standard gpll outputs just model it as a mux. + * + * I am not aware of any board that uses this though. The Ethernet equippe= d ones I have all run the + * phy with its own oscillator. + */ +static const char * const rmii_sel[] =3D { + "gpll_d8", /* 25 MHz */ + "gpll_d4", /* 50 MHz */ +}; + +static const unsigned int mpll_postdivs[] =3D {1, 2, 3, 4, 5, 6, 8, 12, 16= , 26}; +static const unsigned int pll_postdivs[] =3D {1, 2, 3, 4, 5, 6, 8, 12, 16}; +static const unsigned int unknownpll_postdivs[] =3D {2}; + +static const struct zx_pll_desc zx297520v3_plls[] =3D { + /* Default setting: 0x48040c11. 624/312/156. Only a single possible paren= t. This is the + * PLL for pretty much everything, including CPU, RAM and USB. + * + * Changing this PLL makes it possible to overclock the CPU or do more fi= ne grained + * underclocking than the CPU's mux allows. It does run into two problems= though: The USB + * device uses this PLL's output directly and is *very* sensitive to diff= erences. DRAM + * is also fed by this clock and needs to be re-trained on larger changes= , which needs to + * be done by the stage 1 boot loader. + */ + { + .id =3D ZX297520V3_MPLL, + .name =3D "mpll", + .parents =3D clk_main, + .num_parents =3D ARRAY_SIZE(clk_main), + .rate =3D 0, + .postdivs =3D mpll_postdivs, + .num_postdivs =3D ARRAY_SIZE(mpll_postdivs), + .reg =3D 0x8 + }, + + /* ZTE's code calls this PLL "upll". The only possible consumer I found i= s clk_out1, which + * outputs this clock on GPIO 16. The device that consumes this is an SPI= camera, which I + * haven't seen in any device so far. + * + * Long story short, shut it off. + */ + { + .id =3D ZX297520V3_UPLL, + .name =3D "upll", + .parents =3D clk_main, + .num_parents =3D ARRAY_SIZE(clk_main), + .rate =3D 0, + .postdivs =3D pll_postdivs, + .num_postdivs =3D ARRAY_SIZE(pll_postdivs), + .reg =3D 0x10, + }, + + /* Default value 0x4834902d. Feeds dpll. 46.08 MHz. Bit 25 can be set, so= two parents are + * possible. It looks like both values select the 26 MHz oscillator thoug= h. + */ + { + .id =3D 0, + .name =3D "unknownpll", + .parents =3D clk_main, + .num_parents =3D ARRAY_SIZE(clk_main), + .rate =3D 0, + .postdivs =3D unknownpll_postdivs, + .num_postdivs =3D ARRAY_SIZE(unknownpll_postdivs), + .reg =3D 0x100, + }, + + /* The documentation says 491.52 MHz and measurement with the LSP TDM dev= ice supports this. + * The default value is 0x480c2011, but not all boot loaders set it up. T= o get to 491.52 + * with these settings it needs a 23.04 MHz reference clock, which matche= s unknownpll_d2. + * If unknownpll is disabled, dpll loses its lock. We set the frequency o= n this PLL if we + * find it is not enabled by the boot loader. + * + * The proprietary LTE driver or coproc enables and disables it. TDM and = I2S can use it. + * + * It accepts parent values 0, 1, 2 and 3. Parent 0 is unknownpll_d2. The= others look like + * osc26m. With a parent !=3D 0 dpll never loses its lock even when all o= ther PLLs are off + * and the TDM counter register increases at a rate consistent with a 26.= 0/23.04 clock + * increase. + */ + { + .id =3D ZX297520V3_DPLL, + .name =3D "dpll", + .parents =3D clk_main, + .num_parents =3D ARRAY_SIZE(clk_main), + .rate =3D 491520000, + .postdivs =3D pll_postdivs, + .num_postdivs =3D ARRAY_SIZE(pll_postdivs), + .reg =3D 0x18, + }, + + /* "g" is either for "general" or "gigahertz". The VCO runs at 1GHz. Outp= ut clocks are 200, + * 100, 50, 25, ... MHz. It is used optionally by SDIO and QSPI and can d= rive a GPIO clock + * output for RMII, so it doesn't seem very general. + */ + { + .id =3D ZX297520V3_GPLL, + .name =3D "gpll", + .parents =3D clk_main, + .num_parents =3D ARRAY_SIZE(clk_main), + .rate =3D 0, + .postdivs =3D pll_postdivs, + .num_postdivs =3D ARRAY_SIZE(pll_postdivs), + .reg =3D 0x110, + }, +}; + +#define MUX(_id, _name, _parents, _reg, _shift, _size) { \ + _id, _name, _parents, ARRAY_SIZE(_parents), _reg, _shift, _size} + +#define DIV(_id, _name, _parent, _reg, _shift, _size) { _id, _name, _paren= t, _reg, _shift, _size } + +#define GATE(_id, _name, _parent, _reg, _shift, _flags) { \ + .id =3D _id, \ + .name =3D _name, \ + .parent =3D _parent, \ + .flags =3D _flags, \ + .reg =3D _reg, \ + .shift =3D _shift, \ +} + +static const struct zx_mux_desc zx297520v3_top_muxes[] =3D { + MUX(ZX297520V3_M0_WCLK, "m0_wclk", m0_sel, 0x= 38, 0, 2), + MUX(0, "ahb_mux", ahb_sel, 0x= 3c, 4, 2), + MUX(0, "timer_t08_mux", timer_top_sel, 0x= 40, 1, 1), + MUX(0, "timer_t09_mux", timer_top_sel, 0x= 40, 0, 1), + MUX(0, "timer_t12_mux", timer_top_sel, 0x= 3c, 0, 1), + MUX(0, "timer_t13_mux", timer_top_sel, 0x= 44, 0, 1), + MUX(0, "timer_t14_mux", timer_top_sel, 0x= 44, 1, 1), + MUX(0, "timer_t15_mux", timer_top_sel, 0x= 3c, 3, 1), + MUX(0, "timer_t16_mux", timer_top_sel, 0x= 44, 2, 1), + MUX(0, "timer_t17_mux", timer_top_sel, 0x1= 20, 0, 1), + MUX(0, "wdt_t18_mux", timer_top_sel, 0x= 3c, 6, 1), + MUX(0, "i2c0_mux", uart_top_sel, 0x= 3c, 1, 1), + MUX(0, "uart0_mux", uart_top_sel, 0x= 40, 2, 1), + MUX(0, "out0_mux", out0_sel, 0x= 34, 5, 1), + MUX(0, "out1_mux", out1_sel, 0x= 34, 7, 1), + MUX(0, "rmiiphy_mux", rmii_sel, 0x1= 1c, 0, 2), +}; + +static const struct zx_div_desc zx297520v3_top_dividers[] =3D { + DIV(0, "timer_t08_div", "timer_t08_mux", 0x= 4c, 8, 4), + DIV(0, "timer_t09_div", "timer_t09_mux", 0x= 4c, 0, 4), + DIV(0, "timer_t12_div", "timer_t12_mux", 0x= 48, 0, 4), + DIV(0, "timer_t13_div", "timer_t13_mux", 0x= 50, 0, 4), + DIV(0, "timer_t14_div", "timer_t14_mux", 0x= 50, 4, 4), + DIV(0, "timer_t15_div", "timer_t15_mux", 0x= 48, 4, 4), + DIV(0, "timer_t16_div", "timer_t16_mux", 0x= 50, 8, 4), + DIV(0, "timer_t17_div", "timer_t17_mux", 0x1= 24, 0, 4), + DIV(0, "wdt_t18_div", "wdt_t18_mux", 0x= 48, 8, 4), + DIV(0, "usim1_div", clk_main[0], 0x= 48, 12, 1), +}; + +static const struct zx_gate_desc zx297520v3_top_gates[] =3D { + /* Turning off this clock crashes the device. */ + GATE(ZX297520V3_AHB_WCLK, "ahb_wclk", "ahb_mux", 0x= 54, 12, + CLK_IS_CRITICAL), + GATE(ZX297520V3_AHB_PCLK, "ahb_pclk", clk_main[0], 0x= 54, 13, + CLK_IS_CRITICAL), + + /* SRAM1 and 2 clocks. Leave them on for now, as turning them off careles= sly hangs the M0 */ + GATE(ZX297520V3_SRAM1_PCLK, "sram1_pclk", clk_main[0], 0x= 54, 18, + CLK_IS_CRITICAL), + GATE(ZX297520V3_SRAM2_PCLK, "sram2_pclk", clk_main[0], 0x= 54, 16, + CLK_IS_CRITICAL), + + /* Pinmux (AON, TOP, IOCFG but not PDCFG). Critical as well until we have= a driver that + * consumes it. I don't think we'll realistically shut this off ever. + * + * Setting either bit 0 or 1 in register 0x58 makes the device work. + */ + GATE(ZX297520V3_PMM_WCLK, "pmm_wclk", clk_main[0], 0x= 58, 0, + CLK_IS_CRITICAL), + GATE(ZX297520V3_PMM_PCLK, "pmm_pclk", clk_main[0], 0x= 58, 1, + CLK_IS_CRITICAL), + + /* Timers. We don't use any of them, just shut them off. The timers are n= amed and sorted + * by the IO address of the main timer controls. Some of the controls are= documented in + * ZTE's kernel, the others I found by trial and error. + * + * Timer T17 is used by the ZSP firmware. The rproc driver will enable it= as needed. + */ + GATE(ZX297520V3_TIMER_T08_WCLK, "timer_t08_wclk", "timer_t08_div", 0x= 5c, 8, 0), + GATE(ZX297520V3_TIMER_T08_PCLK, "timer_t08_pclk", clk_main[0], 0x= 5c, 9, 0), + GATE(ZX297520V3_TIMER_T09_WCLK, "timer_t09_wclk", "timer_t09_div", 0x= 5c, 4, 0), + GATE(ZX297520V3_TIMER_T09_PCLK, "timer_t09_pclk", clk_main[0], 0x= 5c, 5, 0), + GATE(ZX297520V3_TIMER_T12_WCLK, "timer_t12_wclk", "timer_t12_div", 0x= 54, 4, 0), + GATE(ZX297520V3_TIMER_T12_PCLK, "timer_t12_pclk", clk_main[0], 0x= 54, 5, 0), + GATE(ZX297520V3_TIMER_T13_WCLK, "timer_t13_wclk", "timer_t13_div", 0x= 60, 0, 0), + GATE(ZX297520V3_TIMER_T13_PCLK, "timer_t13_pclk", clk_main[0], 0x= 60, 1, 0), + GATE(ZX297520V3_TIMER_T14_WCLK, "timer_t14_wclk", "timer_t14_div", 0x= 60, 4, 0), + GATE(ZX297520V3_TIMER_T14_PCLK, "timer_t14_pclk", clk_main[0], 0x= 60, 5, 0), + GATE(ZX297520V3_TIMER_T15_WCLK, "timer_t15_wclk", "timer_t15_div", 0x= 54, 20, 0), + GATE(ZX297520V3_TIMER_T15_PCLK, "timer_t15_pclk", clk_main[0], 0x= 54, 21, 0), + GATE(ZX297520V3_TIMER_T16_WCLK, "timer_t16_wclk", "timer_t16_div", 0x= 60, 8, 0), + GATE(ZX297520V3_TIMER_T16_PCLK, "timer_t16_pclk", clk_main[0], 0x= 60, 9, 0), + GATE(ZX297520V3_TIMER_T17_WCLK, "timer_t17_wclk", "timer_t17_div", 0x1= 28, 0, 0), + GATE(ZX297520V3_TIMER_T17_PCLK, "timer_t17_pclk", clk_main[0], 0x1= 28, 1, 0), + /* This watchdog is set up by the bootloader and in normal operation the = m0 firmware will + * feed the dog. The m0 firmware in turn wants to be fed in its own way. = Since we normally + * don't run any m0 firmware we shut it off by default and expose it to u= serspace via the + * watchdog driver. + */ + GATE(ZX297520V3_WDT_T18_WCLK, "wdt_t18_wclk", "wdt_t18_div", 0x= 54, 24, 0), + GATE(ZX297520V3_WDT_T18_PCLK, "wdt_t18_pclk", clk_main[0], 0x= 54, 25, 0), + + GATE(ZX297520V3_I2C0_WCLK, "i2c0_wclk", "i2c0_mux", 0x= 54, 8, 0), + GATE(ZX297520V3_I2C0_PCLK, "i2c0_pclk", clk_main[0], 0x= 54, 9, 0), + GATE(ZX297520V3_UART0_WCLK, "uart0_wclk", "uart0_mux", 0x= 5c, 12, 0), + GATE(ZX297520V3_UART0_PCLK, "uart0_pclk", clk_main[0], 0x= 5c, 13, 0), + + /* ZTE says the USB input is a 24 MHz clock based on mpll. Testing shows = that Upll is not + * involved. The USB register space can be accessed with ahb_pclk gated, = but not with + * ahb_wclk gated. ZTE also lists ahb_wclk as parent for the second clock. + */ + GATE(ZX297520V3_USB_WCLK, "usb_wclk", "mpll_d26", 0x= 6c, 3, 0), + GATE(ZX297520V3_USB_PCLK, "usb_pclk", "ahb_wclk", 0x= 6c, 4, 0), + /* The HSIC hardware is listed in ZTE's code with a physical address of 0= x01600000. These + * bits are part of the ones that control it. + */ + GATE(ZX297520V3_HSIC_WCLK, "hsic_wclk", "mpll_d26", 0x= 6c, 1, 0), + GATE(ZX297520V3_HSIC_PCLK, "hsic_pclk", "ahb_wclk", 0x= 6c, 2, 0), + + /* How does this RTC work? I don't know, the ZTE kernel does not talk to = it. The actual RTC + * is on the I2C connected PMIC. + */ + GATE(ZX297520V3_RTC_WCLK, "rtc_wclk", clk_unknown[0], 0x= 54, 0, 0), + GATE(ZX297520V3_RTC_PCLK, "rtc_pclk", clk_main[0], 0x= 54, 1, 0), + + GATE(ZX297520V3_USIM1_WCLK, "usim1_wclk", "usim1_div", 0x= 54, 28, 0), + GATE(ZX297520V3_USIM1_PCLK, "usim1_pclk", clk_main[0], 0x= 54, 29, 0), + + /* LTE: gate only as far as I can see. I looked for resets and did not fi= nd any. There may + * be mux/div, but without understanding the behavior of this hardware it= is impossible to + * tell. They are sorted by physical MMIO address of the devices, which h= appens to be the + * inverse order of the bits. + * + * I don't know what "LPM", "TD" and "W" mean. I copied them from ZTE's n= ames. + */ + GATE(ZX297520V3_LPM_GSM_WCLK, "lpm_gsm_wclk", clk_unknown[0], 0x= 58, 10, 0), + GATE(ZX297520V3_LPM_GSM_PCLK, "lpm_gsm_pclk", clk_unknown[0], 0x= 58, 11, 0), + GATE(ZX297520V3_LPM_LTE_WCLK, "lpm_lte_wclk", clk_unknown[0], 0x= 58, 8, 0), + GATE(ZX297520V3_LPM_LTE_PCLK, "lpm_lte_pclk", clk_unknown[0], 0x= 58, 9, 0), + GATE(ZX297520V3_LPM_TD_WCLK, "lpm_td_wclk", clk_unknown[0], 0x= 58, 6, 0), + GATE(ZX297520V3_LPM_TD_PCLK, "lpm_td_pclk", clk_unknown[0], 0x= 58, 7, 0), + GATE(ZX297520V3_LPM_W_WCLK, "lpm_w_wclk", clk_unknown[0], 0x= 58, 4, 0), + GATE(ZX297520V3_LPM_W_PCLK, "lpm_w_pclk", clk_unknown[0], 0x= 58, 5, 0), + + GATE(ZX297520V3_OUT0_WCLK, "out0_wclk", "out0_mux", 0x= 34, 0, 0), + GATE(ZX297520V3_OUT1_WCLK, "out1_wclk", "out1_mux", 0x= 90, 2, 0), + GATE(ZX297520V3_OUT2_WCLK, "out2_wclk", clk_main[0], 0x= 94, 2, 0), + GATE(ZX297520V3_OUT32K_WCLK, "out32k_wclk", "osc32k", 0x= 34, 1, 0), + GATE(ZX297520V3_RMIIPHY_WCLK, "rmiiphy_wclk", "rmiiphy_mux", 0x1= 1c, 2, 0), +}; + +static const struct zx_clk_data zx297520v3_topclk_data =3D { + .inputs =3D zx297529v3_top_inputs, + .num_inputs =3D ARRAY_SIZE(zx297529v3_top_inputs), + .plls =3D zx297520v3_plls, + .num_plls =3D ARRAY_SIZE(zx297520v3_plls), + .muxes =3D zx297520v3_top_muxes, + .num_muxes =3D ARRAY_SIZE(zx297520v3_top_muxes), + .divs =3D zx297520v3_top_dividers, + .num_divs =3D ARRAY_SIZE(zx297520v3_top_dividers), + .gates =3D zx297520v3_top_gates, + .num_gates =3D ARRAY_SIZE(zx297520v3_top_gates), + .reset_auxdev_name =3D "zx297520v3_toprst" +}; + +static const struct of_device_id of_match_zx297520v3[] =3D { + { .compatible =3D "zte,zx297520v3-topclk", .data =3D &zx297520v3_topclk_d= ata }, + { } +}; +MODULE_DEVICE_TABLE(of, of_match_zx297520v3); + +static struct platform_driver clk_zx297520v3 =3D { + .probe =3D zx_clk_probe, + .driver =3D { + .name =3D "clk-zx297520v3", + .of_match_table =3D of_match_zx297520v3, + }, +}; + +module_platform_driver(clk_zx297520v3); + +MODULE_AUTHOR("Stefan D=C3=B6singer "); +MODULE_DESCRIPTION("ZTE zx297520v3 clock driver"); +MODULE_LICENSE("GPL"); --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D32A538D3E8 for ; Tue, 16 Jun 2026 20:27:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641646; cv=none; b=cHH5rGuVFFvyHpIWMjVmkToYA6ZXLQ+cfRFckXGxT0PkGjN0eorBSjucd/nyPF170kRViOSb9Ml/QrnkDRb6YceZ+KzbFdIydn06A4/A8ub9W2OJ+N8wzx9sHGjh0NWFahV28eefCOGpun3QRJ0QAhsO0TYn04rjozc0vW5or04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641646; c=relaxed/simple; bh=2CJMMG1/LE5vixHG7JxoV5FWmwbKqkkpuEs/bq1yiII=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mfu9m5r0AIrulUIlWDQFfG0EqWWzRNgPFxqT4EZAQ6y0Ib7ppWMBSfWCwmznOkvTXpPb7I8I/ncKVCfwARcTlKYeibFgvItW4CDkDfn7yFzD34tFVV597+oZukWoGPWqAf95qBPu4YPY70oGuZ6cFX269Xu7TN5LxBBX7p/KNKs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ZTuZzQXN; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZTuZzQXN" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-490b3637b90so39055315e9.3 for ; Tue, 16 Jun 2026 13:27:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641643; x=1782246443; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=IVQO6hIIgLgmlWsatP4pC/13zJii6CGhx+MK+WXIvZM=; b=ZTuZzQXNKNZtAZI3iPpDPUBXB/Vm+0rau009GZ8z3Px2wTl99HTUDtjDE0QHHDJ9yz LSqNpi2zaqGYbyhe5XdbUX/2QQg+2ogI5jEJX0OCs45WqrErVybRisg16zIwCj6dsQkW 5fPMGxdFAfpSL5ZgTgC7pYkwtO82lBi6DktU7Lvx3U7STQ1ZjEyrr50OP0AcMFa686Cx XJacpXI6TSFFbCQo+ztrA/vtRLc+AbrL7pelSDuYk3XaFD+Ol2CTELgy9BscsMoRC4qW d0wQJZyCCSHoLosM9RwkYe/bpqtbYQUf5R6xR+1RFls4XPsTUyTm7Vxm+5EqTIWAb2B+ nPiQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641643; x=1782246443; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=IVQO6hIIgLgmlWsatP4pC/13zJii6CGhx+MK+WXIvZM=; b=si6ndsrELvwBiNT2aL2mC8IbvPwNz24IRHy8GlSMHFpW8YS2K6ARwOkTdK0WZbPVKB 8wRq+Nqmir+Dljb0OuaFpnPhaIMKibEQMopnqBA95VupTMU8iATY9Iodni5QthYGu0dq d/L3IDgZmqh3VkQRQx4iwM7gnaZLl0fCOr0mA4vdff7sSoPZXahHYU39Bp89vvHBfPNZ rzdWN0EE/S00Z2EOFXJvffEzGKqc2YW4qGVBQ31ml2YZNp+DQYqoOa3Bg81Swz3BEocu Tx+YTCA8BO9igu7HQJETwZZgGcKo7XruSTPFhYwo8xio2leRrQu9TnLr+lV/SPjZ6oNF mX5Q== X-Forwarded-Encrypted: i=1; AFNElJ/toEZoPqlE80HIW8mqx1Vg9hEjTIOEQM35KHVXwrl8J/gzo8H0qBb8VGqJPFXMPN2XNF5I4pzKpS0U0V4=@vger.kernel.org X-Gm-Message-State: AOJu0Yx34ZgVkaUnWqtcu8Tuxw/rTlaEa6fso1WUW+DQwDA+BfSmkdue 0dlSN1cPzUIRk3RyHoQbPkTgYPjnIOp6RwNjVm9MCn5AbMG2D2Bl+RE0 X-Gm-Gg: Acq92OFtlMejwjF75KmsrNVxddeuFoqzm1yFrrAxq8XJHD2WCTFPemuBIrO0znGAAiN CdYqg+1aYkwuhD/5LEpDuekFL/l39pq4DUTZp5tXHw15dWhEOgzO/7x3PeWjVwHSWBRE8gXllg8 OXoOYGjKvTmrSbrgPeFaR0+3Ipc8uj8eIC6NAXzjhfnF3fO78P9gx2hsJyzSfnbAR0UpuahRNw3 0ZUaiNZRclWhaTNRe3OUZzPqbeCH4rbLCN4fzMmW1Lo8ag82v3yEZvJNyPOxTXeNi/IYf7OnfAT TmnwHjBaSvU5g9HaF7JTDk25mkrj3Ow9D2RvM/nNpa9qFaOdIJRT1GdBe0+/mPJ18/+ZjjLtIht 2qgQs40JJkFlKwk+zY9EGIw+7qqFvsDo9K1A6r5NtfT9AF+FpGOYd8cD/4hciLELvvmK4A+OAWb vG+XVEyrQJJn/EGpiPcoqf5ShxpRdfg6vlAvpT2LOJWHmM X-Received: by 2002:a05:600c:332a:b0:492:1e36:85dd with SMTP id 5b1f17b1804b1-492333e359fmr11453315e9.37.1781641643101; Tue, 16 Jun 2026 13:27:23 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:22 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:28 +0300 Subject: [PATCH RFC v4 08/12] clk: zte: Introduce a driver for zx297520v3 matrix clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-8-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=9437; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=2CJMMG1/LE5vixHG7JxoV5FWmwbKqkkpuEs/bq1yiII=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGCHFBls8mhrHFC8ZuUkVYYpxIem8E07Qyy 5wFNEEcGaqJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiL9gQ//WHbD9rNammpvKJ6xvivDdcp5lAm7ayr BrI9UdJZ6bORXL8cJ3dRUOqiXwvP6+Mwpz3bArD7GkCui3UWb69rRwF/mS2pzfPFBAG0m6XaRiX KzpE7bBmidqsftCxtWYreTC9z+ZIXrSQeOePfM7mtnEWsCAGdjszc4pZxFEhmE8G3y37U35Lfjy K1Qipeo8D3rTWjTO2S0ryp0g9+K9HJio8+/9YMC8WxknQmbNMUtHnhCJML8ENW3daNK+1zi/nQ6 pH5j5j9KvzBTVr7aUKPRdUKRWMmu4KoeqfoLvq2CpHjzlBXdRe2Bgsg5bHVJww1OJtW8Ne5Bg7C Tt69FM7Am3xuAS89XweaMviBz53Mp5kkfh/i3GHO2eTnVYYVb7IubpeZKel1x8yF/znpUA+ti7f n/L3LoWwa527gicsarv6C7pxEjkatHarJmo3H3EIkRjQiwSRzYq1xepf33omqOJOiRuwqcZynr/ pA4ezELr7pNJiirUbzJ2og3MgYTQYT667U7slpKPxGn2l5QTdOsONlrgrcj8H3CgJOgeJ0UUPOh uzL0hqeliXT8fssLrUAP/h93touFp20x+YBKv1I5BiGxF3fGjCVvkNoUDSaaWRc5li2qAsDiZAh IlE7U35SRr+1fgI8vmOHxa1nvHVZ9P7v/9xnCUgpSK+tAKcELtxA= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This clock controller controls high speed devices: CPU, DMA, RAM, SDIO, Ethernet. The only non-clock, non-reset registers I have spotted here are hardware spinlocks. I put the entire set of PLL generated frequencies as consumed clocks in the binding. Due to lack of a data sheet I can't rule out that the any of the PLL subdivions are used. Signed-off-by: Stefan D=C3=B6singer --- drivers/clk/zte/clk-zx297520v3.c | 172 +++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 172 insertions(+) diff --git a/drivers/clk/zte/clk-zx297520v3.c b/drivers/clk/zte/clk-zx29752= 0v3.c index 50263bca6e08..d90aadf18026 100644 --- a/drivers/clk/zte/clk-zx297520v3.c +++ b/drivers/clk/zte/clk-zx297520v3.c @@ -410,8 +410,180 @@ static const struct zx_clk_data zx297520v3_topclk_dat= a =3D { .reset_auxdev_name =3D "zx297520v3_toprst" }; =20 +static const char * const cpu_sel[] =3D { + "osc26m", + "mpll", /* 624 MHz */ + "mpll_d2", /* 312 MHz */ + "mpll_d4", /* 156 MHz */ +}; + +static const char * const sd0_sel[] =3D { + "osc26m", + "mpll_d4", /* 156 MHz */ + "gpll_d2", /* 100 MHz */ + "mpll_d8", /* 78 MHz */ + "gpll_d4", /* 50 MHz */ + "gpll_d8", /* 25 MHz */ +}; + +static const char * const sd1_sel[] =3D { + "osc26m", + "gpll_d2", /* 100 MHz */ + "mpll_d8", /* 78 MHz */ + "gpll_d4", /* 50 MHz */ + "mpll_d16", /* 39 MHz */ + "gpll_d8", /* 25 MHz */ +}; + +static const char * const nand_sel[] =3D { + "mpll_d4", /* 156 MHz */ + "osc26m", +}; + +static const char * const edcp_sel[] =3D { + "osc26m", + "mpll_d4", /* 156 MHz */ + "mpll_d5", /* 124.8 MHz */ + "mpll_d6", /* 104 MHz */ +}; + +static const char * const tdm_sel[] =3D { + "osc26m", + "dpll_d4", /* 122.88 MHz */ + "mpll_d6", /* 104 MHz */ +}; + +static const struct zx_mux_desc zx297520v3_matrix_muxes[] =3D { + MUX(0, "cpu_mux", cpu_sel, 0x= 20, 0, 2), + MUX(0, "sd0_mux", sd0_sel, 0x= 50, 4, 3), + MUX(0, "sd1_mux", sd1_sel, 0x= 50, 8, 3), + MUX(0, "nand_mux", nand_sel, 0x= 50, 12, 2), + MUX(0, "edcp_mux", edcp_sel, 0x= 50, 16, 2), + MUX(0, "tdm_mux", tdm_sel, 0x= 50, 24, 2), +}; + +static const struct zx_gate_desc zx297520v3_matrix_gates[] =3D { + /* Both 0x24 and 0x28 bits 1 and 2 stop the CPU. There is also a bit in t= opclk+0x138, which + * ZTE's uboot calls "A53 reset", which also stops the CPU. I can't reall= y tell the + * difference between matrix+28 and top+138. The clock (maxtrix+0x24) can= be disabled and + * enabled from the Cortex M0 and it will nicely stop and restart the A53= , retaining all + * state. + * + * 0x50, bits 0-3 have the DDR clock. A lot of DDR gates and resets are i= n 0x100. + */ + GATE(ZX297520V3_CPU_WCLK, "cpu_wclk", "cpu_mux", 0x= 24, 1, + CLK_IS_CRITICAL), + GATE(ZX297520V3_CPU_PCLK, "cpu_pclk", clk_main[0], 0x= 24, 2, + CLK_IS_CRITICAL), + + /* ZSP aka LTE DSP clock. I think there is a mux at matrix+0x30, but I ha= ve no idea + * about the frequencies it selects. + */ + GATE(ZX297520V3_ZSP_WCLK, "zsp_wclk", clk_unknown[0], 0x= 3c, 0, 0), + + GATE(ZX297520V3_SD0_WCLK, "sd0_wclk", "sd0_mux", 0x= 54, 12, 0), + GATE(ZX297520V3_SD0_PCLK, "sd0_pclk", clk_main[0], 0x= 54, 13, 0), + GATE(ZX297520V3_SD0_CDET, "sd0_cdet", "osc32k", 0x= 54, 14, 0), + GATE(ZX297520V3_SD1_WCLK, "sd1_wclk", "sd1_mux", 0x= 54, 4, 0), + GATE(ZX297520V3_SD1_PCLK, "sd1_pclk", clk_main[0], 0x= 54, 5, 0), + /* I don't know how the cdet clock works. Card detection in the way the d= wc,mmc driver uses + * it appears broken no matter this clock's setting. + */ + GATE(ZX297520V3_SD1_CDET, "sd1_cdet", "osc32k", 0x= 54, 6, 0), + + /* This is some "denali" NAND, not the qspi connected one */ + GATE(ZX297520V3_NAND_WCLK, "nand_wclk", "nand_mux", 0x= 54, 20, 0), + GATE(ZX297520V3_NAND_PCLK, "nand_pclk", clk_main[0], 0x= 54, 21, 0), + GATE(ZX297520V3_SSC_WCLK, "ssc_wclk", clk_unknown[0], 0x= 84, 1, 0), + GATE(ZX297520V3_SSC_PCLK, "ssc_pclk", clk_main[0], 0x= 84, 2, 0), + + /* Yes, WCLK bit > PCLK bit for EDCP */ + GATE(ZX297520V3_EDCP_WCLK, "edcp_wclk", "edcp_mux", 0x= 64, 2, 0), + GATE(ZX297520V3_EDCP_PCLK, "edcp_pclk", clk_main[0], 0x= 64, 1, 0), + + /* There are a lot more VOU related controls in these registers, but turn= ing off the main + * clock seems to shut off the entire VOU MMIO range. + */ + GATE(ZX297520V3_VOU_WCLK, "vou_wclk", clk_unknown[0], 0x1= 68, 0, 0), + GATE(ZX297520V3_VOU_PCLK, "vou_pclk", clk_main[0], 0x1= 68, 1, 0), + + /* PDCFG. Like PMM, either clock bit will allow the device to function. */ + GATE(ZX297520V3_PDCFG_WCLK, "pdcfg_wclk", clk_unknown[0], 0x= 88, 0, + CLK_IS_CRITICAL), + GATE(ZX297520V3_PDCFG_PCLK, "pdcfg_pclk", clk_main[0], 0x= 88, 1, + CLK_IS_CRITICAL), + + /* ZTE's driver has a statemt to the effect of *(top->base+0x11c) =3D 5, = with a comment + * suggesting that this sets a 50 mhz clock. The clock code itself lists = gmac clocks in + * matrix+110 and lists the parents of these clock as 50mhz gpll output, = but the GMAC + * driver never enables the clocks. It turns out ZTE's code is highly mis= leading. + * + * The GMAC's work clock is definitly not any gpll output because it keep= s working fine with + * gpll disabled. The MDIO speed is mostly unaffected by mpll speed chang= es, so it is most + * likely not fed by mpll either. All other PLLs can be disabled without = breaking GMAC, so + * osc26m is the only possible remaining parent. + * + * The GMAC Gates are left enabled by the boot loader and are required fo= r the GMAC to work. + * + * As for the 50 MHz comment: See rmiiphy_wclk. + */ + GATE(ZX297520V3_GMAC_WCLK, "gmac_wclk", clk_main[0], 0x1= 10, 0, 0), + GATE(ZX297520V3_GMAC_PCLK, "gmac_pclk", clk_main[0], 0x1= 10, 1, 0), + GATE(ZX297520V3_GMAC_AHB, "gmac_ahb", "AHB_wclk", 0x1= 10, 2, 0), + + GATE(ZX297520V3_MBOX_PCLK, "mbox_pclk", clk_main[0], 0x= 88, 2, 0), + GATE(ZX297520V3_DMA_PCLK, "dma_pclk", clk_main[0], 0x= 94, 3, 0), + + /* LSP uplink clocks. The PCLK is fairly obvious (disabling it shuts off = the entire LSP + * register area). The WCLK speeds were deduced by setting timers and qsp= i muxes to a + * specific speed and seeing which bit in matrix+0x7c needs to be enabled= for the device + * to work. + * + * Due to the timers I am certain about the 26mhz and 32khz clocks. I can= not directly + * observe the qspi mux frequency, so the clock rates depend on ZTE's qsp= i mux selection + * being correct. + * + * Two additional bits are specific to sound components - the mux for the= LSP's TDM IP is + * in matrixclk and gets passed down. I2S has a mux in LSP, which can sel= ect the dpll_d4 + * clock. + */ + GATE(ZX297520V3_LSP_MPLL_D5_WCLK, "lsp_mpll_d5", "mpll_d5", 0x= 7c, 0, 0), + GATE(ZX297520V3_LSP_MPLL_D4_WCLK, "lsp_mpll_d4", "mpll_d4", 0x= 7c, 1, 0), + GATE(ZX297520V3_LSP_MPLL_D6_WCLK, "lsp_mpll_d6", "mpll_d6", 0x= 7c, 2, 0), + GATE(ZX297520V3_LSP_MPLL_D8_WCLK, "lsp_mpll_d8", "mpll_d8", 0x= 7c, 3, 0), + GATE(ZX297520V3_LSP_MPLL_D12_WCLK, "lsp_mpll_d12", "mpll_d12", 0x= 7c, 4, 0), + GATE(ZX297520V3_LSP_OSC26M_WCLK, "lsp_osc26m", clk_main[0], 0x= 7c, 5, 0), + GATE(ZX297520V3_LSP_OSC32K_WCLK, "lsp_osc32k", "osc32k", 0x= 7c, 6, 0), + GATE(ZX297520V3_LSP_PCLK, "lsp_pclk", clk_main[0], 0x= 7c, 7, 0), + GATE(ZX297520V3_LSP_TDM_WCLK, "lsp_tdm_wclk", "tdm_mux", 0x= 7c, 8, 0), + GATE(ZX297520V3_LSP_DPLL_D4_WCLK, "lsp_dpll_d4", "dpll_d4", 0x= 7c, 9, 0), +}; + +static const char * const zx297529v3_matrix_inputs[] =3D { + "osc26m", "osc32k", + "mpll", "mpll_d2", "mpll_d3", "mpll_d4", "mpll_d5", "mpll_d6", "mpll_d8",= "mpll_d12", + "mpll_d16", "mpll_d26", + "upll", "upll_d2", "upll_d3", "upll_d4", "upll_d5", "upll_d6", "upll_d8",= "upll_d12", + "upll_d16", + "dpll", "dpll_d2", "dpll_d3", "dpll_d4", "dpll_d5", "dpll_d6", "dpll_d8",= "dpll_d12", + "dpll_d16", + "gpll", "gpll_d2", "gpll_d3", "gpll_d4", "gpll_d5", "gpll_d6", "gpll_d8",= "gpll_d12", + "gpll_d16", +}; + +static const struct zx_clk_data zx297520v3_matrixclk_data =3D { + .inputs =3D zx297529v3_matrix_inputs, + .num_inputs =3D ARRAY_SIZE(zx297529v3_matrix_inputs), + .muxes =3D zx297520v3_matrix_muxes, + .num_muxes =3D ARRAY_SIZE(zx297520v3_matrix_muxes), + .gates =3D zx297520v3_matrix_gates, + .num_gates =3D ARRAY_SIZE(zx297520v3_matrix_gates), + .reset_auxdev_name =3D "zx297520v3_matrixrst" +}; + static const struct of_device_id of_match_zx297520v3[] =3D { { .compatible =3D "zte,zx297520v3-topclk", .data =3D &zx297520v3_topclk_d= ata }, + { .compatible =3D "zte,zx297520v3-matrixclk", .data =3D &zx297520v3_matri= xclk_data }, { } }; MODULE_DEVICE_TABLE(of, of_match_zx297520v3); --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1060539768C for ; Tue, 16 Jun 2026 20:27:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641651; cv=none; b=PWke0TPQrl4plny7NHrSfwGGvwuykXVGY6KnuDjtXVSlHv/36RpkPQ9uHrDODEnsH5UKCrSJLY5b4wIMoAPASNqhpf/YxFZ8Ah+7kPhyTGMPM4uIzGIScD7ng0yWeWyzhywqyTYP2VPBlypujE1BG3ENuk2NYyPalcvf9Gi049k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641651; c=relaxed/simple; bh=lbHHuSxqYynCWbB7Q+n6QPG7iIdM8EIGUyLv56zQRDc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jwj+6yMf5qJESx27zL0G7Vk5lhZbrxqGm1o8rqsa5H47lw92h9RW5t7dDMMJ+neNi3tb6GGwmrDdpn0W0K69nerblrBcPdvvfLxG+9xjKWoCHPy0WGIH//NOeJxT4j39YK841eEMvnALkeE8fni8Ptyu5aADQdT63og2xLylQc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=XvzRr8/T; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="XvzRr8/T" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-49222b6e871so34696725e9.3 for ; Tue, 16 Jun 2026 13:27:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641647; x=1782246447; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=baR2tJhTCCpjbOvimxFzjlV0YgowSxYpo4W6Y4kO2+g=; b=XvzRr8/THiwh8ObcqyYSCMLygqjIvKd9ENlHy03DJ1NyyBwjg77pN5xTHtD+Ap3Gek Leb+wjfV1tTcyRUZEPWDn9QdOlDEvjvmWDkGuSfQiytce3hSYMbFpZqjEKBj48upIj8I 00zFUiQNgh4ftaFiUKl4bKA4pFZT/ZivpUuRD71M9TiRRZMMZ3EXyC3H59GxHEGFAsyD YBpBzNpUmeGpwt+MFw0Fxb5qm0r/zGZvYAxCpzB+asUDNpc2fo/CXbIYg2ySPlQJIUMc mojef0Mm9WWMCEYMJ3AWFxp9OdPsK7vwbSeVM72S3xnBNxLzZXnv4dt179YaJB3hSir/ kuVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641647; x=1782246447; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=baR2tJhTCCpjbOvimxFzjlV0YgowSxYpo4W6Y4kO2+g=; b=bFiN2T2b3o2KRN+6xF12bSckQN0PEJvJ/YNPrSjVrdVVDkjwMFhxNNWLootqmoK/9G lMgLRzBdoSHcg4WMA0fZF/eqB84BGg4ySChqKF6fme2y5MedjaAtjPQ0PbNeNkdNWsme E5p4/Y6SEoWyQSjDroSg+HeGwRuydKzrcMzbwsgEq3aKg7222qFWT3BAdnrJOIqNWdSc ERFi/zTI0uFA4KJxbNw/FfVhk9DTigrhbcRbeJx5L9yFRj8Ngko+oylAJCNOTwa/7L6p elinkX7C5ie4BruPUvjewkZ2sjlJOaexBmmArl9BtJxyeNWAI6degTwzRkI/mJElwknZ DnUQ== X-Forwarded-Encrypted: i=1; AFNElJ/rhct8dbqxhTZVN4SmQYdoRgciD+mVkZ+Z77uInxP3QKYlYDTpE83xvCCWD+XaoFU3O7Ey5acCqlgVF60=@vger.kernel.org X-Gm-Message-State: AOJu0YweacTYuhGnT56EB0EmHfusQZDpv7jeXIkaEiGT3O49OU5G3wX4 cAF7Ng6h8PEK3vKrdVdUbNTw9OeRyd4YVxUpHdLNwdAeO3ILV0gfAo3/ X-Gm-Gg: Acq92OH+ay9lo0HAZIp5J5SLOL6Xj4ar1N1F27zOhdfoKVT9HapP0kzWRLMyg/IvOgz 0jyqMqTZ1YvsA8PtCdENRZB/kPOboY42ysJU1rQr0znbBdtneGJ2wUYIQYav1xNvTRRJPRvIRDb U3vn0QcW4pnAs7ei+eDcrIbYA7Hjuwv3Z7hQv+WU7Xd3pUHHOOF2Hu7VREWUt/oPiCTI3Jrb38S cj5tDvaysYAY5uBYfc8m/4WvbuWiXCskscKtCiKqltYXfdjwkBlvCeosu0UCmF5a9h25YxQf3Jc km4FxAg0ggijOTsv2q3TBY8Lf4qEKxhojk0khwJGQCF63sgDqlMC6nyCoXSgG3lBX/FzpyY7Gyc p3KGMeSK01fasC6sLR9BuWaVxe23DUO6u9zvxHuuElAIX3owuvpBXwS6bvQlO3N4Q62Sae1IIFx d15ybWmfvQGpkiYR58BMcSG+LW50dCbjk3A5qzrgsm5sOF X-Received: by 2002:a7b:c3d1:0:b0:490:b92f:ef5b with SMTP id 5b1f17b1804b1-492341088b1mr2343925e9.13.1781641647445; Tue, 16 Jun 2026 13:27:27 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:27 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:29 +0300 Subject: [PATCH RFC v4 09/12] clk: zte: Introduce a driver for zx297520v3 LSP clocks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-9-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11110; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=lbHHuSxqYynCWbB7Q+n6QPG7iIdM8EIGUyLv56zQRDc=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGG3cZnUlyNSfTHc6i03TNVKRGuxlVzqM1c0 Z0guS11NSCJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiI0rxAAmYmX3RvSjLds5sb3ahEFkJzTNThkZP6 YwB/Fyo/NA1qs+k8ryr2qqgGK3uifISAIQuPTdXTiqF5lbxGtg4OzfTJjGyQhSgnnH9PgvU0MUK AqFWD/1j2ydjjzK2KQtKsfG193a+PDu8mi7Dg+brHozhi7Df4WAURitykgQRhWfBoP77fB2XgGp 3fyK5BazcrnYn2P1gRdY0fqR2YChWxx2H2so373DOK38K6pr0o3M6t6Ww36px+FsOqBf7MMbp6i oVGj6F5uUjG854BLBiBSojFdWIX51JKWeX3wAGldY63/88Cu09W8mKaRuqSK2wD0OZ1WuDO88pt fBtiYgoQPJipigIXynLVVIB3vqTyhkfgxmAzBZEovS3aytTGM4WwGR1MJCsxCSNLtboZXkpR/MA wgYACIu5wBUZjCiK6WZ56QkXnHNHKWBOg2jctuXSyTUruhYtMayLeCqrQIFl0xVCOyX60E5uz7N G64fdok2OtlAtjF9feYs2vAeBMwFO/C5hN8wO6hPvW+xo8c+xtor2sIoBhgWirs5P8qVw2ee+AZ 9lfck/VAybD2oXkEShpkXo7tAiyKIPOPzTh4oEFOEedJBhI24kB2Hs0clhHXbiDutsgWowLdtWB a1s7vTcaA2evYlSTnT/R9qQp+K5SW39HqGmeDVgrZ/Z6AxS7jcxE= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 "LSP" is ZTE's term for this part of the SoC, I suspect it stands for "low speed peripherals". The main UART is here, together with the flash controller and more surplus proprietary timers. It also has two more I2C controllers that supposedly connect to a battery charger, SPI for displays and I2S for analog telephones. The boards I have don't have any of these components though. Signed-off-by: Stefan D=C3=B6singer --- drivers/clk/zte/clk-zx297520v3.c | 192 +++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 192 insertions(+) diff --git a/drivers/clk/zte/clk-zx297520v3.c b/drivers/clk/zte/clk-zx29752= 0v3.c index d90aadf18026..26b05f2bf97a 100644 --- a/drivers/clk/zte/clk-zx297520v3.c +++ b/drivers/clk/zte/clk-zx297520v3.c @@ -581,9 +581,201 @@ static const struct zx_clk_data zx297520v3_matrixclk_= data =3D { .reset_auxdev_name =3D "zx297520v3_matrixrst" }; =20 +/* LSP clock entries have a common pattern: Bit 0 for WCLK, Bit 1 for PCLK= . Bit 4 (and sometimes + * more) for WCLK mux. + * + * Bit 8 and 9 are reset bits. I don't know the difference between the two= , but they both need to be + * set to deassert the reset. + * + * Bits 15:12 can be a divisor, but not all clocks have it. Some clocks ha= ve a divisor in 19:16. + * + * The ID given in this table is the first register in the device's MMIO s= pace. ZTE's drivers + * usually call this a version register, but it looks more like a device i= dentifier. + * + * It looks like the registers map to devices like this: + * + * Timer reg function div dev offset(lsp + xxxx) ID + * 0x0: Read-only, probably device identifier 0x00752100 + * 0x4: timer_l1 Y 0x1000 0x02020000 + * 0x8: watchdog_l2 Y 0x2000 0x02020000 + * 0xc: watchdog_l3 Y 0x3000 0x02020000 + * 0x10: pwm N 0x4000 0x01020000 + * 0x14: i2s0 Yh 0x5000 0x01030000 + * 0x18: always 0 - - - + * 0x1c: i2s1 Yh 0x6000 0x01030000 + * 0x20: always 0 - - - + * 0x24: qspi N 0x7000 0x01040000 + * 0x28: uart1 N 0x8000 0x01060000 + * 0x2c: i2c1 N 0x9000 0x01020000 + * 0x30: spi0 Y 0xa000 0x01040000 + * 0x34: timer_lb Y 0xb000 0x02020000 + * 0x38: timer_lc Y 0xc000 0x02020000 + * 0x3c: uart2 N 0xd000 0x01060000 + * 0x40: watchdog_le Y 0xe000 0x02020000 + * 0x44: timer_lf Y 0xf000 0x02020000 + * 0x48: spi1 Y 0x10000 0x01040000 + * 0x4c: timer_l11 Y 0x11000 0x02020000 + * 0x50: tdm Yh 0x12000 0x01040000 + * + * Registers 0x58, 0x5c, 0x60, 0x64, 0x68 seem to contain more controls fo= r i2s and tdm. + * + * I am not sure about the device at offset 0x4000 (clk reg 0x10). The ID = matches that of i2c, but + * it has a larger register set. I suspect it is a PWM device, but I have = not seen any ZTE kernel + * operate it - even devices with displays only use a GPIO to control the = backlight. + */ + +static const char * const timer_lsp_sel[] =3D { + "lsp_osc32k", + "lsp_osc26m", +}; + +static const char * const uart_lsp_sel[] =3D { + "lsp_osc26m", + "lsp_mpll_d6", +}; + +static const char * const i2s_lsp_sel[] =3D { + "lsp_osc26m", + "lsp_dpll_d4", + "lsp_mpll_d6", + /* Unknown */ +}; + +static const char * const tdm_lsp_sel[] =3D { + "lsp_tdm_wclk", +}; + +static const char * const spi_lsp_sel[] =3D { + "lsp_osc26m", + "lsp_mpll_d4", + "lsp_mpll_d6", + /* Unknown */ +}; + +static const char * const qspi_lsp_sel[] =3D { + "lsp_osc26m", + "lsp_mpll_d4", + "lsp_mpll_d5", + "lsp_mpll_d6", + "lsp_mpll_d8", + "lsp_mpll_d12", + "lsp_osc26m", + "lsp_osc26m", +}; + +static const struct zx_mux_desc zx297520v3_lsp_muxes[] =3D { + MUX(0, "timer_l1_mux", timer_lsp_sel, 0x= 04, 4, 1), + MUX(0, "wdt_l2_mux", timer_lsp_sel, 0x= 08, 4, 1), + MUX(0, "wdt_l3_mux", timer_lsp_sel, 0x= 0c, 4, 1), + /* PWM: No mux bit can be set */ + MUX(0, "i2s0_mux", i2s_lsp_sel, 0x= 14, 4, 2), + /* 0x18: Always 0 */ + MUX(0, "i2s1_mux", i2s_lsp_sel, 0x= 1c, 4, 2), + /* 0x20: Always 0 */ + MUX(0, "qspi_mux", qspi_lsp_sel, 0x= 24, 4, 3), + MUX(0, "uart1_mux", uart_lsp_sel, 0x= 28, 4, 1), + MUX(0, "i2c1_mux", uart_lsp_sel, 0x= 2c, 4, 1), + MUX(0, "spi0_mux", spi_lsp_sel, 0x= 30, 4, 2), + MUX(0, "timer_lb_mux", timer_lsp_sel, 0x= 34, 4, 1), + MUX(0, "timer_lc_mux", timer_lsp_sel, 0x= 38, 4, 1), + MUX(0, "uart2_mux", uart_lsp_sel, 0x= 3c, 4, 1), + MUX(0, "wdt_le_mux", timer_lsp_sel, 0x= 40, 4, 1), + MUX(0, "timer_lf_mux", timer_lsp_sel, 0x= 44, 4, 1), + MUX(0, "spi1_mux", spi_lsp_sel, 0x= 48, 4, 2), + MUX(0, "timer_l11_mux", timer_lsp_sel, 0x= 4c, 4, 1), + /* TDM: No mux in LSP. Instead, it is in matrix with a separate clk line = to LSP */ +}; + +static const struct zx_div_desc zx297520v3_lsp_dividers[] =3D { + DIV(0, "timer_l1_div", "timer_l1_mux", 0x= 04, 12, 4), + DIV(0, "wdt_l2_div", "wdt_l2_mux", 0x= 08, 12, 4), + DIV(0, "wdt_l3_div", "wdt_l3_mux", 0x= 0c, 12, 4), + /* PWM: No div */ + DIV(0, "i2s0_div", "i2s0_mux", 0x= 14, 16, 4), + /* 0x18: Always 0 */ + DIV(0, "i2s1_div", "i2s1_mux", 0x= 1c, 16, 4), + /* 0x20: Always 0 */ + /* qspi, uart1, i2c1: No div */ + DIV(0, "spi0_div", "spi0_mux", 0x= 30, 12, 4), + DIV(0, "timer_lb_div", "timer_lb_mux", 0x= 34, 12, 4), + DIV(0, "timer_lc_div", "timer_lc_mux", 0x= 38, 12, 4), + /* uart2: No div */ + DIV(0, "wdt_le_div", "wdt_le_mux", 0x= 40, 12, 4), + DIV(0, "timer_lf_div", "timer_lf_mux", 0x= 44, 12, 4), + DIV(0, "spi1_div", "spi1_mux", 0x= 48, 12, 4), + DIV(0, "timer_l11_div", "timer_l11_mux", 0x= 4c, 12, 4), + DIV(0, "tdm_div", "lsp_tdm_wclk", 0x= 50, 16, 4), +}; + +static const struct zx_gate_desc zx297520v3_lsp_gates[] =3D { + GATE(ZX297520V3_TIMER_L1_WCLK, "timer_l1_wclk", "timer_l1_div", 0x= 04, 0, 0), + GATE(ZX297520V3_TIMER_L1_PCLK, "timer_l1_pclk", "lsp_pclk", 0x= 04, 1, 0), + GATE(ZX297520V3_WDT_L2_WCLK, "wdt_l2_wclk", "wdt_l2_div", 0x= 08, 0, 0), + GATE(ZX297520V3_WDT_L2_PCLK, "wdt_l2_pclk", "lsp_pclk", 0x= 08, 1, 0), + GATE(ZX297520V3_WDT_L3_WCLK, "wdt_l3_wclk", "wdt_l3_div", 0x= 0c, 0, 0), + GATE(ZX297520V3_WDT_L3_PCLK, "wdt_l3_pclk", "lsp_pclk", 0x= 0c, 1, 0), + /* I don't know the LSP parent. It must be one of the LSP inputs though. = */ + GATE(ZX297520V3_PWM_WCLK, "pwm_wclk", "lsp_osc26m", 0x= 10, 0, 0), + GATE(ZX297520V3_PWM_PCLK, "pwm_pclk", "lsp_pclk", 0x= 10, 1, 0), + GATE(ZX297520V3_I2S0_WCLK, "i2s0_wclk", "i2s0_div", 0x= 14, 0, 0), + GATE(ZX297520V3_I2S0_PCLK, "i2s0_pclk", "lsp_pclk", 0x= 14, 1, 0), + /* 0x1c: Always 0 */ + GATE(ZX297520V3_I2S1_WCLK, "i2s1_wclk", "i2s1_div", 0x= 1c, 0, 0), + GATE(ZX297520V3_I2S1_PCLK, "i2s1_pclk", "lsp_pclk", 0x= 1c, 1, 0), + /* 0x20: Always 0 */ + GATE(ZX297520V3_QSPI_WCLK, "qspi_wclk", "qspi_mux", 0x= 24, 0, 0), + GATE(ZX297520V3_QSPI_PCLK, "qspi_pclk", "lsp_pclk", 0x= 24, 1, 0), + GATE(ZX297520V3_UART1_WCLK, "uart1_wclk", "uart1_mux", 0x= 28, 0, 0), + GATE(ZX297520V3_UART1_PCLK, "uart1_pclk", "lsp_pclk", 0x= 28, 1, 0), + GATE(ZX297520V3_I2C1_WCLK, "i2c1_wclk", "i2c1_mux", 0x= 2c, 0, 0), + GATE(ZX297520V3_I2C1_PCLK, "i2c1_pclk", "lsp_pclk", 0x= 2c, 1, 0), + GATE(ZX297520V3_SPI0_WCLK, "spi0_wclk", "spi0_div", 0x= 30, 0, 0), + GATE(ZX297520V3_SPI0_PCLK, "spi0_pclk", "lsp_pclk", 0x= 30, 1, 0), + GATE(ZX297520V3_TIMER_LB_WCLK, "timer_lb_wclk", "timer_lb_div", 0x= 34, 0, 0), + GATE(ZX297520V3_TIMER_LB_PCLK, "timer_lb_pclk", "lsp_pclk", 0x= 34, 1, 0), + GATE(ZX297520V3_TIMER_LC_WCLK, "timer_lc_wclk", "timer_lc_div", 0x= 38, 0, 0), + GATE(ZX297520V3_TIMER_LC_PCLK, "timer_lc_pclk", "lsp_pclk", 0x= 38, 1, 0), + GATE(ZX297520V3_UART2_WCLK, "uart2_wclk", "uart2_mux", 0x= 3c, 0, 0), + GATE(ZX297520V3_UART2_PCLK, "uart2_pclk", "lsp_pclk", 0x= 3c, 1, 0), + GATE(ZX297520V3_WDT_LE_WCLK, "wdt_le_wclk", "wdt_le_div", 0x= 40, 0, 0), + GATE(ZX297520V3_WDT_LE_PCLK, "wdt_le_pclk", "lsp_pclk", 0x= 40, 1, 0), + GATE(ZX297520V3_TIMER_LF_WCLK, "timer_lf_wclk", "timer_lf_div", 0x= 44, 0, 0), + GATE(ZX297520V3_TIMER_LF_PCLK, "timer_lf_pclk", "lsp_pclk", 0x= 44, 1, 0), + GATE(ZX297520V3_SPI1_WCLK, "spi1_wclk", "spi1_div", 0x= 48, 0, 0), + GATE(ZX297520V3_SPI1_PCLK, "spi1_pclk", "lsp_pclk", 0x= 48, 1, 0), + GATE(ZX297520V3_TIMER_L11_WCLK, "timer_l11_wclk", "timer_l11_div", 0x= 4c, 0, 0), + GATE(ZX297520V3_TIMER_L11_PCLK, "timer_l11_pclk", "lsp_pclk", 0x= 4c, 1, 0), + GATE(ZX297520V3_TDM_WCLK, "tdm_wclk", "tdm_div", 0x= 50, 0, 0), + GATE(ZX297520V3_TDM_PCLK, "tdm_pclk", "lsp_pclk", 0x= 50, 1, 0), +}; + +static const char * const zx297529v3_lsp_inputs[] =3D { + "mpll_d5", "mpll_d4", "mpll_d6", "mpll_d8", "mpll_d12", + "osc26m", "osc32k", "tdm_wclk", "dpll_d4" +}; + +static const char * const zx297529v3_lsp_inputs_enable[] =3D { + "pclk" +}; + +static const struct zx_clk_data zx297520v3_lspclk_data =3D { + .inputs_enable =3D zx297529v3_lsp_inputs_enable, + .num_inputs_enable =3D ARRAY_SIZE(zx297529v3_lsp_inputs_enable), + .inputs =3D zx297529v3_lsp_inputs, + .num_inputs =3D ARRAY_SIZE(zx297529v3_lsp_inputs), + .muxes =3D zx297520v3_lsp_muxes, + .num_muxes =3D ARRAY_SIZE(zx297520v3_lsp_muxes), + .divs =3D zx297520v3_lsp_dividers, + .num_divs =3D ARRAY_SIZE(zx297520v3_lsp_dividers), + .gates =3D zx297520v3_lsp_gates, + .num_gates =3D ARRAY_SIZE(zx297520v3_lsp_gates), + .reset_auxdev_name =3D "zx297520v3_lsprst" +}; + static const struct of_device_id of_match_zx297520v3[] =3D { { .compatible =3D "zte,zx297520v3-topclk", .data =3D &zx297520v3_topclk_d= ata }, { .compatible =3D "zte,zx297520v3-matrixclk", .data =3D &zx297520v3_matri= xclk_data }, + { .compatible =3D "zte,zx297520v3-lspclk", .data =3D &zx297520v3_lspclk_d= ata }, { } }; MODULE_DEVICE_TABLE(of, of_match_zx297520v3); --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2124039446B for ; Tue, 16 Jun 2026 20:27:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641656; cv=none; b=krIRGmhoD532IktmBY82bU5dhTuj/F0m5ipf4NvChRznauwNMcLFEGcVLHmN57G70tVkd2GnFOIyuGzHotfDNNXNn2TArCqTK65e2X96jw91CeHypgPUyyhbSnMGjJ60b9HDdy/SOa8u9NpK6qLAiQ4MH7XF1C5Duwx3/hMRxgg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641656; c=relaxed/simple; bh=/Onf7SXVmixZtmZBhrlI1d4heQCOgMKCksLiEvEpIR4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qNpMQ1m68vSJx9y39kNHYd70Zb6h8vSHQa82lvvu13VwOdmbZEfdZYFX2AEOFDPVLBbji5WBiw8wKBaUO54tTnnpWKdSEeAYuZ3OHxvdvytiLQCbSEeD9rIOjadiYy8wb68UMFHK7SOX5btbrgMnF19rf87pf1Hfz58pweiYvHg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ec8dQWi8; arc=none smtp.client-ip=209.85.128.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ec8dQWi8" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-490cdae130cso25058155e9.0 for ; Tue, 16 Jun 2026 13:27:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641651; x=1782246451; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=gyQFQwJnUbTFEFdQPMoEQmAROc3LFCyt4oG2RWf7UYA=; b=Ec8dQWi8ltWf+z6OAczJ5BKyO1K/AWmfXNuNFUTTsNnJd51mkb9uk9ejFywDTKp0hr Uspldk0mF9u2dDAN7facFAdtNTfjFd6TVp/Z8i49399Xn79IpCtj4tX3wygJGXfTU4cv MdUO+88AYrqzxUdeQz36/L+dYJ9ghl7y4DYAcZMp9tjR7hC7L/PaWI9gZWonPmz4PRmm 0hDYCfvK0V6+fygpkIaqFQ9HjXHVovWB4eAi5qCkMhC817+gPNkReqiVMdmnMDyDIBFJ x1wCriHuEAuAosfAaKu6ctXjViDbze0nyt4djarpEcqfDoB/YLkVmdHZ91xe8ELW2Grp iFlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641651; x=1782246451; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=gyQFQwJnUbTFEFdQPMoEQmAROc3LFCyt4oG2RWf7UYA=; b=HCPrCTFZxn+kcgT3CF9ARhVq/Y09/n0r9cbuMwavFHxoDJk6V/0WzeMPaqQZavgBJA RKn057xC+QccvxpPxpq3EzM1znoMH9Dr4ybX8za5PY1wO34nsWKNH7vL3ZHSOTmISIx9 ZVGVosBXuZ8WbkBftR0KPIhqvOVHiOYhqJulcB7ktE/Q5X0vMuolxURZbYsS5eb/j8Nx K2k+vQ0S6Vpwz3DUySyt4vPdl7dksxE270qZbJHsdR9TnNjoDn8VbqvEHIkmh4rscPh+ XhrlzLg8YNL1vPYGgOjqNQuTJiSwbTbzEddM82vWbtqqtpABnP4qpBq3HmxzLJltEh43 xH4g== X-Forwarded-Encrypted: i=1; AFNElJ8wZp1wmnoz3J99PjGTAl656nINBoR5jhHHtAOZi35r6JXz/q2zounzjYFs99OEBz33ZMSNUn3JSNrFqK0=@vger.kernel.org X-Gm-Message-State: AOJu0YzAn0fm68SbP/kmH05buakqIQjVQEXaOAbkIbUvwi33V5VQdKLx EnIKTHc5aN94zH1hiK2kE6H2EAHRvv0Yvr9NkRteJVAvQ2V/NnQMXGBs X-Gm-Gg: Acq92OEPiX43pCv2n7zFsrAn/vjvpPYuM/v8EnmoQejICjsU1T4ymDhoOPzFCdobKfC 7n0lay0BjYfieABJIqoFXkINY81PuI3rG+AB40dhBDmYbU7yb9hFkougGzBacA5Baow32WUsbFI QQMVl3PuSo/7EJ57wNDg/xKG8/wVDgyg9mZBUvnW/P0As9xOj0LtaTuxqku+pxPt9z0zIMh97YP xT8CWixbKvqWS7RQEFoMDXSGqloQez7lbDy5JvECAV43aMLcf6kqiyCR56Pd5nHP9MeyZE41/E6 fkz7yn/ZK9+go1I8WtguwN9vMmuzWcurGlhEBcwQgcewoUqozCBI0YpXQHQADeHcOlHf/lD3NXy Qx1Y04m0Umj+DKlvA9S+ym10uBvkGQiP0PISKxTVuE1nun7jPw/T9fLRbCAEisBLs96rzau0fhm fyGizvIJuNbGDGSUn6HHG0/MxXHt3OZkSXtw== X-Received: by 2002:a05:600c:c09a:b0:490:bb37:9d49 with SMTP id 5b1f17b1804b1-492333bf9f6mr15269455e9.11.1781641651403; Tue, 16 Jun 2026 13:27:31 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:30 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:30 +0300 Subject: [PATCH RFC v4 10/12] reset: zte: Add a zx297520v3 reset driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-10-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=11093; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=/Onf7SXVmixZtmZBhrlI1d4heQCOgMKCksLiEvEpIR4=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGZTOmPtLBlyNbaMcWpanSPy4o/C2VjTjma bqpPM5kLaaJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiJaUQ//Zc26M1HzXnLUzAvLgAPfOnYSemnKyuN uFndLu41BWHi4OSmYe2We8unIgoWPnA2+QfeVBSX419pVImDFPR40a67Pf+xxfSSiIUXMMEeQIc n7pO3Dn1lE7yXHyeWyb7Xe765VhZCHOPsZ/a2YDGqU/QhRtb++ZVvJWeyUZLPF6/fvOVSgkUWhY UNBjTUzcgh27yJIP54k+D2yY/AKbXgI5xIQpGKCDegm8WT68W+dtuyNwb9WwoeF5aMq5zsvH1UI Y4aSG7+zMzHHuDJRDsPV6mr4Ma9aLf3QVTsktT3o+wC0mcZZWGIjfu2gaTLwti2fPnFST91lwKO hkW+pYbPQCcgq7Rgyit4EQOKR+IRagTxBQBdHg/VyOT3xsRqi4EuuD0G+vqIMjCv7k4npNmMPGL c0KUw4NNMGfx8JGAf89JQ3D5k5AzUkRCNW/kUG0tJ56ac0fLfYi5VMmlH0FW8R1AKc1gI0zgjFO 68d5b/rbAAFAHumx2gc5Og5WwvhAf/O66ebHt7oQlgXOkzRDTVby7bTkbbMMyzyKbtg+5ObXAUV t1wOXMCCjKlRJBeRWrk9fGtMOTXWIqTgY9bQgxhaiQrtIULuqlVCGLHK8nx5IZu6QvRvtmtgf6I Fo+88mc4F62KqSGGlUsUU3NSobc+Aba7etHHmhWueiL5coVe4BTM= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This drives the auxiliary devices created by the clock driver. Signed-off-by: Stefan D=C3=B6singer --- MAINTAINERS | 1 + drivers/reset/Kconfig | 11 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-zte-zx297520v3.c | 224 +++++++++++++++++++++++++++++++= ++++ 4 files changed, 237 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index f1f0459b2c72..55bf0290343a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3871,6 +3871,7 @@ F: Documentation/devicetree/zte,zx297520v3-* F: arch/arm/boot/dts/zte/ F: arch/arm/mach-zte/ F: drivers/clk/zte/ +F: drivers/reset/reset-zte-zx297520v3.c F: include/dt-bindings/clock/zte,zx297520v3-clk.h =20 ARM/ZYNQ ARCHITECTURE diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index d009eb0849a3..116dd23f1b8e 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -404,6 +404,17 @@ config RESET_UNIPHIER_GLUE on UniPhier SoCs. Say Y if you want to control reset signals provided by the glue layer. =20 +config RESET_ZTE_ZX297520V3 + tristate "ZTE zx297520v3 Reset Driver" + depends on (ARCH_ZTE || COMPILE_TEST) + default CLK_ZTE_ZX297520V3 + select AUXILIARY_BUS + help + This enables the reset controller for ZTE zx297520v3 SoCs. The reset + controller is part of the clock controller on this SoC. This driver + operates on an auxiliary device exposed by the clock driver. Enable + this driver if you plan to boot the kernel on a zx297520v3 based SoC. + config RESET_ZYNQ bool "ZYNQ Reset Driver" if COMPILE_TEST default ARCH_ZYNQ diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 3e52569bd276..9a8a48d44dc4 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -50,5 +50,6 @@ obj-$(CONFIG_RESET_TI_TPS380X) +=3D reset-tps380x.o obj-$(CONFIG_RESET_TN48M_CPLD) +=3D reset-tn48m.o obj-$(CONFIG_RESET_UNIPHIER) +=3D reset-uniphier.o obj-$(CONFIG_RESET_UNIPHIER_GLUE) +=3D reset-uniphier-glue.o +obj-$(CONFIG_RESET_ZTE_ZX297520V3) +=3D reset-zte-zx297520v3.o obj-$(CONFIG_RESET_ZYNQ) +=3D reset-zynq.o obj-$(CONFIG_RESET_ZYNQMP) +=3D reset-zynqmp.o diff --git a/drivers/reset/reset-zte-zx297520v3.c b/drivers/reset/reset-zte= -zx297520v3.c new file mode 100644 index 000000000000..2022f4df2ebd --- /dev/null +++ b/drivers/reset/reset-zte-zx297520v3.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Stefan D=C3=B6singer + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct zte_reset_reg { + u32 mask, wait_mask; + u16 reg; +}; + +struct zte_reset_info { + const struct zte_reset_reg *resets; + unsigned int num; +}; + +struct zte_reset { + struct reset_controller_dev rcdev; + struct regmap *map; + const struct zte_reset_reg *resets; +}; + +static inline struct zte_reset *to_zte_reset(struct reset_controller_dev *= rcdev) +{ + return container_of(rcdev, struct zte_reset, rcdev); +} + +static int zx29_rst_assert(struct reset_controller_dev *rcdev, unsigned lo= ng id) +{ + struct zte_reset *rst =3D to_zte_reset(rcdev); + + return regmap_clear_bits(rst->map, rst->resets[id].reg, rst->resets[id].m= ask); +} + +static int zx29_rst_deassert(struct reset_controller_dev *rcdev, unsigned = long id) +{ + struct zte_reset *rst =3D to_zte_reset(rcdev); + int res; + u32 val; + + res =3D regmap_set_bits(rst->map, rst->resets[id].reg, rst->resets[id].ma= sk); + if (res) + return res; + + /* This is a special case used only by USB reset */ + if (rst->resets[id].wait_mask) { + return regmap_read_poll_timeout(rst->map, rst->resets[id].reg + 4, val, + val & rst->resets[id].wait_mask, 1, 100); + } + + return 0; +} + +static int zx29_rst_status(struct reset_controller_dev *rcdev, unsigned lo= ng id) +{ + struct zte_reset *rst =3D to_zte_reset(rcdev); + int res; + + res =3D regmap_test_bits(rst->map, rst->resets[id].reg, rst->resets[id].m= ask); + if (res < 0) + return res; + + return !res; +} + +static const struct reset_control_ops zx29_rst_ops =3D { + .assert =3D zx29_rst_assert, + .deassert =3D zx29_rst_deassert, + .status =3D zx29_rst_status, +}; + +static const struct zte_reset_reg zx297520v3_top_resets[] =3D { + /* This bit is set by ZTE's cpko.ko blob, it looks like a reset bit for t= he LTE DSP + * coprocessor. Clocks for it are in matrixclk. + */ + [ZX297520V3_ZSP_RESET] =3D { .reg =3D 0x13c, .mask =3D BIT(0) = }, + + [ZX297520V3_UART0_RESET] =3D { .reg =3D 0x78, .mask =3D BIT(6) | BI= T(7) }, + [ZX297520V3_I2C0_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_RTC_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(4) | BI= T(5) }, + [ZX297520V3_TIMER_T08_RESET] =3D { .reg =3D 0x78, .mask =3D BIT(4) | BI= T(5) }, + [ZX297520V3_TIMER_T09_RESET] =3D { .reg =3D 0x78, .mask =3D BIT(2) | BI= T(3) }, + [ZX297520V3_PMM_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(0) | BI= T(1) }, + + /* I haven't found any clocks for GPIO. It probably wouldn't make much + * sense anyway. Only one reset bit per controller. + */ + [ZX297520V3_GPIO_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(3) = }, + [ZX297520V3_GPIO8_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(2) = }, + + [ZX297520V3_TIMER_T12_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(6) | BI= T(7) }, + [ZX297520V3_TIMER_T13_RESET] =3D { .reg =3D 0x7c, .mask =3D BIT(0) | BI= T(1) }, + [ZX297520V3_TIMER_T14_RESET] =3D { .reg =3D 0x7c, .mask =3D BIT(2) | BI= T(3) }, + [ZX297520V3_TIMER_T15_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(10) | BI= T(11) }, + [ZX297520V3_TIMER_T16_RESET] =3D { .reg =3D 0x7c, .mask =3D BIT(4) | BI= T(5) }, + [ZX297520V3_TIMER_T17_RESET] =3D { .reg =3D 0x12c, .mask =3D BIT(0) | BI= T(1) }, + [ZX297520V3_WDT_T18_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(12) | BI= T(13) }, + [ZX297520V3_USIM1_RESET] =3D { .reg =3D 0x74, .mask =3D BIT(14) | BI= T(15) }, + [ZX297520V3_AHB_RESET] =3D { .reg =3D 0x70, .mask =3D BIT(0) | BI= T(1) }, + + /* USB reset. This is slightly special because it needs to wait for a rea= dy bit after + * deasserting. + */ + [ZX297520V3_USB_RESET] =3D { .reg =3D 0x80, .mask =3D BIT(3) | BI= T(4) | BIT(5), + .wait_mask =3D BIT(1)}, + [ZX297520V3_HSIC_RESET] =3D { .reg =3D 0x80, .mask =3D BIT(0) | BI= T(1) | BIT(2), + .wait_mask =3D BIT(0)}, +}; + +static const struct zte_reset_info zx297520v3_top_info =3D { + .resets =3D zx297520v3_top_resets, + .num =3D ARRAY_SIZE(zx297520v3_top_resets), +}; + +static const struct zte_reset_reg zx297520v3_matrix_resets[] =3D { + [ZX297520V3_CPU_RESET] =3D { .reg =3D 0x28, .mask =3D BIT(1) = }, + [ZX297520V3_EDCP_RESET] =3D { .reg =3D 0x68, .mask =3D BIT(0) = }, + [ZX297520V3_SD0_RESET] =3D { .reg =3D 0x58, .mask =3D BIT(1) = }, + [ZX297520V3_SD1_RESET] =3D { .reg =3D 0x58, .mask =3D BIT(0) = }, + [ZX297520V3_NAND_RESET] =3D { .reg =3D 0x58, .mask =3D BIT(4) = }, + [ZX297520V3_PDCFG_RESET] =3D { .reg =3D 0x94, .mask =3D BIT(20) = }, + [ZX297520V3_SSC_RESET] =3D { .reg =3D 0x94, .mask =3D BIT(24) = }, + [ZX297520V3_GMAC_RESET] =3D { .reg =3D 0x114, .mask =3D BIT(0) | BI= T(1) }, + [ZX297520V3_VOU_RESET] =3D { .reg =3D 0x16c, .mask =3D BIT(0) = }, +}; + +static const struct zte_reset_info zx297520v3_matrix_info =3D { + .resets =3D zx297520v3_matrix_resets, + .num =3D ARRAY_SIZE(zx297520v3_matrix_resets), +}; + +static const struct zte_reset_reg zx297520v3_lsp_resets[] =3D { + [ZX297520V3_TIMER_L1_RESET] =3D { .reg =3D 0x04, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_WDT_L2_RESET] =3D { .reg =3D 0x08, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_WDT_L3_RESET] =3D { .reg =3D 0x0c, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_PWM_RESET] =3D { .reg =3D 0x10, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_I2S0_RESET] =3D { .reg =3D 0x14, .mask =3D BIT(8) | BI= T(9) }, + /* 0x18: Not writeable */ + [ZX297520V3_I2S1_RESET] =3D { .reg =3D 0x1c, .mask =3D BIT(8) | BI= T(9) }, + /* 0x20: Not writeable */ + [ZX297520V3_QSPI_RESET] =3D { .reg =3D 0x24, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_UART1_RESET] =3D { .reg =3D 0x28, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_I2C1_RESET] =3D { .reg =3D 0x2c, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_SPI0_RESET] =3D { .reg =3D 0x30, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_TIMER_LB_RESET] =3D { .reg =3D 0x34, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_TIMER_LC_RESET] =3D { .reg =3D 0x38, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_UART2_RESET] =3D { .reg =3D 0x3c, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_WDT_LE_RESET] =3D { .reg =3D 0x40, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_TIMER_LF_RESET] =3D { .reg =3D 0x44, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_SPI1_RESET] =3D { .reg =3D 0x48, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_TIMER_L11_RESET] =3D { .reg =3D 0x4c, .mask =3D BIT(8) | BI= T(9) }, + [ZX297520V3_TDM_RESET] =3D { .reg =3D 0x50, .mask =3D BIT(8) | BI= T(9) }, +}; + +static const struct zte_reset_info zx297520v3_lsp_info =3D { + .resets =3D zx297520v3_lsp_resets, + .num =3D ARRAY_SIZE(zx297520v3_lsp_resets), +}; + +static int reset_zx297520v3_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + const struct zte_reset_info *drv_info; + struct device *dev =3D &adev->dev; + struct zte_reset *rst; + + drv_info =3D (struct zte_reset_info *)id->driver_data; + + rst =3D devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL); + if (!rst) + return -ENOMEM; + + rst->resets =3D drv_info->resets; + rst->rcdev.owner =3D THIS_MODULE; + rst->rcdev.nr_resets =3D drv_info->num; + rst->rcdev.ops =3D &zx29_rst_ops; + rst->rcdev.of_node =3D dev->of_node; + rst->rcdev.dev =3D dev; + rst->rcdev.of_reset_n_cells =3D 1; + + rst->map =3D device_node_to_regmap(dev->of_node); + if (IS_ERR(rst->map)) + return dev_err_probe(dev, PTR_ERR(rst->map), "Cannot get parent syscon r= egmap\n"); + + return devm_reset_controller_register(dev, &rst->rcdev); +} + +static const struct auxiliary_device_id reset_zx297520v3_ids[] =3D { + { + .name =3D "clk_zte.zx297520v3_toprst", + .driver_data =3D (kernel_ulong_t)&zx297520v3_top_info, + }, + { + .name =3D "clk_zte.zx297520v3_matrixrst", + .driver_data =3D (kernel_ulong_t)&zx297520v3_matrix_info, + }, + { + .name =3D "clk_zte.zx297520v3_lsprst", + .driver_data =3D (kernel_ulong_t)&zx297520v3_lsp_info, + }, + { }, +}; + +MODULE_DEVICE_TABLE(auxiliary, reset_zx297520v3_ids); + +static struct auxiliary_driver reset_zx297520v3_drv =3D { + .name =3D "zx297520v3_reset", + .id_table =3D reset_zx297520v3_ids, + .probe =3D reset_zx297520v3_probe, +}; + +module_auxiliary_driver(reset_zx297520v3_drv); + +MODULE_AUTHOR("Stefan D=C3=B6singer "); +MODULE_DESCRIPTION("ZTE zx297520v3 reset driver"); +MODULE_LICENSE("GPL"); --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CDF9394785 for ; Tue, 16 Jun 2026 20:27:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641658; cv=none; b=qVzyiqIAwV5lxgqWDbvF62+s4VoCyQas8qj+tExQsPKFfXVW7ZGwHav/+yGt0mWocCwnYXKf0wz8HJfkt8LdR5fn8ptwg60ZqQnPAb23UVijPb/hy8kNZaq00LIQfZuxzY88I0MCHMgDPKAuelfOTkonW+jVwJnxirZyqt+fA2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641658; c=relaxed/simple; bh=WCM0t2tSpKbIjViogFh06SwJ0ZwBBkr30bJ7ePaJsf4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nFCTdjx5nJdpq8g2mMsBiqT9ZcrKcKOlzYetxlOKvbacfjgCuIs9PiEnFvZBIgfOy7yk+BTnkNJaEAFOWd+UfpvjirKlDs/D81h1D4g7GVGJQDSPURiVYpvH/NpDaQvIlYhWtyBfmY15kwvQAfvZmOHY28NwIShvkTXI9HTcwAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=k18+5I7g; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="k18+5I7g" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4922244f7c7so31363925e9.0 for ; Tue, 16 Jun 2026 13:27:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641656; x=1782246456; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=Ltlo+66CbkzQq4Lsr4cyfZ7a+2/NQVI4939KsTGc97E=; b=k18+5I7gyirNJQGqxBAD41ARjG3k3jceQck30BQMSQRNe0Yb5FB5jtqvc1mmfYxbav lbeCdVldE04+BLc6syy3wDu6/39PDWGowAaGh1vXNO0A/FJ3kWInDUKITDBgv6ujtvGh zDOvNCAjC+lmEOU4Sj1OOHuY/k14k0Rh2eZvL/Kkem2p6tFoqfjaTVIk5auHvVtEZVoK Fbw3UIjkROfk2i6Qek0VfNBkE4hG+uU3u0cIGdVFT726+sR5ShAATnpdRWMvoa3ID2b7 GXN/RiTdyO0jcTRl9DPENawVLp9UMchsz45nMtXtkmSPjtnq1fvvfP+Ge9OwLApLLheD 36SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641656; x=1782246456; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Ltlo+66CbkzQq4Lsr4cyfZ7a+2/NQVI4939KsTGc97E=; b=RFEpdjMIRK5NtMWPNg/HGy56NmOHBtcyG5Zal4r8Y/kEaOHvUX7EhbIzBUNsMJnzPz wu5EKohoeFS4RQdDyCh04vNfn8KWrWd6BPpCTUEaTbX8IrDLh1KLlX6ofRgyp7YPXYF0 ZAZG63Uyny1/j2KU5+h2M2ZfoSPyMTxWR6MY9U1ufSjiKr4HVBoelAfAW5qFRgjghoBz bPwUXg5jc/0y10DzNIaEZguayZCOv9PgGYa9bk4AKnzV9grUl+vhsjmoBl8V/arOiN/c u/1wi9iX4Azc4w2ID+10h/A59ldxJxkK+sNQCOvUbf7EeffX55jpDNbDDNYoUkpOpw6C zcsg== X-Forwarded-Encrypted: i=1; AFNElJ+K7j1N2SpOw0IxQZGL5zWMKlRkAsSQS7BzJuS6TU+0GQJA3sdiHVV9/Z8kA+sbJN9Aex16sy8isRPZ7IE=@vger.kernel.org X-Gm-Message-State: AOJu0Yw09hW5cDm4Ls7ot2Y/7hbopab6mUeARhOaY+UXJM5QzRjY9Pj4 fN/DWWtrKlhngchYuxlDxc+AktE7B2O1Rti9l/nl9lBX/phgReZ9sJhx X-Gm-Gg: Acq92OGXAUe35udVbd6Cv623FfFdaiWcWDwOPHgR1pxJ4Uwgxs2R//GlYBOFJgFfao5 suoklfoOm+W66rj+GW4t5Q1E5IgPkhczS0RseGGjYlkxVzs8Dfm+gNL5TV1+inRCXtannKwf4E4 HKALx1zmEVOuX25K0RfpEckUaBEmWrg9wMIb+RuzXUavdBCfyZKlmovzhgLQWpec+YjL2utkKPK J94d8nfkGE3EQHIZHvDGK6+HwcfJWfpN6GLkuBMIlBT0uSaCfx+bAi4aWt+bwgXLYrKXCA4d2x9 D4P0eMoqbLpC205PjxZXwiRTpX+S9VYT4KkjVK10bWR9uCVbvYvrkqm9/tr/qQ4l3yrQsdOd6WV oLuCNtJemnvXN/epe+qs8qg5D3SiCjirEWG4Vby6TsxTzspwiEG3FAUp8PHTi+DuURHDcge5T1g z6lFXq9a6nXaIIBqZ4wAtO1/xHv3L513pleQ== X-Received: by 2002:a05:600c:a104:b0:492:3347:12a9 with SMTP id 5b1f17b1804b1-492334712camr12197255e9.26.1781641655477; Tue, 16 Jun 2026 13:27:35 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:34 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:31 +0300 Subject: [PATCH RFC v4 11/12] ARM: dts: zte: Declare zx297520v3 clock device nodes Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-11-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=5713; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=WCM0t2tSpKbIjViogFh06SwJ0ZwBBkr30bJ7ePaJsf4=; b=kA0DAAgBPRO8yFRPGiIByyZiAGoxsYaiDmVa7tF78rIc/+Vl7tgrhQY8mQM5Yh4KGvxwiGHNr IkCTwQAAQgAORYhBEMW9LaqBVsnlTJdbD0TvMhUTxoiBQJqMbGGGxSAAAAAAAQADm1hbnUyLDIu NSsxLjEyLDIsMgAKCRA9E7zIVE8aIpRhEACvKmqnDur7+8kPrK12EWu35XXeLXUinVJ0g/4I8QB ZqBj02ZtosMPs4FkVtdx2+9/iGDrf9cBcLN+YkzllQ+jP68E7Ps8GILZx0GqWZlMv9CeFz2DPZV AnwkfeuL4/9GF6rQXDdkaKa4bp7IFgnzkjvdgGzn4/TLoDQO0/YctobzHJZzAbOWra2gmdXqDuT G+RaSViXHnZZMjxB/UfBut8O/3w2IYUSnU7dnXCnAGJRMxoljKzDNXLSqzptpnvdQz5phTA3pTX nvk6Z5gDGgW0i1uCm+rwmBCUuZJWiFJ//A+Y1EcILgxaCsyP63gaxo/EMRKl+UEcLnxXMzB0vaz pWGDB+rOZwj1HBzc3khtcL68RO4CUHvAKlfmljai3o+B/RYrKRw9gu/TGyKkepDS2+xi5OzbDCp GCql6zX8Ig0DxNiU9RQ92P9Z5vcU1m/w2pq/UXy9xPUKluH50vKAQiXSTq/E8OnDMdTzJ9t1zKJ TapBwT+kd/UC/Ycv+38ci/h5lzKA/KkVkieL/1HR9pYokYpe/9sYTH0OEPmKoKD6rlegWD+s5dN wt104eqgKg3dZbwmXZ+cwxVO4W+Q5qeG7CkTrE+jOJ+1JTiwbapHBqL2SUyy/EAOoqW6HBVDKZM Cf4s78AXtxPhTrBhXYqLgUqvYTcSXtutnCoEMVmWDrg== X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This makes use of the driver added in the previous patches. It wires up the uart clocks and resets and allows getting rid of the placeholder uartclk node. Signed-off-by: Stefan D=C3=B6singer --- arch/arm/boot/dts/zte/zx297520v3.dtsi | 90 +++++++++++++++++++++++++++++++= ---- 1 file changed, 81 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/zte/zx297520v3.dtsi b/arch/arm/boot/dts/zte/= zx297520v3.dtsi index a16c30a164bb..a2b6909e7434 100644 --- a/arch/arm/boot/dts/zte/zx297520v3.dtsi +++ b/arch/arm/boot/dts/zte/zx297520v3.dtsi @@ -4,6 +4,7 @@ */ =20 #include +#include =20 / { #address-cells =3D <1>; @@ -20,13 +21,16 @@ cpu@0 { }; }; =20 - /* Base bus clock and default for the UART. It will be replaced once a cl= ock driver has - * been added. - */ - uartclk: uartclk-26000000 { - #clock-cells =3D <0>; + osc26m: osc26m { compatible =3D "fixed-clock"; clock-frequency =3D <26000000>; + #clock-cells =3D <0>; + }; + + osc32k: osc32k { + compatible =3D "fixed-clock"; + clock-frequency =3D <32768>; + #clock-cells =3D <0>; }; =20 timer { @@ -70,13 +74,80 @@ gic: interrupt-controller@f2000000 { <0xf2040000 0x20000>; }; =20 + topclk: clock-controller@13b000 { + compatible =3D "zte,zx297520v3-topclk", "syscon"; + reg =3D <0x0013b000 0x400>; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + clocks =3D <&osc26m>, <&osc32k>; + clock-names =3D "osc26m", "osc32k"; + }; + + matrixclk: clock-controller@1306000 { + compatible =3D "zte,zx297520v3-matrixclk", "syscon"; + reg =3D <0x01306000 0x400>; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + clocks =3D <&osc26m>, <&osc32k>, + <&topclk ZX297520V3_MPLL>, <&topclk ZX297520V3_MPLL_D2>, + <&topclk ZX297520V3_MPLL_D3>, <&topclk ZX297520V3_MPLL_D4>, + <&topclk ZX297520V3_MPLL_D5>, <&topclk ZX297520V3_MPLL_D6>, + <&topclk ZX297520V3_MPLL_D8>, <&topclk ZX297520V3_MPLL_D12>, + <&topclk ZX297520V3_MPLL_D16>, <&topclk ZX297520V3_MPLL_D26>, + <&topclk ZX297520V3_UPLL>, <&topclk ZX297520V3_UPLL_D2>, + <&topclk ZX297520V3_UPLL_D3>, <&topclk ZX297520V3_UPLL_D4>, + <&topclk ZX297520V3_UPLL_D5>, <&topclk ZX297520V3_UPLL_D6>, + <&topclk ZX297520V3_UPLL_D8>, <&topclk ZX297520V3_UPLL_D12>, + <&topclk ZX297520V3_UPLL_D16>, + <&topclk ZX297520V3_DPLL>, <&topclk ZX297520V3_DPLL_D2>, + <&topclk ZX297520V3_DPLL_D3>, <&topclk ZX297520V3_DPLL_D4>, + <&topclk ZX297520V3_DPLL_D5>, <&topclk ZX297520V3_DPLL_D6>, + <&topclk ZX297520V3_DPLL_D8>, <&topclk ZX297520V3_DPLL_D12>, + <&topclk ZX297520V3_DPLL_D16>, + <&topclk ZX297520V3_GPLL>, <&topclk ZX297520V3_GPLL_D2>, + <&topclk ZX297520V3_GPLL_D3>, <&topclk ZX297520V3_GPLL_D4>, + <&topclk ZX297520V3_GPLL_D5>, <&topclk ZX297520V3_GPLL_D6>, + <&topclk ZX297520V3_GPLL_D8>, <&topclk ZX297520V3_GPLL_D12>, + <&topclk ZX297520V3_GPLL_D16>; + clock-names =3D "osc26m", "osc32k", "mpll", "mpll_d2", "mpll_d3", "mpll= _d4", + "mpll_d5", "mpll_d6", "mpll_d8", "mpll_d12", "mpll_d16", + "mpll_d26", "upll", "upll_d2", "upll_d3", "upll_d4", + "upll_d5", "upll_d6", "upll_d8", "upll_d12", "upll_d16", + "dpll", "dpll_d2", "dpll_d3", "dpll_d4", "dpll_d5", "dpll_d6", + "dpll_d8", "dpll_d12", "dpll_d16", "gpll", "gpll_d2", + "gpll_d3", "gpll_d4", "gpll_d5", "gpll_d6", "gpll_d8", + "gpll_d12", "gpll_d16"; + }; + + lspclk: clock-controller@1400000 { + compatible =3D "zte,zx297520v3-lspclk"; + reg =3D <0x01400000 0x100>; + #clock-cells =3D <1>; + #reset-cells =3D <1>; + + clocks =3D <&matrixclk ZX297520V3_LSP_MPLL_D5_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D4_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D6_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D8_WCLK>, + <&matrixclk ZX297520V3_LSP_MPLL_D12_WCLK>, + <&matrixclk ZX297520V3_LSP_OSC26M_WCLK>, + <&matrixclk ZX297520V3_LSP_OSC32K_WCLK>, + <&matrixclk ZX297520V3_LSP_PCLK>, + <&matrixclk ZX297520V3_LSP_TDM_WCLK>, + <&matrixclk ZX297520V3_LSP_DPLL_D4_WCLK>; + clock-names =3D "mpll_d5", "mpll_d4", "mpll_d6", "mpll_d8", "mpll_d12", + "osc26m", "osc32k", "pclk", "tdm_wclk", "dpll_d4"; + }; + + uart0: serial@131000 { compatible =3D "arm,pl011", "arm,primecell"; arm,primecell-periphid =3D <0x0018c011>; reg =3D <0x00131000 0x1000>; interrupts =3D ; - clocks =3D <&uartclk>, <&uartclk>; + clocks =3D <&topclk ZX297520V3_UART0_WCLK>, <&topclk ZX297520V3_UART0_P= CLK>; clock-names =3D "uartclk", "apb_pclk"; + resets =3D <&topclk ZX297520V3_UART0_RESET>; status =3D "disabled"; }; =20 @@ -85,8 +156,9 @@ uart1: serial@1408000 { arm,primecell-periphid =3D <0x0018c011>; reg =3D <0x01408000 0x1000>; interrupts =3D ; - clocks =3D <&uartclk>, <&uartclk>; + clocks =3D <&lspclk ZX297520V3_UART1_WCLK>, <&lspclk ZX297520V3_UART1_P= CLK>; clock-names =3D "uartclk", "apb_pclk"; + resets =3D <&lspclk ZX297520V3_UART1_RESET>; status =3D "disabled"; }; =20 @@ -94,9 +166,9 @@ uart2: serial@140d000 { compatible =3D "arm,pl011", "arm,primecell"; arm,primecell-periphid =3D <0x0018c011>; reg =3D <0x0140d000 0x1000>; - interrupts =3D ; - clocks =3D <&uartclk>, <&uartclk>; + clocks =3D <&lspclk ZX297520V3_UART2_WCLK>, <&lspclk ZX297520V3_UART2_P= CLK>; clock-names =3D "uartclk", "apb_pclk"; + resets =3D <&lspclk ZX297520V3_UART2_RESET>; status =3D "disabled"; }; }; --=20 2.53.0 From nobody Fri Jun 19 17:22:28 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AA3C39A04A for ; Tue, 16 Jun 2026 20:27:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641662; cv=none; b=HrPVw/3CN0QJtY8moV7akLFWyyFswnjzyxuWmXIj7UM75CkZHjd3MSFCHUY6AyW2CWpj/vIqD+x5ao04Bj/I4uCdjLzRzBb6sWiVEADOU/ipTmfMFJU6OM6SeM9hwyMhoum/XObuPDWDEYTgaikRImFVAnIVoKzRFF/TdmISxsQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781641662; c=relaxed/simple; bh=dEe7AnhTFAr5p/XXrX/uCCb9oMxECR6QftpPnuBBlPY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eXIRteranF3Hr1tk3zSrb0C4qfsx+x0LRxwcI0DGfu/A8KHdzhqO4HzQ0to5daTEkn3w/MUmg6JREFaeSzsW0sgVJSVXUT+hKjJnlJ9yQvjTUL7ZNInKvu+FikURJ/gODKk0VoMpP3101WZJIwMJSgGpMx4wm1rJMiMzDAFYK1U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qBVxIJfa; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qBVxIJfa" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-491b390f9e9so42444235e9.0 for ; Tue, 16 Jun 2026 13:27:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781641660; x=1782246460; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=4T7EkkegVyODZ1yMUvqUb4I+TPr2uXbUfFIWfX/3x7g=; b=qBVxIJfayFVV2aFazRaPeUbEs9+fWNdVqCACaFiC33e613MwqIHfzDuBvHI/ar1imK TeSc0JVXlhmGe6rZPqGRxJCByU9FC6UPJcdNT9+ojIU9T1zRQUGDc4kqhAZN77Nyb7Wf 0VaNgk0oiiMA/WCc+hjO8Ocd72I6xJ45mjfG0onGryVu8u24A290O3pT3HiJoKuYsT2T I+8rN0hFPXKXuDS5V6qD4DckFLLNiFnbNVlWVxS217rbUkuHXaLB6a66CDnh9LOf4ILV qhumeSdUEzYspe2RypFYSsVgvK0hvradJJZAqIylirjbFMsAHE4Pz++q/iFHlx0BTr7a RkQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781641660; x=1782246460; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=4T7EkkegVyODZ1yMUvqUb4I+TPr2uXbUfFIWfX/3x7g=; b=PagEoyEcMUQTihtqOZMynCGcYj84W4Tij9Kw0JhCQO0URL83XPHbaoAc1OxcbV/6yX 24uwYG153pP82FXo3C4CyF2VJWQCtGDj/7J7WnFNlOk1FElASe1j59/EpkYUBK+Xg4Db Wzf9e08e0x+obUSM+zmtqKPTPRTFU0VWfoa3k6MMktNKlRqd1tK0FswHfugajRBDPPO2 gZPwZ93nJkWiUN7t42pGkaYmogbNXayvbzzT0J2o9w4soUDmKKwZFvbNRIyhBPd8K8RK OcgYVBRqFVwEfTVFFHJe5WgX3xQ/CCrpX8bT1Vumd2hhNkJkHeV6g2KIdhXQTzuWBdv2 9AAw== X-Forwarded-Encrypted: i=1; AFNElJ9CouF+POS4/G7vrInBgQeW8Crea4jGaTEBvoBEss/J+bSimPvOxzZWyWQ/ilUSnntLg1t3LKy4fSpBP8M=@vger.kernel.org X-Gm-Message-State: AOJu0YwIDOtYhnyOdLB13NpWJCwPVbeLzOyoqFPbE5iLcRVRSbh4AgmQ kLJoBHcCU1egG1b7heeVdivTKIjM2n8GCBfXIIcIiGuY1dbHIXYjb7ek X-Gm-Gg: Acq92OE2dxAj5hWAnAorM9Aj+l4FIGdjlmnFgWS3bd5cdtIf22w3mAS4pHZ2E0KhUGL 3LQ/P1ROF9c0vFDPrWWsk4pjsL03rH32cSGiqCizkmxjzexEObtOjEX8zWcUIZtpudmg2y/GY9e R+mfzwitJPH0LL84uYQ3fALMDWgh9hLVmvTwns1jxb15vKYYPOE9mLamT0h1RzWpfck0ie9NSfT c7AqcgIMEVimm99n2e+yIOAogIZYs5+29jcEAgv9NA0SXOjuHCwg8qkq9LwGgRdjF/EyViJUrn6 TLNvUaIIn9rqhXv34Snc0kHv0DCMvAVIGSJv3ygd5ZiMrspdlgYXygCo3jVKokezJzaTV+fa4d0 RFUNidNV6WzthXhYgCTfqpDkrMgMUbHnOKFiZHPc7UUOJSIX5Zf39paQYkswa/HbQCb9gCbdXfS l2/V/fAwrjn21/lS2zXoBVulMbEA2nDWpsHA== X-Received: by 2002:a7b:c3d1:0:b0:490:9df1:f0cf with SMTP id 5b1f17b1804b1-492333a1b10mr11488675e9.2.1781641659641; Tue, 16 Jun 2026 13:27:39 -0700 (PDT) Received: from [192.168.0.2] ([197.250.51.220]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49230a458f2sm89987005e9.3.2026.06.16.13.27.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Jun 2026 13:27:39 -0700 (PDT) From: =?utf-8?q?Stefan_D=C3=B6singer?= Date: Tue, 16 Jun 2026 23:26:32 +0300 Subject: [PATCH RFC v4 12/12] ARM: dts: zte: Add a syscon-reboot for zx297520v3 boards Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260616-zx29clk-v4-12-ca994bd22e9d@gmail.com> References: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> In-Reply-To: <20260616-zx29clk-v4-0-ca994bd22e9d@gmail.com> To: Michael Turquette , Stephen Boyd , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Philipp Zabel , Brian Masney Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, =?utf-8?q?Stefan_D=C3=B6singer?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=817; i=stefandoesinger@gmail.com; h=from:subject:message-id; bh=dEe7AnhTFAr5p/XXrX/uCCb9oMxECR6QftpPnuBBlPY=; b=owEBiQJ2/ZANAwAIAT0TvMhUTxoiAcsmYgBqMbGGdznTfH74HtE8ynnSgt60AzmAGzDzYjSBF v5tV/6RRTmJAk8EAAEIADkWIQRDFvS2qgVbJ5UyXWw9E7zIVE8aIgUCajGxhhsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQPRO8yFRPGiKHEw/9FhrXlF6q4Lzp5fUaLbRw/bc/1+9787X vYpRe2fXPGZx9mRtm/9BiFcwv84Yw1sVzTFxVOEfG69VjUX+Ku1D2Tk5Q8HT3O6fSn5I9lObMwt kboi/YHrRmec5FIxp8tVGKQSZ7IrtPMkJhQFDs/PzAq0ECfW1pgtVd/kw9s0WqVVliTP+Hu7io4 zeW8EPpUz4HrN9dB8PdC7wo6nL2keck2pwuIqPfxNRRRxItmUbOwNxNTAaZopvL12WPT/tnD0Xm w7TvVmXK6e8iEdznzirlzYc8akeQe2NveWLTO7yNOybrt/UmoWR/NNlkXa6McyKkSGHDRuG1VWB 7/UWwaQqyWW4CG96xs0PIV5zmFV1b4j6lLgnGoSV2YHR/RJ0DqAxBJ3vUhSouV+J7NNwkl4XUgr dYTiRMN4hzq/3imJh08ZRi7AzfZWU3pGob+CwmeCKzhrjYcDLpR8mFFRqGuaRkXpywo14b/jeK8 yD6ZCDRvH8hT1HXv6dAYhIxBnorfg57VBPMWUOM4NEWCTvQaV9MXLTO7V6GmkZ+TIeysUXU/aVa qyb5CKCJptLSpp4D17PARQZ2Vzg2ov9eomoWzLNZ2Sll7WyGs8tdeSwzdix48gEWPfUS+OLWVWE 3hfSH9JKGwoLDkvwwS9LQzW5/uwgcLIT3UeemWbz35claV7Zzc8k= X-Developer-Key: i=stefandoesinger@gmail.com; a=openpgp; fpr=4F9C2C8728019633893EBBB98CB81F9A72BBA155 This is fairly simple with the driver exposing a syscon regmap. Write a one to the lowest bit of register 0 and the board resets. Signed-off-by: Stefan D=C3=B6singer --- arch/arm/boot/dts/zte/zx297520v3.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/zte/zx297520v3.dtsi b/arch/arm/boot/dts/zte/= zx297520v3.dtsi index a2b6909e7434..013ece51c2a0 100644 --- a/arch/arm/boot/dts/zte/zx297520v3.dtsi +++ b/arch/arm/boot/dts/zte/zx297520v3.dtsi @@ -33,6 +33,13 @@ osc32k: osc32k { #clock-cells =3D <0>; }; =20 + syscon-reboot { + compatible =3D "syscon-reboot"; + regmap =3D <&topclk>; + offset =3D <0x0>; + mask =3D <0x1>; + }; + timer { compatible =3D "arm,armv7-timer"; interrupts =3D , --=20 2.53.0