mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 22:09:30 +02:00
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd: "Mostly the usual clk driver updates and new SoC additions plus non-critical data fixes for things that weren't used yet. One thing that's new here in the core is SSC spread spectrum support (SSC) in the clk provider API. The idea is that DT authors will configure SSC for certain clks and they'll be configured at clk provider registration time or when a consumer device is probed, similar to how we handle assigned clk rates or parents. On the clk driver side we have Qualcomm adding almost half the diff because they add support for 4 different SoCs and then a long tail of other SoCs like Mediatek, Renesas, Rockchip, SpaceMiT, etc. add more SoC support this time around. Luckily it's mostly clk data for these new SoCs because the actual clk_ops are already there. Beyond the new drivers we get all the little fixups for more compilation coverage or usage of more modern APIs. That all looks normal. Finally, I kinda buried the lede, I'm bringing on Brian and Jerome to help out with maintaining the clk subsystem. The current working model is already semi-distributed in that silicon vendors typically take care of their drivers and send me pull requests but I'm becoming a bottleneck for new drivers and core framework review because this has become a 100% volunteer effort on my part. Mike is stepping down after all these years (thanks Mike!) and that jump started the conversation around finding co-maintainers. Brian and Jerome have graciously offered to help me with the work load, meaning in the future they'll be sending pull requests and committing directly to the clk.git tree. They've both been around on the list for a while, I've met them both in person, and they've been making changes to the core clk framework along with helping review patches so I'm pretty confident this will work well. Core: - devm_clk_bulk_get_enable() consumer API - devm_clk_hw_register_composite_pdata() provider API - Spread Spectrum Clock (SSC) support via DT bindings and provider APIs - Divider clk rounding improved (and tested) New Drivers: - Cix Sky1 audio subsystem (AUDSS) - UltraRISC DP1000 - MediaTek MT8173 MFG_TOP - Si549 - Aspeed AST2700 PECI - Airoha EN7523 PCIe - Rockchip RV1106 - Mobileye EyeQ7H - Qualcomm Maili GCC, TCSR, RPMh, and video clks - Qualcomm Shikra GCC, RPM, GPU, display, and audio clks - Qualcomm Nord display and graphics clks - Qualcomm Glymur camera and EVA clks - Qualcomm Hawi video clks - Amlogic A9 AO and peripheral clks - Renesas R-Car X5H (R8A78000) CPG" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (269 commits) clk: microchip: mpfs: fix regmap_update_bits() mask/val order clk: visconti: Make sure clk_init_data is fully initialized clk: ti: Make sure clk_init_data is fully initialized MAINTAINERS: Add Brian Masney and Jerome Brunet as co-maintainers for clk subsystem Drop Michael Turquette's clk maintainer entry clk: ti: composite: resolve parent clocks by DT index, not by name clk: ti: mux: resolve parent clocks by DT index, not by name clk: devres: fix cleanup in devm_clk_get_optional_enabled_with_rate() dt-bindings: clock: ti,keystone-gate: Convert to DT schema dt-bindings: clock: ti: Convert APLL clock to DT schema clk: zynq: pll: Fix kernel-doc after determine_rate() conversion dt-bindings: clock: ti,clockdomain: Convert to DT schema dt-bindings: clock: Correct white-space style clk: samsung: Don't include <linux/mod_devicetable.h> clk: at91: Read "reg" with helper clk: renesas: Add R-Car X5H CPG driver clk: rockchip: rk3576: fix source muxes for SPI0..SPI4 clk: rockchip: Add clock controller for the RV1106 dt-bindings: clock: rockchip: Add RV1106 CRU support dt-bindings: clock: Document Renesas R-Car X5H Clock Pulse Generator ...
This commit is contained in:
@@ -4112,6 +4112,10 @@ S: 4226 Landgreen Street
|
||||
S: Rockville, Maryland 20853
|
||||
S: USA
|
||||
|
||||
N: Michael Turquette
|
||||
E: mturquette@baylibre.com
|
||||
D: common clk maintenance
|
||||
|
||||
N: Stephen Tweedie
|
||||
E: sct@redhat.com
|
||||
P: 1024/E7A417AD E2 FE A4 20 34 EC ED FC 7D 7E 67 8D E0 31 D1 69
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2026 Amlogic, Inc. All rights reserved
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/amlogic,a9-aoclkc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic A9 Series Always-On Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
- Jian Hu <jian.hu@amlogic.com>
|
||||
- Xianwei Zhao <xianwei.zhao@amlogic.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: amlogic,a9-aoclkc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
items:
|
||||
- description: input oscillator
|
||||
- description: input fclk div 3
|
||||
- description: input fclk div 4
|
||||
- description: input fclk div 5
|
||||
- description: input sys clk
|
||||
- description: external fixed 32k (optional)
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
items:
|
||||
- const: xtal
|
||||
- const: fdiv3
|
||||
- const: fdiv4
|
||||
- const: fdiv5
|
||||
- const: sys
|
||||
- const: ext_32k
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clock-controller@0 {
|
||||
compatible = "amlogic,a9-aoclkc";
|
||||
reg = <0x0 0x0 0x0 0x58>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&xtal>,
|
||||
<&scmi_clk 14>,
|
||||
<&scmi_clk 16>,
|
||||
<&scmi_clk 18>,
|
||||
<&scmi_clk 21>;
|
||||
clock-names = "xtal",
|
||||
"fdiv3",
|
||||
"fdiv4",
|
||||
"fdiv5",
|
||||
"sys";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,164 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2026 Amlogic, Inc. All rights reserved
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic A9 Series Peripherals Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Neil Armstrong <neil.armstrong@linaro.org>
|
||||
- Jerome Brunet <jbrunet@baylibre.com>
|
||||
- Jian Hu <jian.hu@amlogic.com>
|
||||
- Xianwei Zhao <xianwei.zhao@amlogic.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: amlogic,a9-peripherals-clkc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 27
|
||||
items:
|
||||
- description: input oscillator
|
||||
- description: input fclk div 2
|
||||
- description: input fclk div 3
|
||||
- description: input fclk div 4
|
||||
- description: input fclk div 5
|
||||
- description: input fclk div 7
|
||||
- description: input fclk div 2p5
|
||||
- description: input sys clk
|
||||
- description: input gp1 pll
|
||||
- description: input gp2 pll
|
||||
- description: input sys pll div 16
|
||||
- description: input cpu clk div 16
|
||||
- description: input a78 clk div 16
|
||||
- description: input dsu clk div 16
|
||||
- description: input rtc clk
|
||||
- description: input gp0 pll
|
||||
- description: input hifi0 pll
|
||||
- description: input hifi1 pll
|
||||
- description: input mclk0 pll
|
||||
- description: input mclk1 pll
|
||||
- description: input video1 pll
|
||||
- description: input video2 pll
|
||||
- description: input hdmi out2 clk
|
||||
- description: input hdmi pixel clk
|
||||
- description: input pixel0 pll
|
||||
- description: input pixel1 pll
|
||||
- description: input ddr pll test clk
|
||||
- description: external input rmii oscillator (optional)
|
||||
|
||||
clock-names:
|
||||
minItems: 27
|
||||
items:
|
||||
- const: xtal
|
||||
- const: fdiv2
|
||||
- const: fdiv3
|
||||
- const: fdiv4
|
||||
- const: fdiv5
|
||||
- const: fdiv7
|
||||
- const: fdiv2p5
|
||||
- const: sys
|
||||
- const: gp1
|
||||
- const: gp2
|
||||
- const: sysplldiv16
|
||||
- const: cpudiv16
|
||||
- const: a78div16
|
||||
- const: dsudiv16
|
||||
- const: rtc
|
||||
- const: gp0
|
||||
- const: hifi0
|
||||
- const: hifi1
|
||||
- const: mclk0
|
||||
- const: mclk1
|
||||
- const: vid1
|
||||
- const: vid2
|
||||
- const: hdmiout2
|
||||
- const: hdmipix
|
||||
- const: pix0
|
||||
- const: pix1
|
||||
- const: ddr_test
|
||||
- const: ext_rmii
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clock-controller@200 {
|
||||
compatible = "amlogic,a9-peripherals-clkc";
|
||||
reg = <0x0 0x200 0x0 0x2f8>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&xtal>,
|
||||
<&scmi_clk 10>,
|
||||
<&scmi_clk 12>,
|
||||
<&scmi_clk 14>,
|
||||
<&scmi_clk 16>,
|
||||
<&scmi_clk 18>,
|
||||
<&scmi_clk 20>,
|
||||
<&scmi_clk 21>,
|
||||
<&scmi_clk 33>,
|
||||
<&scmi_clk 34>,
|
||||
<&scmi_clk 35>,
|
||||
<&scmi_clk 36>,
|
||||
<&scmi_clk 37>,
|
||||
<&scmi_clk 38>,
|
||||
<&scmi_clk 40>,
|
||||
<&gp0 3>,
|
||||
<&hifi0 3>,
|
||||
<&hifi1 3>,
|
||||
<&mclk0 3>,
|
||||
<&mclk1 3>,
|
||||
<&vid1>,
|
||||
<&vid2>,
|
||||
<&hdmitx 10>,
|
||||
<&hdmitx 11>,
|
||||
<&pix0>,
|
||||
<&pix1>,
|
||||
<&ddr 3>;
|
||||
clock-names = "xtal",
|
||||
"fdiv2",
|
||||
"fdiv3",
|
||||
"fdiv4",
|
||||
"fdiv5",
|
||||
"fdiv7",
|
||||
"fdiv2p5",
|
||||
"sys",
|
||||
"gp1",
|
||||
"gp2",
|
||||
"sysplldiv16",
|
||||
"cpudiv16",
|
||||
"a78div16",
|
||||
"dsudiv16",
|
||||
"rtc",
|
||||
"gp0",
|
||||
"hifi0",
|
||||
"hifi1",
|
||||
"mclk0",
|
||||
"mclk1",
|
||||
"vid1",
|
||||
"vid2",
|
||||
"hdmiout2",
|
||||
"hdmipix",
|
||||
"pix0",
|
||||
"pix1",
|
||||
"ddr_test";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/eswin,eic7700-hspcrg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ESWIN EIC7700 HSP Clock and Reset Generator
|
||||
|
||||
maintainers:
|
||||
- Xuyang Dong <dongxuyang@eswincomputing.com>
|
||||
|
||||
description:
|
||||
Clock and reset generator for the ESWIN EIC7700 HSP (high-speed peripherals).
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: eswin,eic7700-hspcrg
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: HSP configuration top clock
|
||||
- description: MMC top clock
|
||||
- description: SATA top clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: cfg
|
||||
- const: mmc
|
||||
- const: sata
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description:
|
||||
See <dt-bindings/clock/eswin,eic7700-hspcrg.h> for valid indices.
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
description:
|
||||
See <dt-bindings/reset/eswin,eic7700-hspcrg.h> for valid indices.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@50440000 {
|
||||
compatible = "eswin,eic7700-hspcrg";
|
||||
reg = <0x50440000 0x2000>;
|
||||
clocks = <&clock 171>, <&clock 254>, <&clock 187>;
|
||||
clock-names = "cfg", "mmc", "sata";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -1,27 +0,0 @@
|
||||
Binding for Keystone gate control driver which uses PSC controller IP.
|
||||
|
||||
This binding uses the common clock binding[1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be "ti,keystone,psc-clock".
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
- clocks : parent clock phandle
|
||||
- reg : psc control and domain address address space
|
||||
- reg-names : psc control and domain registers
|
||||
- domain-id : psc domain id needed to check the transition state register
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : From common clock binding to override the
|
||||
default output clock name
|
||||
Example:
|
||||
clkusb: clkusb {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,keystone,psc-clock";
|
||||
clocks = <&chipclk16>;
|
||||
clock-output-names = "usb";
|
||||
reg = <0x02350008 0xb00>, <0x02350000 0x400>;
|
||||
reg-names = "control", "domain";
|
||||
domain-id = <0>;
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/clock/mediatek,mt8173-mfgtop.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek MT8173 MFG TOP controller
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
|
||||
description:
|
||||
The MFG TOP glue layer controls various signals going to the MFG (GPU)
|
||||
block on the MT8173.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt8173-mfgtop
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: sys
|
||||
- const: mem
|
||||
- const: core
|
||||
- const: clk26m
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- '#clock-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/mt8173-clk.h>
|
||||
#include <dt-bindings/power/mt8173-power.h>
|
||||
|
||||
clock-controller@13fff000 {
|
||||
compatible = "mediatek,mt8173-mfgtop";
|
||||
reg = <0x13fff000 0x1000>;
|
||||
clocks = <&topckgen CLK_TOP_AXI_MFG_IN_SEL>,
|
||||
<&topckgen CLK_TOP_MEM_MFG_IN_SEL>,
|
||||
<&topckgen CLK_TOP_MFG_SEL>,
|
||||
<&clk26m>;
|
||||
clock-names = "sys", "mem", "core", "clk26m";
|
||||
power-domains = <&spm MT8173_POWER_DOMAIN_MFG>;
|
||||
#clock-cells = <1>;
|
||||
#power-domain-cells = <0>;
|
||||
};
|
||||
@@ -65,7 +65,7 @@ examples:
|
||||
|
||||
- |
|
||||
pericfg@10003000 {
|
||||
compatible = "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon";
|
||||
compatible = "mediatek,mt7623-pericfg", "mediatek,mt2701-pericfg", "syscon";
|
||||
reg = <0x10003000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
||||
@@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,ipq5018-a53pll
|
||||
- qcom,ipq5210-a53pll
|
||||
- qcom,ipq5332-a53pll
|
||||
- qcom,ipq6018-a53pll
|
||||
- qcom,ipq8074-a53pll
|
||||
|
||||
@@ -25,19 +25,33 @@ properties:
|
||||
enum:
|
||||
- qcom,gcc-mdm9607
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: XO source
|
||||
- description: Sleep clock source
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: sleep_clk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#power-domain-cells'
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@900000 {
|
||||
clock-controller@1800000 {
|
||||
compatible = "qcom,gcc-mdm9607";
|
||||
reg = <0x900000 0x4000>;
|
||||
reg = <0x01800000 0x80000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
clocks = <&xo_board>, <&sleep_clk>;
|
||||
clock-names = "xo", "sleep_clk";
|
||||
};
|
||||
...
|
||||
|
||||
@@ -65,9 +65,15 @@ properties:
|
||||
- description: USB4 PHY 2 pcie pipe clock source
|
||||
- description: USB4 PHY 2 Max pipe clock source
|
||||
|
||||
power-domains:
|
||||
description:
|
||||
A phandle and PM domain specifier for the CX power domain.
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- power-domains
|
||||
- '#power-domain-cells'
|
||||
|
||||
allOf:
|
||||
@@ -78,6 +84,7 @@ unevaluatedProperties: false
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,glymur-gcc";
|
||||
reg = <0x100000 0x1f9000>;
|
||||
@@ -113,6 +120,7 @@ examples:
|
||||
<&usb4_phy_0_pcie_pipe>, <&usb4_phy_0_max_pipe>,
|
||||
<&usb4_phy_1_pcie_pipe>, <&usb4_phy_1_max_pipe>,
|
||||
<&usb4_phy_2_pcie_pipe>, <&usb4_phy_2_max_pipe>;
|
||||
power-domains = <&rpmhpd RPMHPD_CX>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,glymur-tcsr.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm TCSR Clock Controller on Glymur
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
- Taniya Das <taniya.das@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
Qualcomm TCSR clock control module provides the clocks, resets and
|
||||
power domains on Glymur
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,glymur-tcsr.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,glymur-tcsr
|
||||
- qcom,mahua-tcsr
|
||||
- const: syscon
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: TCXO pad clock
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
vdda-qrefrpt0-0p9-supply: true
|
||||
vdda-qrefrpt1-0p9-supply: true
|
||||
vdda-qrefrpt2-0p9-supply: true
|
||||
vdda-qrefrpt3-0p9-supply: true
|
||||
vdda-qrefrpt4-0p9-supply: true
|
||||
vdda-qrefrpt5-0p9-supply: true
|
||||
vdda-qrefrx0-0p9-supply: true
|
||||
vdda-qrefrx1-0p9-supply: true
|
||||
vdda-qrefrx2-0p9-supply: true
|
||||
vdda-qrefrx3-0p9-supply: true
|
||||
vdda-qrefrx4-0p9-supply: true
|
||||
vdda-qrefrx5-0p9-supply: true
|
||||
vdda-qreftx0-0p9-supply: true
|
||||
vdda-qreftx0-1p2-supply: true
|
||||
vdda-qreftx1-0p9-supply: true
|
||||
vdda-refgen3-0p9-supply: true
|
||||
vdda-refgen3-1p2-supply: true
|
||||
vdda-refgen4-0p9-supply: true
|
||||
vdda-refgen4-1p2-supply: true
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,glymur-tcsr
|
||||
then:
|
||||
required:
|
||||
- vdda-qrefrpt0-0p9-supply
|
||||
- vdda-qrefrpt1-0p9-supply
|
||||
- vdda-qrefrpt2-0p9-supply
|
||||
- vdda-qrefrpt3-0p9-supply
|
||||
- vdda-qrefrpt4-0p9-supply
|
||||
- vdda-qrefrx0-0p9-supply
|
||||
- vdda-qrefrx1-0p9-supply
|
||||
- vdda-qrefrx2-0p9-supply
|
||||
- vdda-qrefrx4-0p9-supply
|
||||
- vdda-qrefrx5-0p9-supply
|
||||
- vdda-qreftx0-0p9-supply
|
||||
- vdda-qreftx0-1p2-supply
|
||||
- vdda-qreftx1-0p9-supply
|
||||
- vdda-refgen3-0p9-supply
|
||||
- vdda-refgen3-1p2-supply
|
||||
- vdda-refgen4-0p9-supply
|
||||
- vdda-refgen4-1p2-supply
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,mahua-tcsr
|
||||
then:
|
||||
required:
|
||||
- vdda-qrefrpt0-0p9-supply
|
||||
- vdda-qrefrpt1-0p9-supply
|
||||
- vdda-qrefrpt2-0p9-supply
|
||||
- vdda-qrefrpt3-0p9-supply
|
||||
- vdda-qrefrpt4-0p9-supply
|
||||
- vdda-qrefrpt5-0p9-supply
|
||||
- vdda-qrefrx1-0p9-supply
|
||||
- vdda-qrefrx2-0p9-supply
|
||||
- vdda-qrefrx3-0p9-supply
|
||||
- vdda-qreftx1-0p9-supply
|
||||
- vdda-refgen3-0p9-supply
|
||||
- vdda-refgen3-1p2-supply
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clock-controller@1fd5000 {
|
||||
compatible = "qcom,glymur-tcsr", "syscon";
|
||||
reg = <0x0 0x1fd5000 0x0 0x21000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
vdda-qrefrpt0-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrpt1-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrpt2-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrpt3-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrpt4-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrx0-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrx1-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrx2-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrx4-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qrefrx5-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qreftx0-0p9-supply = <&vreg_l1a>;
|
||||
vdda-qreftx0-1p2-supply = <&vreg_l2a>;
|
||||
vdda-qreftx1-0p9-supply = <&vreg_l1a>;
|
||||
vdda-refgen3-0p9-supply = <&vreg_l1a>;
|
||||
vdda-refgen3-1p2-supply = <&vreg_l2a>;
|
||||
vdda-refgen4-0p9-supply = <&vreg_l1a>;
|
||||
vdda-refgen4-1p2-supply = <&vreg_l2a>;
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -8,16 +8,21 @@ title: Qualcomm Global Clock & Reset Controller on Hawi
|
||||
|
||||
maintainers:
|
||||
- Vivek Aknurwar <vivek.aknurwar@oss.qualcomm.com>
|
||||
- Taniya Das <taniya.das@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module provides the clocks, resets and power
|
||||
domains on Hawi.
|
||||
domains on Hawi and Maili.
|
||||
|
||||
See also: include/dt-bindings/clock/qcom,hawi-gcc.h
|
||||
See also:
|
||||
include/dt-bindings/clock/qcom,hawi-gcc.h
|
||||
include/dt-bindings/clock/qcom,maili-gcc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,hawi-gcc
|
||||
enum:
|
||||
- qcom,hawi-gcc
|
||||
- qcom,maili-gcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
||||
@@ -17,7 +17,13 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcm2290-dispcc
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,shikra-dispcc
|
||||
- const: qcom,qcm2290-dispcc
|
||||
- enum:
|
||||
- qcom,qcm2290-dispcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
@@ -37,10 +43,15 @@ properties:
|
||||
- const: dsi0_phy_pll_out_byteclk
|
||||
- const: dsi0_phy_pll_out_dsiclk
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: CX domain
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- '#power-domain-cells'
|
||||
|
||||
allOf:
|
||||
@@ -53,6 +64,7 @@ examples:
|
||||
#include <dt-bindings/clock/qcom,dispcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/power/qcom-rpmpd.h>
|
||||
clock-controller@5f00000 {
|
||||
compatible = "qcom,qcm2290-dispcc";
|
||||
reg = <0x5f00000 0x20000>;
|
||||
@@ -68,6 +80,7 @@ examples:
|
||||
"gcc_disp_gpll0_div_clk_src",
|
||||
"dsi0_phy_pll_out_byteclk",
|
||||
"dsi0_phy_pll_out_dsiclk";
|
||||
power-domains = <&rpmpd RPMPD_VDDCX>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
|
||||
@@ -18,7 +18,9 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcm2290-gpucc
|
||||
enum:
|
||||
- qcom,qcm2290-gpucc
|
||||
- qcom,shikra-gpucc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -16,36 +16,41 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,eliza-rpmh-clk
|
||||
- qcom,glymur-rpmh-clk
|
||||
- qcom,hawi-rpmh-clk
|
||||
- qcom,kaanapali-rpmh-clk
|
||||
- qcom,milos-rpmh-clk
|
||||
- qcom,nord-rpmh-clk
|
||||
- qcom,qcs615-rpmh-clk
|
||||
- qcom,qdu1000-rpmh-clk
|
||||
- qcom,sa8775p-rpmh-clk
|
||||
- qcom,sar2130p-rpmh-clk
|
||||
- qcom,sc7180-rpmh-clk
|
||||
- qcom,sc7280-rpmh-clk
|
||||
- qcom,sc8180x-rpmh-clk
|
||||
- qcom,sc8280xp-rpmh-clk
|
||||
- qcom,sdm670-rpmh-clk
|
||||
- qcom,sdm845-rpmh-clk
|
||||
- qcom,sdx55-rpmh-clk
|
||||
- qcom,sdx65-rpmh-clk
|
||||
- qcom,sdx75-rpmh-clk
|
||||
- qcom,sm4450-rpmh-clk
|
||||
- qcom,sm6350-rpmh-clk
|
||||
- qcom,sm8150-rpmh-clk
|
||||
- qcom,sm8250-rpmh-clk
|
||||
- qcom,sm8350-rpmh-clk
|
||||
- qcom,sm8450-rpmh-clk
|
||||
- qcom,sm8550-rpmh-clk
|
||||
- qcom,sm8650-rpmh-clk
|
||||
- qcom,sm8750-rpmh-clk
|
||||
- qcom,x1e80100-rpmh-clk
|
||||
oneOf:
|
||||
- enum:
|
||||
- qcom,eliza-rpmh-clk
|
||||
- qcom,glymur-rpmh-clk
|
||||
- qcom,hawi-rpmh-clk
|
||||
- qcom,kaanapali-rpmh-clk
|
||||
- qcom,milos-rpmh-clk
|
||||
- qcom,nord-rpmh-clk
|
||||
- qcom,qcs615-rpmh-clk
|
||||
- qcom,qdu1000-rpmh-clk
|
||||
- qcom,sa8775p-rpmh-clk
|
||||
- qcom,sar2130p-rpmh-clk
|
||||
- qcom,sc7180-rpmh-clk
|
||||
- qcom,sc7280-rpmh-clk
|
||||
- qcom,sc8180x-rpmh-clk
|
||||
- qcom,sc8280xp-rpmh-clk
|
||||
- qcom,sdm670-rpmh-clk
|
||||
- qcom,sdm845-rpmh-clk
|
||||
- qcom,sdx55-rpmh-clk
|
||||
- qcom,sdx65-rpmh-clk
|
||||
- qcom,sdx75-rpmh-clk
|
||||
- qcom,sm4450-rpmh-clk
|
||||
- qcom,sm6350-rpmh-clk
|
||||
- qcom,sm8150-rpmh-clk
|
||||
- qcom,sm8250-rpmh-clk
|
||||
- qcom,sm8350-rpmh-clk
|
||||
- qcom,sm8450-rpmh-clk
|
||||
- qcom,sm8550-rpmh-clk
|
||||
- qcom,sm8650-rpmh-clk
|
||||
- qcom,sm8750-rpmh-clk
|
||||
- qcom,x1e80100-rpmh-clk
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,maili-rpmh-clk
|
||||
- const: qcom,hawi-rpmh-clk
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,shikra-audiocorecc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Core Clock Controller for Qualcomm Shikra SoC
|
||||
|
||||
maintainers:
|
||||
- Imran Shaik <imran.shaik@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
Audio core clock control module provides the clocks on Qualcomm Shikra
|
||||
SoC platform.
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,shikra-audiocorecc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,shikra-audiocorecc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board sleep clock
|
||||
- description: Audio ref clock source
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
#include <dt-bindings/clock/qcom,shikra-gcc.h>
|
||||
clock-controller@a0a0000 {
|
||||
compatible = "qcom,shikra-audiocorecc";
|
||||
reg = <0x0a0a0000 0x10000>;
|
||||
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
|
||||
<&sleep_clk>,
|
||||
<&aud_ref_clk_src>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
...
|
||||
@@ -70,13 +70,11 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,kaanapali-cambistmclkcc
|
||||
- qcom,kaanapali-camcc
|
||||
- qcom,sc8280xp-camcc
|
||||
- qcom,sm8450-camcc
|
||||
- qcom,sm8550-camcc
|
||||
not:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8475-camcc
|
||||
- qcom,sm8650-camcc
|
||||
then:
|
||||
required:
|
||||
- required-opps
|
||||
|
||||
@@ -18,6 +18,8 @@ description: |
|
||||
include/dt-bindings/clock/qcom,glymur-gpucc.h
|
||||
include/dt-bindings/clock/qcom,kaanapali-gpucc.h
|
||||
include/dt-bindings/clock/qcom,milos-gpucc.h
|
||||
include/dt-bindings/clock/qcom,nord-gpu2cc.h
|
||||
include/dt-bindings/clock/qcom,nord-gpucc.h
|
||||
include/dt-bindings/clock/qcom,sar2130p-gpucc.h
|
||||
include/dt-bindings/clock/qcom,sm4450-gpucc.h
|
||||
include/dt-bindings/clock/qcom,sm8450-gpucc.h
|
||||
@@ -33,6 +35,8 @@ properties:
|
||||
- qcom,glymur-gpucc
|
||||
- qcom,kaanapali-gpucc
|
||||
- qcom,milos-gpucc
|
||||
- qcom,nord-gpu2cc
|
||||
- qcom,nord-gpucc
|
||||
- qcom,sar2130p-gpucc
|
||||
- qcom,sm4450-gpucc
|
||||
- qcom,sm8450-gpucc
|
||||
|
||||
@@ -16,7 +16,9 @@ description: |
|
||||
|
||||
See also:
|
||||
include/dt-bindings/clock/qcom,glymur-videocc.h
|
||||
include/dt-bindings/clock/qcom,hawi-videocc.h
|
||||
include/dt-bindings/clock/qcom,kaanapali-videocc.h
|
||||
include/dt-bindings/clock/qcom,maili-videocc.h
|
||||
include/dt-bindings/clock/qcom,sm8450-videocc.h
|
||||
include/dt-bindings/clock/qcom,sm8650-videocc.h
|
||||
include/dt-bindings/clock/qcom,sm8750-videocc.h
|
||||
@@ -26,7 +28,9 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-videocc
|
||||
- qcom,hawi-videocc
|
||||
- qcom,kaanapali-videocc
|
||||
- qcom,maili-videocc
|
||||
- qcom,sm8450-videocc
|
||||
- qcom,sm8475-videocc
|
||||
- qcom,sm8550-videocc
|
||||
@@ -65,14 +69,11 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,glymur-videocc
|
||||
- qcom,kaanapali-videocc
|
||||
- qcom,sm8450-videocc
|
||||
- qcom,sm8550-videocc
|
||||
- qcom,sm8750-videocc
|
||||
- qcom,x1p42100-videocc
|
||||
not:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,sm8475-videocc
|
||||
- qcom,sm8650-videocc
|
||||
then:
|
||||
required:
|
||||
- required-opps
|
||||
|
||||
@@ -16,6 +16,7 @@ description: |
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,kaanapali-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,nord-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8550-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8650-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8750-dispcc.h
|
||||
@@ -25,6 +26,8 @@ properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,kaanapali-dispcc
|
||||
- qcom,nord-dispcc0
|
||||
- qcom,nord-dispcc1
|
||||
- qcom,sar2130p-dispcc
|
||||
- qcom,sm8550-dispcc
|
||||
- qcom,sm8650-dispcc
|
||||
|
||||
@@ -16,7 +16,6 @@ description: |
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,eliza-tcsr.h
|
||||
- include/dt-bindings/clock/qcom,glymur-tcsr.h
|
||||
- include/dt-bindings/clock/qcom,hawi-tcsrcc.h
|
||||
- include/dt-bindings/clock/qcom,nord-tcsrcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8550-tcsr.h
|
||||
@@ -25,20 +24,25 @@ description: |
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,eliza-tcsr
|
||||
- qcom,glymur-tcsr
|
||||
- qcom,hawi-tcsrcc
|
||||
- qcom,kaanapali-tcsr
|
||||
- qcom,milos-tcsr
|
||||
- qcom,nord-tcsrcc
|
||||
- qcom,sar2130p-tcsr
|
||||
- qcom,sm8550-tcsr
|
||||
- qcom,sm8650-tcsr
|
||||
- qcom,sm8750-tcsr
|
||||
- qcom,x1e80100-tcsr
|
||||
- const: syscon
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,eliza-tcsr
|
||||
- qcom,hawi-tcsrcc
|
||||
- qcom,kaanapali-tcsr
|
||||
- qcom,milos-tcsr
|
||||
- qcom,nord-tcsrcc
|
||||
- qcom,sar2130p-tcsr
|
||||
- qcom,sm8550-tcsr
|
||||
- qcom,sm8650-tcsr
|
||||
- qcom,sm8750-tcsr
|
||||
- qcom,x1e80100-tcsr
|
||||
- const: syscon
|
||||
- items:
|
||||
- enum:
|
||||
- qcom,maili-tcsrcc
|
||||
- const: qcom,hawi-tcsrcc
|
||||
- const: syscon
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/renesas,r8a78000-cpg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas R-Car X5H Clock Pulse Generator
|
||||
|
||||
maintainers:
|
||||
- Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
|
||||
description:
|
||||
The R-Car X5H Clock Pulse Generator (CLK CONTROL) consists of oscillators,
|
||||
PLL circuits, clock dividers and clock control circuits. It provides various
|
||||
clocks for other modules.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r8a78000-cpg
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: extal
|
||||
- const: extalr
|
||||
|
||||
'#clock-cells':
|
||||
description:
|
||||
The single clock specifier cell must be the clock number, as defined in
|
||||
<dt-bindings/clock/renesas,r8a78000-cpg.h>.
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@c1320000 {
|
||||
compatible = "renesas,r8a78000-cpg";
|
||||
reg = <0xc1320000 0x10000>;
|
||||
clocks = <&extal_clk>, <&extalr_clk>;
|
||||
clock-names = "extal", "extalr";
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -26,16 +26,22 @@ properties:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
- description: AUDIO_EXTAL clock input
|
||||
- description: RTXIN clock input
|
||||
- description: QEXTAL clock input
|
||||
- description: AUDIO_CLKB clock input
|
||||
- description: AUDIO_CLKC clock input
|
||||
|
||||
clock-names:
|
||||
minItems: 3
|
||||
items:
|
||||
- const: audio_extal
|
||||
- const: rtxin
|
||||
- const: qextal
|
||||
- const: audio_clkb
|
||||
- const: audio_clkc
|
||||
|
||||
'#clock-cells':
|
||||
description: |
|
||||
|
||||
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: Renesas Versaclock7 Programmable Clock
|
||||
|
||||
maintainers:
|
||||
- Alex Helms <alexander.helms.jy@renesas.com>
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
||||
description: |
|
||||
Renesas Versaclock7 is a family of configurable clock generator and
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/rockchip,rv1106-cru.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip RV1106 Clock and Reset Unit
|
||||
|
||||
maintainers:
|
||||
- Simon Glass <sjg@chromium.org>
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
description:
|
||||
The RV1106 clock controller generates the clock and also implements a
|
||||
reset controller for SoC peripherals.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rockchip,rv1106-cru
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
"#reset-cells":
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: xin24m
|
||||
|
||||
rockchip,grf:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the syscon managing the "general register files" (GRF).
|
||||
If missing, pll rates are not changeable due to the missing pll
|
||||
lock status, and the MMC drive and sample phase clocks, whose
|
||||
control registers live in the GRF region, are not registered.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#clock-cells"
|
||||
- "#reset-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@ff3b0000 {
|
||||
compatible = "rockchip,rv1106-cru";
|
||||
reg = <0xff3b0000 0x20000>;
|
||||
rockchip,grf = <&grf>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/clock/silabs,si544.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Silicon Labs SI514/SI544 clock generator
|
||||
title: Silicon Labs SI514/SI544/SI549 clock generator
|
||||
|
||||
maintainers:
|
||||
- Mike Looijmans <mike.looijmans@topic.nl>
|
||||
@@ -13,8 +13,9 @@ description: >
|
||||
Silicon Labs 514/544 programmable I2C clock generator. Details about the device
|
||||
can be found in the datasheet:
|
||||
|
||||
https://www.silabs.com/Support%20Documents/TechnicalDocs/si514.pdf
|
||||
https://www.silabs.com/documents/public/data-sheets/si544-datasheet.pdf
|
||||
https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si514.pdf
|
||||
https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/si544-datasheet.pdf
|
||||
https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/si549-datasheet.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
@@ -23,6 +24,9 @@ properties:
|
||||
- silabs,si544a
|
||||
- silabs,si544b
|
||||
- silabs,si544c
|
||||
- silabs,si549a
|
||||
- silabs,si549b
|
||||
- silabs,si549c
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@@ -125,75 +125,75 @@ examples:
|
||||
reg = <0x44200000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&scmi_clk CK_SCMI_HSE>,
|
||||
<&scmi_clk CK_SCMI_HSI>,
|
||||
<&scmi_clk CK_SCMI_MSI>,
|
||||
<&scmi_clk CK_SCMI_LSE>,
|
||||
<&scmi_clk CK_SCMI_LSI>,
|
||||
<&scmi_clk CK_SCMI_HSE_DIV2>,
|
||||
<&scmi_clk CK_SCMI_ICN_HS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_LS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_SDMMC>,
|
||||
<&scmi_clk CK_SCMI_ICN_DDR>,
|
||||
<&scmi_clk CK_SCMI_ICN_DISPLAY>,
|
||||
<&scmi_clk CK_SCMI_ICN_HSL>,
|
||||
<&scmi_clk CK_SCMI_ICN_NIC>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_07>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_08>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_09>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_10>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_11>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_12>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_13>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_14>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_16>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_17>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_18>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_19>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_20>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_21>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_22>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_23>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_24>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_25>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_26>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_27>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_29>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_30>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_31>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_33>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_36>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_37>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_38>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_39>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_40>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_41>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_42>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_43>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_44>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_45>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_46>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_47>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_48>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_50>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_51>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_52>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_53>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_54>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_55>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_56>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_57>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_58>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_61>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_62>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_63>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB1>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB2>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB3>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB4>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB5>,
|
||||
<&scmi_clk CK_SCMI_ICN_APBDBG>,
|
||||
<&scmi_clk CK_SCMI_TIMG1>,
|
||||
<&scmi_clk CK_SCMI_TIMG2>;
|
||||
clocks = <&scmi_clk CK_SCMI_HSE>,
|
||||
<&scmi_clk CK_SCMI_HSI>,
|
||||
<&scmi_clk CK_SCMI_MSI>,
|
||||
<&scmi_clk CK_SCMI_LSE>,
|
||||
<&scmi_clk CK_SCMI_LSI>,
|
||||
<&scmi_clk CK_SCMI_HSE_DIV2>,
|
||||
<&scmi_clk CK_SCMI_ICN_HS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_LS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_SDMMC>,
|
||||
<&scmi_clk CK_SCMI_ICN_DDR>,
|
||||
<&scmi_clk CK_SCMI_ICN_DISPLAY>,
|
||||
<&scmi_clk CK_SCMI_ICN_HSL>,
|
||||
<&scmi_clk CK_SCMI_ICN_NIC>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_07>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_08>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_09>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_10>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_11>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_12>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_13>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_14>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_16>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_17>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_18>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_19>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_20>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_21>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_22>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_23>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_24>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_25>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_26>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_27>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_29>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_30>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_31>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_33>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_36>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_37>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_38>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_39>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_40>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_41>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_42>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_43>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_44>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_45>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_46>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_47>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_48>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_50>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_51>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_52>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_53>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_54>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_55>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_56>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_57>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_58>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_61>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_62>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_63>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB1>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB2>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB3>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB4>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB5>,
|
||||
<&scmi_clk CK_SCMI_ICN_APBDBG>,
|
||||
<&scmi_clk CK_SCMI_TIMG1>,
|
||||
<&scmi_clk CK_SCMI_TIMG2>;
|
||||
};
|
||||
...
|
||||
|
||||
@@ -135,85 +135,85 @@ examples:
|
||||
reg = <0x44200000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&scmi_clk CK_SCMI_HSE>,
|
||||
<&scmi_clk CK_SCMI_HSI>,
|
||||
<&scmi_clk CK_SCMI_MSI>,
|
||||
<&scmi_clk CK_SCMI_LSE>,
|
||||
<&scmi_clk CK_SCMI_LSI>,
|
||||
<&scmi_clk CK_SCMI_HSE_DIV2>,
|
||||
<&scmi_clk CK_SCMI_ICN_HS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_LS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_SDMMC>,
|
||||
<&scmi_clk CK_SCMI_ICN_DDR>,
|
||||
<&scmi_clk CK_SCMI_ICN_DISPLAY>,
|
||||
<&scmi_clk CK_SCMI_ICN_HSL>,
|
||||
<&scmi_clk CK_SCMI_ICN_NIC>,
|
||||
<&scmi_clk CK_SCMI_ICN_VID>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_07>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_08>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_09>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_10>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_11>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_12>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_13>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_14>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_15>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_16>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_17>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_18>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_19>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_20>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_21>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_22>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_23>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_24>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_25>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_26>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_27>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_28>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_29>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_30>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_31>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_32>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_33>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_34>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_35>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_36>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_37>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_38>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_39>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_40>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_41>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_42>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_43>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_44>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_45>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_46>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_47>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_48>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_49>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_50>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_51>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_52>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_53>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_54>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_55>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_56>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_57>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_58>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_59>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_60>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_61>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_62>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_63>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB1>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB2>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB3>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB4>,
|
||||
<&scmi_clk CK_SCMI_ICN_APBDBG>,
|
||||
<&scmi_clk CK_SCMI_TIMG1>,
|
||||
<&scmi_clk CK_SCMI_TIMG2>,
|
||||
<&scmi_clk CK_SCMI_PLL3>,
|
||||
<&clk_dsi_txbyte>;
|
||||
clocks = <&scmi_clk CK_SCMI_HSE>,
|
||||
<&scmi_clk CK_SCMI_HSI>,
|
||||
<&scmi_clk CK_SCMI_MSI>,
|
||||
<&scmi_clk CK_SCMI_LSE>,
|
||||
<&scmi_clk CK_SCMI_LSI>,
|
||||
<&scmi_clk CK_SCMI_HSE_DIV2>,
|
||||
<&scmi_clk CK_SCMI_ICN_HS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_LS_MCU>,
|
||||
<&scmi_clk CK_SCMI_ICN_SDMMC>,
|
||||
<&scmi_clk CK_SCMI_ICN_DDR>,
|
||||
<&scmi_clk CK_SCMI_ICN_DISPLAY>,
|
||||
<&scmi_clk CK_SCMI_ICN_HSL>,
|
||||
<&scmi_clk CK_SCMI_ICN_NIC>,
|
||||
<&scmi_clk CK_SCMI_ICN_VID>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_07>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_08>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_09>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_10>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_11>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_12>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_13>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_14>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_15>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_16>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_17>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_18>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_19>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_20>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_21>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_22>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_23>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_24>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_25>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_26>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_27>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_28>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_29>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_30>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_31>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_32>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_33>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_34>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_35>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_36>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_37>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_38>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_39>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_40>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_41>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_42>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_43>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_44>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_45>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_46>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_47>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_48>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_49>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_50>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_51>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_52>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_53>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_54>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_55>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_56>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_57>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_58>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_59>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_60>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_61>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_62>,
|
||||
<&scmi_clk CK_SCMI_FLEXGEN_63>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB1>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB2>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB3>,
|
||||
<&scmi_clk CK_SCMI_ICN_APB4>,
|
||||
<&scmi_clk CK_SCMI_ICN_APBDBG>,
|
||||
<&scmi_clk CK_SCMI_TIMG1>,
|
||||
<&scmi_clk CK_SCMI_TIMG2>,
|
||||
<&scmi_clk CK_SCMI_PLL3>,
|
||||
<&clk_dsi_txbyte>;
|
||||
};
|
||||
...
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti,keystone,psc-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI Keystone PSC clock
|
||||
|
||||
maintainers:
|
||||
- Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
- Murali Karicheri <m-karicheri2@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,keystone,psc-clock
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: PSC control
|
||||
- description: Domain
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: control
|
||||
- const: domain
|
||||
|
||||
domain-id:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: PSC domain id needed to check the transition state register
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- domain-id
|
||||
- clocks
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clkusb@2350008 {
|
||||
compatible = "ti,keystone,psc-clock";
|
||||
reg = <0x02350008 0xb00>, <0x02350000 0x400>;
|
||||
reg-names = "control", "domain";
|
||||
domain-id = <0>;
|
||||
clocks = <&chipclk16>;
|
||||
clock-output-names = "usb";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
Binding for Texas Instruments APLL clock.
|
||||
|
||||
This binding uses the common clock binding[1]. It assumes a
|
||||
register-mapped APLL with usually two selectable input clocks
|
||||
(reference clock and bypass clock), with analog phase locked
|
||||
loop logic for multiplying the input clock to a desired output
|
||||
clock. This clock also typically supports different operation
|
||||
modes (locked, low power stop etc.) APLL mostly behaves like
|
||||
a subtype of a DPLL [2], although a simplified one at that.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
[2] Documentation/devicetree/bindings/clock/ti/dpll.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be "ti,dra7-apll-clock" or "ti,omap2-apll-clock"
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
- clocks : link phandles of parent clocks (clk-ref and clk-bypass)
|
||||
- reg : address and length of the register set for controlling the APLL.
|
||||
It contains the information of registers in the following order:
|
||||
"control" - contains the control register offset
|
||||
"idlest" - contains the idlest register offset
|
||||
"autoidle" - contains the autoidle register offset (OMAP2 only)
|
||||
- ti,clock-frequency : static clock frequency for the clock (OMAP2 only)
|
||||
- ti,idlest-shift : bit-shift for the idlest field (OMAP2 only)
|
||||
- ti,bit-shift : bit-shift for enable and autoidle fields (OMAP2 only)
|
||||
|
||||
Examples:
|
||||
apll_pcie_ck: apll_pcie_ck {
|
||||
#clock-cells = <0>;
|
||||
clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>;
|
||||
reg = <0x021c>, <0x0220>;
|
||||
compatible = "ti,dra7-apll-clock";
|
||||
};
|
||||
|
||||
apll96_ck: apll96_ck {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,omap2-apll-clock";
|
||||
clocks = <&sys_ck>;
|
||||
ti,bit-shift = <2>;
|
||||
ti,idlest-shift = <8>;
|
||||
ti,clock-frequency = <96000000>;
|
||||
reg = <0x0500>, <0x0530>, <0x0520>;
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
Binding for Texas Instruments clockdomain.
|
||||
|
||||
This binding uses the common clock binding[1] in consumer role.
|
||||
Every clock on TI SoC belongs to one clockdomain, but software
|
||||
only needs this information for specific clocks which require
|
||||
their parent clockdomain to be controlled when the clock is
|
||||
enabled/disabled. This binding doesn't define a new clock
|
||||
binding type, it is used to group existing clock nodes under
|
||||
hardware hierarchy.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be "ti,clockdomain"
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
- clocks : link phandles of clocks within this domain
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : from common clock binding.
|
||||
|
||||
Examples:
|
||||
dss_clkdm: dss_clkdm {
|
||||
compatible = "ti,clockdomain";
|
||||
clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
|
||||
};
|
||||
@@ -0,0 +1,89 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti/ti,apll-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments APLL clock
|
||||
|
||||
maintainers:
|
||||
- Eduard Bostina <egbostina@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/clock/clock.yaml#
|
||||
|
||||
description:
|
||||
This binding assumes a register-mapped APLL with usually two selectable
|
||||
input clocks (reference clock and bypass clock), with analog phase locked
|
||||
loop logic for multiplying the input clock to a desired output clock.
|
||||
This clock also typically supports different operation modes (locked, low
|
||||
power stop etc.) APLL mostly behaves like a subtype of a DPLL, although
|
||||
a simplified one at that.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,dra7-apll-clock
|
||||
- ti,omap2-apll-clock
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
description: Link phandles of parent clocks (clk-ref and clk-bypass)
|
||||
|
||||
reg:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
description: |
|
||||
Address and length of the register set for controlling the APLL.
|
||||
It contains the information of registers in the following order:
|
||||
"control" - contains the control register offset
|
||||
"idlest" - contains the idlest register offset
|
||||
"autoidle" - contains the autoidle register offset (OMAP2 only)
|
||||
|
||||
ti,clock-frequency:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: static clock frequency for the clock (OMAP2 only)
|
||||
|
||||
ti,idlest-shift:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: bit-shift for the idlest field (OMAP2 only)
|
||||
|
||||
ti,bit-shift:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: bit-shift for enable and autoidle fields (OMAP2 only)
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clock@21c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,dra7-apll-clock";
|
||||
clocks = <&apll_pcie_in_clk_mux>, <&dpll_pcie_ref_ck>;
|
||||
reg = <0x021c>, <0x0220>;
|
||||
};
|
||||
|
||||
clock@500 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,omap2-apll-clock";
|
||||
clocks = <&sys_ck>;
|
||||
ti,bit-shift = <2>;
|
||||
ti,idlest-shift = <8>;
|
||||
ti,clock-frequency = <96000000>;
|
||||
reg = <0x0500>, <0x0530>, <0x0520>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti/ti,clockdomain.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments clockdomain
|
||||
|
||||
maintainers:
|
||||
- Tero Kristo <kristo@kernel.org>
|
||||
|
||||
description:
|
||||
This binding uses the common clock binding in consumer role. Every clock on TI
|
||||
SoC belongs to one clockdomain, but software only needs this information for
|
||||
specific clocks which require their parent clockdomain to be controlled when
|
||||
the clock is enabled/disabled. This binding doesn't define a new clock binding
|
||||
type, it is used to group existing clock nodes under hardware hierarchy.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,clockdomain
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 64
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
dss_clkdm {
|
||||
compatible = "ti,clockdomain";
|
||||
clocks = <&dss1_alwon_fck_3430es2>, <&dss_ick_3430es2>;
|
||||
};
|
||||
@@ -19,7 +19,7 @@ description: |
|
||||
that is used.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
|
||||
[2] Documentation/devicetree/bindings/clock/ti/clockdomain.txt
|
||||
[2] Documentation/devicetree/bindings/clock/ti/ti,clockdomain.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ultrarisc,dp1000-clk.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: UltraRISC DP1000 Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Jia Wang <wangjia@ultrarisc.com>
|
||||
|
||||
description: |
|
||||
The UltraRISC DP1000 clock controller is driven from a single external
|
||||
oscillator input. It provides a system PLL with fractional multiplier
|
||||
and post-divider stages, several fixed-ratio derived clocks for
|
||||
the on-chip subsystem, Clock Configuration Register (CCR) divider
|
||||
outputs for GMAC and the UART, I2C, and SPI root clocks, and
|
||||
per-instance gate clocks for UART0-3, I2C0-3, and SPI0-1.
|
||||
|
||||
All available clocks are defined as preprocessor macros in
|
||||
include/dt-bindings/clock/ultrarisc,dp1000-clk.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ultrarisc,dp1000-clk
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
External oscillator input clock used as the parent of the PLLs.
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/ultrarisc,dp1000-clk.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clock-controller@11080000 {
|
||||
compatible = "ultrarisc,dp1000-clk";
|
||||
reg = <0x0 0x11080000 0x0 0x1000>;
|
||||
clocks = <&osc>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
||||
@@ -70,7 +70,7 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@b0000000 {
|
||||
clock-controller@b0000000 {
|
||||
compatible = "xlnx,clocking-wizard";
|
||||
reg = <0xb0000000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
@@ -75,7 +75,7 @@ SoCs only:
|
||||
|
||||
- clocks: Should contain the device's input clock, and should be
|
||||
defined as per the bindings in,
|
||||
Documentation/devicetree/bindings/clock/keystone-gate.txt
|
||||
Documentation/devicetree/bindings/clock/ti,keystone,psc-clock.yaml
|
||||
|
||||
The following are mandatory properties for Keystone 2 66AK2G SoCs only:
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/reset/qcom,shikra-audiocore-csr.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Audio Core CSR for Qualcomm Shikra SoC
|
||||
|
||||
maintainers:
|
||||
- Imran Shaik <imran.shaik@oss.qualcomm.com>
|
||||
|
||||
description: |
|
||||
Audio Core CSR module provides the resets on Qualcomm Shikra SoC platform.
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,shikra-audiocorecc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,shikra-audiocore-csr
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#reset-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
reset-controller@a0b4000 {
|
||||
compatible = "qcom,shikra-audiocore-csr";
|
||||
reg = <0x0a0b4000 0x1000>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
...
|
||||
@@ -33,6 +33,7 @@ properties:
|
||||
- enum:
|
||||
- allwinner,sun20i-d1-rtc
|
||||
- allwinner,sun55i-a523-rtc
|
||||
- allwinner,sun60i-a733-rtc
|
||||
- const: allwinner,sun50i-r329-rtc
|
||||
|
||||
reg:
|
||||
@@ -175,6 +176,18 @@ allOf:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- allwinner,sun50i-h616-rtc
|
||||
- allwinner,sun50i-r329-rtc
|
||||
|
||||
then:
|
||||
properties:
|
||||
clock-output-names: false
|
||||
|
||||
required:
|
||||
- "#clock-cells"
|
||||
- compatible
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/cix/cix,sky1-audss-cru.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Cix Sky1 audio subsystem clock and reset unit
|
||||
|
||||
maintainers:
|
||||
- Joakim Zhang <joakim.zhang@cixtech.com>
|
||||
|
||||
description: |
|
||||
The Cix Sky1 Audio Subsystem (AUDSS) Clock and Reset Unit (CRU) groups
|
||||
audio-related clock muxing, gating and block-level software reset control
|
||||
in a single register block.
|
||||
|
||||
A single device node exposes both the clock controller and software reset
|
||||
lines. The clock driver registers as a platform driver; the reset controller
|
||||
is registered by an auxiliary driver bound from the clock driver.
|
||||
|
||||
Four SoC-level reference clocks listed in clocks/clock-names feed the AUDSS
|
||||
clock tree. Internal AUDSS clocks are exposed via #clock-cells; indices are
|
||||
defined in include/dt-bindings/clock/cix,sky1-audss-cru.h.
|
||||
|
||||
Block-level software reset indices are exposed via #reset-cells; indices
|
||||
are defined in include/dt-bindings/reset/cix,sky1-audss-cru.h.
|
||||
|
||||
The SoC syscon NoC (or bus) reset is described via resets. The audio
|
||||
subsystem power domain is described via power-domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: cix,sky1-audss-cru
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description:
|
||||
Clock indices are defined in include/dt-bindings/clock/cix,sky1-audss-cru.h.
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
description:
|
||||
Reset indices are defined in include/dt-bindings/reset/cix,sky1-audss-cru.h.
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: I2S parent clock for sampling rates multiple of 8kHz.
|
||||
- description: I2S parent clock for sampling rates multiple of 11.025kHz.
|
||||
- description: Clock feeding most devices in AUDSS (NOC, DSP, SRAM, HDA, DMAC, I2S, and mailbox).
|
||||
- description: Clock feeding HDA, timer and watchdog, which is a dedicated 48 MHz clock.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: x8k
|
||||
- const: x11k
|
||||
- const: sys
|
||||
- const: 48m
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
audss_cru: clock-controller@7110000 {
|
||||
compatible = "cix,sky1-audss-cru";
|
||||
reg = <0x7110000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&scmi_clk 76>, <&scmi_clk 78>,
|
||||
<&scmi_clk 70>, <&scmi_clk 71>;
|
||||
clock-names = "x8k", "x11k", "sys", "48m";
|
||||
power-domains = <&smc_devpd 0>;
|
||||
resets = <&s5_syscon 31>;
|
||||
};
|
||||
@@ -0,0 +1,192 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/soc/mobileye/mobileye,eyeq7h-olb.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Mobileye EyeQ7H SoC system controller
|
||||
|
||||
maintainers:
|
||||
- Benoît Monin <benoit.monin@bootlin.com>
|
||||
- Grégory Clement <gregory.clement@bootlin.com>
|
||||
- Théo Lebrun <theo.lebrun@bootlin.com>
|
||||
- Vladimir Kondratiev <vladimir.kondratiev@mobileye.com>
|
||||
|
||||
description:
|
||||
OLB ("Other Logic Block") is a hardware system controller grouping
|
||||
smaller blocks. Clocks and resets are generated by those blocks and
|
||||
used by internal controllers of the SoC. The EyeQ7H SoC hosts 14
|
||||
different OLB.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- mobileye,eyeq7h-acc0-olb
|
||||
- mobileye,eyeq7h-acc1-olb
|
||||
- mobileye,eyeq7h-ddr0-olb
|
||||
- mobileye,eyeq7h-ddr1-olb
|
||||
- mobileye,eyeq7h-east-olb
|
||||
- mobileye,eyeq7h-mips0-olb
|
||||
- mobileye,eyeq7h-mips1-olb
|
||||
- mobileye,eyeq7h-mips2-olb
|
||||
- mobileye,eyeq7h-periph-east-olb
|
||||
- mobileye,eyeq7h-periph-west-olb
|
||||
- mobileye,eyeq7h-south-olb
|
||||
- mobileye,eyeq7h-west-olb
|
||||
- mobileye,eyeq7h-xnn0-olb
|
||||
- mobileye,eyeq7h-xnn1-olb
|
||||
- const: syscon
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#reset-cells':
|
||||
description:
|
||||
First cell is domain and optional if compatible has a single reset domain.
|
||||
Second cell is reset index inside that domain.
|
||||
enum: [ 1, 2 ]
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-ddr0-olb
|
||||
- mobileye,eyeq7h-ddr1-olb
|
||||
- mobileye,eyeq7h-mips0-olb
|
||||
- mobileye,eyeq7h-mips1-olb
|
||||
- mobileye,eyeq7h-mips2-olb
|
||||
- mobileye,eyeq7h-periph-east-olb
|
||||
- mobileye,eyeq7h-south-olb
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Reference input clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-east-olb
|
||||
- mobileye,eyeq7h-west-olb
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Reference input clock from the main oscillator.
|
||||
- description: 100MHz reference input clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
- const: ref_100p0
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-acc0-olb
|
||||
- mobileye,eyeq7h-acc1-olb
|
||||
- mobileye,eyeq7h-periph-west-olb
|
||||
- mobileye,eyeq7h-xnn0-olb
|
||||
- mobileye,eyeq7h-xnn1-olb
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: 100MHz reference input clock.
|
||||
- description: 106.6MHz reference input clock.
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref_100p0
|
||||
- const: ref_106p6
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-ddr0-olb
|
||||
- mobileye,eyeq7h-ddr1-olb
|
||||
- mobileye,eyeq7h-east-olb
|
||||
- mobileye,eyeq7h-periph-east-olb
|
||||
- mobileye,eyeq7h-periph-west-olb
|
||||
- mobileye,eyeq7h-west-olb
|
||||
then:
|
||||
properties:
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
required:
|
||||
- '#reset-cells'
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-acc0-olb
|
||||
- mobileye,eyeq7h-acc1-olb
|
||||
- mobileye,eyeq7h-south-olb
|
||||
- mobileye,eyeq7h-xnn0-olb
|
||||
- mobileye,eyeq7h-xnn1-olb
|
||||
then:
|
||||
properties:
|
||||
'#reset-cells':
|
||||
const: 2
|
||||
required:
|
||||
- '#reset-cells'
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mobileye,eyeq7h-mips0-olb
|
||||
- mobileye,eyeq7h-mips1-olb
|
||||
- mobileye,eyeq7h-mips2-olb
|
||||
then:
|
||||
properties:
|
||||
'#reset-cells': false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
system-controller0@45000000 {
|
||||
compatible = "mobileye,eyeq7h-acc0-olb", "syscon";
|
||||
reg = <0x0 0x45000000 0x0 0x1000>;
|
||||
#reset-cells = <2>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&olb_south 7>, <&olb_east 5>;
|
||||
clock-names = "ref_100p0", "ref_106p6";
|
||||
};
|
||||
};
|
||||
@@ -42,21 +42,8 @@ clock interface.
|
||||
Common data structures and api
|
||||
==============================
|
||||
|
||||
Below is the common struct clk_core definition from
|
||||
drivers/clk/clk.c, modified for brevity::
|
||||
|
||||
struct clk_core {
|
||||
const char *name;
|
||||
const struct clk_ops *ops;
|
||||
struct clk_hw *hw;
|
||||
struct module *owner;
|
||||
struct clk_core *parent;
|
||||
const char **parent_names;
|
||||
struct clk_core **parents;
|
||||
u8 num_parents;
|
||||
u8 new_parent_index;
|
||||
...
|
||||
};
|
||||
.. kernel-doc:: drivers/clk/clk.c
|
||||
:identifiers: struct clk_core
|
||||
|
||||
The members above make up the core of the clk tree topology. The clk
|
||||
api itself defines several driver-facing functions which operate on
|
||||
@@ -64,38 +51,17 @@ struct clk. That api is documented in include/linux/clk.h.
|
||||
|
||||
Platforms and devices utilizing the common struct clk_core use the struct
|
||||
clk_ops pointer in struct clk_core to perform the hardware-specific parts of
|
||||
the operations defined in clk-provider.h::
|
||||
the operations defined in clk-provider.h, and can set one or more
|
||||
framework-level flags documented below.
|
||||
|
||||
struct clk_ops {
|
||||
int (*prepare)(struct clk_hw *hw);
|
||||
void (*unprepare)(struct clk_hw *hw);
|
||||
int (*is_prepared)(struct clk_hw *hw);
|
||||
void (*unprepare_unused)(struct clk_hw *hw);
|
||||
int (*enable)(struct clk_hw *hw);
|
||||
void (*disable)(struct clk_hw *hw);
|
||||
int (*is_enabled)(struct clk_hw *hw);
|
||||
void (*disable_unused)(struct clk_hw *hw);
|
||||
unsigned long (*recalc_rate)(struct clk_hw *hw,
|
||||
unsigned long parent_rate);
|
||||
int (*determine_rate)(struct clk_hw *hw,
|
||||
struct clk_rate_request *req);
|
||||
int (*set_parent)(struct clk_hw *hw, u8 index);
|
||||
u8 (*get_parent)(struct clk_hw *hw);
|
||||
int (*set_rate)(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate);
|
||||
int (*set_rate_and_parent)(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
u8 index);
|
||||
unsigned long (*recalc_accuracy)(struct clk_hw *hw,
|
||||
unsigned long parent_accuracy);
|
||||
int (*get_phase)(struct clk_hw *hw);
|
||||
int (*set_phase)(struct clk_hw *hw, int degrees);
|
||||
void (*init)(struct clk_hw *hw);
|
||||
void (*debug_init)(struct clk_hw *hw,
|
||||
struct dentry *dentry);
|
||||
};
|
||||
.. kernel-doc:: include/linux/clk-provider.h
|
||||
:identifiers: struct clk_ops
|
||||
|
||||
Core flags
|
||||
==========
|
||||
|
||||
.. kernel-doc:: include/linux/clk-provider.h
|
||||
:doc: clk framework flags
|
||||
|
||||
Hardware clk implementations
|
||||
============================
|
||||
|
||||
@@ -248,6 +248,7 @@ CLOCK
|
||||
devm_clk_put()
|
||||
devm_clk_bulk_get()
|
||||
devm_clk_bulk_get_all()
|
||||
devm_clk_bulk_get_enable()
|
||||
devm_clk_bulk_get_optional()
|
||||
devm_get_clk_from_child()
|
||||
devm_clk_hw_register()
|
||||
|
||||
+17
-6
@@ -6494,9 +6494,9 @@ F: include/linux/comedi/
|
||||
F: include/uapi/linux/comedi.h
|
||||
|
||||
COMMON CLK FRAMEWORK
|
||||
M: Michael Turquette <mturquette@baylibre.com>
|
||||
M: Stephen Boyd <sboyd@kernel.org>
|
||||
R: Brian Masney <bmasney@redhat.com>
|
||||
M: Brian Masney <bmasney+clk@redhat.com>
|
||||
M: Jerome Brunet <jbrunet+clk@baylibre.com>
|
||||
L: linux-clk@vger.kernel.org
|
||||
S: Maintained
|
||||
Q: http://patchwork.kernel.org/project/linux-clk/list/
|
||||
@@ -9729,9 +9729,10 @@ ESWIN EIC7700 CLOCK DRIVER
|
||||
M: Yifeng Huang <huangyifeng@eswincomputing.com>
|
||||
M: Xuyang Dong <dongxuyang@eswincomputing.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml
|
||||
F: Documentation/devicetree/bindings/clock/eswin,eic7700*
|
||||
F: drivers/clk/eswin/
|
||||
F: include/dt-bindings/clock/eswin,eic7700-clock.h
|
||||
F: include/dt-bindings/clock/eswin,eic7700*
|
||||
F: include/dt-bindings/reset/eswin,eic7700-hspcrg.h
|
||||
|
||||
ET131X NETWORK DRIVER
|
||||
M: Mark Einon <mark.einon@gmail.com>
|
||||
@@ -23337,10 +23338,12 @@ L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
|
||||
|
||||
RENESAS VERSACLOCK 7 CLOCK DRIVER
|
||||
M: Alex Helms <alexander.helms.jy@renesas.com>
|
||||
RENESAS VERSACLOCK 3 and VERSACLOCK 7 CLOCK DRIVER
|
||||
M: Biju Das <biju.das.jz@bp.renesas.com>
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/renesas,5p35023.yaml
|
||||
F: Documentation/devicetree/bindings/clock/renesas,versaclock7.yaml
|
||||
F: drivers/clk/clk-versaclock3.c
|
||||
F: drivers/clk/clk-versaclock7.c
|
||||
|
||||
RENESAS X9250 DIGITAL POTENTIOMETERS DRIVER
|
||||
@@ -27967,6 +27970,14 @@ S: Maintained
|
||||
F: drivers/usb/common/ulpi.c
|
||||
F: include/linux/ulpi/
|
||||
|
||||
ULTRARISC DP1000 CLOCK DRIVER
|
||||
M: Jia Wang <wangjia@ultrarisc.com>
|
||||
L: linux-clk@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/clock/ultrarisc,dp1000-clk.yaml
|
||||
F: drivers/clk/ultrarisc/*
|
||||
F: include/dt-bindings/clock/ultrarisc,dp1000-clk.h
|
||||
|
||||
ULTRARISC DP1000 PINCTRL DRIVER
|
||||
M: Jia Wang <wangjia@ultrarisc.com>
|
||||
L: linux-gpio@vger.kernel.org
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/cix,sky1.h>
|
||||
#include <dt-bindings/clock/cix,sky1-audss-cru.h>
|
||||
#include <dt-bindings/reset/cix,sky1-system-control.h>
|
||||
#include <dt-bindings/reset/cix,sky1-s5-system-control.h>
|
||||
#include <dt-bindings/reset/cix,sky1-audss-cru.h>
|
||||
#include "sky1-power.h"
|
||||
|
||||
/ {
|
||||
@@ -572,6 +576,20 @@
|
||||
cix,mbox-dir = "rx";
|
||||
};
|
||||
|
||||
audss_cru: clock-controller@7110000 {
|
||||
compatible = "cix,sky1-audss-cru";
|
||||
reg = <0x0 0x07110000 0x0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>,
|
||||
<&scmi_clk CLK_TREE_AUDIO_CLK2>,
|
||||
<&scmi_clk CLK_TREE_AUDIO_CLK4>,
|
||||
<&scmi_clk CLK_TREE_AUDIO_CLK5>;
|
||||
clock-names = "x8k", "x11k", "sys", "48m";
|
||||
power-domains = <&smc_devpd SKY1_PD_AUDIO>;
|
||||
resets = <&s5_syscon SKY1_AUDIO_HIFI5_NOC_RESET_N>;
|
||||
};
|
||||
|
||||
mbox_sfh2ap: mailbox@8090000 {
|
||||
compatible = "cix,sky1-mbox";
|
||||
reg = <0x0 0x08090000 0x0 0x10000>;
|
||||
|
||||
@@ -4,6 +4,7 @@ CONFIG_OF=y
|
||||
CONFIG_OF_OVERLAY=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
CONFIG_CLK_KUNIT_TEST=y
|
||||
CONFIG_CLK_DIVIDER_KUNIT_TEST=y
|
||||
CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y
|
||||
CONFIG_CLK_GATE_KUNIT_TEST=y
|
||||
CONFIG_CLK_FD_KUNIT_TEST=y
|
||||
|
||||
+14
-4
@@ -155,12 +155,12 @@ config COMMON_CLK_SI514
|
||||
generator.
|
||||
|
||||
config COMMON_CLK_SI544
|
||||
tristate "Clock driver for SiLabs 544 devices"
|
||||
tristate "Clock driver for SiLabs 544 and compatible devices"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports the Silicon Labs 544 programmable clock
|
||||
generator.
|
||||
This driver supports the Silicon Labs 544/549 programmable clock
|
||||
generators.
|
||||
|
||||
config COMMON_CLK_SI570
|
||||
tristate "Clock driver for SiLabs 570 and compatible devices"
|
||||
@@ -278,7 +278,7 @@ config COMMON_CLK_LAN966X
|
||||
tristate "Generic Clock Controller driver for LAN966X SoC"
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
depends on SOC_LAN966 || ARCH_LAN969X || COMPILE_TEST
|
||||
depends on SOC_LAN966 || ARCH_LAN969X || MCHP_LAN966X_PCI || COMPILE_TEST
|
||||
help
|
||||
This driver provides support for Generic Clock Controller(GCK) on
|
||||
LAN966X SoC. GCK generates and supplies clock to various peripherals
|
||||
@@ -509,6 +509,7 @@ source "drivers/clk/actions/Kconfig"
|
||||
source "drivers/clk/analogbits/Kconfig"
|
||||
source "drivers/clk/aspeed/Kconfig"
|
||||
source "drivers/clk/bcm/Kconfig"
|
||||
source "drivers/clk/cix/Kconfig"
|
||||
source "drivers/clk/eswin/Kconfig"
|
||||
source "drivers/clk/hisilicon/Kconfig"
|
||||
source "drivers/clk/imgtec/Kconfig"
|
||||
@@ -541,6 +542,7 @@ source "drivers/clk/tenstorrent/Kconfig"
|
||||
source "drivers/clk/thead/Kconfig"
|
||||
source "drivers/clk/stm32/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
source "drivers/clk/ultrarisc/Kconfig"
|
||||
source "drivers/clk/uniphier/Kconfig"
|
||||
source "drivers/clk/visconti/Kconfig"
|
||||
source "drivers/clk/x86/Kconfig"
|
||||
@@ -579,4 +581,12 @@ config CLK_FD_KUNIT_TEST
|
||||
help
|
||||
Kunit test for the clk-fractional-divider type.
|
||||
|
||||
config CLK_DIVIDER_KUNIT_TEST
|
||||
tristate "KUnit tests for clk divider bestdiv" if !KUNIT_ALL_TESTS
|
||||
depends on KUNIT
|
||||
depends on !S390
|
||||
default KUNIT_ALL_TESTS
|
||||
help
|
||||
Kunit test for the clk-divider type.
|
||||
|
||||
endif
|
||||
|
||||
+18
-4
@@ -18,9 +18,20 @@ clk-test-y := clk_test.o \
|
||||
kunit_clk_assigned_rates_without_consumer.dtbo.o \
|
||||
kunit_clk_assigned_rates_zero.dtbo.o \
|
||||
kunit_clk_assigned_rates_zero_consumer.dtbo.o \
|
||||
kunit_clk_assigned_sscs_one.dtbo.o \
|
||||
kunit_clk_assigned_sscs_one_consumer.dtbo.o \
|
||||
kunit_clk_assigned_sscs_multiple.dtbo.o \
|
||||
kunit_clk_assigned_sscs_multiple_consumer.dtbo.o \
|
||||
kunit_clk_assigned_sscs_null.dtbo.o \
|
||||
kunit_clk_assigned_sscs_null_consumer.dtbo.o \
|
||||
kunit_clk_assigned_sscs_without.dtbo.o \
|
||||
kunit_clk_assigned_sscs_without_consumer.dtbo.o \
|
||||
kunit_clk_assigned_sscs_zero.dtbo.o \
|
||||
kunit_clk_assigned_sscs_zero_consumer.dtbo.o \
|
||||
kunit_clk_hw_get_dev_of_node.dtbo.o \
|
||||
kunit_clk_parent_data_test.dtbo.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
|
||||
obj-$(CONFIG_CLK_DIVIDER_KUNIT_TEST) += clk-divider_test.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
|
||||
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
|
||||
obj-$(CONFIG_CLK_FIXED_RATE_KUNIT_TEST) += clk-fixed-rate-test.o
|
||||
@@ -88,7 +99,8 @@ obj-$(CONFIG_COMMON_CLK_RP1) += clk-rp1.o
|
||||
obj-$(CONFIG_COMMON_CLK_RPMI) += clk-rpmi.o
|
||||
obj-$(CONFIG_COMMON_CLK_HI655X) += clk-hi655x.o
|
||||
obj-$(CONFIG_COMMON_CLK_S2MPS11) += clk-s2mps11.o
|
||||
obj-$(CONFIG_COMMON_CLK_SCMI) += clk-scmi.o
|
||||
scmi-clk-y := clk-scmi.o clk-scmi-oem.o
|
||||
obj-$(CONFIG_COMMON_CLK_SCMI) += scmi-clk.o
|
||||
obj-$(CONFIG_COMMON_CLK_SCPI) += clk-scpi.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI5341) += clk-si5341.o
|
||||
obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
|
||||
@@ -119,9 +131,10 @@ obj-$(CONFIG_ARCH_ARTPEC) += axis/
|
||||
obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
|
||||
obj-y += bcm/
|
||||
obj-$(CONFIG_ARCH_BERLIN) += berlin/
|
||||
obj-y += cix/
|
||||
obj-$(CONFIG_ARCH_DAVINCI) += davinci/
|
||||
obj-$(CONFIG_COMMON_CLK_ESWIN) += eswin/
|
||||
obj-$(CONFIG_ARCH_HISI) += hisilicon/
|
||||
obj-$(CONFIG_COMMON_CLK_HISI) += hisilicon/
|
||||
obj-y += imgtec/
|
||||
obj-y += imx/
|
||||
obj-y += ingenic/
|
||||
@@ -151,14 +164,15 @@ obj-y += spacemit/
|
||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-y += sprd/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_STM32) += stm32/
|
||||
obj-$(CONFIG_COMMON_CLK_STM32MP) += stm32/
|
||||
obj-y += starfive/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-y += sunxi-ng/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-y += tenstorrent/
|
||||
obj-$(CONFIG_ARCH_THEAD) += thead/
|
||||
obj-y += thead/
|
||||
obj-y += ti/
|
||||
obj-y += ultrarisc/
|
||||
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
|
||||
obj-$(CONFIG_ARCH_U8500) += ux500/
|
||||
obj-y += versatile/
|
||||
|
||||
@@ -272,6 +272,13 @@ static const unsigned int sdclk_parent_ids[] = {
|
||||
|
||||
static const struct clk_hw *sdclk_parent_hws[ARRAY_SIZE(sdclk_parent_ids)];
|
||||
|
||||
static const unsigned int peciclk_parent_ids[] = {
|
||||
SCU1_CLKIN,
|
||||
SCU1_CLK_HPLL_DIV4
|
||||
};
|
||||
|
||||
static const struct clk_hw *peciclk_parent_hws[ARRAY_SIZE(peciclk_parent_ids)];
|
||||
|
||||
#define FIXED_CLK(_id, _name, _rate) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
@@ -457,6 +464,7 @@ static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = {
|
||||
PLL_CLK(SCU1_CLK_HPLL, CLK_PLL, "soc1-hpll", SCU1_CLKIN, SCU1_HPLL_PARAM),
|
||||
PLL_CLK(SCU1_CLK_APLL, CLK_PLL, "soc1-apll", SCU1_CLKIN, SCU1_APLL_PARAM),
|
||||
PLL_CLK(SCU1_CLK_DPLL, CLK_PLL, "soc1-dpll", SCU1_CLKIN, SCU1_DPLL_PARAM),
|
||||
FIXED_FACTOR_CLK(SCU1_CLK_HPLL_DIV4, "soc1-hpll_div4", SCU1_CLK_HPLL, 1, 4),
|
||||
FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV2, "soc1-apll_div2", SCU1_CLK_APLL, 1, 2),
|
||||
FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV4, "soc1-apll_div4", SCU1_CLK_APLL, 1, 4),
|
||||
FIXED_FACTOR_CLK(SCU1_CLK_CAN, "canclk", SCU1_CLK_APLL, 1, 10),
|
||||
@@ -480,6 +488,8 @@ static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = {
|
||||
uxclk_parent_hws, SCU1_CLK_SEL2, 0, 2),
|
||||
MUX_CLK(SCU1_CLK_HUXCLK, "huxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids),
|
||||
uxclk_parent_hws, SCU1_CLK_SEL2, 3, 2),
|
||||
MUX_CLK(SCU1_CLK_PECI, "peciclk", peciclk_parent_ids, ARRAY_SIZE(peciclk_parent_ids),
|
||||
peciclk_parent_hws, SCU1_CLK_SEL2, 16, 1),
|
||||
DIVIDER_CLK(SCU1_CLK_SDCLK, "sdclk", SCU1_CLK_SDMUX,
|
||||
SCU1_CLK_SEL1, 14, 3, ast2700_clk_div_table),
|
||||
PLL_CLK(SCU1_CLK_UARTX, CLK_UART_PLL, "uartxclk", SCU1_CLK_UXCLK, SCU1_UXCLK_CTRL),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/at91_pmc.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -217,7 +218,7 @@ CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
|
||||
static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
|
||||
{
|
||||
struct regmap *regmap_sfr;
|
||||
u8 bus_id;
|
||||
u64 bus_id;
|
||||
const char *parent_names[2];
|
||||
struct device_node *i2s_mux_np;
|
||||
struct clk_hw *hw;
|
||||
@@ -228,7 +229,7 @@ static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
|
||||
return;
|
||||
|
||||
for_each_child_of_node(np, i2s_mux_np) {
|
||||
if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
|
||||
if (of_property_read_reg(i2s_mux_np, 0, &bus_id, NULL))
|
||||
continue;
|
||||
|
||||
if (bus_id > I2S_BUS_NR)
|
||||
|
||||
@@ -1098,8 +1098,7 @@ static u8 kona_peri_clk_get_parent(struct clk_hw *hw)
|
||||
|
||||
index = selector_read_index(bcm_clk->ccu, &data->sel);
|
||||
|
||||
/* Not all callers would handle an out-of-range value gracefully */
|
||||
return index == BAD_CLK_INDEX ? 0 : index;
|
||||
return index;
|
||||
}
|
||||
|
||||
static int kona_peri_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Audio subsystem clock support for Cixtech SoC family
|
||||
menu "Cixtech Audio Subsystem Clock Driver"
|
||||
|
||||
config CLK_SKY1_AUDSS
|
||||
tristate "Cixtech Sky1 Audio Subsystem Clock Driver"
|
||||
depends on ARCH_CIX || COMPILE_TEST
|
||||
select AUXILIARY_BUS
|
||||
select REGMAP_MMIO
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
Support for the Audio Subsystem clock controller present on
|
||||
Cixtech Sky1 SoC. This driver provides mux, divider and gate
|
||||
clocks for DSP, I2S, HDA and related blocks in the audio
|
||||
subsystem. Say M or Y here if you want to build this driver.
|
||||
endmenu
|
||||
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CLK_SKY1_AUDSS) += clk-sky1-audss.o
|
||||
File diff suppressed because it is too large
Load Diff
@@ -147,12 +147,12 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct platform_device_id bd718x7_clk_id[] = {
|
||||
{ "bd71837-clk", ROHM_CHIP_TYPE_BD71837 },
|
||||
{ "bd71847-clk", ROHM_CHIP_TYPE_BD71847 },
|
||||
{ "bd71828-clk", ROHM_CHIP_TYPE_BD71828 },
|
||||
{ "bd71815-clk", ROHM_CHIP_TYPE_BD71815 },
|
||||
{ "bd72720-clk", ROHM_CHIP_TYPE_BD72720 },
|
||||
{ },
|
||||
{ .name = "bd71837-clk", .driver_data = ROHM_CHIP_TYPE_BD71837 },
|
||||
{ .name = "bd71847-clk", .driver_data = ROHM_CHIP_TYPE_BD71847 },
|
||||
{ .name = "bd71828-clk", .driver_data = ROHM_CHIP_TYPE_BD71828 },
|
||||
{ .name = "bd71815-clk", .driver_data = ROHM_CHIP_TYPE_BD71815 },
|
||||
{ .name = "bd72720-clk", .driver_data = ROHM_CHIP_TYPE_BD72720 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, bd718x7_clk_id);
|
||||
|
||||
|
||||
@@ -679,7 +679,7 @@ MODULE_DEVICE_TABLE(of, cdce706_dt_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id cdce706_id[] = {
|
||||
{ "cdce706" },
|
||||
{ .name = "cdce706" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cdce706_id);
|
||||
|
||||
@@ -826,10 +826,10 @@ static const struct clk_cdce925_chip_info clk_cdce949_info = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id cdce925_id[] = {
|
||||
{ "cdce913", (kernel_ulong_t)&clk_cdce913_info },
|
||||
{ "cdce925", (kernel_ulong_t)&clk_cdce925_info },
|
||||
{ "cdce937", (kernel_ulong_t)&clk_cdce937_info },
|
||||
{ "cdce949", (kernel_ulong_t)&clk_cdce949_info },
|
||||
{ .name = "cdce913", .driver_data = (kernel_ulong_t)&clk_cdce913_info },
|
||||
{ .name = "cdce925", .driver_data = (kernel_ulong_t)&clk_cdce925_info },
|
||||
{ .name = "cdce937", .driver_data = (kernel_ulong_t)&clk_cdce937_info },
|
||||
{ .name = "cdce949", .driver_data = (kernel_ulong_t)&clk_cdce949_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cdce925_id);
|
||||
|
||||
@@ -462,3 +462,4 @@ struct clk_hw *devm_clk_hw_register_composite_pdata(struct device *dev,
|
||||
rate_hw, rate_ops, gate_hw,
|
||||
gate_ops, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_composite_pdata);
|
||||
|
||||
@@ -155,6 +155,78 @@ static int __set_clk_rates(struct device_node *node, bool clk_supplier)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __set_clk_spread_spectrum(struct device_node *node, bool clk_supplier)
|
||||
{
|
||||
u32 elem_size = sizeof(struct clk_spread_spectrum);
|
||||
struct clk_spread_spectrum *sscs;
|
||||
struct of_phandle_args clkspec;
|
||||
int rc, count, index;
|
||||
struct clk *clk;
|
||||
|
||||
/* modfreq, spreadPercent, modmethod */
|
||||
count = of_property_count_elems_of_size(node, "assigned-clock-sscs", elem_size);
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
sscs = kcalloc(count, elem_size, GFP_KERNEL);
|
||||
if (!sscs)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = of_property_read_u32_array(node, "assigned-clock-sscs", (u32 *)sscs,
|
||||
count * 3);
|
||||
if (rc)
|
||||
goto free_sscs;
|
||||
|
||||
for (index = 0; index < count; index++) {
|
||||
struct clk_spread_spectrum *conf = &sscs[index];
|
||||
struct clk_hw *hw;
|
||||
|
||||
if (!conf->modfreq_hz && !conf->spread_bp && !conf->method)
|
||||
continue;
|
||||
|
||||
rc = of_parse_phandle_with_args(node, "assigned-clocks", "#clock-cells",
|
||||
index, &clkspec);
|
||||
if (rc < 0) {
|
||||
/* skip empty (null) phandles */
|
||||
if (rc == -ENOENT) {
|
||||
rc = 0;
|
||||
continue;
|
||||
} else
|
||||
goto free_sscs;
|
||||
}
|
||||
|
||||
if (clkspec.np == node && !clk_supplier) {
|
||||
of_node_put(clkspec.np);
|
||||
goto free_sscs;
|
||||
}
|
||||
|
||||
clk = of_clk_get_from_provider(&clkspec);
|
||||
of_node_put(clkspec.np);
|
||||
if (IS_ERR(clk)) {
|
||||
if (PTR_ERR(clk) != -EPROBE_DEFER)
|
||||
pr_warn("clk: couldn't get clock %d for %pOF\n",
|
||||
index, node);
|
||||
rc = PTR_ERR(clk);
|
||||
goto free_sscs;
|
||||
}
|
||||
|
||||
hw = __clk_get_hw(clk);
|
||||
rc = clk_hw_set_spread_spectrum(hw, conf);
|
||||
if (rc < 0) {
|
||||
pr_err("clk: couldn't set %s clk spread spectrum %u %u %u: %d\n",
|
||||
__clk_get_name(clk), conf->modfreq_hz, conf->spread_bp,
|
||||
conf->method, rc);
|
||||
/* Do not fail */
|
||||
rc = 0;
|
||||
}
|
||||
clk_put(clk);
|
||||
}
|
||||
|
||||
free_sscs:
|
||||
kfree(sscs);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_clk_set_defaults() - parse and set assigned clocks configuration
|
||||
* @node: device node to apply clock settings for
|
||||
@@ -174,6 +246,10 @@ int of_clk_set_defaults(struct device_node *node, bool clk_supplier)
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
rc = __set_clk_spread_spectrum(node, clk_supplier);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = __set_clk_parents(node, clk_supplier);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -122,8 +122,8 @@ static const struct of_device_id cs2000_of_match[] = {
|
||||
MODULE_DEVICE_TABLE(of, cs2000_of_match);
|
||||
|
||||
static const struct i2c_device_id cs2000_id[] = {
|
||||
{ "cs2000-cp", },
|
||||
{}
|
||||
{ .name = "cs2000-cp" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cs2000_id);
|
||||
|
||||
@@ -404,11 +404,7 @@ static int cs2000_enable(struct clk_hw *hw)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = cs2000_wait_pll_lock(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
return cs2000_wait_pll_lock(priv);
|
||||
}
|
||||
|
||||
static void cs2000_disable(struct clk_hw *hw)
|
||||
|
||||
@@ -99,6 +99,11 @@ struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled);
|
||||
|
||||
static void devm_clk_disable_unprepare(void *data)
|
||||
{
|
||||
clk_disable_unprepare(data);
|
||||
}
|
||||
|
||||
struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
|
||||
const char *id,
|
||||
unsigned long rate)
|
||||
@@ -106,8 +111,7 @@ struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = __devm_clk_get(dev, id, clk_get_optional, NULL,
|
||||
clk_disable_unprepare);
|
||||
clk = devm_clk_get_optional(dev, id);
|
||||
if (IS_ERR(clk))
|
||||
return ERR_CAST(clk);
|
||||
|
||||
@@ -119,6 +123,10 @@ struct clk *devm_clk_get_optional_enabled_with_rate(struct device *dev,
|
||||
if (ret)
|
||||
goto out_put_clk;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, devm_clk_disable_unprepare, clk);
|
||||
if (ret)
|
||||
goto out_put_clk;
|
||||
|
||||
return clk;
|
||||
|
||||
out_put_clk:
|
||||
@@ -222,6 +230,13 @@ err_clk_get:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __must_check devm_clk_bulk_get_enable(struct device *dev, int num_clks,
|
||||
struct clk_bulk_data *clks)
|
||||
{
|
||||
return __devm_clk_bulk_get_enable(dev, num_clks, clks, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_bulk_get_enable);
|
||||
|
||||
int __must_check devm_clk_bulk_get_optional_enable(struct device *dev, int num_clks,
|
||||
struct clk_bulk_data *clks)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/log2.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
/*
|
||||
* DOC: basic adjustable divider clock that cannot gate
|
||||
@@ -301,6 +302,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
|
||||
int i, bestdiv = 0;
|
||||
unsigned long parent_rate, best = 0, now, maxdiv;
|
||||
unsigned long parent_rate_saved = *best_parent_rate;
|
||||
unsigned long target_parent_rate;
|
||||
|
||||
if (!rate)
|
||||
rate = 1;
|
||||
@@ -315,15 +317,11 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
|
||||
return bestdiv;
|
||||
}
|
||||
|
||||
/*
|
||||
* The maximum divider we can use without overflowing
|
||||
* unsigned long in rate * i below
|
||||
*/
|
||||
maxdiv = min(ULONG_MAX / rate, maxdiv);
|
||||
|
||||
for (i = _next_div(table, 0, flags); i <= maxdiv;
|
||||
i = _next_div(table, i, flags)) {
|
||||
if (rate * i == parent_rate_saved) {
|
||||
bool overflow = check_mul_overflow(rate, (unsigned long)i, &target_parent_rate);
|
||||
|
||||
if (!overflow && target_parent_rate == parent_rate_saved) {
|
||||
/*
|
||||
* It's the most ideal case if the requested rate can be
|
||||
* divided from parent clock without needing to change
|
||||
@@ -332,13 +330,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
|
||||
*best_parent_rate = parent_rate_saved;
|
||||
return i;
|
||||
}
|
||||
parent_rate = clk_hw_round_rate(parent, rate * i);
|
||||
/*
|
||||
* Clamp target_parent_rate to ULONG_MAX on overflow. The true
|
||||
* required parent rate exceeds what can be represented, so ask
|
||||
* the parent for the highest rate it can produce. There is no
|
||||
* point continuing the loop past this since larger dividers
|
||||
* only move further from the requested rate.
|
||||
*/
|
||||
if (overflow)
|
||||
target_parent_rate = ULONG_MAX;
|
||||
parent_rate = clk_hw_round_rate(parent, target_parent_rate);
|
||||
now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
|
||||
if (_is_best_div(rate, now, best, flags)) {
|
||||
bestdiv = i;
|
||||
best = now;
|
||||
*best_parent_rate = parent_rate;
|
||||
}
|
||||
if (overflow)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bestdiv) {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* KUnit tests for clk_divider_bestdiv()
|
||||
*/
|
||||
#include <kunit/test.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#define PARENT_RATE_1GHZ GIGA
|
||||
#define PARENT_RATE_2GHZ (2 * GIGA)
|
||||
#define PARENT_RATE_4GHZ (4 * GIGA)
|
||||
|
||||
KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_fixed_rate_wrapper,
|
||||
clk_hw_unregister_fixed_rate, struct clk_hw *);
|
||||
KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_divider_wrapper,
|
||||
clk_hw_unregister_divider, struct clk_hw *);
|
||||
KUNIT_DEFINE_ACTION_WRAPPER(clk_hw_unregister_mux_wrapper,
|
||||
clk_hw_unregister_mux, struct clk_hw *);
|
||||
|
||||
static const struct clk_div_table bestdiv_table[] = {
|
||||
{ .val = 0, .div = 2 },
|
||||
{ .val = 1, .div = 4 },
|
||||
{ .val = 2, .div = 8 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
/*
|
||||
* Test that clk_round_rate(clk, ULONG_MAX) returns the maximum achievable
|
||||
* rate for a divider clock.
|
||||
*/
|
||||
static void clk_divider_bestdiv_ulong_max_returns_max_rate(struct kunit *test)
|
||||
{
|
||||
struct clk_hw *parent_hw, *div_hw;
|
||||
unsigned long rate;
|
||||
u32 *fake_reg;
|
||||
|
||||
fake_reg = kunit_kzalloc(test, sizeof(*fake_reg), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg);
|
||||
|
||||
parent_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-parent",
|
||||
NULL, 0, PARENT_RATE_1GHZ);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper,
|
||||
parent_hw));
|
||||
|
||||
div_hw = clk_hw_register_divider_table(NULL, "bestdiv-div",
|
||||
"bestdiv-parent",
|
||||
CLK_SET_RATE_PARENT,
|
||||
(void __iomem __force *)fake_reg,
|
||||
0, 2, 0, bestdiv_table, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, div_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_divider_wrapper,
|
||||
div_hw));
|
||||
|
||||
/*
|
||||
* ULONG_MAX is the canonical way to probe the maximum rate a clock
|
||||
* can produce.
|
||||
*/
|
||||
rate = clk_hw_round_rate(div_hw, ULONG_MAX);
|
||||
KUNIT_EXPECT_EQ(test, rate, PARENT_RATE_1GHZ / 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that clk_round_rate(clk, ULONG_MAX) returns the correct maximum rate
|
||||
* when a mux clock sits between a divider and its parent candidates.
|
||||
*
|
||||
* Topology:
|
||||
*
|
||||
* [fixed 4 GHz] --\
|
||||
* +--> [mux CLK_SET_RATE_PARENT] --> [div {2,4,8} CLK_SET_RATE_PARENT]
|
||||
* [fixed 2 GHz] --/
|
||||
*
|
||||
*/
|
||||
static void clk_divider_bestdiv_mux_ulong_max_returns_max_rate(struct kunit *test)
|
||||
{
|
||||
static const char * const mux_parents[] = {
|
||||
"bestdiv-mux-parent-a",
|
||||
"bestdiv-mux-parent-b",
|
||||
};
|
||||
struct clk_hw *parent_a_hw, *parent_b_hw, *mux_hw, *div_hw;
|
||||
u32 *fake_reg_mux, *fake_reg_div;
|
||||
unsigned long rate;
|
||||
|
||||
fake_reg_mux = kunit_kzalloc(test, sizeof(*fake_reg_mux), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg_mux);
|
||||
|
||||
fake_reg_div = kunit_kzalloc(test, sizeof(*fake_reg_div), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fake_reg_div);
|
||||
|
||||
/* Higher-rate parent: the mux should select this for ULONG_MAX. */
|
||||
parent_a_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-mux-parent-a",
|
||||
NULL, 0, PARENT_RATE_4GHZ);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_a_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper,
|
||||
parent_a_hw));
|
||||
|
||||
/* Lower-rate parent: should not be selected. */
|
||||
parent_b_hw = clk_hw_register_fixed_rate(NULL, "bestdiv-mux-parent-b",
|
||||
NULL, 0, PARENT_RATE_2GHZ);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent_b_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_fixed_rate_wrapper,
|
||||
parent_b_hw));
|
||||
|
||||
/*
|
||||
* 1-bit mux register selects between the two parents.
|
||||
* CLK_SET_RATE_PARENT allows the divider's rate request to
|
||||
* propagate into clk_mux_determine_rate().
|
||||
*/
|
||||
mux_hw = clk_hw_register_mux(NULL, "bestdiv-mux",
|
||||
mux_parents, ARRAY_SIZE(mux_parents),
|
||||
CLK_SET_RATE_PARENT,
|
||||
(void __iomem __force *)fake_reg_mux,
|
||||
0, 1, 0, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mux_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_mux_wrapper,
|
||||
mux_hw));
|
||||
|
||||
div_hw = clk_hw_register_divider_table(NULL, "bestdiv-mux-div",
|
||||
"bestdiv-mux",
|
||||
CLK_SET_RATE_PARENT,
|
||||
(void __iomem __force *)fake_reg_div,
|
||||
0, 2, 0, bestdiv_table, NULL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, div_hw);
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
kunit_add_action_or_reset(test, clk_hw_unregister_divider_wrapper,
|
||||
div_hw));
|
||||
|
||||
rate = clk_hw_round_rate(div_hw, ULONG_MAX);
|
||||
KUNIT_EXPECT_EQ(test, rate, PARENT_RATE_4GHZ / 2);
|
||||
}
|
||||
|
||||
static struct kunit_case clk_divider_bestdiv_test_cases[] = {
|
||||
KUNIT_CASE(clk_divider_bestdiv_ulong_max_returns_max_rate),
|
||||
KUNIT_CASE(clk_divider_bestdiv_mux_ulong_max_returns_max_rate),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite clk_divider_bestdiv_test_suite = {
|
||||
.name = "clk_divider_bestdiv",
|
||||
.test_cases = clk_divider_bestdiv_test_cases,
|
||||
};
|
||||
|
||||
kunit_test_suite(clk_divider_bestdiv_test_suite);
|
||||
|
||||
MODULE_DESCRIPTION("KUnit tests for clk divider");
|
||||
MODULE_LICENSE("GPL");
|
||||
+33
-10
@@ -57,6 +57,7 @@
|
||||
|
||||
#define REG_RST_CTRL2 0x830
|
||||
#define REG_RST_CTRL1 0x834
|
||||
#define REG_PCIE_HB_RST BIT(29)
|
||||
#define EN751221_REG_RST_DMT 0x84
|
||||
#define EN751221_REG_RST_USB 0xec
|
||||
|
||||
@@ -338,6 +339,7 @@ static const struct en_clk_desc en7581_base_clks[] = {
|
||||
static const u16 en7581_rst_ofs[] = {
|
||||
REG_RST_CTRL2,
|
||||
REG_RST_CTRL1,
|
||||
REG_NP_SCU_PCIC,
|
||||
};
|
||||
|
||||
static const u16 en751221_rst_ofs[] = {
|
||||
@@ -450,6 +452,11 @@ static const u16 en7581_rst_map[] = {
|
||||
[EN7581_CPU_TIMER_RST] = RST_NR_PER_BANK + 28,
|
||||
[EN7581_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
|
||||
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||||
|
||||
/* RST_PCIC */
|
||||
[EN7581_PCIC_PERSTOUT0_RST] = 2 * RST_NR_PER_BANK + 29,
|
||||
[EN7581_PCIC_PERSTOUT1_RST] = 2 * RST_NR_PER_BANK + 26,
|
||||
[EN7581_PCIC_PERSTOUT2_RST] = 2 * RST_NR_PER_BANK + 16,
|
||||
};
|
||||
|
||||
static const u16 en751221_rst_map[] = {
|
||||
@@ -635,9 +642,7 @@ static int en7581_pci_enable(struct clk_hw *hw)
|
||||
void __iomem *np_base = cg->base;
|
||||
u32 val, mask;
|
||||
|
||||
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||
REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||
REG_PCI_CONTROL_PERSTOUT;
|
||||
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
|
||||
val = readl(np_base + REG_PCI_CONTROL);
|
||||
writel(val | mask, np_base + REG_PCI_CONTROL);
|
||||
|
||||
@@ -650,9 +655,7 @@ static void en7581_pci_disable(struct clk_hw *hw)
|
||||
void __iomem *np_base = cg->base;
|
||||
u32 val, mask;
|
||||
|
||||
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1 |
|
||||
REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT2 |
|
||||
REG_PCI_CONTROL_PERSTOUT;
|
||||
mask = REG_PCI_CONTROL_REFCLK_EN0 | REG_PCI_CONTROL_REFCLK_EN1;
|
||||
val = readl(np_base + REG_PCI_CONTROL);
|
||||
writel(val & ~mask, np_base + REG_PCI_CONTROL);
|
||||
usleep_range(1000, 2000);
|
||||
@@ -754,11 +757,17 @@ static int en7523_reset_update(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool assert)
|
||||
{
|
||||
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
|
||||
void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
|
||||
u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
|
||||
void __iomem *addr = rst_data->base + offset;
|
||||
bool inverted = false;
|
||||
u32 val;
|
||||
|
||||
/* For PCIC reset logic is inverted, 0:assert 1:deassert */
|
||||
if (offset == REG_NP_SCU_PCIC)
|
||||
inverted = true;
|
||||
|
||||
val = readl(addr);
|
||||
if (assert)
|
||||
if (assert ^ inverted)
|
||||
val |= BIT(id % RST_NR_PER_BANK);
|
||||
else
|
||||
val &= ~BIT(id % RST_NR_PER_BANK);
|
||||
@@ -783,9 +792,17 @@ static int en7523_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct en_rst_data *rst_data = container_of(rcdev, struct en_rst_data, rcdev);
|
||||
void __iomem *addr = rst_data->base + rst_data->bank_ofs[id / RST_NR_PER_BANK];
|
||||
u32 offset = rst_data->bank_ofs[id / RST_NR_PER_BANK];
|
||||
void __iomem *addr = rst_data->base + offset;
|
||||
bool inverted = false;
|
||||
u32 val;
|
||||
|
||||
return !!(readl(addr) & BIT(id % RST_NR_PER_BANK));
|
||||
/* For PCIC reset logic is inverted, 0:assert 1:deassert */
|
||||
if (offset == REG_NP_SCU_PCIC)
|
||||
inverted = true;
|
||||
|
||||
val = readl(addr) & BIT(id % RST_NR_PER_BANK);
|
||||
return inverted ? !val : !!val;
|
||||
}
|
||||
|
||||
static int en7523_reset_xlate(struct reset_controller_dev *rcdev,
|
||||
@@ -853,6 +870,12 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
|
||||
val = readl(base + REG_NP_SCU_PCIC);
|
||||
writel(val | 3, base + REG_NP_SCU_PCIC);
|
||||
|
||||
val = readl(base + REG_RST_CTRL1);
|
||||
val |= REG_PCIE_HB_RST;
|
||||
writel(val, base + REG_RST_CTRL1);
|
||||
val &= ~REG_PCIE_HB_RST;
|
||||
writel(val, base + REG_RST_CTRL1);
|
||||
|
||||
return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
|
||||
ARRAY_SIZE(en7581_rst_map),
|
||||
en7581_rst_ofs);
|
||||
|
||||
+857
-411
File diff suppressed because it is too large
Load Diff
@@ -36,10 +36,14 @@ static int clk_factor_determine_rate(struct clk_hw *hw,
|
||||
struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
|
||||
struct clk_hw *parent_hw = clk_hw_get_parent(hw);
|
||||
unsigned long best_parent;
|
||||
|
||||
if (!parent_hw)
|
||||
return -EINVAL;
|
||||
|
||||
best_parent = (req->rate / fix->mult) * fix->div;
|
||||
req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
|
||||
req->best_parent_rate = clk_hw_round_rate(parent_hw, best_parent);
|
||||
}
|
||||
|
||||
req->rate = (req->best_parent_rate / fix->div) * fix->mult;
|
||||
@@ -90,7 +94,7 @@ static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *
|
||||
clk_hw_unregister(&fix->hw);
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
struct clk_hw *
|
||||
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
const char *name, const char *parent_name,
|
||||
const struct clk_hw *parent_hw, const struct clk_parent_data *pdata,
|
||||
@@ -124,13 +128,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
init.name = name;
|
||||
init.ops = &clk_fixed_factor_ops;
|
||||
init.flags = flags;
|
||||
if (parent_name)
|
||||
init.parent_names = &parent_name;
|
||||
else if (parent_hw)
|
||||
init.parent_hws = &parent_hw;
|
||||
init.parent_names = parent_name ? &parent_name : NULL;
|
||||
init.parent_hws = parent_hw ? &parent_hw : NULL;
|
||||
init.parent_data = pdata;
|
||||
if (parent_name || parent_hw || pdata)
|
||||
init.num_parents = 1;
|
||||
else
|
||||
init.parent_data = pdata;
|
||||
init.num_parents = 1;
|
||||
init.num_parents = 0;
|
||||
|
||||
hw = &fix->hw;
|
||||
if (dev)
|
||||
@@ -148,6 +152,7 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_factor);
|
||||
|
||||
/**
|
||||
* devm_clk_hw_register_fixed_factor_index - Register a fixed factor clock with
|
||||
@@ -173,52 +178,6 @@ struct clk_hw *devm_clk_hw_register_fixed_factor_index(struct device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_index);
|
||||
|
||||
/**
|
||||
* devm_clk_hw_register_fixed_factor_parent_hw - Register a fixed factor clock with
|
||||
* pointer to parent clock
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_hw: pointer to parent clk
|
||||
* @flags: fixed factor flags
|
||||
* @mult: multiplier
|
||||
* @div: divider
|
||||
*
|
||||
* Return: Pointer to fixed factor clk_hw structure that was registered or
|
||||
* an error pointer.
|
||||
*/
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor_parent_hw(struct device *dev,
|
||||
const char *name, const struct clk_hw *parent_hw,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
{
|
||||
const struct clk_parent_data pdata = { .index = -1 };
|
||||
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw,
|
||||
&pdata, flags, mult, div, 0, 0, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor_parent_hw);
|
||||
|
||||
struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,
|
||||
const char *name, const struct clk_hw *parent_hw,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
{
|
||||
const struct clk_parent_data pdata = { .index = -1 };
|
||||
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, NULL, parent_hw,
|
||||
&pdata, flags, mult, div, 0, 0, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor_parent_hw);
|
||||
|
||||
struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
const struct clk_parent_data pdata = { .index = -1 };
|
||||
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL,
|
||||
&pdata, flags, mult, div, 0, 0, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
|
||||
|
||||
struct clk_hw *clk_hw_register_fixed_factor_fwname(struct device *dev,
|
||||
struct device_node *np, const char *name, const char *fw_name,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
@@ -292,17 +251,6 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
|
||||
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
const struct clk_parent_data pdata = { .index = -1 };
|
||||
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, NULL,
|
||||
&pdata, flags, mult, div, 0, 0, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
|
||||
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor_fwname(struct device *dev,
|
||||
struct device_node *np, const char *name, const char *fw_name,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
|
||||
@@ -2227,6 +2227,7 @@ static int k230_clk_set_rate_mul(struct clk_hw *hw, unsigned long rate,
|
||||
guard(spinlock)(rate_self->lock);
|
||||
|
||||
mul_reg = readl(rate_self->reg + clk->mul_reg_off);
|
||||
mul_reg &= ~(rate_self->mul_mask << rate_self->mul_shift);
|
||||
mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift);
|
||||
mul_reg |= BIT(rate_self->write_enable_bit);
|
||||
writel(mul_reg, rate_self->reg + clk->mul_reg_off);
|
||||
@@ -2257,6 +2258,7 @@ static int k230_clk_set_rate_div(struct clk_hw *hw, unsigned long rate,
|
||||
guard(spinlock)(rate_self->lock);
|
||||
|
||||
div_reg = readl(rate_self->reg + clk->div_reg_off);
|
||||
div_reg &= ~(rate_self->div_mask << rate_self->div_shift);
|
||||
div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift);
|
||||
div_reg |= BIT(rate_self->write_enable_bit);
|
||||
writel(div_reg, rate_self->reg + clk->div_reg_off);
|
||||
@@ -2287,11 +2289,13 @@ static int k230_clk_set_rate_mul_div(struct clk_hw *hw, unsigned long rate,
|
||||
guard(spinlock)(rate_self->lock);
|
||||
|
||||
div_reg = readl(rate_self->reg + clk->div_reg_off);
|
||||
div_reg &= ~(rate_self->div_mask << rate_self->div_shift);
|
||||
div_reg |= ((div - 1) & rate_self->div_mask) << (rate_self->div_shift);
|
||||
div_reg |= BIT(rate_self->write_enable_bit);
|
||||
writel(div_reg, rate_self->reg + clk->div_reg_off);
|
||||
|
||||
mul_reg = readl(rate_self->reg + clk->mul_reg_off);
|
||||
mul_reg &= ~(rate_self->mul_mask << rate_self->mul_shift);
|
||||
mul_reg |= ((mul - 1) & rate_self->mul_mask) << (rate_self->mul_shift);
|
||||
mul_reg |= BIT(rate_self->write_enable_bit);
|
||||
writel(mul_reg, rate_self->reg + clk->mul_reg_off);
|
||||
|
||||
+14
-25
@@ -175,10 +175,6 @@
|
||||
#define LMK04832_REG_RB_HOLDOVER 0x188
|
||||
#define LMK04832_REG_SPI_LOCK 0x555
|
||||
|
||||
enum lmk04832_device_types {
|
||||
LMK04832,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lmk04832_device_info - Holds static device information that is
|
||||
* specific to the chip revision
|
||||
@@ -197,14 +193,12 @@ struct lmk04832_device_info {
|
||||
unsigned int vco1_range[2];
|
||||
};
|
||||
|
||||
static const struct lmk04832_device_info lmk04832_device_info[] = {
|
||||
[LMK04832] = {
|
||||
.pid = 0x63d1, /* WARNING PROD_ID is inverted in the datasheet */
|
||||
.maskrev = 0x70,
|
||||
.num_channels = 14,
|
||||
.vco0_range = { 2440, 2580 },
|
||||
.vco1_range = { 2945, 3255 },
|
||||
},
|
||||
static const struct lmk04832_device_info lmk04832_device_info = {
|
||||
.pid = 0x63d1, /* WARNING PROD_ID is inverted in the datasheet */
|
||||
.maskrev = 0x70,
|
||||
.num_channels = 14,
|
||||
.vco0_range = { 2440, 2580 },
|
||||
.vco1_range = { 2945, 3255 },
|
||||
};
|
||||
|
||||
enum lmk04832_rdbk_type {
|
||||
@@ -422,11 +416,10 @@ static unsigned long lmk04832_vco_recalc_rate(struct clk_hw *hw,
|
||||
*/
|
||||
static int lmk04832_check_vco_ranges(struct lmk04832 *lmk, unsigned long rate)
|
||||
{
|
||||
struct spi_device *spi = to_spi_device(lmk->dev);
|
||||
const struct lmk04832_device_info *info;
|
||||
unsigned long mhz = rate / 1000000;
|
||||
|
||||
info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data];
|
||||
info = &lmk04832_device_info;
|
||||
|
||||
if (mhz >= info->vco0_range[0] && mhz <= info->vco0_range[1])
|
||||
return LMK04832_VAL_VCO_MUX_VCO0;
|
||||
@@ -822,13 +815,6 @@ static int lmk04832_sclk_sync_sequence(struct lmk04832 *lmk)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
|
||||
LMK04832_BIT_SYNC_MODE,
|
||||
FIELD_PREP(LMK04832_BIT_SYNC_MODE,
|
||||
lmk->sync_mode));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* 9. (optional) if SCLKx_y_DIS_MODE was used to mute SYSREF outputs
|
||||
* during the SYNC event, restore SCLKx_y_DIS_MODE=0 for active state,
|
||||
@@ -843,7 +829,10 @@ static int lmk04832_sclk_sync_sequence(struct lmk04832 *lmk)
|
||||
* SYNC pulse to delay the output by some number of VCO counts).
|
||||
*/
|
||||
|
||||
return ret;
|
||||
return regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC,
|
||||
LMK04832_BIT_SYNC_MODE,
|
||||
FIELD_PREP(LMK04832_BIT_SYNC_MODE,
|
||||
lmk->sync_mode));
|
||||
}
|
||||
|
||||
static int lmk04832_sclk_is_enabled(struct clk_hw *hw)
|
||||
@@ -1405,7 +1394,7 @@ static int lmk04832_probe(struct spi_device *spi)
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data];
|
||||
info = &lmk04832_device_info;
|
||||
|
||||
lmk = devm_kzalloc(&spi->dev, sizeof(struct lmk04832), GFP_KERNEL);
|
||||
if (!lmk)
|
||||
@@ -1553,8 +1542,8 @@ static int lmk04832_probe(struct spi_device *spi)
|
||||
}
|
||||
|
||||
static const struct spi_device_id lmk04832_id[] = {
|
||||
{ "lmk04832", LMK04832 },
|
||||
{}
|
||||
{ .name = "lmk04832" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, lmk04832_id);
|
||||
|
||||
|
||||
@@ -264,10 +264,10 @@ static int max77686_clk_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct platform_device_id max77686_clk_id[] = {
|
||||
{ "max77686-clk", .driver_data = CHIP_MAX77686, },
|
||||
{ "max77802-clk", .driver_data = CHIP_MAX77802, },
|
||||
{ "max77620-clock", .driver_data = CHIP_MAX77620, },
|
||||
{},
|
||||
{ .name = "max77686-clk", .driver_data = CHIP_MAX77686 },
|
||||
{ .name = "max77802-clk", .driver_data = CHIP_MAX77802 },
|
||||
{ .name = "max77620-clock", .driver_data = CHIP_MAX77620 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, max77686_clk_id);
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct clk_hw *hw;
|
||||
struct clk *ref_clk;
|
||||
unsigned int mul;
|
||||
const char *name = node->name;
|
||||
const char *parent_name;
|
||||
@@ -34,12 +33,6 @@ static void __init moxart_of_pll_clk_init(struct device_node *node)
|
||||
mul = readl(base + 0x30) >> 3 & 0x3f;
|
||||
iounmap(base);
|
||||
|
||||
ref_clk = of_clk_get(node, 0);
|
||||
if (IS_ERR(ref_clk)) {
|
||||
pr_err("%pOF: of_clk_get failed\n", node);
|
||||
return;
|
||||
}
|
||||
|
||||
hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1);
|
||||
if (IS_ERR(hw)) {
|
||||
pr_err("%pOF: failed to register clock\n", node);
|
||||
@@ -56,7 +49,6 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct clk_hw *hw;
|
||||
struct clk *pll_clk;
|
||||
unsigned int div, val;
|
||||
unsigned int div_idx[] = { 2, 3, 4, 6, 8};
|
||||
const char *name = node->name;
|
||||
@@ -78,12 +70,6 @@ static void __init moxart_of_apb_clk_init(struct device_node *node)
|
||||
val = 0;
|
||||
div = div_idx[val] * 2;
|
||||
|
||||
pll_clk = of_clk_get(node, 0);
|
||||
if (IS_ERR(pll_clk)) {
|
||||
pr_err("%pOF: of_clk_get failed\n", node);
|
||||
return;
|
||||
}
|
||||
|
||||
hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div);
|
||||
if (IS_ERR(hw)) {
|
||||
pr_err("%pOF: failed to register clock\n", node);
|
||||
|
||||
@@ -194,6 +194,13 @@ static void palmas_clks_get_clk_data(struct platform_device *pdev,
|
||||
cinfo->ext_control_pin = prop;
|
||||
}
|
||||
|
||||
static void palmas_clks_unprepare_ext_control(void *data)
|
||||
{
|
||||
struct palmas_clock_info *cinfo = data;
|
||||
|
||||
clk_unprepare(cinfo->hw.clk);
|
||||
}
|
||||
|
||||
static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
|
||||
{
|
||||
int ret;
|
||||
@@ -214,13 +221,18 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(cinfo->dev,
|
||||
palmas_clks_unprepare_ext_control,
|
||||
cinfo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = palmas_ext_control_req_config(cinfo->palmas,
|
||||
cinfo->clk_desc->sleep_reqstr_id,
|
||||
cinfo->ext_control_pin, true);
|
||||
if (ret < 0) {
|
||||
dev_err(cinfo->dev, "Ext config for %s failed, %d\n",
|
||||
cinfo->clk_desc->clk_name, ret);
|
||||
clk_unprepare(cinfo->hw.clk);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -230,7 +242,6 @@ static int palmas_clks_init_configure(struct palmas_clock_info *cinfo)
|
||||
static int palmas_clks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const struct palmas_clks_of_match_data *match_data;
|
||||
struct palmas_clock_info *cinfo;
|
||||
int ret;
|
||||
@@ -264,24 +275,19 @@ static int palmas_clks_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &cinfo->hw);
|
||||
ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
|
||||
&cinfo->hw);
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "Fail to add clock driver, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void palmas_clks_remove(struct platform_device *pdev)
|
||||
{
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
}
|
||||
|
||||
static struct platform_driver palmas_clks_driver = {
|
||||
.driver = {
|
||||
.name = "palmas-clk",
|
||||
.of_match_table = palmas_clks_of_match,
|
||||
},
|
||||
.probe = palmas_clks_probe,
|
||||
.remove = palmas_clks_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(palmas_clks_driver);
|
||||
|
||||
@@ -394,9 +394,9 @@ static const struct rs9_chip_info renesas_9fgv0841_info = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id rs9_id[] = {
|
||||
{ "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info },
|
||||
{ "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info },
|
||||
{ "9fgv0841", .driver_data = (kernel_ulong_t)&renesas_9fgv0841_info },
|
||||
{ .name = "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info },
|
||||
{ .name = "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info },
|
||||
{ .name = "9fgv0841", .driver_data = (kernel_ulong_t)&renesas_9fgv0841_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rs9_id);
|
||||
|
||||
@@ -1174,12 +1174,6 @@ static unsigned long rp1_varsrc_recalc_rate(struct clk_hw *hw,
|
||||
return clock->cached_rate;
|
||||
}
|
||||
|
||||
static int rp1_varsrc_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rp1_pll_core_ops = {
|
||||
.is_prepared = rp1_pll_core_is_on,
|
||||
.prepare = rp1_pll_core_on,
|
||||
@@ -1227,7 +1221,7 @@ static const struct clk_ops rp1_clk_ops = {
|
||||
static const struct clk_ops rp1_varsrc_ops = {
|
||||
.set_rate = rp1_varsrc_set_rate,
|
||||
.recalc_rate = rp1_varsrc_recalc_rate,
|
||||
.determine_rate = rp1_varsrc_determine_rate,
|
||||
.determine_rate = clk_determine_rate_noop,
|
||||
};
|
||||
|
||||
static struct clk_hw *rp1_register_pll(struct rp1_clockman *clockman,
|
||||
|
||||
@@ -225,12 +225,12 @@ static void s2mps11_clk_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct platform_device_id s2mps11_clk_id[] = {
|
||||
{ "s2mpg10-clk", S2MPG10},
|
||||
{ "s2mps11-clk", S2MPS11X},
|
||||
{ "s2mps13-clk", S2MPS13X},
|
||||
{ "s2mps14-clk", S2MPS14X},
|
||||
{ "s5m8767-clk", S5M8767X},
|
||||
{ },
|
||||
{ .name = "s2mpg10-clk", .driver_data = S2MPG10 },
|
||||
{ .name = "s2mps11-clk", .driver_data = S2MPS11X },
|
||||
{ .name = "s2mps13-clk", .driver_data = S2MPS13X },
|
||||
{ .name = "s2mps14-clk", .driver_data = S2MPS14X },
|
||||
{ .name = "s5m8767-clk", .driver_data = S5M8767X },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* The Vendor OEM extension for System Control and Power Interface (SCMI)
|
||||
* Protocol based clock driver
|
||||
*
|
||||
* Copyright 2025 NXP
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/scmi_imx_protocol.h>
|
||||
#include <linux/scmi_protocol.h>
|
||||
|
||||
#include "clk-scmi.h"
|
||||
|
||||
#define SCMI_CLOCK_CFG_IMX_SSC 0x80
|
||||
#define SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK GENMASK(7, 0)
|
||||
#define SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK GENMASK(23, 8)
|
||||
#define SCMI_CLOCK_IMX_SS_ENABLE_MASK BIT(24)
|
||||
|
||||
/*
|
||||
* Selection is based on SCMI vendor_id/sub_vendor_id and optional machine
|
||||
* compatible string, without involving impl_ver. impl_ver‑specific behavior
|
||||
* should be considered a bug and handled via SCMI Quirk framework.
|
||||
*/
|
||||
struct scmi_clk_oem_info {
|
||||
char *vendor_id;
|
||||
char *sub_vendor_id;
|
||||
char *compatible;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
static int
|
||||
scmi_clk_imx_set_spread_spectrum(struct clk_hw *hw,
|
||||
const struct clk_spread_spectrum *ss_conf)
|
||||
{
|
||||
struct scmi_clk *clk = to_scmi_clk(hw);
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* extConfigValue[7:0] - spread percentage (%)
|
||||
* extConfigValue[23:8] - Modulation Frequency
|
||||
* extConfigValue[24] - Enable/Disable
|
||||
* extConfigValue[31:25] - Reserved
|
||||
*/
|
||||
val = FIELD_PREP(SCMI_CLOCK_IMX_SS_PERCENTAGE_MASK, ss_conf->spread_bp / 10000);
|
||||
val |= FIELD_PREP(SCMI_CLOCK_IMX_SS_MOD_FREQ_MASK, ss_conf->modfreq_hz);
|
||||
if (ss_conf->method != CLK_SPREAD_NO)
|
||||
val |= SCMI_CLOCK_IMX_SS_ENABLE_MASK;
|
||||
ret = scmi_proto_clk_ops->config_oem_set(clk->ph, clk->id,
|
||||
SCMI_CLOCK_CFG_IMX_SSC,
|
||||
val, false);
|
||||
if (ret)
|
||||
dev_warn(clk->dev,
|
||||
"Failed to set spread spectrum(%u,%u,%u) for clock ID %d\n",
|
||||
ss_conf->modfreq_hz, ss_conf->spread_bp, ss_conf->method,
|
||||
clk->id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
scmi_clk_imx_query_oem_feats(const struct scmi_protocol_handle *ph, u32 id,
|
||||
unsigned int *feats_key)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
ret = scmi_proto_clk_ops->config_oem_get(ph, id,
|
||||
SCMI_CLOCK_CFG_IMX_SSC,
|
||||
&val, NULL, false);
|
||||
if (!ret)
|
||||
*feats_key |= BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct scmi_clk_oem scmi_clk_oem_imx = {
|
||||
.query_ext_oem_feats = scmi_clk_imx_query_oem_feats,
|
||||
.set_spread_spectrum = scmi_clk_imx_set_spread_spectrum,
|
||||
};
|
||||
|
||||
static const struct scmi_clk_oem_info info[] = {
|
||||
{ SCMI_IMX_VENDOR, SCMI_IMX_SUBVENDOR, NULL, &scmi_clk_oem_imx },
|
||||
};
|
||||
|
||||
int scmi_clk_oem_init(struct scmi_device *sdev)
|
||||
{
|
||||
const struct scmi_handle *handle = sdev->handle;
|
||||
int i, size = ARRAY_SIZE(info);
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if (strcmp(handle->version->vendor_id, info[i].vendor_id) ||
|
||||
strcmp(handle->version->sub_vendor_id, info[i].sub_vendor_id))
|
||||
continue;
|
||||
if (info[i].compatible &&
|
||||
!of_machine_is_compatible(info[i].compatible))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < size)
|
||||
dev_set_drvdata(&sdev->dev, (void *)info[i].data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
+16
-28
@@ -13,32 +13,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/scmi_protocol.h>
|
||||
|
||||
#define NOT_ATOMIC false
|
||||
#define ATOMIC true
|
||||
#include "clk-scmi.h"
|
||||
|
||||
enum scmi_clk_feats {
|
||||
SCMI_CLK_ATOMIC_SUPPORTED,
|
||||
SCMI_CLK_STATE_CTRL_SUPPORTED,
|
||||
SCMI_CLK_RATE_CTRL_SUPPORTED,
|
||||
SCMI_CLK_PARENT_CTRL_SUPPORTED,
|
||||
SCMI_CLK_DUTY_CYCLE_SUPPORTED,
|
||||
SCMI_CLK_FEATS_COUNT
|
||||
};
|
||||
|
||||
#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT)
|
||||
|
||||
static const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
|
||||
|
||||
struct scmi_clk {
|
||||
u32 id;
|
||||
struct device *dev;
|
||||
struct clk_hw hw;
|
||||
const struct scmi_clock_info *info;
|
||||
const struct scmi_protocol_handle *ph;
|
||||
struct clk_parent_data *parent_data;
|
||||
};
|
||||
|
||||
#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
|
||||
const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
|
||||
|
||||
static unsigned long scmi_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
@@ -235,6 +212,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
|
||||
static const struct clk_ops *
|
||||
scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
|
||||
{
|
||||
struct scmi_clk_oem *oem_data = dev_get_drvdata(dev);
|
||||
struct clk_ops *ops;
|
||||
|
||||
ops = devm_kzalloc(dev, sizeof(*ops), GFP_KERNEL);
|
||||
@@ -281,11 +259,15 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
|
||||
ops->set_duty_cycle = scmi_clk_set_duty_cycle;
|
||||
}
|
||||
|
||||
if (oem_data && (feats_key & BIT(SCMI_CLK_EXT_OEM_SSC_SUPPORTED)))
|
||||
ops->set_spread_spectrum = oem_data->set_spread_spectrum;
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* scmi_clk_ops_select() - Select a proper set of clock operations
|
||||
* @sdev: pointer to the SCMI device
|
||||
* @sclk: A reference to an SCMI clock descriptor
|
||||
* @atomic_capable: A flag to indicate if atomic mode is supported by the
|
||||
* transport
|
||||
@@ -310,8 +292,8 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
|
||||
* NULL otherwise.
|
||||
*/
|
||||
static const struct clk_ops *
|
||||
scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
|
||||
unsigned int atomic_threshold_us,
|
||||
scmi_clk_ops_select(struct scmi_device *sdev, struct scmi_clk *sclk,
|
||||
bool atomic_capable, unsigned int atomic_threshold_us,
|
||||
const struct clk_ops **clk_ops_db, size_t db_size)
|
||||
{
|
||||
int ret;
|
||||
@@ -319,6 +301,7 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
|
||||
const struct scmi_clock_info *ci = sclk->info;
|
||||
unsigned int feats_key = 0;
|
||||
const struct clk_ops *ops;
|
||||
struct scmi_clk_oem *oem_data = dev_get_drvdata(&sdev->dev);
|
||||
|
||||
/*
|
||||
* Note that when transport is atomic but SCMI protocol did not
|
||||
@@ -343,6 +326,9 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
|
||||
&val, NULL, false);
|
||||
if (!ret)
|
||||
feats_key |= BIT(SCMI_CLK_DUTY_CYCLE_SUPPORTED);
|
||||
|
||||
if (oem_data && oem_data->query_ext_oem_feats)
|
||||
oem_data->query_ext_oem_feats(sclk->ph, sclk->id, &feats_key);
|
||||
}
|
||||
|
||||
if (WARN_ON(feats_key >= db_size))
|
||||
@@ -400,6 +386,8 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
clk_data->num = count;
|
||||
hws = clk_data->hws;
|
||||
|
||||
scmi_clk_oem_init(sdev);
|
||||
|
||||
transport_is_atomic = handle->is_transport_atomic(handle,
|
||||
&atomic_threshold_us);
|
||||
|
||||
@@ -431,7 +419,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
|
||||
* to avoid sharing the devm_ allocated clk_ops between multiple
|
||||
* SCMI clk driver instances.
|
||||
*/
|
||||
scmi_ops = scmi_clk_ops_select(sclk, transport_is_atomic,
|
||||
scmi_ops = scmi_clk_ops_select(sdev, sclk, transport_is_atomic,
|
||||
atomic_threshold_us,
|
||||
scmi_clk_ops_db,
|
||||
ARRAY_SIZE(scmi_clk_ops_db));
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright 2025 NXP
|
||||
*/
|
||||
|
||||
#ifndef __SCMI_CLK_H
|
||||
#define __SCMI_CLK_H
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/scmi_protocol.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define NOT_ATOMIC false
|
||||
#define ATOMIC true
|
||||
|
||||
enum scmi_clk_feats {
|
||||
SCMI_CLK_ATOMIC_SUPPORTED,
|
||||
SCMI_CLK_STATE_CTRL_SUPPORTED,
|
||||
SCMI_CLK_RATE_CTRL_SUPPORTED,
|
||||
SCMI_CLK_PARENT_CTRL_SUPPORTED,
|
||||
SCMI_CLK_DUTY_CYCLE_SUPPORTED,
|
||||
SCMI_CLK_EXT_OEM_SSC_SUPPORTED,
|
||||
SCMI_CLK_FEATS_COUNT
|
||||
};
|
||||
|
||||
#define SCMI_MAX_CLK_OPS BIT(SCMI_CLK_FEATS_COUNT)
|
||||
|
||||
struct scmi_clk {
|
||||
u32 id;
|
||||
struct device *dev;
|
||||
struct clk_hw hw;
|
||||
const struct scmi_clock_info *info;
|
||||
const struct scmi_protocol_handle *ph;
|
||||
struct clk_parent_data *parent_data;
|
||||
};
|
||||
|
||||
#define to_scmi_clk(clk) container_of(clk, struct scmi_clk, hw)
|
||||
|
||||
extern const struct scmi_clk_proto_ops *scmi_proto_clk_ops;
|
||||
|
||||
struct scmi_clk_oem {
|
||||
int (*query_ext_oem_feats)(const struct scmi_protocol_handle *ph,
|
||||
u32 id, unsigned int *feats_key);
|
||||
int (*set_spread_spectrum)(struct clk_hw *hw,
|
||||
const struct clk_spread_spectrum *ss_conf);
|
||||
};
|
||||
|
||||
int scmi_clk_oem_init(struct scmi_device *dev);
|
||||
|
||||
#endif
|
||||
+1
-13
@@ -32,18 +32,6 @@ static unsigned long scpi_clk_recalc_rate(struct clk_hw *hw,
|
||||
return clk->scpi_ops->clk_get_val(clk->id);
|
||||
}
|
||||
|
||||
static int scpi_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
/*
|
||||
* We can't figure out what rate it will be, so just return the
|
||||
* rate back to the caller. scpi_clk_recalc_rate() will be called
|
||||
* after the rate is set and we'll know what rate the clock is
|
||||
* running at then.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@@ -54,7 +42,7 @@ static int scpi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
static const struct clk_ops scpi_clk_ops = {
|
||||
.recalc_rate = scpi_clk_recalc_rate,
|
||||
.determine_rate = scpi_clk_determine_rate,
|
||||
.determine_rate = clk_determine_rate_noop,
|
||||
.set_rate = scpi_clk_set_rate,
|
||||
};
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ static int si514_probe(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id si514_id[] = {
|
||||
{ "si514" },
|
||||
{ .name = "si514" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si514_id);
|
||||
|
||||
@@ -364,9 +364,9 @@ static int __maybe_unused si521xx_resume(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id si521xx_id[] = {
|
||||
{ "si52144", .driver_data = SI521XX_OE_MAP(0x5, 0xc0) },
|
||||
{ "si52146", .driver_data = SI521XX_OE_MAP(0x15, 0xe0) },
|
||||
{ "si52147", .driver_data = SI521XX_OE_MAP(0x17, 0xf8) },
|
||||
{ .name = "si52144", .driver_data = SI521XX_OE_MAP(0x5, 0xc0) },
|
||||
{ .name = "si52146", .driver_data = SI521XX_OE_MAP(0x15, 0xe0) },
|
||||
{ .name = "si52147", .driver_data = SI521XX_OE_MAP(0x17, 0xf8) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si521xx_id);
|
||||
|
||||
@@ -1825,11 +1825,11 @@ static void si5341_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id si5341_id[] = {
|
||||
{ "si5340", 0 },
|
||||
{ "si5341", 1 },
|
||||
{ "si5342", 2 },
|
||||
{ "si5344", 4 },
|
||||
{ "si5345", 5 },
|
||||
{ .name = "si5340" },
|
||||
{ .name = "si5341" },
|
||||
{ .name = "si5342" },
|
||||
{ .name = "si5344" },
|
||||
{ .name = "si5345" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si5341_id);
|
||||
|
||||
@@ -1425,10 +1425,10 @@ si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
|
||||
#endif /* CONFIG_OF */
|
||||
|
||||
static const struct i2c_device_id si5351_i2c_ids[] = {
|
||||
{ "si5351a", SI5351_VARIANT_A },
|
||||
{ "si5351a-msop", SI5351_VARIANT_A3 },
|
||||
{ "si5351b", SI5351_VARIANT_B },
|
||||
{ "si5351c", SI5351_VARIANT_C },
|
||||
{ .name = "si5351a", .driver_data = SI5351_VARIANT_A },
|
||||
{ .name = "si5351a-msop", .driver_data = SI5351_VARIANT_A3 },
|
||||
{ .name = "si5351b", .driver_data = SI5351_VARIANT_B },
|
||||
{ .name = "si5351c", .driver_data = SI5351_VARIANT_C },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
|
||||
|
||||
+65
-17
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for Silicon Labs Si544 Programmable Oscillator
|
||||
* Driver for Silicon Labs Si544/Si549 Programmable Oscillator
|
||||
* Copyright (C) 2018 Topic Embedded Products
|
||||
* Author: Mike Looijmans <mike.looijmans@topic.nl>
|
||||
*/
|
||||
@@ -40,7 +40,9 @@
|
||||
#define SI544_MIN_FREQ 200000U
|
||||
|
||||
/* Si544 Internal oscillator runs at 55.05 MHz */
|
||||
#define FXO 55050000U
|
||||
#define SI544_XO_FREQ 55050000U
|
||||
/* Si549 Internal oscilator runs at 152.60 MHz */
|
||||
#define SI549_XO_FREQ 152600000U
|
||||
|
||||
/* VCO range is 10.8 .. 12.1 GHz, max depends on speed grade */
|
||||
#define FVCO_MIN 10800000000ULL
|
||||
@@ -56,11 +58,16 @@
|
||||
#define DELTA_M_FRAC_NUM 19
|
||||
#define DELTA_M_FRAC_DEN 20000
|
||||
|
||||
struct si544_clk_desc {
|
||||
unsigned long max_freq;
|
||||
unsigned long xo_freq;
|
||||
};
|
||||
|
||||
struct clk_si544 {
|
||||
struct clk_hw hw;
|
||||
struct regmap *regmap;
|
||||
struct i2c_client *i2c_client;
|
||||
unsigned long max_freq;
|
||||
const struct si544_clk_desc *chip_info;
|
||||
};
|
||||
#define to_clk_si544(_hw) container_of(_hw, struct clk_si544, hw)
|
||||
|
||||
@@ -79,6 +86,7 @@ struct clk_si544_muldiv {
|
||||
u16 hs_div;
|
||||
u8 ls_div_bits;
|
||||
s32 delta_m;
|
||||
u32 xo_freq;
|
||||
};
|
||||
|
||||
/* Enables or disables the output driver */
|
||||
@@ -145,6 +153,8 @@ static int si544_get_muldiv(struct clk_si544 *data,
|
||||
settings->delta_m = reg[0] << 8 | reg[1] << 16 | reg[2] << 24;
|
||||
settings->delta_m >>= 8;
|
||||
|
||||
settings->xo_freq = data->chip_info->xo_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -193,7 +203,7 @@ static bool is_valid_frequency(const struct clk_si544 *data,
|
||||
if (frequency < SI544_MIN_FREQ)
|
||||
return false;
|
||||
|
||||
return frequency <= data->max_freq;
|
||||
return frequency <= data->chip_info->max_freq;
|
||||
}
|
||||
|
||||
/* Calculate divider settings for a given frequency */
|
||||
@@ -201,6 +211,7 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings,
|
||||
unsigned long frequency)
|
||||
{
|
||||
u64 vco;
|
||||
u32 fxo = settings->xo_freq;
|
||||
u32 ls_freq;
|
||||
u32 tmp;
|
||||
u8 res;
|
||||
@@ -238,13 +249,13 @@ static int si544_calc_muldiv(struct clk_si544_muldiv *settings,
|
||||
vco = (u64)ls_freq * settings->hs_div;
|
||||
|
||||
/* Calculate the integer part of the feedback divider */
|
||||
tmp = do_div(vco, FXO);
|
||||
tmp = do_div(vco, fxo);
|
||||
settings->fb_div_int = vco;
|
||||
|
||||
/* And the fractional bits using the remainder */
|
||||
vco = (u64)tmp << 32;
|
||||
vco += FXO / 2; /* Round to nearest multiple */
|
||||
do_div(vco, FXO);
|
||||
vco += fxo / 2; /* Round to nearest multiple */
|
||||
do_div(vco, fxo);
|
||||
settings->fb_div_frac = vco;
|
||||
|
||||
/* Reset the frequency adjustment */
|
||||
@@ -258,15 +269,16 @@ static unsigned long si544_calc_center_rate(
|
||||
const struct clk_si544_muldiv *settings)
|
||||
{
|
||||
u32 d = settings->hs_div * BIT(settings->ls_div_bits);
|
||||
u32 fxo = settings->xo_freq;
|
||||
u64 vco;
|
||||
|
||||
/* Calculate VCO from the fractional part */
|
||||
vco = (u64)settings->fb_div_frac * FXO;
|
||||
vco += (FXO / 2);
|
||||
vco = (u64)settings->fb_div_frac * fxo;
|
||||
vco += (fxo / 2);
|
||||
vco >>= 32;
|
||||
|
||||
/* Add the integer part of the VCO frequency */
|
||||
vco += (u64)settings->fb_div_int * FXO;
|
||||
vco += (u64)settings->fb_div_int * fxo;
|
||||
|
||||
/* Apply divider to obtain the generated frequency */
|
||||
do_div(vco, d);
|
||||
@@ -446,7 +458,7 @@ static int si544_probe(struct i2c_client *client)
|
||||
init.num_parents = 0;
|
||||
data->hw.init = &init;
|
||||
data->i2c_client = client;
|
||||
data->max_freq = (uintptr_t)i2c_get_match_data(client);
|
||||
data->chip_info = i2c_get_match_data(client);
|
||||
|
||||
if (of_property_read_string(client->dev.of_node, "clock-output-names",
|
||||
&init.name))
|
||||
@@ -478,18 +490,54 @@ static int si544_probe(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct si544_clk_desc clk_si544a_info = {
|
||||
.xo_freq = SI544_XO_FREQ,
|
||||
.max_freq = 1500000000,
|
||||
};
|
||||
|
||||
static const struct si544_clk_desc clk_si544b_info = {
|
||||
.xo_freq = SI544_XO_FREQ,
|
||||
.max_freq = 800000000,
|
||||
};
|
||||
|
||||
static const struct si544_clk_desc clk_si544c_info = {
|
||||
.xo_freq = SI544_XO_FREQ,
|
||||
.max_freq = 325000000,
|
||||
};
|
||||
|
||||
static const struct si544_clk_desc clk_si549a_info = {
|
||||
.xo_freq = SI549_XO_FREQ,
|
||||
.max_freq = 1500000000,
|
||||
};
|
||||
|
||||
static const struct si544_clk_desc clk_si549b_info = {
|
||||
.xo_freq = SI549_XO_FREQ,
|
||||
.max_freq = 800000000,
|
||||
};
|
||||
|
||||
static const struct si544_clk_desc clk_si549c_info = {
|
||||
.xo_freq = SI549_XO_FREQ,
|
||||
.max_freq = 325000000,
|
||||
};
|
||||
|
||||
static const struct i2c_device_id si544_id[] = {
|
||||
{ "si544a", 1500000000 },
|
||||
{ "si544b", 800000000 },
|
||||
{ "si544c", 350000000 },
|
||||
{ .name = "si544a", .driver_data = (kernel_ulong_t)&clk_si544a_info },
|
||||
{ .name = "si544b", .driver_data = (kernel_ulong_t)&clk_si544b_info },
|
||||
{ .name = "si544c", .driver_data = (kernel_ulong_t)&clk_si544c_info },
|
||||
{ .name = "si549a", .driver_data = (kernel_ulong_t)&clk_si549a_info },
|
||||
{ .name = "si549b", .driver_data = (kernel_ulong_t)&clk_si549b_info },
|
||||
{ .name = "si549c", .driver_data = (kernel_ulong_t)&clk_si549c_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si544_id);
|
||||
|
||||
static const struct of_device_id clk_si544_of_match[] = {
|
||||
{ .compatible = "silabs,si544a", .data = (void *)1500000000 },
|
||||
{ .compatible = "silabs,si544b", .data = (void *)800000000 },
|
||||
{ .compatible = "silabs,si544c", .data = (void *)350000000 },
|
||||
{ .compatible = "silabs,si544a", .data = &clk_si544a_info },
|
||||
{ .compatible = "silabs,si544b", .data = &clk_si544b_info },
|
||||
{ .compatible = "silabs,si544c", .data = &clk_si544c_info },
|
||||
{ .compatible = "silabs,si549a", .data = &clk_si549a_info },
|
||||
{ .compatible = "silabs,si549b", .data = &clk_si549b_info },
|
||||
{ .compatible = "silabs,si549c", .data = &clk_si549c_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_si544_of_match);
|
||||
|
||||
@@ -503,10 +503,10 @@ static const struct clk_si570_info clk_si590_info = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id si570_id[] = {
|
||||
{ "si570", (kernel_ulong_t)&clk_si570_info },
|
||||
{ "si571", (kernel_ulong_t)&clk_si570_info },
|
||||
{ "si598", (kernel_ulong_t)&clk_si590_info },
|
||||
{ "si599", (kernel_ulong_t)&clk_si590_info },
|
||||
{ .name = "si570", .driver_data = (kernel_ulong_t)&clk_si570_info },
|
||||
{ .name = "si571", .driver_data = (kernel_ulong_t)&clk_si570_info },
|
||||
{ .name = "si598", .driver_data = (kernel_ulong_t)&clk_si590_info },
|
||||
{ .name = "si599", .driver_data = (kernel_ulong_t)&clk_si590_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si570_id);
|
||||
|
||||
@@ -1310,14 +1310,14 @@ static const struct vc5_chip_info idt_5p49v6975_info = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id vc5_id[] = {
|
||||
{ "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info },
|
||||
{ "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info },
|
||||
{ "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info },
|
||||
{ "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info },
|
||||
{ "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info },
|
||||
{ "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info },
|
||||
{ "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info },
|
||||
{ "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info },
|
||||
{ .name = "5p49v5923", .driver_data = (kernel_ulong_t)&idt_5p49v5923_info },
|
||||
{ .name = "5p49v5925", .driver_data = (kernel_ulong_t)&idt_5p49v5925_info },
|
||||
{ .name = "5p49v5933", .driver_data = (kernel_ulong_t)&idt_5p49v5933_info },
|
||||
{ .name = "5p49v5935", .driver_data = (kernel_ulong_t)&idt_5p49v5935_info },
|
||||
{ .name = "5p49v60", .driver_data = (kernel_ulong_t)&idt_5p49v60_info },
|
||||
{ .name = "5p49v6901", .driver_data = (kernel_ulong_t)&idt_5p49v6901_info },
|
||||
{ .name = "5p49v6965", .driver_data = (kernel_ulong_t)&idt_5p49v6965_info },
|
||||
{ .name = "5p49v6975", .driver_data = (kernel_ulong_t)&idt_5p49v6975_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, vc5_id);
|
||||
|
||||
@@ -1197,7 +1197,7 @@ static int vc7_probe(struct i2c_client *client)
|
||||
if (ret) {
|
||||
dev_err_probe(&client->dev, ret,
|
||||
"unable to register output %d\n", i);
|
||||
return ret;
|
||||
goto err_clk;
|
||||
}
|
||||
|
||||
switch (bank_src_map.type) {
|
||||
@@ -1288,8 +1288,8 @@ static const struct regmap_config vc7_regmap_config = {
|
||||
};
|
||||
|
||||
static const struct i2c_device_id vc7_i2c_id[] = {
|
||||
{ "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info },
|
||||
{}
|
||||
{ .name = "rc21008a", .driver_data = (kernel_ulong_t)&vc7_rc21008a_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, vc7_i2c_id);
|
||||
|
||||
|
||||
+104
-8
@@ -63,6 +63,57 @@ struct clk_parent_map {
|
||||
int index;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clk_core - The internal state of a clk in the clk tree.
|
||||
* @name: Unique name of the clk for identification.
|
||||
* @ops: Pointer to hardware-specific operations for this clk.
|
||||
* @hw: Pointer for traversing from a struct clk to its
|
||||
* corresponding hardware-specific structure.
|
||||
* @owner: Kernel module owning this clk (for reference counting).
|
||||
* @dev: Device associated with this clk (optional)
|
||||
* @rpm_node: Node for runtime power management list management.
|
||||
* @of_node: Device tree node associated with this clk (if applicable)
|
||||
* @parent: Pointer to the current parent in the clock tree.
|
||||
* @parents: Array of possible parents (for muxes/selectable parents).
|
||||
* @num_parents: Number of possible parents.
|
||||
* @new_parent_index: Index of the new parent during parent change operations.
|
||||
* @rate: Current cached clock rate (Hz).
|
||||
* @req_rate: The last rate requested by a call to clk_set_rate(). It's
|
||||
* initialized to clk_core->rate. It's also updated to
|
||||
* clk_core->rate every time the clock is reparented, and
|
||||
* when we're doing the orphan -> !orphan transition.
|
||||
* @new_rate: New rate to be set during a rate change operation.
|
||||
* @new_parent: Pointer to new parent during parent change. This is also
|
||||
* used when a clk's rate is changed.
|
||||
* @new_child: Pointer to new child during reparenting. This is also
|
||||
* used when a clk's rate is changed.
|
||||
* @flags: Clock property and capability flags. See
|
||||
* `clk framework flags`.
|
||||
* @orphan: True if this clk is currently orphaned.
|
||||
* @rpm_enabled: True if runtime power management is enabled for this clk.
|
||||
* @enable_count: Reference count of enables.
|
||||
* @prepare_count: Reference count of prepares.
|
||||
* @protect_count: Protection reference count against disable.
|
||||
* @min_rate: Minimum supported clock rate (Hz).
|
||||
* @max_rate: Maximum supported clock rate (Hz).
|
||||
* @accuracy: Accuracy of the clock rate (parts per billion).
|
||||
* @phase: Current phase (degrees).
|
||||
* @duty: Current duty cycle configuration (as ratio: num/den).
|
||||
* @children: All of the children of this clk.
|
||||
* @child_node: Node for linking as a child in the parent's list.
|
||||
* @hashtable_node: Node for hash table that allows fast clk lookup by name.
|
||||
* @clks: All of the clk consumers registered.
|
||||
* @notifier_count: Number of notifiers registered for this clk.
|
||||
* @dentry: DebugFS entry for this clk.
|
||||
* @debug_node: DebugFS node for this clk.
|
||||
* @ref: Reference count for structure lifetime management.
|
||||
*
|
||||
* Managed by the clk framework. Clk providers and consumers do not interact
|
||||
* with this structure directly. Instead, clk operations flow through the
|
||||
* framework and the framework manipulates this structure to keep track of
|
||||
* parent/child relationships, rate, enable state, etc.
|
||||
*
|
||||
*/
|
||||
struct clk_core {
|
||||
const char *name;
|
||||
const struct clk_ops *ops;
|
||||
@@ -882,6 +933,24 @@ int clk_hw_determine_rate_no_reparent(struct clk_hw *hw,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_determine_rate_no_reparent);
|
||||
|
||||
/**
|
||||
* clk_determine_rate_noop - clk_ops::determine_rate noop implementation
|
||||
* @hw: clk to determine rate on
|
||||
* @req: rate request
|
||||
*
|
||||
* Noop determine rate for clocks where the rate rounding is handled by the
|
||||
* firmware/hardware, or the clock is capable of any rate. The requested rate is
|
||||
* passed through unchanged, and the actual rate will be learned via
|
||||
* recalc_rate() after the rate is set.
|
||||
*
|
||||
* Returns: 0 always
|
||||
*/
|
||||
int clk_determine_rate_noop(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_determine_rate_noop);
|
||||
|
||||
/*** clk api ***/
|
||||
|
||||
static void clk_core_rate_unprotect(struct clk_core *core)
|
||||
@@ -1846,10 +1915,10 @@ static int __clk_notify(struct clk_core *core, unsigned long msg,
|
||||
}
|
||||
|
||||
/**
|
||||
* __clk_recalc_accuracies
|
||||
* __clk_recalc_accuracies - recalculate all accuracies in the clk subtree
|
||||
* @core: first clk in the subtree
|
||||
*
|
||||
* Walks the subtree of clks starting with clk and recalculates accuracies as
|
||||
* Walks the subtree of clks starting with @core and recalculates accuracies as
|
||||
* it goes. Note that if a clk does not implement the .recalc_accuracy
|
||||
* callback then it is assumed that the clock will take on the accuracy of its
|
||||
* parent.
|
||||
@@ -1919,16 +1988,16 @@ static unsigned long clk_recalc(struct clk_core *core,
|
||||
}
|
||||
|
||||
/**
|
||||
* __clk_recalc_rates
|
||||
* __clk_recalc_rates - recalculate all rates in the clk subtree
|
||||
* @core: first clk in the subtree
|
||||
* @update_req: Whether req_rate should be updated with the new rate
|
||||
* @msg: notification type (see include/linux/clk.h)
|
||||
*
|
||||
* Walks the subtree of clks starting with clk and recalculates rates as it
|
||||
* Walks the subtree of clks starting with @core and recalculates rates as it
|
||||
* goes. Note that if a clk does not implement the .recalc_rate callback then
|
||||
* it is assumed that the clock will take on the rate of its parent.
|
||||
*
|
||||
* clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
|
||||
* __clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
|
||||
* if necessary.
|
||||
*/
|
||||
static void __clk_recalc_rates(struct clk_core *core, bool update_req,
|
||||
@@ -2191,14 +2260,14 @@ static int __clk_set_parent(struct clk_core *core, struct clk_core *parent,
|
||||
}
|
||||
|
||||
/**
|
||||
* __clk_speculate_rates
|
||||
* __clk_speculate_rates - speculate all rates in the clk subtree
|
||||
* @core: first clk in the subtree
|
||||
* @parent_rate: the "future" rate of clk's parent
|
||||
*
|
||||
* Walks the subtree of clks starting with clk, speculating rates as it
|
||||
* Walks the subtree of clks starting with @core, speculating rates as it
|
||||
* goes and firing off PRE_RATE_CHANGE notifications as necessary.
|
||||
*
|
||||
* Unlike clk_recalc_rates, clk_speculate_rates exists only for sending
|
||||
* Unlike __clk_recalc_rates, __clk_speculate_rates exists only for sending
|
||||
* pre-rate change notifications and returns early if no clks in the
|
||||
* subtree have subscribed to the notifications. Note that if a clk does not
|
||||
* implement the .recalc_rate callback then it is assumed that the clock will
|
||||
@@ -2774,6 +2843,33 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_set_max_rate);
|
||||
|
||||
int clk_hw_set_spread_spectrum(struct clk_hw *hw, const struct clk_spread_spectrum *ss_conf)
|
||||
{
|
||||
struct clk_core *core;
|
||||
int ret;
|
||||
|
||||
if (!hw)
|
||||
return 0;
|
||||
|
||||
core = hw->core;
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
ret = clk_pm_runtime_get(core);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
if (core->ops->set_spread_spectrum)
|
||||
ret = core->ops->set_spread_spectrum(hw, ss_conf);
|
||||
|
||||
clk_pm_runtime_put(core);
|
||||
|
||||
fail:
|
||||
clk_prepare_unlock();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_set_spread_spectrum);
|
||||
|
||||
/**
|
||||
* clk_get_parent - return the parent of a clk
|
||||
* @clk: the clk whose parent gets returned
|
||||
|
||||
+206
-8
@@ -7,6 +7,7 @@
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
/* Needed for clk_hw_get_clk() */
|
||||
#include "clk.h"
|
||||
@@ -21,13 +22,14 @@
|
||||
|
||||
static const struct clk_ops empty_clk_ops = { };
|
||||
|
||||
#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000)
|
||||
#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
|
||||
#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
|
||||
#define DUMMY_CLOCK_INIT_RATE (42 * HZ_PER_MHZ)
|
||||
#define DUMMY_CLOCK_RATE_1 (142 * HZ_PER_MHZ)
|
||||
#define DUMMY_CLOCK_RATE_2 (242 * HZ_PER_MHZ)
|
||||
|
||||
struct clk_dummy_context {
|
||||
struct clk_hw hw;
|
||||
unsigned long rate;
|
||||
struct clk_spread_spectrum sscs;
|
||||
};
|
||||
|
||||
static unsigned long clk_dummy_recalc_rate(struct clk_hw *hw,
|
||||
@@ -83,6 +85,17 @@ static int clk_dummy_set_rate(struct clk_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_dummy_set_spread_spectrum(struct clk_hw *hw,
|
||||
const struct clk_spread_spectrum *ss_conf)
|
||||
{
|
||||
struct clk_dummy_context *ctx =
|
||||
container_of(hw, struct clk_dummy_context, hw);
|
||||
|
||||
ctx->sscs = *ss_conf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_dummy_single_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
if (index >= clk_hw_get_num_parents(hw))
|
||||
@@ -100,18 +113,21 @@ static const struct clk_ops clk_dummy_rate_ops = {
|
||||
.recalc_rate = clk_dummy_recalc_rate,
|
||||
.determine_rate = clk_dummy_determine_rate,
|
||||
.set_rate = clk_dummy_set_rate,
|
||||
.set_spread_spectrum = clk_dummy_set_spread_spectrum,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_dummy_maximize_rate_ops = {
|
||||
.recalc_rate = clk_dummy_recalc_rate,
|
||||
.determine_rate = clk_dummy_maximize_rate,
|
||||
.set_rate = clk_dummy_set_rate,
|
||||
.set_spread_spectrum = clk_dummy_set_spread_spectrum,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_dummy_minimize_rate_ops = {
|
||||
.recalc_rate = clk_dummy_recalc_rate,
|
||||
.determine_rate = clk_dummy_minimize_rate,
|
||||
.set_rate = clk_dummy_set_rate,
|
||||
.set_spread_spectrum = clk_dummy_set_spread_spectrum,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_dummy_single_parent_ops = {
|
||||
@@ -2232,7 +2248,7 @@ static void
|
||||
clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc(
|
||||
const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *t, char *desc)
|
||||
{
|
||||
strcpy(desc, t->desc);
|
||||
strscpy(desc, t->desc, KUNIT_PARAM_DESC_SIZE);
|
||||
}
|
||||
|
||||
static const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case
|
||||
@@ -2644,7 +2660,7 @@ static void
|
||||
clk_register_clk_parent_data_test_case_to_desc(
|
||||
const struct clk_register_clk_parent_data_test_case *t, char *desc)
|
||||
{
|
||||
strcpy(desc, t->desc);
|
||||
strscpy(desc, t->desc, KUNIT_PARAM_DESC_SIZE);
|
||||
}
|
||||
|
||||
static const struct clk_register_clk_parent_data_test_case
|
||||
@@ -3097,6 +3113,7 @@ struct clk_assigned_rates_context {
|
||||
* @overlay_end: Pointer to end of DT overlay to apply for test
|
||||
* @rate0: Initial rate of first clk
|
||||
* @rate1: Initial rate of second clk
|
||||
* @sscs: Initial spread spectrum settings
|
||||
* @consumer_test: true if a consumer is being tested
|
||||
*/
|
||||
struct clk_assigned_rates_test_param {
|
||||
@@ -3105,6 +3122,7 @@ struct clk_assigned_rates_test_param {
|
||||
u8 *overlay_end;
|
||||
unsigned long rate0;
|
||||
unsigned long rate1;
|
||||
struct clk_spread_spectrum sscs;
|
||||
bool consumer_test;
|
||||
};
|
||||
|
||||
@@ -3116,7 +3134,7 @@ static void
|
||||
clk_assigned_rates_register_clk(struct kunit *test,
|
||||
struct clk_dummy_context *ctx,
|
||||
struct device_node *np, const char *name,
|
||||
unsigned long rate)
|
||||
unsigned long rate, const struct clk_spread_spectrum *sscs)
|
||||
{
|
||||
struct clk_init_data init = { };
|
||||
|
||||
@@ -3124,6 +3142,7 @@ clk_assigned_rates_register_clk(struct kunit *test,
|
||||
init.ops = &clk_dummy_rate_ops;
|
||||
ctx->hw.init = &init;
|
||||
ctx->rate = rate;
|
||||
ctx->sscs = *sscs;
|
||||
|
||||
KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, np, &ctx->hw));
|
||||
KUNIT_ASSERT_EQ(test, ctx->rate, rate);
|
||||
@@ -3167,14 +3186,16 @@ static int clk_assigned_rates_test_init(struct kunit *test)
|
||||
KUNIT_ASSERT_LT(test, clk_cells, 2);
|
||||
|
||||
clk_assigned_rates_register_clk(test, &ctx->clk0, np,
|
||||
"test_assigned_rate0", test_param->rate0);
|
||||
"test_assigned_rate0", test_param->rate0,
|
||||
&test_param->sscs);
|
||||
if (clk_cells == 0) {
|
||||
KUNIT_ASSERT_EQ(test, 0,
|
||||
of_clk_add_hw_provider_kunit(test, np, of_clk_hw_simple_get,
|
||||
&ctx->clk0.hw));
|
||||
} else if (clk_cells == 1) {
|
||||
clk_assigned_rates_register_clk(test, &ctx->clk1, np,
|
||||
"test_assigned_rate1", test_param->rate1);
|
||||
"test_assigned_rate1", test_param->rate1,
|
||||
&test_param->sscs);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test,
|
||||
data = kunit_kzalloc(test, struct_size(data, hws, 2), GFP_KERNEL));
|
||||
@@ -3403,6 +3424,182 @@ static struct kunit_suite clk_assigned_rates_suite = {
|
||||
.init = clk_assigned_rates_test_init,
|
||||
};
|
||||
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_one_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_multiple_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_without_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_zero_consumer);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null);
|
||||
OF_OVERLAY_DECLARE(kunit_clk_assigned_sscs_null_consumer);
|
||||
|
||||
static void clk_assigned_sscs_assigns_one(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
|
||||
}
|
||||
|
||||
/* Test cases that assign sscs for one clk */
|
||||
static const struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_one_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-sscs property
|
||||
* assigns the sscs when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a single cell assigned-clock-sscs property
|
||||
* assigns the sscs when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_one_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_one,
|
||||
clk_assigned_sscs_assigns_one_test_params, desc)
|
||||
|
||||
static void clk_assigned_sscs_assigns_multiple(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.modfreq_hz, ASSIGNED_SSCS_1_MODFREQ);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.spread_bp, ASSIGNED_SSCS_1_SPREAD);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk1.sscs.method, ASSIGNED_SSCS_1_METHOD);
|
||||
}
|
||||
|
||||
/* Test cases that assign sscs for multiple clks */
|
||||
static const
|
||||
struct clk_assigned_rates_test_param clk_assigned_sscs_assigns_multiple_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that a multiple cell assigned-clock-sscs property
|
||||
* assigns the sscs when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple),
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that a multiple cell assigned-clock-sscs property
|
||||
* assigns the sscs when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigns",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_multiple_consumer),
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_assigns_multiple,
|
||||
clk_assigned_sscs_assigns_multiple_test_params,
|
||||
desc)
|
||||
|
||||
static void clk_assigned_sscs_skips(struct kunit *test)
|
||||
{
|
||||
struct clk_assigned_rates_context *ctx = test->priv;
|
||||
const struct clk_assigned_rates_test_param *test_param = test->param_value;
|
||||
|
||||
KUNIT_EXPECT_NE(test, ctx->clk0.sscs.modfreq_hz, ASSIGNED_SSCS_0_MODFREQ);
|
||||
KUNIT_EXPECT_NE(test, ctx->clk0.sscs.spread_bp, ASSIGNED_SSCS_0_SPREAD);
|
||||
KUNIT_EXPECT_NE(test, ctx->clk0.sscs.method, ASSIGNED_SSCS_0_METHOD);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.modfreq_hz, test_param->sscs.modfreq_hz);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.spread_bp, test_param->sscs.spread_bp);
|
||||
KUNIT_EXPECT_EQ(test, ctx->clk0.sscs.method, test_param->sscs.method);
|
||||
}
|
||||
|
||||
/* Test cases that skip changing the sscs due to malformed DT */
|
||||
static const struct clk_assigned_rates_test_param clk_assigned_sscs_skips_test_params[] = {
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-sscs property without an assigned-clocks
|
||||
* property fails when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider missing assigned-clocks",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without),
|
||||
.sscs = {50000, 60000, 3},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-sscs property without an assigned-clocks
|
||||
* property fails when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer missing assigned-clocks",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_without_consumer),
|
||||
.sscs = {50000, 60000, 3},
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-sscs property of zero doesn't
|
||||
* set sscs when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigned-clock-sscs of zero",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero),
|
||||
.sscs = {50000, 60000, 3},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clock-sscs property of zero doesn't
|
||||
* set sscs when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigned-clock-sscs of zero",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_zero_consumer),
|
||||
.sscs = {50000, 60000, 3},
|
||||
.consumer_test = true,
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clocks property with a null phandle
|
||||
* doesn't set sscs when the property is in the provider.
|
||||
*/
|
||||
.desc = "provider assigned-clocks null phandle",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null),
|
||||
.sscs = {50000, 60000, 3},
|
||||
},
|
||||
{
|
||||
/*
|
||||
* Test that an assigned-clocks property with a null phandle
|
||||
* doesn't set sscs when the property is in the consumer.
|
||||
*/
|
||||
.desc = "consumer assigned-clocks null phandle",
|
||||
TEST_PARAM_OVERLAY(kunit_clk_assigned_sscs_null_consumer),
|
||||
.sscs = {50000, 60000, 3},
|
||||
.consumer_test = true,
|
||||
},
|
||||
};
|
||||
KUNIT_ARRAY_PARAM_DESC(clk_assigned_sscs_skips,
|
||||
clk_assigned_sscs_skips_test_params,
|
||||
desc)
|
||||
|
||||
static struct kunit_case clk_assigned_sscs_test_cases[] = {
|
||||
KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_one,
|
||||
clk_assigned_sscs_assigns_one_gen_params),
|
||||
KUNIT_CASE_PARAM(clk_assigned_sscs_assigns_multiple,
|
||||
clk_assigned_sscs_assigns_multiple_gen_params),
|
||||
KUNIT_CASE_PARAM(clk_assigned_sscs_skips,
|
||||
clk_assigned_sscs_skips_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
/*
|
||||
* Test suite for assigned-clock-sscs DT property.
|
||||
*/
|
||||
static struct kunit_suite clk_assigned_sscs_suite = {
|
||||
.name = "clk_assigned_sscs",
|
||||
.test_cases = clk_assigned_sscs_test_cases,
|
||||
.init = clk_assigned_rates_test_init,
|
||||
};
|
||||
|
||||
static const struct clk_init_data clk_hw_get_dev_of_node_init_data = {
|
||||
.name = "clk_hw_get_dev_of_node",
|
||||
.ops = &empty_clk_ops,
|
||||
@@ -3544,6 +3741,7 @@ static struct kunit_suite clk_hw_get_dev_of_node_test_suite = {
|
||||
|
||||
kunit_test_suites(
|
||||
&clk_assigned_rates_suite,
|
||||
&clk_assigned_sscs_suite,
|
||||
&clk_hw_get_dev_of_node_test_suite,
|
||||
&clk_leaf_mux_set_rate_parent_test_suite,
|
||||
&clk_test_suite,
|
||||
|
||||
@@ -13,3 +13,16 @@ config COMMON_CLK_EIC7700
|
||||
SoC. The clock controller generates and supplies clocks to various
|
||||
peripherals within the SoC.
|
||||
Say yes here to support the clock controller on the EIC7700 SoC.
|
||||
|
||||
config COMMON_CLK_EIC7700_HSP
|
||||
tristate "EIC7700 HSP Clock Driver"
|
||||
depends on ARCH_ESWIN || COMPILE_TEST
|
||||
select AUXILIARY_BUS
|
||||
select COMMON_CLK_EIC7700
|
||||
select RESET_EIC7700_HSP if RESET_CONTROLLER
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
This driver provides support for clock controller on ESWIN EIC7700
|
||||
HSP. The clock controller generates and supplies clocks to high
|
||||
speed peripherals within the SoC.
|
||||
Say yes here to support the clock controller on the EIC7700 HSP.
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
obj-$(CONFIG_COMMON_CLK_ESWIN) += clk.o
|
||||
|
||||
obj-$(CONFIG_COMMON_CLK_EIC7700) += clk-eic7700.o
|
||||
obj-$(CONFIG_COMMON_CLK_EIC7700_HSP) += clk-eic7700-hsp.o
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
|
||||
* All rights reserved.
|
||||
*
|
||||
* ESWIN EIC7700 HSP Clock Driver
|
||||
*
|
||||
* Authors: Xuyang Dong <dongxuyang@eswincomputing.com>
|
||||
*/
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/eswin,eic7700-hspcrg.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define EIC7700_HSP_SATA_REG 0x300
|
||||
#define EIC7700_HSP_MSHC0_REG 0x510
|
||||
#define EIC7700_HSP_MSHC1_REG 0x610
|
||||
#define EIC7700_HSP_MSHC2_REG 0x710
|
||||
#define EIC7700_HSP_USB0_REG 0x800
|
||||
#define EIC7700_HSP_USB0_REF_REG 0x83c
|
||||
#define EIC7700_HSP_USB1_REG 0x900
|
||||
#define EIC7700_HSP_USB1_REF_REG 0x93c
|
||||
|
||||
#define USB_REF_XTAL24M 0x2a
|
||||
#define EIC7700_HSP_NR_CLKS (EIC7700_HSP_CLK_GATE_SATA + 1)
|
||||
|
||||
struct eic7700_hsp_clk_gate {
|
||||
struct clk_hw hw;
|
||||
unsigned int id;
|
||||
struct regmap *regmap;
|
||||
unsigned int reg;
|
||||
unsigned int ref_reg;
|
||||
const char *name;
|
||||
const struct clk_parent_data *parent_data;
|
||||
unsigned long flags;
|
||||
unsigned int offset;
|
||||
unsigned int ref_offset;
|
||||
u8 bit_idx;
|
||||
};
|
||||
|
||||
static const struct regmap_config eic7700_hsp_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x1ffc,
|
||||
.reg_stride = 4,
|
||||
.fast_io = true,
|
||||
.use_raw_spinlock = true,
|
||||
};
|
||||
|
||||
static inline struct eic7700_hsp_clk_gate *to_gate_clk(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct eic7700_hsp_clk_gate, hw);
|
||||
}
|
||||
|
||||
#define EIC7700_HSP_GATE(_id, _name, _pdata, _flags, _offset, _idx, \
|
||||
_ref_offset) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_data = _pdata, \
|
||||
.flags = _flags, \
|
||||
.offset = _offset, \
|
||||
.ref_offset = _ref_offset, \
|
||||
.bit_idx = _idx, \
|
||||
}
|
||||
|
||||
static void hsp_clk_gate_endisable(struct clk_hw *hw, bool enable)
|
||||
{
|
||||
struct eic7700_hsp_clk_gate *gate = to_gate_clk(hw);
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* Hardware bug: The USB reference clock must be 24MHz.
|
||||
* The default register value after reset is invalid.
|
||||
* Workaround: Rewrite the correct value before enabling
|
||||
* the USB gate clock.
|
||||
*/
|
||||
regmap_update_bits(gate->regmap, gate->ref_reg, 0x3f,
|
||||
USB_REF_XTAL24M);
|
||||
}
|
||||
regmap_assign_bits(gate->regmap, gate->reg, BIT(gate->bit_idx), enable);
|
||||
}
|
||||
|
||||
static int hsp_clk_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
hsp_clk_gate_endisable(hw, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hsp_clk_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
hsp_clk_gate_endisable(hw, false);
|
||||
}
|
||||
|
||||
static int hsp_clk_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct eic7700_hsp_clk_gate *gate = to_gate_clk(hw);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(gate->regmap, gate->reg, &val);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
return !!(val & BIT(gate->bit_idx));
|
||||
}
|
||||
|
||||
static const struct clk_ops hsp_clk_gate_ops = {
|
||||
.enable = hsp_clk_gate_enable,
|
||||
.disable = hsp_clk_gate_disable,
|
||||
.is_enabled = hsp_clk_gate_is_enabled,
|
||||
};
|
||||
|
||||
static struct clk_hw *
|
||||
hsp_clk_register_gate(struct device *dev, unsigned int id, const char *name,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags, struct regmap *regmap,
|
||||
unsigned int reg, unsigned int ref_reg, u8 bit_idx)
|
||||
{
|
||||
struct eic7700_hsp_clk_gate *gate;
|
||||
struct clk_init_data init = {};
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.ops = &hsp_clk_gate_ops;
|
||||
init.flags = flags;
|
||||
init.parent_data = parent_data;
|
||||
init.num_parents = 1;
|
||||
|
||||
gate->id = id;
|
||||
gate->regmap = regmap;
|
||||
gate->reg = reg;
|
||||
gate->ref_reg = ref_reg;
|
||||
gate->bit_idx = bit_idx;
|
||||
gate->hw.init = &init;
|
||||
|
||||
hw = &gate->hw;
|
||||
ret = devm_clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
hw = ERR_PTR(ret);
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
static const struct clk_parent_data hsp_cfg[] = {
|
||||
{ .index = 0 }
|
||||
};
|
||||
|
||||
static const struct clk_parent_data hsp_mmc[] = {
|
||||
{ .index = 1 }
|
||||
};
|
||||
|
||||
static const struct clk_parent_data hsp_usb_sata[] = {
|
||||
{ .index = 2 }
|
||||
};
|
||||
|
||||
static struct eswin_fixed_factor_clock eic7700_hsp_factor_clks[] = {
|
||||
ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_CFG_DIV2, "factor_hsp_cfg_div2",
|
||||
hsp_cfg, 1, 2, 0),
|
||||
ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_CFG_DIV4, "factor_hsp_cfg_div4",
|
||||
hsp_cfg, 1, 4, 0),
|
||||
ESWIN_FACTOR(EIC7700_HSP_CLK_FAC_MMC_DIV10, "factor_hsp_mmc_div10",
|
||||
hsp_mmc, 1, 10, 0),
|
||||
};
|
||||
|
||||
static struct eswin_gate_clock eic7700_hsp_gate_clks[] = {
|
||||
ESWIN_GATE(EIC7700_HSP_CLK_GATE_SATA, "gate_clk_hsp_sata", hsp_usb_sata,
|
||||
CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_SATA_REG, 28, 0),
|
||||
ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC0_TMR, "gate_clk_hsp_mshc0_tmr",
|
||||
hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC0_REG, 8, 0),
|
||||
ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC1_TMR, "gate_clk_hsp_mshc1_tmr",
|
||||
hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC1_REG, 8, 0),
|
||||
ESWIN_GATE(EIC7700_HSP_CLK_GATE_MSHC2_TMR, "gate_clk_hsp_mshc2_tmr",
|
||||
hsp_mmc, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC2_REG, 8, 0),
|
||||
};
|
||||
|
||||
static struct eic7700_hsp_clk_gate eic7700_hsp_spec_gate_clks[] = {
|
||||
EIC7700_HSP_GATE(EIC7700_HSP_CLK_GATE_USB0, "gate_clk_hsp_usb0",
|
||||
hsp_usb_sata, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_USB0_REG, 28, EIC7700_HSP_USB0_REF_REG),
|
||||
EIC7700_HSP_GATE(EIC7700_HSP_CLK_GATE_USB1, "gate_clk_hsp_usb1",
|
||||
hsp_usb_sata, CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_USB1_REG, 28, EIC7700_HSP_USB1_REF_REG),
|
||||
};
|
||||
|
||||
static const struct clk_parent_data mux_mmc_3mux1_p[] = {
|
||||
{ .fw_name = "cfg" },
|
||||
{ .hw = &eic7700_hsp_factor_clks[0].hw },
|
||||
{ .hw = &eic7700_hsp_factor_clks[1].hw },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data mux_mmc_2mux1_p[] = {
|
||||
{ .fw_name = "mmc" },
|
||||
{ .hw = &eic7700_hsp_factor_clks[2].hw },
|
||||
};
|
||||
|
||||
static u32 mux_mmc_3mux1_tbl[] = { 0x0, 0x1, 0x3 };
|
||||
|
||||
static struct eswin_mux_clock eic7700_hsp_mux_clks[] = {
|
||||
ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_EMMC_3MUX1, "mux_hsp_emmc_3mux1",
|
||||
mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC0_REG, 16, 2, 0,
|
||||
mux_mmc_3mux1_tbl),
|
||||
ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_SD0_3MUX1, "mux_hsp_sd0_3mux1",
|
||||
mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC1_REG, 16, 2, 0,
|
||||
mux_mmc_3mux1_tbl),
|
||||
ESWIN_MUX_TBL(EIC7700_HSP_CLK_MUX_SD1_3MUX1, "mux_hsp_sd1_3mux1",
|
||||
mux_mmc_3mux1_p, ARRAY_SIZE(mux_mmc_3mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC2_REG, 16, 2, 0,
|
||||
mux_mmc_3mux1_tbl),
|
||||
ESWIN_MUX(EIC7700_HSP_CLK_MUX_EMMC_CQE_2MUX1, "mux_hsp_emmc_cqe_2mux1",
|
||||
mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC0_REG, 0, 1, 0),
|
||||
ESWIN_MUX(EIC7700_HSP_CLK_MUX_SD0_CQE_2MUX1, "mux_hsp_sd0_cqe_2mux1",
|
||||
mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC1_REG, 0, 1, 0),
|
||||
ESWIN_MUX(EIC7700_HSP_CLK_MUX_SD1_CQE_2MUX1, "mux_hsp_sd1_cqe_2mux1",
|
||||
mux_mmc_2mux1_p, ARRAY_SIZE(mux_mmc_2mux1_p),
|
||||
CLK_SET_RATE_PARENT, EIC7700_HSP_MSHC2_REG, 0, 1, 0),
|
||||
};
|
||||
|
||||
static struct eswin_clk_info eic7700_hsp_clks[] = {
|
||||
ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_EMMC, "gate_clk_hsp_emmc",
|
||||
EIC7700_HSP_CLK_MUX_EMMC_3MUX1,
|
||||
CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC0_REG, 24, 0),
|
||||
ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_SD0, "gate_clk_hsp_sd0",
|
||||
EIC7700_HSP_CLK_MUX_SD0_3MUX1,
|
||||
CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC1_REG, 24, 0),
|
||||
ESWIN_GATE_TYPE(EIC7700_HSP_CLK_GATE_SD1, "gate_clk_hsp_sd1",
|
||||
EIC7700_HSP_CLK_MUX_SD1_3MUX1,
|
||||
CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_HSP_MSHC2_REG, 24, 0),
|
||||
};
|
||||
|
||||
static int eic7700_hsp_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct auxiliary_device *adev;
|
||||
struct eswin_clock_data *data;
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i, ret;
|
||||
|
||||
data = eswin_clk_init(pdev, EIC7700_HSP_NR_CLKS);
|
||||
if (IS_ERR(data))
|
||||
return dev_err_probe(dev, PTR_ERR(data),
|
||||
"failed to get clk data!\n");
|
||||
|
||||
regmap = devm_regmap_init_mmio(dev, data->base,
|
||||
&eic7700_hsp_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"failed to get regmap!\n");
|
||||
|
||||
ret = eswin_clk_register_fixed_factor(dev, eic7700_hsp_factor_clks,
|
||||
ARRAY_SIZE(eic7700_hsp_factor_clks),
|
||||
data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to register fixed factor clock\n");
|
||||
|
||||
ret = eswin_clk_register_gate(dev, eic7700_hsp_gate_clks,
|
||||
ARRAY_SIZE(eic7700_hsp_gate_clks), data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to register gate clock\n");
|
||||
|
||||
ret = eswin_clk_register_mux(dev, eic7700_hsp_mux_clks,
|
||||
ARRAY_SIZE(eic7700_hsp_mux_clks),
|
||||
data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to register mux clock\n");
|
||||
|
||||
ret = eswin_clk_register_clks(dev, eic7700_hsp_clks,
|
||||
ARRAY_SIZE(eic7700_hsp_clks), data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to register clock\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eic7700_hsp_spec_gate_clks); i++) {
|
||||
struct eic7700_hsp_clk_gate *gate;
|
||||
|
||||
gate = &eic7700_hsp_spec_gate_clks[i];
|
||||
hw = hsp_clk_register_gate(dev, gate->id, gate->name,
|
||||
gate->parent_data, gate->flags,
|
||||
regmap, gate->offset,
|
||||
gate->ref_offset, gate->bit_idx);
|
||||
if (IS_ERR(hw))
|
||||
return dev_err_probe(dev, PTR_ERR(hw),
|
||||
"failed to register gate clock\n");
|
||||
|
||||
data->clk_data.hws[gate->id] = hw;
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
|
||||
&data->clk_data);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "add clk provider failed\n");
|
||||
|
||||
adev = devm_auxiliary_device_create(dev, "hsp-reset", NULL);
|
||||
if (!adev)
|
||||
return dev_err_probe(dev, -ENODEV,
|
||||
"register hsp-reset device failed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id eic7700_hsp_clock_dt_ids[] = {
|
||||
{ .compatible = "eswin,eic7700-hspcrg", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, eic7700_hsp_clock_dt_ids);
|
||||
|
||||
static struct platform_driver eic7700_hsp_clock_driver = {
|
||||
.probe = eic7700_hsp_clk_probe,
|
||||
.driver = {
|
||||
.name = "eic7700-hsp-clock",
|
||||
.of_match_table = eic7700_hsp_clock_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(eic7700_hsp_clock_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Xuyang Dong <dongxuyang@eswincomputing.com>");
|
||||
MODULE_DESCRIPTION("ESWIN EIC7700 HSP clock controller driver");
|
||||
@@ -791,7 +791,8 @@ static struct eswin_clk_info eic7700_clks[] = {
|
||||
EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
|
||||
CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 27, 0),
|
||||
ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NOC_NSP_CLK, "gate_noc_nsp_clk",
|
||||
EIC7700_CLK_DIV_NOC_NSP_DYNM, CLK_SET_RATE_PARENT,
|
||||
EIC7700_CLK_DIV_NOC_NSP_DYNM,
|
||||
CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
|
||||
EIC7700_REG_OFFSET_NOC, 31, 0),
|
||||
ESWIN_GATE_TYPE(EIC7700_CLK_GATE_BOOTSPI, "gate_clk_bootspi",
|
||||
EIC7700_CLK_MUX_BOOTSPI_CLK_2MUX1_GFREE,
|
||||
|
||||
@@ -204,7 +204,7 @@ int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
|
||||
int nums, struct eswin_clock_data *data)
|
||||
{
|
||||
struct eswin_clk_pll *p_clk = NULL;
|
||||
struct clk_init_data init;
|
||||
struct clk_init_data init = {};
|
||||
struct clk_hw *clk_hw;
|
||||
int i, ret;
|
||||
|
||||
@@ -419,7 +419,7 @@ struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
|
||||
unsigned long priv_flag, spinlock_t *lock)
|
||||
{
|
||||
struct eswin_divider_clock *dclk;
|
||||
struct clk_init_data init;
|
||||
struct clk_init_data init = {};
|
||||
struct clk_hw *clk_hw;
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config COMMON_CLK_HISI
|
||||
bool
|
||||
default ARCH_HISI
|
||||
|
||||
config COMMON_CLK_HI3516CV300
|
||||
tristate "HI3516CV300 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select RESET_HISI
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3516cv300.
|
||||
@@ -11,6 +16,7 @@ config COMMON_CLK_HI3519
|
||||
tristate "Hi3519 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select RESET_HISI
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3519.
|
||||
@@ -19,6 +25,7 @@ config COMMON_CLK_HI3559A
|
||||
bool "Hi3559A Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select RESET_HISI
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3559a.
|
||||
@@ -26,6 +33,7 @@ config COMMON_CLK_HI3559A
|
||||
config COMMON_CLK_HI3660
|
||||
bool "Hi3660 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3660.
|
||||
@@ -33,6 +41,7 @@ config COMMON_CLK_HI3660
|
||||
config COMMON_CLK_HI3670
|
||||
bool "Hi3670 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3670.
|
||||
@@ -41,6 +50,7 @@ config COMMON_CLK_HI3798CV200
|
||||
tristate "Hi3798CV200 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select RESET_HISI
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the clock driver for hi3798cv200.
|
||||
@@ -48,6 +58,7 @@ config COMMON_CLK_HI3798CV200
|
||||
config COMMON_CLK_HI6220
|
||||
bool "Hi6220 Clock Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select COMMON_CLK_HISI
|
||||
default ARCH_HISI
|
||||
help
|
||||
Build the Hisilicon Hi6220 clock driver based on the common clock framework.
|
||||
@@ -55,6 +66,7 @@ config COMMON_CLK_HI6220
|
||||
config RESET_HISI
|
||||
bool "HiSilicon Reset Controller Driver"
|
||||
depends on ARCH_HISI || COMPILE_TEST
|
||||
select COMMON_CLK_HISI
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
Build reset controller driver for HiSilicon device chipsets.
|
||||
@@ -63,6 +75,7 @@ config STUB_CLK_HI6220
|
||||
bool "Hi6220 Stub Clock Driver" if EXPERT
|
||||
depends on (COMMON_CLK_HI6220 || COMPILE_TEST)
|
||||
depends on MAILBOX
|
||||
select COMMON_CLK_HISI
|
||||
default COMMON_CLK_HI6220
|
||||
help
|
||||
Build the Hisilicon Hi6220 stub clock driver.
|
||||
@@ -71,6 +84,7 @@ config STUB_CLK_HI3660
|
||||
bool "Hi3660 Stub Clock Driver" if EXPERT
|
||||
depends on (COMMON_CLK_HI3660 || COMPILE_TEST)
|
||||
depends on MAILBOX
|
||||
select COMMON_CLK_HISI
|
||||
default COMMON_CLK_HI3660
|
||||
help
|
||||
Build the Hisilicon Hi3660 stub clock driver.
|
||||
|
||||
@@ -67,16 +67,6 @@ static unsigned long hi3660_stub_clk_recalc_rate(struct clk_hw *hw,
|
||||
return stub_clk->rate;
|
||||
}
|
||||
|
||||
static int hi3660_stub_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
/*
|
||||
* LPM3 handles rate rounding so just return whatever
|
||||
* rate is requested.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@@ -97,7 +87,7 @@ static int hi3660_stub_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
static const struct clk_ops hi3660_stub_clk_ops = {
|
||||
.recalc_rate = hi3660_stub_clk_recalc_rate,
|
||||
.determine_rate = hi3660_stub_clk_determine_rate,
|
||||
.determine_rate = clk_determine_rate_noop,
|
||||
.set_rate = hi3660_stub_clk_set_rate,
|
||||
};
|
||||
|
||||
@@ -124,7 +114,6 @@ static struct clk_hw *hi3660_stub_clk_hw_get(struct of_phandle_args *clkspec,
|
||||
static int hi3660_stub_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
@@ -139,12 +128,9 @@ static int hi3660_stub_clk_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(stub_clk_chan.mbox))
|
||||
return PTR_ERR(stub_clk_chan.mbox);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
freq_reg = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (!freq_reg)
|
||||
return -ENOMEM;
|
||||
freq_reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(freq_reg))
|
||||
return PTR_ERR(freq_reg);
|
||||
|
||||
freq_reg += HI3660_STUB_CLOCK_DATA;
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
|
||||
{
|
||||
struct hisi_reset_controller *rstc;
|
||||
|
||||
rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL);
|
||||
rstc = devm_kzalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL);
|
||||
if (!rstc)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct clk_hw *audio_pll_hws[2];
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
@@ -610,6 +611,11 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
|
||||
imx_register_uart_clocks();
|
||||
|
||||
/* Add debug interface for audio PLLs */
|
||||
audio_pll_hws[0] = hws[IMX8MM_AUDIO_PLL1];
|
||||
audio_pll_hws[1] = hws[IMX8MM_AUDIO_PLL2];
|
||||
imx_audio_pll_debug_init(audio_pll_hws, ARRAY_SIZE(audio_pll_hws));
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_hws:
|
||||
|
||||
@@ -354,6 +354,7 @@ static const struct of_device_id imx8qxp_lpcg_match[] = {
|
||||
{ .compatible = "fsl,imx8qxp-lpcg", NULL },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx8qxp_lpcg_match);
|
||||
|
||||
static struct platform_driver imx8qxp_lpcg_clk_driver = {
|
||||
.driver = {
|
||||
|
||||
@@ -337,6 +337,7 @@ static const struct of_device_id imx8qxp_match[] = {
|
||||
{ .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx8qxp_match);
|
||||
|
||||
static struct platform_driver imx8qxp_clk_driver = {
|
||||
.driver = {
|
||||
|
||||
@@ -44,6 +44,8 @@ struct imx95_blk_ctl_clk_dev_data {
|
||||
const char * const *parent_names;
|
||||
u32 num_parents;
|
||||
u32 reg;
|
||||
u32 reg_init_msk;
|
||||
u32 reg_init_val;
|
||||
u32 bit_idx;
|
||||
u32 bit_width;
|
||||
u32 clk_type;
|
||||
@@ -286,10 +288,22 @@ static const struct imx95_blk_ctl_dev_data netcmix_dev_data = {
|
||||
static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = {
|
||||
[0] = {
|
||||
.name = "hsio_blk_ctl_clk",
|
||||
.parent_names = (const char *[]){ "func_out_en", },
|
||||
.num_parents = 1,
|
||||
.reg = 0,
|
||||
.reg_init_msk = GENMASK(10, 7),
|
||||
.reg_init_val = GENMASK(10, 7),
|
||||
.bit_idx = 6,
|
||||
.bit_width = 1,
|
||||
.type = CLK_GATE,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
[1] = {
|
||||
.name = "func_out_en",
|
||||
.parent_names = (const char *[]){ "hsio_pll", },
|
||||
.num_parents = 1,
|
||||
.reg = 0,
|
||||
.bit_idx = 6,
|
||||
.bit_idx = 2,
|
||||
.bit_width = 1,
|
||||
.type = CLK_GATE,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@@ -297,7 +311,7 @@ static const struct imx95_blk_ctl_clk_dev_data hsio_blk_ctl_clk_dev_data[] = {
|
||||
};
|
||||
|
||||
static const struct imx95_blk_ctl_dev_data hsio_blk_ctl_dev_data = {
|
||||
.num_clks = 1,
|
||||
.num_clks = ARRAY_SIZE(hsio_blk_ctl_clk_dev_data),
|
||||
.clk_dev_data = hsio_blk_ctl_clk_dev_data,
|
||||
.clk_reg_offset = 0,
|
||||
};
|
||||
@@ -400,6 +414,9 @@ static int imx95_bc_probe(struct platform_device *pdev)
|
||||
const struct imx95_blk_ctl_clk_dev_data *data = &bc->pdata->clk_dev_data[i];
|
||||
void __iomem *reg = base + data->reg;
|
||||
|
||||
if (data->reg_init_msk)
|
||||
writel((readl(reg) & ~data->reg_init_msk) | data->reg_init_val, reg);
|
||||
|
||||
if (data->type == CLK_MUX) {
|
||||
hws[i] = clk_hw_register_mux(dev, data->name, data->parent_names,
|
||||
data->num_parents, data->flags, reg,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user