mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
A pretty quiet cycle this time around. We have a bunch of new Qualcomm clk
drivers, per usual, and then a handful of drivers for other SoCs. Then the usual pile of cleanups is fairly small data fixes or converting DT bindings to YAML so they can be validated. No changes to the core framework besides an OF node refcount bump that never got decremented. New Drivers: - 5L35023 variant of Versa 3 clock generator - Various Qualcomm clk controllers: IPQ CMN PLL, SM6115 LPASS, SM750 global, tcsr, rpmh, and display. X Plus GPU and global. QCS615 rpmh and MSM8937 and MSM8940 RPM. - Qualcomm Pongo and Taycan Alpha PLLs - Qualcomm IPQ5424 NoC-related interconnect clks - Renesas RZ/G3E (R9A09G047) SoC clk driver - SAMA7D65 SoC clk driver - Samsung Exynos990 SoC clk driver -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmeQNfYRHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSUuwRAAkKea3uRcSkTgHK3Ts0gmf8L2QS+dL47N OFmqhhdF0gYU60kzsaU0A6UGvaagq/rkB8nvZJ6G8/wV6T0jXHmxuCmZ7uRaErpt 4KDjpS9qQ8sl5LXpuxh9LgfxcOOfAueWRpmF/5alHEtAQLXKHKV5CdcyYa71pj40 +LfjoaW6xaqx+G3lqJhakY77zKiRzxWH86XQS5CHD3DITkv3B5/dV/nQlAb3P083 7SzHXKbBpWpXH0y0pLTXZDTVCsHl90t1DO7JKt9Y1fOxtpLB/ROfLPOJ4cZyCQGH Y28ZWDA9jEEX/cz/R2qPY3mRUPrFp2ArsXsx1rKlPTabp4NZLs3d9tZiMI/irK/W GTkRKMUZlDD5w6jSYgmSTbTj2CsTsPXc8EzsNIFudl6WyzyxWHvnpUb+hdrR2B+0 untNOkwcb8GzgucYrbK5s/Aw03CiyGTYZHGJxsnIr7uSYRxe8mlV/cIbDcn5+WWj rrOcPatLEnCeE1Eldm6cOzFsLMbBVP9HeNkms91y2AJDx4mWn8qyY0psX+HaNyBm 1YZBVmo2PiZ84ZEhiK7WhPPMaDyR2ZSQS0/U5FaB56G9+rtuVYs8Z7KFS3nK27Rh oKWcdKDn1wUmtUhVggC+m4PueOH3dlM0ELaRNKzePx9rEimjWhzfy5GlOvPoaBAl MKOVgeLYa4c= =wK9g -----END PGP SIGNATURE----- Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "A pretty quiet cycle this time around. We have a bunch of new Qualcomm clk drivers, per usual, and then a handful of drivers for other SoCs. Then the usual pile of cleanups is fairly small data fixes or converting DT bindings to YAML so they can be validated. No changes to the core framework besides an OF node refcount bump that never got decremented. New Drivers: - 5L35023 variant of Versa 3 clock generator - Various Qualcomm clk controllers: IPQ CMN PLL, SM6115 LPASS, SM750 global, tcsr, rpmh, and display. X Plus GPU and global. QCS615 rpmh and MSM8937 and MSM8940 RPM. - Qualcomm Pongo and Taycan Alpha PLLs - Qualcomm IPQ5424 NoC-related interconnect clks - Renesas RZ/G3E (R9A09G047) SoC clk driver - SAMA7D65 SoC clk driver - Samsung Exynos990 SoC clk driver" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (159 commits) clk: analogbits: Fix incorrect calculation of vco rate delta clk: bcm: rpi: Add disp clock clk: bcm: rpi: Create helper to retrieve private data clk: bcm: rpi: Enable minimize for all firmware clocks clk: bcm: rpi: Allow cpufreq driver to also adjust gpu clocks clk: bcm: rpi: Add ISP to exported clocks clk: stm32f4: support spread spectrum clock generation clk: stm32f4: use FIELD helpers to access the PLLCFGR fields dt-bindings: clock: st,stm32-rcc: support spread spectrum clocking dt-bindings: clock: convert stm32 rcc bindings to json-schema clk: Use str_enable_disable-like helpers clk: clk-loongson2: Fix the number count of clk provider clk: clk-loongson2: Switch to use devm_clk_hw_register_fixed_rate_parent_data() clk: starfive: Make _clk_get become a common helper function clk: en7523: Add clock for eMMC for EN7581 dt-bindings: clock: add ID for eMMC for EN7581 dt-bindings: clock: drop NUM_CLOCKS define for EN7581 clk: en7523: Rework clock handling for different clock numbers clk: thead: Fix cpu2vp_clk for TH1520 AP_SUBSYS clocks clk: thead: Add CLK_IGNORE_UNUSED to fix TH1520 boot ...
This commit is contained in:
commit
641b0c64b8
|
@ -43,6 +43,7 @@ properties:
|
|||
- atmel,sama5d4-pmc
|
||||
- microchip,sam9x60-pmc
|
||||
- microchip,sam9x7-pmc
|
||||
- microchip,sama7d65-pmc
|
||||
- microchip,sama7g5-pmc
|
||||
- const: syscon
|
||||
|
||||
|
@ -90,6 +91,7 @@ allOf:
|
|||
enum:
|
||||
- microchip,sam9x60-pmc
|
||||
- microchip,sam9x7-pmc
|
||||
- microchip,sama7d65-pmc
|
||||
- microchip,sama7g5-pmc
|
||||
then:
|
||||
properties:
|
||||
|
|
|
@ -20,6 +20,7 @@ properties:
|
|||
- items:
|
||||
- enum:
|
||||
- microchip,sam9x7-sckc
|
||||
- microchip,sama7d65-sckc
|
||||
- microchip,sama7g5-sckc
|
||||
- const: microchip,sam9x60-sckc
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,ipq9574-cmn-pll.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm CMN PLL Clock Controller on IPQ SoC
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <andersson@kernel.org>
|
||||
- Luo Jie <quic_luoj@quicinc.com>
|
||||
|
||||
description:
|
||||
The CMN (or common) PLL clock controller expects a reference
|
||||
input clock. This reference clock is from the on-board Wi-Fi.
|
||||
The CMN PLL supplies a number of fixed rate output clocks to
|
||||
the devices providing networking functions and to GCC. These
|
||||
networking hardware include PPE (packet process engine), PCS
|
||||
and the externally connected switch or PHY devices. The CMN
|
||||
PLL block also outputs fixed rate clocks to GCC. The PLL's
|
||||
primary function is to enable fixed rate output clocks for
|
||||
networking hardware functions used with the IPQ SoC.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,ipq9574-cmn-pll
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: The reference clock. The supported clock rates include
|
||||
25000000, 31250000, 40000000, 48000000, 50000000 and 96000000 HZ.
|
||||
- description: The AHB clock
|
||||
- description: The SYS clock
|
||||
description:
|
||||
The reference clock is the source clock of CMN PLL, which is from the
|
||||
Wi-Fi. The AHB and SYS clocks must be enabled to access CMN PLL
|
||||
clock registers.
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
- const: ahb
|
||||
- const: sys
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
||||
#include <dt-bindings/clock/qcom,ipq9574-gcc.h>
|
||||
|
||||
cmn_pll: clock-controller@9b000 {
|
||||
compatible = "qcom,ipq9574-cmn-pll";
|
||||
reg = <0x0009b000 0x800>;
|
||||
clocks = <&cmn_pll_ref_clk>,
|
||||
<&gcc GCC_CMN_12GPLL_AHB_CLK>,
|
||||
<&gcc GCC_CMN_12GPLL_SYS_CLK>;
|
||||
clock-names = "ref", "ahb", "sys";
|
||||
#clock-cells = <1>;
|
||||
assigned-clocks = <&cmn_pll CMN_PLL_CLK>;
|
||||
assigned-clock-rates-u64 = /bits/ 64 <12000000000>;
|
||||
};
|
||||
...
|
|
@ -78,6 +78,7 @@ allOf:
|
|||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 8
|
||||
items:
|
||||
- description: Board PXO source
|
||||
- description: PLL 3 clock
|
||||
|
@ -87,8 +88,10 @@ allOf:
|
|||
- description: DSI phy instance 2 dsi clock
|
||||
- description: DSI phy instance 2 byte clock
|
||||
- description: HDMI phy PLL clock
|
||||
- description: LVDS PLL clock
|
||||
|
||||
clock-names:
|
||||
minItems: 8
|
||||
items:
|
||||
- const: pxo
|
||||
- const: pll3
|
||||
|
@ -98,6 +101,7 @@ allOf:
|
|||
- const: dsi2pll
|
||||
- const: dsi2pllbyte
|
||||
- const: hdmipll
|
||||
- const: lvdspll
|
||||
|
||||
- if:
|
||||
properties:
|
||||
|
|
59
Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml
Normal file
59
Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml
Normal file
|
@ -0,0 +1,59 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,qcs615-gcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller on QCS615
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <quic_tdas@quicinc.com>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module provides the clocks, resets and power
|
||||
domains on QCS615.
|
||||
|
||||
See also: include/dt-bindings/clock/qcom,qcs615-gcc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,qcs615-gcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
- const: sleep_clk
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#power-domain-cells'
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,gcc.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,qcs615-gcc";
|
||||
reg = <0x00100000 0x1f0000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK_A>,
|
||||
<&sleep_clk>;
|
||||
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -33,6 +33,8 @@ properties:
|
|||
- qcom,rpmcc-msm8916
|
||||
- qcom,rpmcc-msm8917
|
||||
- qcom,rpmcc-msm8936
|
||||
- qcom,rpmcc-msm8937
|
||||
- qcom,rpmcc-msm8940
|
||||
- qcom,rpmcc-msm8953
|
||||
- qcom,rpmcc-msm8974
|
||||
- qcom,rpmcc-msm8976
|
||||
|
@ -110,6 +112,8 @@ allOf:
|
|||
- qcom,rpmcc-msm8916
|
||||
- qcom,rpmcc-msm8917
|
||||
- qcom,rpmcc-msm8936
|
||||
- qcom,rpmcc-msm8937
|
||||
- qcom,rpmcc-msm8940
|
||||
- qcom,rpmcc-msm8953
|
||||
- qcom,rpmcc-msm8974
|
||||
- qcom,rpmcc-msm8976
|
||||
|
|
|
@ -17,6 +17,7 @@ description: |
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qcs615-rpmh-clk
|
||||
- qcom,qdu1000-rpmh-clk
|
||||
- qcom,sa8775p-rpmh-clk
|
||||
- qcom,sar2130p-rpmh-clk
|
||||
|
@ -37,6 +38,7 @@ properties:
|
|||
- qcom,sm8450-rpmh-clk
|
||||
- qcom,sm8550-rpmh-clk
|
||||
- qcom,sm8650-rpmh-clk
|
||||
- qcom,sm8750-rpmh-clk
|
||||
- qcom,x1e80100-rpmh-clk
|
||||
|
||||
clocks:
|
||||
|
|
|
@ -18,12 +18,6 @@ description: |
|
|||
include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
|
||||
|
||||
properties:
|
||||
clocks: true
|
||||
|
||||
clock-names: true
|
||||
|
||||
reg: true
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7280-lpassaoncc
|
||||
|
@ -31,12 +25,24 @@ properties:
|
|||
- qcom,sc7280-lpasscorecc
|
||||
- qcom,sc7280-lpasshm
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
reg:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
|
@ -57,8 +63,6 @@ required:
|
|||
- '#clock-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
|
@ -125,6 +129,9 @@ allOf:
|
|||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
|
|
|
@ -20,7 +20,11 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sdm845-camcc
|
||||
oneOf:
|
||||
- items:
|
||||
- const: qcom,sdm670-camcc
|
||||
- const: qcom,sdm845-camcc
|
||||
- const: qcom,sdm845-camcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,sm6115-lpasscc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm LPASS Core & Audio Clock Controller on SM6115
|
||||
|
||||
maintainers:
|
||||
- Konrad Dybcio <konradybcio@kernel.org>
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm LPASS core and audio clock controllers provide audio-related resets
|
||||
on SM6115 and its derivatives.
|
||||
|
||||
See also::
|
||||
include/dt-bindings/clock/qcom,sm6115-lpasscc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm6115-lpassaudiocc
|
||||
- qcom,sm6115-lpasscc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#reset-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
lpass_audiocc: clock-controller@a6a9000 {
|
||||
compatible = "qcom,sm6115-lpassaudiocc";
|
||||
reg = <0x0a6a9000 0x1000>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -19,7 +19,6 @@ description: |
|
|||
include/dt-bindings/clock/qcom,sm8450-camcc.h
|
||||
include/dt-bindings/clock/qcom,sm8550-camcc.h
|
||||
include/dt-bindings/clock/qcom,sm8650-camcc.h
|
||||
include/dt-bindings/clock/qcom,x1e80100-camcc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -29,7 +28,6 @@ properties:
|
|||
- qcom,sm8475-camcc
|
||||
- qcom,sm8550-camcc
|
||||
- qcom,sm8650-camcc
|
||||
- qcom,x1e80100-camcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
@ -32,6 +32,7 @@ properties:
|
|||
- qcom,sm8550-gpucc
|
||||
- qcom,sm8650-gpucc
|
||||
- qcom,x1e80100-gpucc
|
||||
- qcom,x1p42100-gpucc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
@ -12,11 +12,12 @@ maintainers:
|
|||
|
||||
description: |
|
||||
Qualcomm display clock control module provides the clocks, resets and power
|
||||
domains on SM8550.
|
||||
domains on SM8550, SM8650, SM8750 and few other platforms.
|
||||
|
||||
See also:
|
||||
- include/dt-bindings/clock/qcom,sm8550-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8650-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,sm8750-dispcc.h
|
||||
- include/dt-bindings/clock/qcom,x1e80100-dispcc.h
|
||||
|
||||
properties:
|
||||
|
@ -25,6 +26,7 @@ properties:
|
|||
- qcom,sar2130p-dispcc
|
||||
- qcom,sm8550-dispcc
|
||||
- qcom,sm8650-dispcc
|
||||
- qcom,sm8750-dispcc
|
||||
- qcom,x1e80100-dispcc
|
||||
|
||||
clocks:
|
||||
|
|
|
@ -16,6 +16,7 @@ description: |
|
|||
See also:
|
||||
- include/dt-bindings/clock/qcom,sm8550-tcsr.h
|
||||
- include/dt-bindings/clock/qcom,sm8650-tcsr.h
|
||||
- include/dt-bindings/clock/qcom,sm8750-tcsr.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -24,6 +25,7 @@ properties:
|
|||
- qcom,sar2130p-tcsr
|
||||
- qcom,sm8550-tcsr
|
||||
- qcom,sm8650-tcsr
|
||||
- qcom,sm8750-tcsr
|
||||
- qcom,x1e80100-tcsr
|
||||
- const: syscon
|
||||
|
||||
|
|
62
Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml
Normal file
62
Documentation/devicetree/bindings/clock/qcom,sm8750-gcc.yaml
Normal file
|
@ -0,0 +1,62 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,sm8750-gcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller on SM8750
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <quic_tdas@quicinc.com>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module provides the clocks, resets and power
|
||||
domains on SM8750
|
||||
|
||||
See also: include/dt-bindings/clock/qcom,sm8750-gcc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8750-gcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board Always On XO source
|
||||
- description: Sleep clock source
|
||||
- description: PCIE 0 Pipe clock source
|
||||
- description: UFS Phy Rx symbol 0 clock source
|
||||
- description: UFS Phy Rx symbol 1 clock source
|
||||
- description: UFS Phy Tx symbol 0 clock source
|
||||
- description: USB3 Phy wrapper pipe clock source
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- '#power-domain-cells'
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,gcc.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,sm8750-gcc";
|
||||
reg = <0x00100000 0x001f4200>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK_A>,
|
||||
<&sleep_clk>,
|
||||
<&pcie0_phy>,
|
||||
<&ufs_mem_phy 0>,
|
||||
<&ufs_mem_phy 1>,
|
||||
<&ufs_mem_phy 2>,
|
||||
<&usb_1_qmpphy>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,74 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,x1e80100-camcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Camera Clock & Reset Controller on x1e80100
|
||||
|
||||
maintainers:
|
||||
- Bryan O'Donoghue <bryan.odonoghue@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm camera clock control module provides the clocks, resets and power
|
||||
domains on x1e80100.
|
||||
|
||||
See also:
|
||||
include/dt-bindings/clock/qcom,x1e80100-camcc.h
|
||||
|
||||
allOf:
|
||||
- $ref: qcom,gcc.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,x1e80100-camcc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Camera AHB clock from GCC
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
|
||||
power-domains:
|
||||
items:
|
||||
- description: A phandle to the MXC power-domain
|
||||
- description: A phandle to the MMCX power-domain
|
||||
|
||||
required-opps:
|
||||
maxItems: 1
|
||||
description:
|
||||
A phandle to an OPP node describing MMCX performance points.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- power-domains
|
||||
- required-opps
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,x1e80100-gcc.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/power/qcom,rpmhpd.h>
|
||||
clock-controller@ade0000 {
|
||||
compatible = "qcom,x1e80100-camcc";
|
||||
reg = <0xade0000 0x20000>;
|
||||
clocks = <&gcc GCC_CAMERA_AHB_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK_A>,
|
||||
<&sleep_clk>;
|
||||
power-domains = <&rpmhpd RPMHPD_MXC>,
|
||||
<&rpmhpd RPMHPD_MMCX>;
|
||||
required-opps = <&rpmhpd_opp_low_svs>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -17,7 +17,11 @@ description: |
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,x1e80100-gcc
|
||||
oneOf:
|
||||
- items:
|
||||
- const: qcom,x1p42100-gcc
|
||||
- const: qcom,x1e80100-gcc
|
||||
- const: qcom,x1e80100-gcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
@ -31,6 +31,7 @@ description: |
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- renesas,5l35023
|
||||
- renesas,5p35023
|
||||
|
||||
reg:
|
||||
|
|
|
@ -4,19 +4,22 @@
|
|||
$id: http://devicetree.org/schemas/clock/renesas,rzv2h-cpg.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/V2H(P) Clock Pulse Generator (CPG)
|
||||
title: Renesas RZ/{G3E,V2H(P)} Clock Pulse Generator (CPG)
|
||||
|
||||
maintainers:
|
||||
- Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
|
||||
|
||||
description:
|
||||
On Renesas RZ/V2H(P) SoCs, the CPG (Clock Pulse Generator) handles generation
|
||||
and control of clock signals for the IP modules, generation and control of resets,
|
||||
and control over booting, low power consumption and power supply domains.
|
||||
On Renesas RZ/{G3E,V2H(P)} SoCs, the CPG (Clock Pulse Generator) handles
|
||||
generation and control of clock signals for the IP modules, generation and
|
||||
control of resets, and control over booting, low power consumption and power
|
||||
supply domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: renesas,r9a09g057-cpg
|
||||
enum:
|
||||
- renesas,r9a09g047-cpg # RZ/G3E
|
||||
- renesas,r9a09g057-cpg # RZ/V2H
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
@ -37,7 +40,7 @@ properties:
|
|||
description: |
|
||||
- For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
|
||||
and a core clock reference, as defined in
|
||||
<dt-bindings/clock/renesas,r9a09g057-cpg.h>,
|
||||
<dt-bindings/clock/renesas,r9a09g0*-cpg.h>,
|
||||
- For module clocks, the two clock specifier cells must be "CPG_MOD" and
|
||||
a module number. The module number is calculated as the CLKON register
|
||||
offset index multiplied by 16, plus the actual bit in the register
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/samsung,exynos990-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung Exynos990 SoC clock controller
|
||||
|
||||
maintainers:
|
||||
- Igor Belwon <igor.belwon@mentallysanemainliners.org>
|
||||
- Chanwoo Choi <cw00.choi@samsung.com>
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
|
||||
description: |
|
||||
Exynos990 clock controller is comprised of several CMU units, generating
|
||||
clocks for different domains. Those CMU units are modeled as separate device
|
||||
tree nodes, and might depend on each other. The root clock in that root tree
|
||||
is an external clock: OSCCLK (26 MHz). This external clock must be defined
|
||||
as a fixed-rate clock in dts.
|
||||
|
||||
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
|
||||
dividers; all other clocks of function blocks (other CMUs) are usually
|
||||
derived from CMU_TOP.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All clocks available for usage
|
||||
in clock consumer nodes are defined as preprocessor macros in
|
||||
'include/dt-bindings/clock/samsung,exynos990.h' header.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,exynos990-cmu-hsi0
|
||||
- samsung,exynos990-cmu-top
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- "#clock-cells"
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos990-cmu-hsi0
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: CMU_HSI0 BUS clock (from CMU_TOP)
|
||||
- description: CMU_HSI0 USB31DRD clock (from CMU_TOP)
|
||||
- description: CMU_HSI0 USBDP_DEBUG clock (from CMU_TOP)
|
||||
- description: CMU_HSI0 DPGTC clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: bus
|
||||
- const: usb31drd
|
||||
- const: usbdp_debug
|
||||
- const: dpgtc
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos990-cmu-top
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/samsung,exynos990.h>
|
||||
|
||||
cmu_hsi0: clock-controller@10a00000 {
|
||||
compatible = "samsung,exynos990-cmu-hsi0";
|
||||
reg = <0x10a00000 0x8000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&oscclk>,
|
||||
<&cmu_top CLK_DOUT_CMU_HSI0_BUS>,
|
||||
<&cmu_top CLK_DOUT_CMU_HSI0_USB31DRD>,
|
||||
<&cmu_top CLK_DOUT_CMU_HSI0_USBDP_DEBUG>,
|
||||
<&cmu_top CLK_DOUT_CMU_HSI0_DPGTC>;
|
||||
clock-names = "oscclk",
|
||||
"bus",
|
||||
"usb31drd",
|
||||
"usbdp_debug",
|
||||
"dpgtc";
|
||||
};
|
||||
|
||||
...
|
|
@ -1,138 +0,0 @@
|
|||
STMicroelectronics STM32 Reset and Clock Controller
|
||||
===================================================
|
||||
|
||||
The RCC IP is both a reset and a clock controller.
|
||||
|
||||
Please refer to clock-bindings.txt for common clock controller binding usage.
|
||||
Please also refer to reset.txt for common reset controller binding usage.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be:
|
||||
"st,stm32f42xx-rcc"
|
||||
"st,stm32f469-rcc"
|
||||
"st,stm32f746-rcc"
|
||||
"st,stm32f769-rcc"
|
||||
|
||||
- reg: should be register base and length as documented in the
|
||||
datasheet
|
||||
- #reset-cells: 1, see below
|
||||
- #clock-cells: 2, device nodes should specify the clock in their "clocks"
|
||||
property, containing a phandle to the clock device node, an index selecting
|
||||
between gated clocks and other clocks and an index specifying the clock to
|
||||
use.
|
||||
- clocks: External oscillator clock phandle
|
||||
- high speed external clock signal (HSE)
|
||||
- external I2S clock (I2S_CKIN)
|
||||
|
||||
Example:
|
||||
|
||||
rcc: rcc@40023800 {
|
||||
#reset-cells = <1>;
|
||||
#clock-cells = <2>
|
||||
compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
|
||||
reg = <0x40023800 0x400>;
|
||||
clocks = <&clk_hse>, <&clk_i2s_ckin>;
|
||||
};
|
||||
|
||||
Specifying gated clocks
|
||||
=======================
|
||||
|
||||
The primary index must be set to 0.
|
||||
|
||||
The secondary index is the bit number within the RCC register bank, starting
|
||||
from the first RCC clock enable register (RCC_AHB1ENR, address offset 0x30).
|
||||
|
||||
It is calculated as: index = register_offset / 4 * 32 + bit_offset.
|
||||
Where bit_offset is the bit offset within the register (LSB is 0, MSB is 31).
|
||||
|
||||
To simplify the usage and to share bit definition with the reset and clock
|
||||
drivers of the RCC IP, macros are available to generate the index in
|
||||
human-readble format.
|
||||
|
||||
For STM32F4 series, the macro are available here:
|
||||
- include/dt-bindings/mfd/stm32f4-rcc.h
|
||||
|
||||
Example:
|
||||
|
||||
/* Gated clock, AHB1 bit 0 (GPIOA) */
|
||||
... {
|
||||
clocks = <&rcc 0 STM32F4_AHB1_CLOCK(GPIOA)>
|
||||
};
|
||||
|
||||
/* Gated clock, AHB2 bit 4 (CRYP) */
|
||||
... {
|
||||
clocks = <&rcc 0 STM32F4_AHB2_CLOCK(CRYP)>
|
||||
};
|
||||
|
||||
Specifying other clocks
|
||||
=======================
|
||||
|
||||
The primary index must be set to 1.
|
||||
|
||||
The secondary index is bound with the following magic numbers:
|
||||
|
||||
0 SYSTICK
|
||||
1 FCLK
|
||||
2 CLK_LSI (low-power clock source)
|
||||
3 CLK_LSE (generated from a 32.768 kHz low-speed external
|
||||
crystal or ceramic resonator)
|
||||
4 CLK_HSE_RTC (HSE division factor for RTC clock)
|
||||
5 CLK_RTC (real-time clock)
|
||||
6 PLL_VCO_I2S (vco frequency of I2S pll)
|
||||
7 PLL_VCO_SAI (vco frequency of SAI pll)
|
||||
8 CLK_LCD (LCD-TFT)
|
||||
9 CLK_I2S (I2S clocks)
|
||||
10 CLK_SAI1 (audio clocks)
|
||||
11 CLK_SAI2
|
||||
12 CLK_I2SQ_PDIV (post divisor of pll i2s q divisor)
|
||||
13 CLK_SAIQ_PDIV (post divisor of pll sai q divisor)
|
||||
|
||||
14 CLK_HSI (Internal ocscillator clock)
|
||||
15 CLK_SYSCLK (System Clock)
|
||||
16 CLK_HDMI_CEC (HDMI-CEC clock)
|
||||
17 CLK_SPDIF (SPDIF-Rx clock)
|
||||
18 CLK_USART1 (U(s)arts clocks)
|
||||
19 CLK_USART2
|
||||
20 CLK_USART3
|
||||
21 CLK_UART4
|
||||
22 CLK_UART5
|
||||
23 CLK_USART6
|
||||
24 CLK_UART7
|
||||
25 CLK_UART8
|
||||
26 CLK_I2C1 (I2S clocks)
|
||||
27 CLK_I2C2
|
||||
28 CLK_I2C3
|
||||
29 CLK_I2C4
|
||||
30 CLK_LPTIMER (LPTimer1 clock)
|
||||
31 CLK_PLL_SRC
|
||||
32 CLK_DFSDM1
|
||||
33 CLK_ADFSDM1
|
||||
34 CLK_F769_DSI
|
||||
)
|
||||
|
||||
Example:
|
||||
|
||||
/* Misc clock, FCLK */
|
||||
... {
|
||||
clocks = <&rcc 1 STM32F4_APB1_CLOCK(TIM2)>
|
||||
};
|
||||
|
||||
|
||||
Specifying softreset control of devices
|
||||
=======================================
|
||||
|
||||
Device nodes should specify the reset channel required in their "resets"
|
||||
property, containing a phandle to the reset device node and an index specifying
|
||||
which channel to use.
|
||||
The index is the bit number within the RCC registers bank, starting from RCC
|
||||
base address.
|
||||
It is calculated as: index = register_offset / 4 * 32 + bit_offset.
|
||||
Where bit_offset is the bit offset within the register.
|
||||
For example, for CRC reset:
|
||||
crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140
|
||||
|
||||
example:
|
||||
|
||||
timer2 {
|
||||
resets = <&rcc STM32F4_APB1_RESET(TIM2)>;
|
||||
};
|
144
Documentation/devicetree/bindings/clock/st,stm32-rcc.yaml
Normal file
144
Documentation/devicetree/bindings/clock/st,stm32-rcc.yaml
Normal file
|
@ -0,0 +1,144 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/st,stm32-rcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: STMicroelectronics STM32 Reset Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Dario Binacchi <dario.binacchi@amarulasolutions.com>
|
||||
|
||||
description: |
|
||||
The RCC IP is both a reset and a clock controller.
|
||||
The reset phandle argument is the bit number within the RCC registers bank,
|
||||
starting from RCC base address.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- st,stm32f42xx-rcc
|
||||
- st,stm32f746-rcc
|
||||
- st,stm32h743-rcc
|
||||
- const: st,stm32-rcc
|
||||
- items:
|
||||
- enum:
|
||||
- st,stm32f469-rcc
|
||||
- const: st,stm32f42xx-rcc
|
||||
- const: st,stm32-rcc
|
||||
- items:
|
||||
- enum:
|
||||
- st,stm32f769-rcc
|
||||
- const: st,stm32f746-rcc
|
||||
- const: st,stm32-rcc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#clock-cells':
|
||||
enum: [1, 2]
|
||||
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
st,syscfg:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to system configuration controller. It can be used to control the
|
||||
power domain circuitry.
|
||||
|
||||
st,ssc-modfreq-hz:
|
||||
description:
|
||||
The modulation frequency for main PLL (in Hz)
|
||||
|
||||
st,ssc-moddepth-permyriad:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
The modulation rate for main PLL (in permyriad, i.e. 0.01%)
|
||||
minimum: 25
|
||||
maximum: 200
|
||||
|
||||
st,ssc-modmethod:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
The modulation techniques for main PLL.
|
||||
items:
|
||||
enum:
|
||||
- center-spread
|
||||
- down-spread
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#reset-cells'
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- st,syscfg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: st,stm32h743-rcc
|
||||
then:
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description: |
|
||||
The clock index for the specified type.
|
||||
clocks:
|
||||
items:
|
||||
- description: high speed external (HSE) clock input
|
||||
- description: low speed external (LSE) clock input
|
||||
- description: Inter-IC sound (I2S) clock input
|
||||
st,ssc-modfreq-hz: false
|
||||
st,ssc-moddepth-permyriad: false
|
||||
st,ssc-modmethod: false
|
||||
|
||||
else:
|
||||
properties:
|
||||
'#clock-cells':
|
||||
const: 2
|
||||
description: |
|
||||
- The first cell is the clock type, possible values are 0 for
|
||||
gated clocks and 1 otherwise.
|
||||
- The second cell is the clock index for the specified type.
|
||||
clocks:
|
||||
items:
|
||||
- description: high speed external (HSE) clock input
|
||||
- description: Inter-IC sound (I2S) clock input
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
# Reset and Clock Control Module node:
|
||||
- |
|
||||
clock-controller@40023800 {
|
||||
compatible = "st,stm32f42xx-rcc", "st,stm32-rcc";
|
||||
reg = <0x40023800 0x400>;
|
||||
#clock-cells = <2>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&clk_hse>, <&clk_i2s_ckin>;
|
||||
st,syscfg = <&pwrcfg>;
|
||||
st,ssc-modfreq-hz = <10000>;
|
||||
st,ssc-moddepth-permyriad = <200>;
|
||||
st,ssc-modmethod = "center-spread";
|
||||
};
|
||||
- |
|
||||
clock-controller@58024400 {
|
||||
compatible = "st,stm32h743-rcc", "st,stm32-rcc";
|
||||
reg = <0x58024400 0x400>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s>;
|
||||
st,syscfg = <&pwrcfg>;
|
||||
};
|
||||
|
||||
...
|
|
@ -21,7 +21,7 @@ description: |
|
|||
=================
|
||||
|
||||
All available clocks are defined as preprocessor macros in
|
||||
dt-bindings/clock/stm32mp1-clks.h header and can be used in device
|
||||
include/dt-bindings/clock/stm32mp1-clks.h header and can be used in device
|
||||
tree sources.
|
||||
|
||||
Specifying softreset control of devices
|
||||
|
@ -40,8 +40,8 @@ description: |
|
|||
= 0x180 / 4 * 32 + 0 = 3072
|
||||
|
||||
The list of valid indices for STM32MP1 is available in:
|
||||
include/dt-bindings/reset-controller/stm32mp1-resets.h
|
||||
include/dt-bindings/reset-controller/stm32mp13-resets.h
|
||||
include/dt-bindings/reset/stm32mp1-resets.h
|
||||
include/dt-bindings/reset/stm32mp13-resets.h
|
||||
|
||||
This file implements defines like:
|
||||
#define LTDC_R 3072
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
Binding for TI composite clock.
|
||||
|
||||
This binding uses the common clock binding[1]. It assumes a
|
||||
register-mapped composite clock with multiple different sub-types;
|
||||
|
||||
a multiplexer clock with multiple input clock signals or parents, one
|
||||
of which can be selected as output, this behaves exactly as [2]
|
||||
|
||||
an adjustable clock rate divider, this behaves exactly as [3]
|
||||
|
||||
a gating function which can be used to enable and disable the output
|
||||
clock, this behaves exactly as [4]
|
||||
|
||||
The binding must provide a list of the component clocks that shall be
|
||||
merged to this clock. The component clocks shall be of one of the
|
||||
"ti,*composite*-clock" types.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
[2] Documentation/devicetree/bindings/clock/ti/ti,mux-clock.yaml
|
||||
[3] Documentation/devicetree/bindings/clock/ti/ti,divider-clock.yaml
|
||||
[4] Documentation/devicetree/bindings/clock/ti/gate.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be: "ti,composite-clock"
|
||||
- clocks : link phandles of component clocks
|
||||
- #clock-cells : from common clock binding; shall be set to 0.
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : from common clock binding.
|
||||
|
||||
Examples:
|
||||
|
||||
usb_l4_gate_ick: usb_l4_gate_ick {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-interface-clock";
|
||||
clocks = <&l4_ick>;
|
||||
ti,bit-shift = <5>;
|
||||
reg = <0x0a10>;
|
||||
};
|
||||
|
||||
usb_l4_div_ick: usb_l4_div_ick {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-divider-clock";
|
||||
clocks = <&l4_ick>;
|
||||
ti,bit-shift = <4>;
|
||||
ti,max-div = <1>;
|
||||
reg = <0x0a40>;
|
||||
ti,index-starts-at-one;
|
||||
};
|
||||
|
||||
usb_l4_ick: usb_l4_ick {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-clock";
|
||||
clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>;
|
||||
};
|
|
@ -1,105 +0,0 @@
|
|||
Binding for Texas Instruments gate clock.
|
||||
|
||||
This binding uses the common clock binding[1]. This clock is
|
||||
quite much similar to the basic gate-clock [2], however,
|
||||
it supports a number of additional features. If no register
|
||||
is provided for this clock, the code assumes that a clockdomain
|
||||
will be controlled instead and the corresponding hw-ops for
|
||||
that is used.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
[2] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
|
||||
[3] Documentation/devicetree/bindings/clock/ti/clockdomain.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be one of:
|
||||
"ti,gate-clock" - basic gate clock
|
||||
"ti,wait-gate-clock" - gate clock which waits until clock is active before
|
||||
returning from clk_enable()
|
||||
"ti,dss-gate-clock" - gate clock with DSS specific hardware handling
|
||||
"ti,am35xx-gate-clock" - gate clock with AM35xx specific hardware handling
|
||||
"ti,clkdm-gate-clock" - clockdomain gate clock, which derives its functional
|
||||
clock directly from a clockdomain, see [3] how
|
||||
to map clockdomains properly
|
||||
"ti,hsdiv-gate-clock" - gate clock with OMAP36xx specific hardware handling,
|
||||
required for a hardware errata
|
||||
"ti,composite-gate-clock" - composite gate clock, to be part of composite
|
||||
clock
|
||||
"ti,composite-no-wait-gate-clock" - composite gate clock that does not wait
|
||||
for clock to be active before returning
|
||||
from clk_enable()
|
||||
- #clock-cells : from common clock binding; shall be set to 0
|
||||
- clocks : link to phandle of parent clock
|
||||
- reg : offset for register controlling adjustable gate, not needed for
|
||||
ti,clkdm-gate-clock type
|
||||
|
||||
Optional properties:
|
||||
- clock-output-names : from common clock binding.
|
||||
- ti,bit-shift : bit shift for programming the clock gate, invalid for
|
||||
ti,clkdm-gate-clock type
|
||||
- ti,set-bit-to-disable : inverts default gate programming. Setting the bit
|
||||
gates the clock and clearing the bit ungates the clock.
|
||||
|
||||
Examples:
|
||||
mmchs2_fck: mmchs2_fck@48004a00 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,gate-clock";
|
||||
clocks = <&core_96m_fck>;
|
||||
reg = <0x0a00>;
|
||||
ti,bit-shift = <25>;
|
||||
};
|
||||
|
||||
uart4_fck_am35xx: uart4_fck_am35xx {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,wait-gate-clock";
|
||||
clocks = <&core_48m_fck>;
|
||||
reg = <0x0a00>;
|
||||
ti,bit-shift = <23>;
|
||||
};
|
||||
|
||||
dss1_alwon_fck_3430es2: dss1_alwon_fck_3430es2@48004e00 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,dss-gate-clock";
|
||||
clocks = <&dpll4_m4x2_ck>;
|
||||
reg = <0x0e00>;
|
||||
ti,bit-shift = <0>;
|
||||
};
|
||||
|
||||
emac_ick: emac_ick@4800259c {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,am35xx-gate-clock";
|
||||
clocks = <&ipss_ick>;
|
||||
reg = <0x059c>;
|
||||
ti,bit-shift = <1>;
|
||||
};
|
||||
|
||||
emu_src_ck: emu_src_ck {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,clkdm-gate-clock";
|
||||
clocks = <&emu_src_mux_ck>;
|
||||
};
|
||||
|
||||
dpll4_m2x2_ck: dpll4_m2x2_ck@48004d00 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,hsdiv-gate-clock";
|
||||
clocks = <&dpll4_m2x2_mul_ck>;
|
||||
ti,bit-shift = <0x1b>;
|
||||
reg = <0x0d00>;
|
||||
ti,set-bit-to-disable;
|
||||
};
|
||||
|
||||
vlynq_gate_fck: vlynq_gate_fck {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-gate-clock";
|
||||
clocks = <&core_ck>;
|
||||
ti,bit-shift = <3>;
|
||||
reg = <0x0200>;
|
||||
};
|
||||
|
||||
sys_clkout2_src_gate: sys_clkout2_src_gate {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-no-wait-gate-clock";
|
||||
clocks = <&core_ck>;
|
||||
ti,bit-shift = <15>;
|
||||
reg = <0x0070>;
|
||||
};
|
|
@ -0,0 +1,82 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti/ti,composite-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments composite clock
|
||||
|
||||
maintainers:
|
||||
- Tero Kristo <kristo@kernel.org>
|
||||
|
||||
description: |
|
||||
*Deprecated design pattern: one node per clock*
|
||||
|
||||
This binding assumes a register-mapped composite clock with multiple
|
||||
different sub-types:
|
||||
|
||||
a multiplexer clock with multiple input clock signals or parents, one
|
||||
of which can be selected as output, this behaves exactly as [1].
|
||||
|
||||
an adjustable clock rate divider, this behaves exactly as [2].
|
||||
|
||||
a gating function which can be used to enable and disable the output
|
||||
clock, this behaves exactly as [3].
|
||||
|
||||
The binding must provide a list of the component clocks that shall be
|
||||
merged to this clock. The component clocks shall be of one of the
|
||||
"ti,*composite*-clock" types.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/ti/ti,mux-clock.yaml
|
||||
[2] Documentation/devicetree/bindings/clock/ti/ti,divider-clock.yaml
|
||||
[3] Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,composite-clock
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clocks: true
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
usb_l4_gate_ick: clock-controller@a10 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-gate-clock";
|
||||
clocks = <&l4_ick>;
|
||||
ti,bit-shift = <5>;
|
||||
reg = <0x0a10>;
|
||||
};
|
||||
|
||||
usb_l4_div_ick: clock-controller@a40 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-divider-clock";
|
||||
clocks = <&l4_ick>;
|
||||
ti,bit-shift = <4>;
|
||||
ti,max-div = <1>;
|
||||
reg = <0x0a40>;
|
||||
ti,index-starts-at-one;
|
||||
};
|
||||
};
|
||||
|
||||
clock-controller {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,composite-clock";
|
||||
clocks = <&usb_l4_gate_ick>, <&usb_l4_div_ick>;
|
||||
};
|
125
Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml
Normal file
125
Documentation/devicetree/bindings/clock/ti/ti,gate-clock.yaml
Normal file
|
@ -0,0 +1,125 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti/ti,gate-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments gate clock
|
||||
|
||||
maintainers:
|
||||
- Tero Kristo <kristo@kernel.org>
|
||||
|
||||
description: |
|
||||
*Deprecated design pattern: one node per clock*
|
||||
|
||||
This clock is quite much similar to the basic gate-clock [1], however,
|
||||
it supports a number of additional features. If no register
|
||||
is provided for this clock, the code assumes that a clockdomain
|
||||
will be controlled instead and the corresponding hw-ops for
|
||||
that is used.
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/gpio-gate-clock.yaml
|
||||
[2] Documentation/devicetree/bindings/clock/ti/clockdomain.txt
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,gate-clock # basic gate clock
|
||||
- ti,wait-gate-clock # gate clock which waits until clock is
|
||||
# active before returning from clk_enable()
|
||||
- ti,dss-gate-clock # gate clock with DSS specific hardware
|
||||
# handling
|
||||
- ti,am35xx-gate-clock # gate clock with AM35xx specific hardware
|
||||
# handling
|
||||
- ti,clkdm-gate-clock # clockdomain gate clock, which derives its
|
||||
# functional clock directly from a
|
||||
# clockdomain, see [2] how to map
|
||||
# clockdomains properly
|
||||
- ti,hsdiv-gate-clock # gate clock with OMAP36xx specific hardware
|
||||
# handling, required for a hardware errata
|
||||
- ti,composite-gate-clock # composite gate clock, to be part of
|
||||
# composite clock
|
||||
- ti,composite-no-wait-gate-clock # composite gate clock that does not
|
||||
# wait for clock to be active before
|
||||
# returning from clk_enable()
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
clocks: true
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
ti,bit-shift:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Number of bits to shift the bit-mask
|
||||
maximum: 31
|
||||
default: 0
|
||||
|
||||
ti,set-bit-to-disable:
|
||||
type: boolean
|
||||
description:
|
||||
Inverts default gate programming. Setting the bit
|
||||
gates the clock and clearing the bit ungates the clock.
|
||||
|
||||
ti,set-rate-parent:
|
||||
type: boolean
|
||||
description:
|
||||
clk_set_rate is propagated to parent clock,
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ti,clkdm-gate-clock
|
||||
then:
|
||||
properties:
|
||||
reg: false
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
else:
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clock-controller@a00 {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,gate-clock";
|
||||
clocks = <&core_96m_fck>;
|
||||
reg = <0x0a00>;
|
||||
ti,bit-shift = <25>;
|
||||
};
|
||||
|
||||
clock-controller@d00 {
|
||||
compatible = "ti,hsdiv-gate-clock";
|
||||
reg = <0x0d00>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&dpll4_m2x2_mul_ck>;
|
||||
ti,bit-shift = <0x1b>;
|
||||
ti,set-bit-to-disable;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
clock-controller {
|
||||
#clock-cells = <0>;
|
||||
compatible = "ti,clkdm-gate-clock";
|
||||
clocks = <&emu_src_mux_ck>;
|
||||
};
|
||||
|
59
Documentation/devicetree/bindings/clock/xlnx,vcu.yaml
Normal file
59
Documentation/devicetree/bindings/clock/xlnx,vcu.yaml
Normal file
|
@ -0,0 +1,59 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/xlnx,vcu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
title: LogicoreIP designed compatible with Xilinx ZYNQ family.
|
||||
|
||||
maintainers:
|
||||
- Rohit Visavalia <rohit.visavalia@amd.com>
|
||||
|
||||
description:
|
||||
LogicoreIP design to provide the isolation between processing system
|
||||
and programmable logic. Also provides the list of register set to configure
|
||||
the frequency.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- xlnx,vcu
|
||||
- xlnx,vcu-logicoreip-1.0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: pll ref clocksource
|
||||
- description: aclk
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: pll_ref
|
||||
- const: aclk
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
fpga {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
xlnx_vcu: vcu@a0040000 {
|
||||
compatible = "xlnx,vcu-logicoreip-1.0";
|
||||
reg = <0x0 0xa0040000 0x0 0x1000>;
|
||||
reset-gpios = <&gpio 78 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&si570_1>, <&clkc 71>;
|
||||
clock-names = "pll_ref", "aclk";
|
||||
};
|
||||
};
|
|
@ -3,4 +3,4 @@ STMicroelectronics STM32 Peripheral Reset Controller
|
|||
|
||||
The RCC IP is both a reset and a clock controller.
|
||||
|
||||
Please see Documentation/devicetree/bindings/clock/st,stm32-rcc.txt
|
||||
Please see Documentation/devicetree/bindings/clock/st,stm32-rcc.yaml
|
||||
|
|
|
@ -525,6 +525,23 @@ properties:
|
|||
- renesas,rzv2mevk2 # RZ/V2M Eval Board v2.0
|
||||
- const: renesas,r9a09g011
|
||||
|
||||
- description: RZ/G3E (R9A09G047)
|
||||
items:
|
||||
- enum:
|
||||
- renesas,smarc2-evk # RZ SMARC Carrier-II EVK
|
||||
- enum:
|
||||
- renesas,rzg3e-smarcm # RZ/G3E SMARC Module (SoM)
|
||||
- enum:
|
||||
- renesas,r9a09g047e27 # Dual Cortex-A55 + Cortex-M33 (15mm BGA)
|
||||
- renesas,r9a09g047e28 # Dual Cortex-A55 + Cortex-M33 (21mm BGA)
|
||||
- renesas,r9a09g047e37 # Dual Cortex-A55 + Cortex-M33 + Ethos-U55 (15mm BGA)
|
||||
- renesas,r9a09g047e38 # Dual Cortex-A55 + Cortex-M33 + Ethos-U55 (21mm BGA)
|
||||
- renesas,r9a09g047e47 # Quad Cortex-A55 + Cortex-M33 (15mm BGA)
|
||||
- renesas,r9a09g047e48 # Quad Cortex-A55 + Cortex-M33 (21mm BGA)
|
||||
- renesas,r9a09g047e57 # Quad Cortex-A55 + Cortex-M33 + Ethos-U55 (15mm BGA)
|
||||
- renesas,r9a09g047e58 # Quad Cortex-A55 + Cortex-M33 + Ethos-U55 (21mm BGA)
|
||||
- const: renesas,r9a09g047
|
||||
|
||||
- description: RZ/V2H(P) (R9A09G057)
|
||||
items:
|
||||
- enum:
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
LogicoreIP designed compatible with Xilinx ZYNQ family.
|
||||
-------------------------------------------------------
|
||||
|
||||
General concept
|
||||
---------------
|
||||
|
||||
LogicoreIP design to provide the isolation between processing system
|
||||
and programmable logic. Also provides the list of register set to configure
|
||||
the frequency.
|
||||
|
||||
Required properties:
|
||||
- compatible: shall be one of:
|
||||
"xlnx,vcu"
|
||||
"xlnx,vcu-logicoreip-1.0"
|
||||
- reg : The base offset and size of the VCU_PL_SLCR register space.
|
||||
- clocks: phandle for aclk and pll_ref clocksource
|
||||
- clock-names: The identification string, "aclk", is always required for
|
||||
the axi clock. "pll_ref" is required for pll.
|
||||
Example:
|
||||
|
||||
xlnx_vcu: vcu@a0040000 {
|
||||
compatible = "xlnx,vcu-logicoreip-1.0";
|
||||
reg = <0x0 0xa0040000 0x0 0x1000>;
|
||||
clocks = <&si570_1>, <&clkc 71>;
|
||||
clock-names = "pll_ref", "aclk";
|
||||
};
|
|
@ -925,7 +925,7 @@
|
|||
reg-names = "ram", "regs", "rxfifo", "txfifo";
|
||||
interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clk IMX93_CLK_BUS_WAKEUP>,
|
||||
clocks = <&clk IMX93_CLK_SPDIF_IPG>,
|
||||
<&clk IMX93_CLK_SPDIF_GATE>,
|
||||
<&clk IMX93_CLK_DUMMY>,
|
||||
<&clk IMX93_CLK_AUD_XCVR_GATE>;
|
||||
|
|
|
@ -292,7 +292,7 @@ int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
|
|||
vco = vco_pre * f;
|
||||
}
|
||||
|
||||
delta = abs(target_rate - vco);
|
||||
delta = abs(target_vco_rate - vco);
|
||||
if (delta < best_delta) {
|
||||
best_delta = delta;
|
||||
best_r = r;
|
||||
|
|
|
@ -24,4 +24,5 @@ obj-$(CONFIG_SOC_SAM9X7) += sam9x7.o
|
|||
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o
|
||||
obj-$(CONFIG_SOC_SAMA7D65) += sama7d65.o
|
||||
obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#define PMC_MCR_CSS_SHIFT (16)
|
||||
|
||||
#define MASTER_MAX_ID 4
|
||||
#define MASTER_MAX_ID 9
|
||||
|
||||
#define to_clk_master(hw) container_of(hw, struct clk_master, hw)
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define UPLL_DIV 2
|
||||
#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
|
||||
|
||||
#define PLL_MAX_ID 7
|
||||
#define PLL_MAX_ID 9
|
||||
|
||||
struct sam9x60_pll_core {
|
||||
struct regmap *regmap;
|
||||
|
|
|
@ -151,6 +151,7 @@ static struct syscore_ops pmc_syscore_ops = {
|
|||
static const struct of_device_id pmc_dt_ids[] = {
|
||||
{ .compatible = "atmel,sama5d2-pmc" },
|
||||
{ .compatible = "microchip,sama7g5-pmc", },
|
||||
{ .compatible = "microchip,sama7d65-pmc", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
|
1375
drivers/clk/at91/sama7d65.c
Normal file
1375
drivers/clk/at91/sama7d65.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -12,6 +12,8 @@
|
|||
#include <linux/of_address.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#define SLOW_CLOCK_FREQ 32768
|
||||
#define SLOWCK_SW_CYCLES 5
|
||||
#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
|
||||
|
@ -470,7 +472,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np)
|
|||
{
|
||||
void __iomem *regbase = of_iomap(np, 0);
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw *slow_rc, *slow_osc;
|
||||
struct clk_hw *slow_rc, *slow_osc, *hw;
|
||||
const char *xtal_name;
|
||||
const struct clk_hw *parent_hws[2];
|
||||
static struct clk_parent_data parent_data = {
|
||||
|
@ -506,19 +508,19 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np)
|
|||
|
||||
/* MD_SLCK and TD_SLCK. */
|
||||
clk_data->num = 2;
|
||||
clk_data->hws[0] = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck",
|
||||
slow_rc,
|
||||
0, 32768);
|
||||
if (IS_ERR(clk_data->hws[0]))
|
||||
hw = clk_hw_register_fixed_rate_parent_hw(NULL, "md_slck", slow_rc,
|
||||
0, 32768);
|
||||
if (IS_ERR(hw))
|
||||
goto clk_data_free;
|
||||
clk_data->hws[SCKC_MD_SLCK] = hw;
|
||||
|
||||
parent_hws[0] = slow_rc;
|
||||
parent_hws[1] = slow_osc;
|
||||
clk_data->hws[1] = at91_clk_register_sam9x5_slow(regbase, "td_slck",
|
||||
parent_hws, 2,
|
||||
&at91sam9x60_bits);
|
||||
if (IS_ERR(clk_data->hws[1]))
|
||||
hw = at91_clk_register_sam9x5_slow(regbase, "td_slck", parent_hws,
|
||||
2, &at91sam9x60_bits);
|
||||
if (IS_ERR(hw))
|
||||
goto unregister_md_slck;
|
||||
clk_data->hws[SCKC_TD_SLCK] = hw;
|
||||
|
||||
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
if (WARN_ON(ret))
|
||||
|
@ -527,9 +529,9 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np)
|
|||
return;
|
||||
|
||||
unregister_td_slck:
|
||||
at91_clk_unregister_sam9x5_slow(clk_data->hws[1]);
|
||||
at91_clk_unregister_sam9x5_slow(clk_data->hws[SCKC_TD_SLCK]);
|
||||
unregister_md_slck:
|
||||
clk_hw_unregister(clk_data->hws[0]);
|
||||
clk_hw_unregister(clk_data->hws[SCKC_MD_SLCK]);
|
||||
clk_data_free:
|
||||
kfree(clk_data);
|
||||
unregister_slow_osc:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
/*
|
||||
* "Policies" affect the frequencies of bus clocks provided by a
|
||||
|
@ -502,7 +503,7 @@ static int clk_gate(struct ccu_data *ccu, const char *name,
|
|||
return 0;
|
||||
|
||||
pr_err("%s: failed to %s gate for %s\n", __func__,
|
||||
enable ? "enable" : "disable", name);
|
||||
str_enable_disable(enable), name);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ static char *rpi_firmware_clk_names[] = {
|
|||
[RPI_FIRMWARE_M2MC_CLK_ID] = "m2mc",
|
||||
[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = "pixel-bvb",
|
||||
[RPI_FIRMWARE_VEC_CLK_ID] = "vec",
|
||||
[RPI_FIRMWARE_DISP_CLK_ID] = "disp",
|
||||
};
|
||||
|
||||
#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
|
||||
|
@ -56,6 +57,12 @@ struct raspberrypi_clk_data {
|
|||
struct raspberrypi_clk *rpi;
|
||||
};
|
||||
|
||||
static inline
|
||||
const struct raspberrypi_clk_data *clk_hw_to_data(const struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct raspberrypi_clk_data, hw);
|
||||
}
|
||||
|
||||
struct raspberrypi_clk_variant {
|
||||
bool export;
|
||||
char *clkdev;
|
||||
|
@ -111,18 +118,31 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
|
|||
},
|
||||
[RPI_FIRMWARE_V3D_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_PIXEL_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_HEVC_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_ISP_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_VEC_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
[RPI_FIRMWARE_DISP_CLK_ID] = {
|
||||
.export = true,
|
||||
.minimize = true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -153,7 +173,6 @@ static int raspberrypi_clock_property(struct rpi_firmware *firmware,
|
|||
struct raspberrypi_firmware_prop msg = {
|
||||
.id = cpu_to_le32(data->id),
|
||||
.val = cpu_to_le32(*val),
|
||||
.disable_turbo = cpu_to_le32(1),
|
||||
};
|
||||
int ret;
|
||||
|
||||
|
@ -168,8 +187,7 @@ static int raspberrypi_clock_property(struct rpi_firmware *firmware,
|
|||
|
||||
static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct raspberrypi_clk_data *data =
|
||||
container_of(hw, struct raspberrypi_clk_data, hw);
|
||||
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
|
||||
struct raspberrypi_clk *rpi = data->rpi;
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
|
@ -186,8 +204,7 @@ static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
|
|||
static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct raspberrypi_clk_data *data =
|
||||
container_of(hw, struct raspberrypi_clk_data, hw);
|
||||
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
|
||||
struct raspberrypi_clk *rpi = data->rpi;
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
|
@ -203,8 +220,7 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
|
|||
static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct raspberrypi_clk_data *data =
|
||||
container_of(hw, struct raspberrypi_clk_data, hw);
|
||||
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
|
||||
struct raspberrypi_clk *rpi = data->rpi;
|
||||
u32 _rate = rate;
|
||||
int ret;
|
||||
|
@ -221,8 +237,7 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct raspberrypi_clk_data *data =
|
||||
container_of(hw, struct raspberrypi_clk_data, hw);
|
||||
const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
|
||||
struct raspberrypi_clk_variant *variant = data->variant;
|
||||
|
||||
/*
|
||||
|
|
|
@ -75,6 +75,7 @@ struct en_rst_data {
|
|||
};
|
||||
|
||||
struct en_clk_soc_data {
|
||||
u32 num_clocks;
|
||||
const struct clk_ops pcie_ops;
|
||||
int (*hw_init)(struct platform_device *pdev,
|
||||
struct clk_hw_onecell_data *clk_data);
|
||||
|
@ -90,6 +91,7 @@ static const u32 emi7581_base[] = { 540000000, 480000000, 400000000, 300000000 }
|
|||
static const u32 bus7581_base[] = { 600000000, 540000000 };
|
||||
static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
|
||||
static const u32 crypto_base[] = { 540000000, 480000000 };
|
||||
static const u32 emmc7581_base[] = { 200000000, 150000000 };
|
||||
|
||||
static const struct en_clk_desc en7523_base_clks[] = {
|
||||
{
|
||||
|
@ -280,6 +282,15 @@ static const struct en_clk_desc en7581_base_clks[] = {
|
|||
.base_shift = 0,
|
||||
.base_values = crypto_base,
|
||||
.n_base_values = ARRAY_SIZE(crypto_base),
|
||||
}, {
|
||||
.id = EN7581_CLK_EMMC,
|
||||
.name = "emmc",
|
||||
|
||||
.base_reg = REG_CRYPTO_CLKSRC2,
|
||||
.base_bits = 1,
|
||||
.base_shift = 12,
|
||||
.base_values = emmc7581_base,
|
||||
.n_base_values = ARRAY_SIZE(emmc7581_base),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -504,8 +515,6 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat
|
|||
u32 rate;
|
||||
int i;
|
||||
|
||||
clk_data->num = EN7523_NUM_CLOCKS;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
|
||||
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||
u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||||
|
@ -587,8 +596,6 @@ static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_dat
|
|||
|
||||
hw = en7523_register_pcie_clk(dev, base);
|
||||
clk_data->hws[EN7523_CLK_PCIE] = hw;
|
||||
|
||||
clk_data->num = EN7523_NUM_CLOCKS;
|
||||
}
|
||||
|
||||
static int en7523_reset_update(struct reset_controller_dev *rcdev,
|
||||
|
@ -702,13 +709,15 @@ static int en7523_clk_probe(struct platform_device *pdev)
|
|||
struct clk_hw_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
soc_data = device_get_match_data(&pdev->dev);
|
||||
|
||||
clk_data = devm_kzalloc(&pdev->dev,
|
||||
struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
|
||||
struct_size(clk_data, hws, soc_data->num_clocks),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
soc_data = device_get_match_data(&pdev->dev);
|
||||
clk_data->num = soc_data->num_clocks;
|
||||
r = soc_data->hw_init(pdev, clk_data);
|
||||
if (r)
|
||||
return r;
|
||||
|
@ -717,6 +726,7 @@ static int en7523_clk_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct en_clk_soc_data en7523_data = {
|
||||
.num_clocks = ARRAY_SIZE(en7523_base_clks) + 1,
|
||||
.pcie_ops = {
|
||||
.is_enabled = en7523_pci_is_enabled,
|
||||
.prepare = en7523_pci_prepare,
|
||||
|
@ -726,6 +736,8 @@ static const struct en_clk_soc_data en7523_data = {
|
|||
};
|
||||
|
||||
static const struct en_clk_soc_data en7581_data = {
|
||||
/* We increment num_clocks by 1 to account for additional PCIe clock */
|
||||
.num_clocks = ARRAY_SIZE(en7581_base_clks) + 1,
|
||||
.pcie_ops = {
|
||||
.is_enabled = en7581_pci_is_enabled,
|
||||
.enable = en7581_pci_enable,
|
||||
|
|
|
@ -586,9 +586,9 @@ static unsigned long calc_pll_rate(u64 rate, u32 config_word)
|
|||
|
||||
static int ep93xx_plls_init(struct ep93xx_clk_priv *priv)
|
||||
{
|
||||
const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
|
||||
const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
|
||||
const char pclk_divisors[] = { 1, 2, 4, 8 };
|
||||
static const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
|
||||
static const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
|
||||
static const char pclk_divisors[] = { 1, 2, 4, 8 };
|
||||
struct clk_parent_data xtali = { .index = 0 };
|
||||
unsigned int clk_f_div, clk_h_div, clk_p_div;
|
||||
unsigned long clk_pll1_rate, clk_pll2_rate;
|
||||
|
|
|
@ -375,7 +375,7 @@ static unsigned long lmk04832_vco_recalc_rate(struct clk_hw *hw,
|
|||
unsigned long prate)
|
||||
{
|
||||
struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco);
|
||||
const unsigned int pll2_p[] = {8, 2, 2, 3, 4, 5, 6, 7};
|
||||
static const unsigned int pll2_p[] = {8, 2, 2, 3, 4, 5, 6, 7};
|
||||
unsigned int pll2_n, p, pll2_r;
|
||||
unsigned int pll2_misc;
|
||||
unsigned long vco_rate;
|
||||
|
@ -637,7 +637,7 @@ static int lmk04832_register_vco(struct lmk04832 *lmk)
|
|||
|
||||
static int lmk04832_clkout_set_ddly(struct lmk04832 *lmk, int id)
|
||||
{
|
||||
const int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0};
|
||||
static const int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0};
|
||||
unsigned int sclkx_y_ddly = 10;
|
||||
unsigned int dclkx_y_ddly;
|
||||
unsigned int dclkx_y_div;
|
||||
|
|
|
@ -294,7 +294,7 @@ static int loongson2_clk_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
|
||||
for (p = data; p->name; p++)
|
||||
clks_num++;
|
||||
clks_num = max(clks_num, p->id + 1);
|
||||
|
||||
clp = devm_kzalloc(dev, struct_size(clp, clk_data.hws, clks_num),
|
||||
GFP_KERNEL);
|
||||
|
@ -309,6 +309,9 @@ static int loongson2_clk_probe(struct platform_device *pdev)
|
|||
clp->clk_data.num = clks_num;
|
||||
clp->dev = dev;
|
||||
|
||||
/* Avoid returning NULL for unused id */
|
||||
memset_p((void **)clp->clk_data.hws, ERR_PTR(-ENOENT), clks_num);
|
||||
|
||||
for (i = 0; i < clks_num; i++) {
|
||||
p = &data[i];
|
||||
switch (p->type) {
|
||||
|
@ -335,8 +338,8 @@ static int loongson2_clk_probe(struct platform_device *pdev)
|
|||
&clp->clk_lock);
|
||||
break;
|
||||
case CLK_TYPE_FIXED:
|
||||
hw = clk_hw_register_fixed_rate_parent_data(dev, p->name, pdata,
|
||||
0, p->fixed_rate);
|
||||
hw = devm_clk_hw_register_fixed_rate_parent_data(dev, p->name, pdata,
|
||||
0, p->fixed_rate);
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(dev, -EINVAL, "Invalid clk type\n");
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
/*
|
||||
|
@ -116,9 +117,9 @@ static void __init nomadik_src_init(void)
|
|||
|
||||
val = readl(src_base + SRC_XTALCR);
|
||||
pr_info("SXTALO is %s\n",
|
||||
(val & SRC_XTALCR_SXTALDIS) ? "disabled" : "enabled");
|
||||
str_disabled_enabled(val & SRC_XTALCR_SXTALDIS));
|
||||
pr_info("MXTAL is %s\n",
|
||||
(val & SRC_XTALCR_MXTALSTAT) ? "enabled" : "disabled");
|
||||
str_enabled_disabled(val & SRC_XTALCR_MXTALSTAT));
|
||||
if (of_property_read_bool(np, "disable-sxtalo")) {
|
||||
/* The machine uses an external oscillator circuit */
|
||||
val |= SRC_XTALCR_SXTALDIS;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Inspired by clk-asm9260.c .
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -34,11 +35,20 @@
|
|||
#define STM32F4_RCC_APB2ENR 0x44
|
||||
#define STM32F4_RCC_BDCR 0x70
|
||||
#define STM32F4_RCC_CSR 0x74
|
||||
#define STM32F4_RCC_SSCGR 0x80
|
||||
#define STM32F4_RCC_PLLI2SCFGR 0x84
|
||||
#define STM32F4_RCC_PLLSAICFGR 0x88
|
||||
#define STM32F4_RCC_DCKCFGR 0x8c
|
||||
#define STM32F7_RCC_DCKCFGR2 0x90
|
||||
|
||||
#define STM32F4_RCC_PLLCFGR_N_MASK GENMASK(14, 6)
|
||||
|
||||
#define STM32F4_RCC_SSCGR_SSCGEN BIT(31)
|
||||
#define STM32F4_RCC_SSCGR_SPREADSEL BIT(30)
|
||||
#define STM32F4_RCC_SSCGR_RESERVED_MASK GENMASK(29, 28)
|
||||
#define STM32F4_RCC_SSCGR_INCSTEP_MASK GENMASK(27, 13)
|
||||
#define STM32F4_RCC_SSCGR_MODPER_MASK GENMASK(12, 0)
|
||||
|
||||
#define NONE -1
|
||||
#define NO_IDX NONE
|
||||
#define NO_MUX NONE
|
||||
|
@ -364,6 +374,16 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
|
|||
{ STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" },
|
||||
};
|
||||
|
||||
enum stm32f4_pll_ssc_mod_type {
|
||||
STM32F4_PLL_SSC_CENTER_SPREAD,
|
||||
STM32F4_PLL_SSC_DOWN_SPREAD,
|
||||
};
|
||||
|
||||
static const char * const stm32f4_ssc_mod_methods[] __initconst = {
|
||||
[STM32F4_PLL_SSC_DOWN_SPREAD] = "down-spread",
|
||||
[STM32F4_PLL_SSC_CENTER_SPREAD] = "center-spread",
|
||||
};
|
||||
|
||||
/*
|
||||
* This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx
|
||||
* have gate bits associated with them. Its combined hweight is 71.
|
||||
|
@ -509,6 +529,12 @@ static const struct clk_div_table pll_divr_table[] = {
|
|||
{ 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 0 }
|
||||
};
|
||||
|
||||
struct stm32f4_pll_ssc {
|
||||
unsigned int mod_freq;
|
||||
unsigned int mod_depth;
|
||||
enum stm32f4_pll_ssc_mod_type mod_type;
|
||||
};
|
||||
|
||||
struct stm32f4_pll {
|
||||
spinlock_t *lock;
|
||||
struct clk_gate gate;
|
||||
|
@ -516,6 +542,8 @@ struct stm32f4_pll {
|
|||
u8 bit_rdy_idx;
|
||||
u8 status;
|
||||
u8 n_start;
|
||||
bool ssc_enable;
|
||||
struct stm32f4_pll_ssc ssc_conf;
|
||||
};
|
||||
|
||||
#define to_stm32f4_pll(_gate) container_of(_gate, struct stm32f4_pll, gate)
|
||||
|
@ -538,6 +566,7 @@ struct stm32f4_vco_data {
|
|||
u8 offset;
|
||||
u8 bit_idx;
|
||||
u8 bit_rdy_idx;
|
||||
bool sscg;
|
||||
};
|
||||
|
||||
static const struct stm32f4_vco_data vco_data[] = {
|
||||
|
@ -632,9 +661,11 @@ static unsigned long stm32f4_pll_recalc(struct clk_hw *hw,
|
|||
{
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
struct stm32f4_pll *pll = to_stm32f4_pll(gate);
|
||||
unsigned long val;
|
||||
unsigned long n;
|
||||
|
||||
n = (readl(base + pll->offset) >> 6) & 0x1ff;
|
||||
val = readl(base + pll->offset);
|
||||
n = FIELD_GET(STM32F4_RCC_PLLCFGR_N_MASK, val);
|
||||
|
||||
return parent_rate * n;
|
||||
}
|
||||
|
@ -656,6 +687,32 @@ static long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return *prate * n;
|
||||
}
|
||||
|
||||
static void stm32f4_pll_set_ssc(struct clk_hw *hw, unsigned long parent_rate,
|
||||
unsigned int ndiv)
|
||||
{
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
struct stm32f4_pll *pll = to_stm32f4_pll(gate);
|
||||
struct stm32f4_pll_ssc *ssc = &pll->ssc_conf;
|
||||
u32 modeper, incstep;
|
||||
u32 sscgr;
|
||||
|
||||
sscgr = readl(base + STM32F4_RCC_SSCGR);
|
||||
/* reserved field must be kept at reset value */
|
||||
sscgr &= STM32F4_RCC_SSCGR_RESERVED_MASK;
|
||||
|
||||
modeper = DIV_ROUND_CLOSEST(parent_rate, 4 * ssc->mod_freq);
|
||||
incstep = DIV_ROUND_CLOSEST(((1 << 15) - 1) * ssc->mod_depth * ndiv,
|
||||
5 * 10000 * modeper);
|
||||
sscgr |= STM32F4_RCC_SSCGR_SSCGEN |
|
||||
FIELD_PREP(STM32F4_RCC_SSCGR_INCSTEP_MASK, incstep) |
|
||||
FIELD_PREP(STM32F4_RCC_SSCGR_MODPER_MASK, modeper);
|
||||
|
||||
if (ssc->mod_type)
|
||||
sscgr |= STM32F4_RCC_SSCGR_SPREADSEL;
|
||||
|
||||
writel(sscgr, base + STM32F4_RCC_SSCGR);
|
||||
}
|
||||
|
||||
static int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
|
@ -673,9 +730,13 @@ static int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
n = rate / parent_rate;
|
||||
|
||||
val = readl(base + pll->offset) & ~(0x1ff << 6);
|
||||
val = readl(base + pll->offset) & ~STM32F4_RCC_PLLCFGR_N_MASK;
|
||||
val |= FIELD_PREP(STM32F4_RCC_PLLCFGR_N_MASK, n);
|
||||
|
||||
writel(val | ((n & 0x1ff) << 6), base + pll->offset);
|
||||
writel(val, base + pll->offset);
|
||||
|
||||
if (pll->ssc_enable)
|
||||
stm32f4_pll_set_ssc(hw, parent_rate, n);
|
||||
|
||||
if (pll_state)
|
||||
stm32f4_pll_enable(hw);
|
||||
|
@ -782,6 +843,84 @@ static struct clk_hw *clk_register_pll_div(const char *name,
|
|||
return hw;
|
||||
}
|
||||
|
||||
static int __init stm32f4_pll_init_ssc(struct clk_hw *hw,
|
||||
const struct stm32f4_pll_ssc *conf)
|
||||
{
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
struct stm32f4_pll *pll = to_stm32f4_pll(gate);
|
||||
struct clk_hw *parent;
|
||||
unsigned long parent_rate;
|
||||
int pll_state;
|
||||
unsigned long n, val;
|
||||
|
||||
parent = clk_hw_get_parent(hw);
|
||||
if (!parent) {
|
||||
pr_err("%s: failed to get clock parent\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
parent_rate = clk_hw_get_rate(parent);
|
||||
|
||||
pll->ssc_enable = true;
|
||||
memcpy(&pll->ssc_conf, conf, sizeof(pll->ssc_conf));
|
||||
|
||||
pll_state = stm32f4_pll_is_enabled(hw);
|
||||
|
||||
if (pll_state)
|
||||
stm32f4_pll_disable(hw);
|
||||
|
||||
val = readl(base + pll->offset);
|
||||
n = FIELD_GET(STM32F4_RCC_PLLCFGR_N_MASK, val);
|
||||
|
||||
pr_debug("%s: pll: %s, parent: %s, parent-rate: %lu, n: %lu\n",
|
||||
__func__, clk_hw_get_name(hw), clk_hw_get_name(parent),
|
||||
parent_rate, n);
|
||||
|
||||
stm32f4_pll_set_ssc(hw, parent_rate, n);
|
||||
|
||||
if (pll_state)
|
||||
stm32f4_pll_enable(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init stm32f4_pll_ssc_parse_dt(struct device_node *np,
|
||||
struct stm32f4_pll_ssc *conf)
|
||||
{
|
||||
int ret;
|
||||
const char *s;
|
||||
|
||||
if (!conf)
|
||||
return -EINVAL;
|
||||
|
||||
ret = of_property_read_u32(np, "st,ssc-modfreq-hz", &conf->mod_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = of_property_read_u32(np, "st,ssc-moddepth-permyriad",
|
||||
&conf->mod_depth);
|
||||
if (ret) {
|
||||
pr_err("%pOF: missing st,ssc-moddepth-permyriad\n", np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = fwnode_property_match_property_string(of_fwnode_handle(np),
|
||||
"st,ssc-modmethod",
|
||||
stm32f4_ssc_mod_methods,
|
||||
ARRAY_SIZE(stm32f4_ssc_mod_methods));
|
||||
if (ret < 0) {
|
||||
pr_err("%pOF: failed to get st,ssc-modmethod\n", np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
conf->mod_type = ret;
|
||||
|
||||
pr_debug("%pOF: SSCG settings: mod_freq: %d, mod_depth: %d mod_method: %s [%d]\n",
|
||||
np, conf->mod_freq, conf->mod_depth, s, conf->mod_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc,
|
||||
const struct stm32f4_pll_data *data, spinlock_t *lock)
|
||||
{
|
||||
|
@ -1689,7 +1828,8 @@ static void __init stm32f4_rcc_init(struct device_node *np)
|
|||
const struct of_device_id *match;
|
||||
const struct stm32f4_clk_data *data;
|
||||
unsigned long pllm;
|
||||
struct clk_hw *pll_src_hw;
|
||||
struct clk_hw *pll_src_hw, *pll_vco_hw;
|
||||
struct stm32f4_pll_ssc ssc_conf;
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
|
@ -1748,8 +1888,8 @@ static void __init stm32f4_rcc_init(struct device_node *np)
|
|||
clk_hw_register_fixed_factor(NULL, "vco_in", pll_src,
|
||||
0, 1, pllm);
|
||||
|
||||
stm32f4_rcc_register_pll("vco_in", &data->pll_data[0],
|
||||
&stm32f4_clk_lock);
|
||||
pll_vco_hw = stm32f4_rcc_register_pll("vco_in", &data->pll_data[0],
|
||||
&stm32f4_clk_lock);
|
||||
|
||||
clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in",
|
||||
&data->pll_data[1], &stm32f4_clk_lock);
|
||||
|
@ -1894,6 +2034,9 @@ static void __init stm32f4_rcc_init(struct device_node *np)
|
|||
|
||||
of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL);
|
||||
|
||||
if (!stm32f4_pll_ssc_parse_dt(np, &ssc_conf))
|
||||
stm32f4_pll_init_ssc(pll_vco_hw, &ssc_conf);
|
||||
|
||||
return;
|
||||
fail:
|
||||
kfree(clks);
|
||||
|
|
|
@ -78,9 +78,6 @@
|
|||
#define VC3_PLL1_VCO_MIN 300000000UL
|
||||
#define VC3_PLL1_VCO_MAX 600000000UL
|
||||
|
||||
#define VC3_PLL2_VCO_MIN 400000000UL
|
||||
#define VC3_PLL2_VCO_MAX 1200000000UL
|
||||
|
||||
#define VC3_PLL3_VCO_MIN 300000000UL
|
||||
#define VC3_PLL3_VCO_MAX 800000000UL
|
||||
|
||||
|
@ -147,9 +144,13 @@ struct vc3_pfd_data {
|
|||
u8 mdiv2_bitmsk;
|
||||
};
|
||||
|
||||
struct vc3_vco {
|
||||
unsigned long min;
|
||||
unsigned long max;
|
||||
};
|
||||
|
||||
struct vc3_pll_data {
|
||||
unsigned long vco_min;
|
||||
unsigned long vco_max;
|
||||
struct vc3_vco vco;
|
||||
u8 num;
|
||||
u8 int_div_msb_offs;
|
||||
u8 int_div_lsb_offs;
|
||||
|
@ -166,12 +167,17 @@ struct vc3_div_data {
|
|||
struct vc3_hw_data {
|
||||
struct clk_hw hw;
|
||||
struct regmap *regmap;
|
||||
const void *data;
|
||||
void *data;
|
||||
|
||||
u32 div_int;
|
||||
u32 div_frc;
|
||||
};
|
||||
|
||||
struct vc3_hw_cfg {
|
||||
struct vc3_vco pll2_vco;
|
||||
u32 se2_clk_sel_msk;
|
||||
};
|
||||
|
||||
static const struct clk_div_table div1_divs[] = {
|
||||
{ .val = 0, .div = 1, }, { .val = 1, .div = 4, },
|
||||
{ .val = 2, .div = 5, }, { .val = 3, .div = 6, },
|
||||
|
@ -386,10 +392,10 @@ static long vc3_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
const struct vc3_pll_data *pll = vc3->data;
|
||||
u64 div_frc;
|
||||
|
||||
if (rate < pll->vco_min)
|
||||
rate = pll->vco_min;
|
||||
if (rate > pll->vco_max)
|
||||
rate = pll->vco_max;
|
||||
if (rate < pll->vco.min)
|
||||
rate = pll->vco.min;
|
||||
if (rate > pll->vco.max)
|
||||
rate = pll->vco.max;
|
||||
|
||||
vc3->div_int = rate / *parent_rate;
|
||||
|
||||
|
@ -680,8 +686,10 @@ static struct vc3_hw_data clk_pll[] = {
|
|||
.num = VC3_PLL1,
|
||||
.int_div_msb_offs = VC3_PLL1_LOOP_FILTER_N_DIV_MSB,
|
||||
.int_div_lsb_offs = VC3_PLL1_VCO_N_DIVIDER,
|
||||
.vco_min = VC3_PLL1_VCO_MIN,
|
||||
.vco_max = VC3_PLL1_VCO_MAX
|
||||
.vco = {
|
||||
.min = VC3_PLL1_VCO_MIN,
|
||||
.max = VC3_PLL1_VCO_MAX
|
||||
}
|
||||
},
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "pll1",
|
||||
|
@ -698,8 +706,6 @@ static struct vc3_hw_data clk_pll[] = {
|
|||
.num = VC3_PLL2,
|
||||
.int_div_msb_offs = VC3_PLL2_FB_INT_DIV_MSB,
|
||||
.int_div_lsb_offs = VC3_PLL2_FB_INT_DIV_LSB,
|
||||
.vco_min = VC3_PLL2_VCO_MIN,
|
||||
.vco_max = VC3_PLL2_VCO_MAX
|
||||
},
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "pll2",
|
||||
|
@ -716,8 +722,10 @@ static struct vc3_hw_data clk_pll[] = {
|
|||
.num = VC3_PLL3,
|
||||
.int_div_msb_offs = VC3_PLL3_LOOP_FILTER_N_DIV_MSB,
|
||||
.int_div_lsb_offs = VC3_PLL3_N_DIVIDER,
|
||||
.vco_min = VC3_PLL3_VCO_MIN,
|
||||
.vco_max = VC3_PLL3_VCO_MAX
|
||||
.vco = {
|
||||
.min = VC3_PLL3_VCO_MIN,
|
||||
.max = VC3_PLL3_VCO_MAX
|
||||
}
|
||||
},
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "pll3",
|
||||
|
@ -901,7 +909,6 @@ static struct vc3_hw_data clk_mux[] = {
|
|||
[VC3_SE2_MUX] = {
|
||||
.data = &(struct vc3_clk_data) {
|
||||
.offs = VC3_SE2_CTRL_REG0,
|
||||
.bitmsk = VC3_SE2_CTRL_REG0_SE2_CLK_SEL
|
||||
},
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "se2_mux",
|
||||
|
@ -982,6 +989,7 @@ static int vc3_probe(struct i2c_client *client)
|
|||
{
|
||||
struct device *dev = &client->dev;
|
||||
u8 settings[NUM_CONFIG_REGISTERS];
|
||||
const struct vc3_hw_cfg *data;
|
||||
struct regmap *regmap;
|
||||
const char *name;
|
||||
int ret, i;
|
||||
|
@ -1029,9 +1037,16 @@ static int vc3_probe(struct i2c_client *client)
|
|||
clk_pfd[i].hw.init->name);
|
||||
}
|
||||
|
||||
data = i2c_get_match_data(client);
|
||||
|
||||
/* Register pll's */
|
||||
for (i = 0; i < ARRAY_SIZE(clk_pll); i++) {
|
||||
clk_pll[i].regmap = regmap;
|
||||
if (i == VC3_PLL2) {
|
||||
struct vc3_pll_data *pll_data = clk_pll[i].data;
|
||||
|
||||
pll_data->vco = data->pll2_vco;
|
||||
}
|
||||
ret = devm_clk_hw_register(dev, &clk_pll[i].hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "%s failed\n",
|
||||
|
@ -1059,6 +1074,11 @@ static int vc3_probe(struct i2c_client *client)
|
|||
/* Register clk muxes */
|
||||
for (i = 0; i < ARRAY_SIZE(clk_mux); i++) {
|
||||
clk_mux[i].regmap = regmap;
|
||||
if (i == VC3_SE2_MUX) {
|
||||
struct vc3_clk_data *clk_data = clk_mux[i].data;
|
||||
|
||||
clk_data->bitmsk = data->se2_clk_sel_msk;
|
||||
}
|
||||
ret = devm_clk_hw_register(dev, &clk_mux[i].hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "%s failed\n",
|
||||
|
@ -1108,8 +1128,19 @@ static int vc3_probe(struct i2c_client *client)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static const struct vc3_hw_cfg vc3_5p = {
|
||||
.pll2_vco = { .min = 400000000UL, .max = 1200000000UL },
|
||||
.se2_clk_sel_msk = BIT(6),
|
||||
};
|
||||
|
||||
static const struct vc3_hw_cfg vc3_5l = {
|
||||
.pll2_vco = { .min = 30000000UL, .max = 130000000UL },
|
||||
.se2_clk_sel_msk = BIT(0),
|
||||
};
|
||||
|
||||
static const struct of_device_id dev_ids[] = {
|
||||
{ .compatible = "renesas,5p35023" },
|
||||
{ .compatible = "renesas,5p35023", .data = &vc3_5p },
|
||||
{ .compatible = "renesas,5l35023", .data = &vc3_5l },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, dev_ids);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/clkdev.h>
|
||||
|
@ -520,8 +521,7 @@ static int xgene_clk_is_enabled(struct clk_hw *hw)
|
|||
data = xgene_clk_read(pclk->param.csr_reg +
|
||||
pclk->param.reg_clk_offset);
|
||||
pr_debug("%s clock is %s\n", clk_hw_get_name(hw),
|
||||
data & pclk->param.reg_clk_mask ? "enabled" :
|
||||
"disabled");
|
||||
str_enabled_disabled(data & pclk->param.reg_clk_mask));
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -5385,8 +5385,10 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index)
|
|||
count++;
|
||||
}
|
||||
/* We went off the end of 'clock-indices' without finding it */
|
||||
if (of_property_present(clkspec.np, "clock-indices") && !found)
|
||||
if (of_property_present(clkspec.np, "clock-indices") && !found) {
|
||||
of_node_put(clkspec.np);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (of_property_read_string_index(clkspec.np, "clock-output-names",
|
||||
index,
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_data/clk-davinci-pll.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -840,27 +839,6 @@ int of_davinci_pll_init(struct device *dev, struct device_node *node,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct davinci_pll_platform_data *davinci_pll_get_pdata(struct device *dev)
|
||||
{
|
||||
struct davinci_pll_platform_data *pdata = dev_get_platdata(dev);
|
||||
|
||||
/*
|
||||
* Platform data is optional, so allocate a new struct if one was not
|
||||
* provided. For device tree, this will always be the case.
|
||||
*/
|
||||
if (!pdata)
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
|
||||
/* for device tree, we need to fill in the struct */
|
||||
if (dev->of_node)
|
||||
pdata->cfgchip =
|
||||
syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
|
||||
|
||||
return pdata;
|
||||
}
|
||||
|
||||
/* needed in early boot for clocksource/clockevent */
|
||||
#ifdef CONFIG_ARCH_DAVINCI_DA850
|
||||
CLK_OF_DECLARE(da850_pll0, "ti,da850-pll0", of_da850_pll0_init);
|
||||
|
@ -890,8 +868,8 @@ typedef int (*davinci_pll_init)(struct device *dev, void __iomem *base,
|
|||
static int davinci_pll_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct davinci_pll_platform_data *pdata;
|
||||
davinci_pll_init pll_init = NULL;
|
||||
struct regmap *cfgchip;
|
||||
void __iomem *base;
|
||||
|
||||
pll_init = device_get_match_data(dev);
|
||||
|
@ -903,17 +881,13 @@ static int davinci_pll_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
pdata = davinci_pll_get_pdata(dev);
|
||||
if (!pdata) {
|
||||
dev_err(dev, "missing platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
cfgchip = syscon_regmap_lookup_by_compatible("ti,da830-cfgchip");
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
return pll_init(dev, base, pdata->cfgchip);
|
||||
return pll_init(dev, base, cfgchip);
|
||||
}
|
||||
|
||||
static struct platform_driver davinci_pll_driver = {
|
||||
|
|
|
@ -399,8 +399,9 @@ static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_r
|
|||
|
||||
static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
|
||||
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
|
||||
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
|
||||
"arm_pll_out", "sys_pll1_out", "sys_pll2_out",
|
||||
"sys_pll3_out", "dummy", "dummy", "osc_24m",
|
||||
"dummy", "osc_32k"};
|
||||
|
||||
static struct clk_hw **hws;
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "clk.h"
|
||||
|
||||
#define IMX93_CLK_END 207
|
||||
#define IMX93_CLK_END 208
|
||||
|
||||
#define PLAT_IMX93 BIT(0)
|
||||
#define PLAT_IMX91 BIT(1)
|
||||
|
@ -38,6 +38,7 @@ static u32 share_count_sai2;
|
|||
static u32 share_count_sai3;
|
||||
static u32 share_count_mub;
|
||||
static u32 share_count_pdm;
|
||||
static u32 share_count_spdif;
|
||||
|
||||
static const char * const a55_core_sels[] = {"a55_alt", "arm_pll"};
|
||||
static const char *parent_names[MAX_SEL][4] = {
|
||||
|
@ -70,8 +71,8 @@ static const struct imx93_clk_root {
|
|||
{ IMX93_CLK_WAKEUP_AXI, "wakeup_axi_root", 0x0380, FAST_SEL, CLK_IS_CRITICAL },
|
||||
{ IMX93_CLK_SWO_TRACE, "swo_trace_root", 0x0400, LOW_SPEED_IO_SEL, },
|
||||
{ IMX93_CLK_M33_SYSTICK, "m33_systick_root", 0x0480, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
|
||||
{ IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, },
|
||||
{ IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, },
|
||||
{ IMX93_CLK_FLEXIO1, "flexio1_root", 0x0500, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
|
||||
{ IMX93_CLK_FLEXIO2, "flexio2_root", 0x0580, LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
|
||||
{ IMX93_CLK_LPTMR1, "lptmr1_root", 0x0700, LOW_SPEED_IO_SEL, },
|
||||
{ IMX93_CLK_LPTMR2, "lptmr2_root", 0x0780, LOW_SPEED_IO_SEL, },
|
||||
{ IMX93_CLK_TPM2, "tpm2_root", 0x0880, TPM_SEL, },
|
||||
|
@ -177,10 +178,10 @@ static const struct imx93_clk_ccgr {
|
|||
{ IMX93_CLK_WDOG5_GATE, "wdog5", "osc_24m", 0x8400, },
|
||||
{ IMX93_CLK_SEMA1_GATE, "sema1", "bus_aon_root", 0x8440, },
|
||||
{ IMX93_CLK_SEMA2_GATE, "sema2", "bus_wakeup_root", 0x8480, },
|
||||
{ IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED },
|
||||
{ IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED },
|
||||
{ IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub },
|
||||
{ IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub },
|
||||
{ IMX93_CLK_MU1_A_GATE, "mu1_a", "bus_aon_root", 0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 },
|
||||
{ IMX93_CLK_MU2_A_GATE, "mu2_a", "bus_wakeup_root", 0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 },
|
||||
{ IMX93_CLK_MU1_B_GATE, "mu1_b", "bus_aon_root", 0x8500, 0, &share_count_mub, PLAT_IMX93 },
|
||||
{ IMX93_CLK_MU2_B_GATE, "mu2_b", "bus_wakeup_root", 0x8500, 0, &share_count_mub, PLAT_IMX93 },
|
||||
{ IMX93_CLK_EDMA1_GATE, "edma1", "m33_root", 0x8540, },
|
||||
{ IMX93_CLK_EDMA2_GATE, "edma2", "wakeup_axi_root", 0x8580, },
|
||||
{ IMX93_CLK_FLEXSPI1_GATE, "flexspi1", "flexspi1_root", 0x8640, },
|
||||
|
@ -188,8 +189,8 @@ static const struct imx93_clk_ccgr {
|
|||
{ IMX93_CLK_GPIO2_GATE, "gpio2", "bus_wakeup_root", 0x88c0, },
|
||||
{ IMX93_CLK_GPIO3_GATE, "gpio3", "bus_wakeup_root", 0x8900, },
|
||||
{ IMX93_CLK_GPIO4_GATE, "gpio4", "bus_wakeup_root", 0x8940, },
|
||||
{ IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, },
|
||||
{ IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, },
|
||||
{ IMX93_CLK_FLEXIO1_GATE, "flexio1", "flexio1_root", 0x8980, 0, NULL, PLAT_IMX93},
|
||||
{ IMX93_CLK_FLEXIO2_GATE, "flexio2", "flexio2_root", 0x89c0, 0, NULL, PLAT_IMX93},
|
||||
{ IMX93_CLK_LPIT1_GATE, "lpit1", "bus_aon_root", 0x8a00, },
|
||||
{ IMX93_CLK_LPIT2_GATE, "lpit2", "bus_wakeup_root", 0x8a40, },
|
||||
{ IMX93_CLK_LPTMR1_GATE, "lptmr1", "lptmr1_root", 0x8a80, },
|
||||
|
@ -238,10 +239,10 @@ static const struct imx93_clk_ccgr {
|
|||
{ IMX93_CLK_SAI3_GATE, "sai3", "sai3_root", 0x94c0, 0, &share_count_sai3},
|
||||
{ IMX93_CLK_SAI3_IPG, "sai3_ipg_clk", "bus_wakeup_root", 0x94c0, 0, &share_count_sai3},
|
||||
{ IMX93_CLK_MIPI_CSI_GATE, "mipi_csi", "media_apb_root", 0x9580, },
|
||||
{ IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, },
|
||||
{ IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, },
|
||||
{ IMX93_CLK_MIPI_DSI_GATE, "mipi_dsi", "media_apb_root", 0x95c0, 0, NULL, PLAT_IMX93 },
|
||||
{ IMX93_CLK_LVDS_GATE, "lvds", "media_ldb_root", 0x9600, 0, NULL, PLAT_IMX93 },
|
||||
{ IMX93_CLK_LCDIF_GATE, "lcdif", "media_apb_root", 0x9640, },
|
||||
{ IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, },
|
||||
{ IMX93_CLK_PXP_GATE, "pxp", "media_apb_root", 0x9680, 0, NULL, PLAT_IMX93 },
|
||||
{ IMX93_CLK_ISI_GATE, "isi", "media_apb_root", 0x96c0, },
|
||||
{ IMX93_CLK_NIC_MEDIA_GATE, "nic_media", "media_axi_root", 0x9700, },
|
||||
{ IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root", 0x9a00, },
|
||||
|
@ -252,12 +253,13 @@ static const struct imx93_clk_ccgr {
|
|||
{ IMX93_CLK_MQS1_GATE, "mqs1", "sai1_root", 0x9b00, },
|
||||
{ IMX93_CLK_MQS2_GATE, "mqs2", "sai3_root", 0x9b40, },
|
||||
{ IMX93_CLK_AUD_XCVR_GATE, "aud_xcvr", "audio_xcvr_root", 0x9b80, },
|
||||
{ IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, },
|
||||
{ IMX93_CLK_SPDIF_IPG, "spdif_ipg_clk", "bus_wakeup_root", 0x9c00, 0, &share_count_spdif},
|
||||
{ IMX93_CLK_SPDIF_GATE, "spdif", "spdif_root", 0x9c00, 0, &share_count_spdif},
|
||||
{ IMX93_CLK_HSIO_32K_GATE, "hsio_32k", "osc_32k", 0x9dc0, },
|
||||
{ IMX93_CLK_ENET1_GATE, "enet1", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX93, },
|
||||
{ IMX93_CLK_ENET_QOS_GATE, "enet_qos", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX93, },
|
||||
{ IMX91_CLK_ENET2_REGULAR_GATE, "enet2_regular", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX91, },
|
||||
{ IMX91_CLK_ENET1_QOS_TSN_GATE, "enet1_qos_tsn", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX91, },
|
||||
{ IMX91_CLK_ENET2_REGULAR_GATE, "enet2_regular", "wakeup_axi_root", 0x9e00, 0, NULL, PLAT_IMX91, },
|
||||
{ IMX91_CLK_ENET1_QOS_TSN_GATE, "enet1_qos_tsn", "wakeup_axi_root", 0x9e40, 0, NULL, PLAT_IMX91, },
|
||||
/* Critical because clk accessed during CPU idle */
|
||||
{ IMX93_CLK_SYS_CNT_GATE, "sys_cnt", "osc_24m", 0x9e80, CLK_IS_CRITICAL},
|
||||
{ IMX93_CLK_TSTMR1_GATE, "tstmr1", "bus_aon_root", 0x9ec0, },
|
||||
|
|
|
@ -56,7 +56,9 @@ static const struct imx_pll14xx_rate_table imx_pll1416x_tbl[] = {
|
|||
PLL_1416X_RATE(700000000U, 350, 3, 2),
|
||||
PLL_1416X_RATE(640000000U, 320, 3, 2),
|
||||
PLL_1416X_RATE(600000000U, 300, 3, 2),
|
||||
PLL_1416X_RATE(416000000U, 208, 3, 2),
|
||||
PLL_1416X_RATE(320000000U, 160, 3, 2),
|
||||
PLL_1416X_RATE(208000000U, 208, 3, 3),
|
||||
};
|
||||
|
||||
static const struct imx_pll14xx_rate_table imx_pll1443x_tbl[] = {
|
||||
|
|
|
@ -55,10 +55,16 @@ static const struct mtk_gate audio_clks[] = {
|
|||
GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
|
||||
/* AUDIO0 */
|
||||
GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
|
||||
GATE_DUMMY(CLK_AUD_LRCK_DETECT, "audio_lrck_detect_dummy"),
|
||||
GATE_DUMMY(CLK_AUD_I2S, "audio_i2c_dummy"),
|
||||
GATE_DUMMY(CLK_AUD_APLL_TUNER, "audio_apll_tuner_dummy"),
|
||||
GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
|
||||
GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21),
|
||||
GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22),
|
||||
GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23),
|
||||
GATE_DUMMY(CLK_AUD_TML, "audio_tml_dummy"),
|
||||
GATE_DUMMY(CLK_AUD_AHB_IDLE_EXT, "audio_ahb_idle_ext_dummy"),
|
||||
GATE_DUMMY(CLK_AUD_AHB_IDLE_INT, "audio_ahb_idle_int_dummy"),
|
||||
/* AUDIO1 */
|
||||
GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0),
|
||||
GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1),
|
||||
|
@ -76,10 +82,12 @@ static const struct mtk_gate audio_clks[] = {
|
|||
GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13),
|
||||
GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14),
|
||||
GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15),
|
||||
GATE_DUMMY(CLK_AUD_HDMIRX, "audio_hdmirx_dummy"),
|
||||
GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20),
|
||||
GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21),
|
||||
GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22),
|
||||
GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23),
|
||||
GATE_DUMMY(CLK_AUD_AFE_PCMIF, "audio_afe_pcmif_dummy"),
|
||||
GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25),
|
||||
/* AUDIO2 */
|
||||
GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0),
|
||||
|
@ -100,6 +108,8 @@ static const struct mtk_gate audio_clks[] = {
|
|||
GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15),
|
||||
GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16),
|
||||
/* AUDIO3 */
|
||||
GATE_DUMMY(CLK_AUD_DMIC1, "audio_dmic1_dummy"),
|
||||
GATE_DUMMY(CLK_AUD_DMIC2, "audio_dmic2_dummy"),
|
||||
GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2),
|
||||
GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3),
|
||||
GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4),
|
||||
|
|
|
@ -31,6 +31,7 @@ static const struct mtk_gate_regs bdp1_cg_regs = {
|
|||
GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
||||
|
||||
static const struct mtk_gate bdp_clks[] = {
|
||||
GATE_DUMMY(CLK_DUMMY, "bdp_dummy"),
|
||||
GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
|
||||
GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
|
||||
GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
|
||||
|
|
|
@ -22,6 +22,7 @@ static const struct mtk_gate_regs img_cg_regs = {
|
|||
GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
|
||||
|
||||
static const struct mtk_gate img_clks[] = {
|
||||
GATE_DUMMY(CLK_DUMMY, "img_dummy"),
|
||||
GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
|
||||
GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
|
||||
GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),
|
||||
|
|
|
@ -31,6 +31,7 @@ static const struct mtk_gate_regs disp1_cg_regs = {
|
|||
GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
|
||||
|
||||
static const struct mtk_gate mm_clks[] = {
|
||||
GATE_DUMMY(CLK_DUMMY, "mm_dummy"),
|
||||
GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
|
||||
GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
|
||||
GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2),
|
||||
|
|
|
@ -31,6 +31,7 @@ static const struct mtk_gate_regs vdec1_cg_regs = {
|
|||
GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
|
||||
|
||||
static const struct mtk_gate vdec_clks[] = {
|
||||
GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
|
||||
GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
|
||||
GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
|
||||
};
|
||||
|
|
|
@ -96,8 +96,8 @@ static int pxa1908_apbc_probe(struct platform_device *pdev)
|
|||
struct pxa1908_clk_unit *pxa_unit;
|
||||
|
||||
pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL);
|
||||
if (IS_ERR(pxa_unit))
|
||||
return PTR_ERR(pxa_unit);
|
||||
if (!pxa_unit)
|
||||
return -ENOMEM;
|
||||
|
||||
pxa_unit->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pxa_unit->base))
|
||||
|
|
|
@ -48,8 +48,8 @@ static int pxa1908_apbcp_probe(struct platform_device *pdev)
|
|||
struct pxa1908_clk_unit *pxa_unit;
|
||||
|
||||
pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL);
|
||||
if (IS_ERR(pxa_unit))
|
||||
return PTR_ERR(pxa_unit);
|
||||
if (!pxa_unit)
|
||||
return -ENOMEM;
|
||||
|
||||
pxa_unit->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pxa_unit->base))
|
||||
|
|
|
@ -78,8 +78,8 @@ static int pxa1908_mpmu_probe(struct platform_device *pdev)
|
|||
struct pxa1908_clk_unit *pxa_unit;
|
||||
|
||||
pxa_unit = devm_kzalloc(&pdev->dev, sizeof(*pxa_unit), GFP_KERNEL);
|
||||
if (IS_ERR(pxa_unit))
|
||||
return PTR_ERR(pxa_unit);
|
||||
if (!pxa_unit)
|
||||
return -ENOMEM;
|
||||
|
||||
pxa_unit->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pxa_unit->base))
|
||||
|
|
|
@ -106,10 +106,10 @@ struct generic_pm_domain *mmp_pm_domain_register(const char *name,
|
|||
pm_domain->flags = flags;
|
||||
pm_domain->lock = lock;
|
||||
|
||||
pm_genpd_init(&pm_domain->genpd, NULL, true);
|
||||
pm_domain->genpd.name = name;
|
||||
pm_domain->genpd.power_on = mmp_pm_domain_power_on;
|
||||
pm_domain->genpd.power_off = mmp_pm_domain_power_off;
|
||||
pm_genpd_init(&pm_domain->genpd, NULL, true);
|
||||
|
||||
return &pm_domain->genpd;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,15 @@ config CLK_X1E80100_TCSRCC
|
|||
Support for the TCSR clock controller on X1E80100 devices.
|
||||
Say Y if you want to use peripheral devices such as SD/UFS.
|
||||
|
||||
config CLK_X1P42100_GPUCC
|
||||
tristate "X1P42100 Graphics Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select CLK_X1E80100_GCC
|
||||
help
|
||||
Support for the graphics clock controller on X1P42100 devices.
|
||||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics.
|
||||
|
||||
config CLK_QCM2290_GPUCC
|
||||
tristate "QCM2290 Graphics Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
@ -190,6 +199,15 @@ config IPQ_APSS_6018
|
|||
Say Y if you want to support CPU frequency scaling on
|
||||
ipq based devices.
|
||||
|
||||
config IPQ_CMN_PLL
|
||||
tristate "IPQ CMN PLL Clock Controller"
|
||||
help
|
||||
Support for CMN PLL clock controller on IPQ platform. The
|
||||
CMN PLL consumes the AHB/SYS clocks from GCC and supplies
|
||||
the output clocks to the networking hardware and GCC blocks.
|
||||
Say Y or M if you want to support CMN PLL clock on the IPQ
|
||||
based devices.
|
||||
|
||||
config IPQ_GCC_4019
|
||||
tristate "IPQ4019 Global Clock Controller"
|
||||
help
|
||||
|
@ -495,6 +513,15 @@ config QCS_GCC_8300
|
|||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config QCS_GCC_615
|
||||
tristate "QCS615 Global Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on QCS615 devices.
|
||||
Say Y if you want to use multimedia devices or peripheral
|
||||
devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
|
||||
|
||||
config SC_CAMCC_7180
|
||||
tristate "SC7180 Camera Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
@ -1022,6 +1049,17 @@ config SM_DISPCC_8550
|
|||
Say Y if you want to support display devices and functionality such as
|
||||
splash screen.
|
||||
|
||||
config SM_DISPCC_8750
|
||||
tristate "SM8750 Display Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
depends on SM_GCC_8750
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the display clock controller on Qualcomm Technologies, Inc
|
||||
SM8750 devices.
|
||||
Say Y if you want to support display devices and functionality such as
|
||||
splash screen.
|
||||
|
||||
config SM_GCC_4450
|
||||
tristate "SM4450 Global Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
@ -1079,6 +1117,7 @@ config SM_GCC_7150
|
|||
config SM_GCC_8150
|
||||
tristate "SM8150 Global Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on SM8150 devices.
|
||||
Say Y if you want to use peripheral devices such as UART,
|
||||
|
@ -1130,6 +1169,15 @@ config SM_GCC_8650
|
|||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config SM_GCC_8750
|
||||
tristate "SM8750 Global Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on SM8750 devices.
|
||||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config SM_GPUCC_4450
|
||||
tristate "SM4450 Graphics Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
@ -1230,6 +1278,15 @@ config SM_GPUCC_8650
|
|||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics.
|
||||
|
||||
config SM_LPASSCC_6115
|
||||
tristate "SM6115 Low Power Audio Subsystem (LPASS) Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select SM_GCC_6115
|
||||
help
|
||||
Support for the LPASS clock controller on SM6115 devices.
|
||||
Say Y if you want to toggle LPASS-adjacent resets within
|
||||
this clock controller to reset the LPASS subsystem.
|
||||
|
||||
config SM_TCSRCC_8550
|
||||
tristate "SM8550 TCSR Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
@ -1246,6 +1303,14 @@ config SM_TCSRCC_8650
|
|||
Support for the TCSR clock controller on SM8650 devices.
|
||||
Say Y if you want to use peripheral devices such as SD/UFS.
|
||||
|
||||
config SM_TCSRCC_8750
|
||||
tristate "SM8750 TCSR Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the TCSR clock controller on SM8750 devices.
|
||||
Say Y if you want to use peripheral devices such as UFS/USB/PCIe.
|
||||
|
||||
config SA_VIDEOCC_8775P
|
||||
tristate "SA8775P Video Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
|
|
@ -26,9 +26,11 @@ obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
|
|||
obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
|
||||
obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o
|
||||
obj-$(CONFIG_CLK_X1E80100_TCSRCC) += tcsrcc-x1e80100.o
|
||||
obj-$(CONFIG_CLK_X1P42100_GPUCC) += gpucc-x1p42100.o
|
||||
obj-$(CONFIG_CLK_QCM2290_GPUCC) += gpucc-qcm2290.o
|
||||
obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
|
||||
obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
|
||||
obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
|
||||
obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
|
||||
|
@ -71,6 +73,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
|
|||
obj-$(CONFIG_QCM_GCC_2290) += gcc-qcm2290.o
|
||||
obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o
|
||||
obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
|
||||
obj-$(CONFIG_QCS_GCC_615) += gcc-qcs615.o
|
||||
obj-$(CONFIG_QCS_GCC_8300) += gcc-qcs8300.o
|
||||
obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
|
||||
obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
|
||||
|
@ -131,6 +134,7 @@ obj-$(CONFIG_SM_DISPCC_7150) += dispcc-sm7150.o
|
|||
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
|
||||
obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
|
||||
obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
|
||||
obj-$(CONFIG_SM_DISPCC_8750) += dispcc-sm8750.o
|
||||
obj-$(CONFIG_SM_GCC_4450) += gcc-sm4450.o
|
||||
obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
|
||||
obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
|
||||
|
@ -143,6 +147,7 @@ obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
|
|||
obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o
|
||||
obj-$(CONFIG_SM_GCC_8550) += gcc-sm8550.o
|
||||
obj-$(CONFIG_SM_GCC_8650) += gcc-sm8650.o
|
||||
obj-$(CONFIG_SM_GCC_8750) += gcc-sm8750.o
|
||||
obj-$(CONFIG_SM_GPUCC_4450) += gpucc-sm4450.o
|
||||
obj-$(CONFIG_SM_GPUCC_6115) += gpucc-sm6115.o
|
||||
obj-$(CONFIG_SM_GPUCC_6125) += gpucc-sm6125.o
|
||||
|
@ -154,8 +159,10 @@ obj-$(CONFIG_SM_GPUCC_8350) += gpucc-sm8350.o
|
|||
obj-$(CONFIG_SM_GPUCC_8450) += gpucc-sm8450.o
|
||||
obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o
|
||||
obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o
|
||||
obj-$(CONFIG_SM_LPASSCC_6115) += lpasscc-sm6115.o
|
||||
obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o
|
||||
obj-$(CONFIG_SM_TCSRCC_8650) += tcsrcc-sm8650.o
|
||||
obj-$(CONFIG_SM_TCSRCC_8750) += tcsrcc-sm8750.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_7150) += videocc-sm7150.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o
|
||||
|
|
|
@ -73,20 +73,19 @@ static const struct alpha_pll_config ipq5018_pll_config = {
|
|||
.main_output_mask = BIT(0),
|
||||
.aux_output_mask = BIT(1),
|
||||
.early_output_mask = BIT(3),
|
||||
.alpha_en_mask = BIT(24),
|
||||
.status_val = 0x3,
|
||||
.status_mask = GENMASK(10, 8),
|
||||
.lock_det = BIT(2),
|
||||
.test_ctl_hi_val = 0x00400003,
|
||||
};
|
||||
|
||||
/* 1.080 GHz configuration */
|
||||
static const struct alpha_pll_config ipq5332_pll_config = {
|
||||
.l = 0x2d,
|
||||
.config_ctl_val = 0x4001075b,
|
||||
.main_output_mask = BIT(0),
|
||||
.aux_output_mask = BIT(1),
|
||||
.early_output_mask = BIT(3),
|
||||
.alpha_en_mask = BIT(24),
|
||||
.status_val = 0x3,
|
||||
.status_mask = GENMASK(10, 8),
|
||||
.lock_det = BIT(2),
|
||||
|
|
|
@ -2212,6 +2212,8 @@ static struct clk_branch cam_cc_sfe_0_fast_ahb_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct gdsc cam_cc_titan_top_gdsc;
|
||||
|
||||
static struct gdsc cam_cc_bps_gdsc = {
|
||||
.gdscr = 0x10004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
|
@ -2221,6 +2223,7 @@ static struct gdsc cam_cc_bps_gdsc = {
|
|||
.name = "cam_cc_bps_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -2233,6 +2236,7 @@ static struct gdsc cam_cc_ife_0_gdsc = {
|
|||
.name = "cam_cc_ife_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -2245,6 +2249,7 @@ static struct gdsc cam_cc_ife_1_gdsc = {
|
|||
.name = "cam_cc_ife_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -2257,6 +2262,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = {
|
|||
.name = "cam_cc_ipe_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -2269,6 +2275,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = {
|
|||
.name = "cam_cc_sfe_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#define PLL_TEST_CTL_U(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
|
||||
#define PLL_TEST_CTL_U1(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
|
||||
#define PLL_TEST_CTL_U2(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U2])
|
||||
#define PLL_TEST_CTL_U3(p) ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U3])
|
||||
#define PLL_STATUS(p) ((p)->offset + (p)->regs[PLL_OFF_STATUS])
|
||||
#define PLL_OPMODE(p) ((p)->offset + (p)->regs[PLL_OFF_OPMODE])
|
||||
#define PLL_FRAC(p) ((p)->offset + (p)->regs[PLL_OFF_FRAC])
|
||||
|
@ -197,6 +198,37 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
|
|||
[PLL_OFF_TEST_CTL_U1] = 0x34,
|
||||
[PLL_OFF_TEST_CTL_U2] = 0x38,
|
||||
},
|
||||
[CLK_ALPHA_PLL_TYPE_PONGO_ELU] = {
|
||||
[PLL_OFF_OPMODE] = 0x04,
|
||||
[PLL_OFF_STATE] = 0x08,
|
||||
[PLL_OFF_STATUS] = 0x0c,
|
||||
[PLL_OFF_L_VAL] = 0x10,
|
||||
[PLL_OFF_USER_CTL] = 0x14,
|
||||
[PLL_OFF_USER_CTL_U] = 0x18,
|
||||
[PLL_OFF_CONFIG_CTL] = 0x1c,
|
||||
[PLL_OFF_CONFIG_CTL_U] = 0x20,
|
||||
[PLL_OFF_CONFIG_CTL_U1] = 0x24,
|
||||
[PLL_OFF_CONFIG_CTL_U2] = 0x28,
|
||||
[PLL_OFF_TEST_CTL] = 0x2c,
|
||||
[PLL_OFF_TEST_CTL_U] = 0x30,
|
||||
[PLL_OFF_TEST_CTL_U1] = 0x34,
|
||||
[PLL_OFF_TEST_CTL_U2] = 0x38,
|
||||
[PLL_OFF_TEST_CTL_U3] = 0x3c,
|
||||
},
|
||||
[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU] = {
|
||||
[PLL_OFF_OPMODE] = 0x04,
|
||||
[PLL_OFF_STATE] = 0x08,
|
||||
[PLL_OFF_STATUS] = 0x0c,
|
||||
[PLL_OFF_L_VAL] = 0x10,
|
||||
[PLL_OFF_ALPHA_VAL] = 0x14,
|
||||
[PLL_OFF_USER_CTL] = 0x18,
|
||||
[PLL_OFF_USER_CTL_U] = 0x1c,
|
||||
[PLL_OFF_CONFIG_CTL] = 0x20,
|
||||
[PLL_OFF_CONFIG_CTL_U] = 0x24,
|
||||
[PLL_OFF_CONFIG_CTL_U1] = 0x28,
|
||||
[PLL_OFF_TEST_CTL] = 0x2c,
|
||||
[PLL_OFF_TEST_CTL_U] = 0x30,
|
||||
},
|
||||
[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO] = {
|
||||
[PLL_OFF_OPMODE] = 0x04,
|
||||
[PLL_OFF_STATUS] = 0x0c,
|
||||
|
@ -323,6 +355,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
|
|||
#define LUCID_EVO_PLL_CAL_L_VAL_SHIFT 16
|
||||
#define LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT 24
|
||||
|
||||
/* PONGO ELU PLL specific setting and offsets */
|
||||
#define PONGO_PLL_OUT_MASK GENMASK(1, 0)
|
||||
#define PONGO_PLL_L_VAL_MASK GENMASK(11, 0)
|
||||
#define PONGO_XO_PRESENT BIT(10)
|
||||
#define PONGO_CLOCK_SELECT BIT(12)
|
||||
|
||||
/* ZONDA PLL specific */
|
||||
#define ZONDA_PLL_OUT_MASK 0xf
|
||||
#define ZONDA_STAY_IN_CFA BIT(16)
|
||||
|
@ -352,7 +390,8 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (count = 200; count > 0; count--) {
|
||||
/* Pongo PLLs using a 32KHz reference can take upwards of 1500us to lock. */
|
||||
for (count = 1500; count > 0; count--) {
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -432,6 +471,8 @@ void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
|||
mask |= config->pre_div_mask;
|
||||
mask |= config->post_div_mask;
|
||||
mask |= config->vco_mask;
|
||||
mask |= config->alpha_en_mask;
|
||||
mask |= config->alpha_mode_mask;
|
||||
|
||||
regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
|
||||
|
||||
|
@ -2494,6 +2535,144 @@ const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_reset_lucid_evo_ops);
|
||||
|
||||
static int alpha_pll_pongo_elu_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
struct regmap *regmap = pll->clkr.regmap;
|
||||
int ret;
|
||||
|
||||
/* Enable PLL intially to one-time calibrate against XO. */
|
||||
regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PONGO_XO_PRESENT, PONGO_XO_PRESENT);
|
||||
|
||||
/* Set regmap for wait_for_pll() */
|
||||
pll->clkr.regmap = regmap;
|
||||
ret = wait_for_pll_enable_lock(pll);
|
||||
if (ret) {
|
||||
/* Reverse calibration - disable PLL output */
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable PLL after one-time calibration. */
|
||||
regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
|
||||
|
||||
/* Select internally generated clock. */
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PONGO_CLOCK_SELECT,
|
||||
PONGO_CLOCK_SELECT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alpha_pll_pongo_elu_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
struct regmap *regmap = pll->clkr.regmap;
|
||||
int ret;
|
||||
|
||||
/* Check if PLL is already enabled */
|
||||
if (trion_pll_is_enabled(pll, regmap))
|
||||
return 0;
|
||||
|
||||
ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set operation mode to RUN */
|
||||
regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN);
|
||||
|
||||
ret = wait_for_pll_enable_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable the global PLL outputs */
|
||||
ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Ensure that the write above goes through before returning. */
|
||||
mb();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void alpha_pll_pongo_elu_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
struct regmap *regmap = pll->clkr.regmap;
|
||||
int ret;
|
||||
|
||||
/* Disable the global PLL output */
|
||||
ret = regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* Place the PLL mode in STANDBY */
|
||||
regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
|
||||
}
|
||||
|
||||
static unsigned long alpha_pll_pongo_elu_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
struct regmap *regmap = pll->clkr.regmap;
|
||||
u32 l;
|
||||
|
||||
if (regmap_read(regmap, PLL_L_VAL(pll), &l))
|
||||
return 0;
|
||||
|
||||
l &= PONGO_PLL_L_VAL_MASK;
|
||||
|
||||
return alpha_pll_calc_rate(parent_rate, l, 0, pll_alpha_width(pll));
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_pongo_elu_ops = {
|
||||
.prepare = alpha_pll_pongo_elu_prepare,
|
||||
.enable = alpha_pll_pongo_elu_enable,
|
||||
.disable = alpha_pll_pongo_elu_disable,
|
||||
.recalc_rate = alpha_pll_pongo_elu_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_pongo_elu_ops);
|
||||
|
||||
void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll,
|
||||
struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
regmap_update_bits(regmap, PLL_USER_CTL(pll), PONGO_PLL_OUT_MASK,
|
||||
PONGO_PLL_OUT_MASK);
|
||||
|
||||
if (trion_pll_is_enabled(pll, regmap))
|
||||
return;
|
||||
|
||||
if (regmap_read(regmap, PLL_L_VAL(pll), &val))
|
||||
return;
|
||||
val &= PONGO_PLL_L_VAL_MASK;
|
||||
if (val)
|
||||
return;
|
||||
|
||||
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
|
||||
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U2(pll), config->config_ctl_hi2_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
|
||||
config->user_ctl_val | PONGO_PLL_OUT_MASK);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U3(pll), config->test_ctl_hi3_val);
|
||||
|
||||
/* Disable PLL output */
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_pongo_elu_pll_configure);
|
||||
|
||||
void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
|
|
|
@ -27,6 +27,8 @@ enum {
|
|||
CLK_ALPHA_PLL_TYPE_ZONDA_OLE,
|
||||
CLK_ALPHA_PLL_TYPE_LUCID_EVO,
|
||||
CLK_ALPHA_PLL_TYPE_LUCID_OLE,
|
||||
CLK_ALPHA_PLL_TYPE_PONGO_ELU,
|
||||
CLK_ALPHA_PLL_TYPE_TAYCAN_ELU,
|
||||
CLK_ALPHA_PLL_TYPE_RIVIAN_EVO,
|
||||
CLK_ALPHA_PLL_TYPE_DEFAULT_EVO,
|
||||
CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
|
||||
|
@ -52,6 +54,7 @@ enum {
|
|||
PLL_OFF_TEST_CTL_U,
|
||||
PLL_OFF_TEST_CTL_U1,
|
||||
PLL_OFF_TEST_CTL_U2,
|
||||
PLL_OFF_TEST_CTL_U3,
|
||||
PLL_OFF_STATE,
|
||||
PLL_OFF_STATUS,
|
||||
PLL_OFF_OPMODE,
|
||||
|
@ -137,6 +140,7 @@ struct alpha_pll_config {
|
|||
u32 test_ctl_hi_mask;
|
||||
u32 test_ctl_hi1_val;
|
||||
u32 test_ctl_hi2_val;
|
||||
u32 test_ctl_hi3_val;
|
||||
u32 main_output_mask;
|
||||
u32 aux_output_mask;
|
||||
u32 aux2_output_mask;
|
||||
|
@ -185,13 +189,17 @@ extern const struct clk_ops clk_alpha_pll_zonda_ops;
|
|||
#define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops
|
||||
|
||||
extern const struct clk_ops clk_alpha_pll_lucid_evo_ops;
|
||||
#define clk_alpha_pll_taycan_elu_ops clk_alpha_pll_lucid_evo_ops
|
||||
extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops;
|
||||
#define clk_alpha_pll_reset_lucid_ole_ops clk_alpha_pll_reset_lucid_evo_ops
|
||||
extern const struct clk_ops clk_alpha_pll_fixed_lucid_evo_ops;
|
||||
#define clk_alpha_pll_fixed_lucid_ole_ops clk_alpha_pll_fixed_lucid_evo_ops
|
||||
#define clk_alpha_pll_fixed_taycan_elu_ops clk_alpha_pll_fixed_lucid_evo_ops
|
||||
extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops;
|
||||
#define clk_alpha_pll_postdiv_lucid_ole_ops clk_alpha_pll_postdiv_lucid_evo_ops
|
||||
#define clk_alpha_pll_postdiv_taycan_elu_ops clk_alpha_pll_postdiv_lucid_evo_ops
|
||||
|
||||
extern const struct clk_ops clk_alpha_pll_pongo_elu_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
|
||||
#define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops
|
||||
|
||||
|
@ -218,6 +226,11 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma
|
|||
const struct alpha_pll_config *config);
|
||||
void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
void clk_pongo_elu_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
#define clk_taycan_elu_pll_configure(pll, regmap, config) \
|
||||
clk_lucid_evo_pll_configure(pll, regmap, config)
|
||||
|
||||
void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
void clk_stromer_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
|
|
|
@ -597,6 +597,7 @@ struct frac_entry {
|
|||
};
|
||||
|
||||
static const struct frac_entry pixel_table[] = {
|
||||
{ 1, 1 },
|
||||
{ 1, 2 },
|
||||
{ 1, 3 },
|
||||
{ 3, 16 },
|
||||
|
|
|
@ -189,6 +189,7 @@ struct clk_rcg2_gfx3d {
|
|||
container_of(to_clk_rcg2(_hw), struct clk_rcg2_gfx3d, rcg)
|
||||
|
||||
extern const struct clk_ops clk_rcg2_ops;
|
||||
extern const struct clk_ops clk_rcg2_gp_ops;
|
||||
extern const struct clk_ops clk_rcg2_floor_ops;
|
||||
extern const struct clk_ops clk_rcg2_fm_ops;
|
||||
extern const struct clk_ops clk_rcg2_mux_closest_ops;
|
||||
|
|
|
@ -8,11 +8,13 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rational.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/gcd.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -32,6 +34,7 @@
|
|||
|
||||
#define CFG_REG 0x4
|
||||
#define CFG_SRC_DIV_SHIFT 0
|
||||
#define CFG_SRC_DIV_LENGTH 8
|
||||
#define CFG_SRC_SEL_SHIFT 8
|
||||
#define CFG_SRC_SEL_MASK (0x7 << CFG_SRC_SEL_SHIFT)
|
||||
#define CFG_MODE_SHIFT 12
|
||||
|
@ -148,12 +151,32 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
|
|||
return update_config(rcg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate m/n:d rate
|
||||
/**
|
||||
* convert_to_reg_val() - Convert divisor values to hardware values.
|
||||
*
|
||||
* @f: Frequency table with pure m/n/pre_div parameters.
|
||||
*/
|
||||
static void convert_to_reg_val(struct freq_tbl *f)
|
||||
{
|
||||
f->pre_div *= 2;
|
||||
f->pre_div -= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc_rate() - Calculate rate based on m/n:d values
|
||||
*
|
||||
* @rate: Parent rate.
|
||||
* @m: Multiplier.
|
||||
* @n: Divisor.
|
||||
* @mode: Use zero to ignore m/n calculation.
|
||||
* @hid_div: Pre divisor register value. Pre divisor value
|
||||
* relates to hid_div as pre_div = (hid_div + 1) / 2.
|
||||
*
|
||||
* Return calculated rate according to formula:
|
||||
*
|
||||
* parent_rate m
|
||||
* rate = ----------- x ---
|
||||
* hid_div n
|
||||
* pre_div n
|
||||
*/
|
||||
static unsigned long
|
||||
calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
|
||||
|
@ -393,16 +416,110 @@ static int clk_rcg2_fm_determine_rate(struct clk_hw *hw,
|
|||
return _freq_tbl_fm_determine_rate(hw, rcg->freq_multi_tbl, req);
|
||||
}
|
||||
|
||||
static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
||||
u32 *_cfg)
|
||||
/**
|
||||
* clk_rcg2_split_div() - Split multiplier that doesn't fit in n neither in pre_div.
|
||||
*
|
||||
* @multiplier: Multiplier to split between n and pre_div.
|
||||
* @pre_div: Pointer to pre divisor value.
|
||||
* @n: Pointer to n divisor value.
|
||||
* @pre_div_max: Pre divisor maximum value.
|
||||
*/
|
||||
static inline void clk_rcg2_split_div(int multiplier, unsigned int *pre_div,
|
||||
u16 *n, unsigned int pre_div_max)
|
||||
{
|
||||
*n = mult_frac(multiplier * *n, *pre_div, pre_div_max);
|
||||
*pre_div = pre_div_max;
|
||||
}
|
||||
|
||||
static void clk_rcg2_calc_mnd(u64 parent_rate, u64 rate, struct freq_tbl *f,
|
||||
unsigned int mnd_max, unsigned int pre_div_max)
|
||||
{
|
||||
int i = 2;
|
||||
unsigned int pre_div = 1;
|
||||
unsigned long rates_gcd, scaled_parent_rate;
|
||||
u16 m, n = 1, n_candidate = 1, n_max;
|
||||
|
||||
rates_gcd = gcd(parent_rate, rate);
|
||||
m = div64_u64(rate, rates_gcd);
|
||||
scaled_parent_rate = div64_u64(parent_rate, rates_gcd);
|
||||
while (scaled_parent_rate > (mnd_max + m) * pre_div_max) {
|
||||
// we're exceeding divisor's range, trying lower scale.
|
||||
if (m > 1) {
|
||||
m--;
|
||||
scaled_parent_rate = mult_frac(scaled_parent_rate, m, (m + 1));
|
||||
} else {
|
||||
// cannot lower scale, just set max divisor values.
|
||||
f->n = mnd_max + m;
|
||||
f->pre_div = pre_div_max;
|
||||
f->m = m;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
n_max = m + mnd_max;
|
||||
|
||||
while (scaled_parent_rate > 1) {
|
||||
while (scaled_parent_rate % i == 0) {
|
||||
n_candidate *= i;
|
||||
if (n_candidate < n_max)
|
||||
n = n_candidate;
|
||||
else if (pre_div * i < pre_div_max)
|
||||
pre_div *= i;
|
||||
else
|
||||
clk_rcg2_split_div(i, &pre_div, &n, pre_div_max);
|
||||
|
||||
scaled_parent_rate /= i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
f->m = m;
|
||||
f->n = n;
|
||||
f->pre_div = pre_div > 1 ? pre_div : 0;
|
||||
}
|
||||
|
||||
static int clk_rcg2_determine_gp_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
struct freq_tbl f_tbl = {}, *f = &f_tbl;
|
||||
int mnd_max = BIT(rcg->mnd_width) - 1;
|
||||
int hid_max = BIT(rcg->hid_width) - 1;
|
||||
struct clk_hw *parent;
|
||||
u64 parent_rate;
|
||||
|
||||
parent = clk_hw_get_parent(hw);
|
||||
parent_rate = clk_get_rate(parent->clk);
|
||||
if (!parent_rate)
|
||||
return -EINVAL;
|
||||
|
||||
clk_rcg2_calc_mnd(parent_rate, req->rate, f, mnd_max, hid_max / 2);
|
||||
convert_to_reg_val(f);
|
||||
req->rate = calc_rate(parent_rate, f->m, f->n, f->n, f->pre_div);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __clk_rcg2_configure_parent(struct clk_rcg2 *rcg, u8 src, u32 *_cfg)
|
||||
{
|
||||
u32 cfg, mask, d_val, not2d_val, n_minus_m;
|
||||
struct clk_hw *hw = &rcg->clkr.hw;
|
||||
int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
int index = qcom_find_src_index(hw, rcg->parent_map, src);
|
||||
|
||||
if (index < 0)
|
||||
return index;
|
||||
|
||||
*_cfg &= ~CFG_SRC_SEL_MASK;
|
||||
*_cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __clk_rcg2_configure_mnd(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
||||
u32 *_cfg)
|
||||
{
|
||||
u32 cfg, mask, d_val, not2d_val, n_minus_m;
|
||||
int ret;
|
||||
|
||||
if (rcg->mnd_width && f->n) {
|
||||
mask = BIT(rcg->mnd_width) - 1;
|
||||
ret = regmap_update_bits(rcg->clkr.regmap,
|
||||
|
@ -431,9 +548,8 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
|||
}
|
||||
|
||||
mask = BIT(rcg->hid_width) - 1;
|
||||
mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK;
|
||||
mask |= CFG_MODE_MASK | CFG_HW_CLK_CTRL_MASK;
|
||||
cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
|
||||
cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
if (rcg->mnd_width && f->n && (f->m != f->n))
|
||||
cfg |= CFG_MODE_DUAL_EDGE;
|
||||
if (rcg->hw_clk_ctrl)
|
||||
|
@ -445,6 +561,22 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f,
|
||||
u32 *_cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __clk_rcg2_configure_parent(rcg, f->src, _cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_rcg2_configure_mnd(rcg, f, _cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
|
||||
{
|
||||
u32 cfg;
|
||||
|
@ -465,6 +597,26 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
|
|||
return update_config(rcg);
|
||||
}
|
||||
|
||||
static int clk_rcg2_configure_gp(struct clk_rcg2 *rcg, const struct freq_tbl *f)
|
||||
{
|
||||
u32 cfg;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), &cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_rcg2_configure_mnd(rcg, f, &cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(rcg->clkr.regmap, RCG_CFG_OFFSET(rcg), cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return update_config(rcg);
|
||||
}
|
||||
|
||||
static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
enum freq_policy policy)
|
||||
{
|
||||
|
@ -518,6 +670,22 @@ static int clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return __clk_rcg2_set_rate(hw, rate, CEIL);
|
||||
}
|
||||
|
||||
static int clk_rcg2_set_gp_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
int mnd_max = BIT(rcg->mnd_width) - 1;
|
||||
int hid_max = BIT(rcg->hid_width) - 1;
|
||||
struct freq_tbl f_tbl = {}, *f = &f_tbl;
|
||||
int ret;
|
||||
|
||||
clk_rcg2_calc_mnd(parent_rate, rate, f, mnd_max, hid_max / 2);
|
||||
convert_to_reg_val(f);
|
||||
ret = clk_rcg2_configure_gp(rcg, f);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_rcg2_set_floor_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
|
@ -645,6 +813,18 @@ const struct clk_ops clk_rcg2_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(clk_rcg2_ops);
|
||||
|
||||
const struct clk_ops clk_rcg2_gp_ops = {
|
||||
.is_enabled = clk_rcg2_is_enabled,
|
||||
.get_parent = clk_rcg2_get_parent,
|
||||
.set_parent = clk_rcg2_set_parent,
|
||||
.recalc_rate = clk_rcg2_recalc_rate,
|
||||
.determine_rate = clk_rcg2_determine_gp_rate,
|
||||
.set_rate = clk_rcg2_set_gp_rate,
|
||||
.get_duty_cycle = clk_rcg2_get_duty_cycle,
|
||||
.set_duty_cycle = clk_rcg2_set_duty_cycle,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_rcg2_gp_ops);
|
||||
|
||||
const struct clk_ops clk_rcg2_floor_ops = {
|
||||
.is_enabled = clk_rcg2_is_enabled,
|
||||
.get_parent = clk_rcg2_get_parent,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
|
@ -224,10 +225,10 @@ static void clk_rpm_unprepare(struct clk_hw *hw)
|
|||
unsigned long active_rate, sleep_rate;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rpm_clk_lock);
|
||||
guard(mutex)(&rpm_clk_lock);
|
||||
|
||||
if (!r->rate)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
/* Take peer clock's rate into account only if it's enabled. */
|
||||
if (peer->enabled)
|
||||
|
@ -237,17 +238,14 @@ static void clk_rpm_unprepare(struct clk_hw *hw)
|
|||
active_rate = r->branch ? !!peer_rate : peer_rate;
|
||||
ret = clk_rpm_set_rate_active(r, active_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate;
|
||||
ret = clk_rpm_set_rate_sleep(r, sleep_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
r->enabled = false;
|
||||
|
||||
out:
|
||||
mutex_unlock(&rpm_clk_lock);
|
||||
}
|
||||
|
||||
static int clk_rpm_xo_prepare(struct clk_hw *hw)
|
||||
|
@ -324,12 +322,12 @@ static int clk_rpm_set_rate(struct clk_hw *hw,
|
|||
unsigned long active_rate, sleep_rate;
|
||||
unsigned long this_rate = 0, this_sleep_rate = 0;
|
||||
unsigned long peer_rate = 0, peer_sleep_rate = 0;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rpm_clk_lock);
|
||||
guard(mutex)(&rpm_clk_lock);
|
||||
|
||||
if (!r->enabled)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
to_active_sleep(r, rate, &this_rate, &this_sleep_rate);
|
||||
|
||||
|
@ -341,19 +339,16 @@ static int clk_rpm_set_rate(struct clk_hw *hw,
|
|||
active_rate = max(this_rate, peer_rate);
|
||||
ret = clk_rpm_set_rate_active(r, active_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
sleep_rate = max(this_sleep_rate, peer_sleep_rate);
|
||||
ret = clk_rpm_set_rate_sleep(r, sleep_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
r->rate = rate;
|
||||
|
||||
out:
|
||||
mutex_unlock(&rpm_clk_lock);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long clk_rpm_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <soc/qcom/cmd-db.h>
|
||||
#include <soc/qcom/rpmh.h>
|
||||
#include <soc/qcom/tcs.h>
|
||||
|
@ -206,7 +207,7 @@ static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c,
|
|||
c->state = c->valid_state_mask;
|
||||
|
||||
WARN(1, "clk: %s failed to %s\n", c->res_name,
|
||||
enable ? "enable" : "disable");
|
||||
str_enable_disable(enable));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -329,7 +330,7 @@ static unsigned long clk_rpmh_bcm_recalc_rate(struct clk_hw *hw,
|
|||
{
|
||||
struct clk_rpmh *c = to_clk_rpmh(hw);
|
||||
|
||||
return c->aggr_state * c->unit;
|
||||
return (unsigned long)c->aggr_state * c->unit;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_rpmh_bcm_ops = {
|
||||
|
@ -368,6 +369,8 @@ DEFINE_CLK_RPMH_VRM(rf_clk2, _d, "rfclkd2", 1);
|
|||
DEFINE_CLK_RPMH_VRM(rf_clk3, _d, "rfclkd3", 1);
|
||||
DEFINE_CLK_RPMH_VRM(rf_clk4, _d, "rfclkd4", 1);
|
||||
|
||||
DEFINE_CLK_RPMH_VRM(rf_clk3, _a2, "rfclka3", 2);
|
||||
|
||||
DEFINE_CLK_RPMH_VRM(clk1, _a1, "clka1", 1);
|
||||
DEFINE_CLK_RPMH_VRM(clk2, _a1, "clka2", 1);
|
||||
DEFINE_CLK_RPMH_VRM(clk3, _a1, "clka3", 1);
|
||||
|
@ -807,6 +810,45 @@ static const struct clk_rpmh_desc clk_rpmh_x1e80100 = {
|
|||
.num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *qcs615_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw,
|
||||
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw,
|
||||
[RPMH_LN_BB_CLK2] = &clk_rpmh_ln_bb_clk2_a2.hw,
|
||||
[RPMH_LN_BB_CLK2_A] = &clk_rpmh_ln_bb_clk2_a2_ao.hw,
|
||||
[RPMH_LN_BB_CLK3] = &clk_rpmh_ln_bb_clk3_a2.hw,
|
||||
[RPMH_LN_BB_CLK3_A] = &clk_rpmh_ln_bb_clk3_a2_ao.hw,
|
||||
[RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw,
|
||||
[RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw,
|
||||
[RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw,
|
||||
[RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_qcs615 = {
|
||||
.clks = qcs615_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(qcs615_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *sm8750_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw,
|
||||
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw,
|
||||
[RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2.hw,
|
||||
[RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_ao.hw,
|
||||
[RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2.hw,
|
||||
[RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_ao.hw,
|
||||
[RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw,
|
||||
[RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw,
|
||||
[RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw,
|
||||
[RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw,
|
||||
[RPMH_RF_CLK3] = &clk_rpmh_rf_clk3_a2.hw,
|
||||
[RPMH_RF_CLK3_A] = &clk_rpmh_rf_clk3_a2_ao.hw,
|
||||
[RPMH_IPA_CLK] = &clk_rpmh_ipa.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sm8750 = {
|
||||
.clks = sm8750_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sm8750_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
|
@ -890,10 +932,12 @@ static int clk_rpmh_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id clk_rpmh_match_table[] = {
|
||||
{ .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615},
|
||||
{ .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000},
|
||||
{ .compatible = "qcom,sa8775p-rpmh-clk", .data = &clk_rpmh_sa8775p},
|
||||
{ .compatible = "qcom,sar2130p-rpmh-clk", .data = &clk_rpmh_sar2130p},
|
||||
{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
|
||||
{ .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
|
||||
{ .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
|
||||
{ .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
|
||||
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
|
||||
|
@ -909,7 +953,7 @@ static const struct of_device_id clk_rpmh_match_table[] = {
|
|||
{ .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450},
|
||||
{ .compatible = "qcom,sm8550-rpmh-clk", .data = &clk_rpmh_sm8550},
|
||||
{ .compatible = "qcom,sm8650-rpmh-clk", .data = &clk_rpmh_sm8650},
|
||||
{ .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
|
||||
{ .compatible = "qcom,sm8750-rpmh-clk", .data = &clk_rpmh_sm8750},
|
||||
{ .compatible = "qcom,x1e80100-rpmh-clk", .data = &clk_rpmh_x1e80100},
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
|
@ -309,10 +310,10 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw)
|
|||
unsigned long active_rate, sleep_rate;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&rpm_smd_clk_lock);
|
||||
guard(mutex)(&rpm_smd_clk_lock);
|
||||
|
||||
if (!r->rate)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
/* Take peer clock's rate into account only if it's enabled. */
|
||||
if (peer->enabled)
|
||||
|
@ -322,17 +323,14 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw)
|
|||
active_rate = r->branch ? !!peer_rate : peer_rate;
|
||||
ret = clk_smd_rpm_set_rate_active(r, active_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate;
|
||||
ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return;
|
||||
|
||||
r->enabled = false;
|
||||
|
||||
out:
|
||||
mutex_unlock(&rpm_smd_clk_lock);
|
||||
}
|
||||
|
||||
static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -345,10 +343,10 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
unsigned long peer_rate = 0, peer_sleep_rate = 0;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&rpm_smd_clk_lock);
|
||||
guard(mutex)(&rpm_smd_clk_lock);
|
||||
|
||||
if (!r->enabled)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
to_active_sleep(r, rate, &this_rate, &this_sleep_rate);
|
||||
|
||||
|
@ -360,19 +358,16 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
active_rate = max(this_rate, peer_rate);
|
||||
ret = clk_smd_rpm_set_rate_active(r, active_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
sleep_rate = max(this_sleep_rate, peer_sleep_rate);
|
||||
ret = clk_smd_rpm_set_rate_sleep(r, sleep_rate);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
r->rate = rate;
|
||||
|
||||
out:
|
||||
mutex_unlock(&rpm_smd_clk_lock);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long clk_smd_rpm_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -700,6 +695,60 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8936 = {
|
|||
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
|
||||
};
|
||||
|
||||
static struct clk_smd_rpm *msm8937_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a,
|
||||
[RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk,
|
||||
[RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk,
|
||||
[RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1,
|
||||
[RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a,
|
||||
[RPM_SMD_BB_CLK2] = &clk_smd_rpm_bb_clk2,
|
||||
[RPM_SMD_BB_CLK2_A] = &clk_smd_rpm_bb_clk2_a,
|
||||
[RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2,
|
||||
[RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a,
|
||||
[RPM_SMD_DIV_CLK2] = &clk_smd_rpm_div_clk2,
|
||||
[RPM_SMD_DIV_A_CLK2] = &clk_smd_rpm_div_clk2_a,
|
||||
[RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin,
|
||||
[RPM_SMD_BB_CLK1_A_PIN] = &clk_smd_rpm_bb_clk1_a_pin,
|
||||
[RPM_SMD_BB_CLK2_PIN] = &clk_smd_rpm_bb_clk2_pin,
|
||||
[RPM_SMD_BB_CLK2_A_PIN] = &clk_smd_rpm_bb_clk2_a_pin,
|
||||
};
|
||||
|
||||
static const struct rpm_smd_clk_desc rpm_clk_msm8937 = {
|
||||
.clks = msm8937_clks,
|
||||
.num_clks = ARRAY_SIZE(msm8937_clks),
|
||||
.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
|
||||
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
|
||||
};
|
||||
|
||||
static struct clk_smd_rpm *msm8940_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a,
|
||||
[RPM_SMD_IPA_CLK] = &clk_smd_rpm_ipa_clk,
|
||||
[RPM_SMD_IPA_A_CLK] = &clk_smd_rpm_ipa_a_clk,
|
||||
[RPM_SMD_QDSS_CLK] = &clk_smd_rpm_qdss_clk,
|
||||
[RPM_SMD_QDSS_A_CLK] = &clk_smd_rpm_qdss_a_clk,
|
||||
[RPM_SMD_BB_CLK1] = &clk_smd_rpm_bb_clk1,
|
||||
[RPM_SMD_BB_CLK1_A] = &clk_smd_rpm_bb_clk1_a,
|
||||
[RPM_SMD_BB_CLK2] = &clk_smd_rpm_bb_clk2,
|
||||
[RPM_SMD_BB_CLK2_A] = &clk_smd_rpm_bb_clk2_a,
|
||||
[RPM_SMD_RF_CLK2] = &clk_smd_rpm_rf_clk2,
|
||||
[RPM_SMD_RF_CLK2_A] = &clk_smd_rpm_rf_clk2_a,
|
||||
[RPM_SMD_DIV_CLK2] = &clk_smd_rpm_div_clk2,
|
||||
[RPM_SMD_DIV_A_CLK2] = &clk_smd_rpm_div_clk2_a,
|
||||
[RPM_SMD_BB_CLK1_PIN] = &clk_smd_rpm_bb_clk1_pin,
|
||||
[RPM_SMD_BB_CLK1_A_PIN] = &clk_smd_rpm_bb_clk1_a_pin,
|
||||
[RPM_SMD_BB_CLK2_PIN] = &clk_smd_rpm_bb_clk2_pin,
|
||||
[RPM_SMD_BB_CLK2_A_PIN] = &clk_smd_rpm_bb_clk2_a_pin,
|
||||
};
|
||||
|
||||
static const struct rpm_smd_clk_desc rpm_clk_msm8940 = {
|
||||
.clks = msm8940_clks,
|
||||
.num_clks = ARRAY_SIZE(msm8940_clks),
|
||||
.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
|
||||
.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
|
||||
};
|
||||
|
||||
static struct clk_smd_rpm *msm8974_clks[] = {
|
||||
[RPM_SMD_XO_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo,
|
||||
[RPM_SMD_XO_A_CLK_SRC] = &clk_smd_rpm_branch_bi_tcxo_a,
|
||||
|
@ -1216,6 +1265,8 @@ static const struct of_device_id rpm_smd_clk_match_table[] = {
|
|||
{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
|
||||
{ .compatible = "qcom,rpmcc-msm8917", .data = &rpm_clk_msm8917 },
|
||||
{ .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
|
||||
{ .compatible = "qcom,rpmcc-msm8937", .data = &rpm_clk_msm8937 },
|
||||
{ .compatible = "qcom,rpmcc-msm8940", .data = &rpm_clk_msm8940 },
|
||||
{ .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 },
|
||||
{ .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
|
||||
{ .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 },
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
|
@ -140,30 +141,26 @@ static int clk_spmi_pmic_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clkdiv *clkdiv = to_clkdiv(hw);
|
||||
unsigned int div_factor = div_to_div_factor(parent_rate / rate);
|
||||
unsigned long flags;
|
||||
bool enabled;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&clkdiv->lock, flags);
|
||||
guard(spinlock_irqsave)(&clkdiv->lock);
|
||||
|
||||
enabled = is_spmi_pmic_clkdiv_enabled(clkdiv);
|
||||
if (enabled) {
|
||||
ret = spmi_pmic_clkdiv_set_enable_state(clkdiv, false);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(clkdiv->regmap, clkdiv->base + REG_DIV_CTL1,
|
||||
DIV_CTL1_DIV_FACTOR_MASK, div_factor);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
return ret;
|
||||
|
||||
if (enabled)
|
||||
ret = __spmi_pmic_clkdiv_set_enable_state(clkdiv, true,
|
||||
div_factor);
|
||||
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&clkdiv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,8 +40,6 @@ static const struct pll_vco spark_vco[] = {
|
|||
/* 768MHz configuration */
|
||||
static const struct alpha_pll_config disp_cc_pll0_config = {
|
||||
.l = 0x28,
|
||||
.alpha = 0x0,
|
||||
.alpha_en_mask = BIT(24),
|
||||
.vco_val = 0x2 << 20,
|
||||
.vco_mask = GENMASK(21, 20),
|
||||
.main_output_mask = BIT(0),
|
||||
|
|
|
@ -48,8 +48,6 @@ static const struct pll_vco spark_vco[] = {
|
|||
/* 768MHz configuration */
|
||||
static const struct alpha_pll_config disp_cc_pll0_config = {
|
||||
.l = 0x28,
|
||||
.alpha = 0x0,
|
||||
.alpha_en_mask = BIT(24),
|
||||
.vco_val = 0x2 << 20,
|
||||
.vco_mask = GENMASK(21, 20),
|
||||
.main_output_mask = BIT(0),
|
||||
|
|
|
@ -187,13 +187,12 @@ static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
|
|||
.cmd_rcgr = 0x1144,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_6,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_aux_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.parent_data = disp_cc_parent_data_6,
|
||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
|
1963
drivers/clk/qcom/dispcc-sm8750.c
Normal file
1963
drivers/clk/qcom/dispcc-sm8750.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/interconnect-provider.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -12,6 +13,7 @@
|
|||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,ipq5424-gcc.h>
|
||||
#include <dt-bindings/interconnect/qcom,ipq5424.h>
|
||||
#include <dt-bindings/reset/qcom,ipq5424-gcc.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
|
@ -325,6 +327,24 @@ static struct clk_rcg2 gcc_xo_clk_src = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_xo_clk = {
|
||||
.halt_reg = 0x34018,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x34018,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gcc_xo_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gcc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor gcc_xo_div4_clk_src = {
|
||||
.mult = 1,
|
||||
.div = 4,
|
||||
|
@ -1097,24 +1117,6 @@ static struct clk_branch gcc_adss_pwm_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_apss_dbg_clk = {
|
||||
.halt_reg = 0x2402c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2402c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gcc_apss_dbg_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gcc_qdss_dap_sync_clk_src.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_cnoc_pcie0_1lane_s_clk = {
|
||||
.halt_reg = 0x31088,
|
||||
.halt_check = BRANCH_HALT,
|
||||
|
@ -2785,7 +2787,6 @@ static struct clk_branch gcc_pcie3_rchng_clk = {
|
|||
static struct clk_regmap *gcc_ipq5424_clocks[] = {
|
||||
[GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr,
|
||||
[GCC_ADSS_PWM_CLK_SRC] = &gcc_adss_pwm_clk_src.clkr,
|
||||
[GCC_APSS_DBG_CLK] = &gcc_apss_dbg_clk.clkr,
|
||||
[GCC_CNOC_PCIE0_1LANE_S_CLK] = &gcc_cnoc_pcie0_1lane_s_clk.clkr,
|
||||
[GCC_CNOC_PCIE1_1LANE_S_CLK] = &gcc_cnoc_pcie1_1lane_s_clk.clkr,
|
||||
[GCC_CNOC_PCIE2_2LANE_S_CLK] = &gcc_cnoc_pcie2_2lane_s_clk.clkr,
|
||||
|
@ -2920,6 +2921,7 @@ static struct clk_regmap *gcc_ipq5424_clocks[] = {
|
|||
[GCC_QPIC_CLK_SRC] = &gcc_qpic_clk_src.clkr,
|
||||
[GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
|
||||
[GCC_XO_CLK_SRC] = &gcc_xo_clk_src.clkr,
|
||||
[GCC_XO_CLK] = &gcc_xo_clk.clkr,
|
||||
[GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
|
||||
[GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr,
|
||||
[GPLL0] = &gpll0.clkr,
|
||||
|
@ -3230,6 +3232,20 @@ static const struct qcom_reset_map gcc_ipq5424_resets[] = {
|
|||
[GCC_QUSB2_1_PHY_BCR] = { 0x3C030, 0 },
|
||||
};
|
||||
|
||||
#define IPQ_APPS_ID 5424 /* some unique value */
|
||||
|
||||
static const struct qcom_icc_hws_data icc_ipq5424_hws[] = {
|
||||
{ MASTER_ANOC_PCIE0, SLAVE_ANOC_PCIE0, GCC_ANOC_PCIE0_1LANE_M_CLK },
|
||||
{ MASTER_CNOC_PCIE0, SLAVE_CNOC_PCIE0, GCC_CNOC_PCIE0_1LANE_S_CLK },
|
||||
{ MASTER_ANOC_PCIE1, SLAVE_ANOC_PCIE1, GCC_ANOC_PCIE1_1LANE_M_CLK },
|
||||
{ MASTER_CNOC_PCIE1, SLAVE_CNOC_PCIE1, GCC_CNOC_PCIE1_1LANE_S_CLK },
|
||||
{ MASTER_ANOC_PCIE2, SLAVE_ANOC_PCIE2, GCC_ANOC_PCIE2_2LANE_M_CLK },
|
||||
{ MASTER_CNOC_PCIE2, SLAVE_CNOC_PCIE2, GCC_CNOC_PCIE2_2LANE_S_CLK },
|
||||
{ MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK },
|
||||
{ MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_CNOC_PCIE3_2LANE_S_CLK },
|
||||
{ MASTER_CNOC_USB, SLAVE_CNOC_USB, GCC_CNOC_USB_CLK },
|
||||
};
|
||||
|
||||
static const struct of_device_id gcc_ipq5424_match_table[] = {
|
||||
{ .compatible = "qcom,ipq5424-gcc" },
|
||||
{ }
|
||||
|
@ -3260,6 +3276,8 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = {
|
|||
.num_resets = ARRAY_SIZE(gcc_ipq5424_resets),
|
||||
.clk_hws = gcc_ipq5424_hws,
|
||||
.num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws),
|
||||
.icc_hws = icc_ipq5424_hws,
|
||||
.num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws),
|
||||
};
|
||||
|
||||
static int gcc_ipq5424_probe(struct platform_device *pdev)
|
||||
|
@ -3272,6 +3290,7 @@ static struct platform_driver gcc_ipq5424_driver = {
|
|||
.driver = {
|
||||
.name = "qcom,gcc-ipq5424",
|
||||
.of_match_table = gcc_ipq5424_match_table,
|
||||
.sync_state = icc_sync_state,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -4194,10 +4194,9 @@ static const struct alpha_pll_config ubi32_pll_config = {
|
|||
.test_ctl_hi_val = 0x4000,
|
||||
};
|
||||
|
||||
/* 1200 MHz configuration */
|
||||
static const struct alpha_pll_config nss_crypto_pll_config = {
|
||||
.l = 0x32,
|
||||
.alpha = 0x0,
|
||||
.alpha_hi = 0x0,
|
||||
.config_ctl_val = 0x4001055b,
|
||||
.main_output_mask = BIT(0),
|
||||
.pre_div_val = 0x0,
|
||||
|
@ -4206,7 +4205,6 @@ static const struct alpha_pll_config nss_crypto_pll_config = {
|
|||
.post_div_mask = GENMASK(11, 8),
|
||||
.vco_mask = GENMASK(21, 20),
|
||||
.vco_val = 0x0,
|
||||
.alpha_en_mask = BIT(24),
|
||||
};
|
||||
|
||||
static struct clk_hw *gcc_ipq6018_hws[] = {
|
||||
|
|
|
@ -535,7 +535,7 @@ static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
|
|||
};
|
||||
|
||||
static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
|
||||
.cmd_rcgr = 0x6044,
|
||||
.cmd_rcgr = 0x7044,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_xo_gpll0_map,
|
||||
|
|
3034
drivers/clk/qcom/gcc-qcs615.c
Normal file
3034
drivers/clk/qcom/gcc-qcs615.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -284,11 +284,6 @@ static struct clk_rcg2 gcc_sdm670_cpuss_rbcpr_clk_src = {
|
|||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
|
||||
F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
|
||||
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -302,7 +297,7 @@ static struct clk_rcg2 gcc_gp1_clk_src = {
|
|||
.name = "gcc_gp1_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
.ops = &clk_rcg2_gp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -316,7 +311,7 @@ static struct clk_rcg2 gcc_gp2_clk_src = {
|
|||
.name = "gcc_gp2_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
.ops = &clk_rcg2_gp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -330,7 +325,7 @@ static struct clk_rcg2 gcc_gp3_clk_src = {
|
|||
.name = "gcc_gp3_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
.ops = &clk_rcg2_gp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -454,7 +449,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s0_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
|
||||
|
@ -470,7 +465,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s1_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
|
||||
|
@ -486,7 +481,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s2_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
|
||||
|
@ -502,7 +497,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s3_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
|
||||
|
@ -518,7 +513,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s4_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
|
||||
|
@ -534,7 +529,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s5_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
|
||||
|
@ -550,7 +545,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s6_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
|
||||
|
@ -566,7 +561,7 @@ static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap0_s7_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
|
||||
|
@ -582,7 +577,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s0_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
|
||||
|
@ -598,7 +593,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s1_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
|
||||
|
@ -614,7 +609,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s2_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
|
||||
|
@ -630,7 +625,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s3_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
|
||||
|
@ -646,7 +641,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s4_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
|
||||
|
@ -662,7 +657,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s5_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
|
||||
|
@ -678,7 +673,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s6_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
|
||||
|
@ -694,7 +689,7 @@ static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
|
|||
.name = "gcc_qupv3_wrap1_s7_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
|
||||
|
|
|
@ -182,6 +182,14 @@ static const struct clk_parent_data gcc_parent_data_2_ao[] = {
|
|||
{ .hw = &gpll0_out_odd.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct parent_map gcc_parent_map_3[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gcc_parent_data_3[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
};
|
||||
|
||||
static const struct parent_map gcc_parent_map_4[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPLL0_OUT_MAIN, 1 },
|
||||
|
@ -701,13 +709,12 @@ static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
|
|||
.cmd_rcgr = 0x3a0b0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_3,
|
||||
.freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_phy_phy_aux_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.parent_data = gcc_parent_data_3,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_3),
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
@ -764,13 +771,12 @@ static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
|
|||
.cmd_rcgr = 0x1a034,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_3,
|
||||
.freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_usb30_prim_mock_utmi_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.parent_data = gcc_parent_data_3,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_3),
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -3003,7 +3003,7 @@ static struct gdsc pcie_0_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -3014,7 +3014,7 @@ static struct gdsc pcie_0_phy_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_0_phy_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -3025,7 +3025,7 @@ static struct gdsc pcie_1_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
@ -3036,7 +3036,7 @@ static struct gdsc pcie_1_phy_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_1_phy_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
|
@ -3437,7 +3437,7 @@ static struct gdsc pcie_0_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
|
||||
};
|
||||
|
||||
|
@ -3448,7 +3448,7 @@ static struct gdsc pcie_0_phy_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_0_phy_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
|
||||
};
|
||||
|
||||
|
@ -3459,7 +3459,7 @@ static struct gdsc pcie_1_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
|
||||
};
|
||||
|
||||
|
@ -3470,7 +3470,7 @@ static struct gdsc pcie_1_phy_gdsc = {
|
|||
.pd = {
|
||||
.name = "pcie_1_phy_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
|
||||
};
|
||||
|
||||
|
|
3274
drivers/clk/qcom/gcc-sm8750.c
Normal file
3274
drivers/clk/qcom/gcc-sm8750.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -6083,7 +6083,7 @@ static struct gdsc gcc_usb20_prim_gdsc = {
|
|||
.pd = {
|
||||
.name = "gcc_usb20_prim_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.pwrsts = PWRSTS_RET_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
587
drivers/clk/qcom/gpucc-x1p42100.c
Normal file
587
drivers/clk/qcom/gpucc-x1p42100.c
Normal file
|
@ -0,0 +1,587 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,x1e80100-gpucc.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-pll.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "clk-regmap-mux.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
#include "reset.h"
|
||||
|
||||
enum {
|
||||
DT_BI_TCXO,
|
||||
DT_GPLL0_OUT_MAIN,
|
||||
DT_GPLL0_OUT_MAIN_DIV,
|
||||
};
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_GPLL0_OUT_MAIN,
|
||||
P_GPLL0_OUT_MAIN_DIV,
|
||||
P_GPU_CC_PLL0_OUT_MAIN,
|
||||
P_GPU_CC_PLL1_OUT_MAIN,
|
||||
};
|
||||
|
||||
static const struct pll_vco lucid_ole_vco[] = {
|
||||
{ 249600000, 2300000000, 0 },
|
||||
};
|
||||
|
||||
/* 560.0 MHz Configuration */
|
||||
static const struct alpha_pll_config gpu_cc_pll0_config = {
|
||||
.l = 0x1d,
|
||||
.alpha = 0x2aaa,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x00182261,
|
||||
.config_ctl_hi1_val = 0x82aa299c,
|
||||
.test_ctl_val = 0x00000000,
|
||||
.test_ctl_hi_val = 0x00000003,
|
||||
.test_ctl_hi1_val = 0x00009000,
|
||||
.test_ctl_hi2_val = 0x00000034,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000005,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpu_cc_pll0 = {
|
||||
.offset = 0x0,
|
||||
.vco_table = lucid_ole_vco,
|
||||
.num_vco = ARRAY_SIZE(lucid_ole_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
|
||||
.clkr = {
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_pll0",
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.index = DT_BI_TCXO,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_lucid_evo_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* 440.0 MHz Configuration */
|
||||
static const struct alpha_pll_config gpu_cc_pll1_config = {
|
||||
.l = 0x16,
|
||||
.alpha = 0xeaaa,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x00182261,
|
||||
.config_ctl_hi1_val = 0x82aa299c,
|
||||
.test_ctl_val = 0x00000000,
|
||||
.test_ctl_hi_val = 0x00000003,
|
||||
.test_ctl_hi1_val = 0x00009000,
|
||||
.test_ctl_hi2_val = 0x00000034,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000005,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpu_cc_pll1 = {
|
||||
.offset = 0x1000,
|
||||
.vco_table = lucid_ole_vco,
|
||||
.num_vco = ARRAY_SIZE(lucid_ole_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
|
||||
.clkr = {
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_pll1",
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.index = DT_BI_TCXO,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_lucid_evo_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map gpu_cc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpu_cc_parent_data_0[] = {
|
||||
{ .index = DT_BI_TCXO },
|
||||
{ .index = DT_GPLL0_OUT_MAIN },
|
||||
{ .index = DT_GPLL0_OUT_MAIN_DIV },
|
||||
};
|
||||
|
||||
static const struct parent_map gpu_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
|
||||
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpu_cc_parent_data_1[] = {
|
||||
{ .index = DT_BI_TCXO },
|
||||
{ .hw = &gpu_cc_pll0.clkr.hw },
|
||||
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||
{ .index = DT_GPLL0_OUT_MAIN },
|
||||
{ .index = DT_GPLL0_OUT_MAIN_DIV },
|
||||
};
|
||||
|
||||
static const struct parent_map gpu_cc_parent_map_2[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpu_cc_parent_data_2[] = {
|
||||
{ .index = DT_BI_TCXO },
|
||||
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||
{ .index = DT_GPLL0_OUT_MAIN },
|
||||
{ .index = DT_GPLL0_OUT_MAIN_DIV },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
|
||||
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gpu_cc_ff_clk_src = {
|
||||
.cmd_rcgr = 0x9474,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpu_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_gpu_cc_ff_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_ff_clk_src",
|
||||
.parent_data = gpu_cc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(220000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
|
||||
F(550000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gpu_cc_gmu_clk_src = {
|
||||
.cmd_rcgr = 0x9318,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpu_cc_parent_map_1,
|
||||
.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_gmu_clk_src",
|
||||
.parent_data = gpu_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gpu_cc_hub_clk_src = {
|
||||
.cmd_rcgr = 0x93ec,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpu_cc_parent_map_2,
|
||||
.freq_tbl = ftbl_gpu_cc_ff_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_hub_clk_src",
|
||||
.parent_data = gpu_cc_parent_data_2,
|
||||
.num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_ahb_clk = {
|
||||
.halt_reg = 0x911c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x911c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_ahb_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_hub_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_crc_ahb_clk = {
|
||||
.halt_reg = 0x9120,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9120,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_crc_ahb_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_hub_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cx_accu_shift_clk = {
|
||||
.halt_reg = 0x9480,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9480,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_cx_accu_shift_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cx_ff_clk = {
|
||||
.halt_reg = 0x914c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x914c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_cx_ff_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_ff_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cx_gmu_clk = {
|
||||
.halt_reg = 0x913c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x913c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_cx_gmu_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_gmu_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_aon_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cxo_clk = {
|
||||
.halt_reg = 0x9144,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9144,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_cxo_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_freq_measure_clk = {
|
||||
.halt_reg = 0x9008,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_freq_measure_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_gx_accu_shift_clk = {
|
||||
.halt_reg = 0x947c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x947c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_gx_accu_shift_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_gx_gmu_clk = {
|
||||
.halt_reg = 0x90bc,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x90bc,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_gx_gmu_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_gmu_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_gx_vsense_clk = {
|
||||
.halt_reg = 0x90b0,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x90b0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_gx_vsense_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_hub_aon_clk = {
|
||||
.halt_reg = 0x93e8,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x93e8,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_hub_aon_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_hub_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_aon_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_hub_cx_int_clk = {
|
||||
.halt_reg = 0x9148,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9148,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_hub_cx_int_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&gpu_cc_hub_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_aon_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_memnoc_gfx_clk = {
|
||||
.halt_reg = 0x9150,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9150,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_memnoc_gfx_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = {
|
||||
.halt_reg = 0x9288,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9288,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_mnd1x_0_gfx3d_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = {
|
||||
.halt_reg = 0x928c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x928c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_mnd1x_1_gfx3d_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_sleep_clk = {
|
||||
.halt_reg = 0x9134,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9134,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpu_cc_sleep_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc gpu_cc_cx_gdsc = {
|
||||
.gdscr = 0x9108,
|
||||
.gds_hw_ctrl = 0x953c,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "gpu_cc_cx_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
static struct gdsc gpu_cc_gx_gdsc = {
|
||||
.gdscr = 0x905c,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "gpu_cc_gx_gdsc",
|
||||
.power_on = gdsc_gx_do_nothing_enable,
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = CLAMP_IO | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gpu_cc_x1p42100_clocks[] = {
|
||||
[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
|
||||
[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
|
||||
[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr,
|
||||
[GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
|
||||
[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
|
||||
[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
|
||||
[GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
|
||||
[GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr,
|
||||
[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
|
||||
[GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr,
|
||||
[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
|
||||
[GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
|
||||
[GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
|
||||
[GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
|
||||
[GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
|
||||
[GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
|
||||
[GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr,
|
||||
[GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr,
|
||||
[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
|
||||
[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
|
||||
[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gpu_cc_x1p42100_gdscs[] = {
|
||||
[GPU_CX_GDSC] = &gpu_cc_cx_gdsc,
|
||||
[GPU_GX_GDSC] = &gpu_cc_gx_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gpu_cc_x1p42100_resets[] = {
|
||||
[GPU_CC_ACD_BCR] = { 0x9358 },
|
||||
[GPU_CC_CB_BCR] = { 0x93a0 },
|
||||
[GPU_CC_CX_BCR] = { 0x9104 },
|
||||
[GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
|
||||
[GPU_CC_FF_BCR] = { 0x9470 },
|
||||
[GPU_CC_GFX3D_AON_BCR] = { 0x9198 },
|
||||
[GPU_CC_GMU_BCR] = { 0x9314 },
|
||||
[GPU_CC_GX_BCR] = { 0x9058 },
|
||||
[GPU_CC_XO_BCR] = { 0x9000 },
|
||||
};
|
||||
|
||||
static const struct regmap_config gpu_cc_x1p42100_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x9988,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct qcom_cc_desc gpu_cc_x1p42100_desc = {
|
||||
.config = &gpu_cc_x1p42100_regmap_config,
|
||||
.clks = gpu_cc_x1p42100_clocks,
|
||||
.num_clks = ARRAY_SIZE(gpu_cc_x1p42100_clocks),
|
||||
.resets = gpu_cc_x1p42100_resets,
|
||||
.num_resets = ARRAY_SIZE(gpu_cc_x1p42100_resets),
|
||||
.gdscs = gpu_cc_x1p42100_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(gpu_cc_x1p42100_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id gpu_cc_x1p42100_match_table[] = {
|
||||
{ .compatible = "qcom,x1p42100-gpucc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpu_cc_x1p42100_match_table);
|
||||
|
||||
static int gpu_cc_x1p42100_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
ret = devm_pm_runtime_enable(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &gpu_cc_x1p42100_desc);
|
||||
if (IS_ERR(regmap)) {
|
||||
pm_runtime_put(&pdev->dev);
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
|
||||
clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
|
||||
|
||||
/* Keep some clocks always enabled */
|
||||
qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */
|
||||
|
||||
ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1p42100_desc, regmap);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver gpu_cc_x1p42100_driver = {
|
||||
.probe = gpu_cc_x1p42100_probe,
|
||||
.driver = {
|
||||
.name = "gpucc-x1p42100",
|
||||
.of_match_table = gpu_cc_x1p42100_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(gpu_cc_x1p42100_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QTI GPUCC X1P42100 Driver");
|
||||
MODULE_LICENSE("GPL");
|
435
drivers/clk/qcom/ipq-cmn-pll.c
Normal file
435
drivers/clk/qcom/ipq-cmn-pll.c
Normal file
|
@ -0,0 +1,435 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CMN PLL block expects the reference clock from on-board Wi-Fi block,
|
||||
* and supplies fixed rate clocks as output to the networking hardware
|
||||
* blocks and to GCC. The networking related blocks include PPE (packet
|
||||
* process engine), the externally connected PHY or switch devices, and
|
||||
* the PCS.
|
||||
*
|
||||
* On the IPQ9574 SoC, there are three clocks with 50 MHZ and one clock
|
||||
* with 25 MHZ which are output from the CMN PLL to Ethernet PHY (or switch),
|
||||
* and one clock with 353 MHZ to PPE. The other fixed rate output clocks
|
||||
* are supplied to GCC (24 MHZ as XO and 32 KHZ as sleep clock), and to PCS
|
||||
* with 31.25 MHZ.
|
||||
*
|
||||
* +---------+
|
||||
* | GCC |
|
||||
* +--+---+--+
|
||||
* AHB CLK| |SYS CLK
|
||||
* V V
|
||||
* +-------+---+------+
|
||||
* | +-------------> eth0-50mhz
|
||||
* REF CLK | IPQ9574 |
|
||||
* -------->+ +-------------> eth1-50mhz
|
||||
* | CMN PLL block |
|
||||
* | +-------------> eth2-50mhz
|
||||
* | |
|
||||
* +----+----+----+---+-------------> eth-25mhz
|
||||
* | | |
|
||||
* V V V
|
||||
* GCC PCS NSS/PPE
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
|
||||
|
||||
#define CMN_PLL_REFCLK_SRC_SELECTION 0x28
|
||||
#define CMN_PLL_REFCLK_SRC_DIV GENMASK(9, 8)
|
||||
|
||||
#define CMN_PLL_LOCKED 0x64
|
||||
#define CMN_PLL_CLKS_LOCKED BIT(8)
|
||||
|
||||
#define CMN_PLL_POWER_ON_AND_RESET 0x780
|
||||
#define CMN_ANA_EN_SW_RSTN BIT(6)
|
||||
|
||||
#define CMN_PLL_REFCLK_CONFIG 0x784
|
||||
#define CMN_PLL_REFCLK_EXTERNAL BIT(9)
|
||||
#define CMN_PLL_REFCLK_DIV GENMASK(8, 4)
|
||||
#define CMN_PLL_REFCLK_INDEX GENMASK(3, 0)
|
||||
|
||||
#define CMN_PLL_CTRL 0x78c
|
||||
#define CMN_PLL_CTRL_LOCK_DETECT_EN BIT(15)
|
||||
|
||||
#define CMN_PLL_DIVIDER_CTRL 0x794
|
||||
#define CMN_PLL_DIVIDER_CTRL_FACTOR GENMASK(9, 0)
|
||||
|
||||
/**
|
||||
* struct cmn_pll_fixed_output_clk - CMN PLL output clocks information
|
||||
* @id: Clock specifier to be supplied
|
||||
* @name: Clock name to be registered
|
||||
* @rate: Clock rate
|
||||
*/
|
||||
struct cmn_pll_fixed_output_clk {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct clk_cmn_pll - CMN PLL hardware specific data
|
||||
* @regmap: hardware regmap.
|
||||
* @hw: handle between common and hardware-specific interfaces
|
||||
*/
|
||||
struct clk_cmn_pll {
|
||||
struct regmap *regmap;
|
||||
struct clk_hw hw;
|
||||
};
|
||||
|
||||
#define CLK_PLL_OUTPUT(_id, _name, _rate) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.rate = _rate, \
|
||||
}
|
||||
|
||||
#define to_clk_cmn_pll(_hw) container_of(_hw, struct clk_cmn_pll, hw)
|
||||
|
||||
static const struct regmap_config ipq_cmn_pll_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x7fc,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct cmn_pll_fixed_output_clk ipq9574_output_clks[] = {
|
||||
CLK_PLL_OUTPUT(XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
|
||||
CLK_PLL_OUTPUT(SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
|
||||
CLK_PLL_OUTPUT(PCS_31P25MHZ_CLK, "pcs-31p25mhz", 31250000UL),
|
||||
CLK_PLL_OUTPUT(NSS_1200MHZ_CLK, "nss-1200mhz", 1200000000UL),
|
||||
CLK_PLL_OUTPUT(PPE_353MHZ_CLK, "ppe-353mhz", 353000000UL),
|
||||
CLK_PLL_OUTPUT(ETH0_50MHZ_CLK, "eth0-50mhz", 50000000UL),
|
||||
CLK_PLL_OUTPUT(ETH1_50MHZ_CLK, "eth1-50mhz", 50000000UL),
|
||||
CLK_PLL_OUTPUT(ETH2_50MHZ_CLK, "eth2-50mhz", 50000000UL),
|
||||
CLK_PLL_OUTPUT(ETH_25MHZ_CLK, "eth-25mhz", 25000000UL),
|
||||
};
|
||||
|
||||
/*
|
||||
* CMN PLL has the single parent clock, which supports the several
|
||||
* possible parent clock rates, each parent clock rate is reflected
|
||||
* by the specific reference index value in the hardware.
|
||||
*/
|
||||
static int ipq_cmn_pll_find_freq_index(unsigned long parent_rate)
|
||||
{
|
||||
int index = -EINVAL;
|
||||
|
||||
switch (parent_rate) {
|
||||
case 25000000:
|
||||
index = 3;
|
||||
break;
|
||||
case 31250000:
|
||||
index = 4;
|
||||
break;
|
||||
case 40000000:
|
||||
index = 6;
|
||||
break;
|
||||
case 48000000:
|
||||
case 96000000:
|
||||
/*
|
||||
* Parent clock rate 48 MHZ and 96 MHZ take the same value
|
||||
* of reference clock index. 96 MHZ needs the source clock
|
||||
* divider to be programmed as 2.
|
||||
*/
|
||||
index = 7;
|
||||
break;
|
||||
case 50000000:
|
||||
index = 8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static unsigned long clk_cmn_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
||||
u32 val, factor;
|
||||
|
||||
/*
|
||||
* The value of CMN_PLL_DIVIDER_CTRL_FACTOR is automatically adjusted
|
||||
* by HW according to the parent clock rate.
|
||||
*/
|
||||
regmap_read(cmn_pll->regmap, CMN_PLL_DIVIDER_CTRL, &val);
|
||||
factor = FIELD_GET(CMN_PLL_DIVIDER_CTRL_FACTOR, val);
|
||||
|
||||
return parent_rate * 2 * factor;
|
||||
}
|
||||
|
||||
static int clk_cmn_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Validate the rate of the single parent clock. */
|
||||
ret = ipq_cmn_pll_find_freq_index(req->best_parent_rate);
|
||||
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to initialize the CMN PLL to enable the fixed
|
||||
* rate output clocks. It is expected to be configured once.
|
||||
*/
|
||||
static int clk_cmn_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_cmn_pll *cmn_pll = to_clk_cmn_pll(hw);
|
||||
int ret, index;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Configure the reference input clock selection as per the given
|
||||
* parent clock. The output clock rates are always of fixed value.
|
||||
*/
|
||||
index = ipq_cmn_pll_find_freq_index(parent_rate);
|
||||
if (index < 0)
|
||||
return index;
|
||||
|
||||
ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
||||
CMN_PLL_REFCLK_INDEX,
|
||||
FIELD_PREP(CMN_PLL_REFCLK_INDEX, index));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Update the source clock rate selection and source clock
|
||||
* divider as 2 when the parent clock rate is 96 MHZ.
|
||||
*/
|
||||
if (parent_rate == 96000000) {
|
||||
ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_CONFIG,
|
||||
CMN_PLL_REFCLK_DIV,
|
||||
FIELD_PREP(CMN_PLL_REFCLK_DIV, 2));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(cmn_pll->regmap, CMN_PLL_REFCLK_SRC_SELECTION,
|
||||
CMN_PLL_REFCLK_SRC_DIV,
|
||||
FIELD_PREP(CMN_PLL_REFCLK_SRC_DIV, 0));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Enable PLL locked detect. */
|
||||
ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_CTRL,
|
||||
CMN_PLL_CTRL_LOCK_DETECT_EN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Reset the CMN PLL block to ensure the updated configurations
|
||||
* take effect.
|
||||
*/
|
||||
ret = regmap_clear_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
||||
CMN_ANA_EN_SW_RSTN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
usleep_range(1000, 1200);
|
||||
ret = regmap_set_bits(cmn_pll->regmap, CMN_PLL_POWER_ON_AND_RESET,
|
||||
CMN_ANA_EN_SW_RSTN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Stability check of CMN PLL output clocks. */
|
||||
return regmap_read_poll_timeout(cmn_pll->regmap, CMN_PLL_LOCKED, val,
|
||||
(val & CMN_PLL_CLKS_LOCKED),
|
||||
100, 100 * USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_cmn_pll_ops = {
|
||||
.recalc_rate = clk_cmn_pll_recalc_rate,
|
||||
.determine_rate = clk_cmn_pll_determine_rate,
|
||||
.set_rate = clk_cmn_pll_set_rate,
|
||||
};
|
||||
|
||||
static struct clk_hw *ipq_cmn_pll_clk_hw_register(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_parent_data pdata = { .index = 0 };
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_init_data init = {};
|
||||
struct clk_cmn_pll *cmn_pll;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return ERR_CAST(base);
|
||||
|
||||
regmap = devm_regmap_init_mmio(dev, base, &ipq_cmn_pll_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return ERR_CAST(regmap);
|
||||
|
||||
cmn_pll = devm_kzalloc(dev, sizeof(*cmn_pll), GFP_KERNEL);
|
||||
if (!cmn_pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = "cmn_pll";
|
||||
init.parent_data = &pdata;
|
||||
init.num_parents = 1;
|
||||
init.ops = &clk_cmn_pll_ops;
|
||||
|
||||
cmn_pll->hw.init = &init;
|
||||
cmn_pll->regmap = regmap;
|
||||
|
||||
ret = devm_clk_hw_register(dev, &cmn_pll->hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return &cmn_pll->hw;
|
||||
}
|
||||
|
||||
static int ipq_cmn_pll_register_clks(struct platform_device *pdev)
|
||||
{
|
||||
const struct cmn_pll_fixed_output_clk *fixed_clk;
|
||||
struct clk_hw_onecell_data *hw_data;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_hw *cmn_pll_hw;
|
||||
unsigned int num_clks;
|
||||
struct clk_hw *hw;
|
||||
int ret, i;
|
||||
|
||||
fixed_clk = ipq9574_output_clks;
|
||||
num_clks = ARRAY_SIZE(ipq9574_output_clks);
|
||||
|
||||
hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks + 1),
|
||||
GFP_KERNEL);
|
||||
if (!hw_data)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Register the CMN PLL clock, which is the parent clock of
|
||||
* the fixed rate output clocks.
|
||||
*/
|
||||
cmn_pll_hw = ipq_cmn_pll_clk_hw_register(pdev);
|
||||
if (IS_ERR(cmn_pll_hw))
|
||||
return PTR_ERR(cmn_pll_hw);
|
||||
|
||||
/* Register the fixed rate output clocks. */
|
||||
for (i = 0; i < num_clks; i++) {
|
||||
hw = clk_hw_register_fixed_rate_parent_hw(dev, fixed_clk[i].name,
|
||||
cmn_pll_hw, 0,
|
||||
fixed_clk[i].rate);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto unregister_fixed_clk;
|
||||
}
|
||||
|
||||
hw_data->hws[fixed_clk[i].id] = hw;
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the CMN PLL clock. The clock rate of CMN PLL
|
||||
* is configured to 12 GHZ by DT property assigned-clock-rates-u64.
|
||||
*/
|
||||
hw_data->hws[CMN_PLL_CLK] = cmn_pll_hw;
|
||||
hw_data->num = num_clks + 1;
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data);
|
||||
if (ret)
|
||||
goto unregister_fixed_clk;
|
||||
|
||||
platform_set_drvdata(pdev, hw_data);
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_fixed_clk:
|
||||
while (i > 0)
|
||||
clk_hw_unregister(hw_data->hws[fixed_clk[--i].id]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ipq_cmn_pll_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
ret = devm_pm_runtime_enable(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_pm_clk_create(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* To access the CMN PLL registers, the GCC AHB & SYS clocks
|
||||
* of CMN PLL block need to be enabled.
|
||||
*/
|
||||
ret = pm_clk_add(dev, "ahb");
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Fail to add AHB clock\n");
|
||||
|
||||
ret = pm_clk_add(dev, "sys");
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Fail to add SYS clock\n");
|
||||
|
||||
ret = pm_runtime_resume_and_get(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Register CMN PLL clock and fixed rate output clocks. */
|
||||
ret = ipq_cmn_pll_register_clks(pdev);
|
||||
pm_runtime_put(dev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Fail to register CMN PLL clocks\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ipq_cmn_pll_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_hw_onecell_data *hw_data = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The clock with index CMN_PLL_CLK is unregistered by
|
||||
* device management.
|
||||
*/
|
||||
for (i = 0; i < hw_data->num; i++) {
|
||||
if (i != CMN_PLL_CLK)
|
||||
clk_hw_unregister(hw_data->hws[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
|
||||
{ .compatible = "qcom,ipq9574-cmn-pll", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ipq_cmn_pll_clk_ids);
|
||||
|
||||
static struct platform_driver ipq_cmn_pll_clk_driver = {
|
||||
.probe = ipq_cmn_pll_clk_probe,
|
||||
.remove = ipq_cmn_pll_clk_remove,
|
||||
.driver = {
|
||||
.name = "ipq_cmn_pll",
|
||||
.of_match_table = ipq_cmn_pll_clk_ids,
|
||||
.pm = &ipq_cmn_pll_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(ipq_cmn_pll_clk_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPQ CMN PLL Driver");
|
||||
MODULE_LICENSE("GPL");
|
85
drivers/clk/qcom/lpasscc-sm6115.c
Normal file
85
drivers/clk/qcom/lpasscc-sm6115.c
Normal file
|
@ -0,0 +1,85 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022, 2023 Linaro Limited
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,sm6115-lpasscc.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "reset.h"
|
||||
|
||||
static const struct qcom_reset_map lpass_audiocc_sm6115_resets[] = {
|
||||
[LPASS_AUDIO_SWR_RX_CGCR] = { .reg = 0x98, .bit = 1, .udelay = 500 },
|
||||
};
|
||||
|
||||
static struct regmap_config lpass_audiocc_sm6115_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.name = "lpass-audio-csr",
|
||||
.max_register = 0x1000,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc lpass_audiocc_sm6115_reset_desc = {
|
||||
.config = &lpass_audiocc_sm6115_regmap_config,
|
||||
.resets = lpass_audiocc_sm6115_resets,
|
||||
.num_resets = ARRAY_SIZE(lpass_audiocc_sm6115_resets),
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map lpasscc_sm6115_resets[] = {
|
||||
[LPASS_SWR_TX_CONFIG_CGCR] = { .reg = 0x100, .bit = 1, .udelay = 500 },
|
||||
};
|
||||
|
||||
static struct regmap_config lpasscc_sm6115_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.name = "lpass-tcsr",
|
||||
.max_register = 0x1000,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc lpasscc_sm6115_reset_desc = {
|
||||
.config = &lpasscc_sm6115_regmap_config,
|
||||
.resets = lpasscc_sm6115_resets,
|
||||
.num_resets = ARRAY_SIZE(lpasscc_sm6115_resets),
|
||||
};
|
||||
|
||||
static const struct of_device_id lpasscc_sm6115_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,sm6115-lpassaudiocc",
|
||||
.data = &lpass_audiocc_sm6115_reset_desc,
|
||||
}, {
|
||||
.compatible = "qcom,sm6115-lpasscc",
|
||||
.data = &lpasscc_sm6115_reset_desc,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpasscc_sm6115_match_table);
|
||||
|
||||
static int lpasscc_sm6115_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qcom_cc_desc *desc = of_device_get_match_data(&pdev->dev);
|
||||
|
||||
return qcom_cc_probe_by_index(pdev, 0, desc);
|
||||
}
|
||||
|
||||
static struct platform_driver lpasscc_sm6115_driver = {
|
||||
.probe = lpasscc_sm6115_probe,
|
||||
.driver = {
|
||||
.name = "lpasscc-sm6115",
|
||||
.of_match_table = lpasscc_sm6115_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(lpasscc_sm6115_driver);
|
||||
|
||||
MODULE_DESCRIPTION("QTI LPASSCC SM6115 Driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -37,6 +37,7 @@ enum {
|
|||
P_DSI2_PLL_DSICLK,
|
||||
P_DSI1_PLL_BYTECLK,
|
||||
P_DSI2_PLL_BYTECLK,
|
||||
P_LVDS_PLL,
|
||||
};
|
||||
|
||||
#define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
|
||||
|
@ -143,6 +144,20 @@ static const struct clk_parent_data mmcc_pxo_dsi2_dsi1[] = {
|
|||
{ .fw_name = "dsi1pll", .name = "dsi1pll" },
|
||||
};
|
||||
|
||||
static const struct parent_map mmcc_pxo_dsi2_dsi1_lvds_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_DSI2_PLL_DSICLK, 1 },
|
||||
{ P_LVDS_PLL, 2 },
|
||||
{ P_DSI1_PLL_DSICLK, 3 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data mmcc_pxo_dsi2_dsi1_lvds[] = {
|
||||
{ .fw_name = "pxo", .name = "pxo_board" },
|
||||
{ .fw_name = "dsi2pll", .name = "dsi2pll" },
|
||||
{ .fw_name = "lvdspll", .name = "mpd4_lvds_pll" },
|
||||
{ .fw_name = "dsi1pll", .name = "dsi1pll" },
|
||||
};
|
||||
|
||||
static const struct parent_map mmcc_pxo_dsi1_dsi2_byte_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_DSI1_PLL_BYTECLK, 1 },
|
||||
|
@ -2439,26 +2454,42 @@ static struct clk_rcg dsi2_pixel_src = {
|
|||
},
|
||||
.s = {
|
||||
.src_sel_shift = 0,
|
||||
.parent_map = mmcc_pxo_dsi2_dsi1_map,
|
||||
.parent_map = mmcc_pxo_dsi2_dsi1_lvds_map,
|
||||
},
|
||||
.clkr = {
|
||||
.enable_reg = 0x0094,
|
||||
.enable_mask = BIT(2),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi2_pixel_src",
|
||||
.parent_data = mmcc_pxo_dsi2_dsi1,
|
||||
.num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1),
|
||||
.parent_data = mmcc_pxo_dsi2_dsi1_lvds,
|
||||
.num_parents = ARRAY_SIZE(mmcc_pxo_dsi2_dsi1_lvds),
|
||||
.ops = &clk_rcg_pixel_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch dsi2_pixel_lvds_src = {
|
||||
.clkr = {
|
||||
.enable_reg = 0x0094,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "dsi2_pixel_lvds_src",
|
||||
.parent_hws = (const struct clk_hw*[]){
|
||||
&dsi2_pixel_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch_simple_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch dsi2_pixel_clk = {
|
||||
.halt_reg = 0x01d0,
|
||||
.halt_bit = 19,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0094,
|
||||
.enable_mask = BIT(0),
|
||||
.enable_mask = 0,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mdp_pclk2_clk",
|
||||
.parent_hws = (const struct clk_hw*[]){
|
||||
|
@ -2471,6 +2502,24 @@ static struct clk_branch dsi2_pixel_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch lvds_clk = {
|
||||
.halt_reg = 0x024c,
|
||||
.halt_bit = 6,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0264,
|
||||
.enable_mask = BIT(1),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mdp_lvds_clk",
|
||||
.parent_hws = (const struct clk_hw*[]){
|
||||
&dsi2_pixel_lvds_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gfx2d0_ahb_clk = {
|
||||
.hwcg_reg = 0x0038,
|
||||
.hwcg_bit = 28,
|
||||
|
@ -2799,6 +2848,8 @@ static struct clk_regmap *mmcc_msm8960_clks[] = {
|
|||
[CSIPHY1_TIMER_CLK] = &csiphy1_timer_clk.clkr,
|
||||
[CSIPHY0_TIMER_CLK] = &csiphy0_timer_clk.clkr,
|
||||
[PLL2] = &pll2.clkr,
|
||||
[DSI2_PIXEL_LVDS_SRC] = &dsi2_pixel_lvds_src.clkr,
|
||||
[LVDS_CLK] = &lvds_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map mmcc_msm8960_resets[] = {
|
||||
|
@ -2983,6 +3034,8 @@ static struct clk_regmap *mmcc_apq8064_clks[] = {
|
|||
[VCAP_CLK] = &vcap_clk.clkr,
|
||||
[VCAP_NPL_CLK] = &vcap_npl_clk.clkr,
|
||||
[PLL15] = &pll15.clkr,
|
||||
[DSI2_PIXEL_LVDS_SRC] = &dsi2_pixel_lvds_src.clkr,
|
||||
[LVDS_CLK] = &lvds_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map mmcc_apq8064_resets[] = {
|
||||
|
|
141
drivers/clk/qcom/tcsrcc-sm8750.c
Normal file
141
drivers/clk/qcom/tcsrcc-sm8750.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
/*
|
||||
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,sm8750-tcsr.h>
|
||||
|
||||
#include "clk-branch.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "clk-regmap-mux.h"
|
||||
#include "common.h"
|
||||
|
||||
enum {
|
||||
DT_BI_TCXO_PAD,
|
||||
};
|
||||
|
||||
static struct clk_branch tcsr_pcie_0_clkref_en = {
|
||||
.halt_reg = 0x0,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_pcie_0_clkref_en",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch tcsr_ufs_clkref_en = {
|
||||
.halt_reg = 0x1000,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1000,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_ufs_clkref_en",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.index = DT_BI_TCXO_PAD,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch tcsr_usb2_clkref_en = {
|
||||
.halt_reg = 0x2000,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2000,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb2_clkref_en",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.index = DT_BI_TCXO_PAD,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch tcsr_usb3_clkref_en = {
|
||||
.halt_reg = 0x3000,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x3000,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb3_clkref_en",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.index = DT_BI_TCXO_PAD,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap *tcsr_cc_sm8750_clocks[] = {
|
||||
[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
|
||||
[TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
|
||||
[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
|
||||
[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
|
||||
};
|
||||
|
||||
static const struct regmap_config tcsr_cc_sm8750_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x3000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc tcsr_cc_sm8750_desc = {
|
||||
.config = &tcsr_cc_sm8750_regmap_config,
|
||||
.clks = tcsr_cc_sm8750_clocks,
|
||||
.num_clks = ARRAY_SIZE(tcsr_cc_sm8750_clocks),
|
||||
};
|
||||
|
||||
static const struct of_device_id tcsr_cc_sm8750_match_table[] = {
|
||||
{ .compatible = "qcom,sm8750-tcsr" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tcsr_cc_sm8750_match_table);
|
||||
|
||||
static int tcsr_cc_sm8750_probe(struct platform_device *pdev)
|
||||
{
|
||||
return qcom_cc_probe(pdev, &tcsr_cc_sm8750_desc);
|
||||
}
|
||||
|
||||
static struct platform_driver tcsr_cc_sm8750_driver = {
|
||||
.probe = tcsr_cc_sm8750_probe,
|
||||
.driver = {
|
||||
.name = "tcsr_cc-sm8750",
|
||||
.of_match_table = tcsr_cc_sm8750_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init tcsr_cc_sm8750_init(void)
|
||||
{
|
||||
return platform_driver_register(&tcsr_cc_sm8750_driver);
|
||||
}
|
||||
subsys_initcall(tcsr_cc_sm8750_init);
|
||||
|
||||
static void __exit tcsr_cc_sm8750_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tcsr_cc_sm8750_driver);
|
||||
}
|
||||
module_exit(tcsr_cc_sm8750_exit);
|
||||
|
||||
MODULE_DESCRIPTION("QTI TCSR_CC SM8750 Driver");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -266,7 +266,6 @@ err_clk_unreg:
|
|||
}
|
||||
|
||||
static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {
|
||||
CLK_FIXED("xtal", NULL, 40000000),
|
||||
CLK_FIXED("periph", "xtal", 40000000)
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ config CLK_RENESAS
|
|||
select CLK_R9A07G054 if ARCH_R9A07G054
|
||||
select CLK_R9A08G045 if ARCH_R9A08G045
|
||||
select CLK_R9A09G011 if ARCH_R9A09G011
|
||||
select CLK_R9A09G047 if ARCH_R9A09G047
|
||||
select CLK_R9A09G057 if ARCH_R9A09G057
|
||||
select CLK_SH73A0 if ARCH_SH73A0
|
||||
|
||||
|
@ -194,6 +195,10 @@ config CLK_R9A09G011
|
|||
bool "RZ/V2M clock support" if COMPILE_TEST
|
||||
select CLK_RZG2L
|
||||
|
||||
config CLK_R9A09G047
|
||||
bool "RZ/G3E clock support" if COMPILE_TEST
|
||||
select CLK_RZV2H
|
||||
|
||||
config CLK_R9A09G057
|
||||
bool "RZ/V2H(P) clock support" if COMPILE_TEST
|
||||
select CLK_RZV2H
|
||||
|
@ -234,7 +239,7 @@ config CLK_RZG2L
|
|||
select RESET_CONTROLLER
|
||||
|
||||
config CLK_RZV2H
|
||||
bool "RZ/V2H(P) family clock support" if COMPILE_TEST
|
||||
bool "RZ/{G3E,V2H(P)} family clock support" if COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
|
||||
config CLK_RENESAS_VBATTB
|
||||
|
|
|
@ -37,6 +37,7 @@ obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
|
|||
obj-$(CONFIG_CLK_R9A07G054) += r9a07g044-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A08G045) += r9a08g045-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A09G011) += r9a09g011-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A09G047) += r9a09g047-cpg.o
|
||||
obj-$(CONFIG_CLK_R9A09G057) += r9a09g057-cpg.o
|
||||
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
|
||||
|
||||
|
|
|
@ -238,6 +238,10 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
|
|||
DEF_MOD("pfc2", 917, R8A779G0_CLK_CP),
|
||||
DEF_MOD("pfc3", 918, R8A779G0_CLK_CP),
|
||||
DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M),
|
||||
DEF_MOD("vspx0", 1028, R8A779G0_CLK_S0D1_VIO),
|
||||
DEF_MOD("vspx1", 1029, R8A779G0_CLK_S0D1_VIO),
|
||||
DEF_MOD("fcpvx0", 1100, R8A779G0_CLK_S0D1_VIO),
|
||||
DEF_MOD("fcpvx1", 1101, R8A779G0_CLK_S0D1_VIO),
|
||||
DEF_MOD("tsn", 2723, R8A779G0_CLK_S0D4_HSC),
|
||||
DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
|
||||
DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
|
||||
|
|
|
@ -177,6 +177,9 @@ static const struct mssr_mod_clk r8a779h0_mod_clks[] __initconst = {
|
|||
DEF_MOD("canfd0", 328, R8A779H0_CLK_SASYNCPERD2),
|
||||
DEF_MOD("csi40", 331, R8A779H0_CLK_CSI),
|
||||
DEF_MOD("csi41", 400, R8A779H0_CLK_CSI),
|
||||
DEF_MOD("dis0", 411, R8A779H0_CLK_VIOBUSD2),
|
||||
DEF_MOD("dsitxlink0", 415, R8A779H0_CLK_VIOBUSD2),
|
||||
DEF_MOD("fcpvd0", 508, R8A779H0_CLK_VIOBUSD2),
|
||||
DEF_MOD("hscif0", 514, R8A779H0_CLK_SASYNCPERD1),
|
||||
DEF_MOD("hscif1", 515, R8A779H0_CLK_SASYNCPERD1),
|
||||
DEF_MOD("hscif2", 516, R8A779H0_CLK_SASYNCPERD1),
|
||||
|
@ -225,6 +228,7 @@ static const struct mssr_mod_clk r8a779h0_mod_clks[] __initconst = {
|
|||
DEF_MOD("vin15", 811, R8A779H0_CLK_S0D4_VIO),
|
||||
DEF_MOD("vin16", 812, R8A779H0_CLK_S0D4_VIO),
|
||||
DEF_MOD("vin17", 813, R8A779H0_CLK_S0D4_VIO),
|
||||
DEF_MOD("vspd0", 830, R8A779H0_CLK_VIOBUSD2),
|
||||
DEF_MOD("wdt1:wdt0", 907, R8A779H0_CLK_R),
|
||||
DEF_MOD("cmt0", 910, R8A779H0_CLK_R),
|
||||
DEF_MOD("cmt1", 911, R8A779H0_CLK_R),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user