mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 09:40:58 +07:00
There are a few changes to the core framework this time around, in addition to
the normal collection of driver updates to support new SoCs, fix incorrect data, and convert various drivers to clk_hw based APIs. In the core, we allow clk_ops::init() to return an error code now so that we can fail clk registration if the callback does something like fail to allocate memory. We also add a new "terminate" clk_op so that things done in clk_ops::init() can be undone, e.g. free memory. We also spit out a warning now when critical clks fail to enable and we support changing clk rates and enable/disable state through debugfs when developers compile the kernel themselves. On the driver front, we get support for what seems like a lot of Qualcomm and NXP SoCs given that those vendors dominate the diffstat. There are a couple new drivers for Xilinx and Amlogic SoCs too. The updates are all small things like fixing the way glitch free muxes switch parents, avoiding div-by-zero problems, or fixing data like parent names. See the updates section below for more details. Finally, the "basic" clk types have been converted to support specifying parents with clk_hw pointers. This work includes an overhaul of the fixed-rate clk type to be more modern by using clk_hw APIs. Core: - Let clk_ops::init() return an error code - Add a clk_ops::terminate() callback to undo clk_ops::init() - Warn about critical clks that fail to enable or prepare - Support dangerous debugfs actions on clks with dead code New Drivers: - Support for Xilinx Versal platform clks - Display clk controller on qcom sc7180 - Video clk controller on qcom sc7180 - Graphics clk controller on qcom sc7180 - CPU PLLs for qcom msm8916 - Move qcom msm8974 gfx3d clk to RPM control - Display port clk support on qcom sdm845 SoCs - Global clk controller on qcom ipq6018 - Add a driver for BCLK of Freescale SAI cores - Add cam, vpe and sgx clock support for TI dra7 - Add aess clock support for TI omap5 - Enable clks for CPUfreq on Allwinner A64 SoCs - Add Amlogic meson8b DDR clock controller - Add input clocks to Amlogic meson8b controllers - Add SPIBSC (SPI FLASH) clock on Renesas RZ/A2 - i.MX8MP clk driver support Updates: - Convert gpio, fixed-factor, mux, gate, divider basic clks to hw based APIs - Detect more PRMCU variants in ux500 driver - Adjust the composite clk type to new way of describing clk parents - Fixes for clk controllers on qcom msm8998 SoCs - Fix gmac main clock for TI dra7 - Move TI dra7-atl clock header to correct location - Fix hidden node name dependency on TI clkctrl clocks - Fix Amlogic meson8b mali clock update using the glitch free mux - Fix Amlogic pll driver division by zero at init - Prepare for split of Renesas R-Car H3 ES1.x and ES2.0+ config symbols - Switch more i.MX clk drivers to clk_hw based APIs - Disable non-functional divider between pll4_audio_div and pll4_post_div on imx6q - Fix watchdog2 clock name typo in imx7ulp clock driver - Set CLK_GET_RATE_NOCACHE flag for DRAM related clocks on i.MX8M SoCs - Suppress bind attrs for i.MX8M clock driver - Add a big comment in imx8qxp-lpcg driver to tell why devm_platform_ioremap_resource() shouldn't be used for the driver - A correction on i.MX8MN usb1_ctrl parent clock setting -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAl44cXMRHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSVK5RAA2RUSUv8VI8Yg5ppZjJsQaVfTFBe6/djt fToQ81J2vDorCGAhJQmPPBob8Ylxbw903k7480LYHxe3jghf9rA9NtiTEF/1F/YJ 6EebFMSppRo+UeUAHUp78VQmMS3xgVDyod9nfHacMKd1wM2GCPFW+Nlz/uc/Y6tC CEkeVIyRejatX0ZkNK8IhtQF5VGNXh//9DfWwPORJsJrXpJPLJLVkPC5xqfJaBTZ uh/y7VJnYvJ6Yw5fm5mhzGvwjevuR2jpej+pHnCVvTAn4reg5tXH982T/u5rf71T I+6QDpclCNRduz3HeYcLygDa5vSYlT/7A2eucAB+OURGFjN7dpaDf3nUgxwZOgv/ LSV4g83rAob3mRofLKSfTwh2B/cBl9YKvMrZljnABg1RpFl03PUEZx437hPyT0vP S3uXdrH1yQpY/GZ94G2nBaV7AYzEYp5DJD72bWVNlAhhScIdblc5ANUQya7dHQdp EWMecfqt8PnBwj2WqHUXlz9uFdLQVughyp7bxUtJeD1+x91a05+sk2guntA4Ao6S Xn7eBIElbAIgMVUmVroKGEtJoA2JTDzQj4xQ337lp9MKOGAuytf6HHja/lBSanbu xB4gjrTuFHIHOPiiYpuG3UIX+NVwQzCfRvUZqcv0mUCTGwLrs620wMrzadUGMmIF +ajwSdMmS2o= =UjXu -----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: "There are a few changes to the core framework this time around, in addition to the normal collection of driver updates to support new SoCs, fix incorrect data, and convert various drivers to clk_hw based APIs. In the core, we allow clk_ops::init() to return an error code now so that we can fail clk registration if the callback does something like fail to allocate memory. We also add a new "terminate" clk_op so that things done in clk_ops::init() can be undone, e.g. free memory. We also spit out a warning now when critical clks fail to enable and we support changing clk rates and enable/disable state through debugfs when developers compile the kernel themselves. On the driver front, we get support for what seems like a lot of Qualcomm and NXP SoCs given that those vendors dominate the diffstat. There are a couple new drivers for Xilinx and Amlogic SoCs too. The updates are all small things like fixing the way glitch free muxes switch parents, avoiding div-by-zero problems, or fixing data like parent names. See the updates section below for more details. Finally, the "basic" clk types have been converted to support specifying parents with clk_hw pointers. This work includes an overhaul of the fixed-rate clk type to be more modern by using clk_hw APIs. Core: - Let clk_ops::init() return an error code - Add a clk_ops::terminate() callback to undo clk_ops::init() - Warn about critical clks that fail to enable or prepare - Support dangerous debugfs actions on clks with dead code New Drivers: - Support for Xilinx Versal platform clks - Display clk controller on qcom sc7180 - Video clk controller on qcom sc7180 - Graphics clk controller on qcom sc7180 - CPU PLLs for qcom msm8916 - Move qcom msm8974 gfx3d clk to RPM control - Display port clk support on qcom sdm845 SoCs - Global clk controller on qcom ipq6018 - Add a driver for BCLK of Freescale SAI cores - Add cam, vpe and sgx clock support for TI dra7 - Add aess clock support for TI omap5 - Enable clks for CPUfreq on Allwinner A64 SoCs - Add Amlogic meson8b DDR clock controller - Add input clocks to Amlogic meson8b controllers - Add SPIBSC (SPI FLASH) clock on Renesas RZ/A2 - i.MX8MP clk driver support Updates: - Convert gpio, fixed-factor, mux, gate, divider basic clks to hw based APIs - Detect more PRMCU variants in ux500 driver - Adjust the composite clk type to new way of describing clk parents - Fixes for clk controllers on qcom msm8998 SoCs - Fix gmac main clock for TI dra7 - Move TI dra7-atl clock header to correct location - Fix hidden node name dependency on TI clkctrl clocks - Fix Amlogic meson8b mali clock update using the glitch free mux - Fix Amlogic pll driver division by zero at init - Prepare for split of Renesas R-Car H3 ES1.x and ES2.0+ config symbols - Switch more i.MX clk drivers to clk_hw based APIs - Disable non-functional divider between pll4_audio_div and pll4_post_div on imx6q - Fix watchdog2 clock name typo in imx7ulp clock driver - Set CLK_GET_RATE_NOCACHE flag for DRAM related clocks on i.MX8M SoCs - Suppress bind attrs for i.MX8M clock driver - Add a big comment in imx8qxp-lpcg driver to tell why devm_platform_ioremap_resource() shouldn't be used for the driver - A correction on i.MX8MN usb1_ctrl parent clock setting" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (140 commits) dt/bindings: clk: fsl,plldig: Drop 'bindings' from schema id clk: ls1028a: Fix warning on clamp() usage clk: qoriq: add ls1088a hwaccel clocks support clk: ls1028a: Add clock driver for Display output interface dt/bindings: clk: Add YAML schemas for LS1028A Display Clock bindings clk: fsl-sai: new driver dt-bindings: clock: document the fsl-sai driver clk: composite: add _register_composite_pdata() variants clk: qcom: rpmh: Sort OF match table dt-bindings: fix warnings in validation of qcom,gcc.yaml dt-binding: fix compilation error of the example in qcom,gcc.yaml clk: zynqmp: Add support for clock with CLK_DIVIDER_POWER_OF_TWO flag clk: zynqmp: Fix divider calculation clk: zynqmp: Add support for get max divider clk: zynqmp: Warn user if clock user are more than allowed clk: zynqmp: Extend driver for versal dt-bindings: clock: Add bindings for versal clock driver clk: ti: clkctrl: Fix hidden dependency to node name clk: ti: add clkctrl data dra7 sgx clk: ti: omap5: Add missing AESS clock ...
This commit is contained in:
commit
f4a6365ae8
@ -0,0 +1,50 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/amlogic,meson8-ddr-clkc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic DDR Clock Controller Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- amlogic,meson8-ddr-clkc
|
||||
- amlogic,meson8b-ddr-clkc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xtal
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- "#clock-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
ddr_clkc: clock-controller@400 {
|
||||
compatible = "amlogic,meson8-ddr-clkc";
|
||||
reg = <0x400 0x20>;
|
||||
clocks = <&xtal>;
|
||||
clock-names = "xtal";
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
@ -11,6 +11,11 @@ Required Properties:
|
||||
- "amlogic,meson8m2-clkc" for Meson8m2 (S812) SoCs
|
||||
- #clock-cells: should be 1.
|
||||
- #reset-cells: should be 1.
|
||||
- clocks: list of clock phandles, one for each entry in clock-names
|
||||
- clock-names: should contain the following:
|
||||
* "xtal": the 24MHz system oscillator
|
||||
* "ddr_pll": the DDR PLL clock
|
||||
* "clk_32k": (if present) the 32kHz clock signal from GPIOAO_6 (CLK_32K_IN)
|
||||
|
||||
Parent node should have the following properties :
|
||||
- compatible: "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon"
|
||||
|
54
Documentation/devicetree/bindings/clock/fsl,plldig.yaml
Normal file
54
Documentation/devicetree/bindings/clock/fsl,plldig.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/fsl,plldig.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP QorIQ Layerscape LS1028A Display PIXEL Clock Binding
|
||||
|
||||
maintainers:
|
||||
- Wen He <wen.he_1@nxp.com>
|
||||
|
||||
description: |
|
||||
NXP LS1028A has a clock domain PXLCLK0 used for the Display output
|
||||
interface in the display core, as implemented in TSMC CLN28HPM PLL.
|
||||
which generate and offers pixel clocks to Display.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,ls1028a-plldig
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
fsl,vco-hz:
|
||||
description: Optional for VCO frequency of the PLL in Hertz.
|
||||
The VCO frequency of this PLL cannot be changed during runtime
|
||||
only at startup. Therefore, the output frequencies are very
|
||||
limited and might not even closely match the requested frequency.
|
||||
To work around this restriction the user may specify its own
|
||||
desired VCO frequency for the PLL.
|
||||
minimum: 650000000
|
||||
maximum: 1300000000
|
||||
default: 1188000000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- '#clock-cells'
|
||||
|
||||
examples:
|
||||
# Display PIXEL Clock node:
|
||||
- |
|
||||
dpclk: clock-display@f1f0000 {
|
||||
compatible = "fsl,ls1028a-plldig";
|
||||
reg = <0x0 0xf1f0000 0x0 0xffff>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&osc_27m>;
|
||||
};
|
||||
|
||||
...
|
55
Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
Normal file
55
Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/fsl,sai-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale SAI bitclock-as-a-clock binding
|
||||
|
||||
maintainers:
|
||||
- Michael Walle <michael@walle.cc>
|
||||
|
||||
description: |
|
||||
It is possible to use the BCLK pin of a SAI module as a generic clock
|
||||
output. Some SoC are very constrained in their pin multiplexer
|
||||
configuration. Eg. pins can only be changed groups. For example, on the
|
||||
LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
|
||||
the second pins are wasted. Using this binding it is possible to use the
|
||||
clock of the second SAI as a MCLK clock for an audio codec, for example.
|
||||
|
||||
This is a composite of a gated clock and a divider clock.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,vf610-sai-clock
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
mclk: clock-mclk@f130080 {
|
||||
compatible = "fsl,vf610-sai-clock";
|
||||
reg = <0x0 0xf130080 0x0 0x80>;
|
||||
#clock-cells = <0>;
|
||||
clocks = <&parentclk>;
|
||||
};
|
||||
};
|
68
Documentation/devicetree/bindings/clock/imx8mp-clock.yaml
Normal file
68
Documentation/devicetree/bindings/clock/imx8mp-clock.yaml
Normal file
@ -0,0 +1,68 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/imx8mp-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP i.MX8M Plus Clock Control Module Binding
|
||||
|
||||
maintainers:
|
||||
- Anson Huang <Anson.Huang@nxp.com>
|
||||
|
||||
description:
|
||||
NXP i.MX8M Plus clock control module is an integrated clock controller, which
|
||||
generates and supplies to all modules.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx8mp-ccm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: 32k osc
|
||||
- description: 24m osc
|
||||
- description: ext1 clock input
|
||||
- description: ext2 clock input
|
||||
- description: ext3 clock input
|
||||
- description: ext4 clock input
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: osc_32k
|
||||
- const: osc_24m
|
||||
- const: clk_ext1
|
||||
- const: clk_ext2
|
||||
- const: clk_ext3
|
||||
- const: clk_ext4
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
description:
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mp-clock.h
|
||||
for the full list of i.MX8M Plus clock IDs.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
|
||||
examples:
|
||||
# Clock Control Module node:
|
||||
- |
|
||||
clk: clock-controller@30380000 {
|
||||
compatible = "fsl,imx8mp-ccm";
|
||||
reg = <0x30380000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>,
|
||||
<&clk_ext2>, <&clk_ext3>, <&clk_ext4>;
|
||||
clock-names = "osc_32k", "osc_24m", "clk_ext1",
|
||||
"clk_ext2", "clk_ext3", "clk_ext4";
|
||||
};
|
||||
|
||||
...
|
@ -1,19 +0,0 @@
|
||||
Qualcomm Technologies, Inc. Display Clock Controller Binding
|
||||
------------------------------------------------------------
|
||||
|
||||
Required properties :
|
||||
|
||||
- compatible : shall contain "qcom,sdm845-dispcc"
|
||||
- reg : shall contain base register location and length.
|
||||
- #clock-cells : from common clock binding, shall contain 1.
|
||||
- #reset-cells : from common reset binding, shall contain 1.
|
||||
- #power-domain-cells : from generic power domain binding, shall contain 1.
|
||||
|
||||
Example:
|
||||
dispcc: clock-controller@af00000 {
|
||||
compatible = "qcom,sdm845-dispcc";
|
||||
reg = <0xaf00000 0x100000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
67
Documentation/devicetree/bindings/clock/qcom,dispcc.yaml
Normal file
67
Documentation/devicetree/bindings/clock/qcom,dispcc.yaml
Normal file
@ -0,0 +1,67 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/qcom,dispcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display Clock & Reset Controller Binding
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm display clock control module which supports the clocks, resets and
|
||||
power domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7180-dispcc
|
||||
- qcom,sdm845-dispcc
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: GPLL0 source from GCC
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: gpll0
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
examples:
|
||||
# Example of DISPCC with clock node properties for SDM845:
|
||||
- |
|
||||
clock-controller@af00000 {
|
||||
compatible = "qcom,sdm845-dispcc";
|
||||
reg = <0xaf00000 0x10000>;
|
||||
clocks = <&rpmhcc 0>, <&gcc 24>;
|
||||
clock-names = "xo", "gpll0";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
@ -19,8 +19,9 @@ properties:
|
||||
enum:
|
||||
- qcom,gcc-apq8064
|
||||
- qcom,gcc-apq8084
|
||||
- qcom,gcc-ipq8064
|
||||
- qcom,gcc-ipq4019
|
||||
- qcom,gcc-ipq6018
|
||||
- qcom,gcc-ipq8064
|
||||
- qcom,gcc-ipq8074
|
||||
- qcom,gcc-msm8660
|
||||
- qcom,gcc-msm8916
|
||||
@ -40,20 +41,50 @@ properties:
|
||||
- qcom,gcc-sm8150
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
oneOf:
|
||||
#qcom,gcc-sm8150
|
||||
#qcom,gcc-sc7180
|
||||
- items:
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
#qcom,gcc-msm8996
|
||||
- items:
|
||||
- description: XO source
|
||||
- description: Second XO source
|
||||
- description: Sleep clock source
|
||||
#qcom,gcc-msm8998
|
||||
- items:
|
||||
- description: Board XO source
|
||||
- description: Sleep clock source
|
||||
- description: USB 3.0 phy pipe clock
|
||||
- description: UFS phy rx symbol clock for pipe 0
|
||||
- description: UFS phy rx symbol clock for pipe 1
|
||||
- description: UFS phy tx symbol clock
|
||||
- description: PCIE phy pipe clock
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
- const: sleep_clk
|
||||
oneOf:
|
||||
#qcom,gcc-sm8150
|
||||
#qcom,gcc-sc7180
|
||||
- items:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
- const: sleep_clk
|
||||
#qcom,gcc-msm8996
|
||||
- items:
|
||||
- const: cxo
|
||||
- const: cxo2
|
||||
- const: sleep_clk
|
||||
#qcom,gcc-msm8998
|
||||
- items:
|
||||
- const: xo
|
||||
- const: sleep_clk
|
||||
- const: usb3_pipe
|
||||
- const: ufs_rx_symbol0
|
||||
- const: ufs_rx_symbol1
|
||||
- const: ufs_tx_symbol0
|
||||
- const: pcie0_pipe
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
@ -118,6 +149,7 @@ else:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,gcc-msm8998
|
||||
- qcom,gcc-sm8150
|
||||
- qcom,gcc-sc7180
|
||||
then:
|
||||
@ -179,10 +211,35 @@ examples:
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-sc7180";
|
||||
reg = <0x100000 0x1f0000>;
|
||||
clocks = <&rpmhcc 0>, <&rpmhcc 1>;
|
||||
clock-names = "bi_tcxo", "bi_tcxo_ao";
|
||||
clocks = <&rpmhcc 0>, <&rpmhcc 1>, <0>;
|
||||
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
# Example of MSM8998 GCC:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-msm8998";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
reg = <0x00100000 0xb0000>;
|
||||
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
|
||||
<&sleep>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>,
|
||||
<0>;
|
||||
clock-names = "xo",
|
||||
"sleep_clk",
|
||||
"usb3_pipe",
|
||||
"ufs_rx_symbol0",
|
||||
"ufs_rx_symbol1",
|
||||
"ufs_tx_symbol0",
|
||||
"pcie0_pipe";
|
||||
};
|
||||
...
|
||||
|
@ -1,24 +0,0 @@
|
||||
Qualcomm Graphics Clock & Reset Controller Binding
|
||||
--------------------------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible : shall contain "qcom,sdm845-gpucc" or "qcom,msm8998-gpucc"
|
||||
- reg : shall contain base register location and length
|
||||
- #clock-cells : from common clock binding, shall contain 1
|
||||
- #reset-cells : from common reset binding, shall contain 1
|
||||
- #power-domain-cells : from generic power domain binding, shall contain 1
|
||||
- clocks : shall contain the XO clock
|
||||
shall contain the gpll0 out main clock (msm8998)
|
||||
- clock-names : shall be "xo"
|
||||
shall be "gpll0" (msm8998)
|
||||
|
||||
Example:
|
||||
gpucc: clock-controller@5090000 {
|
||||
compatible = "qcom,sdm845-gpucc";
|
||||
reg = <0x5090000 0x9000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "xo";
|
||||
};
|
72
Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
Normal file
72
Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
Normal file
@ -0,0 +1,72 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/qcom,gpucc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Graphics Clock & Reset Controller Binding
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm grpahics clock control module which supports the clocks, resets and
|
||||
power domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,msm8998-gpucc
|
||||
- qcom,sc7180-gpucc
|
||||
- qcom,sdm845-gpucc
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: GPLL0 main branch source from GCC(gcc_gpu_gpll0_clk_src)
|
||||
- description: GPLL0 div branch source from GCC(gcc_gpu_gpll0_div_clk_src)
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
items:
|
||||
- const: xo
|
||||
- const: gpll0_main
|
||||
- const: gpll0_div
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
examples:
|
||||
# Example of GPUCC with clock node properties for SDM845:
|
||||
- |
|
||||
clock-controller@5090000 {
|
||||
compatible = "qcom,sdm845-gpucc";
|
||||
reg = <0x5090000 0x9000>;
|
||||
clocks = <&rpmhcc 0>, <&gcc 31>, <&gcc 32>;
|
||||
clock-names = "xo", "gpll0_main", "gpll0_div";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
@ -1,28 +0,0 @@
|
||||
Qualcomm Multimedia Clock & Reset Controller Binding
|
||||
----------------------------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible : shall contain only one of the following:
|
||||
|
||||
"qcom,mmcc-apq8064"
|
||||
"qcom,mmcc-apq8084"
|
||||
"qcom,mmcc-msm8660"
|
||||
"qcom,mmcc-msm8960"
|
||||
"qcom,mmcc-msm8974"
|
||||
"qcom,mmcc-msm8996"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
- #clock-cells : shall contain 1
|
||||
- #reset-cells : shall contain 1
|
||||
|
||||
Optional properties :
|
||||
- #power-domain-cells : shall contain 1
|
||||
|
||||
Example:
|
||||
clock-controller@4000000 {
|
||||
compatible = "qcom,mmcc-msm8960";
|
||||
reg = <0x4000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
98
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
Normal file
98
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
Normal file
@ -0,0 +1,98 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/qcom,mmcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Multimedia Clock & Reset Controller Binding
|
||||
|
||||
maintainers:
|
||||
- Jeffrey Hugo <jhugo@codeaurora.org>
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm multimedia clock control module which supports the clocks, resets and
|
||||
power domains.
|
||||
|
||||
properties:
|
||||
compatible :
|
||||
enum:
|
||||
- qcom,mmcc-apq8064
|
||||
- qcom,mmcc-apq8084
|
||||
- qcom,mmcc-msm8660
|
||||
- qcom,mmcc-msm8960
|
||||
- qcom,mmcc-msm8974
|
||||
- qcom,mmcc-msm8996
|
||||
- qcom,mmcc-msm8998
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board sleep source
|
||||
- description: Global PLL 0 clock
|
||||
- description: DSI phy instance 0 dsi clock
|
||||
- description: DSI phy instance 0 byte clock
|
||||
- description: DSI phy instance 1 dsi clock
|
||||
- description: DSI phy instance 1 byte clock
|
||||
- description: HDMI phy PLL clock
|
||||
- description: DisplayPort phy PLL vco clock
|
||||
- description: DisplayPort phy PLL link clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: sleep
|
||||
- const: gpll0
|
||||
- const: dsi0dsi
|
||||
- const: dsi0byte
|
||||
- const: dsi1dsi
|
||||
- const: dsi1byte
|
||||
- const: hdmipll
|
||||
- const: dpvco
|
||||
- const: dplink
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
protected-clocks:
|
||||
description:
|
||||
Protected clock specifier list as per common clock binding
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: qcom,mmcc-msm8998
|
||||
|
||||
then:
|
||||
required:
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
examples:
|
||||
# Example for MMCC for MSM8960:
|
||||
- |
|
||||
clock-controller@4000000 {
|
||||
compatible = "qcom,mmcc-msm8960";
|
||||
reg = <0x4000000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
@ -1,18 +0,0 @@
|
||||
Qualcomm Video Clock & Reset Controller Binding
|
||||
-----------------------------------------------
|
||||
|
||||
Required properties :
|
||||
- compatible : shall contain "qcom,sdm845-videocc"
|
||||
- reg : shall contain base register location and length
|
||||
- #clock-cells : from common clock binding, shall contain 1.
|
||||
- #power-domain-cells : from generic power domain binding, shall contain 1.
|
||||
- #reset-cells : from common reset binding, shall contain 1.
|
||||
|
||||
Example:
|
||||
videocc: clock-controller@ab00000 {
|
||||
compatible = "qcom,sdm845-videocc";
|
||||
reg = <0xab00000 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
62
Documentation/devicetree/bindings/clock/qcom,videocc.yaml
Normal file
62
Documentation/devicetree/bindings/clock/qcom,videocc.yaml
Normal file
@ -0,0 +1,62 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/qcom,videocc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Video Clock & Reset Controller Binding
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm video clock control module which supports the clocks, resets and
|
||||
power domains.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sc7180-videocc
|
||||
- qcom,sdm845-videocc
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
examples:
|
||||
# Example of VIDEOCC with clock node properties for SDM845:
|
||||
- |
|
||||
clock-controller@ab00000 {
|
||||
compatible = "qcom,sdm845-videocc";
|
||||
reg = <0xab00000 0x10000>;
|
||||
clocks = <&rpmhcc 0>;
|
||||
clock-names = "xo";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
@ -19,7 +19,7 @@ Required Properties:
|
||||
- "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E)
|
||||
- "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C)
|
||||
- "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M)
|
||||
- "renesas,r8a774b1-cpg-mssr" for the r8a774a1 SoC (RZ/G2N)
|
||||
- "renesas,r8a774b1-cpg-mssr" for the r8a774b1 SoC (RZ/G2N)
|
||||
- "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E)
|
||||
- "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2)
|
||||
- "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W)
|
||||
|
@ -16,18 +16,23 @@ For more information, please see the Linux clock framework binding at
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt.
|
||||
|
||||
Required properties :
|
||||
- compatible : shall be "ti,clkctrl"
|
||||
- compatible : shall be "ti,clkctrl" or a clock domain specific name:
|
||||
"ti,clkctrl-l4-cfg"
|
||||
"ti,clkctrl-l4-per"
|
||||
"ti,clkctrl-l4-secure"
|
||||
"ti,clkctrl-l4-wkup"
|
||||
- #clock-cells : shall contain 2 with the first entry being the instance
|
||||
offset from the clock domain base and the second being the
|
||||
clock index
|
||||
- reg : clock registers
|
||||
|
||||
Example: Clock controller node on omap 4430:
|
||||
|
||||
&cm2 {
|
||||
l4per: cm@1400 {
|
||||
cm_l4per@0 {
|
||||
cm_l4per_clkctrl: clk@20 {
|
||||
compatible = "ti,clkctrl";
|
||||
cm_l4per_clkctrl: clock@20 {
|
||||
compatible = "ti,clkctrl-l4-per", "ti,clkctrl";
|
||||
reg = <0x20 0x1b0>;
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ Configuration of ATL instances:
|
||||
- aws : Audio word select signal selection
|
||||
};
|
||||
|
||||
For valid word select signals, see the dt-bindings/clk/ti-dra7-atl.h include
|
||||
For valid word select signals, see the dt-bindings/clock/ti-dra7-atl.h include
|
||||
file.
|
||||
|
||||
Examples:
|
||||
@ -83,7 +83,7 @@ atl: atl@4843c000 {
|
||||
clock-names = "fck";
|
||||
};
|
||||
|
||||
#include <dt-bindings/clk/ti-dra7-atl.h>
|
||||
#include <dt-bindings/clock/ti-dra7-atl.h>
|
||||
|
||||
&atl {
|
||||
|
||||
|
64
Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
Normal file
64
Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
Normal file
@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/bindings/clock/xlnx,versal-clk.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Xilinx Versal clock controller
|
||||
|
||||
maintainers:
|
||||
- Michal Simek <michal.simek@xilinx.com>
|
||||
- Jolly Shah <jolly.shah@xilinx.com>
|
||||
- Rajan Vaja <rajan.vaja@xilinx.com>
|
||||
|
||||
description: |
|
||||
The clock controller is a hardware block of Xilinx versal clock tree. It
|
||||
reads required input clock frequencies from the devicetree and acts as clock
|
||||
provider for all clock consumers of PS clocks.
|
||||
|
||||
select: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: xlnx,versal-clk
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
description: List of clock specifiers which are external input
|
||||
clocks to the given clock controller.
|
||||
items:
|
||||
- description: reference clock
|
||||
- description: alternate reference clock
|
||||
- description: alternate reference clock for programmable logic
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ref
|
||||
- const: alt_ref
|
||||
- const: pl_alt_ref
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
firmware {
|
||||
zynqmp_firmware: zynqmp-firmware {
|
||||
compatible = "xlnx,zynqmp-firmware";
|
||||
method = "smc";
|
||||
versal_clk: clock-controller {
|
||||
#clock-cells = <1>;
|
||||
compatible = "xlnx,versal-clk";
|
||||
clocks = <&ref>, <&alt_ref>, <&pl_alt_ref>;
|
||||
clock-names = "ref", "alt_ref", "pl_alt_ref";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -21,10 +21,11 @@ platforms.
|
||||
Usage: required
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: must specify the base address and size of the global block
|
||||
|
||||
- clocks:
|
||||
Usage: required if #clocks-cells property is present
|
||||
Value type: <phandle>
|
||||
Definition: phandle to the input PLL, which feeds the APCS mux/divider
|
||||
Usage: required if #clock-names property is present
|
||||
Value type: <phandle array>
|
||||
Definition: phandles to the two parent clocks of the clock driver.
|
||||
|
||||
- #mbox-cells:
|
||||
Usage: required
|
||||
@ -36,6 +37,12 @@ platforms.
|
||||
Value type: <u32>
|
||||
Definition: as described in clock.txt, must be 0
|
||||
|
||||
- clock-names:
|
||||
Usage: required if the platform data based clock driver needs to
|
||||
retrieve the parent clock names from device tree.
|
||||
This will requires two mandatory clocks to be defined.
|
||||
Value type: <string-array>
|
||||
Definition: must be "pll" and "aux"
|
||||
|
||||
= EXAMPLE
|
||||
The following example describes the APCS HMSS found in MSM8996 and part of the
|
||||
@ -68,3 +75,14 @@ Below is another example of the APCS binding on MSM8916 platforms:
|
||||
clocks = <&a53pll>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
Below is another example of the APCS binding on QCS404 platforms:
|
||||
|
||||
apcs_glb: mailbox@b011000 {
|
||||
compatible = "qcom,qcs404-apcs-apps-global", "syscon";
|
||||
reg = <0x0b011000 0x1000>;
|
||||
#mbox-cells = <1>;
|
||||
clocks = <&apcs_hfpll>, <&gcc GCC_GPLL0_AO_OUT_MAIN>;
|
||||
clock-names = "pll", "aux";
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/clk/ti-dra7-atl.h>
|
||||
#include <dt-bindings/clock/ti-dra7-atl.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
/ {
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "dra72x.dtsi"
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/clk/ti-dra7-atl.h>
|
||||
#include <dt-bindings/clock/ti-dra7-atl.h>
|
||||
|
||||
/ {
|
||||
compatible = "ti,dra72-evm", "ti,dra722", "ti,dra72", "ti,dra7";
|
||||
|
@ -1734,6 +1734,20 @@ dss_clkctrl: dss-clkctrl@20 {
|
||||
};
|
||||
};
|
||||
|
||||
gpu_cm: gpu-cm@1200 {
|
||||
compatible = "ti,omap4-cm";
|
||||
reg = <0x1200 0x100>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0 0x1200 0x100>;
|
||||
|
||||
gpu_clkctrl: gpu-clkctrl@20 {
|
||||
compatible = "ti,clkctrl";
|
||||
reg = <0x20 0x4>;
|
||||
#clock-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
l3init_cm: l3init-cm@1300 {
|
||||
compatible = "ti,omap4-cm";
|
||||
reg = <0x1300 0x100>;
|
||||
|
@ -27,7 +27,7 @@ config COMMON_CLK_WM831X
|
||||
tristate "Clock driver for WM831x/2x PMICs"
|
||||
depends on MFD_WM831X
|
||||
---help---
|
||||
Supports the clocking subsystem of the WM831x/2x series of
|
||||
Supports the clocking subsystem of the WM831x/2x series of
|
||||
PMICs from Wolfson Microelectronics.
|
||||
|
||||
source "drivers/clk/versatile/Kconfig"
|
||||
@ -174,6 +174,18 @@ config COMMON_CLK_CS2000_CP
|
||||
help
|
||||
If you say yes here you get support for the CS2000 clock multiplier.
|
||||
|
||||
config COMMON_CLK_FSL_SAI
|
||||
bool "Clock driver for BCLK of Freescale SAI cores"
|
||||
depends on ARCH_LAYERSCAPE || COMPILE_TEST
|
||||
help
|
||||
This driver supports the Freescale SAI (Synchronous Audio Interface)
|
||||
to be used as a generic clock output. Some SoCs have restrictions
|
||||
regarding the possible pin multiplexer settings. Eg. on some SoCs
|
||||
two SAI interfaces can only be enabled together. If just one is
|
||||
needed, the BCLK pin of the second one can be used as general
|
||||
purpose clock output. Ideally, it can be used to drive an audio
|
||||
codec (sometimes known as MCLK).
|
||||
|
||||
config COMMON_CLK_GEMINI
|
||||
bool "Clock driver for Cortina Systems Gemini SoC"
|
||||
depends on ARCH_GEMINI || COMPILE_TEST
|
||||
@ -225,6 +237,16 @@ config CLK_QORIQ
|
||||
This adds the clock driver support for Freescale QorIQ platforms
|
||||
using common clock framework.
|
||||
|
||||
config CLK_LS1028A_PLLDIG
|
||||
tristate "Clock driver for LS1028A Display output"
|
||||
depends on ARCH_LAYERSCAPE || COMPILE_TEST
|
||||
default ARCH_LAYERSCAPE
|
||||
help
|
||||
This driver support the Display output interfaces(LCD, DPHY) pixel clocks
|
||||
of the QorIQ Layerscape LS1028A, as implemented TSMC CLN28HPM PLL. Not all
|
||||
features of the PLL are currently supported by the driver. By default,
|
||||
configured bypass mode with this PLL.
|
||||
|
||||
config COMMON_CLK_XGENE
|
||||
bool "Clock driver for APM XGene SoC"
|
||||
default ARCH_XGENE
|
||||
|
@ -29,6 +29,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
||||
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
||||
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
|
||||
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
|
||||
obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
|
||||
obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
|
||||
obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
|
||||
obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o
|
||||
@ -44,6 +45,7 @@ obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o
|
||||
obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o
|
||||
obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o
|
||||
obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o
|
||||
obj-$(CONFIG_CLK_LS1028A_PLLDIG) += clk-plldig.o
|
||||
obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o
|
||||
obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o
|
||||
obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o
|
||||
|
@ -25,7 +25,8 @@
|
||||
#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
|
||||
|
||||
#define PMC_PLL_ACR 0x18
|
||||
#define PMC_PLL_ACR_DEFAULT 0x1b040010UL
|
||||
#define PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL
|
||||
#define PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL
|
||||
#define PMC_PLL_ACR_UTMIVR BIT(12)
|
||||
#define PMC_PLL_ACR_UTMIBG BIT(13)
|
||||
#define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24)
|
||||
@ -88,7 +89,10 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
|
||||
}
|
||||
|
||||
/* Recommended value for PMC_PLL_ACR */
|
||||
val = PMC_PLL_ACR_DEFAULT;
|
||||
if (pll->characteristics->upll)
|
||||
val = PMC_PLL_ACR_DEFAULT_UPLL;
|
||||
else
|
||||
val = PMC_PLL_ACR_DEFAULT_PLLA;
|
||||
regmap_write(regmap, PMC_PLL_ACR, val);
|
||||
|
||||
regmap_write(regmap, PMC_PLL_CTRL1,
|
||||
|
@ -47,6 +47,7 @@ static const struct clk_programmable_layout sam9x60_programmable_layout = {
|
||||
.pres_shift = 8,
|
||||
.css_mask = 0x1f,
|
||||
.have_slck_mck = 0,
|
||||
.is_pres_direct = 1,
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout sam9x60_pcr_layout = {
|
||||
|
@ -260,7 +260,6 @@ static void __init asm9260_acc_init(struct device_node *np)
|
||||
const char *ref_clk, *pll_clk = "pll";
|
||||
u32 rate;
|
||||
int n;
|
||||
u32 accuracy = 0;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
@ -275,10 +274,11 @@ static void __init asm9260_acc_init(struct device_node *np)
|
||||
/* register pll */
|
||||
rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
|
||||
|
||||
/* TODO: Convert to DT parent scheme */
|
||||
ref_clk = of_clk_get_parent_name(np, 0);
|
||||
accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
|
||||
hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
|
||||
ref_clk, 0, rate, accuracy);
|
||||
hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk,
|
||||
ref_clk, NULL, NULL, 0, rate, 0,
|
||||
CLK_FIXED_RATE_PARENT_ACCURACY);
|
||||
|
||||
if (IS_ERR(hw))
|
||||
panic("%pOFn: can't register REFCLK. Check DT!", np);
|
||||
|
@ -474,11 +474,10 @@ static struct bm1880_composite_clock bm1880_composite_clks[] = {
|
||||
static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate)
|
||||
{
|
||||
u64 numerator;
|
||||
u32 fbdiv, fref, refdiv;
|
||||
u32 fbdiv, refdiv;
|
||||
u32 postdiv1, postdiv2, denominator;
|
||||
|
||||
fbdiv = (regval >> 16) & 0xfff;
|
||||
fref = parent_rate;
|
||||
refdiv = regval & 0x1f;
|
||||
postdiv1 = (regval >> 8) & 0x7;
|
||||
postdiv2 = (regval >> 12) & 0x7;
|
||||
|
@ -199,8 +199,9 @@ static void clk_composite_disable(struct clk_hw *hw)
|
||||
gate_ops->disable(gate_hw);
|
||||
}
|
||||
|
||||
struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
|
||||
const char * const *parent_names, int num_parents,
|
||||
static struct clk_hw *__clk_hw_register_composite(struct device *dev,
|
||||
const char *name, const char * const *parent_names,
|
||||
const struct clk_parent_data *pdata, int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
@ -218,7 +219,10 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
|
||||
|
||||
init.name = name;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
if (parent_names)
|
||||
init.parent_names = parent_names;
|
||||
else
|
||||
init.parent_data = pdata;
|
||||
init.num_parents = num_parents;
|
||||
hw = &composite->hw;
|
||||
|
||||
@ -312,6 +316,34 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
|
||||
return hw;
|
||||
}
|
||||
|
||||
struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
|
||||
const char * const *parent_names, int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
unsigned long flags)
|
||||
{
|
||||
return __clk_hw_register_composite(dev, name, parent_names, NULL,
|
||||
num_parents, mux_hw, mux_ops,
|
||||
rate_hw, rate_ops, gate_hw,
|
||||
gate_ops, flags);
|
||||
}
|
||||
|
||||
struct clk_hw *clk_hw_register_composite_pdata(struct device *dev,
|
||||
const char *name,
|
||||
const struct clk_parent_data *parent_data,
|
||||
int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
unsigned long flags)
|
||||
{
|
||||
return __clk_hw_register_composite(dev, name, NULL, parent_data,
|
||||
num_parents, mux_hw, mux_ops,
|
||||
rate_hw, rate_ops, gate_hw,
|
||||
gate_ops, flags);
|
||||
}
|
||||
|
||||
struct clk *clk_register_composite(struct device *dev, const char *name,
|
||||
const char * const *parent_names, int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
@ -329,6 +361,24 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
|
||||
const struct clk_parent_data *parent_data,
|
||||
int num_parents,
|
||||
struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
|
||||
struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
|
||||
struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_composite_pdata(dev, name, parent_data,
|
||||
num_parents, mux_hw, mux_ops, rate_hw, rate_ops,
|
||||
gate_hw, gate_ops, flags);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
void clk_unregister_composite(struct clk *clk)
|
||||
{
|
||||
struct clk_composite *composite;
|
||||
|
@ -463,11 +463,12 @@ const struct clk_ops clk_divider_ro_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
|
||||
|
||||
static struct clk_hw *_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_divider_flags, const struct clk_div_table *table,
|
||||
spinlock_t *lock)
|
||||
struct clk_hw *__clk_hw_register_divider(struct device *dev,
|
||||
struct device_node *np, const char *name,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
|
||||
const struct clk_div_table *table, spinlock_t *lock)
|
||||
{
|
||||
struct clk_divider *div;
|
||||
struct clk_hw *hw;
|
||||
@ -514,55 +515,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_register_divider - register a divider clock with the clock framework
|
||||
* @dev: device registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of clock's parent
|
||||
* @flags: framework-specific flags
|
||||
* @reg: register address to adjust divider
|
||||
* @shift: number of bits to shift the bitfield
|
||||
* @width: width of the bitfield
|
||||
* @clk_divider_flags: divider-specific flags for this clock
|
||||
* @lock: shared register lock for this clock
|
||||
*/
|
||||
struct clk *clk_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_divider_flags, spinlock_t *lock)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, NULL, lock);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_divider);
|
||||
|
||||
/**
|
||||
* clk_hw_register_divider - register a divider clock with the clock framework
|
||||
* @dev: device registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of clock's parent
|
||||
* @flags: framework-specific flags
|
||||
* @reg: register address to adjust divider
|
||||
* @shift: number of bits to shift the bitfield
|
||||
* @width: width of the bitfield
|
||||
* @clk_divider_flags: divider-specific flags for this clock
|
||||
* @lock: shared register lock for this clock
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_divider_flags, spinlock_t *lock)
|
||||
{
|
||||
return _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, NULL, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_divider);
|
||||
EXPORT_SYMBOL_GPL(__clk_hw_register_divider);
|
||||
|
||||
/**
|
||||
* clk_register_divider_table - register a table based divider clock with
|
||||
@ -586,39 +539,15 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, table, lock);
|
||||
hw = __clk_hw_register_divider(dev, NULL, name, parent_name, NULL,
|
||||
NULL, flags, reg, shift, width, clk_divider_flags,
|
||||
table, lock);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_divider_table);
|
||||
|
||||
/**
|
||||
* clk_hw_register_divider_table - register a table based divider clock with
|
||||
* the clock framework
|
||||
* @dev: device registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of clock's parent
|
||||
* @flags: framework-specific flags
|
||||
* @reg: register address to adjust divider
|
||||
* @shift: number of bits to shift the bitfield
|
||||
* @width: width of the bitfield
|
||||
* @clk_divider_flags: divider-specific flags for this clock
|
||||
* @table: array of divider/value pairs ending with a div set to 0
|
||||
* @lock: shared register lock for this clock
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_divider_table(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_divider_flags, const struct clk_div_table *table,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
return _register_divider(dev, name, parent_name, flags, reg, shift,
|
||||
width, clk_divider_flags, table, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
|
||||
|
||||
void clk_unregister_divider(struct clk *clk)
|
||||
{
|
||||
struct clk_divider *div;
|
||||
|
@ -24,6 +24,8 @@
|
||||
* parent - fixed parent. No clk_set_parent support
|
||||
*/
|
||||
|
||||
#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
|
||||
|
||||
static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
@ -33,7 +35,12 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
|
||||
static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw,
|
||||
unsigned long parent_accuracy)
|
||||
{
|
||||
return to_clk_fixed_rate(hw)->fixed_accuracy;
|
||||
struct clk_fixed_rate *fixed = to_clk_fixed_rate(hw);
|
||||
|
||||
if (fixed->flags & CLK_FIXED_RATE_PARENT_ACCURACY)
|
||||
return parent_accuracy;
|
||||
|
||||
return fixed->fixed_accuracy;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_fixed_rate_ops = {
|
||||
@ -42,24 +49,17 @@ const struct clk_ops clk_fixed_rate_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
|
||||
|
||||
/**
|
||||
* clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
|
||||
* the clock framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of clock's parent
|
||||
* @flags: framework-specific flags
|
||||
* @fixed_rate: non-adjustable clock rate
|
||||
* @fixed_accuracy: non-adjustable clock rate
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned long fixed_rate, unsigned long fixed_accuracy)
|
||||
struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
|
||||
struct device_node *np, const char *name,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data, unsigned long flags,
|
||||
unsigned long fixed_rate, unsigned long fixed_accuracy,
|
||||
unsigned long clk_fixed_flags)
|
||||
{
|
||||
struct clk_fixed_rate *fixed;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init = {};
|
||||
int ret;
|
||||
int ret = -EINVAL;
|
||||
|
||||
/* allocate fixed-rate clock */
|
||||
fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
|
||||
@ -69,17 +69,26 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
|
||||
init.name = name;
|
||||
init.ops = &clk_fixed_rate_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = (parent_name ? &parent_name: NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
init.parent_names = parent_name ? &parent_name : NULL;
|
||||
init.parent_hws = parent_hw ? &parent_hw : NULL;
|
||||
init.parent_data = parent_data;
|
||||
if (parent_name || parent_hw || parent_data)
|
||||
init.num_parents = 1;
|
||||
else
|
||||
init.num_parents = 0;
|
||||
|
||||
/* struct clk_fixed_rate assignments */
|
||||
fixed->flags = clk_fixed_flags;
|
||||
fixed->fixed_rate = fixed_rate;
|
||||
fixed->fixed_accuracy = fixed_accuracy;
|
||||
fixed->hw.init = &init;
|
||||
|
||||
/* register the clock */
|
||||
hw = &fixed->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (dev || !np)
|
||||
ret = clk_hw_register(dev, hw);
|
||||
else if (np)
|
||||
ret = of_clk_hw_register(np, hw);
|
||||
if (ret) {
|
||||
kfree(fixed);
|
||||
hw = ERR_PTR(ret);
|
||||
@ -87,46 +96,19 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
|
||||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
|
||||
|
||||
struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned long fixed_rate, unsigned long fixed_accuracy)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
|
||||
flags, fixed_rate, fixed_accuracy);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
|
||||
|
||||
/**
|
||||
* clk_hw_register_fixed_rate - register fixed-rate clock with the clock
|
||||
* framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of clock's parent
|
||||
* @flags: framework-specific flags
|
||||
* @fixed_rate: non-adjustable clock rate
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
unsigned long fixed_rate)
|
||||
{
|
||||
return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
|
||||
flags, fixed_rate, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
|
||||
EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_rate);
|
||||
|
||||
struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
unsigned long fixed_rate)
|
||||
{
|
||||
return clk_register_fixed_rate_with_accuracy(dev, name, parent_name,
|
||||
flags, fixed_rate, 0);
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
|
||||
flags, fixed_rate, 0);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
|
||||
|
||||
@ -155,9 +137,9 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct clk *_of_fixed_clk_setup(struct device_node *node)
|
||||
static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
const char *clk_name = node->name;
|
||||
u32 rate;
|
||||
u32 accuracy = 0;
|
||||
@ -170,18 +152,18 @@ static struct clk *_of_fixed_clk_setup(struct device_node *node)
|
||||
|
||||
of_property_read_string(node, "clock-output-names", &clk_name);
|
||||
|
||||
clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
|
||||
hw = clk_hw_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
|
||||
0, rate, accuracy);
|
||||
if (IS_ERR(clk))
|
||||
return clk;
|
||||
if (IS_ERR(hw))
|
||||
return hw;
|
||||
|
||||
ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
|
||||
if (ret) {
|
||||
clk_unregister(clk);
|
||||
clk_hw_unregister_fixed_rate(hw);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -195,27 +177,27 @@ CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
|
||||
|
||||
static int of_fixed_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk = platform_get_drvdata(pdev);
|
||||
struct clk_hw *hw = platform_get_drvdata(pdev);
|
||||
|
||||
of_clk_del_provider(pdev->dev.of_node);
|
||||
clk_unregister_fixed_rate(clk);
|
||||
clk_hw_unregister_fixed_rate(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int of_fixed_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
|
||||
/*
|
||||
* This function is not executed when of_fixed_clk_setup
|
||||
* succeeded.
|
||||
*/
|
||||
clk = _of_fixed_clk_setup(pdev->dev.of_node);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
hw = _of_fixed_clk_setup(pdev->dev.of_node);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
|
||||
platform_set_drvdata(pdev, clk);
|
||||
platform_set_drvdata(pdev, hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -224,7 +206,6 @@ static const struct of_device_id of_fixed_clk_ids[] = {
|
||||
{ .compatible = "fixed-clock" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_fixed_clk_ids);
|
||||
|
||||
static struct platform_driver of_fixed_clk_driver = {
|
||||
.driver = {
|
||||
|
92
drivers/clk/clk-fsl-sai.c
Normal file
92
drivers/clk/clk-fsl-sai.c
Normal file
@ -0,0 +1,92 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Freescale SAI BCLK as a generic clock driver
|
||||
*
|
||||
* Copyright 2020 Michael Walle <michael@walle.cc>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define I2S_CSR 0x00
|
||||
#define I2S_CR2 0x08
|
||||
#define CSR_BCE_BIT 28
|
||||
#define CR2_BCD BIT(24)
|
||||
#define CR2_DIV_SHIFT 0
|
||||
#define CR2_DIV_WIDTH 8
|
||||
|
||||
struct fsl_sai_clk {
|
||||
struct clk_divider div;
|
||||
struct clk_gate gate;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
static int fsl_sai_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct fsl_sai_clk *sai_clk;
|
||||
struct clk_parent_data pdata = { .index = 0 };
|
||||
void __iomem *base;
|
||||
struct clk_hw *hw;
|
||||
struct resource *res;
|
||||
|
||||
sai_clk = devm_kzalloc(dev, sizeof(*sai_clk), GFP_KERNEL);
|
||||
if (!sai_clk)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
spin_lock_init(&sai_clk->lock);
|
||||
|
||||
sai_clk->gate.reg = base + I2S_CSR;
|
||||
sai_clk->gate.bit_idx = CSR_BCE_BIT;
|
||||
sai_clk->gate.lock = &sai_clk->lock;
|
||||
|
||||
sai_clk->div.reg = base + I2S_CR2;
|
||||
sai_clk->div.shift = CR2_DIV_SHIFT;
|
||||
sai_clk->div.width = CR2_DIV_WIDTH;
|
||||
sai_clk->div.lock = &sai_clk->lock;
|
||||
|
||||
/* set clock direction, we are the BCLK master */
|
||||
writel(CR2_BCD, base + I2S_CR2);
|
||||
|
||||
hw = clk_hw_register_composite_pdata(dev, dev->of_node->name,
|
||||
&pdata, 1, NULL, NULL,
|
||||
&sai_clk->div.hw,
|
||||
&clk_divider_ops,
|
||||
&sai_clk->gate.hw,
|
||||
&clk_gate_ops,
|
||||
CLK_SET_RATE_GATE);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_fsl_sai_clk_ids[] = {
|
||||
{ .compatible = "fsl,vf610-sai-clock" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids);
|
||||
|
||||
static struct platform_driver fsl_sai_clk_driver = {
|
||||
.probe = fsl_sai_clk_probe,
|
||||
.driver = {
|
||||
.name = "fsl-sai-clk",
|
||||
.of_match_table = of_fsl_sai_clk_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(fsl_sai_clk_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver");
|
||||
MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:fsl-sai-clk");
|
@ -123,26 +123,18 @@ const struct clk_ops clk_gate_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_gate_ops);
|
||||
|
||||
/**
|
||||
* clk_hw_register_gate - register a gate clock with the clock framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of this clock's parent
|
||||
* @flags: framework-specific flags for this clock
|
||||
* @reg: register address to control gating of this clock
|
||||
* @bit_idx: which bit in the register controls gating of this clock
|
||||
* @clk_gate_flags: gate-specific flags for this clock
|
||||
* @lock: shared register lock for this clock
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
struct clk_hw *__clk_hw_register_gate(struct device *dev,
|
||||
struct device_node *np, const char *name,
|
||||
const char *parent_name, const struct clk_hw *parent_hw,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock)
|
||||
{
|
||||
struct clk_gate *gate;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init = {};
|
||||
int ret;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
|
||||
if (bit_idx > 15) {
|
||||
@ -160,7 +152,12 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
|
||||
init.ops = &clk_gate_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_name ? &parent_name : NULL;
|
||||
init.num_parents = parent_name ? 1 : 0;
|
||||
init.parent_hws = parent_hw ? &parent_hw : NULL;
|
||||
init.parent_data = parent_data;
|
||||
if (parent_name || parent_hw || parent_data)
|
||||
init.num_parents = 1;
|
||||
else
|
||||
init.num_parents = 0;
|
||||
|
||||
/* struct clk_gate assignments */
|
||||
gate->reg = reg;
|
||||
@ -170,15 +167,19 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
|
||||
gate->hw.init = &init;
|
||||
|
||||
hw = &gate->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (dev || !np)
|
||||
ret = clk_hw_register(dev, hw);
|
||||
else if (np)
|
||||
ret = of_clk_hw_register(np, hw);
|
||||
if (ret) {
|
||||
kfree(gate);
|
||||
hw = ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return hw;
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_gate);
|
||||
EXPORT_SYMBOL_GPL(__clk_hw_register_gate);
|
||||
|
||||
struct clk *clk_register_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
|
@ -28,6 +28,26 @@
|
||||
* parent - fixed parent. No clk_set_parent support
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct clk_gpio - gpio gated clock
|
||||
*
|
||||
* @hw: handle between common and hardware-specific interfaces
|
||||
* @gpiod: gpio descriptor
|
||||
*
|
||||
* Clock with a gpio control for enabling and disabling the parent clock
|
||||
* or switching between two parents by asserting or deasserting the gpio.
|
||||
*
|
||||
* Implements .enable, .disable and .is_enabled or
|
||||
* .get_parent, .set_parent and .determine_rate depending on which clk_ops
|
||||
* is used.
|
||||
*/
|
||||
struct clk_gpio {
|
||||
struct clk_hw hw;
|
||||
struct gpio_desc *gpiod;
|
||||
};
|
||||
|
||||
#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
|
||||
|
||||
static int clk_gpio_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gpio *clk = to_clk_gpio(hw);
|
||||
@ -51,12 +71,11 @@ static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
|
||||
return gpiod_get_value(clk->gpiod);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_gpio_gate_ops = {
|
||||
static const struct clk_ops clk_gpio_gate_ops = {
|
||||
.enable = clk_gpio_gate_enable,
|
||||
.disable = clk_gpio_gate_disable,
|
||||
.is_enabled = clk_gpio_gate_is_enabled,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
|
||||
|
||||
static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
|
||||
{
|
||||
@ -111,67 +130,49 @@ static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_gpio_mux_ops = {
|
||||
static const struct clk_ops clk_gpio_mux_ops = {
|
||||
.get_parent = clk_gpio_mux_get_parent,
|
||||
.set_parent = clk_gpio_mux_set_parent,
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
|
||||
|
||||
static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
|
||||
unsigned long flags, const struct clk_ops *clk_gpio_ops)
|
||||
static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
|
||||
struct gpio_desc *gpiod,
|
||||
const struct clk_ops *clk_gpio_ops)
|
||||
{
|
||||
struct clk_gpio *clk_gpio;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init = {};
|
||||
int err;
|
||||
const struct clk_parent_data gpio_parent_data[] = {
|
||||
{ .index = 0 },
|
||||
{ .index = 1 },
|
||||
};
|
||||
|
||||
if (dev)
|
||||
clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
|
||||
else
|
||||
clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL);
|
||||
|
||||
clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
|
||||
if (!clk_gpio)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.name = dev->of_node->name;
|
||||
init.ops = clk_gpio_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
init.parent_data = gpio_parent_data;
|
||||
init.num_parents = num_parents;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
|
||||
clk_gpio->gpiod = gpiod;
|
||||
clk_gpio->hw.init = &init;
|
||||
|
||||
hw = &clk_gpio->hw;
|
||||
if (dev)
|
||||
err = devm_clk_hw_register(dev, hw);
|
||||
else
|
||||
err = clk_hw_register(NULL, hw);
|
||||
err = devm_clk_hw_register(dev, hw);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
if (!err)
|
||||
return hw;
|
||||
|
||||
if (!dev) {
|
||||
kfree(clk_gpio);
|
||||
}
|
||||
|
||||
return ERR_PTR(err);
|
||||
return hw;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_hw_register_gpio_gate - register a gpio clock gate with the clock
|
||||
* framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_name: name of this clock's parent
|
||||
* @gpiod: gpio descriptor to gate this clock
|
||||
* @flags: clock flags
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, struct gpio_desc *gpiod,
|
||||
unsigned long flags)
|
||||
static struct clk_hw *clk_hw_register_gpio_gate(struct device *dev,
|
||||
int num_parents,
|
||||
struct gpio_desc *gpiod)
|
||||
{
|
||||
const struct clk_ops *ops;
|
||||
|
||||
@ -180,88 +181,36 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
|
||||
else
|
||||
ops = &clk_gpio_gate_ops;
|
||||
|
||||
return clk_register_gpio(dev, name,
|
||||
(parent_name ? &parent_name : NULL),
|
||||
(parent_name ? 1 : 0), gpiod, flags, ops);
|
||||
return clk_register_gpio(dev, num_parents, gpiod, ops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
|
||||
|
||||
struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
|
||||
const char *parent_name, struct gpio_desc *gpiod,
|
||||
unsigned long flags)
|
||||
static struct clk_hw *clk_hw_register_gpio_mux(struct device *dev,
|
||||
struct gpio_desc *gpiod)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
return clk_register_gpio(dev, 2, gpiod, &clk_gpio_mux_ops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
|
||||
|
||||
/**
|
||||
* clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
|
||||
* @dev: device that is registering this clock
|
||||
* @name: name of this clock
|
||||
* @parent_names: names of this clock's parents
|
||||
* @num_parents: number of parents listed in @parent_names
|
||||
* @gpiod: gpio descriptor to gate this clock
|
||||
* @flags: clock flags
|
||||
*/
|
||||
struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (num_parents != 2) {
|
||||
pr_err("mux-clock %s must have 2 parents\n", name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return clk_register_gpio(dev, name, parent_names, num_parents,
|
||||
gpiod, flags, &clk_gpio_mux_ops);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
|
||||
|
||||
struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
|
||||
gpiod, flags);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
|
||||
|
||||
static int gpio_clk_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
const char **parent_names, *gpio_name;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->of_node;
|
||||
const char *gpio_name;
|
||||
unsigned int num_parents;
|
||||
struct gpio_desc *gpiod;
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
bool is_mux;
|
||||
int ret;
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (num_parents) {
|
||||
parent_names = devm_kcalloc(&pdev->dev, num_parents,
|
||||
sizeof(char *), GFP_KERNEL);
|
||||
if (!parent_names)
|
||||
return -ENOMEM;
|
||||
|
||||
of_clk_parent_fill(node, parent_names, num_parents);
|
||||
} else {
|
||||
parent_names = NULL;
|
||||
}
|
||||
|
||||
is_mux = of_device_is_compatible(node, "gpio-mux-clock");
|
||||
|
||||
num_parents = of_clk_get_parent_count(node);
|
||||
if (is_mux && num_parents != 2) {
|
||||
dev_err(dev, "mux-clock must have 2 parents\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gpio_name = is_mux ? "select" : "enable";
|
||||
gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW);
|
||||
gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(gpiod)) {
|
||||
ret = PTR_ERR(gpiod);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
@ -275,16 +224,13 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (is_mux)
|
||||
clk = clk_register_gpio_mux(&pdev->dev, node->name,
|
||||
parent_names, num_parents, gpiod, 0);
|
||||
hw = clk_hw_register_gpio_mux(dev, gpiod);
|
||||
else
|
||||
clk = clk_register_gpio_gate(&pdev->dev, node->name,
|
||||
parent_names ? parent_names[0] : NULL, gpiod,
|
||||
CLK_SET_RATE_PARENT);
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
hw = clk_hw_register_gpio_gate(dev, num_parents, gpiod);
|
||||
if (IS_ERR(hw))
|
||||
return PTR_ERR(hw);
|
||||
|
||||
return of_clk_add_provider(node, of_clk_src_simple_get, clk);
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
|
||||
}
|
||||
|
||||
static const struct of_device_id gpio_clk_match_table[] = {
|
||||
|
@ -145,17 +145,19 @@ const struct clk_ops clk_mux_ro_ops = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
|
||||
|
||||
struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u32 mask,
|
||||
struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
|
||||
const char *name, u8 num_parents,
|
||||
const char * const *parent_names,
|
||||
const struct clk_hw **parent_hws,
|
||||
const struct clk_parent_data *parent_data,
|
||||
unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
|
||||
u8 clk_mux_flags, u32 *table, spinlock_t *lock)
|
||||
{
|
||||
struct clk_mux *mux;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init = {};
|
||||
u8 width = 0;
|
||||
int ret;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
|
||||
width = fls(mask) - ffs(mask) + 1;
|
||||
@ -177,6 +179,8 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
|
||||
init.ops = &clk_mux_ops;
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
init.parent_data = parent_data;
|
||||
init.parent_hws = parent_hws;
|
||||
init.num_parents = num_parents;
|
||||
|
||||
/* struct clk_mux assignments */
|
||||
@ -189,7 +193,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
|
||||
mux->hw.init = &init;
|
||||
|
||||
hw = &mux->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (dev || !np)
|
||||
ret = clk_hw_register(dev, hw);
|
||||
else if (np)
|
||||
ret = of_clk_hw_register(np, hw);
|
||||
if (ret) {
|
||||
kfree(mux);
|
||||
hw = ERR_PTR(ret);
|
||||
@ -197,53 +204,24 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
|
||||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
|
||||
EXPORT_SYMBOL_GPL(__clk_hw_register_mux);
|
||||
|
||||
struct clk *clk_register_mux_table(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u32 mask,
|
||||
unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
|
||||
u8 clk_mux_flags, u32 *table, spinlock_t *lock)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
|
||||
flags, reg, shift, mask, clk_mux_flags,
|
||||
table, lock);
|
||||
hw = clk_hw_register_mux_table(dev, name, parent_names,
|
||||
num_parents, flags, reg, shift, mask,
|
||||
clk_mux_flags, table, lock);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_mux_table);
|
||||
|
||||
struct clk *clk_register_mux(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_mux_flags, spinlock_t *lock)
|
||||
{
|
||||
u32 mask = BIT(width) - 1;
|
||||
|
||||
return clk_register_mux_table(dev, name, parent_names, num_parents,
|
||||
flags, reg, shift, mask, clk_mux_flags,
|
||||
NULL, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register_mux);
|
||||
|
||||
struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
|
||||
const char * const *parent_names, u8 num_parents,
|
||||
unsigned long flags,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_mux_flags, spinlock_t *lock)
|
||||
{
|
||||
u32 mask = BIT(width) - 1;
|
||||
|
||||
return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
|
||||
flags, reg, shift, mask, clk_mux_flags,
|
||||
NULL, lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_mux);
|
||||
|
||||
void clk_unregister_mux(struct clk *clk)
|
||||
{
|
||||
struct clk_mux *mux;
|
||||
|
286
drivers/clk/clk-plldig.c
Normal file
286
drivers/clk/clk-plldig.c
Normal file
@ -0,0 +1,286 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2019 NXP
|
||||
*
|
||||
* Clock driver for LS1028A Display output interfaces(LCD, DPHY).
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/bitfield.h>
|
||||
|
||||
/* PLLDIG register offsets and bit masks */
|
||||
#define PLLDIG_REG_PLLSR 0x24
|
||||
#define PLLDIG_LOCK_MASK BIT(2)
|
||||
#define PLLDIG_REG_PLLDV 0x28
|
||||
#define PLLDIG_MFD_MASK GENMASK(7, 0)
|
||||
#define PLLDIG_RFDPHI1_MASK GENMASK(30, 25)
|
||||
#define PLLDIG_REG_PLLFM 0x2c
|
||||
#define PLLDIG_SSCGBYP_ENABLE BIT(30)
|
||||
#define PLLDIG_REG_PLLFD 0x30
|
||||
#define PLLDIG_FDEN BIT(30)
|
||||
#define PLLDIG_FRAC_MASK GENMASK(15, 0)
|
||||
#define PLLDIG_REG_PLLCAL1 0x38
|
||||
#define PLLDIG_REG_PLLCAL2 0x3c
|
||||
|
||||
/* Range of the VCO frequencies, in Hz */
|
||||
#define PLLDIG_MIN_VCO_FREQ 650000000
|
||||
#define PLLDIG_MAX_VCO_FREQ 1300000000
|
||||
|
||||
/* Range of the output frequencies, in Hz */
|
||||
#define PHI1_MIN_FREQ 27000000UL
|
||||
#define PHI1_MAX_FREQ 600000000UL
|
||||
|
||||
/* Maximum value of the reduced frequency divider */
|
||||
#define MAX_RFDPHI1 63UL
|
||||
|
||||
/* Best value of multiplication factor divider */
|
||||
#define PLLDIG_DEFAULT_MFD 44
|
||||
|
||||
/*
|
||||
* Denominator part of the fractional part of the
|
||||
* loop multiplication factor.
|
||||
*/
|
||||
#define MFDEN 20480
|
||||
|
||||
static const struct clk_parent_data parent_data[] = {
|
||||
{ .index = 0 },
|
||||
};
|
||||
|
||||
struct clk_plldig {
|
||||
struct clk_hw hw;
|
||||
void __iomem *regs;
|
||||
unsigned int vco_freq;
|
||||
};
|
||||
|
||||
#define to_clk_plldig(_hw) container_of(_hw, struct clk_plldig, hw)
|
||||
|
||||
static int plldig_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl(data->regs + PLLDIG_REG_PLLFM);
|
||||
/*
|
||||
* Use Bypass mode with PLL off by default, the frequency overshoot
|
||||
* detector output was disable. SSCG Bypass mode should be enable.
|
||||
*/
|
||||
val |= PLLDIG_SSCGBYP_ENABLE;
|
||||
writel(val, data->regs + PLLDIG_REG_PLLFM);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void plldig_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl(data->regs + PLLDIG_REG_PLLFM);
|
||||
|
||||
val &= ~PLLDIG_SSCGBYP_ENABLE;
|
||||
val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0);
|
||||
|
||||
writel(val, data->regs + PLLDIG_REG_PLLFM);
|
||||
}
|
||||
|
||||
static int plldig_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
|
||||
return readl(data->regs + PLLDIG_REG_PLLFM) &
|
||||
PLLDIG_SSCGBYP_ENABLE;
|
||||
}
|
||||
|
||||
static unsigned long plldig_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
u32 val, rfdphi1;
|
||||
|
||||
val = readl(data->regs + PLLDIG_REG_PLLDV);
|
||||
|
||||
/* Check if PLL is bypassed */
|
||||
if (val & PLLDIG_SSCGBYP_ENABLE)
|
||||
return parent_rate;
|
||||
|
||||
rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val);
|
||||
|
||||
/*
|
||||
* If RFDPHI1 has a value of 1 the VCO frequency is also divided by
|
||||
* one.
|
||||
*/
|
||||
if (!rfdphi1)
|
||||
rfdphi1 = 1;
|
||||
|
||||
return DIV_ROUND_UP(data->vco_freq, rfdphi1);
|
||||
}
|
||||
|
||||
static unsigned long plldig_calc_target_div(unsigned long vco_freq,
|
||||
unsigned long target_rate)
|
||||
{
|
||||
unsigned long div;
|
||||
|
||||
div = DIV_ROUND_CLOSEST(vco_freq, target_rate);
|
||||
div = clamp(div, 1UL, MAX_RFDPHI1);
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
static int plldig_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
unsigned int div;
|
||||
|
||||
req->rate = clamp(req->rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
|
||||
div = plldig_calc_target_div(data->vco_freq, req->rate);
|
||||
req->rate = DIV_ROUND_UP(data->vco_freq, div);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plldig_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
unsigned int val, cond;
|
||||
unsigned int rfdphi1;
|
||||
|
||||
rate = clamp(rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
|
||||
rfdphi1 = plldig_calc_target_div(data->vco_freq, rate);
|
||||
|
||||
/* update the divider value */
|
||||
val = readl(data->regs + PLLDIG_REG_PLLDV);
|
||||
val &= ~PLLDIG_RFDPHI1_MASK;
|
||||
val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1);
|
||||
writel(val, data->regs + PLLDIG_REG_PLLDV);
|
||||
|
||||
/* waiting for old lock state to clear */
|
||||
udelay(200);
|
||||
|
||||
/* Wait until PLL is locked or timeout */
|
||||
return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond,
|
||||
cond & PLLDIG_LOCK_MASK, 0,
|
||||
USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static const struct clk_ops plldig_clk_ops = {
|
||||
.enable = plldig_enable,
|
||||
.disable = plldig_disable,
|
||||
.is_enabled = plldig_is_enabled,
|
||||
.recalc_rate = plldig_recalc_rate,
|
||||
.determine_rate = plldig_determine_rate,
|
||||
.set_rate = plldig_set_rate,
|
||||
};
|
||||
|
||||
static int plldig_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_plldig *data = to_clk_plldig(hw);
|
||||
struct clk_hw *parent = clk_hw_get_parent(hw);
|
||||
unsigned long parent_rate = clk_hw_get_rate(parent);
|
||||
unsigned long val;
|
||||
unsigned long long lltmp;
|
||||
unsigned int mfd, fracdiv = 0;
|
||||
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
if (data->vco_freq) {
|
||||
mfd = data->vco_freq / parent_rate;
|
||||
lltmp = data->vco_freq % parent_rate;
|
||||
lltmp *= MFDEN;
|
||||
do_div(lltmp, parent_rate);
|
||||
fracdiv = lltmp;
|
||||
} else {
|
||||
mfd = PLLDIG_DEFAULT_MFD;
|
||||
data->vco_freq = parent_rate * mfd;
|
||||
}
|
||||
|
||||
val = FIELD_PREP(PLLDIG_MFD_MASK, mfd);
|
||||
writel(val, data->regs + PLLDIG_REG_PLLDV);
|
||||
|
||||
/* Enable fractional divider */
|
||||
if (fracdiv) {
|
||||
val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv);
|
||||
val |= PLLDIG_FDEN;
|
||||
writel(val, data->regs + PLLDIG_REG_PLLFD);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int plldig_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_plldig *data;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
data->regs = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(data->regs))
|
||||
return PTR_ERR(data->regs);
|
||||
|
||||
data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk",
|
||||
parent_data,
|
||||
&plldig_clk_ops,
|
||||
0);
|
||||
|
||||
ret = devm_clk_hw_register(dev, &data->hw);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register %s clock\n",
|
||||
dev->of_node->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
&data->hw);
|
||||
if (ret) {
|
||||
dev_err(dev, "unable to add clk provider\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The frequency of the VCO cannot be changed during runtime.
|
||||
* Therefore, let the user specify a desired frequency.
|
||||
*/
|
||||
if (!of_property_read_u32(dev->of_node, "fsl,vco-hz",
|
||||
&data->vco_freq)) {
|
||||
if (data->vco_freq < PLLDIG_MIN_VCO_FREQ ||
|
||||
data->vco_freq > PLLDIG_MAX_VCO_FREQ)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return plldig_init(&data->hw);
|
||||
}
|
||||
|
||||
static const struct of_device_id plldig_clk_id[] = {
|
||||
{ .compatible = "fsl,ls1028a-plldig" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, plldig_clk_id);
|
||||
|
||||
static struct platform_driver plldig_clk_driver = {
|
||||
.driver = {
|
||||
.name = "plldig-clock",
|
||||
.of_match_table = plldig_clk_id,
|
||||
},
|
||||
.probe = plldig_clk_probe,
|
||||
};
|
||||
module_platform_driver(plldig_clk_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Wen He <wen.he_1@nxp.com>");
|
||||
MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver");
|
@ -342,6 +342,32 @@ static const struct clockgen_muxinfo ls1046a_hwa2 = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clockgen_muxinfo ls1088a_hwa1 = {
|
||||
{
|
||||
{},
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
|
||||
{},
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clockgen_muxinfo ls1088a_hwa2 = {
|
||||
{
|
||||
{},
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
|
||||
{ CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
|
||||
{},
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
|
||||
{ CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clockgen_muxinfo ls1012a_cmux = {
|
||||
{
|
||||
[0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
|
||||
@ -607,6 +633,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
||||
.cmux_groups = {
|
||||
&clockgen2_cmux_cga12
|
||||
},
|
||||
.hwaccel = {
|
||||
&ls1088a_hwa1, &ls1088a_hwa2
|
||||
},
|
||||
.cmux_to_group = {
|
||||
0, 0, -1
|
||||
},
|
||||
|
@ -2996,6 +2996,41 @@ static int clk_dump_show(struct seq_file *s, void *data)
|
||||
}
|
||||
DEFINE_SHOW_ATTRIBUTE(clk_dump);
|
||||
|
||||
#undef CLOCK_ALLOW_WRITE_DEBUGFS
|
||||
#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
|
||||
/*
|
||||
* This can be dangerous, therefore don't provide any real compile time
|
||||
* configuration option for this feature.
|
||||
* People who want to use this will need to modify the source code directly.
|
||||
*/
|
||||
static int clk_rate_set(void *data, u64 val)
|
||||
{
|
||||
struct clk_core *core = data;
|
||||
int ret;
|
||||
|
||||
clk_prepare_lock();
|
||||
ret = clk_core_set_rate_nolock(core, val);
|
||||
clk_prepare_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define clk_rate_mode 0644
|
||||
#else
|
||||
#define clk_rate_set NULL
|
||||
#define clk_rate_mode 0444
|
||||
#endif
|
||||
|
||||
static int clk_rate_get(void *data, u64 *val)
|
||||
{
|
||||
struct clk_core *core = data;
|
||||
|
||||
*val = core->rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
|
||||
|
||||
static const struct {
|
||||
unsigned long flag;
|
||||
const char *name;
|
||||
@ -3145,7 +3180,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
|
||||
root = debugfs_create_dir(core->name, pdentry);
|
||||
core->dentry = root;
|
||||
|
||||
debugfs_create_ulong("clk_rate", 0444, root, &core->rate);
|
||||
debugfs_create_file("clk_rate", clk_rate_mode, root, core,
|
||||
&clk_rate_fops);
|
||||
debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
|
||||
debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
|
||||
debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
|
||||
@ -3338,6 +3374,26 @@ static int __clk_core_init(struct clk_core *core)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* optional platform-specific magic
|
||||
*
|
||||
* The .init callback is not used by any of the basic clock types, but
|
||||
* exists for weird hardware that must perform initialization magic for
|
||||
* CCF to get an accurate view of clock for any other callbacks. It may
|
||||
* also be used needs to perform dynamic allocations. Such allocation
|
||||
* must be freed in the terminate() callback.
|
||||
* This callback shall not be used to initialize the parameters state,
|
||||
* such as rate, parent, etc ...
|
||||
*
|
||||
* If it exist, this callback should called before any other callback of
|
||||
* the clock
|
||||
*/
|
||||
if (core->ops->init) {
|
||||
ret = core->ops->init(core->hw);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
core->parent = __clk_init_parent(core);
|
||||
|
||||
/*
|
||||
@ -3362,17 +3418,6 @@ static int __clk_core_init(struct clk_core *core)
|
||||
core->orphan = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* optional platform-specific magic
|
||||
*
|
||||
* The .init callback is not used by any of the basic clock types, but
|
||||
* exists for weird hardware that must perform initialization magic.
|
||||
* Please consider other ways of solving initialization problems before
|
||||
* using this callback, as its use is discouraged.
|
||||
*/
|
||||
if (core->ops->init)
|
||||
core->ops->init(core->hw);
|
||||
|
||||
/*
|
||||
* Set clk's accuracy. The preferred method is to use
|
||||
* .recalc_accuracy. For simple clocks and lazy developers the default
|
||||
@ -3427,13 +3472,18 @@ static int __clk_core_init(struct clk_core *core)
|
||||
unsigned long flags;
|
||||
|
||||
ret = clk_core_prepare(core);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
pr_warn("%s: critical clk '%s' failed to prepare\n",
|
||||
__func__, core->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags = clk_enable_lock();
|
||||
ret = clk_core_enable(core);
|
||||
clk_enable_unlock(flags);
|
||||
if (ret) {
|
||||
pr_warn("%s: critical clk '%s' failed to enable\n",
|
||||
__func__, core->name);
|
||||
clk_core_unprepare(core);
|
||||
goto out;
|
||||
}
|
||||
@ -3732,6 +3782,28 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* dev_or_parent_of_node() - Get device node of @dev or @dev's parent
|
||||
* @dev: Device to get device node of
|
||||
*
|
||||
* Return: device node pointer of @dev, or the device node pointer of
|
||||
* @dev->parent if dev doesn't have a device node, or NULL if neither
|
||||
* @dev or @dev->parent have a device node.
|
||||
*/
|
||||
static struct device_node *dev_or_parent_of_node(struct device *dev)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
np = dev_of_node(dev);
|
||||
if (!np)
|
||||
np = dev_of_node(dev->parent);
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_register - allocate a new clock, register it and return an opaque cookie
|
||||
* @dev: device that is registering this clock
|
||||
@ -3747,7 +3819,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
|
||||
*/
|
||||
struct clk *clk_register(struct device *dev, struct clk_hw *hw)
|
||||
{
|
||||
return __clk_register(dev, dev_of_node(dev), hw);
|
||||
return __clk_register(dev, dev_or_parent_of_node(dev), hw);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_register);
|
||||
|
||||
@ -3763,7 +3835,8 @@ EXPORT_SYMBOL_GPL(clk_register);
|
||||
*/
|
||||
int clk_hw_register(struct device *dev, struct clk_hw *hw)
|
||||
{
|
||||
return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
|
||||
return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev),
|
||||
hw));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register);
|
||||
|
||||
@ -3866,6 +3939,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core)
|
||||
void clk_unregister(struct clk *clk)
|
||||
{
|
||||
unsigned long flags;
|
||||
const struct clk_ops *ops;
|
||||
|
||||
if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
|
||||
return;
|
||||
@ -3874,7 +3948,8 @@ void clk_unregister(struct clk *clk)
|
||||
|
||||
clk_prepare_lock();
|
||||
|
||||
if (clk->core->ops == &clk_nodrv_ops) {
|
||||
ops = clk->core->ops;
|
||||
if (ops == &clk_nodrv_ops) {
|
||||
pr_err("%s: unregistered clock: %s\n", __func__,
|
||||
clk->core->name);
|
||||
goto unlock;
|
||||
@ -3887,6 +3962,9 @@ void clk_unregister(struct clk *clk)
|
||||
clk->core->ops = &clk_nodrv_ops;
|
||||
clk_enable_unlock(flags);
|
||||
|
||||
if (ops->terminate)
|
||||
ops->terminate(clk->core->hw);
|
||||
|
||||
if (!hlist_empty(&clk->core->children)) {
|
||||
struct clk_core *child;
|
||||
struct hlist_node *t;
|
||||
|
@ -20,6 +20,12 @@ config CLK_IMX8MN
|
||||
help
|
||||
Build the driver for i.MX8MN CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MP
|
||||
bool "IMX8MP CCM Clock Driver"
|
||||
depends on ARCH_MXC && ARM64
|
||||
help
|
||||
Build the driver for i.MX8MP CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MQ
|
||||
bool "IMX8MQ CCM Clock Driver"
|
||||
depends on ARCH_MXC && ARM64
|
||||
|
@ -18,7 +18,7 @@ obj-$(CONFIG_MXC_CLK) += \
|
||||
clk-pllv2.o \
|
||||
clk-pllv3.o \
|
||||
clk-pllv4.o \
|
||||
clk-sccg-pll.o \
|
||||
clk-sscg-pll.o \
|
||||
clk-pll14xx.o
|
||||
|
||||
obj-$(CONFIG_MXC_CLK_SCU) += \
|
||||
@ -27,6 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
|
||||
|
||||
obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
|
||||
obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
|
||||
obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
|
||||
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
|
||||
obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#define PCG_PCD_WIDTH 3
|
||||
#define PCG_PCD_MASK 0x7
|
||||
|
||||
struct clk_hw *imx7ulp_clk_composite(const char *name,
|
||||
struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents, bool mux_present,
|
||||
bool rate_present, bool gate_present,
|
||||
|
@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
|
||||
.set_rate = imx8m_clk_composite_divider_set_rate,
|
||||
};
|
||||
|
||||
struct clk *imx8m_clk_composite_flags(const char *name,
|
||||
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents, void __iomem *reg,
|
||||
unsigned long flags)
|
||||
@ -171,7 +171,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
|
||||
if (IS_ERR(hw))
|
||||
goto fail;
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
|
||||
fail:
|
||||
kfree(gate);
|
||||
|
@ -43,7 +43,7 @@ static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
|
||||
struct clk_divider *div = to_clk_divider(hw);
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
unsigned int val;
|
||||
|
||||
spin_lock_irqsave(div->lock, flags);
|
||||
@ -75,7 +75,7 @@ static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
{
|
||||
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
|
||||
struct clk_divider *div = to_clk_divider(hw);
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
int value;
|
||||
u32 val;
|
||||
|
||||
@ -104,7 +104,7 @@ static int clk_divider_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
|
||||
struct clk_divider *div = to_clk_divider(hw);
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
if (!div_gate->cached_val) {
|
||||
@ -127,7 +127,7 @@ static void clk_divider_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
|
||||
struct clk_divider *div = to_clk_divider(hw);
|
||||
unsigned long flags = 0;
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(div->lock, flags);
|
||||
@ -167,13 +167,13 @@ static const struct clk_ops clk_divider_gate_ops = {
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: In order to resue the most code from the common divider,
|
||||
* NOTE: In order to reuse the most code from the common divider,
|
||||
* we also design our divider following the way that provids an extra
|
||||
* clk_divider_flags, however it's fixed to CLK_DIVIDER_ONE_BASED by
|
||||
* default as our HW is. Besides that it supports only CLK_DIVIDER_READ_ONLY
|
||||
* flag which can be specified by user flexibly.
|
||||
*/
|
||||
struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
|
||||
unsigned long flags, void __iomem *reg,
|
||||
u8 shift, u8 width, u8 clk_divider_flags,
|
||||
const struct clk_div_table *table,
|
||||
|
@ -201,8 +201,9 @@ static const struct clk_ops clk_frac_pll_ops = {
|
||||
.set_rate = clk_pll_set_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
|
||||
void __iomem *base)
|
||||
struct clk_hw *imx_clk_hw_frac_pll(const char *name,
|
||||
const char *parent_name,
|
||||
void __iomem *base)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct clk_frac_pll *pll;
|
||||
@ -230,5 +231,5 @@ struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
}
|
||||
|
@ -598,7 +598,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
}
|
||||
|
||||
hws[IMX6QDL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
|
||||
if (clk_on_imx6q() || clk_on_imx6qp())
|
||||
hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = imx_clk_hw_fixed_factor("pll4_audio_div", "pll4_post_div", 1, 1);
|
||||
else
|
||||
hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
|
||||
hws[IMX6QDL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
hws[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
|
||||
|
||||
|
@ -59,7 +59,7 @@ static struct clk **pcc3_uart_clks[ARRAY_SIZE(pcc3_uart_clk_ids) + 1] __initdata
|
||||
static void __init imx7ulp_clk_scg1_init(struct device_node *np)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
struct clk_hw **hws;
|
||||
void __iomem *base;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END),
|
||||
@ -68,76 +68,76 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
clk_data->num = IMX7ULP_CLK_SCG1_END;
|
||||
clks = clk_data->hws;
|
||||
hws = clk_data->hws;
|
||||
|
||||
clks[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
hws[IMX7ULP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
|
||||
clks[IMX7ULP_CLK_ROSC] = imx_obtain_fixed_clk_hw(np, "rosc");
|
||||
clks[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc");
|
||||
clks[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc");
|
||||
clks[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc");
|
||||
clks[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll");
|
||||
hws[IMX7ULP_CLK_ROSC] = imx_obtain_fixed_clk_hw(np, "rosc");
|
||||
hws[IMX7ULP_CLK_SOSC] = imx_obtain_fixed_clk_hw(np, "sosc");
|
||||
hws[IMX7ULP_CLK_SIRC] = imx_obtain_fixed_clk_hw(np, "sirc");
|
||||
hws[IMX7ULP_CLK_FIRC] = imx_obtain_fixed_clk_hw(np, "firc");
|
||||
hws[IMX7ULP_CLK_UPLL] = imx_obtain_fixed_clk_hw(np, "upll");
|
||||
|
||||
/* SCG1 */
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
/* NOTE: xPLL config can't be changed when xPLL is enabled */
|
||||
clks[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
clks[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_APLL_PRE_SEL] = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_SPLL_PRE_SEL] = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
|
||||
|
||||
/* name parent_name reg shift width flags */
|
||||
clks[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3, CLK_SET_RATE_GATE);
|
||||
clks[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE);
|
||||
hws[IMX7ULP_CLK_APLL_PRE_DIV] = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508, 8, 3, CLK_SET_RATE_GATE);
|
||||
hws[IMX7ULP_CLK_SPLL_PRE_DIV] = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608, 8, 3, CLK_SET_RATE_GATE);
|
||||
|
||||
/* name parent_name base */
|
||||
clks[IMX7ULP_CLK_APLL] = imx_clk_pllv4("apll", "apll_pre_div", base + 0x500);
|
||||
clks[IMX7ULP_CLK_SPLL] = imx_clk_pllv4("spll", "spll_pre_div", base + 0x600);
|
||||
hws[IMX7ULP_CLK_APLL] = imx_clk_hw_pllv4("apll", "apll_pre_div", base + 0x500);
|
||||
hws[IMX7ULP_CLK_SPLL] = imx_clk_hw_pllv4("spll", "spll_pre_div", base + 0x600);
|
||||
|
||||
/* APLL PFDs */
|
||||
clks[IMX7ULP_CLK_APLL_PFD0] = imx_clk_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
|
||||
clks[IMX7ULP_CLK_APLL_PFD1] = imx_clk_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
|
||||
clks[IMX7ULP_CLK_APLL_PFD2] = imx_clk_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
|
||||
clks[IMX7ULP_CLK_APLL_PFD3] = imx_clk_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
|
||||
hws[IMX7ULP_CLK_APLL_PFD0] = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
|
||||
hws[IMX7ULP_CLK_APLL_PFD1] = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
|
||||
hws[IMX7ULP_CLK_APLL_PFD2] = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
|
||||
hws[IMX7ULP_CLK_APLL_PFD3] = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
|
||||
|
||||
/* SPLL PFDs */
|
||||
clks[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
|
||||
clks[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
|
||||
clks[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
|
||||
clks[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
|
||||
hws[IMX7ULP_CLK_SPLL_PFD0] = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
|
||||
hws[IMX7ULP_CLK_SPLL_PFD1] = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
|
||||
hws[IMX7ULP_CLK_SPLL_PFD2] = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
|
||||
hws[IMX7ULP_CLK_SPLL_PFD3] = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
|
||||
|
||||
/* PLL Mux */
|
||||
clks[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
clks[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
clks[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
clks[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_APLL_PFD_SEL] = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_SPLL_PFD_SEL] = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_APLL_SEL] = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
hws[IMX7ULP_CLK_SPLL_SEL] = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
|
||||
|
||||
clks[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock);
|
||||
hws[IMX7ULP_CLK_SPLL_BUS_CLK] = imx_clk_hw_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock);
|
||||
|
||||
/* scs/ddr/nic select different clock source requires that clock to be enabled first */
|
||||
clks[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
|
||||
clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
|
||||
clks[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
|
||||
clks[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
hws[IMX7ULP_CLK_SYS_SEL] = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
|
||||
hws[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
|
||||
hws[IMX7ULP_CLK_NIC_SEL] = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
|
||||
hws[IMX7ULP_CLK_DDR_SEL] = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
|
||||
clks[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
|
||||
clks[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
|
||||
hws[IMX7ULP_CLK_CORE_DIV] = imx_clk_hw_divider_flags("divcore", "scs_sel", base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
|
||||
hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
|
||||
|
||||
clks[IMX7ULP_CLK_DDR_DIV] = imx_clk_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
|
||||
hws[IMX7ULP_CLK_DDR_DIV] = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
|
||||
0, ulp_div_table, &imx_ccm_lock);
|
||||
|
||||
clks[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
clks[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic0_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
hws[IMX7ULP_CLK_NIC0_DIV] = imx_clk_hw_divider_flags("nic0_clk", "nic_sel", base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
hws[IMX7ULP_CLK_NIC1_DIV] = imx_clk_hw_divider_flags("nic1_clk", "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
hws[IMX7ULP_CLK_NIC1_BUS_DIV] = imx_clk_hw_divider_flags("nic1_bus_clk", "nic0_clk", base + 0x40, 4, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4);
|
||||
hws[IMX7ULP_CLK_GPU_DIV] = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4);
|
||||
|
||||
clks[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
|
||||
hws[IMX7ULP_CLK_SOSC_BUS_CLK] = imx_clk_hw_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
|
||||
CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
|
||||
clks[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
|
||||
hws[IMX7ULP_CLK_FIRC_BUS_CLK] = imx_clk_hw_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
|
||||
CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
imx_check_clk_hws(hws, clk_data->num);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
@ -146,7 +146,7 @@ CLK_OF_DECLARE(imx7ulp_clk_scg1, "fsl,imx7ulp-scg1", imx7ulp_clk_scg1_init);
|
||||
static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
struct clk_hw **hws;
|
||||
void __iomem *base;
|
||||
int i;
|
||||
|
||||
@ -156,42 +156,42 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
clk_data->num = IMX7ULP_CLK_PCC2_END;
|
||||
clks = clk_data->hws;
|
||||
hws = clk_data->hws;
|
||||
|
||||
/* PCC2 */
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
clks[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
|
||||
clks[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
|
||||
clks[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
|
||||
clks[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
|
||||
clks[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
|
||||
clks[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
|
||||
clks[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
|
||||
clks[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4);
|
||||
clks[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8);
|
||||
clks[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac);
|
||||
clks[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0);
|
||||
clks[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4);
|
||||
clks[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8);
|
||||
clks[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4);
|
||||
clks[IMX7ULP_CLK_USB0] = imx7ulp_clk_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xcc);
|
||||
clks[IMX7ULP_CLK_USB1] = imx7ulp_clk_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xd0);
|
||||
clks[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30);
|
||||
clks[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xdc);
|
||||
clks[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xe0);
|
||||
clks[IMX7ULP_CLK_WDG1] = imx7ulp_clk_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xf4);
|
||||
clks[IMX7ULP_CLK_WDG2] = imx7ulp_clk_composite("sdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10c);
|
||||
hws[IMX7ULP_CLK_DMA1] = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
|
||||
hws[IMX7ULP_CLK_RGPIO2P1] = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
|
||||
hws[IMX7ULP_CLK_DMA_MUX1] = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
|
||||
hws[IMX7ULP_CLK_CAAM] = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
|
||||
hws[IMX7ULP_CLK_LPTPM4] = imx7ulp_clk_hw_composite("lptpm4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
|
||||
hws[IMX7ULP_CLK_LPTPM5] = imx7ulp_clk_hw_composite("lptpm5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
|
||||
hws[IMX7ULP_CLK_LPIT1] = imx7ulp_clk_hw_composite("lpit1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
|
||||
hws[IMX7ULP_CLK_LPSPI2] = imx7ulp_clk_hw_composite("lpspi2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4);
|
||||
hws[IMX7ULP_CLK_LPSPI3] = imx7ulp_clk_hw_composite("lpspi3", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8);
|
||||
hws[IMX7ULP_CLK_LPI2C4] = imx7ulp_clk_hw_composite("lpi2c4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac);
|
||||
hws[IMX7ULP_CLK_LPI2C5] = imx7ulp_clk_hw_composite("lpi2c5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0);
|
||||
hws[IMX7ULP_CLK_LPUART4] = imx7ulp_clk_hw_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4);
|
||||
hws[IMX7ULP_CLK_LPUART5] = imx7ulp_clk_hw_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8);
|
||||
hws[IMX7ULP_CLK_FLEXIO1] = imx7ulp_clk_hw_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4);
|
||||
hws[IMX7ULP_CLK_USB0] = imx7ulp_clk_hw_composite("usb0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xcc);
|
||||
hws[IMX7ULP_CLK_USB1] = imx7ulp_clk_hw_composite("usb1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xd0);
|
||||
hws[IMX7ULP_CLK_USB_PHY] = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30);
|
||||
hws[IMX7ULP_CLK_USDHC0] = imx7ulp_clk_hw_composite("usdhc0", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xdc);
|
||||
hws[IMX7ULP_CLK_USDHC1] = imx7ulp_clk_hw_composite("usdhc1", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xe0);
|
||||
hws[IMX7ULP_CLK_WDG1] = imx7ulp_clk_hw_composite("wdg1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xf4);
|
||||
hws[IMX7ULP_CLK_WDG2] = imx7ulp_clk_hw_composite("wdg2", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0x10c);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
imx_check_clk_hws(hws, clk_data->num);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pcc2_uart_clk_ids); i++) {
|
||||
int index = pcc2_uart_clk_ids[i];
|
||||
|
||||
pcc2_uart_clks[i] = &clks[index]->clk;
|
||||
pcc2_uart_clks[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(pcc2_uart_clks);
|
||||
@ -201,7 +201,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
|
||||
static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
struct clk_hw **hws;
|
||||
void __iomem *base;
|
||||
int i;
|
||||
|
||||
@ -211,41 +211,41 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
clk_data->num = IMX7ULP_CLK_PCC3_END;
|
||||
clks = clk_data->hws;
|
||||
hws = clk_data->hws;
|
||||
|
||||
/* PCC3 */
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
clks[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
|
||||
clks[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
|
||||
hws[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_hw_composite("lptpm6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
|
||||
hws[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_hw_composite("lptpm7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
|
||||
|
||||
clks[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
|
||||
hws[IMX7ULP_CLK_MMDC] = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
|
||||
base + 0xac, 30, 0, &imx_ccm_lock);
|
||||
clks[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
|
||||
clks[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
|
||||
clks[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
|
||||
clks[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
|
||||
clks[IMX7ULP_CLK_DSI] = imx7ulp_clk_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xa4);
|
||||
clks[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xa8);
|
||||
hws[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_hw_composite("lpi2c6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
|
||||
hws[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_hw_composite("lpi2c7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
|
||||
hws[IMX7ULP_CLK_LPUART6] = imx7ulp_clk_hw_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
|
||||
hws[IMX7ULP_CLK_LPUART7] = imx7ulp_clk_hw_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
|
||||
hws[IMX7ULP_CLK_DSI] = imx7ulp_clk_hw_composite("dsi", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true, true, base + 0xa4);
|
||||
hws[IMX7ULP_CLK_LCDIF] = imx7ulp_clk_hw_composite("lcdif", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true, true, base + 0xa8);
|
||||
|
||||
clks[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu", "nic1_clk", base + 0xa0, 30);
|
||||
clks[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30);
|
||||
clks[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30);
|
||||
clks[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30);
|
||||
clks[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30);
|
||||
hws[IMX7ULP_CLK_VIU] = imx_clk_hw_gate("viu", "nic1_clk", base + 0xa0, 30);
|
||||
hws[IMX7ULP_CLK_PCTLC] = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30);
|
||||
hws[IMX7ULP_CLK_PCTLD] = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30);
|
||||
hws[IMX7ULP_CLK_PCTLE] = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30);
|
||||
hws[IMX7ULP_CLK_PCTLF] = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30);
|
||||
|
||||
clks[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
|
||||
clks[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
|
||||
hws[IMX7ULP_CLK_GPU3D] = imx7ulp_clk_hw_composite("gpu3d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
|
||||
hws[IMX7ULP_CLK_GPU2D] = imx7ulp_clk_hw_composite("gpu2d", periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
imx_check_clk_hws(hws, clk_data->num);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pcc3_uart_clk_ids); i++) {
|
||||
int index = pcc3_uart_clk_ids[i];
|
||||
|
||||
pcc3_uart_clks[i] = &clks[index]->clk;
|
||||
pcc3_uart_clks[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(pcc3_uart_clks);
|
||||
@ -255,7 +255,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);
|
||||
static void __init imx7ulp_clk_smc1_init(struct device_node *np)
|
||||
{
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **clks;
|
||||
struct clk_hw **hws;
|
||||
void __iomem *base;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END),
|
||||
@ -264,15 +264,15 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
clk_data->num = IMX7ULP_CLK_SMC1_END;
|
||||
clks = clk_data->hws;
|
||||
hws = clk_data->hws;
|
||||
|
||||
/* SMC1 */
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
clks[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
|
||||
hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
|
||||
|
||||
imx_check_clk_hws(clks, clk_data->num);
|
||||
imx_check_clk_hws(hws, clk_data->num);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "clk.h"
|
||||
@ -285,118 +286,126 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }
|
||||
static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_out",
|
||||
"vpu_pll", "sys_pll1_80m", };
|
||||
|
||||
static struct clk *clks[IMX8MM_CLK_END];
|
||||
static struct clk_onecell_data clk_data;
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
static struct clk ** const uart_clks[] = {
|
||||
&clks[IMX8MM_CLK_UART1_ROOT],
|
||||
&clks[IMX8MM_CLK_UART2_ROOT],
|
||||
&clks[IMX8MM_CLK_UART3_ROOT],
|
||||
&clks[IMX8MM_CLK_UART4_ROOT],
|
||||
NULL
|
||||
static const int uart_clk_ids[] = {
|
||||
IMX8MM_CLK_UART1_ROOT,
|
||||
IMX8MM_CLK_UART2_ROOT,
|
||||
IMX8MM_CLK_UART3_ROOT,
|
||||
IMX8MM_CLK_UART4_ROOT,
|
||||
};
|
||||
static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
|
||||
|
||||
static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
|
||||
clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
|
||||
clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
|
||||
clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
|
||||
clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
|
||||
clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
|
||||
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
|
||||
IMX8MM_CLK_END), GFP_KERNEL);
|
||||
if (WARN_ON(!clk_hw_data))
|
||||
return -ENOMEM;
|
||||
|
||||
clk_hw_data->num = IMX8MM_CLK_END;
|
||||
hws = clk_hw_data->hws;
|
||||
|
||||
hws[IMX8MM_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
hws[IMX8MM_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
|
||||
hws[IMX8MM_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
|
||||
hws[IMX8MM_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
|
||||
hws[IMX8MM_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
|
||||
hws[IMX8MM_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
|
||||
hws[IMX8MM_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
if (WARN_ON(!base))
|
||||
return -ENOMEM;
|
||||
|
||||
clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
|
||||
clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
|
||||
clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
|
||||
clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
|
||||
clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll);
|
||||
clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
|
||||
clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
|
||||
clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
|
||||
clks[IMX8MM_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000);
|
||||
clks[IMX8MM_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000);
|
||||
clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
|
||||
hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
|
||||
hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
|
||||
hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
|
||||
hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
|
||||
hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
|
||||
hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
|
||||
hws[IMX8MM_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
|
||||
hws[IMX8MM_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
|
||||
hws[IMX8MM_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
|
||||
hws[IMX8MM_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
|
||||
|
||||
/* PLL bypass out */
|
||||
clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
||||
/* PLL out gate */
|
||||
clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
|
||||
clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
|
||||
clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
|
||||
clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
|
||||
clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
|
||||
clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
|
||||
clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
|
||||
clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
|
||||
hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
|
||||
hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
|
||||
hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
|
||||
hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
|
||||
hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
|
||||
hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
|
||||
hws[IMX8MM_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
|
||||
hws[IMX8MM_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
|
||||
|
||||
/* SYS PLL1 fixed output */
|
||||
clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
|
||||
clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
|
||||
clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
|
||||
clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
|
||||
clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
|
||||
clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
|
||||
clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
|
||||
clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
|
||||
clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
|
||||
hws[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
|
||||
hws[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
|
||||
hws[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
|
||||
hws[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
|
||||
hws[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
|
||||
hws[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
|
||||
hws[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
|
||||
hws[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
|
||||
hws[IMX8MM_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
|
||||
|
||||
clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
|
||||
clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
|
||||
clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
|
||||
clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
|
||||
clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
|
||||
clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
|
||||
clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
|
||||
clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
|
||||
clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
hws[IMX8MM_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
|
||||
hws[IMX8MM_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
|
||||
hws[IMX8MM_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
|
||||
hws[IMX8MM_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
|
||||
hws[IMX8MM_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
|
||||
hws[IMX8MM_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
|
||||
hws[IMX8MM_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
|
||||
hws[IMX8MM_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
|
||||
hws[IMX8MM_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
|
||||
/* SYS PLL2 fixed output */
|
||||
clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
|
||||
clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
|
||||
clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
|
||||
clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
|
||||
clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
|
||||
clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
|
||||
clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
|
||||
clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
|
||||
clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
|
||||
hws[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
|
||||
hws[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
|
||||
hws[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
|
||||
hws[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
|
||||
hws[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
|
||||
hws[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
|
||||
hws[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
|
||||
hws[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
|
||||
hws[IMX8MM_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
|
||||
|
||||
clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
|
||||
clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
|
||||
clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
|
||||
clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
|
||||
clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
|
||||
clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
|
||||
clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
|
||||
clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
|
||||
clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
hws[IMX8MM_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
|
||||
hws[IMX8MM_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
|
||||
hws[IMX8MM_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
|
||||
hws[IMX8MM_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
|
||||
hws[IMX8MM_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
|
||||
hws[IMX8MM_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
|
||||
hws[IMX8MM_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
|
||||
hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
|
||||
hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
@ -404,204 +413,213 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(base);
|
||||
|
||||
/* Core Slice */
|
||||
clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
|
||||
clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
|
||||
clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
|
||||
clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
|
||||
clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
|
||||
clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
|
||||
clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
|
||||
clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
|
||||
clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
|
||||
clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
|
||||
clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
|
||||
clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
|
||||
hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
|
||||
hws[IMX8MM_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
|
||||
hws[IMX8MM_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
|
||||
hws[IMX8MM_CLK_GPU3D_SRC] = imx_clk_hw_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
|
||||
hws[IMX8MM_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels));
|
||||
hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
|
||||
hws[IMX8MM_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
hws[IMX8MM_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
|
||||
hws[IMX8MM_CLK_GPU3D_CG] = imx_clk_hw_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
|
||||
hws[IMX8MM_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
|
||||
hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
hws[IMX8MM_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
hws[IMX8MM_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
|
||||
hws[IMX8MM_CLK_GPU3D_DIV] = imx_clk_hw_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
|
||||
hws[IMX8MM_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
|
||||
|
||||
/* BUS */
|
||||
clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
|
||||
clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
|
||||
clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
|
||||
clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
|
||||
clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
|
||||
clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
|
||||
clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
|
||||
clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
|
||||
clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
|
||||
clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
|
||||
clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
|
||||
clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
|
||||
hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800);
|
||||
hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
|
||||
hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
|
||||
hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
|
||||
hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
|
||||
hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
|
||||
hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
|
||||
hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
|
||||
hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
|
||||
hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
|
||||
hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
|
||||
hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
|
||||
|
||||
/* AHB */
|
||||
clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
|
||||
clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
|
||||
hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
|
||||
hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
|
||||
|
||||
/* IPG */
|
||||
clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
hws[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
|
||||
/*
|
||||
* DRAM clocks are manipulated from TF-A outside clock framework.
|
||||
* Mark with GET_RATE_NOCACHE to always read div value from hardware
|
||||
*/
|
||||
hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
|
||||
hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
|
||||
|
||||
/* IP */
|
||||
clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
|
||||
clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
|
||||
clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
|
||||
clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
|
||||
clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
|
||||
clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
|
||||
clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
|
||||
clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
|
||||
clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
|
||||
clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
|
||||
clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
|
||||
clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
|
||||
clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
|
||||
clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
|
||||
clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
|
||||
clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
|
||||
clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
|
||||
clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
|
||||
clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
|
||||
clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
|
||||
clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
|
||||
clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
|
||||
clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
|
||||
clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
|
||||
clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
|
||||
clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
|
||||
clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
|
||||
clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
|
||||
clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
|
||||
clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
|
||||
clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
|
||||
clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
|
||||
clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
|
||||
clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
|
||||
clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
|
||||
clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
|
||||
clks[IMX8MM_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mm_gic_sels, base + 0xb200);
|
||||
clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
|
||||
clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
|
||||
clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
|
||||
clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
|
||||
clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
|
||||
clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
|
||||
clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
|
||||
clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
|
||||
clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
|
||||
clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
|
||||
clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
|
||||
clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
|
||||
clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
|
||||
clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
|
||||
clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
|
||||
clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
|
||||
clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
|
||||
clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
|
||||
clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
|
||||
clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
|
||||
clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
|
||||
clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
|
||||
clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
|
||||
clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
|
||||
clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
|
||||
clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
|
||||
hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
|
||||
hws[IMX8MM_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
|
||||
hws[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
|
||||
hws[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
|
||||
hws[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
|
||||
hws[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
|
||||
hws[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
|
||||
hws[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
|
||||
hws[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
|
||||
hws[IMX8MM_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
|
||||
hws[IMX8MM_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
|
||||
hws[IMX8MM_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
|
||||
hws[IMX8MM_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
|
||||
hws[IMX8MM_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
|
||||
hws[IMX8MM_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
|
||||
hws[IMX8MM_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
|
||||
hws[IMX8MM_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
|
||||
hws[IMX8MM_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
|
||||
hws[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
|
||||
hws[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
|
||||
hws[IMX8MM_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mm_nand_sels, base + 0xab00);
|
||||
hws[IMX8MM_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
|
||||
hws[IMX8MM_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
|
||||
hws[IMX8MM_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
|
||||
hws[IMX8MM_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
|
||||
hws[IMX8MM_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
|
||||
hws[IMX8MM_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
|
||||
hws[IMX8MM_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
|
||||
hws[IMX8MM_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
|
||||
hws[IMX8MM_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
|
||||
hws[IMX8MM_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
|
||||
hws[IMX8MM_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
|
||||
hws[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
|
||||
hws[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
|
||||
hws[IMX8MM_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mm_gic_sels, base + 0xb200);
|
||||
hws[IMX8MM_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
|
||||
hws[IMX8MM_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
|
||||
hws[IMX8MM_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
|
||||
hws[IMX8MM_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
|
||||
hws[IMX8MM_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
|
||||
hws[IMX8MM_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
|
||||
hws[IMX8MM_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
|
||||
hws[IMX8MM_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
|
||||
hws[IMX8MM_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
|
||||
hws[IMX8MM_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
|
||||
hws[IMX8MM_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
|
||||
hws[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
|
||||
hws[IMX8MM_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
|
||||
hws[IMX8MM_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
|
||||
hws[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
|
||||
hws[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
|
||||
hws[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
|
||||
hws[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
|
||||
hws[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
|
||||
hws[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
|
||||
hws[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
|
||||
hws[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
|
||||
hws[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
|
||||
hws[IMX8MM_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
|
||||
hws[IMX8MM_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
|
||||
hws[IMX8MM_CLK_VPU_H1] = imx8m_clk_hw_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
|
||||
|
||||
/* CCGR */
|
||||
clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
clks[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
clks[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
clks[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
clks[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
clks[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||
clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
|
||||
clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MM_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
||||
clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
|
||||
clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
|
||||
clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
|
||||
clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
|
||||
clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
|
||||
clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
|
||||
clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
|
||||
clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
|
||||
clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
|
||||
clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
|
||||
hws[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
hws[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
hws[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
hws[IMX8MM_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
hws[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
hws[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
hws[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
hws[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
hws[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
hws[IMX8MM_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||
hws[IMX8MM_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
hws[IMX8MM_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
hws[IMX8MM_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
hws[IMX8MM_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
hws[IMX8MM_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
hws[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
hws[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
|
||||
hws[IMX8MM_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
hws[IMX8MM_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
hws[IMX8MM_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
hws[IMX8MM_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
hws[IMX8MM_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
hws[IMX8MM_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MM_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
|
||||
hws[IMX8MM_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
|
||||
hws[IMX8MM_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MM_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MM_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MM_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MM_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
|
||||
hws[IMX8MM_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
|
||||
hws[IMX8MM_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MM_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
||||
hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
hws[IMX8MM_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
hws[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
|
||||
hws[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
|
||||
hws[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
hws[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
hws[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
hws[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
hws[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
hws[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
|
||||
hws[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
|
||||
hws[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_hw_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
|
||||
hws[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
|
||||
hws[IMX8MM_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
|
||||
hws[IMX8MM_CLK_PDM_IPG] = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
|
||||
hws[IMX8MM_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
|
||||
hws[IMX8MM_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
hws[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
|
||||
hws[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
hws[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
hws[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
hws[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
|
||||
hws[IMX8MM_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
|
||||
|
||||
clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
|
||||
hws[IMX8MM_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8);
|
||||
|
||||
clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
|
||||
hws[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
hws[IMX8MM_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
|
||||
clks[IMX8MM_CLK_A53_DIV],
|
||||
clks[IMX8MM_CLK_A53_SRC],
|
||||
clks[IMX8MM_ARM_PLL_OUT],
|
||||
clks[IMX8MM_SYS_PLL1_800M]);
|
||||
hws[IMX8MM_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
|
||||
hws[IMX8MM_CLK_A53_DIV]->clk,
|
||||
hws[IMX8MM_CLK_A53_SRC]->clk,
|
||||
hws[IMX8MM_ARM_PLL_OUT]->clk,
|
||||
hws[IMX8MM_SYS_PLL1_800M]->clk);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
imx_check_clk_hws(hws, IMX8MM_CLK_END);
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
|
||||
if (ret < 0) {
|
||||
pr_err("failed to register clks for i.MX8MM\n");
|
||||
goto unregister_clks;
|
||||
dev_err(dev, "failed to register clks for i.MX8MM\n");
|
||||
goto unregister_hws;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_clks);
|
||||
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
|
||||
int index = uart_clk_ids[i];
|
||||
|
||||
uart_hws[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_hws);
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_clks:
|
||||
imx_unregister_clocks(clks, ARRAY_SIZE(clks));
|
||||
unregister_hws:
|
||||
imx_unregister_hw_clocks(hws, IMX8MM_CLK_END);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -616,6 +634,11 @@ static struct platform_driver imx8mm_clk_driver = {
|
||||
.probe = imx8mm_clocks_probe,
|
||||
.driver = {
|
||||
.name = "imx8mm-ccm",
|
||||
/*
|
||||
* Disable bind attributes: clocks are not removed and
|
||||
* reloading the driver will crash or break devices.
|
||||
*/
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(imx8mm_clk_of_match),
|
||||
},
|
||||
};
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "clk.h"
|
||||
@ -280,284 +281,302 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy
|
||||
"sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "osc_32k", };
|
||||
|
||||
static struct clk *clks[IMX8MN_CLK_END];
|
||||
static struct clk_onecell_data clk_data;
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
static struct clk ** const uart_clks[] = {
|
||||
&clks[IMX8MN_CLK_UART1_ROOT],
|
||||
&clks[IMX8MN_CLK_UART2_ROOT],
|
||||
&clks[IMX8MN_CLK_UART3_ROOT],
|
||||
&clks[IMX8MN_CLK_UART4_ROOT],
|
||||
NULL
|
||||
static const int uart_clk_ids[] = {
|
||||
IMX8MN_CLK_UART1_ROOT,
|
||||
IMX8MN_CLK_UART2_ROOT,
|
||||
IMX8MN_CLK_UART3_ROOT,
|
||||
IMX8MN_CLK_UART4_ROOT,
|
||||
};
|
||||
static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
|
||||
|
||||
static int imx8mn_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
int ret, i;
|
||||
|
||||
clks[IMX8MN_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clks[IMX8MN_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
|
||||
clks[IMX8MN_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
|
||||
clks[IMX8MN_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
|
||||
clks[IMX8MN_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
|
||||
clks[IMX8MN_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
|
||||
clks[IMX8MN_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
|
||||
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
|
||||
IMX8MN_CLK_END), GFP_KERNEL);
|
||||
if (WARN_ON(!clk_hw_data))
|
||||
return -ENOMEM;
|
||||
|
||||
clk_hw_data->num = IMX8MN_CLK_END;
|
||||
hws = clk_hw_data->hws;
|
||||
|
||||
hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
hws[IMX8MN_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
|
||||
hws[IMX8MN_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
|
||||
hws[IMX8MN_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
|
||||
hws[IMX8MN_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
|
||||
hws[IMX8MN_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
|
||||
hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
if (WARN_ON(!base)) {
|
||||
ret = -ENOMEM;
|
||||
goto unregister_clks;
|
||||
goto unregister_hws;
|
||||
}
|
||||
|
||||
clks[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
|
||||
clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
|
||||
clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
|
||||
clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
|
||||
clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll);
|
||||
clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
|
||||
clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
|
||||
clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
|
||||
clks[IMX8MN_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000);
|
||||
clks[IMX8MN_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000);
|
||||
clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
|
||||
hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
|
||||
hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
|
||||
hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
|
||||
hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
|
||||
hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
|
||||
hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
|
||||
hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
|
||||
hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
|
||||
hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
|
||||
hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
|
||||
|
||||
/* PLL bypass out */
|
||||
clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
||||
/* PLL out gate */
|
||||
clks[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
|
||||
clks[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
|
||||
clks[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
|
||||
clks[IMX8MN_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
|
||||
clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
|
||||
clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
|
||||
clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
|
||||
clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
|
||||
hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
|
||||
hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
|
||||
hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
|
||||
hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
|
||||
hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
|
||||
hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
|
||||
hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
|
||||
hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
|
||||
|
||||
/* SYS PLL1 fixed output */
|
||||
clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
|
||||
clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
|
||||
clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
|
||||
clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
|
||||
clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
|
||||
clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
|
||||
clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
|
||||
clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
|
||||
clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
|
||||
hws[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
|
||||
hws[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
|
||||
hws[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
|
||||
hws[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
|
||||
hws[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
|
||||
hws[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
|
||||
hws[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
|
||||
hws[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
|
||||
hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
|
||||
|
||||
clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
|
||||
clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
|
||||
clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
|
||||
clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
|
||||
clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
|
||||
clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
|
||||
clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
|
||||
clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
|
||||
clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
|
||||
hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
|
||||
hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
|
||||
hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
|
||||
hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
|
||||
hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
|
||||
hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
|
||||
hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
|
||||
hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
|
||||
/* SYS PLL2 fixed output */
|
||||
clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
|
||||
clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
|
||||
clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
|
||||
clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
|
||||
clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
|
||||
clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
|
||||
clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
|
||||
clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
|
||||
clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
|
||||
hws[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
|
||||
hws[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
|
||||
hws[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
|
||||
hws[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
|
||||
hws[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
|
||||
hws[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
|
||||
hws[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
|
||||
hws[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
|
||||
hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
|
||||
|
||||
clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
|
||||
clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
|
||||
clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
|
||||
clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
|
||||
clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
|
||||
clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
|
||||
clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
|
||||
clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
|
||||
clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
|
||||
hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
|
||||
hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
|
||||
hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
|
||||
hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
|
||||
hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
|
||||
hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
|
||||
hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
|
||||
hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base))) {
|
||||
ret = PTR_ERR(base);
|
||||
goto unregister_clks;
|
||||
goto unregister_hws;
|
||||
}
|
||||
|
||||
/* CORE */
|
||||
clks[IMX8MN_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
|
||||
clks[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
|
||||
clks[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels, ARRAY_SIZE(imx8mn_gpu_shader_sels));
|
||||
clks[IMX8MN_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
|
||||
clks[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
|
||||
clks[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
|
||||
hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
|
||||
hws[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
|
||||
hws[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels, ARRAY_SIZE(imx8mn_gpu_shader_sels));
|
||||
hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
|
||||
hws[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
|
||||
hws[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
|
||||
|
||||
clks[IMX8MN_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
|
||||
clks[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
|
||||
hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
hws[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
|
||||
hws[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
|
||||
|
||||
/* BUS */
|
||||
clks[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
|
||||
clks[IMX8MN_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
|
||||
clks[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
|
||||
clks[IMX8MN_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
|
||||
clks[IMX8MN_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
|
||||
clks[IMX8MN_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
|
||||
clks[IMX8MN_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
|
||||
clks[IMX8MN_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
|
||||
clks[IMX8MN_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
|
||||
hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
|
||||
hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
|
||||
hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
|
||||
hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
|
||||
hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
|
||||
hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
|
||||
hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
|
||||
hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
|
||||
hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
|
||||
|
||||
clks[IMX8MN_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
|
||||
clks[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
|
||||
clks[IMX8MN_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
clks[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
clks[IMX8MN_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
|
||||
clks[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
|
||||
clks[IMX8MN_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
|
||||
clks[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
|
||||
clks[IMX8MN_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
|
||||
clks[IMX8MN_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
|
||||
clks[IMX8MN_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
|
||||
clks[IMX8MN_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
|
||||
clks[IMX8MN_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
|
||||
clks[IMX8MN_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
|
||||
clks[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
|
||||
clks[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
|
||||
clks[IMX8MN_CLK_NAND] = imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00);
|
||||
clks[IMX8MN_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
|
||||
clks[IMX8MN_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
|
||||
clks[IMX8MN_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
|
||||
clks[IMX8MN_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
|
||||
clks[IMX8MN_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
|
||||
clks[IMX8MN_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
|
||||
clks[IMX8MN_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
|
||||
clks[IMX8MN_CLK_UART1] = imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
|
||||
clks[IMX8MN_CLK_UART2] = imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
|
||||
clks[IMX8MN_CLK_UART3] = imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
|
||||
clks[IMX8MN_CLK_UART4] = imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
|
||||
clks[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
|
||||
clks[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
|
||||
clks[IMX8MN_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
|
||||
clks[IMX8MN_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
|
||||
clks[IMX8MN_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
|
||||
clks[IMX8MN_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
|
||||
clks[IMX8MN_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
|
||||
clks[IMX8MN_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
|
||||
clks[IMX8MN_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
|
||||
clks[IMX8MN_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
|
||||
clks[IMX8MN_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
|
||||
clks[IMX8MN_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
|
||||
clks[IMX8MN_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
|
||||
clks[IMX8MN_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
|
||||
clks[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
|
||||
clks[IMX8MN_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
|
||||
clks[IMX8MN_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
|
||||
clks[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
|
||||
clks[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
|
||||
clks[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
|
||||
clks[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
|
||||
clks[IMX8MN_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
|
||||
clks[IMX8MN_CLK_PDM] = imx8m_clk_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
|
||||
clks[IMX8MN_CLK_SAI7] = imx8m_clk_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
|
||||
hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
|
||||
hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
|
||||
hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
|
||||
|
||||
clks[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
clks[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
clks[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
clks[IMX8MN_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
clks[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
clks[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
clks[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
clks[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
clks[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
clks[IMX8MN_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
clks[IMX8MN_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
clks[IMX8MN_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
clks[IMX8MN_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
clks[IMX8MN_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
clks[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
clks[IMX8MN_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
clks[IMX8MN_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
clks[IMX8MN_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
clks[IMX8MN_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
clks[IMX8MN_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
clks[IMX8MN_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MN_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MN_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MN_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MN_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MN_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MN_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MN_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MN_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MN_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
|
||||
clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
|
||||
clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
clks[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
clks[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
clks[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
clks[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
|
||||
clks[IMX8MN_CLK_ASRC_ROOT] = imx_clk_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
|
||||
clks[IMX8MN_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MN_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
|
||||
clks[IMX8MN_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MN_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
|
||||
clks[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
|
||||
clks[IMX8MN_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
clks[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
clks[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
clks[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
clks[IMX8MN_CLK_SAI7_ROOT] = imx_clk_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
|
||||
/*
|
||||
* DRAM clocks are manipulated from TF-A outside clock framework.
|
||||
* Mark with GET_RATE_NOCACHE to always read div value from hardware
|
||||
*/
|
||||
hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
|
||||
hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
|
||||
|
||||
clks[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
|
||||
hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
|
||||
hws[IMX8MN_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
|
||||
hws[IMX8MN_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
|
||||
hws[IMX8MN_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
|
||||
hws[IMX8MN_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
|
||||
hws[IMX8MN_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
|
||||
hws[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
|
||||
hws[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
|
||||
hws[IMX8MN_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mn_nand_sels, base + 0xab00);
|
||||
hws[IMX8MN_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
|
||||
hws[IMX8MN_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
|
||||
hws[IMX8MN_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
|
||||
hws[IMX8MN_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
|
||||
hws[IMX8MN_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
|
||||
hws[IMX8MN_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
|
||||
hws[IMX8MN_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
|
||||
hws[IMX8MN_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
|
||||
hws[IMX8MN_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
|
||||
hws[IMX8MN_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
|
||||
hws[IMX8MN_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
|
||||
hws[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
|
||||
hws[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
|
||||
hws[IMX8MN_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
|
||||
hws[IMX8MN_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
|
||||
hws[IMX8MN_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
|
||||
hws[IMX8MN_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
|
||||
hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
|
||||
hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
|
||||
hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
|
||||
hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
|
||||
hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
|
||||
hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
|
||||
hws[IMX8MN_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
|
||||
hws[IMX8MN_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
|
||||
hws[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
|
||||
hws[IMX8MN_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
|
||||
hws[IMX8MN_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
|
||||
hws[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_hw_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
|
||||
hws[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
|
||||
hws[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
|
||||
hws[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
|
||||
hws[IMX8MN_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
|
||||
hws[IMX8MN_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
|
||||
hws[IMX8MN_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
|
||||
|
||||
clks[IMX8MN_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
|
||||
clks[IMX8MN_CLK_A53_DIV],
|
||||
clks[IMX8MN_CLK_A53_SRC],
|
||||
clks[IMX8MN_ARM_PLL_OUT],
|
||||
clks[IMX8MN_SYS_PLL1_800M]);
|
||||
hws[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
hws[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
hws[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
hws[IMX8MN_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
hws[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
hws[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
hws[IMX8MN_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
hws[IMX8MN_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
hws[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
hws[IMX8MN_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
hws[IMX8MN_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
hws[IMX8MN_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
hws[IMX8MN_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
hws[IMX8MN_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
hws[IMX8MN_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MN_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MN_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MN_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MN_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MN_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
hws[IMX8MN_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
hws[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
|
||||
hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
|
||||
hws[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
hws[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
hws[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
hws[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
hws[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
hws[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
|
||||
hws[IMX8MN_CLK_ASRC_ROOT] = imx_clk_hw_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
|
||||
hws[IMX8MN_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
|
||||
hws[IMX8MN_CLK_PDM_IPG] = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
|
||||
hws[IMX8MN_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MN_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
|
||||
hws[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
|
||||
hws[IMX8MN_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
hws[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
hws[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||
hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
|
||||
hws[IMX8MN_CLK_A53_DIV]->clk,
|
||||
hws[IMX8MN_CLK_A53_SRC]->clk,
|
||||
hws[IMX8MN_ARM_PLL_OUT]->clk,
|
||||
hws[IMX8MN_SYS_PLL1_800M]->clk);
|
||||
|
||||
imx_check_clk_hws(hws, IMX8MN_CLK_END);
|
||||
|
||||
ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to register clks for i.MX8MN\n");
|
||||
goto unregister_clks;
|
||||
dev_err(dev, "failed to register hws for i.MX8MN\n");
|
||||
goto unregister_hws;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_clks);
|
||||
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
|
||||
int index = uart_clk_ids[i];
|
||||
|
||||
uart_hws[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_hws);
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_clks:
|
||||
imx_unregister_clocks(clks, ARRAY_SIZE(clks));
|
||||
unregister_hws:
|
||||
imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -572,6 +591,11 @@ static struct platform_driver imx8mn_clk_driver = {
|
||||
.probe = imx8mn_clocks_probe,
|
||||
.driver = {
|
||||
.name = "imx8mn-ccm",
|
||||
/*
|
||||
* Disable bind attributes: clocks are not removed and
|
||||
* reloading the driver will crash or break devices.
|
||||
*/
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(imx8mn_clk_of_match),
|
||||
},
|
||||
};
|
||||
|
764
drivers/clk/imx/clk-imx8mp.c
Normal file
764
drivers/clk/imx/clk-imx8mp.c
Normal file
@ -0,0 +1,764 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2019 NXP.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx8mp-clock.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
static u32 share_count_nand;
|
||||
static u32 share_count_media;
|
||||
|
||||
static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
|
||||
static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
|
||||
static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
|
||||
static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
|
||||
static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
|
||||
static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
|
||||
static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
|
||||
static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
||||
static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
|
||||
static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
|
||||
static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
|
||||
|
||||
static const char * const imx8mp_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
|
||||
"sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
|
||||
"audio_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m",
|
||||
"vpu_pll_out", "sys_pll1_800m", "audio_pll1_out",
|
||||
"video_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
|
||||
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
|
||||
"clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll1_400m", "audio_pll2_out",
|
||||
"clk_ext1", "sys_pll2_500m", };
|
||||
|
||||
static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
|
||||
"sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "sys_pll1_100m",};
|
||||
|
||||
static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
|
||||
"sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
|
||||
"video_pll1_out", "sys_pll3_out", };
|
||||
|
||||
static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
|
||||
"sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out",
|
||||
"audio_pll2_out", "sys_pll3_out", "sys_pll2_1000m",
|
||||
"sys_pll2_200m", "sys_pll1_100m", };
|
||||
|
||||
static const char * const imx8mp_media_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
|
||||
"clk_ext1", "sys_pll2_500m", };
|
||||
|
||||
static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m",
|
||||
"sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
|
||||
"clk_ext1", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
|
||||
"sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
|
||||
"sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
|
||||
"audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
|
||||
"audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll3_out", "clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
|
||||
"sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
|
||||
"audio_pll1_out", "sys_pll1_266m", };
|
||||
|
||||
static const char * const imx8mp_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m",
|
||||
"sys_pll3_out", "audio_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m",
|
||||
"sys_pll3_out", "audio_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_can1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
|
||||
"clk_ext1", "clk_ext2", "clk_ext3",
|
||||
"clk_ext4", "sys_pll1_400m", };
|
||||
|
||||
static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "sys_pll2_100m", "sys_pll1_80m",
|
||||
"sys_pll1_160m", "sys_pll1_200m", };
|
||||
|
||||
static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext1", "clk_ext2", };
|
||||
|
||||
static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext1", "clk_ext2", };
|
||||
|
||||
static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext2", "clk_ext3", };
|
||||
|
||||
static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
|
||||
"sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
|
||||
"video_pll1_out", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
|
||||
"clk_ext1", "clk_ext2", "clk_ext3",
|
||||
"clk_ext4", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
|
||||
"sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
|
||||
"video_pll1_out", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
|
||||
"clk_ext1", "clk_ext2", "clk_ext3",
|
||||
"clk_ext4", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
|
||||
"sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
|
||||
"sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
|
||||
"sys_pll2_250m", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
|
||||
"sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
|
||||
"sys_pll3_out", "sys_pll1_100m", };
|
||||
|
||||
static const char * const imx8mp_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
|
||||
"sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
|
||||
"audio_pll2_out", "sys_pll1_100m", };
|
||||
|
||||
static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
|
||||
"sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
|
||||
"audio_pll2_out", "sys_pll1_100m", };
|
||||
|
||||
static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
|
||||
"sys_pll2_100m", "sys_pll3_out", "clk_ext2",
|
||||
"clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
|
||||
"sys_pll2_100m", "sys_pll3_out", "clk_ext2",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
|
||||
"sys_pll2_100m", "sys_pll3_out", "clk_ext2",
|
||||
"clk_ext4", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
|
||||
"sys_pll2_100m", "sys_pll3_out", "clk_ext2",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_usb_core_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
|
||||
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_usb_phy_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
|
||||
"sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_gic_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll2_100m", "sys_pll1_800m",
|
||||
"sys_pll2_500m", "clk_ext4", "audio_pll2_out" };
|
||||
|
||||
static const char * const imx8mp_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
|
||||
"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
|
||||
"sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
|
||||
"sys_pll1_40m", "sys_pll3_out", "clk_ext1",
|
||||
"sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
|
||||
"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
|
||||
"sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
|
||||
"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
|
||||
"sys_pll1_80m", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext1" };
|
||||
|
||||
static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext2" };
|
||||
|
||||
static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext3" };
|
||||
|
||||
static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext1" };
|
||||
|
||||
static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext2" };
|
||||
|
||||
static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||
"audio_pll1_out", "clk_ext3" };
|
||||
|
||||
static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
|
||||
"vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
|
||||
"sys_pll1_80m", "sys_pll2_166m" };
|
||||
|
||||
static const char * const imx8mp_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
|
||||
"sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
|
||||
"sys_pll2_500m", "sys_pll1_100m" };
|
||||
|
||||
static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_133m",
|
||||
"sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m",
|
||||
"vpu_pll_out", "sys_pll1_80m" };
|
||||
|
||||
static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
|
||||
"sys_pll1_166m", "sys_pll3_out", "audio_pll1_out",
|
||||
"video_pll1_out", "osc_32k" };
|
||||
|
||||
static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
|
||||
"audio_pll2_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_hdmi_27m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out",
|
||||
"sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m",
|
||||
"audio_pll1_out", "video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
|
||||
"sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
|
||||
"audio_pll2_out", "sys_pll1_100m", };
|
||||
|
||||
static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll3_out", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"clk_ext2", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
|
||||
"audio_pll1_out", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll3_out", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_phy2_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"clk_ext2", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll3_out", "clk_ext3",
|
||||
"audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m",
|
||||
"sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
"sys_pll2_333m", "sys_pll3_out", };
|
||||
|
||||
static const char * const imx8mp_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
|
||||
"clk_ext1", "clk_ext2", "clk_ext3",
|
||||
"clk_ext4", "sys_pll1_400m", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "sys_pll2_100m",
|
||||
"sys_pll1_80m", "sys_pll1_160m",
|
||||
"sys_pll1_200m", };
|
||||
|
||||
static const char * const imx8mp_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
|
||||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
|
||||
"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
|
||||
"sys_pll2_1000m", "audio_pll2_out", "sys_pll2_125m",
|
||||
"sys_pll3_out", "audio_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
|
||||
"video_pll1_out", "sys_pll1_133m", "osc_hdmi",
|
||||
"clk_ext3", "clk_ext4", };
|
||||
|
||||
static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
|
||||
|
||||
static struct clk_hw **hws;
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
|
||||
static const int uart_clk_ids[] = {
|
||||
IMX8MP_CLK_UART1_ROOT,
|
||||
IMX8MP_CLK_UART2_ROOT,
|
||||
IMX8MP_CLK_UART3_ROOT,
|
||||
IMX8MP_CLK_UART4_ROOT,
|
||||
};
|
||||
static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1];
|
||||
|
||||
static int imx8mp_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
void __iomem *anatop_base, *ccm_base;
|
||||
int i;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
|
||||
anatop_base = of_iomap(np, 0);
|
||||
if (WARN_ON(!anatop_base))
|
||||
return -ENOMEM;
|
||||
|
||||
np = dev->of_node;
|
||||
ccm_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(ccm_base))) {
|
||||
iounmap(anatop_base);
|
||||
return PTR_ERR(ccm_base);
|
||||
}
|
||||
|
||||
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
|
||||
if (WARN_ON(!clk_hw_data)) {
|
||||
iounmap(anatop_base);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_hw_data->num = IMX8MP_CLK_END;
|
||||
hws = clk_hw_data->hws;
|
||||
|
||||
hws[IMX8MP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
hws[IMX8MP_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
|
||||
hws[IMX8MP_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
|
||||
hws[IMX8MP_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
|
||||
hws[IMX8MP_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
|
||||
hws[IMX8MP_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
|
||||
hws[IMX8MP_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
|
||||
|
||||
hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", anatop_base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_SYS_PLL1_REF_SEL] = imx_clk_hw_mux("sys_pll1_ref_sel", anatop_base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_SYS_PLL2_REF_SEL] = imx_clk_hw_mux("sys_pll2_ref_sel", anatop_base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MP_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", anatop_base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
|
||||
hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
|
||||
hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
|
||||
hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
|
||||
hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
|
||||
hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
|
||||
hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
|
||||
hws[IMX8MP_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", anatop_base + 0x84, &imx_1416x_pll);
|
||||
hws[IMX8MP_SYS_PLL1] = imx_clk_hw_pll14xx("sys_pll1", "sys_pll1_ref_sel", anatop_base + 0x94, &imx_1416x_pll);
|
||||
hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
|
||||
hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
|
||||
|
||||
hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
|
||||
hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
|
||||
hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
|
||||
hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13);
|
||||
hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
|
||||
hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
|
||||
hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
|
||||
hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
|
||||
hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
|
||||
hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
|
||||
hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
|
||||
|
||||
hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
|
||||
hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
|
||||
hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
|
||||
hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
|
||||
hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
|
||||
hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
|
||||
hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
|
||||
hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
|
||||
hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
|
||||
|
||||
hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
|
||||
hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
|
||||
hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
|
||||
hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
|
||||
hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
|
||||
hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
|
||||
hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
|
||||
hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
|
||||
hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||
|
||||
hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels));
|
||||
hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels));
|
||||
hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels));
|
||||
hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3, imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels));
|
||||
hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels));
|
||||
hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels));
|
||||
hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels));
|
||||
hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels));
|
||||
hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels));
|
||||
hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28);
|
||||
hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28);
|
||||
hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28);
|
||||
hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28);
|
||||
hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28);
|
||||
hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28);
|
||||
hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28);
|
||||
hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28);
|
||||
hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28);
|
||||
hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3);
|
||||
hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3);
|
||||
hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3);
|
||||
hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3);
|
||||
hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3);
|
||||
hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3);
|
||||
hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3);
|
||||
hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3);
|
||||
hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3);
|
||||
|
||||
hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
|
||||
hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
|
||||
hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
|
||||
hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
|
||||
hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
|
||||
hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
|
||||
hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
|
||||
hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_apb_sels, ccm_base + 0x8b80);
|
||||
hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
|
||||
hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
|
||||
hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
|
||||
hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
|
||||
hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
|
||||
hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
|
||||
|
||||
hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
|
||||
hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
|
||||
hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
|
||||
|
||||
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
|
||||
hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
|
||||
|
||||
hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
|
||||
hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
|
||||
hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
|
||||
hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
|
||||
hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
|
||||
hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
|
||||
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300);
|
||||
hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", imx8mp_pcie_phy_sels, ccm_base + 0xa380);
|
||||
hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
|
||||
hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
|
||||
hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500);
|
||||
hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
|
||||
hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
|
||||
hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
|
||||
hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700);
|
||||
hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
|
||||
hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
|
||||
hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
|
||||
hws[IMX8MP_CLK_ENET_QOS_TIMER] = imx8m_clk_hw_composite("enet_qos_timer", imx8mp_enet_qos_timer_sels, ccm_base + 0xa900);
|
||||
hws[IMX8MP_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mp_enet_ref_sels, ccm_base + 0xa980);
|
||||
hws[IMX8MP_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mp_enet_timer_sels, ccm_base + 0xaa00);
|
||||
hws[IMX8MP_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, ccm_base + 0xaa80);
|
||||
hws[IMX8MP_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mp_nand_sels, ccm_base + 0xab00);
|
||||
hws[IMX8MP_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mp_qspi_sels, ccm_base + 0xab80);
|
||||
hws[IMX8MP_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mp_usdhc1_sels, ccm_base + 0xac00);
|
||||
hws[IMX8MP_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mp_usdhc2_sels, ccm_base + 0xac80);
|
||||
hws[IMX8MP_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mp_i2c1_sels, ccm_base + 0xad00);
|
||||
hws[IMX8MP_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mp_i2c2_sels, ccm_base + 0xad80);
|
||||
hws[IMX8MP_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mp_i2c3_sels, ccm_base + 0xae00);
|
||||
hws[IMX8MP_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mp_i2c4_sels, ccm_base + 0xae80);
|
||||
|
||||
hws[IMX8MP_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mp_uart1_sels, ccm_base + 0xaf00);
|
||||
hws[IMX8MP_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mp_uart2_sels, ccm_base + 0xaf80);
|
||||
hws[IMX8MP_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mp_uart3_sels, ccm_base + 0xb000);
|
||||
hws[IMX8MP_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mp_uart4_sels, ccm_base + 0xb080);
|
||||
hws[IMX8MP_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mp_usb_core_ref_sels, ccm_base + 0xb100);
|
||||
hws[IMX8MP_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mp_usb_phy_ref_sels, ccm_base + 0xb180);
|
||||
hws[IMX8MP_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mp_gic_sels, ccm_base + 0xb200);
|
||||
hws[IMX8MP_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mp_ecspi1_sels, ccm_base + 0xb280);
|
||||
hws[IMX8MP_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mp_ecspi2_sels, ccm_base + 0xb300);
|
||||
hws[IMX8MP_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mp_pwm1_sels, ccm_base + 0xb380);
|
||||
hws[IMX8MP_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mp_pwm2_sels, ccm_base + 0xb400);
|
||||
hws[IMX8MP_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mp_pwm3_sels, ccm_base + 0xb480);
|
||||
hws[IMX8MP_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mp_pwm4_sels, ccm_base + 0xb500);
|
||||
|
||||
hws[IMX8MP_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mp_gpt1_sels, ccm_base + 0xb580);
|
||||
hws[IMX8MP_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mp_gpt2_sels, ccm_base + 0xb600);
|
||||
hws[IMX8MP_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mp_gpt3_sels, ccm_base + 0xb680);
|
||||
hws[IMX8MP_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mp_gpt4_sels, ccm_base + 0xb700);
|
||||
hws[IMX8MP_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mp_gpt5_sels, ccm_base + 0xb780);
|
||||
hws[IMX8MP_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mp_gpt6_sels, ccm_base + 0xb800);
|
||||
hws[IMX8MP_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mp_wdog_sels, ccm_base + 0xb900);
|
||||
hws[IMX8MP_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mp_wrclk_sels, ccm_base + 0xb980);
|
||||
hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00);
|
||||
hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80);
|
||||
hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00);
|
||||
hws[IMX8MP_CLK_HDMI_27M] = imx8m_clk_hw_composite("hdmi_27m", imx8mp_hdmi_27m_sels, ccm_base + 0xbb80);
|
||||
hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00);
|
||||
hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY2_REF] = imx8m_clk_hw_composite("media_mipi_phy2_ref", imx8mp_media_mipi_phy2_ref_sels, ccm_base + 0xbf00);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80);
|
||||
hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
|
||||
hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
|
||||
hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180);
|
||||
hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200);
|
||||
hws[IMX8MP_CLK_VPU_VC8000E] = imx8m_clk_hw_composite("vpu_vc8000e", imx8mp_vpu_vc8000e_sels, ccm_base + 0xc280);
|
||||
hws[IMX8MP_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mp_sai7_sels, ccm_base + 0xc300);
|
||||
|
||||
hws[IMX8MP_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
hws[IMX8MP_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", ccm_base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL);
|
||||
|
||||
hws[IMX8MP_CLK_DRAM1_ROOT] = imx_clk_hw_gate4_flags("dram1_root_clk", "dram_core_clk", ccm_base + 0x4050, 0, CLK_IS_CRITICAL);
|
||||
hws[IMX8MP_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", ccm_base + 0x4070, 0);
|
||||
hws[IMX8MP_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", ccm_base + 0x4080, 0);
|
||||
hws[IMX8MP_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", ccm_base + 0x4090, 0);
|
||||
hws[IMX8MP_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", ccm_base + 0x40a0, 0);
|
||||
hws[IMX8MP_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", ccm_base + 0x40b0, 0);
|
||||
hws[IMX8MP_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", ccm_base + 0x40c0, 0);
|
||||
hws[IMX8MP_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", ccm_base + 0x40d0, 0);
|
||||
hws[IMX8MP_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", ccm_base + 0x40e0, 0);
|
||||
hws[IMX8MP_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", ccm_base + 0x40f0, 0);
|
||||
hws[IMX8MP_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", ccm_base + 0x4100, 0);
|
||||
hws[IMX8MP_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", ccm_base + 0x4110, 0);
|
||||
hws[IMX8MP_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", ccm_base + 0x4120, 0);
|
||||
hws[IMX8MP_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", ccm_base + 0x4130, 0);
|
||||
hws[IMX8MP_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", ccm_base + 0x4140, 0);
|
||||
hws[IMX8MP_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", ccm_base + 0x4150, 0);
|
||||
hws[IMX8MP_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", ccm_base + 0x4170, 0);
|
||||
hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0);
|
||||
hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0);
|
||||
hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0);
|
||||
hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0);
|
||||
hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0);
|
||||
hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0);
|
||||
hws[IMX8MP_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", ccm_base + 0x42a0, 0);
|
||||
hws[IMX8MP_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", ccm_base + 0x42b0, 0);
|
||||
hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0);
|
||||
hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0);
|
||||
hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0);
|
||||
hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0);
|
||||
hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0);
|
||||
hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
|
||||
hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
|
||||
hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
|
||||
hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "enet_axi", ccm_base + 0x43b0, 0);
|
||||
hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
|
||||
hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0);
|
||||
hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0);
|
||||
hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
|
||||
hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
|
||||
hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
|
||||
hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
|
||||
hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
|
||||
hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0);
|
||||
hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
|
||||
hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
|
||||
hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
|
||||
hws[IMX8MP_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", ccm_base + 0x4530, 0);
|
||||
hws[IMX8MP_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", ccm_base + 0x4540, 0);
|
||||
hws[IMX8MP_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", ccm_base + 0x4550, 0);
|
||||
hws[IMX8MP_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", ccm_base + 0x4560, 0);
|
||||
hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
|
||||
hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
|
||||
hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
|
||||
hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0);
|
||||
hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
|
||||
hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media);
|
||||
|
||||
hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
|
||||
hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
|
||||
hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0);
|
||||
hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0);
|
||||
hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0);
|
||||
|
||||
hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
|
||||
hws[IMX8MP_CLK_A53_DIV]->clk,
|
||||
hws[IMX8MP_CLK_A53_SRC]->clk,
|
||||
hws[IMX8MP_ARM_PLL_OUT]->clk,
|
||||
hws[IMX8MP_SYS_PLL1_800M]->clk);
|
||||
|
||||
imx_check_clk_hws(hws, IMX8MP_CLK_END);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
|
||||
int index = uart_clk_ids[i];
|
||||
|
||||
uart_clks[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_clks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id imx8mp_clk_of_match[] = {
|
||||
{ .compatible = "fsl,imx8mp-ccm" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx8mp_clk_of_match);
|
||||
|
||||
static struct platform_driver imx8mp_clk_driver = {
|
||||
.probe = imx8mp_clocks_probe,
|
||||
.driver = {
|
||||
.name = "imx8mp-ccm",
|
||||
/*
|
||||
* Disable bind attributes: clocks are not removed and
|
||||
* reloading the driver will crash or break devices.
|
||||
*/
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(imx8mp_clk_of_match),
|
||||
},
|
||||
};
|
||||
module_platform_driver(imx8mp_clk_driver);
|
@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk.h"
|
||||
@ -24,8 +25,6 @@ static u32 share_count_sai6;
|
||||
static u32 share_count_dcss;
|
||||
static u32 share_count_nand;
|
||||
|
||||
static struct clk *clks[IMX8MQ_CLK_END];
|
||||
|
||||
static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
|
||||
static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
||||
static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
|
||||
@ -269,124 +268,133 @@ static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "os
|
||||
static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
|
||||
"sys3_pll_out", "audio_pll1_out", "video_pll1_out", "ckil", };
|
||||
|
||||
static struct clk_onecell_data clk_data;
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
static struct clk ** const uart_clks[] = {
|
||||
&clks[IMX8MQ_CLK_UART1_ROOT],
|
||||
&clks[IMX8MQ_CLK_UART2_ROOT],
|
||||
&clks[IMX8MQ_CLK_UART3_ROOT],
|
||||
&clks[IMX8MQ_CLK_UART4_ROOT],
|
||||
NULL
|
||||
static const int uart_clk_ids[] = {
|
||||
IMX8MQ_CLK_UART1_ROOT,
|
||||
IMX8MQ_CLK_UART2_ROOT,
|
||||
IMX8MQ_CLK_UART3_ROOT,
|
||||
IMX8MQ_CLK_UART4_ROOT,
|
||||
};
|
||||
static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
|
||||
|
||||
static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
void __iomem *base;
|
||||
int err;
|
||||
int err, i;
|
||||
|
||||
clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil");
|
||||
clks[IMX8MQ_CLK_25M] = of_clk_get_by_name(np, "osc_25m");
|
||||
clks[IMX8MQ_CLK_27M] = of_clk_get_by_name(np, "osc_27m");
|
||||
clks[IMX8MQ_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
|
||||
clks[IMX8MQ_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
|
||||
clks[IMX8MQ_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
|
||||
clks[IMX8MQ_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
|
||||
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
|
||||
IMX8MQ_CLK_END), GFP_KERNEL);
|
||||
if (WARN_ON(!clk_hw_data))
|
||||
return -ENOMEM;
|
||||
|
||||
clk_hw_data->num = IMX8MQ_CLK_END;
|
||||
hws = clk_hw_data->hws;
|
||||
|
||||
hws[IMX8MQ_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
|
||||
hws[IMX8MQ_CLK_32K] = imx_obtain_fixed_clk_hw(np, "ckil");
|
||||
hws[IMX8MQ_CLK_25M] = imx_obtain_fixed_clk_hw(np, "osc_25m");
|
||||
hws[IMX8MQ_CLK_27M] = imx_obtain_fixed_clk_hw(np, "osc_27m");
|
||||
hws[IMX8MQ_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
|
||||
hws[IMX8MQ_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
|
||||
hws[IMX8MQ_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
|
||||
hws[IMX8MQ_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
if (WARN_ON(!base))
|
||||
return -ENOMEM;
|
||||
|
||||
clks[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_SYS3_PLL1_REF_SEL] = imx_clk_hw_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_DRAM_PLL1_REF_SEL] = imx_clk_hw_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
hws[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_hw_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
|
||||
|
||||
clks[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
|
||||
clks[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
|
||||
clks[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
|
||||
clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
|
||||
clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
|
||||
clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
|
||||
hws[IMX8MQ_ARM_PLL_REF_DIV] = imx_clk_hw_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
|
||||
hws[IMX8MQ_GPU_PLL_REF_DIV] = imx_clk_hw_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
|
||||
hws[IMX8MQ_VPU_PLL_REF_DIV] = imx_clk_hw_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
|
||||
hws[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_hw_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
|
||||
hws[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_hw_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
|
||||
hws[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_hw_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
|
||||
|
||||
clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
|
||||
clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
|
||||
clks[IMX8MQ_VPU_PLL] = imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
|
||||
clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
|
||||
clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
|
||||
clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
|
||||
hws[IMX8MQ_ARM_PLL] = imx_clk_hw_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
|
||||
hws[IMX8MQ_GPU_PLL] = imx_clk_hw_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
|
||||
hws[IMX8MQ_VPU_PLL] = imx_clk_hw_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
|
||||
hws[IMX8MQ_AUDIO_PLL1] = imx_clk_hw_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
|
||||
hws[IMX8MQ_AUDIO_PLL2] = imx_clk_hw_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
|
||||
hws[IMX8MQ_VIDEO_PLL1] = imx_clk_hw_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
|
||||
|
||||
/* PLL bypass out */
|
||||
clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
|
||||
clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
|
||||
clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
|
||||
clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
|
||||
clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
|
||||
hws[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
|
||||
hws[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_hw_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
|
||||
hws[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_hw_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
|
||||
hws[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
|
||||
hws[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
|
||||
hws[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
|
||||
|
||||
/* PLL OUT GATE */
|
||||
clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
|
||||
clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
|
||||
clks[IMX8MQ_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
|
||||
clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
|
||||
clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
|
||||
clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
|
||||
hws[IMX8MQ_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
|
||||
hws[IMX8MQ_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
|
||||
hws[IMX8MQ_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
|
||||
hws[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
|
||||
hws[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
|
||||
hws[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
|
||||
|
||||
clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_fixed("sys1_pll_out", 800000000);
|
||||
clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_fixed("sys2_pll_out", 1000000000);
|
||||
clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
|
||||
hws[IMX8MQ_SYS1_PLL_OUT] = imx_clk_hw_fixed("sys1_pll_out", 800000000);
|
||||
hws[IMX8MQ_SYS2_PLL_OUT] = imx_clk_hw_fixed("sys2_pll_out", 1000000000);
|
||||
hws[IMX8MQ_SYS3_PLL_OUT] = imx_clk_hw_sscg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL);
|
||||
hws[IMX8MQ_DRAM_PLL_OUT] = imx_clk_hw_sscg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
|
||||
hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
|
||||
|
||||
/* SYS PLL1 fixed output */
|
||||
clks[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9);
|
||||
clks[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11);
|
||||
clks[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13);
|
||||
clks[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15);
|
||||
clks[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17);
|
||||
clks[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19);
|
||||
clks[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21);
|
||||
clks[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23);
|
||||
clks[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25);
|
||||
hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9);
|
||||
hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11);
|
||||
hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13);
|
||||
hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15);
|
||||
hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17);
|
||||
hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19);
|
||||
hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21);
|
||||
hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23);
|
||||
hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25);
|
||||
|
||||
clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20);
|
||||
clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10);
|
||||
clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8);
|
||||
clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6);
|
||||
clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5);
|
||||
clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4);
|
||||
clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3);
|
||||
clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2);
|
||||
clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1);
|
||||
hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20);
|
||||
hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10);
|
||||
hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8);
|
||||
hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6);
|
||||
hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5);
|
||||
hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4);
|
||||
hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3);
|
||||
hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2);
|
||||
hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1);
|
||||
|
||||
/* SYS PLL2 fixed output */
|
||||
clks[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9);
|
||||
clks[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11);
|
||||
clks[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13);
|
||||
clks[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15);
|
||||
clks[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17);
|
||||
clks[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19);
|
||||
clks[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21);
|
||||
clks[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23);
|
||||
clks[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25);
|
||||
hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9);
|
||||
hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11);
|
||||
hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13);
|
||||
hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15);
|
||||
hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17);
|
||||
hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19);
|
||||
hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21);
|
||||
hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23);
|
||||
hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25);
|
||||
|
||||
clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20);
|
||||
clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10);
|
||||
clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8);
|
||||
clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6);
|
||||
clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5);
|
||||
clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4);
|
||||
clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3);
|
||||
clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2);
|
||||
clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1);
|
||||
hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20);
|
||||
hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10);
|
||||
hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8);
|
||||
hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6);
|
||||
hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5);
|
||||
hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4);
|
||||
hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3);
|
||||
hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2);
|
||||
hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
@ -394,206 +402,213 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(base);
|
||||
|
||||
/* CORE */
|
||||
clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
|
||||
clks[IMX8MQ_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
|
||||
clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
|
||||
clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
|
||||
clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
|
||||
hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
|
||||
hws[IMX8MQ_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
|
||||
hws[IMX8MQ_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
|
||||
hws[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3, imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
|
||||
hws[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels, ARRAY_SIZE(imx8mq_gpu_shader_sels));
|
||||
|
||||
clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
|
||||
clks[IMX8MQ_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
|
||||
clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
|
||||
clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
|
||||
hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
|
||||
hws[IMX8MQ_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
hws[IMX8MQ_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
|
||||
hws[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
|
||||
hws[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
|
||||
|
||||
clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
clks[IMX8MQ_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
|
||||
clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
|
||||
clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
|
||||
hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
|
||||
hws[IMX8MQ_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
|
||||
hws[IMX8MQ_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
|
||||
hws[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
|
||||
hws[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
|
||||
|
||||
/* BUS */
|
||||
clks[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
|
||||
clks[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
|
||||
clks[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
|
||||
clks[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
|
||||
clks[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
|
||||
clks[IMX8MQ_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
|
||||
clks[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
|
||||
clks[IMX8MQ_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
|
||||
clks[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
|
||||
clks[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
|
||||
clks[IMX8MQ_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
|
||||
clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
|
||||
hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
|
||||
hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
|
||||
hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
|
||||
hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
|
||||
hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
|
||||
hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
|
||||
hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
|
||||
hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
|
||||
hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
|
||||
hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
|
||||
hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
|
||||
hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
|
||||
|
||||
/* AHB */
|
||||
/* AHB clock is used by the AHB bus therefore marked as critical */
|
||||
clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
|
||||
clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
|
||||
hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
|
||||
hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
|
||||
|
||||
/* IPG */
|
||||
clks[IMX8MQ_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
clks[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
|
||||
hws[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
|
||||
|
||||
/*
|
||||
* DRAM clocks are manipulated from TF-A outside clock framework.
|
||||
* Mark with GET_RATE_NOCACHE to always read div value from hardware
|
||||
*/
|
||||
hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
|
||||
hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
|
||||
hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
|
||||
|
||||
/* IP */
|
||||
clks[IMX8MQ_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
|
||||
hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
|
||||
hws[IMX8MQ_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
|
||||
hws[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
|
||||
hws[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
|
||||
hws[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
|
||||
hws[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
|
||||
hws[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
|
||||
hws[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
|
||||
hws[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
|
||||
hws[IMX8MQ_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
|
||||
hws[IMX8MQ_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
|
||||
hws[IMX8MQ_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
|
||||
hws[IMX8MQ_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
|
||||
hws[IMX8MQ_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
|
||||
hws[IMX8MQ_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
|
||||
hws[IMX8MQ_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
|
||||
hws[IMX8MQ_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
|
||||
hws[IMX8MQ_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
|
||||
hws[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
|
||||
hws[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
|
||||
hws[IMX8MQ_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mq_nand_sels, base + 0xab00);
|
||||
hws[IMX8MQ_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
|
||||
hws[IMX8MQ_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
|
||||
hws[IMX8MQ_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
|
||||
hws[IMX8MQ_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
|
||||
hws[IMX8MQ_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
|
||||
hws[IMX8MQ_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
|
||||
hws[IMX8MQ_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
|
||||
hws[IMX8MQ_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
|
||||
hws[IMX8MQ_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
|
||||
hws[IMX8MQ_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
|
||||
hws[IMX8MQ_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
|
||||
hws[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
|
||||
hws[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
|
||||
hws[IMX8MQ_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mq_gic_sels, base + 0xb200);
|
||||
hws[IMX8MQ_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
|
||||
hws[IMX8MQ_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
|
||||
hws[IMX8MQ_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
|
||||
hws[IMX8MQ_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
|
||||
hws[IMX8MQ_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
|
||||
hws[IMX8MQ_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
|
||||
hws[IMX8MQ_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
|
||||
hws[IMX8MQ_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
|
||||
hws[IMX8MQ_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
|
||||
hws[IMX8MQ_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
|
||||
hws[IMX8MQ_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
|
||||
hws[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
|
||||
hws[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
|
||||
hws[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
|
||||
hws[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_hw_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
|
||||
hws[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_hw_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
|
||||
hws[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_hw_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
|
||||
hws[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
|
||||
hws[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
|
||||
hws[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
|
||||
hws[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
|
||||
hws[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
|
||||
hws[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
|
||||
hws[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
|
||||
hws[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
|
||||
hws[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
|
||||
hws[IMX8MQ_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
|
||||
|
||||
clks[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
|
||||
clks[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
|
||||
clks[IMX8MQ_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
|
||||
clks[IMX8MQ_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
|
||||
clks[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
|
||||
clks[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
|
||||
clks[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
|
||||
clks[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
|
||||
clks[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
|
||||
clks[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
|
||||
clks[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
|
||||
clks[IMX8MQ_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
|
||||
clks[IMX8MQ_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
|
||||
clks[IMX8MQ_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
|
||||
clks[IMX8MQ_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
|
||||
clks[IMX8MQ_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
|
||||
clks[IMX8MQ_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
|
||||
clks[IMX8MQ_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
|
||||
clks[IMX8MQ_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
|
||||
clks[IMX8MQ_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
|
||||
clks[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
|
||||
clks[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
|
||||
clks[IMX8MQ_CLK_NAND] = imx8m_clk_composite("nand", imx8mq_nand_sels, base + 0xab00);
|
||||
clks[IMX8MQ_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
|
||||
clks[IMX8MQ_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
|
||||
clks[IMX8MQ_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
|
||||
clks[IMX8MQ_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
|
||||
clks[IMX8MQ_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
|
||||
clks[IMX8MQ_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
|
||||
clks[IMX8MQ_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
|
||||
clks[IMX8MQ_CLK_UART1] = imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
|
||||
clks[IMX8MQ_CLK_UART2] = imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
|
||||
clks[IMX8MQ_CLK_UART3] = imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
|
||||
clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
|
||||
clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
|
||||
clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
|
||||
clks[IMX8MQ_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mq_gic_sels, base + 0xb200);
|
||||
clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
|
||||
clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
|
||||
clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
|
||||
clks[IMX8MQ_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
|
||||
clks[IMX8MQ_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
|
||||
clks[IMX8MQ_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
|
||||
clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
|
||||
clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
|
||||
clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
|
||||
clks[IMX8MQ_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
|
||||
clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
|
||||
clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
|
||||
clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
|
||||
clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
|
||||
clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
|
||||
clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
|
||||
clks[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
|
||||
clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
|
||||
clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
|
||||
clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
|
||||
clks[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
|
||||
clks[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
|
||||
clks[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
|
||||
clks[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
|
||||
clks[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
|
||||
clks[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
|
||||
clks[IMX8MQ_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
|
||||
hws[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
hws[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
hws[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
hws[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
hws[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
hws[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
hws[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
hws[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
hws[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
hws[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||
hws[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
hws[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
hws[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
hws[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
hws[IMX8MQ_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
hws[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
hws[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
|
||||
hws[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_hw_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
|
||||
hws[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
hws[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
hws[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
hws[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
hws[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
hws[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
hws[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
|
||||
hws[IMX8MQ_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
|
||||
hws[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MQ_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
|
||||
hws[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MQ_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
|
||||
hws[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
|
||||
hws[IMX8MQ_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
|
||||
hws[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
hws[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
||||
hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
hws[IMX8MQ_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
hws[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
|
||||
hws[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_hw_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
|
||||
hws[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_hw_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
|
||||
hws[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_hw_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
|
||||
hws[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
hws[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
hws[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
hws[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
hws[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
hws[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_hw_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
hws[IMX8MQ_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
|
||||
hws[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_hw_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
hws[IMX8MQ_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
|
||||
hws[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
|
||||
hws[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
|
||||
hws[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
|
||||
hws[IMX8MQ_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
hws[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
hws[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
|
||||
hws[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_hw_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
|
||||
hws[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
hws[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
|
||||
clks[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
|
||||
clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
|
||||
clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
|
||||
clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||
clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||
clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||
clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||
clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||
clks[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||
clks[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
|
||||
clks[IMX8MQ_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
|
||||
clks[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
|
||||
clks[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
|
||||
clks[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
|
||||
clks[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
|
||||
clks[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
|
||||
clks[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
|
||||
clks[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
|
||||
clks[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
|
||||
clks[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
|
||||
clks[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MQ_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
|
||||
clks[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MQ_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
|
||||
clks[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MQ_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
|
||||
clks[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MQ_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
|
||||
clks[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||
clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||
clks[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
||||
clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||
clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||
clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||
clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
|
||||
clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
|
||||
clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
|
||||
clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
|
||||
clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
|
||||
clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
|
||||
clks[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
|
||||
clks[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
|
||||
clks[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
|
||||
clks[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
|
||||
clks[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
clks[IMX8MQ_CLK_GPU_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
|
||||
clks[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
clks[IMX8MQ_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MQ_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MQ_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
|
||||
clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
|
||||
clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
|
||||
clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
|
||||
clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
|
||||
clks[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
|
||||
clks[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
|
||||
hws[IMX8MQ_GPT_3M_CLK] = imx_clk_hw_fixed_factor("gpt_3m", "osc_25m", 1, 8);
|
||||
hws[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
|
||||
clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
|
||||
clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||
hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
|
||||
hws[IMX8MQ_CLK_A53_DIV]->clk,
|
||||
hws[IMX8MQ_CLK_A53_SRC]->clk,
|
||||
hws[IMX8MQ_ARM_PLL_OUT]->clk,
|
||||
hws[IMX8MQ_SYS1_PLL_800M]->clk);
|
||||
|
||||
clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
|
||||
clks[IMX8MQ_CLK_A53_DIV],
|
||||
clks[IMX8MQ_CLK_A53_SRC],
|
||||
clks[IMX8MQ_ARM_PLL_OUT],
|
||||
clks[IMX8MQ_SYS1_PLL_800M]);
|
||||
imx_check_clk_hws(hws, IMX8MQ_CLK_END);
|
||||
|
||||
imx_check_clocks(clks, ARRAY_SIZE(clks));
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
|
||||
err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
|
||||
if (err < 0) {
|
||||
dev_err(dev, "failed to register clks for i.MX8MQ\n");
|
||||
goto unregister_clks;
|
||||
dev_err(dev, "failed to register hws for i.MX8MQ\n");
|
||||
goto unregister_hws;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_clks);
|
||||
for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
|
||||
int index = uart_clk_ids[i];
|
||||
|
||||
uart_hws[i] = &hws[index]->clk;
|
||||
}
|
||||
|
||||
imx_register_uart_clocks(uart_hws);
|
||||
|
||||
return 0;
|
||||
|
||||
unregister_clks:
|
||||
imx_unregister_clocks(clks, ARRAY_SIZE(clks));
|
||||
unregister_hws:
|
||||
imx_unregister_hw_clocks(hws, IMX8MQ_CLK_END);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -609,6 +624,11 @@ static struct platform_driver imx8mq_clk_driver = {
|
||||
.probe = imx8mq_clocks_probe,
|
||||
.driver = {
|
||||
.name = "imx8mq-ccm",
|
||||
/*
|
||||
* Disable bind attributes: clocks are not removed and
|
||||
* reloading the driver will crash or break devices.
|
||||
*/
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = of_match_ptr(imx8mq_clk_of_match),
|
||||
},
|
||||
};
|
||||
|
@ -173,6 +173,17 @@ static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
|
||||
if (!ss_lpcg)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Please don't replace this with devm_platform_ioremap_resource.
|
||||
*
|
||||
* devm_platform_ioremap_resource calls devm_ioremap_resource which
|
||||
* differs from devm_ioremap by also calling devm_request_mem_region
|
||||
* and preventing other mappings in the same area.
|
||||
*
|
||||
* On imx8 the LPCG nodes map entire subsystems and overlap
|
||||
* peripherals, this means that using devm_platform_ioremap_resource
|
||||
* will cause many devices to fail to probe including serial ports.
|
||||
*/
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -EINVAL;
|
||||
|
@ -166,7 +166,7 @@ static const struct clk_ops clk_pfdv2_ops = {
|
||||
.is_enabled = clk_pfdv2_is_enabled,
|
||||
};
|
||||
|
||||
struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
|
@ -67,6 +67,13 @@ struct imx_pll14xx_clk imx_1443x_pll = {
|
||||
.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
|
||||
};
|
||||
|
||||
struct imx_pll14xx_clk imx_1443x_dram_pll = {
|
||||
.type = PLL_1443X,
|
||||
.rate_table = imx_pll1443x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
};
|
||||
|
||||
struct imx_pll14xx_clk imx_1416x_pll = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx_pll1416x_tbl,
|
||||
@ -369,13 +376,14 @@ static const struct clk_ops clk_pll1443x_ops = {
|
||||
.set_rate = clk_pll1443x_set_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base,
|
||||
const struct imx_pll14xx_clk *pll_clk)
|
||||
struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base,
|
||||
const struct imx_pll14xx_clk *pll_clk)
|
||||
{
|
||||
struct clk_pll14xx *pll;
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
@ -412,12 +420,15 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
val &= ~BYPASS_MASK;
|
||||
writel_relaxed(val, pll->base + GNRL_CTL);
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register pll %s %lu\n",
|
||||
__func__, name, PTR_ERR(clk));
|
||||
hw = &pll->hw;
|
||||
|
||||
ret = clk_hw_register(NULL, hw);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register pll %s %d\n",
|
||||
__func__, name, ret);
|
||||
kfree(pll);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
@ -111,12 +111,13 @@ static const struct clk_ops clk_pllv1_ops = {
|
||||
.recalc_rate = clk_pllv1_recalc_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
const char *parent, void __iomem *base)
|
||||
{
|
||||
struct clk_pllv1 *pll;
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
pll = kmalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll)
|
||||
@ -132,10 +133,13 @@ struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
init.num_parents = 1;
|
||||
|
||||
pll->hw.init = &init;
|
||||
hw = &pll->hw;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk))
|
||||
ret = clk_hw_register(NULL, hw);
|
||||
if (ret) {
|
||||
kfree(pll);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
@ -239,12 +239,13 @@ static const struct clk_ops clk_pllv2_ops = {
|
||||
.set_rate = clk_pllv2_set_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pllv2(const char *name, const char *parent,
|
||||
struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
|
||||
void __iomem *base)
|
||||
{
|
||||
struct clk_pllv2 *pll;
|
||||
struct clk *clk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
pll = kzalloc(sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll)
|
||||
@ -259,10 +260,13 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
|
||||
init.num_parents = 1;
|
||||
|
||||
pll->hw.init = &init;
|
||||
hw = &pll->hw;
|
||||
|
||||
clk = clk_register(NULL, &pll->hw);
|
||||
if (IS_ERR(clk))
|
||||
ret = clk_hw_register(NULL, hw);
|
||||
if (ret) {
|
||||
kfree(pll);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return clk;
|
||||
return hw;
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ static const struct clk_ops clk_pllv4_ops = {
|
||||
.is_enabled = clk_pllv4_is_enabled,
|
||||
};
|
||||
|
||||
struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
|
||||
void __iomem *base)
|
||||
{
|
||||
struct clk_pllv4 *pll;
|
||||
|
@ -67,7 +67,7 @@
|
||||
|
||||
#define PLL_SCCG_LOCK_TIMEOUT 70
|
||||
|
||||
struct clk_sccg_pll_setup {
|
||||
struct clk_sscg_pll_setup {
|
||||
int divr1, divf1;
|
||||
int divr2, divf2;
|
||||
int divq;
|
||||
@ -83,22 +83,22 @@ struct clk_sccg_pll_setup {
|
||||
int fout_error;
|
||||
};
|
||||
|
||||
struct clk_sccg_pll {
|
||||
struct clk_sscg_pll {
|
||||
struct clk_hw hw;
|
||||
const struct clk_ops ops;
|
||||
|
||||
void __iomem *base;
|
||||
|
||||
struct clk_sccg_pll_setup setup;
|
||||
struct clk_sscg_pll_setup setup;
|
||||
|
||||
u8 parent;
|
||||
u8 bypass1;
|
||||
u8 bypass2;
|
||||
};
|
||||
|
||||
#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
|
||||
#define to_clk_sscg_pll(_hw) container_of(_hw, struct clk_sscg_pll, hw)
|
||||
|
||||
static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
|
||||
static int clk_sscg_pll_wait_lock(struct clk_sscg_pll *pll)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@ -112,15 +112,15 @@ static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_pll2_check_match(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int new_diff = temp_setup->fout - temp_setup->fout_request;
|
||||
int diff = temp_setup->fout_error;
|
||||
|
||||
if (abs(diff) > abs(new_diff)) {
|
||||
temp_setup->fout_error = new_diff;
|
||||
memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
|
||||
memcpy(setup, temp_setup, sizeof(struct clk_sscg_pll_setup));
|
||||
|
||||
if (temp_setup->fout_request == temp_setup->fout)
|
||||
return 0;
|
||||
@ -128,8 +128,8 @@ static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_divq_lookup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
@ -144,7 +144,7 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
|
||||
temp_setup->fout = temp_setup->vco2;
|
||||
do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
|
||||
|
||||
ret = clk_sccg_pll2_check_match(setup, temp_setup);
|
||||
ret = clk_sscg_pll2_check_match(setup, temp_setup);
|
||||
if (!ret) {
|
||||
temp_setup->bypass = PLL_BYPASS1;
|
||||
return ret;
|
||||
@ -155,14 +155,14 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_divf2_lookup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
|
||||
temp_setup->divf2++) {
|
||||
ret = clk_sccg_divq_lookup(setup, temp_setup);
|
||||
ret = clk_sscg_divq_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
@ -170,8 +170,8 @@ static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_divr2_lookup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
@ -181,7 +181,7 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
|
||||
if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
|
||||
temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
|
||||
ret = clk_sccg_divf2_lookup(setup, temp_setup);
|
||||
ret = clk_sscg_divf2_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
@ -190,8 +190,8 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup,
|
||||
static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup,
|
||||
uint64_t ref)
|
||||
{
|
||||
|
||||
@ -202,12 +202,12 @@ static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
|
||||
temp_setup->vco1 = ref;
|
||||
|
||||
ret = clk_sccg_divr2_lookup(setup, temp_setup);
|
||||
ret = clk_sscg_divr2_lookup(setup, temp_setup);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_divf1_lookup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
@ -219,7 +219,7 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
vco1 *= 2;
|
||||
vco1 *= temp_setup->divf1 + 1;
|
||||
|
||||
ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
|
||||
ret = clk_sscg_pll2_find_setup(setup, temp_setup, vco1);
|
||||
if (!ret) {
|
||||
temp_setup->bypass = PLL_BYPASS_NONE;
|
||||
return ret;
|
||||
@ -229,8 +229,8 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup)
|
||||
static int clk_sscg_divr1_lookup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
||||
@ -240,7 +240,7 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
|
||||
if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
|
||||
temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
|
||||
ret = clk_sccg_divf1_lookup(setup, temp_setup);
|
||||
ret = clk_sscg_divf1_lookup(setup, temp_setup);
|
||||
if (!ret)
|
||||
return ret;
|
||||
}
|
||||
@ -249,8 +249,8 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
struct clk_sccg_pll_setup *temp_setup,
|
||||
static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup,
|
||||
struct clk_sscg_pll_setup *temp_setup,
|
||||
uint64_t ref)
|
||||
{
|
||||
|
||||
@ -261,20 +261,20 @@ static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
|
||||
temp_setup->ref = ref;
|
||||
|
||||
ret = clk_sccg_divr1_lookup(setup, temp_setup);
|
||||
ret = clk_sscg_divr1_lookup(setup, temp_setup);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
|
||||
uint64_t prate,
|
||||
uint64_t rate, int try_bypass)
|
||||
{
|
||||
struct clk_sccg_pll_setup temp_setup;
|
||||
struct clk_sscg_pll_setup temp_setup;
|
||||
int ret = -EINVAL;
|
||||
|
||||
memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
|
||||
memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
|
||||
memset(&temp_setup, 0, sizeof(struct clk_sscg_pll_setup));
|
||||
memset(setup, 0, sizeof(struct clk_sscg_pll_setup));
|
||||
|
||||
temp_setup.fout_error = PLL_OUT_MAX_FREQ;
|
||||
temp_setup.fout_request = rate;
|
||||
@ -290,11 +290,11 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
break;
|
||||
|
||||
case PLL_BYPASS1:
|
||||
ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
|
||||
ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
|
||||
break;
|
||||
|
||||
case PLL_BYPASS_NONE:
|
||||
ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
|
||||
ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -302,30 +302,30 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
|
||||
}
|
||||
|
||||
|
||||
static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
|
||||
static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
|
||||
u32 val = readl_relaxed(pll->base + PLL_CFG0);
|
||||
|
||||
return (val & PLL_PD_MASK) ? 0 : 1;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_prepare(struct clk_hw *hw)
|
||||
static int clk_sscg_pll_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(pll->base + PLL_CFG0);
|
||||
val &= ~PLL_PD_MASK;
|
||||
writel_relaxed(val, pll->base + PLL_CFG0);
|
||||
|
||||
return clk_sccg_pll_wait_lock(pll);
|
||||
return clk_sscg_pll_wait_lock(pll);
|
||||
}
|
||||
|
||||
static void clk_sccg_pll_unprepare(struct clk_hw *hw)
|
||||
static void clk_sscg_pll_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl_relaxed(pll->base + PLL_CFG0);
|
||||
@ -333,10 +333,10 @@ static void clk_sccg_pll_unprepare(struct clk_hw *hw)
|
||||
writel_relaxed(val, pll->base + PLL_CFG0);
|
||||
}
|
||||
|
||||
static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
|
||||
static unsigned long clk_sscg_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
u32 val, divr1, divf1, divr2, divf2, divq;
|
||||
u64 temp64;
|
||||
|
||||
@ -364,11 +364,11 @@ static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
|
||||
return temp64;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
static int clk_sscg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
struct clk_sscg_pll_setup *setup = &pll->setup;
|
||||
u32 val;
|
||||
|
||||
/* set bypass here too since the parent might be the same */
|
||||
@ -387,12 +387,12 @@ static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
|
||||
writel_relaxed(val, pll->base + PLL_CFG2);
|
||||
|
||||
return clk_sccg_pll_wait_lock(pll);
|
||||
return clk_sscg_pll_wait_lock(pll);
|
||||
}
|
||||
|
||||
static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
|
||||
static u8 clk_sscg_pll_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
u32 val;
|
||||
u8 ret = pll->parent;
|
||||
|
||||
@ -404,9 +404,9 @@ static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
|
||||
static int clk_sscg_pll_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
u32 val;
|
||||
|
||||
val = readl(pll->base + PLL_CFG0);
|
||||
@ -414,18 +414,18 @@ static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
|
||||
val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
|
||||
writel(val, pll->base + PLL_CFG0);
|
||||
|
||||
return clk_sccg_pll_wait_lock(pll);
|
||||
return clk_sscg_pll_wait_lock(pll);
|
||||
}
|
||||
|
||||
static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
static int __clk_sscg_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req,
|
||||
uint64_t min,
|
||||
uint64_t max,
|
||||
uint64_t rate,
|
||||
int bypass)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
struct clk_sscg_pll_setup *setup = &pll->setup;
|
||||
struct clk_hw *parent_hw = NULL;
|
||||
int bypass_parent_index;
|
||||
int ret = -EINVAL;
|
||||
@ -448,7 +448,7 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
|
||||
ret = __clk_determine_rate(parent_hw, req);
|
||||
if (!ret) {
|
||||
ret = clk_sccg_pll_find_setup(setup, req->rate,
|
||||
ret = clk_sscg_pll_find_setup(setup, req->rate,
|
||||
rate, bypass);
|
||||
}
|
||||
|
||||
@ -459,11 +459,11 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
static int clk_sscg_pll_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
|
||||
struct clk_sccg_pll_setup *setup = &pll->setup;
|
||||
struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
|
||||
struct clk_sscg_pll_setup *setup = &pll->setup;
|
||||
uint64_t rate = req->rate;
|
||||
uint64_t min = req->min_rate;
|
||||
uint64_t max = req->max_rate;
|
||||
@ -472,18 +472,18 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
|
||||
ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate,
|
||||
rate, PLL_BYPASS2);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
|
||||
ret = __clk_sscg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
|
||||
PLL_STAGE1_REF_MAX_FREQ, rate,
|
||||
PLL_BYPASS1);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
|
||||
ret = __clk_sscg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
|
||||
PLL_REF_MAX_FREQ, rate,
|
||||
PLL_BYPASS_NONE);
|
||||
if (!ret)
|
||||
@ -495,25 +495,25 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_sccg_pll_ops = {
|
||||
.prepare = clk_sccg_pll_prepare,
|
||||
.unprepare = clk_sccg_pll_unprepare,
|
||||
.is_prepared = clk_sccg_pll_is_prepared,
|
||||
.recalc_rate = clk_sccg_pll_recalc_rate,
|
||||
.set_rate = clk_sccg_pll_set_rate,
|
||||
.set_parent = clk_sccg_pll_set_parent,
|
||||
.get_parent = clk_sccg_pll_get_parent,
|
||||
.determine_rate = clk_sccg_pll_determine_rate,
|
||||
static const struct clk_ops clk_sscg_pll_ops = {
|
||||
.prepare = clk_sscg_pll_prepare,
|
||||
.unprepare = clk_sscg_pll_unprepare,
|
||||
.is_prepared = clk_sscg_pll_is_prepared,
|
||||
.recalc_rate = clk_sscg_pll_recalc_rate,
|
||||
.set_rate = clk_sscg_pll_set_rate,
|
||||
.set_parent = clk_sscg_pll_set_parent,
|
||||
.get_parent = clk_sscg_pll_get_parent,
|
||||
.determine_rate = clk_sscg_pll_determine_rate,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_sccg_pll(const char *name,
|
||||
struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
|
||||
const char * const *parent_names,
|
||||
u8 num_parents,
|
||||
u8 parent, u8 bypass1, u8 bypass2,
|
||||
void __iomem *base,
|
||||
unsigned long flags)
|
||||
{
|
||||
struct clk_sccg_pll *pll;
|
||||
struct clk_sscg_pll *pll;
|
||||
struct clk_init_data init;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
@ -528,7 +528,7 @@ struct clk *imx_clk_sccg_pll(const char *name,
|
||||
|
||||
pll->base = base;
|
||||
init.name = name;
|
||||
init.ops = &clk_sccg_pll_ops;
|
||||
init.ops = &clk_sscg_pll_ops;
|
||||
|
||||
init.flags = flags;
|
||||
init.parent_names = parent_names;
|
||||
@ -545,5 +545,5 @@ struct clk *imx_clk_sccg_pll(const char *name,
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return hw->clk;
|
||||
return hw;
|
||||
}
|
@ -22,6 +22,14 @@ void imx_unregister_clocks(struct clk *clks[], unsigned int count)
|
||||
clk_unregister(clks[i]);
|
||||
}
|
||||
|
||||
void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
clk_hw_unregister(hws[i]);
|
||||
}
|
||||
|
||||
void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
|
||||
unsigned int chn)
|
||||
{
|
||||
@ -94,8 +102,8 @@ struct clk_hw * __init imx_obtain_fixed_clock_hw(
|
||||
return __clk_get_hw(clk);
|
||||
}
|
||||
|
||||
struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np,
|
||||
const char *name)
|
||||
struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np,
|
||||
const char *name)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
|
@ -12,6 +12,7 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
|
||||
void imx_register_uart_clocks(struct clk ** const clks[]);
|
||||
void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
|
||||
void imx_unregister_clocks(struct clk *clks[], unsigned int count);
|
||||
void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
|
||||
|
||||
extern void imx_cscmr1_fixup(u32 *val);
|
||||
|
||||
@ -24,7 +25,7 @@ enum imx_pllv1_type {
|
||||
IMX_PLLV1_IMX35,
|
||||
};
|
||||
|
||||
enum imx_sccg_pll_type {
|
||||
enum imx_sscg_pll_type {
|
||||
SCCG_PLL1,
|
||||
SCCG_PLL2,
|
||||
};
|
||||
@ -52,64 +53,98 @@ struct imx_pll14xx_clk {
|
||||
|
||||
extern struct imx_pll14xx_clk imx_1416x_pll;
|
||||
extern struct imx_pll14xx_clk imx_1443x_pll;
|
||||
extern struct imx_pll14xx_clk imx_1443x_dram_pll;
|
||||
|
||||
#define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
|
||||
imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
|
||||
to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
|
||||
|
||||
#define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
|
||||
cgr_val, clk_gate_flags, lock, share_count) \
|
||||
clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
|
||||
cgr_val, clk_gate_flags, lock, share_count)->clk
|
||||
to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
|
||||
cgr_val, clk_gate_flags, lock, share_count))
|
||||
|
||||
#define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
|
||||
imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk
|
||||
to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
|
||||
|
||||
#define imx_clk_pfd(name, parent_name, reg, idx) \
|
||||
imx_clk_hw_pfd(name, parent_name, reg, idx)->clk
|
||||
to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
|
||||
|
||||
#define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
|
||||
imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
|
||||
to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
|
||||
|
||||
#define imx_clk_fixed(name, rate) \
|
||||
to_clk(imx_clk_hw_fixed(name, rate))
|
||||
|
||||
#define imx_clk_fixed_factor(name, parent, mult, div) \
|
||||
imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
|
||||
to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
|
||||
|
||||
#define imx_clk_divider(name, parent, reg, shift, width) \
|
||||
to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
|
||||
|
||||
#define imx_clk_divider2(name, parent, reg, shift, width) \
|
||||
imx_clk_hw_divider2(name, parent, reg, shift, width)->clk
|
||||
to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
|
||||
|
||||
#define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \
|
||||
to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags))
|
||||
|
||||
#define imx_clk_gate(name, parent, reg, shift) \
|
||||
to_clk(imx_clk_hw_gate(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate_dis(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
|
||||
to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate2(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate2(name, parent, reg, shift)->clk
|
||||
to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
|
||||
imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
|
||||
to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
|
||||
|
||||
#define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
|
||||
imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
|
||||
to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count))
|
||||
|
||||
#define imx_clk_gate3(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate3(name, parent, reg, shift)->clk
|
||||
to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_gate4(name, parent, reg, shift) \
|
||||
imx_clk_hw_gate4(name, parent, reg, shift)->clk
|
||||
to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
|
||||
|
||||
#define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
|
||||
imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk
|
||||
to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
|
||||
|
||||
#define imx_clk_pllv1(type, name, parent, base) \
|
||||
to_clk(imx_clk_hw_pllv1(type, name, parent, base))
|
||||
|
||||
#define imx_clk_pllv2(name, parent, base) \
|
||||
to_clk(imx_clk_hw_pllv2(name, parent, base))
|
||||
|
||||
#define imx_clk_frac_pll(name, parent_name, base) \
|
||||
to_clk(imx_clk_hw_frac_pll(name, parent_name, base))
|
||||
|
||||
#define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\
|
||||
bypass1, bypass2, base, flags) \
|
||||
to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\
|
||||
bypass1, bypass2, base, flags))
|
||||
|
||||
struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
|
||||
|
||||
struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
|
||||
to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
|
||||
|
||||
struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
|
||||
void __iomem *base,
|
||||
const struct imx_pll14xx_clk *pll_clk);
|
||||
|
||||
struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
|
||||
const char *parent, void __iomem *base);
|
||||
|
||||
struct clk *imx_clk_pllv2(const char *name, const char *parent,
|
||||
struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
|
||||
void __iomem *base);
|
||||
|
||||
struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name,
|
||||
void __iomem *base);
|
||||
|
||||
struct clk *imx_clk_sccg_pll(const char *name,
|
||||
struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
|
||||
const char * const *parent_names,
|
||||
u8 num_parents,
|
||||
u8 parent, u8 bypass1, u8 bypass2,
|
||||
@ -149,7 +184,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
.kdiv = (_k), \
|
||||
}
|
||||
|
||||
struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
|
||||
void __iomem *base);
|
||||
|
||||
struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
|
||||
@ -173,7 +208,7 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
|
||||
struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx);
|
||||
|
||||
struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
|
||||
void __iomem *reg, u8 idx);
|
||||
|
||||
struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
|
||||
@ -184,7 +219,7 @@ struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift
|
||||
u8 width, void __iomem *busy_reg, u8 busy_shift,
|
||||
const char * const *parent_names, int num_parents);
|
||||
|
||||
struct clk_hw *imx7ulp_clk_composite(const char *name,
|
||||
struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents, bool mux_present,
|
||||
bool rate_present, bool gate_present,
|
||||
@ -198,9 +233,11 @@ struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char * const *parents,
|
||||
int num_parents, void (*fixup)(u32 *val));
|
||||
|
||||
static inline struct clk *imx_clk_fixed(const char *name, int rate)
|
||||
static inline struct clk *to_clk(struct clk_hw *hw)
|
||||
{
|
||||
return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
|
||||
if (IS_ERR_OR_NULL(hw))
|
||||
return ERR_CAST(hw);
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
|
||||
@ -224,13 +261,6 @@ static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
|
||||
CLK_SET_RATE_PARENT, mult, div);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width)
|
||||
{
|
||||
return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_divider(const char *name,
|
||||
const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
@ -240,14 +270,6 @@ static inline struct clk_hw *imx_clk_hw_divider(const char *name,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_divider_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift, u8 width,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_divider(NULL, name, parent, flags,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
|
||||
const char *parent,
|
||||
void __iomem *reg, u8 shift,
|
||||
@ -274,13 +296,6 @@ static inline struct clk *imx_clk_divider2_flags(const char *name,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
|
||||
shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, unsigned long flags)
|
||||
{
|
||||
@ -355,15 +370,18 @@ static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *pare
|
||||
reg, shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate3_flags(const char *name,
|
||||
static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_gate(NULL, name, parent,
|
||||
return clk_hw_register_gate(NULL, name, parent,
|
||||
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
#define imx_clk_gate3_flags(name, parent, reg, shift, flags) \
|
||||
to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags))
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
@ -372,15 +390,18 @@ static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *pare
|
||||
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_gate4_flags(const char *name,
|
||||
static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name,
|
||||
const char *parent, void __iomem *reg, u8 shift,
|
||||
unsigned long flags)
|
||||
{
|
||||
return clk_register_gate2(NULL, name, parent,
|
||||
return clk_hw_register_gate2(NULL, name, parent,
|
||||
flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
|
||||
}
|
||||
|
||||
#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
|
||||
to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags))
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
|
||||
u8 shift, u8 width, const char * const *parents,
|
||||
int num_parents)
|
||||
@ -420,6 +441,16 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
|
||||
&imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
int num_parents, unsigned long flags)
|
||||
{
|
||||
return clk_hw_register_mux(NULL, name, parents, num_parents,
|
||||
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
|
||||
reg, shift, width, 0, &imx_ccm_lock);
|
||||
}
|
||||
|
||||
static inline struct clk *imx_clk_mux2_flags(const char *name,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
const char * const *parents,
|
||||
@ -446,23 +477,38 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
|
||||
struct clk *div, struct clk *mux, struct clk *pll,
|
||||
struct clk *step);
|
||||
|
||||
struct clk *imx8m_clk_composite_flags(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents, void __iomem *reg,
|
||||
unsigned long flags);
|
||||
struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
|
||||
const char * const *parent_names,
|
||||
int num_parents,
|
||||
void __iomem *reg,
|
||||
unsigned long flags);
|
||||
|
||||
#define __imx8m_clk_composite(name, parent_names, reg, flags) \
|
||||
imx8m_clk_composite_flags(name, parent_names, \
|
||||
#define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
|
||||
flags) \
|
||||
to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
num_parents, reg, flags))
|
||||
|
||||
#define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \
|
||||
imx8m_clk_hw_composite_flags(name, parent_names, \
|
||||
ARRAY_SIZE(parent_names), reg, \
|
||||
flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
|
||||
|
||||
#define __imx8m_clk_composite(name, parent_names, reg, flags) \
|
||||
to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
|
||||
|
||||
#define imx8m_clk_hw_composite(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_composite(name, parent_names, reg, 0)
|
||||
|
||||
#define imx8m_clk_composite(name, parent_names, reg) \
|
||||
__imx8m_clk_composite(name, parent_names, reg, 0)
|
||||
|
||||
#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
|
||||
__imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL)
|
||||
|
||||
#define imx8m_clk_composite_critical(name, parent_names, reg) \
|
||||
__imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
|
||||
|
||||
struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
|
||||
struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
|
||||
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
|
||||
u8 clk_divider_flags, const struct clk_div_table *table,
|
||||
spinlock_t *lock);
|
||||
|
@ -174,36 +174,36 @@ config COMMON_CLK_MT6779_AUDSYS
|
||||
This driver supports Mediatek MT6779 audsys clocks.
|
||||
|
||||
config COMMON_CLK_MT6797
|
||||
bool "Clock driver for MediaTek MT6797"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK && ARM64
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 basic clocks.
|
||||
bool "Clock driver for MediaTek MT6797"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK && ARM64
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 basic clocks.
|
||||
|
||||
config COMMON_CLK_MT6797_MMSYS
|
||||
bool "Clock driver for MediaTek MT6797 mmsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 mmsys clocks.
|
||||
bool "Clock driver for MediaTek MT6797 mmsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 mmsys clocks.
|
||||
|
||||
config COMMON_CLK_MT6797_IMGSYS
|
||||
bool "Clock driver for MediaTek MT6797 imgsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 imgsys clocks.
|
||||
bool "Clock driver for MediaTek MT6797 imgsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 imgsys clocks.
|
||||
|
||||
config COMMON_CLK_MT6797_VDECSYS
|
||||
bool "Clock driver for MediaTek MT6797 vdecsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 vdecsys clocks.
|
||||
bool "Clock driver for MediaTek MT6797 vdecsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 vdecsys clocks.
|
||||
|
||||
config COMMON_CLK_MT6797_VENCSYS
|
||||
bool "Clock driver for MediaTek MT6797 vencsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 vencsys clocks.
|
||||
bool "Clock driver for MediaTek MT6797 vencsys"
|
||||
depends on COMMON_CLK_MT6797
|
||||
---help---
|
||||
This driver supports MediaTek MT6797 vencsys clocks.
|
||||
|
||||
config COMMON_CLK_MT7622
|
||||
bool "Clock driver for MediaTek MT7622"
|
||||
|
@ -18,4 +18,4 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
|
||||
obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
|
||||
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
|
||||
obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
|
||||
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
|
||||
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
|
||||
|
@ -129,7 +129,7 @@ static int mpll_set_rate(struct clk_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mpll_init(struct clk_hw *hw)
|
||||
static int mpll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
|
||||
@ -151,6 +151,8 @@ static void mpll_init(struct clk_hw *hw)
|
||||
/* Set the magic misc bit if required */
|
||||
if (MESON_PARM_APPLICABLE(&mpll->misc))
|
||||
meson_parm_write(clk->map, &mpll->misc, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_clk_mpll_ro_ops = {
|
||||
|
@ -78,7 +78,7 @@ meson_clk_triphase_data(struct clk_regmap *clk)
|
||||
return (struct meson_clk_triphase_data *)clk->data;
|
||||
}
|
||||
|
||||
static void meson_clk_triphase_sync(struct clk_hw *hw)
|
||||
static int meson_clk_triphase_sync(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
|
||||
@ -88,6 +88,8 @@ static void meson_clk_triphase_sync(struct clk_hw *hw)
|
||||
val = meson_parm_read(clk->map, &tph->ph0);
|
||||
meson_parm_write(clk->map, &tph->ph1, val);
|
||||
meson_parm_write(clk->map, &tph->ph2, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_triphase_get_phase(struct clk_hw *hw)
|
||||
|
@ -77,6 +77,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned int m, n, frac;
|
||||
|
||||
n = meson_parm_read(clk->map, &pll->n);
|
||||
|
||||
/*
|
||||
* On some HW, N is set to zero on init. This value is invalid as
|
||||
* it would result in a division by zero. The rate can't be
|
||||
* calculated in this case
|
||||
*/
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
m = meson_parm_read(clk->map, &pll->m);
|
||||
|
||||
frac = MESON_PARM_APPLICABLE(&pll->frac) ?
|
||||
@ -277,7 +286,7 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void meson_clk_pll_init(struct clk_hw *hw)
|
||||
static int meson_clk_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
@ -288,6 +297,8 @@ static void meson_clk_pll_init(struct clk_hw *hw)
|
||||
pll->init_count);
|
||||
meson_parm_write(clk->map, &pll->rst, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_clk_pll_is_enabled(struct clk_hw *hw)
|
||||
|
@ -4692,6 +4692,7 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
|
||||
&g12a_bt656,
|
||||
&g12a_usb1_to_ddr,
|
||||
&g12a_mmc_pclk,
|
||||
&g12a_uart2,
|
||||
&g12a_vpu_intr,
|
||||
&g12a_gic,
|
||||
&g12a_sd_emmc_a_clk0,
|
||||
|
149
drivers/clk/meson/meson8-ddr.c
Normal file
149
drivers/clk/meson/meson8-ddr.c
Normal file
@ -0,0 +1,149 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Amlogic Meson8 DDR clock controller
|
||||
*
|
||||
* Copyright (C) 2019 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/meson8-ddr-clkc.h>
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define AM_DDR_PLL_CNTL 0x00
|
||||
#define AM_DDR_PLL_CNTL1 0x04
|
||||
#define AM_DDR_PLL_CNTL2 0x08
|
||||
#define AM_DDR_PLL_CNTL3 0x0c
|
||||
#define AM_DDR_PLL_CNTL4 0x10
|
||||
#define AM_DDR_PLL_STS 0x14
|
||||
#define DDR_CLK_CNTL 0x18
|
||||
#define DDR_CLK_STS 0x1c
|
||||
|
||||
static struct clk_regmap meson8_ddr_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
.reg_off = AM_DDR_PLL_CNTL,
|
||||
.shift = 30,
|
||||
.width = 1,
|
||||
},
|
||||
.m = {
|
||||
.reg_off = AM_DDR_PLL_CNTL,
|
||||
.shift = 0,
|
||||
.width = 9,
|
||||
},
|
||||
.n = {
|
||||
.reg_off = AM_DDR_PLL_CNTL,
|
||||
.shift = 9,
|
||||
.width = 5,
|
||||
},
|
||||
.l = {
|
||||
.reg_off = AM_DDR_PLL_CNTL,
|
||||
.shift = 31,
|
||||
.width = 1,
|
||||
},
|
||||
.rst = {
|
||||
.reg_off = AM_DDR_PLL_CNTL,
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ddr_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8_ddr_pll = {
|
||||
.data = &(struct clk_regmap_div_data){
|
||||
.offset = AM_DDR_PLL_CNTL,
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
.flags = CLK_DIVIDER_POWER_OF_TWO,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ddr_pll",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8_ddr_pll_dco.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_hw_onecell_data meson8_ddr_clk_hw_onecell_data = {
|
||||
.hws = {
|
||||
[DDR_CLKID_DDR_PLL_DCO] = &meson8_ddr_pll_dco.hw,
|
||||
[DDR_CLKID_DDR_PLL] = &meson8_ddr_pll.hw,
|
||||
},
|
||||
.num = 2,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const meson8_ddr_clk_regmaps[] = {
|
||||
&meson8_ddr_pll_dco,
|
||||
&meson8_ddr_pll,
|
||||
};
|
||||
|
||||
static const struct regmap_config meson8_ddr_clkc_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = DDR_CLK_STS,
|
||||
};
|
||||
|
||||
static int meson8_ddr_clkc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
struct clk_hw *hw;
|
||||
int ret, i;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
regmap = devm_regmap_init_mmio(&pdev->dev, base,
|
||||
&meson8_ddr_clkc_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* Populate regmap */
|
||||
for (i = 0; i < ARRAY_SIZE(meson8_ddr_clk_regmaps); i++)
|
||||
meson8_ddr_clk_regmaps[i]->map = regmap;
|
||||
|
||||
/* Register all clks */
|
||||
for (i = 0; i < meson8_ddr_clk_hw_onecell_data.num; i++) {
|
||||
hw = meson8_ddr_clk_hw_onecell_data.hws[i];
|
||||
|
||||
ret = devm_clk_hw_register(&pdev->dev, hw);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Clock registration failed\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
|
||||
&meson8_ddr_clk_hw_onecell_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id meson8_ddr_clkc_match_table[] = {
|
||||
{ .compatible = "amlogic,meson8-ddr-clkc" },
|
||||
{ .compatible = "amlogic,meson8b-ddr-clkc" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver meson8_ddr_clkc_driver = {
|
||||
.probe = meson8_ddr_clkc_probe,
|
||||
.driver = {
|
||||
.name = "meson8-ddr-clkc",
|
||||
.of_match_table = meson8_ddr_clkc_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
builtin_platform_driver(meson8_ddr_clkc_driver);
|
@ -97,8 +97,10 @@ static struct clk_regmap meson8b_fixed_pll_dco = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
@ -162,8 +164,10 @@ static struct clk_regmap meson8b_hdmi_pll_dco = {
|
||||
/* sometimes also called "HPLL" or "HPLL PLL" */
|
||||
.name = "hdmi_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
@ -237,8 +241,10 @@ static struct clk_regmap meson8b_sys_pll_dco = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
@ -631,9 +637,9 @@ static struct clk_regmap meson8b_cpu_in_sel = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_in_sel",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw,
|
||||
&meson8b_sys_pll.hw,
|
||||
.parent_data = (const struct clk_parent_data[]) {
|
||||
{ .fw_name = "xtal", .name = "xtal", .index = -1, },
|
||||
{ .hw = &meson8b_sys_pll.hw, },
|
||||
},
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_SET_RATE_PARENT |
|
||||
@ -736,9 +742,9 @@ static struct clk_regmap meson8b_cpu_clk = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cpu_clk",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw,
|
||||
&meson8b_cpu_scale_out_sel.hw,
|
||||
.parent_data = (const struct clk_parent_data[]) {
|
||||
{ .fw_name = "xtal", .name = "xtal", .index = -1, },
|
||||
{ .hw = &meson8b_cpu_scale_out_sel.hw, },
|
||||
},
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_SET_RATE_PARENT |
|
||||
@ -758,12 +764,12 @@ static struct clk_regmap meson8b_nand_clk_sel = {
|
||||
.name = "nand_clk_sel",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
/* FIXME all other parents are unknown: */
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_fclk_div4.hw,
|
||||
&meson8b_fclk_div3.hw,
|
||||
&meson8b_fclk_div5.hw,
|
||||
&meson8b_fclk_div7.hw,
|
||||
&meson8b_xtal.hw,
|
||||
.parent_data = (const struct clk_parent_data[]) {
|
||||
{ .hw = &meson8b_fclk_div4.hw, },
|
||||
{ .hw = &meson8b_fclk_div3.hw, },
|
||||
{ .hw = &meson8b_fclk_div5.hw, },
|
||||
{ .hw = &meson8b_fclk_div7.hw, },
|
||||
{ .fw_name = "xtal", .name = "xtal", .index = -1, },
|
||||
},
|
||||
.num_parents = 5,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1721,8 +1727,10 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
|
||||
.name = "hdmi_sys_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
/* FIXME: all other parents are unknown */
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_NO_REPARENT,
|
||||
@ -1764,17 +1772,20 @@ static struct clk_regmap meson8b_hdmi_sys = {
|
||||
|
||||
/*
|
||||
* The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
|
||||
* muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
|
||||
* has mali_0 and no glitch-free mux.
|
||||
* muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
|
||||
* actually manage this glitch-free mux because it does top-to-bottom
|
||||
* updates the each clock tree and switches to the "inactive" one when
|
||||
* CLK_SET_RATE_GATE is set.
|
||||
* Meson8 only has mali_0 and no glitch-free mux.
|
||||
*/
|
||||
static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = {
|
||||
&meson8b_xtal.hw,
|
||||
&meson8b_mpll2.hw,
|
||||
&meson8b_mpll1.hw,
|
||||
&meson8b_fclk_div7.hw,
|
||||
&meson8b_fclk_div4.hw,
|
||||
&meson8b_fclk_div3.hw,
|
||||
&meson8b_fclk_div5.hw,
|
||||
static const struct clk_parent_data meson8b_mali_0_1_parent_data[] = {
|
||||
{ .fw_name = "xtal", .name = "xtal", .index = -1, },
|
||||
{ .hw = &meson8b_mpll2.hw, },
|
||||
{ .hw = &meson8b_mpll1.hw, },
|
||||
{ .hw = &meson8b_fclk_div7.hw, },
|
||||
{ .hw = &meson8b_fclk_div4.hw, },
|
||||
{ .hw = &meson8b_fclk_div3.hw, },
|
||||
{ .hw = &meson8b_fclk_div5.hw, },
|
||||
};
|
||||
|
||||
static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
|
||||
@ -1789,8 +1800,8 @@ static struct clk_regmap meson8b_mali_0_sel = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mali_0_sel",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_mali_0_1_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
|
||||
.parent_data = meson8b_mali_0_1_parent_data,
|
||||
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data),
|
||||
/*
|
||||
* Don't propagate rate changes up because the only changeable
|
||||
* parents are mpll1 and mpll2 but we need those for audio and
|
||||
@ -1830,7 +1841,7 @@ static struct clk_regmap meson8b_mali_0 = {
|
||||
&meson8b_mali_0_div.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1844,8 +1855,8 @@ static struct clk_regmap meson8b_mali_1_sel = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mali_1_sel",
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_mali_0_1_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
|
||||
.parent_data = meson8b_mali_0_1_parent_data,
|
||||
.num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data),
|
||||
/*
|
||||
* Don't propagate rate changes up because the only changeable
|
||||
* parents are mpll1 and mpll2 but we need those for audio and
|
||||
@ -1885,7 +1896,7 @@ static struct clk_regmap meson8b_mali_1 = {
|
||||
&meson8b_mali_1_div.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1944,8 +1955,10 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp_pll_dco",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_xtal.hw
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
@ -3585,7 +3598,7 @@ static const struct reset_control_ops meson8b_clk_reset_ops = {
|
||||
|
||||
struct meson8b_nb_data {
|
||||
struct notifier_block nb;
|
||||
struct clk_hw_onecell_data *onecell_data;
|
||||
struct clk_hw *cpu_clk;
|
||||
};
|
||||
|
||||
static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
|
||||
@ -3593,30 +3606,25 @@ static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
|
||||
{
|
||||
struct meson8b_nb_data *nb_data =
|
||||
container_of(nb, struct meson8b_nb_data, nb);
|
||||
struct clk_hw **hws = nb_data->onecell_data->hws;
|
||||
struct clk_hw *cpu_clk_hw, *parent_clk_hw;
|
||||
struct clk *cpu_clk, *parent_clk;
|
||||
struct clk_hw *parent_clk;
|
||||
int ret;
|
||||
|
||||
switch (event) {
|
||||
case PRE_RATE_CHANGE:
|
||||
parent_clk_hw = hws[CLKID_XTAL];
|
||||
/* xtal */
|
||||
parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 0);
|
||||
break;
|
||||
|
||||
case POST_RATE_CHANGE:
|
||||
parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL];
|
||||
/* cpu_scale_out_sel */
|
||||
parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
cpu_clk_hw = hws[CLKID_CPUCLK];
|
||||
cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw));
|
||||
|
||||
parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw));
|
||||
|
||||
ret = clk_set_parent(cpu_clk, parent_clk);
|
||||
ret = clk_hw_set_parent(nb_data->cpu_clk, parent_clk);
|
||||
if (ret)
|
||||
return notifier_from_errno(ret);
|
||||
|
||||
@ -3682,20 +3690,26 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
|
||||
meson8b_clk_regmaps[i]->map = map;
|
||||
|
||||
/*
|
||||
* register all clks
|
||||
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
|
||||
* always skip CLKID_UNUSED and also skip XTAL if the .dtb provides the
|
||||
* XTAL clock as input.
|
||||
*/
|
||||
for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
|
||||
if (!IS_ERR(of_clk_get_by_name(np, "xtal")))
|
||||
i = CLKID_PLL_FIXED;
|
||||
else
|
||||
i = CLKID_XTAL;
|
||||
|
||||
/* register all clks */
|
||||
for (; i < CLK_NR_CLKS; i++) {
|
||||
/* array might be sparse */
|
||||
if (!clk_hw_onecell_data->hws[i])
|
||||
continue;
|
||||
|
||||
ret = clk_hw_register(NULL, clk_hw_onecell_data->hws[i]);
|
||||
ret = of_clk_hw_register(np, clk_hw_onecell_data->hws[i]);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
meson8b_cpu_nb_data.onecell_data = clk_hw_onecell_data;
|
||||
meson8b_cpu_nb_data.cpu_clk = clk_hw_onecell_data->hws[CLKID_CPUCLK];
|
||||
|
||||
/*
|
||||
* FIXME we shouldn't program the muxes in notifier handlers. The
|
||||
|
@ -216,7 +216,7 @@ static int sclk_div_is_enabled(struct clk_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sclk_div_init(struct clk_hw *hw)
|
||||
static int sclk_div_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
|
||||
@ -231,6 +231,8 @@ static void sclk_div_init(struct clk_hw *hw)
|
||||
sclk->cached_div = val + 1;
|
||||
|
||||
sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_sclk_div_ops = {
|
||||
|
@ -266,10 +266,12 @@ static void roclk_disable(struct clk_hw *hw)
|
||||
writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg));
|
||||
}
|
||||
|
||||
static void roclk_init(struct clk_hw *hw)
|
||||
static int roclk_init(struct clk_hw *hw)
|
||||
{
|
||||
/* initialize clock in disabled state */
|
||||
roclk_disable(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 roclk_get_parent(struct clk_hw *hw)
|
||||
@ -880,7 +882,7 @@ static int sclk_set_parent(struct clk_hw *hw, u8 index)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void sclk_init(struct clk_hw *hw)
|
||||
static int sclk_init(struct clk_hw *hw)
|
||||
{
|
||||
struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw);
|
||||
unsigned long flags;
|
||||
@ -899,6 +901,8 @@ static void sclk_init(struct clk_hw *hw)
|
||||
writel(v, sclk->slew_reg);
|
||||
spin_unlock_irqrestore(&sclk->core->reg_lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sclk with post-divider */
|
||||
|
@ -109,7 +109,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_factor_init(struct clk_hw *hw)
|
||||
static int clk_factor_init(struct clk_hw *hw)
|
||||
{
|
||||
struct mmp_clk_factor *factor = to_clk_factor(hw);
|
||||
struct mmp_clk_factor_masks *masks = factor->masks;
|
||||
@ -146,6 +146,8 @@ static void clk_factor_init(struct clk_hw *hw)
|
||||
|
||||
if (factor->lock)
|
||||
spin_unlock_irqrestore(factor->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_factor_ops = {
|
||||
|
@ -419,12 +419,14 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
}
|
||||
}
|
||||
|
||||
static void mmp_clk_mix_init(struct clk_hw *hw)
|
||||
static int mmp_clk_mix_init(struct clk_hw *hw)
|
||||
{
|
||||
struct mmp_clk_mix *mix = to_clk_mix(hw);
|
||||
|
||||
if (mix->table)
|
||||
_filter_clk_table(mix, mix->table, mix->table_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops mmp_clk_mix_ops = {
|
||||
|
@ -29,7 +29,7 @@ config ARMADA_39X_CLK
|
||||
select MVEBU_CLK_COMMON
|
||||
|
||||
config ARMADA_37XX_CLK
|
||||
bool
|
||||
bool
|
||||
|
||||
config ARMADA_XP_CLK
|
||||
bool
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config KRAIT_CLOCKS
|
||||
bool
|
||||
select KRAIT_L2_ACCESSORS
|
||||
bool
|
||||
select KRAIT_L2_ACCESSORS
|
||||
|
||||
config QCOM_GDSC
|
||||
bool
|
||||
@ -14,6 +14,7 @@ menuconfig COMMON_CLK_QCOM
|
||||
tristate "Support for Qualcomm's clock controllers"
|
||||
depends on OF
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
select RATIONAL
|
||||
select REGMAP_MMIO
|
||||
select RESET_CONTROLLER
|
||||
|
||||
@ -95,6 +96,14 @@ config IPQ_GCC_4019
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2c, USB, SD/eMMC, etc.
|
||||
|
||||
config IPQ_GCC_6018
|
||||
tristate "IPQ6018 Global Clock Controller"
|
||||
help
|
||||
Support for global clock controller on ipq6018 devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2c, USB, SD/eMMC, etc. Select this for the root clock
|
||||
of ipq6018.
|
||||
|
||||
config IPQ_GCC_806X
|
||||
tristate "IPQ806x Global Clock Controller"
|
||||
help
|
||||
@ -229,6 +238,15 @@ config MSM_GPUCC_8998
|
||||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics.
|
||||
|
||||
config MSM_MMCC_8998
|
||||
tristate "MSM8998 Multimedia Clock Controller"
|
||||
select MSM_GCC_8998
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the multimedia clock controller on msm8998 devices.
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
||||
config QCS_GCC_404
|
||||
tristate "QCS404 Global Clock Controller"
|
||||
help
|
||||
@ -236,6 +254,15 @@ config QCS_GCC_404
|
||||
Say Y if you want to use multimedia devices or peripheral
|
||||
devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
|
||||
|
||||
config SC_DISPCC_7180
|
||||
tristate "SC7180 Display Clock Controller"
|
||||
select SC_GCC_7180
|
||||
help
|
||||
Support for the display clock controller on Qualcomm Technologies, Inc
|
||||
SC7180 devices.
|
||||
Say Y if you want to support display devices and functionality such as
|
||||
splash screen.
|
||||
|
||||
config SC_GCC_7180
|
||||
tristate "SC7180 Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
@ -245,6 +272,22 @@ config SC_GCC_7180
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
I2C, USB, UFS, SDCC, etc.
|
||||
|
||||
config SC_GPUCC_7180
|
||||
tristate "SC7180 Graphics Clock Controller"
|
||||
select SC_GCC_7180
|
||||
help
|
||||
Support for the graphics clock controller on SC7180 devices.
|
||||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics.
|
||||
|
||||
config SC_VIDEOCC_7180
|
||||
tristate "SC7180 Video Clock Controller"
|
||||
select SC_GCC_7180
|
||||
help
|
||||
Support for the video clock controller on SC7180 devices.
|
||||
Say Y if you want to support video devices and functionality such as
|
||||
video encode and decode.
|
||||
|
||||
config SDM_CAMCC_845
|
||||
tristate "SDM845 Camera Clock Controller"
|
||||
select SDM_GCC_845
|
||||
|
@ -20,6 +20,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
|
||||
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
|
||||
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
|
||||
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
|
||||
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
|
||||
@ -37,6 +38,7 @@ obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o
|
||||
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
|
||||
obj-$(CONFIG_MSM_MMCC_8998) += mmcc-msm8998.o
|
||||
obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
|
||||
obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
|
||||
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
|
||||
@ -45,7 +47,10 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
|
||||
obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
|
||||
obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
|
||||
obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
|
||||
obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
|
||||
obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
|
||||
obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
|
||||
obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
|
||||
obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
static const u32 gpll0_a53cc_map[] = { 4, 5 };
|
||||
|
||||
static const char * const gpll0_a53cc[] = {
|
||||
"gpll0_vote",
|
||||
"a53pll",
|
||||
static const struct clk_parent_data pdata[] = {
|
||||
{ .fw_name = "aux", .name = "gpll0_vote", },
|
||||
{ .fw_name = "pll", .name = "a53pll", },
|
||||
};
|
||||
|
||||
/*
|
||||
@ -62,8 +62,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
init.name = "a53mux";
|
||||
init.parent_names = gpll0_a53cc;
|
||||
init.num_parents = ARRAY_SIZE(gpll0_a53cc);
|
||||
init.parent_data = pdata;
|
||||
init.num_parents = ARRAY_SIZE(pdata);
|
||||
init.ops = &clk_regmap_mux_div_ops;
|
||||
init.flags = CLK_SET_RATE_PARENT;
|
||||
|
||||
@ -79,7 +79,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
|
||||
a53cc->pclk = devm_clk_get(parent, NULL);
|
||||
if (IS_ERR(a53cc->pclk)) {
|
||||
ret = PTR_ERR(a53cc->pclk);
|
||||
dev_err(dev, "failed to get clk: %d\n", ret);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err(dev, "failed to get clk: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -878,6 +878,14 @@ static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return clamp(rate, min_freq, max_freq);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_fixed_ops = {
|
||||
.enable = clk_alpha_pll_enable,
|
||||
.disable = clk_alpha_pll_disable,
|
||||
.is_enabled = clk_alpha_pll_is_enabled,
|
||||
.recalc_rate = clk_alpha_pll_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);
|
||||
|
||||
const struct clk_ops clk_alpha_pll_ops = {
|
||||
.enable = clk_alpha_pll_enable,
|
||||
.disable = clk_alpha_pll_disable,
|
||||
@ -1024,6 +1032,25 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
regmap_write(regmap, PLL_CONFIG_CTL(pll),
|
||||
config->config_ctl_val);
|
||||
|
||||
if (config->config_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
config->config_ctl_hi_val);
|
||||
|
||||
if (config->user_ctl_val)
|
||||
regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
|
||||
|
||||
if (config->user_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_USER_CTL_U(pll),
|
||||
config->user_ctl_hi_val);
|
||||
|
||||
if (config->test_ctl_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL(pll),
|
||||
config->test_ctl_val);
|
||||
|
||||
if (config->test_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL_U(pll),
|
||||
config->test_ctl_hi_val);
|
||||
|
||||
if (config->post_div_mask) {
|
||||
mask = config->post_div_mask;
|
||||
val = config->post_div_val;
|
||||
@ -1141,14 +1168,9 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 val, l, alpha_width = pll_alpha_width(pll);
|
||||
u32 l, alpha_width = pll_alpha_width(pll);
|
||||
u64 a;
|
||||
unsigned long rrate;
|
||||
int ret = 0;
|
||||
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
|
||||
|
||||
@ -1167,7 +1189,64 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
return __clk_alpha_pll_update_latch(pll);
|
||||
}
|
||||
|
||||
static int alpha_pll_fabia_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
const struct pll_vco *vco;
|
||||
struct clk_hw *parent_hw;
|
||||
unsigned long cal_freq, rrate;
|
||||
u32 cal_l, val, alpha_width = pll_alpha_width(pll);
|
||||
u64 a;
|
||||
int ret;
|
||||
|
||||
/* Check if calibration needs to be done i.e. PLL is in reset */
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Return early if calibration is not needed. */
|
||||
if (val & PLL_RESET_N)
|
||||
return 0;
|
||||
|
||||
vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
|
||||
if (!vco) {
|
||||
pr_err("alpha pll: not in a valid vco range\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq +
|
||||
pll->vco_table[0].max_freq) * 54, 100);
|
||||
|
||||
parent_hw = clk_hw_get_parent(hw);
|
||||
if (!parent_hw)
|
||||
return -EINVAL;
|
||||
|
||||
rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
|
||||
&cal_l, &a, alpha_width);
|
||||
/*
|
||||
* Due to a limited number of bits for fractional rate programming, the
|
||||
* rounded up rate could be marginally higher than the requested rate.
|
||||
*/
|
||||
if (rrate > (cal_freq + FABIA_PLL_RATE_MARGIN) || rrate < cal_freq)
|
||||
return -EINVAL;
|
||||
|
||||
/* Setup PLL for calibration frequency */
|
||||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l);
|
||||
|
||||
/* Bringup the PLL at calibration frequency */
|
||||
ret = clk_alpha_pll_enable(hw);
|
||||
if (ret) {
|
||||
pr_err("alpha pll calibration failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_alpha_pll_disable(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_fabia_ops = {
|
||||
.prepare = alpha_pll_fabia_prepare,
|
||||
.enable = alpha_pll_fabia_enable,
|
||||
.disable = alpha_pll_fabia_disable,
|
||||
.is_enabled = clk_alpha_pll_is_enabled,
|
||||
|
@ -94,6 +94,10 @@ struct alpha_pll_config {
|
||||
u32 alpha_hi;
|
||||
u32 config_ctl_val;
|
||||
u32 config_ctl_hi_val;
|
||||
u32 user_ctl_val;
|
||||
u32 user_ctl_hi_val;
|
||||
u32 test_ctl_val;
|
||||
u32 test_ctl_hi_val;
|
||||
u32 main_output_mask;
|
||||
u32 aux_output_mask;
|
||||
u32 aux2_output_mask;
|
||||
@ -109,6 +113,7 @@ struct alpha_pll_config {
|
||||
};
|
||||
|
||||
extern const struct clk_ops clk_alpha_pll_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_fixed_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_postdiv_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_huayra_ops;
|
||||
|
@ -196,7 +196,7 @@ static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
|
||||
return l_val * parent_rate;
|
||||
}
|
||||
|
||||
static void clk_hfpll_init(struct clk_hw *hw)
|
||||
static int clk_hfpll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_hfpll *h = to_clk_hfpll(hw);
|
||||
struct hfpll_data const *hd = h->d;
|
||||
@ -206,7 +206,7 @@ static void clk_hfpll_init(struct clk_hw *hw)
|
||||
regmap_read(regmap, hd->mode_reg, &mode);
|
||||
if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
|
||||
__clk_hfpll_init_once(hw);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hd->status_reg) {
|
||||
@ -218,6 +218,8 @@ static void clk_hfpll_init(struct clk_hw *hw)
|
||||
__clk_hfpll_init_once(hw);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hfpll_is_enabled(struct clk_hw *hw)
|
||||
|
@ -161,6 +161,7 @@ extern const struct clk_ops clk_byte2_ops;
|
||||
extern const struct clk_ops clk_pixel_ops;
|
||||
extern const struct clk_ops clk_gfx3d_ops;
|
||||
extern const struct clk_ops clk_rcg2_shared_ops;
|
||||
extern const struct clk_ops clk_dp_ops;
|
||||
|
||||
struct clk_rcg_dfs_data {
|
||||
struct clk_rcg2 *rcg;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/rational.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/slab.h>
|
||||
@ -1124,3 +1125,79 @@ int qcom_cc_register_rcg_dfs(struct regmap *regmap,
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs);
|
||||
|
||||
static int clk_rcg2_dp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
struct freq_tbl f = { 0 };
|
||||
u32 mask = BIT(rcg->hid_width) - 1;
|
||||
u32 hid_div, cfg;
|
||||
int i, num_parents = clk_hw_get_num_parents(hw);
|
||||
unsigned long num, den;
|
||||
|
||||
rational_best_approximation(parent_rate, rate,
|
||||
GENMASK(rcg->mnd_width - 1, 0),
|
||||
GENMASK(rcg->mnd_width - 1, 0), &den, &num);
|
||||
|
||||
if (!num || !den)
|
||||
return -EINVAL;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
|
||||
hid_div = cfg;
|
||||
cfg &= CFG_SRC_SEL_MASK;
|
||||
cfg >>= CFG_SRC_SEL_SHIFT;
|
||||
|
||||
for (i = 0; i < num_parents; i++) {
|
||||
if (cfg == rcg->parent_map[i].cfg) {
|
||||
f.src = rcg->parent_map[i].src;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f.pre_div = hid_div;
|
||||
f.pre_div >>= CFG_SRC_DIV_SHIFT;
|
||||
f.pre_div &= mask;
|
||||
|
||||
if (num != den) {
|
||||
f.m = num;
|
||||
f.n = den;
|
||||
} else {
|
||||
f.m = 0;
|
||||
f.n = 0;
|
||||
}
|
||||
|
||||
return clk_rcg2_configure(rcg, &f);
|
||||
}
|
||||
|
||||
static int clk_rcg2_dp_set_rate_and_parent(struct clk_hw *hw,
|
||||
unsigned long rate, unsigned long parent_rate, u8 index)
|
||||
{
|
||||
return clk_rcg2_dp_set_rate(hw, rate, parent_rate);
|
||||
}
|
||||
|
||||
static int clk_rcg2_dp_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_rate_request parent_req = *req;
|
||||
int ret;
|
||||
|
||||
ret = __clk_determine_rate(clk_hw_get_parent(hw), &parent_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->best_parent_rate = parent_req.rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_dp_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,
|
||||
.set_rate = clk_rcg2_dp_set_rate,
|
||||
.set_rate_and_parent = clk_rcg2_dp_set_rate_and_parent,
|
||||
.determine_rate = clk_rcg2_dp_determine_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_dp_ops);
|
||||
|
@ -396,6 +396,7 @@ static struct clk_hw *sc7180_rpmh_clocks[] = {
|
||||
[RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
|
||||
[RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
|
||||
[RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
|
||||
[RPMH_IPA_CLK] = &sdm845_ipa.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
|
||||
@ -431,11 +432,16 @@ static int clk_rpmh_probe(struct platform_device *pdev)
|
||||
hw_clks = desc->clks;
|
||||
|
||||
for (i = 0; i < desc->num_clks; i++) {
|
||||
const char *name = hw_clks[i]->init->name;
|
||||
const char *name;
|
||||
u32 res_addr;
|
||||
size_t aux_data_len;
|
||||
const struct bcm_db *data;
|
||||
|
||||
if (!hw_clks[i])
|
||||
continue;
|
||||
|
||||
name = hw_clks[i]->init->name;
|
||||
|
||||
rpmh_clk = to_clk_rpmh(hw_clks[i]);
|
||||
res_addr = cmd_db_read_addr(rpmh_clk->res_name);
|
||||
if (!res_addr) {
|
||||
@ -481,9 +487,9 @@ static int clk_rpmh_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id clk_rpmh_match_table[] = {
|
||||
{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
|
||||
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
|
||||
{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
|
||||
{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
|
||||
|
@ -485,6 +485,8 @@ static struct clk_smd_rpm *msm8974_clks[] = {
|
||||
[RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk,
|
||||
[RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk,
|
||||
[RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk,
|
||||
[RPM_SMD_GFX3D_CLK_SRC] = &msm8974_gfx3d_clk_src,
|
||||
[RPM_SMD_GFX3D_A_CLK_SRC] = &msm8974_gfx3d_a_clk_src,
|
||||
[RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk,
|
||||
[RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk,
|
||||
[RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk,
|
||||
@ -648,6 +650,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
|
||||
};
|
||||
|
||||
/* msm8998 */
|
||||
DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
|
||||
DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
|
||||
DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
|
||||
DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
|
||||
@ -671,6 +674,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6);
|
||||
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6);
|
||||
static struct clk_smd_rpm *msm8998_clks[] = {
|
||||
[RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk,
|
||||
[RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk,
|
||||
[RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk,
|
||||
[RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk,
|
||||
[RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk,
|
||||
|
776
drivers/clk/qcom/dispcc-sc7180.c
Normal file
776
drivers/clk/qcom/dispcc-sc7180.c
Normal file
@ -0,0 +1,776 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_CHIP_SLEEP_CLK,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_DISP_CC_PLL0_OUT_EVEN,
|
||||
P_DISP_CC_PLL0_OUT_MAIN,
|
||||
P_DP_PHY_PLL_LINK_CLK,
|
||||
P_DP_PHY_PLL_VCO_DIV_CLK,
|
||||
P_DSI0_PHY_PLL_OUT_BYTECLK,
|
||||
P_DSI0_PHY_PLL_OUT_DSICLK,
|
||||
P_GPLL0_OUT_MAIN,
|
||||
};
|
||||
|
||||
static const struct pll_vco fabia_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll disp_cc_pll0 = {
|
||||
.offset = 0x0,
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_pll0",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fabia_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct clk_div_table post_div_table_disp_cc_pll0_out_even[] = {
|
||||
{ 0x0, 1 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv disp_cc_pll0_out_even = {
|
||||
.offset = 0x0,
|
||||
.post_div_shift = 8,
|
||||
.post_div_table = post_div_table_disp_cc_pll0_out_even,
|
||||
.num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_even),
|
||||
.width = 4,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_pll0_out_even",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_pll0.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_0[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_DP_PHY_PLL_LINK_CLK, 1 },
|
||||
{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_1[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .fw_name = "dp_phy_pll_link_clk", .name = "dp_phy_pll_link_clk" },
|
||||
{ .fw_name = "dp_phy_pll_vco_div_clk",
|
||||
.name = "dp_phy_pll_vco_div_clk"},
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_2[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_2[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .fw_name = "dsi0_phy_pll_out_byteclk",
|
||||
.name = "dsi0_phy_pll_out_byteclk" },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_3[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
|
||||
{ P_GPLL0_OUT_MAIN, 4 },
|
||||
{ P_DISP_CC_PLL0_OUT_EVEN, 5 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_3[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &disp_cc_pll0.clkr.hw },
|
||||
{ .fw_name = "gcc_disp_gpll0_clk_src" },
|
||||
{ .hw = &disp_cc_pll0_out_even.clkr.hw },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_4[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPLL0_OUT_MAIN, 4 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_4[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .fw_name = "gcc_disp_gpll0_clk_src" },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_5[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data disp_cc_parent_data_5[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .fw_name = "dsi0_phy_pll_out_dsiclk",
|
||||
.name = "dsi0_phy_pll_out_dsiclk" },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
|
||||
F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
|
||||
.cmd_rcgr = 0x22bc,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_4,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_ahb_clk_src",
|
||||
.parent_data = disp_cc_parent_data_4,
|
||||
.num_parents = 3,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
|
||||
.cmd_rcgr = 0x2110,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_2,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_byte0_clk_src",
|
||||
.parent_data = disp_cc_parent_data_2,
|
||||
.num_parents = 3,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
|
||||
.cmd_rcgr = 0x21dc,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_0,
|
||||
.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 = disp_cc_parent_data_0,
|
||||
.num_parents = 2,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
||||
.cmd_rcgr = 0x2194,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_crypto_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
||||
.cmd_rcgr = 0x2178,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
||||
.cmd_rcgr = 0x21ac,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_dp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
|
||||
.cmd_rcgr = 0x2148,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_2,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_esc0_clk_src",
|
||||
.parent_data = disp_cc_parent_data_2,
|
||||
.num_parents = 3,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
|
||||
F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(345000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
|
||||
F(460000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
|
||||
.cmd_rcgr = 0x20c8,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_3,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_mdp_clk_src",
|
||||
.parent_data = disp_cc_parent_data_3,
|
||||
.num_parents = 5,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
|
||||
.cmd_rcgr = 0x2098,
|
||||
.mnd_width = 8,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_5,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_pclk0_clk_src",
|
||||
.parent_data = disp_cc_parent_data_5,
|
||||
.num_parents = 3,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_pixel_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
|
||||
.cmd_rcgr = 0x20e0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_3,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_rot_clk_src",
|
||||
.parent_data = disp_cc_parent_data_3,
|
||||
.num_parents = 5,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
|
||||
.cmd_rcgr = 0x20f8,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_vsync_clk_src",
|
||||
.parent_data = disp_cc_parent_data_0,
|
||||
.num_parents = 2,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_ahb_clk = {
|
||||
.halt_reg = 0x2080,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2080,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_byte0_clk = {
|
||||
.halt_reg = 0x2028,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2028,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_byte0_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_byte0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
|
||||
.reg = 0x2128,
|
||||
.shift = 0,
|
||||
.width = 2,
|
||||
.clkr.hw.init = &(struct clk_init_data) {
|
||||
.name = "disp_cc_mdss_byte0_div_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_byte0_clk_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
|
||||
.reg = 0x2190,
|
||||
.shift = 0,
|
||||
.width = 2,
|
||||
.clkr.hw.init = &(struct clk_init_data) {
|
||||
.name = "disp_cc_mdss_dp_link_div_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_regmap_div_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
|
||||
.halt_reg = 0x202c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x202c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_byte0_intf_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_aux_clk = {
|
||||
.halt_reg = 0x2054,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2054,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_aux_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
|
||||
.halt_reg = 0x2048,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2048,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_crypto_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_link_clk = {
|
||||
.halt_reg = 0x2040,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
|
||||
.halt_reg = 0x2044,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2044,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_intf_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
|
||||
.halt_reg = 0x204c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x204c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_esc0_clk = {
|
||||
.halt_reg = 0x2038,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2038,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_esc0_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_esc0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_mdp_clk = {
|
||||
.halt_reg = 0x200c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x200c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_mdp_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
|
||||
.halt_reg = 0x201c,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x201c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_mdp_lut_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
|
||||
.halt_reg = 0x4004,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x4004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_non_gdsc_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_pclk0_clk = {
|
||||
.halt_reg = 0x2004,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_pclk0_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_pclk0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_rot_clk = {
|
||||
.halt_reg = 0x2014,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2014,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_rot_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_rot_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
|
||||
.halt_reg = 0x400c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x400c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_rscc_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
|
||||
.halt_reg = 0x4008,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x4008,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_rscc_vsync_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_vsync_clk = {
|
||||
.halt_reg = 0x2024,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2024,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_vsync_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc mdss_gdsc = {
|
||||
.gdscr = 0x3000,
|
||||
.pd = {
|
||||
.name = "mdss_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = HW_CTRL,
|
||||
};
|
||||
|
||||
static struct gdsc *disp_cc_sc7180_gdscs[] = {
|
||||
[MDSS_GDSC] = &mdss_gdsc,
|
||||
};
|
||||
|
||||
static struct clk_regmap *disp_cc_sc7180_clocks[] = {
|
||||
[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
|
||||
[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
|
||||
[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
|
||||
[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
|
||||
[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
|
||||
[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
|
||||
&disp_cc_mdss_dp_link_div_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
|
||||
[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
|
||||
[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
|
||||
[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
|
||||
[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
|
||||
[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
|
||||
[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
|
||||
[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
|
||||
[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
|
||||
[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
|
||||
[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
|
||||
[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
|
||||
[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
|
||||
[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
|
||||
[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
|
||||
[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
|
||||
[DISP_CC_PLL0_OUT_EVEN] = &disp_cc_pll0_out_even.clkr,
|
||||
};
|
||||
|
||||
static const struct regmap_config disp_cc_sc7180_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x10000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc disp_cc_sc7180_desc = {
|
||||
.config = &disp_cc_sc7180_regmap_config,
|
||||
.clks = disp_cc_sc7180_clocks,
|
||||
.num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks),
|
||||
.gdscs = disp_cc_sc7180_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id disp_cc_sc7180_match_table[] = {
|
||||
{ .compatible = "qcom,sc7180-dispcc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, disp_cc_sc7180_match_table);
|
||||
|
||||
static int disp_cc_sc7180_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct alpha_pll_config disp_cc_pll_config = {};
|
||||
|
||||
regmap = qcom_cc_map(pdev, &disp_cc_sc7180_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* 1380MHz configuration */
|
||||
disp_cc_pll_config.l = 0x47;
|
||||
disp_cc_pll_config.alpha = 0xe000;
|
||||
disp_cc_pll_config.user_ctl_val = 0x00000001;
|
||||
disp_cc_pll_config.user_ctl_hi_val = 0x00004805;
|
||||
|
||||
clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver disp_cc_sc7180_driver = {
|
||||
.probe = disp_cc_sc7180_probe,
|
||||
.driver = {
|
||||
.name = "sc7180-dispcc",
|
||||
.of_match_table = disp_cc_sc7180_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init disp_cc_sc7180_init(void)
|
||||
{
|
||||
return platform_driver_register(&disp_cc_sc7180_driver);
|
||||
}
|
||||
subsys_initcall(disp_cc_sc7180_init);
|
||||
|
||||
static void __exit disp_cc_sc7180_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&disp_cc_sc7180_driver);
|
||||
}
|
||||
module_exit(disp_cc_sc7180_exit);
|
||||
|
||||
MODULE_DESCRIPTION("QTI DISP_CC SC7180 Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
@ -29,6 +29,8 @@ enum {
|
||||
P_DSI1_PHY_PLL_OUT_DSICLK,
|
||||
P_GPLL0_OUT_MAIN,
|
||||
P_GPLL0_OUT_MAIN_DIV,
|
||||
P_DP_PHY_PLL_LINK_CLK,
|
||||
P_DP_PHY_PLL_VCO_DIV_CLK,
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_0[] = {
|
||||
@ -45,6 +47,20 @@ static const char * const disp_cc_parent_names_0[] = {
|
||||
"core_bi_pll_test_se",
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_DP_PHY_PLL_LINK_CLK, 1 },
|
||||
{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const char * const disp_cc_parent_names_1[] = {
|
||||
"bi_tcxo",
|
||||
"dp_link_clk_divsel_ten",
|
||||
"dp_vco_divided_clk_src_mux",
|
||||
"core_bi_pll_test_se",
|
||||
};
|
||||
|
||||
static const struct parent_map disp_cc_parent_map_2[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
@ -128,6 +144,81 @@ static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
|
||||
.cmd_rcgr = 0x219c,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_2,
|
||||
.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_names = disp_cc_parent_names_2,
|
||||
.num_parents = 2,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
||||
.cmd_rcgr = 0x2154,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_crypto_clk_src",
|
||||
.parent_names = disp_cc_parent_names_1,
|
||||
.num_parents = 4,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
||||
.cmd_rcgr = 0x2138,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_clk_src",
|
||||
.parent_names = disp_cc_parent_names_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
|
||||
.cmd_rcgr = 0x2184,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel1_clk_src",
|
||||
.parent_names = disp_cc_parent_names_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_dp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
||||
.cmd_rcgr = 0x216c,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = disp_cc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel_clk_src",
|
||||
.parent_names = disp_cc_parent_names_1,
|
||||
.num_parents = 4,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_dp_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
{ }
|
||||
@ -391,6 +482,114 @@ static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_aux_clk = {
|
||||
.halt_reg = 0x2054,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2054,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_aux_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_aux_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
|
||||
.halt_reg = 0x2048,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2048,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_crypto_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_crypto_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_link_clk = {
|
||||
.halt_reg = 0x2040,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_link_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */
|
||||
static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
|
||||
.halt_reg = 0x2044,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2044,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_link_intf_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_link_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
|
||||
.halt_reg = 0x2050,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2050,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel1_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_pixel1_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
|
||||
.halt_reg = 0x204c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x204c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "disp_cc_mdss_dp_pixel_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"disp_cc_mdss_dp_pixel_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch disp_cc_mdss_esc0_clk = {
|
||||
.halt_reg = 0x2038,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@ -589,6 +788,19 @@ static struct clk_regmap *disp_cc_sdm845_clocks[] = {
|
||||
[DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
|
||||
[DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] =
|
||||
&disp_cc_mdss_byte1_div_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] =
|
||||
&disp_cc_mdss_dp_crypto_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] =
|
||||
&disp_cc_mdss_dp_pixel1_clk_src.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
|
||||
[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
|
||||
[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
|
||||
[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
|
||||
[DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
|
||||
|
4635
drivers/clk/qcom/gcc-ipq6018.c
Normal file
4635
drivers/clk/qcom/gcc-ipq6018.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -3046,7 +3046,10 @@ static struct clk_branch gcc_usb3_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_usb3_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3060,7 +3063,10 @@ static struct clk_branch gcc_hdmi_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_hdmi_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3074,7 +3080,10 @@ static struct clk_branch gcc_edp_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_edp_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3088,7 +3097,10 @@ static struct clk_branch gcc_ufs_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3102,7 +3114,10 @@ static struct clk_branch gcc_pcie_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_pcie_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3116,7 +3131,10 @@ static struct clk_branch gcc_rx2_usb2_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_rx2_usb2_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
@ -3130,7 +3148,10 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_rx1_usb2_clkref_clk",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "cxo2",
|
||||
.name = "xo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
|
@ -1996,6 +1996,19 @@ static struct clk_branch gcc_gp3_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_bimc_gfx_clk = {
|
||||
.halt_reg = 0x46040,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x46040,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_bimc_gfx_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_gpu_bimc_gfx_clk = {
|
||||
.halt_reg = 0x71010,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@ -2810,6 +2823,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
||||
[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
|
||||
[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
|
||||
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
|
||||
[GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
|
||||
[GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr,
|
||||
[GCC_GPU_BIMC_GFX_SRC_CLK] = &gcc_gpu_bimc_gfx_src_clk.clkr,
|
||||
[GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
|
||||
|
@ -330,7 +330,7 @@ static struct clk_alpha_pll gpll0_ao_out_main = {
|
||||
.parent_names = (const char *[]){ "cxo" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
266
drivers/clk/qcom/gpucc-sc7180.c
Normal file
266
drivers/clk/qcom/gpucc-sc7180.c
Normal file
@ -0,0 +1,266 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,gpucc-sc7180.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
#define CX_GMU_CBCR_SLEEP_MASK 0xF
|
||||
#define CX_GMU_CBCR_SLEEP_SHIFT 4
|
||||
#define CX_GMU_CBCR_WAKE_MASK 0xF
|
||||
#define CX_GMU_CBCR_WAKE_SHIFT 8
|
||||
#define CLK_DIS_WAIT_SHIFT 12
|
||||
#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_GPLL0_OUT_MAIN,
|
||||
P_GPLL0_OUT_MAIN_DIV,
|
||||
P_GPU_CC_PLL1_OUT_EVEN,
|
||||
P_GPU_CC_PLL1_OUT_MAIN,
|
||||
P_GPU_CC_PLL1_OUT_ODD,
|
||||
};
|
||||
|
||||
static const struct pll_vco fabia_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpu_cc_pll1 = {
|
||||
.offset = 0x100,
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_pll1",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fabia_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map gpu_cc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpu_cc_parent_data_0[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &gpu_cc_pll1.clkr.hw },
|
||||
{ .fw_name = "gcc_gpu_gpll0_clk_src" },
|
||||
{ .fw_name = "gcc_gpu_gpll0_div_clk_src" },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gpu_cc_gmu_clk_src = {
|
||||
.cmd_rcgr = 0x1120,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpu_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_gmu_clk_src",
|
||||
.parent_data = gpu_cc_parent_data_0,
|
||||
.num_parents = 5,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_crc_ahb_clk = {
|
||||
.halt_reg = 0x107c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x107c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_crc_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cx_gmu_clk = {
|
||||
.halt_reg = 0x1098,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1098,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_cx_gmu_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.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_cx_snoc_dvm_clk = {
|
||||
.halt_reg = 0x108c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x108c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_cx_snoc_dvm_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cxo_aon_clk = {
|
||||
.halt_reg = 0x1004,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1004,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_cxo_aon_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpu_cc_cxo_clk = {
|
||||
.halt_reg = 0x109c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x109c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_cc_cxo_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc cx_gdsc = {
|
||||
.gdscr = 0x106c,
|
||||
.gds_hw_ctrl = 0x1540,
|
||||
.pd = {
|
||||
.name = "cx_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc *gpu_cc_sc7180_gdscs[] = {
|
||||
[CX_GDSC] = &cx_gdsc,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gpu_cc_sc7180_clocks[] = {
|
||||
[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
|
||||
[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
|
||||
[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
|
||||
[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
|
||||
[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
|
||||
[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
|
||||
[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
|
||||
};
|
||||
|
||||
static const struct regmap_config gpu_cc_sc7180_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x8008,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gpu_cc_sc7180_desc = {
|
||||
.config = &gpu_cc_sc7180_regmap_config,
|
||||
.clks = gpu_cc_sc7180_clocks,
|
||||
.num_clks = ARRAY_SIZE(gpu_cc_sc7180_clocks),
|
||||
.gdscs = gpu_cc_sc7180_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id gpu_cc_sc7180_match_table[] = {
|
||||
{ .compatible = "qcom,sc7180-gpucc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpu_cc_sc7180_match_table);
|
||||
|
||||
static int gpu_cc_sc7180_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct alpha_pll_config gpu_cc_pll_config = {};
|
||||
unsigned int value, mask;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &gpu_cc_sc7180_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* 360MHz Configuration */
|
||||
gpu_cc_pll_config.l = 0x12;
|
||||
gpu_cc_pll_config.alpha = 0xc000;
|
||||
gpu_cc_pll_config.config_ctl_val = 0x20485699;
|
||||
gpu_cc_pll_config.config_ctl_hi_val = 0x00002067;
|
||||
gpu_cc_pll_config.user_ctl_val = 0x00000001;
|
||||
gpu_cc_pll_config.user_ctl_hi_val = 0x00004805;
|
||||
gpu_cc_pll_config.test_ctl_hi_val = 0x40000000;
|
||||
|
||||
clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll_config);
|
||||
|
||||
/* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */
|
||||
mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
|
||||
mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
|
||||
value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
|
||||
regmap_update_bits(regmap, 0x1098, mask, value);
|
||||
|
||||
/* Configure clk_dis_wait for gpu_cx_gdsc */
|
||||
regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
|
||||
8 << CLK_DIS_WAIT_SHIFT);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver gpu_cc_sc7180_driver = {
|
||||
.probe = gpu_cc_sc7180_probe,
|
||||
.driver = {
|
||||
.name = "sc7180-gpucc",
|
||||
.of_match_table = gpu_cc_sc7180_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init gpu_cc_sc7180_init(void)
|
||||
{
|
||||
return platform_driver_register(&gpu_cc_sc7180_driver);
|
||||
}
|
||||
subsys_initcall(gpu_cc_sc7180_init);
|
||||
|
||||
static void __exit gpu_cc_sc7180_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gpu_cc_sc7180_driver);
|
||||
}
|
||||
module_exit(gpu_cc_sc7180_exit);
|
||||
|
||||
MODULE_DESCRIPTION("QTI GPU_CC SC7180 Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -53,10 +53,18 @@ static int qcom_hfpll_probe(struct platform_device *pdev)
|
||||
struct regmap *regmap;
|
||||
struct clk_hfpll *h;
|
||||
struct clk_init_data init = {
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_ops_hfpll,
|
||||
/*
|
||||
* rather than marking the clock critical and forcing the clock
|
||||
* to be always enabled, we make sure that the clock is not
|
||||
* disabled: the firmware remains responsible of enabling this
|
||||
* clock (for more info check the commit log)
|
||||
*/
|
||||
.flags = CLK_IGNORE_UNUSED,
|
||||
};
|
||||
int ret;
|
||||
struct clk_parent_data pdata = { .index = 0 };
|
||||
|
||||
h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
|
||||
if (!h)
|
||||
@ -75,11 +83,20 @@ static int qcom_hfpll_probe(struct platform_device *pdev)
|
||||
0, &init.name))
|
||||
return -ENODEV;
|
||||
|
||||
init.parent_data = &pdata;
|
||||
|
||||
h->d = &hdata;
|
||||
h->clkr.hw.init = &init;
|
||||
spin_lock_init(&h->lock);
|
||||
|
||||
return devm_clk_register_regmap(&pdev->dev, &h->clkr);
|
||||
ret = devm_clk_register_regmap(dev, &h->clkr);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to register regmap clock: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
&h->clkr.hw);
|
||||
}
|
||||
|
||||
static struct platform_driver qcom_hfpll_driver = {
|
||||
|
@ -452,18 +452,6 @@ static struct clk_rcg2 mdp_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gfx3d_clk_src = {
|
||||
.cmd_rcgr = 0x4000,
|
||||
.hid_width = 5,
|
||||
.parent_map = mmcc_xo_mmpll0_1_2_gpll0_map,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_clk_src",
|
||||
.parent_names = mmcc_xo_mmpll0_1_2_gpll0,
|
||||
.num_parents = 5,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct freq_tbl ftbl_camss_jpeg_jpeg0_2_clk[] = {
|
||||
F(75000000, P_GPLL0, 8, 0, 0),
|
||||
F(133330000, P_GPLL0, 4.5, 0, 0),
|
||||
@ -2411,7 +2399,6 @@ static struct clk_regmap *mmcc_msm8974_clocks[] = {
|
||||
[VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
|
||||
[VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
|
||||
[MDP_CLK_SRC] = &mdp_clk_src.clkr,
|
||||
[GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
|
||||
[JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
|
||||
[JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr,
|
||||
[JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr,
|
||||
|
2913
drivers/clk/qcom/mmcc-msm8998.c
Normal file
2913
drivers/clk/qcom/mmcc-msm8998.c
Normal file
File diff suppressed because it is too large
Load Diff
259
drivers/clk/qcom/videocc-sc7180.c
Normal file
259
drivers/clk/qcom/videocc-sc7180.c
Normal file
@ -0,0 +1,259 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,videocc-sc7180.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_CHIP_SLEEP_CLK,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_VIDEO_PLL0_OUT_EVEN,
|
||||
P_VIDEO_PLL0_OUT_MAIN,
|
||||
P_VIDEO_PLL0_OUT_ODD,
|
||||
};
|
||||
|
||||
static const struct pll_vco fabia_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll video_pll0 = {
|
||||
.offset = 0x42c,
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_pll0",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fabia_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_VIDEO_PLL0_OUT_MAIN, 1 },
|
||||
{ P_CORE_BI_PLL_TEST_SE, 7 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_1[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &video_pll0.clkr.hw },
|
||||
{ .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(150000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
|
||||
F(270000000, P_VIDEO_PLL0_OUT_MAIN, 2.5, 0, 0),
|
||||
F(340000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(434000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(500000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_venus_clk_src = {
|
||||
.cmd_rcgr = 0x7f0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_1,
|
||||
.freq_tbl = ftbl_video_cc_venus_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_venus_clk_src",
|
||||
.parent_data = video_cc_parent_data_1,
|
||||
.num_parents = 3,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_vcodec0_axi_clk = {
|
||||
.halt_reg = 0x9ec,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9ec,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_vcodec0_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_vcodec0_core_clk = {
|
||||
.halt_reg = 0x890,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x890,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_vcodec0_core_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_venus_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_venus_ahb_clk = {
|
||||
.halt_reg = 0xa4c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xa4c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_venus_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_venus_ctl_axi_clk = {
|
||||
.halt_reg = 0x9cc,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x9cc,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_venus_ctl_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_venus_ctl_core_clk = {
|
||||
.halt_reg = 0x850,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x850,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_venus_ctl_core_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_venus_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc venus_gdsc = {
|
||||
.gdscr = 0x814,
|
||||
.pd = {
|
||||
.name = "venus_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc vcodec0_gdsc = {
|
||||
.gdscr = 0x874,
|
||||
.pd = {
|
||||
.name = "vcodec0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *video_cc_sc7180_clocks[] = {
|
||||
[VIDEO_CC_VCODEC0_AXI_CLK] = &video_cc_vcodec0_axi_clk.clkr,
|
||||
[VIDEO_CC_VCODEC0_CORE_CLK] = &video_cc_vcodec0_core_clk.clkr,
|
||||
[VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr,
|
||||
[VIDEO_CC_VENUS_CLK_SRC] = &video_cc_venus_clk_src.clkr,
|
||||
[VIDEO_CC_VENUS_CTL_AXI_CLK] = &video_cc_venus_ctl_axi_clk.clkr,
|
||||
[VIDEO_CC_VENUS_CTL_CORE_CLK] = &video_cc_venus_ctl_core_clk.clkr,
|
||||
[VIDEO_PLL0] = &video_pll0.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *video_cc_sc7180_gdscs[] = {
|
||||
[VENUS_GDSC] = &venus_gdsc,
|
||||
[VCODEC0_GDSC] = &vcodec0_gdsc,
|
||||
};
|
||||
|
||||
static const struct regmap_config video_cc_sc7180_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xb94,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc video_cc_sc7180_desc = {
|
||||
.config = &video_cc_sc7180_regmap_config,
|
||||
.clks = video_cc_sc7180_clocks,
|
||||
.num_clks = ARRAY_SIZE(video_cc_sc7180_clocks),
|
||||
.gdscs = video_cc_sc7180_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(video_cc_sc7180_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id video_cc_sc7180_match_table[] = {
|
||||
{ .compatible = "qcom,sc7180-videocc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, video_cc_sc7180_match_table);
|
||||
|
||||
static int video_cc_sc7180_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct alpha_pll_config video_pll0_config = {};
|
||||
|
||||
regmap = qcom_cc_map(pdev, &video_cc_sc7180_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
video_pll0_config.l = 0x1f;
|
||||
video_pll0_config.alpha = 0x4000;
|
||||
video_pll0_config.user_ctl_val = 0x00000001;
|
||||
video_pll0_config.user_ctl_hi_val = 0x00004805;
|
||||
|
||||
clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
||||
|
||||
/* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
|
||||
regmap_update_bits(regmap, 0x984, 0x1, 0x1);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &video_cc_sc7180_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver video_cc_sc7180_driver = {
|
||||
.probe = video_cc_sc7180_probe,
|
||||
.driver = {
|
||||
.name = "sc7180-videocc",
|
||||
.of_match_table = video_cc_sc7180_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init video_cc_sc7180_init(void)
|
||||
{
|
||||
return platform_driver_register(&video_cc_sc7180_driver);
|
||||
}
|
||||
subsys_initcall(video_cc_sc7180_init);
|
||||
|
||||
static void __exit video_cc_sc7180_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&video_cc_sc7180_driver);
|
||||
}
|
||||
module_exit(video_cc_sc7180_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("QTI VIDEOCC SC7180 Driver");
|
@ -20,8 +20,8 @@ config CLK_RENESAS
|
||||
select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
|
||||
select CLK_R8A7792 if ARCH_R8A7792
|
||||
select CLK_R8A7794 if ARCH_R8A7794
|
||||
select CLK_R8A7795 if ARCH_R8A7795
|
||||
select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796
|
||||
select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795
|
||||
select CLK_R8A77960 if ARCH_R8A77960
|
||||
select CLK_R8A77961 if ARCH_R8A77961
|
||||
select CLK_R8A77965 if ARCH_R8A77965
|
||||
select CLK_R8A77970 if ARCH_R8A77970
|
||||
|
@ -93,6 +93,7 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = {
|
||||
DEF_MOD_STB("ether1", 64, R7S9210_CLK_B),
|
||||
DEF_MOD_STB("ether0", 65, R7S9210_CLK_B),
|
||||
|
||||
DEF_MOD_STB("spibsc", 83, R7S9210_CLK_P1),
|
||||
DEF_MOD_STB("i2c3", 84, R7S9210_CLK_P1),
|
||||
DEF_MOD_STB("i2c2", 85, R7S9210_CLK_P1),
|
||||
DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1),
|
||||
|
@ -24,10 +24,10 @@ enum rcar_gen2_clk_types {
|
||||
};
|
||||
|
||||
struct rcar_gen2_cpg_pll_config {
|
||||
unsigned int extal_div;
|
||||
unsigned int pll1_mult;
|
||||
unsigned int pll3_mult;
|
||||
unsigned int pll0_mult; /* leave as zero if PLL0CR exists */
|
||||
u8 extal_div;
|
||||
u8 pll1_mult;
|
||||
u8 pll3_mult;
|
||||
u8 pll0_mult; /* leave as zero if PLL0CR exists */
|
||||
};
|
||||
|
||||
struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
|
||||
|
@ -470,7 +470,8 @@ static struct clk * __init cpg_rpc_clk_register(const char *name,
|
||||
|
||||
clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
|
||||
&rpc->div.hw, &clk_divider_ops,
|
||||
&rpc->gate.hw, &clk_gate_ops, 0);
|
||||
&rpc->gate.hw, &clk_gate_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
if (IS_ERR(clk)) {
|
||||
kfree(rpc);
|
||||
return clk;
|
||||
@ -506,7 +507,8 @@ static struct clk * __init cpg_rpcd2_clk_register(const char *name,
|
||||
|
||||
clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
|
||||
&rpcd2->fixed.hw, &clk_fixed_factor_ops,
|
||||
&rpcd2->gate.hw, &clk_gate_ops, 0);
|
||||
&rpcd2->gate.hw, &clk_gate_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
if (IS_ERR(clk))
|
||||
kfree(rpcd2);
|
||||
|
||||
|
@ -282,7 +282,7 @@ static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
|
||||
return !(pllcon & RK3036_PLLCON1_PWRDOWN);
|
||||
}
|
||||
|
||||
static void rockchip_rk3036_pll_init(struct clk_hw *hw)
|
||||
static int rockchip_rk3036_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
@ -290,14 +290,14 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
|
||||
unsigned long drate;
|
||||
|
||||
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
drate = clk_hw_get_rate(hw);
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
|
||||
/* when no rate setting for the current rate, rely on clk_set_rate */
|
||||
if (!rate)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
rockchip_rk3036_pll_get_params(pll, &cur);
|
||||
|
||||
@ -319,13 +319,15 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
|
||||
if (!parent) {
|
||||
pr_warn("%s: parent of %s not available\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
rockchip_rk3036_pll_set_params(pll, rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
|
||||
@ -515,7 +517,7 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
|
||||
return !(pllcon & RK3066_PLLCON3_PWRDOWN);
|
||||
}
|
||||
|
||||
static void rockchip_rk3066_pll_init(struct clk_hw *hw)
|
||||
static int rockchip_rk3066_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
@ -523,14 +525,14 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
|
||||
unsigned long drate;
|
||||
|
||||
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
drate = clk_hw_get_rate(hw);
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
|
||||
/* when no rate setting for the current rate, rely on clk_set_rate */
|
||||
if (!rate)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
rockchip_rk3066_pll_get_params(pll, &cur);
|
||||
|
||||
@ -543,6 +545,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
|
||||
__func__, clk_hw_get_name(hw));
|
||||
rockchip_rk3066_pll_set_params(pll, rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
|
||||
@ -761,7 +765,7 @@ static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
|
||||
return !(pllcon & RK3399_PLLCON3_PWRDOWN);
|
||||
}
|
||||
|
||||
static void rockchip_rk3399_pll_init(struct clk_hw *hw)
|
||||
static int rockchip_rk3399_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
const struct rockchip_pll_rate_table *rate;
|
||||
@ -769,14 +773,14 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
|
||||
unsigned long drate;
|
||||
|
||||
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
drate = clk_hw_get_rate(hw);
|
||||
rate = rockchip_get_pll_settings(pll, drate);
|
||||
|
||||
/* when no rate setting for the current rate, rely on clk_set_rate */
|
||||
if (!rate)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
rockchip_rk3399_pll_get_params(pll, &cur);
|
||||
|
||||
@ -798,13 +802,15 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
|
||||
if (!parent) {
|
||||
pr_warn("%s: parent of %s not available\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
rockchip_rk3399_pll_set_params(pll, rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
|
||||
|
@ -921,11 +921,26 @@ static const struct sunxi_ccu_desc sun50i_a64_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun50i_a64_ccu_resets),
|
||||
};
|
||||
|
||||
static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = {
|
||||
.common = &pll_cpux_clk.common,
|
||||
/* copy from pll_cpux_clk */
|
||||
.enable = BIT(31),
|
||||
.lock = BIT(28),
|
||||
};
|
||||
|
||||
static struct ccu_mux_nb sun50i_a64_cpu_nb = {
|
||||
.common = &cpux_clk.common,
|
||||
.cm = &cpux_clk.mux,
|
||||
.delay_us = 1, /* > 8 clock cycles at 24 MHz */
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static int sun50i_a64_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
@ -939,7 +954,18 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
|
||||
|
||||
writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
|
||||
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb);
|
||||
|
||||
/* Reparent CPU during PLL CPU rate changes */
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun50i_a64_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sun50i_a64_ccu_ids[] = {
|
||||
|
@ -36,7 +36,6 @@
|
||||
#define CLK_PLL_HSIC 18
|
||||
#define CLK_PLL_DE 19
|
||||
#define CLK_PLL_DDR1 20
|
||||
#define CLK_CPUX 21
|
||||
#define CLK_AXI 22
|
||||
#define CLK_APB 23
|
||||
#define CLK_AHB1 24
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user