This is all driver updates, the majority of which is a bunch of new Qualcomm
clk drivers that dominate the diffstat because we add support for six SoCs from that particular vendor. The other big change is the removal of various clk drivers that are no longer used now that the kernel is dropping support for those SoCs. Beyond that there's the usual non-critical fixes for existing drivers and a good number of patches from Lee Jones that cleanup a bunch of W=1 enabled builds. Removed Drivers: - Remove efm32 clk driver - Remove tango4 clk driver - Remove zte zx clk driver - Remove sirf prima2/atlast clk drivers - Remove u300 clk driver New Drivers: - PLL support on MStar/SigmaStar ARMv7 SoCs - CPU clks for Qualcomm SDX55 - GCC and RPMh clks for Qualcomm SC8180x and SC7280 SoCs - GCC clks for Qualcomm SM8350 - GPU clks for Qualcomm SDM660/SDM630 Updates: - Video clk fixups on Qualcomm SM8250 - Improvements for multimedia clks on Qualcomm MSM8998 - Fix many warnings with W=1 enabled builds under drivers/clk/ - Support crystal load capacitance for Versaclock VC5 - Add a "skip recall" DT binding for Silicon Labs' si570 to avoid glitches at boot - Convert Xilinx VCU clk driver to a proper clk provider driver - Expose Xilinx ZynqMP clk driver to more platforms - Amlogic pll driver fixup - Amlogic meson8b clock controller dt support clean up - Remove mipi clk from the Amlogic axg clock controller - New Rockchip rk3368 clock ids related to camera input - Use pr_notice() instead of pr_warn() on i.MX6Q pre-boot ldb_di_clk reparenting - A series from Liu Ying that adds some SCU clocks support for i.MX8qxp DC0/MIPI-LVDS subsystems - A series from Lucas Stach that adds PLL monitor clocks for i.MX8MQ, and clkout1/2 support for i.MX8MM/MN - Add I2c and Ethernet (RAVB) clocks on Renesas R-Car V3U - Add timer (TMU) clocks on most Renesas R-Car Gen3 SoCs - Add video-related (FCPVD/VSPD/VSPX), watchdog (RWDT), serial (HSCIF), pincontrol/GPIO (PFC/GPIO), SPI (MSIOF), SDHI, and DMA (SYS-DMAC) clocks on Renesas R-Car V3U - Add support for the USB 2.0 clock selector on Renesas RZ/G2 SoCs - Allwinner H616 SoC clk support -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmAwFu8RHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSXiWQ/+LbMeJF5zSvK240XcWomyS+kmImqKPT6e +l9Lt5xEPc+KzfMFHGAv+b6vMZCYevMIjBYCleiQ3oSh3sICFJmcCI8AkwQ62aQC 32VL0z8U956SxmlCcgIgHK3yKUDSZcNC9FtfGRIRzR6srx+Eu/8TK007RpAYn2bQ PZYzOjiueSjOpjTRry2WGiCvpwRaJ7XrGj7P4rshO5eKpML1hYAv84vm12QrkoTR j7B73x1bOYf4NUBGGzYH5kw6tDO4mZvR+0TdyjI2Yg+SvHSdkpv9pxgRSAFus6rv sY/EjUCmCgp+y/MuMRvMA7vk6+THTqF9v4HqE0+izUI+dIoeDmsFVPr3UXGhqmtm wmdsMuG/cMhj1rIFz+1aNXQjdbitwmTCyqbiyt+6fOH3NkrP4vQACzQlxeBS2n6o E02lMwvMEoLcBMQyWLG+IWasIYWp7L2FlTOGOHxlAkZxJwNmynfaWYafoaIfOtBk qtk3ZjNFo3av94AWuKieeWdOj3CY3LGhQqwVuJudOzfvcBu3UybCfceHIwXuIWk1 msUOh2RA7CTXn7XYPszwEbOlWugKvUc46rTfDBXsmgir7sIIgVXK65SO9xPWd7Bz b7MDtrQwSTNYecxjI6uUPRrzKM6xSnL8I69lxaUWT1ScXFcOjqOgc6iwSfLNj4lh FFCMY5koKMw= =dDCt -----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: "This is all driver updates, the majority of which is a bunch of new Qualcomm clk drivers that dominate the diffstat because we add support for six SoCs from that particular vendor. The other big change is the removal of various clk drivers that are no longer used now that the kernel is dropping support for those SoCs. Beyond that there's the usual non-critical fixes for existing drivers and a good number of patches from Lee Jones that cleanup a bunch of W=1 enabled builds. Removed Drivers: - Remove efm32 clk driver - Remove tango4 clk driver - Remove zte zx clk driver - Remove sirf prima2/atlast clk drivers - Remove u300 clk driver New Drivers: - PLL support on MStar/SigmaStar ARMv7 SoCs - CPU clks for Qualcomm SDX55 - GCC and RPMh clks for Qualcomm SC8180x and SC7280 SoCs - GCC clks for Qualcomm SM8350 - GPU clks for Qualcomm SDM660/SDM630 Updates: - Video clk fixups on Qualcomm SM8250 - Improvements for multimedia clks on Qualcomm MSM8998 - Fix many warnings with W=1 enabled builds under drivers/clk/ - Support crystal load capacitance for Versaclock VC5 - Add a "skip recall" DT binding for Silicon Labs' si570 to avoid glitches at boot - Convert Xilinx VCU clk driver to a proper clk provider driver - Expose Xilinx ZynqMP clk driver to more platforms - Amlogic pll driver fixup - Amlogic meson8b clock controller dt support clean up - Remove mipi clk from the Amlogic axg clock controller - New Rockchip rk3368 clock ids related to camera input - Use pr_notice() instead of pr_warn() on i.MX6Q pre-boot ldb_di_clk reparenting - A series from Liu Ying that adds some SCU clocks support for i.MX8qxp DC0/MIPI-LVDS subsystems - A series from Lucas Stach that adds PLL monitor clocks for i.MX8MQ, and clkout1/2 support for i.MX8MM/MN - Add I2c and Ethernet (RAVB) clocks on Renesas R-Car V3U - Add timer (TMU) clocks on most Renesas R-Car Gen3 SoCs - Add video-related (FCPVD/VSPD/VSPX), watchdog (RWDT), serial (HSCIF), pincontrol/GPIO (PFC/GPIO), SPI (MSIOF), SDHI, and DMA (SYS-DMAC) clocks on Renesas R-Car V3U - Add support for the USB 2.0 clock selector on Renesas RZ/G2 SoCs - Allwinner H616 SoC clk support" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (171 commits) clk: mstar: msc313-mpll: Fix format specifier clk: mstar: Allow MStar clk drivers to be compile tested clk: qoriq: use macros to generate pll_mask clk: qcom: Add Global Clock controller (GCC) driver for SC7280 dt-bindings: clock: Add SC7280 GCC clock binding clk: qcom: rpmh: Add support for RPMH clocks on SC7280 dt-bindings: clock: Add RPMHCC bindings for SC7280 clk: qcom: gcc-sm8350: add gdsc dt-bindings: clock: Add QCOM SDM630 and SDM660 graphics clock bindings clk: qcom: Add SDM660 GPU Clock Controller (GPUCC) driver clk: qcom: mmcc-msm8996: Migrate gfx3d clock to clk_rcg2_gfx3d clk: qcom: rcg2: Stop hardcoding gfx3d pingpong parent numbers dt-bindings: clock: Add support for the SDM630 and SDM660 mmcc clk: qcom: Add SDM660 Multimedia Clock Controller (MMCC) driver clk: qcom: gcc-sdm660: Mark GPU CFG AHB clock as critical clk: qcom: gcc-sdm660: Mark MMSS NoC CFG AHB clock as critical clk: qcom: gpucc-msm8998: Allow fabia gpupll0 rate setting clk: qcom: gpucc-msm8998: Add resets, cxc, fix flags on gpu_gx_gdsc clk: qcom: gdsc: Implement NO_RET_PERIPH flag clk: mstar: MStar/SigmaStar MPLL driver ...
This commit is contained in:
Коммит
28b9aaac4c
|
@ -20,6 +20,7 @@ properties:
|
|||
compatible:
|
||||
enum:
|
||||
- adi,axi-clkgen-2.00.a
|
||||
- adi,zynqmp-axi-clkgen-2.00.a
|
||||
|
||||
clocks:
|
||||
description:
|
||||
|
|
|
@ -41,6 +41,8 @@ properties:
|
|||
- allwinner,sun50i-h5-ccu
|
||||
- allwinner,sun50i-h6-ccu
|
||||
- allwinner,sun50i-h6-r-ccu
|
||||
- allwinner,sun50i-h616-ccu
|
||||
- allwinner,sun50i-h616-r-ccu
|
||||
- allwinner,suniv-f1c100s-ccu
|
||||
- nextthing,gr8-ccu
|
||||
|
||||
|
@ -82,6 +84,7 @@ if:
|
|||
- allwinner,sun50i-a64-r-ccu
|
||||
- allwinner,sun50i-a100-r-ccu
|
||||
- allwinner,sun50i-h6-r-ccu
|
||||
- allwinner,sun50i-h616-r-ccu
|
||||
|
||||
then:
|
||||
properties:
|
||||
|
@ -100,6 +103,7 @@ else:
|
|||
enum:
|
||||
- allwinner,sun50i-a100-ccu
|
||||
- allwinner,sun50i-h6-ccu
|
||||
- allwinner,sun50i-h616-ccu
|
||||
|
||||
then:
|
||||
properties:
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
* Clock and reset bindings for CSR atlas7
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "sirf,atlas7-car"
|
||||
- reg: Address and length of the register set
|
||||
- #clock-cells: Should be <1>
|
||||
- #reset-cells: Should be <1>
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell.
|
||||
The ID list atlas7_clks defined in drivers/clk/sirf/clk-atlas7.c
|
||||
|
||||
The reset consumer should specify the desired reset by having the reset
|
||||
ID in its "reset" phandle cell.
|
||||
The ID list atlas7_reset_unit defined in drivers/clk/sirf/clk-atlas7.c
|
||||
|
||||
Examples: Clock and reset controller node:
|
||||
|
||||
car: clock-controller@18620000 {
|
||||
compatible = "sirf,atlas7-car";
|
||||
reg = <0x18620000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
Examples: Consumers using clock or reset:
|
||||
|
||||
timer@10dc0000 {
|
||||
compatible = "sirf,macro-tick";
|
||||
reg = <0x10dc0000 0x1000>;
|
||||
clocks = <&car 54>;
|
||||
interrupts = <0 0 0>,
|
||||
<0 1 0>,
|
||||
<0 2 0>,
|
||||
<0 49 0>,
|
||||
<0 50 0>,
|
||||
<0 51 0>;
|
||||
};
|
||||
|
||||
uart1: uart@18020000 {
|
||||
cell-index = <1>;
|
||||
compatible = "sirf,macro-uart";
|
||||
reg = <0x18020000 0x1000>;
|
||||
clocks = <&clks 95>;
|
||||
interrupts = <0 18 0>;
|
||||
fifosize = <32>;
|
||||
};
|
||||
|
||||
vpp@13110000 {
|
||||
compatible = "sirf,prima2-vpp";
|
||||
reg = <0x13110000 0x10000>;
|
||||
interrupts = <0 31 0>;
|
||||
clocks = <&car 85>;
|
||||
resets = <&car 29>;
|
||||
};
|
|
@ -59,6 +59,12 @@ properties:
|
|||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
idt,xtal-load-femtofarads:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 9000
|
||||
maximum: 22760
|
||||
description: Optional load capacitor for XTAL1 and XTAL2
|
||||
|
||||
patternProperties:
|
||||
"^OUT[1-4]$":
|
||||
type: object
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Clock bindings for Freescale i.MX27
|
||||
|
||||
maintainers:
|
||||
- Fabio Estevam <fabio.estevam@nxp.com>
|
||||
- Fabio Estevam <festevam@gmail.com>
|
||||
|
||||
description: |
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Clock bindings for Freescale i.MX31
|
||||
|
||||
maintainers:
|
||||
- Fabio Estevam <fabio.estevam@nxp.com>
|
||||
- Fabio Estevam <festevam@gmail.com>
|
||||
|
||||
description: |
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
|
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Clock bindings for Freescale i.MX5
|
||||
|
||||
maintainers:
|
||||
- Fabio Estevam <fabio.estevam@nxp.com>
|
||||
- Fabio Estevam <festevam@gmail.com>
|
||||
|
||||
description: |
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/intel,easic-n5x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Intel SoCFPGA eASIC N5X platform clock controller binding
|
||||
|
||||
maintainers:
|
||||
- Dinh Nguyen <dinguyen@kernel.org>
|
||||
|
||||
description:
|
||||
The Intel eASIC N5X Clock controller is an integrated clock controller, which
|
||||
generates and supplies to all modules.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: intel,easic-n5x-clkmgr
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
# Clock controller node:
|
||||
- |
|
||||
clkmgr: clock-controller@ffd10000 {
|
||||
compatible = "intel,easic-n5x-clkmgr";
|
||||
reg = <0xffd10000 0x1000>;
|
||||
clocks = <&osc1>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/mstar,msc313-mpll.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MStar/Sigmastar MSC313 MPLL
|
||||
|
||||
maintainers:
|
||||
- Daniel Palmer <daniel@thingy.jp>
|
||||
|
||||
description: |
|
||||
The MStar/SigmaStar MSC313 and later ARMv7 chips have an MPLL block that
|
||||
takes the external xtal input and multiplies it to create a high
|
||||
frequency clock and divides that down into a number of clocks that
|
||||
peripherals use.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: mstar,msc313-mpll
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mpll@206000 {
|
||||
compatible = "mstar,msc313-mpll";
|
||||
reg = <0x206000 0x200>;
|
||||
#clock-cells = <1>;
|
||||
clocks = <&xtal>;
|
||||
};
|
|
@ -1,73 +0,0 @@
|
|||
* Clock bindings for CSR SiRFprimaII
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "sirf,prima2-clkc"
|
||||
- reg: Address and length of the register set
|
||||
- interrupts: Should contain clock controller interrupt
|
||||
- #clock-cells: Should be <1>
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. The following is a full list of prima2
|
||||
clocks and IDs.
|
||||
|
||||
Clock ID
|
||||
---------------------------
|
||||
rtc 0
|
||||
osc 1
|
||||
pll1 2
|
||||
pll2 3
|
||||
pll3 4
|
||||
mem 5
|
||||
sys 6
|
||||
security 7
|
||||
dsp 8
|
||||
gps 9
|
||||
mf 10
|
||||
io 11
|
||||
cpu 12
|
||||
uart0 13
|
||||
uart1 14
|
||||
uart2 15
|
||||
tsc 16
|
||||
i2c0 17
|
||||
i2c1 18
|
||||
spi0 19
|
||||
spi1 20
|
||||
pwmc 21
|
||||
efuse 22
|
||||
pulse 23
|
||||
dmac0 24
|
||||
dmac1 25
|
||||
nand 26
|
||||
audio 27
|
||||
usp0 28
|
||||
usp1 29
|
||||
usp2 30
|
||||
vip 31
|
||||
gfx 32
|
||||
mm 33
|
||||
lcd 34
|
||||
vpp 35
|
||||
mmc01 36
|
||||
mmc23 37
|
||||
mmc45 38
|
||||
usbpll 39
|
||||
usb0 40
|
||||
usb1 41
|
||||
|
||||
Examples:
|
||||
|
||||
clks: clock-controller@88000000 {
|
||||
compatible = "sirf,prima2-clkc";
|
||||
reg = <0x88000000 0x1000>;
|
||||
interrupts = <3>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
i2c0: i2c@b00e0000 {
|
||||
cell-index = <0>;
|
||||
compatible = "sirf,prima2-i2c";
|
||||
reg = <0xb00e0000 0x10000>;
|
||||
interrupts = <24>;
|
||||
clocks = <&clks 17>;
|
||||
};
|
|
@ -0,0 +1,51 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,a7pll.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm A7 PLL Binding
|
||||
|
||||
maintainers:
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
|
||||
description:
|
||||
The A7 PLL on the Qualcomm platforms like SDX55 is used to provide high
|
||||
frequency clock to the CPU.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sdx55-a7pll
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: board XO clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
a7pll: clock@17808000 {
|
||||
compatible = "qcom,sdx55-a7pll";
|
||||
reg = <0x17808000 0x1000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "bi_tcxo";
|
||||
#clock-cells = <0>;
|
||||
};
|
|
@ -0,0 +1,92 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,gcc-sc7280.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller Binding for SC7280
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module which supports the clocks, resets and
|
||||
power domains on SC7280.
|
||||
|
||||
See also:
|
||||
- dt-bindings/clock/qcom,gcc-sc7280.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,gcc-sc7280
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
- description: PCIE-0 pipe clock source
|
||||
- description: PCIE-1 pipe clock source
|
||||
- description: USF phy rx symbol 0 clock source
|
||||
- description: USF phy rx symbol 1 clock source
|
||||
- description: USF phy tx symbol 0 clock source
|
||||
- description: USB30 phy wrapper pipe clock source
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
- const: sleep_clk
|
||||
- const: pcie_0_pipe_clk
|
||||
- const: pcie_1_pipe_clk
|
||||
- const: ufs_phy_rx_symbol_0_clk
|
||||
- const: ufs_phy_rx_symbol_1_clk
|
||||
- const: ufs_phy_tx_symbol_0_clk
|
||||
- const: usb3_phy_wrapper_gcc_usb30_pipe_clk
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-sc7280";
|
||||
reg = <0x00100000 0x1f0000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK_A>,
|
||||
<&sleep_clk>,
|
||||
<&pcie_0_pipe_clk>, <&pcie_1_pipe_clk>,
|
||||
<&ufs_phy_rx_symbol_0_clk>, <&ufs_phy_rx_symbol_1_clk>,
|
||||
<&ufs_phy_tx_symbol_0_clk>,
|
||||
<&usb3_phy_wrapper_gcc_usb30_pipe_clk>;
|
||||
|
||||
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", "pcie_0_pipe_clk",
|
||||
"pcie_1_pipe_clk", "ufs_phy_rx_symbol_0_clk",
|
||||
"ufs_phy_rx_symbol_1_clk", "ufs_phy_tx_symbol_0_clk",
|
||||
"usb3_phy_wrapper_gcc_usb30_pipe_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -0,0 +1,76 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,gcc-sc8180x.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller Binding for SC8180x
|
||||
|
||||
maintainers:
|
||||
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module which supports the clocks, resets and
|
||||
power domains on SC8180x.
|
||||
|
||||
See also:
|
||||
- dt-bindings/clock/qcom,gcc-sc8180x.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,gcc-sc8180x
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Board active XO source
|
||||
- description: Sleep clock source
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
- const: sleep_clk
|
||||
|
||||
'#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
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-sc8180x";
|
||||
reg = <0x00100000 0x1f0000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&rpmhcc RPMH_CXO_CLK_A>,
|
||||
<&sleep_clk>;
|
||||
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -0,0 +1,96 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,gcc-sm8350.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller Binding for SM8350
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module which supports the clocks, resets and
|
||||
power domains on SM8350.
|
||||
|
||||
See also:
|
||||
- dt-bindings/clock/qcom,gcc-sm8350.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,gcc-sm8350
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Sleep clock source
|
||||
- description: PLL test clock source (Optional clock)
|
||||
- description: PCIE 0 Pipe clock source (Optional clock)
|
||||
- description: PCIE 1 Pipe clock source (Optional clock)
|
||||
- description: UFS card Rx symbol 0 clock source (Optional clock)
|
||||
- description: UFS card Rx symbol 1 clock source (Optional clock)
|
||||
- description: UFS card Tx symbol 0 clock source (Optional clock)
|
||||
- description: UFS phy Rx symbol 0 clock source (Optional clock)
|
||||
- description: UFS phy Rx symbol 1 clock source (Optional clock)
|
||||
- description: UFS phy Tx symbol 0 clock source (Optional clock)
|
||||
- description: USB3 phy wrapper pipe clock source (Optional clock)
|
||||
- description: USB3 phy sec pipe clock source (Optional clock)
|
||||
minItems: 2
|
||||
maxItems: 13
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: sleep_clk
|
||||
- const: core_bi_pll_test_se # Optional clock
|
||||
- const: pcie_0_pipe_clk # Optional clock
|
||||
- const: pcie_1_pipe_clk # Optional clock
|
||||
- const: ufs_card_rx_symbol_0_clk # Optional clock
|
||||
- const: ufs_card_rx_symbol_1_clk # Optional clock
|
||||
- const: ufs_card_tx_symbol_0_clk # Optional clock
|
||||
- const: ufs_phy_rx_symbol_0_clk # Optional clock
|
||||
- const: ufs_phy_rx_symbol_1_clk # Optional clock
|
||||
- const: ufs_phy_tx_symbol_0_clk # Optional clock
|
||||
- const: usb3_phy_wrapper_gcc_usb30_pipe_clk # Optional clock
|
||||
- const: usb3_uni_phy_sec_gcc_usb30_pipe_clk # Optional clock
|
||||
minItems: 2
|
||||
maxItems: 13
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-sm8350";
|
||||
reg = <0x00100000 0x1f0000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&sleep_clk>;
|
||||
clock-names = "bi_tcxo", "sleep_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
|
@ -0,0 +1,76 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,gpucc-sdm660.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Graphics Clock & Reset Controller Binding for SDM630 and SDM660
|
||||
|
||||
maintainers:
|
||||
- AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
|
||||
|
||||
description: |
|
||||
Qualcomm graphics clock control module which supports the clocks, resets and
|
||||
power domains on SDM630 and SDM660.
|
||||
|
||||
See also dt-bindings/clock/qcom,gpucc-sdm660.h.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,gpucc-sdm630
|
||||
- qcom,gpucc-sdm660
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: GPLL0 main gpu branch
|
||||
- description: GPLL0 divider gpu branch
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: xo
|
||||
- const: gcc_gpu_gpll0_clk
|
||||
- const: gcc_gpu_gpll0_div_clk
|
||||
|
||||
'#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'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sdm660.h>
|
||||
#include <dt-bindings/clock/qcom,rpmcc.h>
|
||||
|
||||
clock-controller@5065000 {
|
||||
compatible = "qcom,gpucc-sdm660";
|
||||
reg = <0x05065000 0x9038>;
|
||||
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
|
||||
<&gcc GCC_GPU_GPLL0_CLK>,
|
||||
<&gcc GCC_GPU_GPLL0_DIV_CLK>;
|
||||
clock-names = "xo", "gcc_gpu_gpll0_clk",
|
||||
"gcc_gpu_gpll0_div_clk";
|
||||
#clock-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -24,6 +24,8 @@ properties:
|
|||
- qcom,mmcc-msm8974
|
||||
- qcom,mmcc-msm8996
|
||||
- qcom,mmcc-msm8998
|
||||
- qcom,mmcc-sdm630
|
||||
- qcom,mmcc-sdm660
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
@ -18,6 +18,8 @@ properties:
|
|||
compatible:
|
||||
enum:
|
||||
- qcom,sc7180-rpmh-clk
|
||||
- qcom,sc7280-rpmh-clk
|
||||
- qcom,sc8180x-rpmh-clk
|
||||
- qcom,sdm845-rpmh-clk
|
||||
- qcom,sdx55-rpmh-clk
|
||||
- qcom,sm8150-rpmh-clk
|
||||
|
|
|
@ -35,6 +35,9 @@ properties:
|
|||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r8a774a1-rcar-usb2-clock-sel # RZ/G2M
|
||||
- renesas,r8a774b1-rcar-usb2-clock-sel # RZ/G2N
|
||||
- renesas,r8a774e1-rcar-usb2-clock-sel # RZ/G2H
|
||||
- renesas,r8a7795-rcar-usb2-clock-sel # R-Car H3
|
||||
- renesas,r8a7796-rcar-usb2-clock-sel # R-Car M3-W
|
||||
- renesas,r8a77961-rcar-usb2-clock-sel # R-Car M3-W+
|
||||
|
|
|
@ -28,6 +28,8 @@ Optional properties:
|
|||
- clock-frequency: Output frequency to generate. This defines the output
|
||||
frequency set during boot. It can be reprogrammed during
|
||||
runtime through the common clock framework.
|
||||
- silabs,skip-recall: Do not perform NVM->RAM recall operation. It will rely
|
||||
on hardware loading of RAM from NVM at power on.
|
||||
|
||||
Example:
|
||||
si570: clock-generator@5d {
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
Clock bindings for ST-Ericsson U300 System Controller Clocks
|
||||
|
||||
Bindings for the gated system controller clocks:
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "stericsson,u300-syscon-clk"
|
||||
- #clock-cells: must be <0>
|
||||
- clock-type: specifies the type of clock:
|
||||
0 = slow clock
|
||||
1 = fast clock
|
||||
2 = rest/remaining clock
|
||||
- clock-id: specifies the clock in the type range
|
||||
|
||||
Optional properties:
|
||||
- clocks: parent clock(s)
|
||||
|
||||
The available clocks per type are as follows:
|
||||
|
||||
Type: ID: Clock:
|
||||
-------------------
|
||||
0 0 Slow peripheral bridge clock
|
||||
0 1 UART0 clock
|
||||
0 4 GPIO clock
|
||||
0 6 RTC clock
|
||||
0 7 Application timer clock
|
||||
0 8 Access timer clock
|
||||
|
||||
1 0 Fast peripheral bridge clock
|
||||
1 1 I2C bus 0 clock
|
||||
1 2 I2C bus 1 clock
|
||||
1 5 MMC interface peripheral (silicon) clock
|
||||
1 6 SPI clock
|
||||
|
||||
2 3 CPU clock
|
||||
2 4 DMA controller clock
|
||||
2 5 External Memory Interface (EMIF) clock
|
||||
2 6 NAND flask interface clock
|
||||
2 8 XGAM graphics engine clock
|
||||
2 9 Shared External Memory Interface (SEMI) clock
|
||||
2 10 AHB Subsystem Bridge clock
|
||||
2 12 Interrupt controller clock
|
||||
|
||||
Example:
|
||||
|
||||
gpio_clk: gpio_clk@13M {
|
||||
#clock-cells = <0>;
|
||||
compatible = "stericsson,u300-syscon-clk";
|
||||
clock-type = <0>; /* Slow */
|
||||
clock-id = <4>;
|
||||
clocks = <&slow_clk>;
|
||||
};
|
||||
|
||||
gpio: gpio@c0016000 {
|
||||
compatible = "stericsson,gpio-coh901";
|
||||
(...)
|
||||
clocks = <&gpio_clk>;
|
||||
};
|
||||
|
||||
|
||||
Bindings for the MMC/SD card clock:
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "stericsson,u300-syscon-mclk"
|
||||
- #clock-cells: must be <0>
|
||||
|
||||
Optional properties:
|
||||
- clocks: parent clock(s)
|
||||
|
||||
mmc_mclk: mmc_mclk {
|
||||
#clock-cells = <0>;
|
||||
compatible = "stericsson,u300-syscon-mclk";
|
||||
clocks = <&mmc_pclk>;
|
||||
};
|
||||
|
||||
mmcsd: mmcsd@c0001000 {
|
||||
compatible = "arm,pl18x", "arm,primecell";
|
||||
clocks = <&mmc_pclk>, <&mmc_mclk>;
|
||||
clock-names = "apb_pclk", "mclk";
|
||||
(...)
|
||||
};
|
|
@ -1,23 +0,0 @@
|
|||
* Sigma Designs Tango4 Clock Generator
|
||||
|
||||
The Tango4 clock generator outputs cpu_clk and sys_clk (the latter is used
|
||||
for RAM and various peripheral devices). The clock binding described here
|
||||
is applicable to all Tango4 SoCs.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be "sigma,tango4-clkgen".
|
||||
- reg: physical base address of the device and length of memory mapped region.
|
||||
- clocks: phandle of the input clock (crystal oscillator).
|
||||
- clock-output-names: should be "cpuclk" and "sysclk".
|
||||
- #clock-cells: should be set to 1.
|
||||
|
||||
Example:
|
||||
|
||||
clkgen: clkgen@10000 {
|
||||
compatible = "sigma,tango4-clkgen";
|
||||
reg = <0x10000 0x40>;
|
||||
clocks = <&xtal>;
|
||||
clock-output-names = "cpuclk", "sysclk";
|
||||
#clock-cells = <1>;
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
Device Tree Clock bindings for ZTE zx296702
|
||||
|
||||
This binding uses the common clock binding[1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be one of the following:
|
||||
"zte,zx296702-topcrm-clk":
|
||||
zx296702 top clock selection, divider and gating
|
||||
|
||||
"zte,zx296702-lsp0crpm-clk" and
|
||||
"zte,zx296702-lsp1crpm-clk":
|
||||
zx296702 device level clock selection and gating
|
||||
|
||||
- reg: Address and length of the register set
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296702-clock.h
|
||||
for the full list of zx296702 clock IDs.
|
||||
|
||||
|
||||
topclk: topcrm@09800000 {
|
||||
compatible = "zte,zx296702-topcrm-clk";
|
||||
reg = <0x09800000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
uart0: serial@09405000 {
|
||||
compatible = "zte,zx296702-uart";
|
||||
reg = <0x09405000 0x1000>;
|
||||
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&lsp1clk ZX296702_UART0_PCLK>;
|
||||
};
|
|
@ -1,37 +0,0 @@
|
|||
Device Tree Clock bindings for ZTE zx296718
|
||||
|
||||
This binding uses the common clock binding[1].
|
||||
|
||||
[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
||||
Required properties:
|
||||
- compatible : shall be one of the following:
|
||||
"zte,zx296718-topcrm":
|
||||
zx296718 top clock selection, divider and gating
|
||||
|
||||
"zte,zx296718-lsp0crm" and
|
||||
"zte,zx296718-lsp1crm":
|
||||
zx296718 device level clock selection and gating
|
||||
|
||||
"zte,zx296718-audiocrm":
|
||||
zx296718 audio clock selection, divider and gating
|
||||
|
||||
- reg: Address and length of the register set
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/zx296718-clock.h
|
||||
for the full list of zx296718 clock IDs.
|
||||
|
||||
|
||||
topclk: topcrm@1461000 {
|
||||
compatible = "zte,zx296718-topcrm-clk";
|
||||
reg = <0x01461000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
usbphy0:usb-phy0 {
|
||||
compatible = "zte,zx296718-usb-phy";
|
||||
#phy-cells = <0>;
|
||||
clocks = <&topclk USB20_PHY_CLK>;
|
||||
clock-names = "phyclk";
|
||||
};
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -2126,10 +2126,13 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
|||
S: Maintained
|
||||
W: http://linux-chenxing.org/
|
||||
F: Documentation/devicetree/bindings/arm/mstar/*
|
||||
F: Documentation/devicetree/bindings/clock/mstar,msc313-mpll.yaml
|
||||
F: Documentation/devicetree/bindings/gpio/mstar,msc313-gpio.yaml
|
||||
F: arch/arm/boot/dts/mstar-*
|
||||
F: arch/arm/mach-mstar/
|
||||
F: drivers/clk/mstar/
|
||||
F: drivers/gpio/gpio-msc313.c
|
||||
F: include/dt-bindings/clock/mstar-*
|
||||
F: include/dt-bindings/gpio/msc313-gpio.h
|
||||
|
||||
ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
|
||||
|
@ -12774,6 +12777,13 @@ F: drivers/iio/gyro/fxas21002c_core.c
|
|||
F: drivers/iio/gyro/fxas21002c_i2c.c
|
||||
F: drivers/iio/gyro/fxas21002c_spi.c
|
||||
|
||||
NXP i.MX CLOCK DRIVERS
|
||||
M: Abel Vesa <abel.vesa@nxp.com>
|
||||
L: linux-clk@vger.kernel.org
|
||||
L: linux-imx@nxp.com
|
||||
S: Maintained
|
||||
F: drivers/clk/imx/
|
||||
|
||||
NXP i.MX 8MQ DCSS DRIVER
|
||||
M: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com>
|
||||
R: Lucas Stach <l.stach@pengutronix.de>
|
||||
|
|
|
@ -85,7 +85,6 @@ void imx_anatop_pre_suspend(void);
|
|||
void imx_anatop_post_resume(void);
|
||||
int imx6_set_lpm(enum mxc_cpu_pwr_mode mode);
|
||||
void imx6_set_int_mem_clk_lpm(bool enable);
|
||||
void imx6sl_set_wait_clk(bool enter);
|
||||
int imx_mmdc_get_ddr_type(void);
|
||||
int imx7ulp_set_lpm(enum ulp_cpu_pwr_mode mode);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (C) 2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/clk/imx.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/cpuidle.h>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright 2011 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/clk/imx.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -43,16 +43,4 @@ void spear13xx_cpu_die(unsigned int cpu);
|
|||
|
||||
extern const struct smp_operations spear13xx_smp_ops;
|
||||
|
||||
#ifdef CONFIG_MACH_SPEAR1310
|
||||
void __init spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base);
|
||||
#else
|
||||
static inline void spear1310_clk_init(void __iomem *misc_base, void __iomem *ras_base) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MACH_SPEAR1340
|
||||
void __init spear1340_clk_init(void __iomem *misc_base);
|
||||
#else
|
||||
static inline void spear1340_clk_init(void __iomem *misc_base) {}
|
||||
#endif
|
||||
|
||||
#endif /* __MACH_GENERIC_H */
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <linux/amba/pl022.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk/spear.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
|
|
|
@ -247,7 +247,8 @@ config CLK_TWL6040
|
|||
|
||||
config COMMON_CLK_AXI_CLKGEN
|
||||
tristate "AXI clkgen driver"
|
||||
depends on ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST
|
||||
depends on HAS_IOMEM || COMPILE_TEST
|
||||
depends on OF
|
||||
help
|
||||
Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
|
||||
FPGAs. It is commonly used in Analog Devices' reference designs.
|
||||
|
@ -379,6 +380,7 @@ source "drivers/clk/ingenic/Kconfig"
|
|||
source "drivers/clk/keystone/Kconfig"
|
||||
source "drivers/clk/mediatek/Kconfig"
|
||||
source "drivers/clk/meson/Kconfig"
|
||||
source "drivers/clk/mstar/Kconfig"
|
||||
source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/renesas/Kconfig"
|
||||
|
@ -392,6 +394,7 @@ source "drivers/clk/tegra/Kconfig"
|
|||
source "drivers/clk/ti/Kconfig"
|
||||
source "drivers/clk/uniphier/Kconfig"
|
||||
source "drivers/clk/x86/Kconfig"
|
||||
source "drivers/clk/xilinx/Kconfig"
|
||||
source "drivers/clk/zynqmp/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -27,7 +27,6 @@ obj-$(CONFIG_COMMON_CLK_CDCE706) += clk-cdce706.o
|
|||
obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
|
||||
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_ARCH_SPARX5) += clk-sparx5.o
|
||||
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
|
||||
obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o
|
||||
|
@ -63,9 +62,7 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
|
|||
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
|
||||
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
|
||||
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
|
||||
obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o
|
||||
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
|
||||
obj-$(CONFIG_ARCH_U300) += clk-u300.o
|
||||
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
|
||||
obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
|
||||
obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
|
||||
|
@ -95,6 +92,7 @@ obj-$(CONFIG_MACH_PIC32) += microchip/
|
|||
ifeq ($(CONFIG_COMMON_CLK), y)
|
||||
obj-$(CONFIG_ARCH_MMP) += mmp/
|
||||
endif
|
||||
obj-y += mstar/
|
||||
obj-y += mvebu/
|
||||
obj-$(CONFIG_ARCH_MXS) += mxs/
|
||||
obj-$(CONFIG_COMMON_CLK_NXP) += nxp/
|
||||
|
@ -105,7 +103,6 @@ obj-y += renesas/
|
|||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_CLK_SIFIVE) += sifive/
|
||||
obj-$(CONFIG_ARCH_SIRF) += sirf/
|
||||
obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
|
||||
obj-$(CONFIG_ARCH_AGILEX) += socfpga/
|
||||
obj-$(CONFIG_ARCH_STRATIX10) += socfpga/
|
||||
|
@ -122,6 +119,6 @@ obj-y += versatile/
|
|||
ifeq ($(CONFIG_COMMON_CLK), y)
|
||||
obj-$(CONFIG_X86) += x86/
|
||||
endif
|
||||
obj-$(CONFIG_ARCH_ZX) += zte/
|
||||
obj-y += xilinx/
|
||||
obj-$(CONFIG_ARCH_ZYNQ) += zynq/
|
||||
obj-$(CONFIG_COMMON_CLK_ZYNQMP) += zynqmp/
|
||||
|
|
|
@ -215,5 +215,4 @@ err_free:
|
|||
* deferring properly. Once this is fixed, this can be switched to a platform
|
||||
* driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91rm9200_pmc, "atmel,at91rm9200-pmc",
|
||||
at91rm9200_pmc_setup);
|
||||
CLK_OF_DECLARE(at91rm9200_pmc, "atmel,at91rm9200-pmc", at91rm9200_pmc_setup);
|
||||
|
|
|
@ -491,26 +491,26 @@ static void __init at91sam9260_pmc_setup(struct device_node *np)
|
|||
{
|
||||
at91sam926x_pmc_setup(np, &at91sam9260_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc",
|
||||
at91sam9260_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9260_pmc, "atmel,at91sam9260-pmc", at91sam9260_pmc_setup);
|
||||
|
||||
static void __init at91sam9261_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam926x_pmc_setup(np, &at91sam9261_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc",
|
||||
at91sam9261_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9261_pmc, "atmel,at91sam9261-pmc", at91sam9261_pmc_setup);
|
||||
|
||||
static void __init at91sam9263_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam926x_pmc_setup(np, &at91sam9263_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc",
|
||||
at91sam9263_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9263_pmc, "atmel,at91sam9263-pmc", at91sam9263_pmc_setup);
|
||||
|
||||
static void __init at91sam9g20_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam926x_pmc_setup(np, &at91sam9g20_data);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc",
|
||||
at91sam9g20_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9g20_pmc, "atmel,at91sam9g20-pmc", at91sam9g20_pmc_setup);
|
||||
|
|
|
@ -228,5 +228,4 @@ err_free:
|
|||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g45_pmc, "atmel,at91sam9g45-pmc",
|
||||
at91sam9g45_pmc_setup);
|
||||
CLK_OF_DECLARE(at91sam9g45_pmc, "atmel,at91sam9g45-pmc", at91sam9g45_pmc_setup);
|
||||
|
|
|
@ -255,5 +255,4 @@ err_free:
|
|||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9n12_pmc, "atmel,at91sam9n12-pmc",
|
||||
at91sam9n12_pmc_setup);
|
||||
CLK_OF_DECLARE(at91sam9n12_pmc, "atmel,at91sam9n12-pmc", at91sam9n12_pmc_setup);
|
||||
|
|
|
@ -186,4 +186,5 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
|
|||
err_free:
|
||||
kfree(at91sam9rl_pmc);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
|
||||
|
|
|
@ -302,33 +302,33 @@ static void __init at91sam9g15_pmc_setup(struct device_node *np)
|
|||
{
|
||||
at91sam9x5_pmc_setup(np, at91sam9g15_periphck, true);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g15_pmc, "atmel,at91sam9g15-pmc",
|
||||
at91sam9g15_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9g15_pmc, "atmel,at91sam9g15-pmc", at91sam9g15_pmc_setup);
|
||||
|
||||
static void __init at91sam9g25_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam9x5_pmc_setup(np, at91sam9g25_periphck, false);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g25_pmc, "atmel,at91sam9g25-pmc",
|
||||
at91sam9g25_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9g25_pmc, "atmel,at91sam9g25-pmc", at91sam9g25_pmc_setup);
|
||||
|
||||
static void __init at91sam9g35_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam9x5_pmc_setup(np, at91sam9g35_periphck, true);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g35_pmc, "atmel,at91sam9g35-pmc",
|
||||
at91sam9g35_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9g35_pmc, "atmel,at91sam9g35-pmc", at91sam9g35_pmc_setup);
|
||||
|
||||
static void __init at91sam9x25_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam9x5_pmc_setup(np, at91sam9x25_periphck, false);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9x25_pmc, "atmel,at91sam9x25-pmc",
|
||||
at91sam9x25_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9x25_pmc, "atmel,at91sam9x25-pmc", at91sam9x25_pmc_setup);
|
||||
|
||||
static void __init at91sam9x35_pmc_setup(struct device_node *np)
|
||||
{
|
||||
at91sam9x5_pmc_setup(np, at91sam9x35_periphck, true);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9x35_pmc, "atmel,at91sam9x35-pmc",
|
||||
at91sam9x35_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(at91sam9x35_pmc, "atmel,at91sam9x35-pmc", at91sam9x35_pmc_setup);
|
||||
|
|
|
@ -372,4 +372,5 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
|
|||
err_free:
|
||||
kfree(sama5d2_pmc);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup);
|
||||
|
|
|
@ -255,4 +255,4 @@ err_free:
|
|||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup);
|
||||
CLK_OF_DECLARE(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup);
|
||||
|
|
|
@ -286,4 +286,5 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
|
|||
err_free:
|
||||
kfree(sama5d4_pmc);
|
||||
}
|
||||
CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
|
||||
|
||||
CLK_OF_DECLARE(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup);
|
||||
|
|
|
@ -704,7 +704,7 @@ static const struct clk_ops iproc_clk_ops = {
|
|||
.set_rate = iproc_clk_set_rate,
|
||||
};
|
||||
|
||||
/**
|
||||
/*
|
||||
* Some PLLs require the PLL SW override bit to be set before changes can be
|
||||
* applied to the PLL
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#define ASPEED_G6_NUM_CLKS 71
|
||||
|
||||
#define ASPEED_G6_SILICON_REV 0x004
|
||||
#define ASPEED_G6_SILICON_REV 0x014
|
||||
#define CHIP_REVISION_ID GENMASK(23, 16)
|
||||
|
||||
#define ASPEED_G6_RESET_CTRL 0x040
|
||||
#define ASPEED_G6_RESET_CTRL2 0x050
|
||||
|
@ -190,18 +191,34 @@ static struct clk_hw *ast2600_calc_pll(const char *name, u32 val)
|
|||
static struct clk_hw *ast2600_calc_apll(const char *name, u32 val)
|
||||
{
|
||||
unsigned int mult, div;
|
||||
u32 chip_id = readl(scu_g6_base + ASPEED_G6_SILICON_REV);
|
||||
|
||||
if (val & BIT(20)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
if (((chip_id & CHIP_REVISION_ID) >> 16) >= 2) {
|
||||
if (val & BIT(24)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
} else {
|
||||
/* F = 25Mhz * [(m + 1) / (n + 1)] / (p + 1) */
|
||||
u32 m = val & 0x1fff;
|
||||
u32 n = (val >> 13) & 0x3f;
|
||||
u32 p = (val >> 19) & 0xf;
|
||||
|
||||
mult = (m + 1);
|
||||
div = (n + 1) * (p + 1);
|
||||
}
|
||||
} else {
|
||||
/* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
|
||||
u32 m = (val >> 5) & 0x3f;
|
||||
u32 od = (val >> 4) & 0x1;
|
||||
u32 n = val & 0xf;
|
||||
if (val & BIT(20)) {
|
||||
/* Pass through mode */
|
||||
mult = div = 1;
|
||||
} else {
|
||||
/* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
|
||||
u32 m = (val >> 5) & 0x3f;
|
||||
u32 od = (val >> 4) & 0x1;
|
||||
u32 n = val & 0xf;
|
||||
|
||||
mult = (2 - od) * (m + 2);
|
||||
div = n + 1;
|
||||
mult = (2 - od) * (m + 2);
|
||||
div = n + 1;
|
||||
}
|
||||
}
|
||||
return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
|
||||
mult, div);
|
||||
|
|
|
@ -108,6 +108,13 @@ static uint32_t axi_clkgen_lookup_lock(unsigned int m)
|
|||
return 0x1f1f00fa;
|
||||
}
|
||||
|
||||
static const struct axi_clkgen_limits axi_clkgen_zynqmp_default_limits = {
|
||||
.fpfd_min = 10000,
|
||||
.fpfd_max = 450000,
|
||||
.fvco_min = 800000,
|
||||
.fvco_max = 1600000,
|
||||
};
|
||||
|
||||
static const struct axi_clkgen_limits axi_clkgen_zynq_default_limits = {
|
||||
.fpfd_min = 10000,
|
||||
.fpfd_max = 300000,
|
||||
|
@ -503,7 +510,6 @@ static int axi_clkgen_probe(struct platform_device *pdev)
|
|||
struct clk_init_data init;
|
||||
const char *parent_names[2];
|
||||
const char *clk_name;
|
||||
struct resource *mem;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -515,8 +521,7 @@ static int axi_clkgen_probe(struct platform_device *pdev)
|
|||
if (!axi_clkgen)
|
||||
return -ENOMEM;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
axi_clkgen->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(axi_clkgen->base))
|
||||
return PTR_ERR(axi_clkgen->base);
|
||||
|
||||
|
@ -560,6 +565,10 @@ static int axi_clkgen_remove(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
static const struct of_device_id axi_clkgen_ids[] = {
|
||||
{
|
||||
.compatible = "adi,zynqmp-axi-clkgen-2.00.a",
|
||||
.data = &axi_clkgen_zynqmp_default_limits,
|
||||
},
|
||||
{
|
||||
.compatible = "adi,axi-clkgen-2.00.a",
|
||||
.data = &axi_clkgen_zynq_default_limits,
|
||||
|
|
|
@ -31,12 +31,12 @@ struct bd718xx_clk {
|
|||
u8 reg;
|
||||
u8 mask;
|
||||
struct platform_device *pdev;
|
||||
struct rohm_regmap_dev *mfd;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
|
||||
{
|
||||
return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status);
|
||||
return regmap_update_bits(c->regmap, c->reg, c->mask, status);
|
||||
}
|
||||
|
||||
static void bd71837_clk_disable(struct clk_hw *hw)
|
||||
|
@ -62,7 +62,7 @@ static int bd71837_clk_is_enabled(struct clk_hw *hw)
|
|||
int rval;
|
||||
struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
|
||||
|
||||
rval = regmap_read(c->mfd->regmap, c->reg, &enabled);
|
||||
rval = regmap_read(c->regmap, c->reg, &enabled);
|
||||
|
||||
if (rval)
|
||||
return rval;
|
||||
|
@ -82,7 +82,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
|||
int rval = -ENOMEM;
|
||||
const char *parent_clk;
|
||||
struct device *parent = pdev->dev.parent;
|
||||
struct rohm_regmap_dev *mfd = dev_get_drvdata(parent);
|
||||
struct clk_init_data init = {
|
||||
.name = "bd718xx-32k-out",
|
||||
.ops = &bd71837_clk_ops,
|
||||
|
@ -93,6 +92,10 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
|||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
c->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!c->regmap)
|
||||
return -ENODEV;
|
||||
|
||||
init.num_parents = 1;
|
||||
parent_clk = of_clk_get_parent_name(parent->of_node, 0);
|
||||
|
||||
|
@ -119,7 +122,6 @@ static int bd71837_clk_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "Unknown clk chip\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
c->mfd = mfd;
|
||||
c->pdev = pdev;
|
||||
c->hw.init = &init;
|
||||
|
||||
|
|
|
@ -494,8 +494,13 @@ struct clk_hw *__clk_hw_register_divider(struct device *dev,
|
|||
else
|
||||
init.ops = &clk_divider_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_divider assignments */
|
||||
div->reg = reg;
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2013 Pengutronix
|
||||
* Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
|
||||
*/
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/efm32-cmu.h>
|
||||
|
||||
#define CMU_HFPERCLKEN0 0x44
|
||||
#define CMU_MAX_CLKS 37
|
||||
|
||||
static struct clk_hw_onecell_data *clk_data;
|
||||
|
||||
static void __init efm32gg_cmu_init(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
void __iomem *base;
|
||||
struct clk_hw **hws;
|
||||
|
||||
clk_data = kzalloc(struct_size(clk_data, hws, CMU_MAX_CLKS),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!clk_data)
|
||||
return;
|
||||
|
||||
hws = clk_data->hws;
|
||||
|
||||
for (i = 0; i < CMU_MAX_CLKS; ++i)
|
||||
hws[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
base = of_iomap(np, 0);
|
||||
if (!base) {
|
||||
pr_warn("Failed to map address range for efm32gg,cmu node\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hws[clk_HFXO] = clk_hw_register_fixed_rate(NULL, "HFXO", NULL, 0,
|
||||
48000000);
|
||||
|
||||
hws[clk_HFPERCLKUSART0] = clk_hw_register_gate(NULL, "HFPERCLK.USART0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 0, 0, NULL);
|
||||
hws[clk_HFPERCLKUSART1] = clk_hw_register_gate(NULL, "HFPERCLK.USART1",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 1, 0, NULL);
|
||||
hws[clk_HFPERCLKUSART2] = clk_hw_register_gate(NULL, "HFPERCLK.USART2",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 2, 0, NULL);
|
||||
hws[clk_HFPERCLKUART0] = clk_hw_register_gate(NULL, "HFPERCLK.UART0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 3, 0, NULL);
|
||||
hws[clk_HFPERCLKUART1] = clk_hw_register_gate(NULL, "HFPERCLK.UART1",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 4, 0, NULL);
|
||||
hws[clk_HFPERCLKTIMER0] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 5, 0, NULL);
|
||||
hws[clk_HFPERCLKTIMER1] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER1",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 6, 0, NULL);
|
||||
hws[clk_HFPERCLKTIMER2] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER2",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 7, 0, NULL);
|
||||
hws[clk_HFPERCLKTIMER3] = clk_hw_register_gate(NULL, "HFPERCLK.TIMER3",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 8, 0, NULL);
|
||||
hws[clk_HFPERCLKACMP0] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 9, 0, NULL);
|
||||
hws[clk_HFPERCLKACMP1] = clk_hw_register_gate(NULL, "HFPERCLK.ACMP1",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 10, 0, NULL);
|
||||
hws[clk_HFPERCLKI2C0] = clk_hw_register_gate(NULL, "HFPERCLK.I2C0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 11, 0, NULL);
|
||||
hws[clk_HFPERCLKI2C1] = clk_hw_register_gate(NULL, "HFPERCLK.I2C1",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 12, 0, NULL);
|
||||
hws[clk_HFPERCLKGPIO] = clk_hw_register_gate(NULL, "HFPERCLK.GPIO",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 13, 0, NULL);
|
||||
hws[clk_HFPERCLKVCMP] = clk_hw_register_gate(NULL, "HFPERCLK.VCMP",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 14, 0, NULL);
|
||||
hws[clk_HFPERCLKPRS] = clk_hw_register_gate(NULL, "HFPERCLK.PRS",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 15, 0, NULL);
|
||||
hws[clk_HFPERCLKADC0] = clk_hw_register_gate(NULL, "HFPERCLK.ADC0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 16, 0, NULL);
|
||||
hws[clk_HFPERCLKDAC0] = clk_hw_register_gate(NULL, "HFPERCLK.DAC0",
|
||||
"HFXO", 0, base + CMU_HFPERCLKEN0, 17, 0, NULL);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
|
||||
}
|
||||
CLK_OF_DECLARE(efm32ggcmu, "efm32gg,cmu", efm32gg_cmu_init);
|
|
@ -64,10 +64,16 @@ const struct clk_ops clk_fixed_factor_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
|
||||
|
||||
static void devm_clk_hw_register_fixed_factor_release(struct device *dev, void *res)
|
||||
{
|
||||
clk_hw_unregister_fixed_factor(&((struct clk_fixed_factor *)res)->hw);
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
__clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
||||
const char *name, const char *parent_name, int index,
|
||||
unsigned long flags, unsigned int mult, unsigned int div)
|
||||
unsigned long flags, unsigned int mult, unsigned int div,
|
||||
bool devm)
|
||||
{
|
||||
struct clk_fixed_factor *fix;
|
||||
struct clk_init_data init = { };
|
||||
|
@ -75,7 +81,15 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
|||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
|
||||
/* You can't use devm without a dev */
|
||||
if (devm && !dev)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (devm)
|
||||
fix = devres_alloc(devm_clk_hw_register_fixed_factor_release,
|
||||
sizeof(*fix), GFP_KERNEL);
|
||||
else
|
||||
fix = kmalloc(sizeof(*fix), GFP_KERNEL);
|
||||
if (!fix)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -99,9 +113,13 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np,
|
|||
else
|
||||
ret = of_clk_hw_register(np, hw);
|
||||
if (ret) {
|
||||
kfree(fix);
|
||||
if (devm)
|
||||
devres_free(fix);
|
||||
else
|
||||
kfree(fix);
|
||||
hw = ERR_PTR(ret);
|
||||
}
|
||||
} else if (devm)
|
||||
devres_add(dev, fix);
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
@ -111,7 +129,7 @@ struct clk_hw *clk_hw_register_fixed_factor(struct device *dev,
|
|||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
|
||||
flags, mult, div);
|
||||
flags, mult, div, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor);
|
||||
|
||||
|
@ -153,6 +171,15 @@ void clk_hw_unregister_fixed_factor(struct clk_hw *hw)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor);
|
||||
|
||||
struct clk_hw *devm_clk_hw_register_fixed_factor(struct device *dev,
|
||||
const char *name, const char *parent_name, unsigned long flags,
|
||||
unsigned int mult, unsigned int div)
|
||||
{
|
||||
return __clk_hw_register_fixed_factor(dev, NULL, name, parent_name, -1,
|
||||
flags, mult, div, true);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_register_fixed_factor);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id set_rate_parent_matches[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-pll3-2x-clk" },
|
||||
|
@ -185,7 +212,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
|
|||
flags |= CLK_SET_RATE_PARENT;
|
||||
|
||||
hw = __clk_hw_register_fixed_factor(NULL, node, clk_name, NULL, 0,
|
||||
flags, mult, div);
|
||||
flags, mult, div, false);
|
||||
if (IS_ERR(hw)) {
|
||||
/*
|
||||
* Clear OF_POPULATED flag so that clock registration can be
|
||||
|
|
|
@ -55,7 +55,7 @@ static void __init of_fixed_mmio_clk_setup(struct device_node *node)
|
|||
}
|
||||
CLK_OF_DECLARE(fixed_mmio_clk, "fixed-mmio-clock", of_fixed_mmio_clk_setup);
|
||||
|
||||
/**
|
||||
/*
|
||||
* This is not executed when of_fixed_mmio_clk_setup succeeded.
|
||||
*/
|
||||
static int of_fixed_mmio_clk_probe(struct platform_device *pdev)
|
||||
|
|
|
@ -361,13 +361,6 @@ static const struct npcm7xx_clk_mux_data npcm7xx_muxes[] __initconst = {
|
|||
dvcssel_mux_parents, ARRAY_SIZE(dvcssel_mux_parents), 0, -1},
|
||||
};
|
||||
|
||||
/* fixed ratio dividers (no register): */
|
||||
static const struct npcm7xx_clk_div_fixed_data npcm7xx_divs_fx[] __initconst = {
|
||||
{ 1, 2, NPCM7XX_CLK_S_MC, NPCM7XX_CLK_S_MC_MUX, 0, NPCM7XX_CLK_MC},
|
||||
{ 1, 2, NPCM7XX_CLK_S_PLL1_DIV2, NPCM7XX_CLK_S_PLL1, 0, -1},
|
||||
{ 1, 2, NPCM7XX_CLK_S_PLL2_DIV2, NPCM7XX_CLK_S_PLL2, 0, -1},
|
||||
};
|
||||
|
||||
/* configurable dividers: */
|
||||
static const struct npcm7xx_clk_div_data npcm7xx_divs[] __initconst = {
|
||||
{NPCM7XX_CLKDIV1, 28, 3, NPCM7XX_CLK_S_ADC,
|
||||
|
@ -435,107 +428,6 @@ static const struct npcm7xx_clk_div_data npcm7xx_divs[] __initconst = {
|
|||
|
||||
};
|
||||
|
||||
static const struct npcm7xx_clk_gate_data npcm7xx_gates[] __initconst = {
|
||||
{NPCM7XX_CLKEN1, 31, "smb1-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 30, "smb0-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 29, "smb7-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 28, "smb6-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 27, "adc-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 26, "wdt-gate", NPCM7XX_CLK_S_TIMER, 0},
|
||||
{NPCM7XX_CLKEN1, 25, "usbdev3-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 24, "usbdev6-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 23, "usbdev5-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 22, "usbdev4-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 21, "emc2-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 20, "timer5_9-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 19, "timer0_4-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 18, "pwmm0-gate", NPCM7XX_CLK_S_APB3, 0},
|
||||
{NPCM7XX_CLKEN1, 17, "huart-gate", NPCM7XX_CLK_S_UART, 0},
|
||||
{NPCM7XX_CLKEN1, 16, "smb5-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 15, "smb4-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 14, "smb3-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 13, "smb2-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN1, 12, "mc-gate", NPCM7XX_CLK_S_MC, 0},
|
||||
{NPCM7XX_CLKEN1, 11, "uart01-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 10, "aes-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 9, "peci-gate", NPCM7XX_CLK_S_APB3, 0},
|
||||
{NPCM7XX_CLKEN1, 8, "usbdev2-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 7, "uart23-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 6, "emc1-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 5, "usbdev1-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 4, "shm-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
/* bit 3 is reserved */
|
||||
{NPCM7XX_CLKEN1, 2, "kcs-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN1, 1, "spi3-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN1, 0, "spi0-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
|
||||
{NPCM7XX_CLKEN2, 31, "cp-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 30, "tock-gate", NPCM7XX_CLK_S_TOCK, 0},
|
||||
/* bit 29 is reserved */
|
||||
{NPCM7XX_CLKEN2, 28, "gmac1-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 27, "usbif-gate", NPCM7XX_CLK_S_USBIF, 0},
|
||||
{NPCM7XX_CLKEN2, 26, "usbhost-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 25, "gmac2-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
/* bit 24 is reserved */
|
||||
{NPCM7XX_CLKEN2, 23, "pspi2-gate", NPCM7XX_CLK_S_APB5, 0},
|
||||
{NPCM7XX_CLKEN2, 22, "pspi1-gate", NPCM7XX_CLK_S_APB5, 0},
|
||||
{NPCM7XX_CLKEN2, 21, "3des-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
/* bit 20 is reserved */
|
||||
{NPCM7XX_CLKEN2, 19, "siox2-gate", NPCM7XX_CLK_S_APB3, 0},
|
||||
{NPCM7XX_CLKEN2, 18, "siox1-gate", NPCM7XX_CLK_S_APB3, 0},
|
||||
/* bit 17 is reserved */
|
||||
{NPCM7XX_CLKEN2, 16, "fuse-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
/* bit 15 is reserved */
|
||||
{NPCM7XX_CLKEN2, 14, "vcd-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 13, "ece-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 12, "vdma-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 11, "ahbpcibrg-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 10, "gfxsys-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN2, 9, "sdhc-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 8, "mmc-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN2, 7, "mft7-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 6, "mft6-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 5, "mft5-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 4, "mft4-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 3, "mft3-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 2, "mft2-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 1, "mft1-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
{NPCM7XX_CLKEN2, 0, "mft0-gate", NPCM7XX_CLK_S_APB4, 0},
|
||||
|
||||
{NPCM7XX_CLKEN3, 31, "gpiom7-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 30, "gpiom6-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 29, "gpiom5-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 28, "gpiom4-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 27, "gpiom3-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 26, "gpiom2-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 25, "gpiom1-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 24, "gpiom0-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 23, "espi-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 22, "smb11-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 21, "smb10-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 20, "smb9-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 19, "smb8-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 18, "smb15-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 17, "rng-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 16, "timer10_14-gate", NPCM7XX_CLK_S_APB1, 0},
|
||||
{NPCM7XX_CLKEN3, 15, "pcirc-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 14, "sececc-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 13, "sha-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 12, "smb14-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
/* bit 11 is reserved */
|
||||
/* bit 10 is reserved */
|
||||
{NPCM7XX_CLKEN3, 9, "pcimbx-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
/* bit 8 is reserved */
|
||||
{NPCM7XX_CLKEN3, 7, "usbdev9-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 6, "usbdev8-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 5, "usbdev7-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 4, "usbdev0-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 3, "smb13-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 2, "spix-gate", NPCM7XX_CLK_S_AHB, 0},
|
||||
{NPCM7XX_CLKEN3, 1, "smb12-gate", NPCM7XX_CLK_S_APB2, 0},
|
||||
{NPCM7XX_CLKEN3, 0, "pwmm1-gate", NPCM7XX_CLK_S_APB3, 0},
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(npcm7xx_clk_lock);
|
||||
|
||||
static void __init npcm7xx_clk_init(struct device_node *clk_np)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
* Copyright 2021 NXP
|
||||
*
|
||||
* clock driver for Freescale QorIQ SoCs.
|
||||
*/
|
||||
|
@ -564,7 +565,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -580,7 +583,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -591,7 +596,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,ls1028a-clockgen",
|
||||
|
@ -605,7 +611,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
|
@ -620,7 +627,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -635,7 +643,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -649,7 +658,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
|
@ -660,7 +670,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,ls2080a-clockgen",
|
||||
|
@ -670,7 +680,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x37,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
|
@ -681,7 +693,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x37,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_VER3 | CG_LITTLE_ENDIAN,
|
||||
},
|
||||
{
|
||||
|
@ -694,7 +708,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p3041-clockgen",
|
||||
|
@ -706,7 +721,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p4080-clockgen",
|
||||
|
@ -718,7 +734,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x1f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) |
|
||||
BIT(CGA_PLL3) | BIT(CGA_PLL4),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p5020-clockgen",
|
||||
|
@ -730,7 +748,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 1, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,p5040-clockgen",
|
||||
|
@ -742,7 +761,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 1, 1, -1
|
||||
},
|
||||
.pll_mask = 0x0f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3),
|
||||
},
|
||||
{
|
||||
.compat = "fsl,t1023-clockgen",
|
||||
|
@ -757,7 +777,7 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x03,
|
||||
.pll_mask = BIT(PLATFORM_PLL) | BIT(CGA_PLL1),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -770,7 +790,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 0, 0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -786,7 +807,8 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, -1
|
||||
},
|
||||
.pll_mask = 0x07,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{
|
||||
|
@ -802,7 +824,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
|
|||
.cmux_to_group = {
|
||||
0, 0, 1, -1
|
||||
},
|
||||
.pll_mask = 0x3f,
|
||||
.pll_mask = BIT(PLATFORM_PLL) |
|
||||
BIT(CGA_PLL1) | BIT(CGA_PLL2) | BIT(CGA_PLL3) |
|
||||
BIT(CGB_PLL1) | BIT(CGB_PLL2),
|
||||
.flags = CG_PLL_8BIT,
|
||||
},
|
||||
{},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Copyright (C) 2010, 2011 Ericsson AB.
|
||||
* Copyright (C) 2011 Guenter Roeck.
|
||||
* Copyright (C) 2011 - 2013 Xilinx Inc.
|
||||
* Copyright (C) 2011 - 2021 Xilinx Inc.
|
||||
*
|
||||
* Author: Guenter Roeck <guenter.roeck@ericsson.com>
|
||||
* Sören Brinkmann <soren.brinkmann@xilinx.com>
|
||||
|
@ -123,14 +123,18 @@ static int si570_get_divs(struct clk_si570 *data, u64 *rfreq,
|
|||
* si570_get_defaults() - Get default values
|
||||
* @data: Driver data structure
|
||||
* @fout: Factory frequency output
|
||||
* @skip_recall: If true, don't recall NVM into RAM
|
||||
* Returns 0 on success, negative errno otherwise.
|
||||
*/
|
||||
static int si570_get_defaults(struct clk_si570 *data, u64 fout)
|
||||
static int si570_get_defaults(struct clk_si570 *data, u64 fout,
|
||||
bool skip_recall)
|
||||
{
|
||||
int err;
|
||||
u64 fdco;
|
||||
|
||||
regmap_write(data->regmap, SI570_REG_CONTROL, SI570_CNTRL_RECALL);
|
||||
if (!skip_recall)
|
||||
regmap_write(data->regmap, SI570_REG_CONTROL,
|
||||
SI570_CNTRL_RECALL);
|
||||
|
||||
err = si570_get_divs(data, &data->rfreq, &data->n1, &data->hs_div);
|
||||
if (err)
|
||||
|
@ -400,6 +404,7 @@ static int si570_probe(struct i2c_client *client,
|
|||
struct clk_si570 *data;
|
||||
struct clk_init_data init;
|
||||
u32 initial_fout, factory_fout, stability;
|
||||
bool skip_recall;
|
||||
int err;
|
||||
enum clk_si570_variant variant = id->driver_data;
|
||||
|
||||
|
@ -441,6 +446,9 @@ static int si570_probe(struct i2c_client *client,
|
|||
return err;
|
||||
}
|
||||
|
||||
skip_recall = of_property_read_bool(client->dev.of_node,
|
||||
"silabs,skip-recall");
|
||||
|
||||
data->regmap = devm_regmap_init_i2c(client, &si570_regmap_config);
|
||||
if (IS_ERR(data->regmap)) {
|
||||
dev_err(&client->dev, "failed to allocate register map\n");
|
||||
|
@ -448,7 +456,7 @@ static int si570_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
err = si570_get_defaults(data, factory_fout);
|
||||
err = si570_get_defaults(data, factory_fout, skip_recall);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#define CLK_COUNT 4 /* cpu_clk, sys_clk, usb_clk, sdio_clk */
|
||||
static struct clk *clks[CLK_COUNT];
|
||||
static struct clk_onecell_data clk_data = { clks, CLK_COUNT };
|
||||
|
||||
#define SYSCLK_DIV 0x20
|
||||
#define CPUCLK_DIV 0x24
|
||||
#define DIV_BYPASS BIT(23)
|
||||
|
||||
/*** CLKGEN_PLL ***/
|
||||
#define extract_pll_n(val) ((val >> 0) & ((1u << 7) - 1))
|
||||
#define extract_pll_k(val) ((val >> 13) & ((1u << 3) - 1))
|
||||
#define extract_pll_m(val) ((val >> 16) & ((1u << 3) - 1))
|
||||
#define extract_pll_isel(val) ((val >> 24) & ((1u << 3) - 1))
|
||||
|
||||
static void __init make_pll(int idx, const char *parent, void __iomem *base)
|
||||
{
|
||||
char name[8];
|
||||
u32 val, mul, div;
|
||||
|
||||
sprintf(name, "pll%d", idx);
|
||||
val = readl(base + idx * 8);
|
||||
mul = extract_pll_n(val) + 1;
|
||||
div = (extract_pll_m(val) + 1) << extract_pll_k(val);
|
||||
clk_register_fixed_factor(NULL, name, parent, 0, mul, div);
|
||||
if (extract_pll_isel(val) != 1)
|
||||
panic("%s: input not set to XTAL_IN\n", name);
|
||||
}
|
||||
|
||||
static void __init make_cd(int idx, void __iomem *base)
|
||||
{
|
||||
char name[8];
|
||||
u32 val, mul, div;
|
||||
|
||||
sprintf(name, "cd%d", idx);
|
||||
val = readl(base + idx * 8);
|
||||
mul = 1 << 27;
|
||||
div = (2 << 27) + val;
|
||||
clk_register_fixed_factor(NULL, name, "pll2", 0, mul, div);
|
||||
if (val > 0xf0000000)
|
||||
panic("%s: unsupported divider %x\n", name, val);
|
||||
}
|
||||
|
||||
static void __init tango4_clkgen_setup(struct device_node *np)
|
||||
{
|
||||
struct clk **pp = clk_data.clks;
|
||||
void __iomem *base = of_iomap(np, 0);
|
||||
const char *parent = of_clk_get_parent_name(np, 0);
|
||||
|
||||
if (!base)
|
||||
panic("%pOFn: invalid address\n", np);
|
||||
|
||||
if (readl(base + CPUCLK_DIV) & DIV_BYPASS)
|
||||
panic("%pOFn: unsupported cpuclk setup\n", np);
|
||||
|
||||
if (readl(base + SYSCLK_DIV) & DIV_BYPASS)
|
||||
panic("%pOFn: unsupported sysclk setup\n", np);
|
||||
|
||||
writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */
|
||||
|
||||
make_pll(0, parent, base);
|
||||
make_pll(1, parent, base);
|
||||
make_pll(2, parent, base);
|
||||
make_cd(2, base + 0x80);
|
||||
make_cd(6, base + 0x80);
|
||||
|
||||
pp[0] = clk_register_divider(NULL, "cpu_clk", "pll0", 0,
|
||||
base + CPUCLK_DIV, 8, 8, CLK_DIVIDER_ONE_BASED, NULL);
|
||||
pp[1] = clk_register_fixed_factor(NULL, "sys_clk", "pll1", 0, 1, 4);
|
||||
pp[2] = clk_register_fixed_factor(NULL, "usb_clk", "cd2", 0, 1, 2);
|
||||
pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2);
|
||||
|
||||
if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3]))
|
||||
panic("%pOFn: clk registration failed\n", np);
|
||||
|
||||
if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data))
|
||||
panic("%pOFn: clk provider registration failed\n", np);
|
||||
}
|
||||
CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -759,6 +759,63 @@ static int vc5_update_power(struct device_node *np_output,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vc5_map_cap_value(u32 femtofarads)
|
||||
{
|
||||
int mapped_value;
|
||||
|
||||
/*
|
||||
* The datasheet explicitly states 9000 - 25000 with 0.5pF
|
||||
* steps, but the Programmer's guide shows the steps are 0.430pF.
|
||||
* After getting feedback from Renesas, the .5pF steps were the
|
||||
* goal, but 430nF was the actual values.
|
||||
* Because of this, the actual range goes to 22760 instead of 25000
|
||||
*/
|
||||
if (femtofarads < 9000 || femtofarads > 22760)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* The Programmer's guide shows XTAL[5:0] but in reality,
|
||||
* XTAL[0] and XTAL[1] are both LSB which makes the math
|
||||
* strange. With clarfication from Renesas, setting the
|
||||
* values should be simpler by ignoring XTAL[0]
|
||||
*/
|
||||
mapped_value = DIV_ROUND_CLOSEST(femtofarads - 9000, 430);
|
||||
|
||||
/*
|
||||
* Since the calculation ignores XTAL[0], there is one
|
||||
* special case where mapped_value = 32. In reality, this means
|
||||
* the real mapped value should be 111111b. In other cases,
|
||||
* the mapped_value needs to be shifted 1 to the left.
|
||||
*/
|
||||
if (mapped_value > 31)
|
||||
mapped_value = 0x3f;
|
||||
else
|
||||
mapped_value <<= 1;
|
||||
|
||||
return mapped_value;
|
||||
}
|
||||
static int vc5_update_cap_load(struct device_node *node, struct vc5_driver_data *vc5)
|
||||
{
|
||||
u32 value;
|
||||
int mapped_value;
|
||||
|
||||
if (!of_property_read_u32(node, "idt,xtal-load-femtofarads", &value)) {
|
||||
mapped_value = vc5_map_cap_value(value);
|
||||
if (mapped_value < 0)
|
||||
return mapped_value;
|
||||
|
||||
/*
|
||||
* The mapped_value is really the high 6 bits of
|
||||
* VC5_XTAL_X1_LOAD_CAP and VC5_XTAL_X2_LOAD_CAP, so
|
||||
* shift the value 2 places.
|
||||
*/
|
||||
regmap_update_bits(vc5->regmap, VC5_XTAL_X1_LOAD_CAP, ~0x03, mapped_value << 2);
|
||||
regmap_update_bits(vc5->regmap, VC5_XTAL_X2_LOAD_CAP, ~0x03, mapped_value << 2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vc5_update_slew(struct device_node *np_output,
|
||||
struct vc5_out_data *clk_out)
|
||||
{
|
||||
|
@ -884,6 +941,13 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Configure Optional Loading Capacitance for external XTAL */
|
||||
if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) {
|
||||
ret = vc5_update_cap_load(client->dev.of_node, vc5);
|
||||
if (ret)
|
||||
goto err_clk_register;
|
||||
}
|
||||
|
||||
init.name = kasprintf(GFP_KERNEL, "%pOFn.mux", client->dev.of_node);
|
||||
init.ops = &vc5_mux_ops;
|
||||
init.flags = 0;
|
||||
|
|
|
@ -206,17 +206,16 @@ static void xgene_pcppllclk_init(struct device_node *np)
|
|||
* @hw: handle between common and hardware-specific interfaces
|
||||
* @reg: register containing the fractional scale multiplier (scaler)
|
||||
* @shift: shift to the unit bit field
|
||||
* @mask: mask to the unit bit field
|
||||
* @denom: 1/denominator unit
|
||||
* @lock: register lock
|
||||
* Flags:
|
||||
* XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
|
||||
* @flags: XGENE_CLK_PMD_SCALE_INVERTED - By default the scaler is the value read
|
||||
* from the register plus one. For example,
|
||||
* 0 for (0 + 1) / denom,
|
||||
* 1 for (1 + 1) / denom and etc.
|
||||
* If this flag is set, it is
|
||||
* 0 for (denom - 0) / denom,
|
||||
* 1 for (denom - 1) / denom and etc.
|
||||
*
|
||||
*/
|
||||
struct xgene_clk_pmd {
|
||||
struct clk_hw hw;
|
||||
|
|
|
@ -51,16 +51,6 @@ enum mx31_clks {
|
|||
static struct clk *clk[clk_max];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static struct clk ** const uart_clks[] __initconst = {
|
||||
&clk[ipg],
|
||||
&clk[uart1_gate],
|
||||
&clk[uart2_gate],
|
||||
&clk[uart3_gate],
|
||||
&clk[uart4_gate],
|
||||
&clk[uart5_gate],
|
||||
NULL
|
||||
};
|
||||
|
||||
static void __init _mx31_clocks_init(void __iomem *base, unsigned long fref)
|
||||
{
|
||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||
|
|
|
@ -338,10 +338,10 @@ static void init_ldb_clks(struct device_node *np, void __iomem *ccm_base)
|
|||
of_assigned_ldb_sels(np, &sel[0][3], &sel[1][3]);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Warn if a glitch might have been introduced already */
|
||||
/* Print a notice if a glitch might have been introduced already */
|
||||
if (sel[i][0] != 3) {
|
||||
pr_warn("ccm: ldb_di%d_sel already changed from reset value: %d\n",
|
||||
i, sel[i][0]);
|
||||
pr_notice("ccm: possible glitch: ldb_di%d_sel already changed from reset value: %d\n",
|
||||
i, sel[i][0]);
|
||||
}
|
||||
|
||||
if (sel[i][0] == sel[i][3])
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk/imx.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
|
|
@ -288,6 +288,11 @@ static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", "
|
|||
static const char *imx8mm_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", "sys_pll2_166m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out", "osc_32k", };
|
||||
|
||||
static const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
|
||||
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
|
||||
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
|
||||
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
|
@ -410,6 +415,13 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
|||
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);
|
||||
|
||||
hws[IMX8MM_CLK_CLKOUT1_SEL] = imx_clk_hw_mux("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
|
||||
hws[IMX8MM_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4);
|
||||
hws[IMX8MM_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
|
||||
hws[IMX8MM_CLK_CLKOUT2_SEL] = imx_clk_hw_mux("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
|
||||
hws[IMX8MM_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4);
|
||||
hws[IMX8MM_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
|
|
|
@ -281,6 +281,11 @@ 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 const char * const clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||
"dummy", "dummy", "gpu_pll_out", "dummy",
|
||||
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
|
||||
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
|
||||
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
|
@ -405,6 +410,13 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
|||
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);
|
||||
|
||||
hws[IMX8MN_CLK_CLKOUT1_SEL] = imx_clk_hw_mux("clkout1_sel", base + 0x128, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
|
||||
hws[IMX8MN_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, 0, 4);
|
||||
hws[IMX8MN_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8);
|
||||
hws[IMX8MN_CLK_CLKOUT2_SEL] = imx_clk_hw_mux("clkout2_sel", base + 0x128, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels));
|
||||
hws[IMX8MN_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, 16, 4);
|
||||
hws[IMX8MN_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base))) {
|
||||
|
|
|
@ -270,6 +270,14 @@ 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 const char * const pllout_monitor_sels[] = {"osc_25m", "osc_27m", "dummy", "dummy", "ckil",
|
||||
"audio_pll1_out_monitor", "audio_pll2_out_monitor",
|
||||
"video_pll1_out_monitor", "gpu_pll_out_monitor",
|
||||
"vpu_pll_out_monitor", "arm_pll_out_monitor",
|
||||
"sys_pll1_out_monitor", "sys_pll2_out_monitor",
|
||||
"sys_pll3_out_monitor", "dram_pll_out_monitor",
|
||||
"video_pll2_out_monitor", };
|
||||
|
||||
static struct clk_hw_onecell_data *clk_hw_data;
|
||||
static struct clk_hw **hws;
|
||||
|
||||
|
@ -399,6 +407,20 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
|||
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);
|
||||
|
||||
hws[IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = imx_clk_hw_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3);
|
||||
hws[IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = imx_clk_hw_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3);
|
||||
hws[IMX8MQ_CLK_MON_VIDEO_PLL1_DIV] = imx_clk_hw_divider("video_pll1_out_monitor", "video_pll1_bypass", base + 0x78, 8, 3);
|
||||
hws[IMX8MQ_CLK_MON_GPU_PLL_DIV] = imx_clk_hw_divider("gpu_pll_out_monitor", "gpu_pll_bypass", base + 0x78, 12, 3);
|
||||
hws[IMX8MQ_CLK_MON_VPU_PLL_DIV] = imx_clk_hw_divider("vpu_pll_out_monitor", "vpu_pll_bypass", base + 0x78, 16, 3);
|
||||
hws[IMX8MQ_CLK_MON_ARM_PLL_DIV] = imx_clk_hw_divider("arm_pll_out_monitor", "arm_pll_bypass", base + 0x78, 20, 3);
|
||||
hws[IMX8MQ_CLK_MON_SYS_PLL1_DIV] = imx_clk_hw_divider("sys_pll1_out_monitor", "sys1_pll_out", base + 0x7c, 0, 3);
|
||||
hws[IMX8MQ_CLK_MON_SYS_PLL2_DIV] = imx_clk_hw_divider("sys_pll2_out_monitor", "sys2_pll_out", base + 0x7c, 4, 3);
|
||||
hws[IMX8MQ_CLK_MON_SYS_PLL3_DIV] = imx_clk_hw_divider("sys_pll3_out_monitor", "sys3_pll_out", base + 0x7c, 8, 3);
|
||||
hws[IMX8MQ_CLK_MON_DRAM_PLL_DIV] = imx_clk_hw_divider("dram_pll_out_monitor", "dram_pll_out", base + 0x7c, 12, 3);
|
||||
hws[IMX8MQ_CLK_MON_VIDEO_PLL2_DIV] = imx_clk_hw_divider("video_pll2_out_monitor", "video2_pll_out", base + 0x7c, 16, 3);
|
||||
hws[IMX8MQ_CLK_MON_SEL] = imx_clk_hw_mux("pllout_monitor_sel", base + 0x74, 0, 4, pllout_monitor_sels, ARRAY_SIZE(pllout_monitor_sels));
|
||||
hws[IMX8MQ_CLK_MON_CLK2_OUT] = imx_clk_hw_gate("pllout_monitor_clk2", "pllout_monitor_sel", base + 0x74, 4);
|
||||
|
||||
np = dev->of_node;
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (WARN_ON(IS_ERR(base)))
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
#include <dt-bindings/clock/imx8-clock.h>
|
||||
#include <dt-bindings/firmware/imx/rsrc.h>
|
||||
|
||||
static const char *dc0_sels[] = {
|
||||
"clk_dummy",
|
||||
"clk_dummy",
|
||||
"dc0_pll0_clk",
|
||||
"dc0_pll1_clk",
|
||||
"dc0_bypass0_clk",
|
||||
};
|
||||
|
||||
static int imx8qxp_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *ccm_node = pdev->dev.of_node;
|
||||
|
@ -115,12 +123,26 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
|
|||
clks[IMX_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC, clk_cells);
|
||||
|
||||
/* Display controller SS */
|
||||
clks[IMX_DC0_DISP0_CLK] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells);
|
||||
clks[IMX_DC0_DISP1_CLK] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells);
|
||||
clks[IMX_DC0_DISP0_CLK] = imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells);
|
||||
clks[IMX_DC0_DISP1_CLK] = imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells);
|
||||
clks[IMX_DC0_PLL0_CLK] = imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL, clk_cells);
|
||||
clks[IMX_DC0_PLL1_CLK] = imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL, clk_cells);
|
||||
clks[IMX_DC0_BYPASS0_CLK] = imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS, clk_cells);
|
||||
clks[IMX_DC0_BYPASS1_CLK] = imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS, clk_cells);
|
||||
|
||||
/* MIPI-LVDS SS */
|
||||
clks[IMX_MIPI0_LVDS_PIXEL_CLK] = imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI0_LVDS_BYPASS_CLK] = imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS, clk_cells);
|
||||
clks[IMX_MIPI0_LVDS_PHY_CLK] = imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3, clk_cells);
|
||||
clks[IMX_MIPI0_I2C0_CLK] = imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI0_I2C1_CLK] = imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI0_PWM0_CLK] = imx_clk_scu("mipi0_pwm0_clk", IMX_SC_R_MIPI_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells);
|
||||
clks[IMX_MIPI1_LVDS_PIXEL_CLK] = imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI1_LVDS_BYPASS_CLK] = imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS, clk_cells);
|
||||
clks[IMX_MIPI1_LVDS_PHY_CLK] = imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3, clk_cells);
|
||||
clks[IMX_MIPI1_I2C0_CLK] = imx_clk_scu("mipi1_i2c0_clk", IMX_SC_R_MIPI_1_I2C_0, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI1_I2C1_CLK] = imx_clk_scu("mipi1_i2c1_clk", IMX_SC_R_MIPI_1_I2C_1, IMX_SC_PM_CLK_MISC2, clk_cells);
|
||||
clks[IMX_MIPI1_PWM0_CLK] = imx_clk_scu("mipi1_pwm0_clk", IMX_SC_R_MIPI_1_PWM_0, IMX_SC_PM_CLK_PER, clk_cells);
|
||||
|
||||
/* MIPI CSI SS */
|
||||
clks[IMX_CSI0_CORE_CLK] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER, clk_cells);
|
||||
|
|
|
@ -426,66 +426,77 @@ config COMMON_CLK_MT8183
|
|||
config COMMON_CLK_MT8183_AUDIOSYS
|
||||
bool "Clock driver for MediaTek MT8183 audiosys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 audiosys clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_CAMSYS
|
||||
bool "Clock driver for MediaTek MT8183 camsys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 camsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_IMGSYS
|
||||
bool "Clock driver for MediaTek MT8183 imgsys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 imgsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_IPU_CORE0
|
||||
bool "Clock driver for MediaTek MT8183 ipu_core0"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 ipu_core0 clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_IPU_CORE1
|
||||
bool "Clock driver for MediaTek MT8183 ipu_core1"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 ipu_core1 clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_IPU_ADL
|
||||
bool "Clock driver for MediaTek MT8183 ipu_adl"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 ipu_adl clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_IPU_CONN
|
||||
bool "Clock driver for MediaTek MT8183 ipu_conn"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 ipu_conn clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_MFGCFG
|
||||
bool "Clock driver for MediaTek MT8183 mfgcfg"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 mfgcfg clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_MMSYS
|
||||
bool "Clock driver for MediaTek MT8183 mmsys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 mmsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_VDECSYS
|
||||
bool "Clock driver for MediaTek MT8183 vdecsys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 vdecsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8183_VENCSYS
|
||||
bool "Clock driver for MediaTek MT8183 vencsys"
|
||||
depends on COMMON_CLK_MT8183
|
||||
default COMMON_CLK_MT8183
|
||||
help
|
||||
This driver supports MediaTek MT8183 vencsys clocks.
|
||||
|
||||
|
|
|
@ -17,29 +17,36 @@ static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
|
|||
return container_of(hw, struct mtk_clk_mux, hw);
|
||||
}
|
||||
|
||||
static int mtk_clk_mux_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
|
||||
u32 mask = BIT(mux->data->gate_shift);
|
||||
|
||||
return regmap_update_bits(mux->regmap, mux->data->mux_ofs,
|
||||
mask, ~mask);
|
||||
}
|
||||
|
||||
static void mtk_clk_mux_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
|
||||
u32 mask = BIT(mux->data->gate_shift);
|
||||
|
||||
regmap_update_bits(mux->regmap, mux->data->mux_ofs, mask, mask);
|
||||
}
|
||||
|
||||
static int mtk_clk_mux_enable_setclr(struct clk_hw *hw)
|
||||
{
|
||||
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
|
||||
unsigned long flags = 0;
|
||||
|
||||
return regmap_write(mux->regmap, mux->data->clr_ofs,
|
||||
BIT(mux->data->gate_shift));
|
||||
if (mux->lock)
|
||||
spin_lock_irqsave(mux->lock, flags);
|
||||
else
|
||||
__acquire(mux->lock);
|
||||
|
||||
regmap_write(mux->regmap, mux->data->clr_ofs,
|
||||
BIT(mux->data->gate_shift));
|
||||
|
||||
/*
|
||||
* If the parent has been changed when the clock was disabled, it will
|
||||
* not be effective yet. Set the update bit to ensure the mux gets
|
||||
* updated.
|
||||
*/
|
||||
if (mux->reparent && mux->data->upd_shift >= 0) {
|
||||
regmap_write(mux->regmap, mux->data->upd_ofs,
|
||||
BIT(mux->data->upd_shift));
|
||||
mux->reparent = false;
|
||||
}
|
||||
|
||||
if (mux->lock)
|
||||
spin_unlock_irqrestore(mux->lock, flags);
|
||||
else
|
||||
__release(mux->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mtk_clk_mux_disable_setclr(struct clk_hw *hw)
|
||||
|
@ -72,28 +79,6 @@ static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
|
|||
return val;
|
||||
}
|
||||
|
||||
static int mtk_clk_mux_set_parent_lock(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
|
||||
u32 mask = GENMASK(mux->data->mux_width - 1, 0);
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (mux->lock)
|
||||
spin_lock_irqsave(mux->lock, flags);
|
||||
else
|
||||
__acquire(mux->lock);
|
||||
|
||||
regmap_update_bits(mux->regmap, mux->data->mux_ofs, mask,
|
||||
index << mux->data->mux_shift);
|
||||
|
||||
if (mux->lock)
|
||||
spin_unlock_irqrestore(mux->lock, flags);
|
||||
else
|
||||
__release(mux->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
|
||||
|
@ -116,9 +101,11 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
|
|||
regmap_write(mux->regmap, mux->data->set_ofs,
|
||||
index << mux->data->mux_shift);
|
||||
|
||||
if (mux->data->upd_shift >= 0)
|
||||
if (mux->data->upd_shift >= 0) {
|
||||
regmap_write(mux->regmap, mux->data->upd_ofs,
|
||||
BIT(mux->data->upd_shift));
|
||||
mux->reparent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mux->lock)
|
||||
|
@ -129,25 +116,7 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops mtk_mux_ops = {
|
||||
.get_parent = mtk_clk_mux_get_parent,
|
||||
.set_parent = mtk_clk_mux_set_parent_lock,
|
||||
};
|
||||
|
||||
const struct clk_ops mtk_mux_clr_set_upd_ops = {
|
||||
.get_parent = mtk_clk_mux_get_parent,
|
||||
.set_parent = mtk_clk_mux_set_parent_setclr_lock,
|
||||
};
|
||||
|
||||
const struct clk_ops mtk_mux_gate_ops = {
|
||||
.enable = mtk_clk_mux_enable,
|
||||
.disable = mtk_clk_mux_disable,
|
||||
.is_enabled = mtk_clk_mux_is_enabled,
|
||||
.get_parent = mtk_clk_mux_get_parent,
|
||||
.set_parent = mtk_clk_mux_set_parent_lock,
|
||||
};
|
||||
|
||||
const struct clk_ops mtk_mux_gate_clr_set_upd_ops = {
|
||||
static const struct clk_ops mtk_mux_ops = {
|
||||
.enable = mtk_clk_mux_enable_setclr,
|
||||
.disable = mtk_clk_mux_disable_setclr,
|
||||
.is_enabled = mtk_clk_mux_is_enabled,
|
||||
|
@ -171,7 +140,7 @@ static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
|
|||
init.flags = mux->flags | CLK_SET_RATE_PARENT;
|
||||
init.parent_names = mux->parent_names;
|
||||
init.num_parents = mux->num_parents;
|
||||
init.ops = mux->ops;
|
||||
init.ops = &mtk_mux_ops;
|
||||
|
||||
clk_mux->regmap = regmap;
|
||||
clk_mux->data = mux;
|
||||
|
|
|
@ -14,6 +14,7 @@ struct mtk_clk_mux {
|
|||
struct regmap *regmap;
|
||||
const struct mtk_mux *data;
|
||||
spinlock_t *lock;
|
||||
bool reparent;
|
||||
};
|
||||
|
||||
struct mtk_mux {
|
||||
|
@ -32,19 +33,12 @@ struct mtk_mux {
|
|||
u8 gate_shift;
|
||||
s8 upd_shift;
|
||||
|
||||
const struct clk_ops *ops;
|
||||
|
||||
signed char num_parents;
|
||||
};
|
||||
|
||||
extern const struct clk_ops mtk_mux_ops;
|
||||
extern const struct clk_ops mtk_mux_clr_set_upd_ops;
|
||||
extern const struct clk_ops mtk_mux_gate_ops;
|
||||
extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
|
||||
|
||||
#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
|
||||
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
|
||||
_gate, _upd_ofs, _upd, _flags, _ops) { \
|
||||
_gate, _upd_ofs, _upd, _flags) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.mux_ofs = _mux_ofs, \
|
||||
|
@ -58,7 +52,6 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
|
|||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.flags = _flags, \
|
||||
.ops = &_ops, \
|
||||
}
|
||||
|
||||
#define MUX_GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
|
||||
|
@ -66,8 +59,7 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
|
|||
_gate, _upd_ofs, _upd, _flags) \
|
||||
GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
|
||||
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
|
||||
_gate, _upd_ofs, _upd, _flags, \
|
||||
mtk_mux_gate_clr_set_upd_ops)
|
||||
_gate, _upd_ofs, _upd, _flags) \
|
||||
|
||||
#define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
|
||||
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
|
||||
|
|
|
@ -1879,7 +1879,6 @@ static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11);
|
|||
static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25);
|
||||
static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
|
||||
static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30);
|
||||
static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29);
|
||||
|
||||
/* Always On (AO) domain gates */
|
||||
|
||||
|
@ -1974,7 +1973,6 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
|
|||
[CLKID_PCIE_REF] = &axg_pcie_ref.hw,
|
||||
[CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw,
|
||||
[CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw,
|
||||
[CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw,
|
||||
[CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw,
|
||||
[CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw,
|
||||
[CLKID_GEN_CLK] = &axg_gen_clk.hw,
|
||||
|
@ -2115,7 +2113,6 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
|
|||
&axg_pcie_ref,
|
||||
&axg_pcie_cml_en0,
|
||||
&axg_pcie_cml_en1,
|
||||
&axg_mipi_enable,
|
||||
&axg_gen_clk_sel,
|
||||
&axg_gen_clk_div,
|
||||
&axg_gen_clk,
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* Register offsets from the data sheet must be multiplied by 4 before
|
||||
* adding them to the base address to get the right value.
|
||||
*/
|
||||
#define HHI_MIPI_CNTL0 0x00
|
||||
#define HHI_GP0_PLL_CNTL 0x40
|
||||
#define HHI_GP0_PLL_CNTL2 0x44
|
||||
#define HHI_GP0_PLL_CNTL3 0x48
|
||||
|
|
|
@ -365,13 +365,14 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
|
||||
unsigned int enabled, m, n, frac = 0, ret;
|
||||
unsigned int enabled, m, n, frac = 0;
|
||||
unsigned long old_rate;
|
||||
int ret;
|
||||
|
||||
if (parent_rate == 0 || rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
old_rate = rate;
|
||||
old_rate = clk_hw_get_rate(hw);
|
||||
|
||||
ret = meson_clk_get_pll_settings(rate, parent_rate, &m, &n, pll);
|
||||
if (ret)
|
||||
|
@ -393,7 +394,8 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
if (!enabled)
|
||||
return 0;
|
||||
|
||||
if (meson_clk_pll_enable(hw)) {
|
||||
ret = meson_clk_pll_enable(hw);
|
||||
if (ret) {
|
||||
pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
|
||||
__func__, old_rate);
|
||||
/*
|
||||
|
@ -405,7 +407,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
meson_clk_pll_set_rate(hw, old_rate, parent_rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -52,15 +52,6 @@ static const struct pll_params_table sys_pll_params_table[] = {
|
|||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct clk_fixed_rate meson8b_xtal = {
|
||||
.fixed_rate = 24000000,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "xtal",
|
||||
.num_parents = 0,
|
||||
.ops = &clk_fixed_rate_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_fixed_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
|
@ -2715,7 +2706,6 @@ static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
|
|||
|
||||
static struct clk_hw_onecell_data meson8_hw_onecell_data = {
|
||||
.hws = {
|
||||
[CLKID_XTAL] = &meson8b_xtal.hw,
|
||||
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
||||
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
||||
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
||||
|
@ -2922,7 +2912,6 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
|
|||
|
||||
static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
||||
.hws = {
|
||||
[CLKID_XTAL] = &meson8b_xtal.hw,
|
||||
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
||||
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
||||
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
||||
|
@ -3140,7 +3129,6 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
|||
|
||||
static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
|
||||
.hws = {
|
||||
[CLKID_XTAL] = &meson8b_xtal.hw,
|
||||
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
|
||||
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
|
||||
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
|
||||
|
@ -3725,36 +3713,19 @@ static struct meson8b_nb_data meson8b_cpu_nb_data = {
|
|||
.nb.notifier_call = meson8b_cpu_clk_notifier_cb,
|
||||
};
|
||||
|
||||
static const struct regmap_config clkc_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static void __init meson8b_clkc_init_common(struct device_node *np,
|
||||
struct clk_hw_onecell_data *clk_hw_onecell_data)
|
||||
{
|
||||
struct meson8b_clk_reset *rstc;
|
||||
const char *notifier_clk_name;
|
||||
struct clk *notifier_clk;
|
||||
void __iomem *clk_base;
|
||||
struct regmap *map;
|
||||
int i, ret;
|
||||
|
||||
map = syscon_node_to_regmap(of_get_parent(np));
|
||||
if (IS_ERR(map)) {
|
||||
pr_info("failed to get HHI regmap - Trying obsolete regs\n");
|
||||
|
||||
/* Generic clocks, PLLs and some of the reset-bits */
|
||||
clk_base = of_iomap(np, 1);
|
||||
if (!clk_base) {
|
||||
pr_err("%s: Unable to map clk base\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
map = regmap_init_mmio(NULL, clk_base, &clkc_regmap_config);
|
||||
if (IS_ERR(map))
|
||||
return;
|
||||
pr_err("failed to get HHI regmap - Trying obsolete regs\n");
|
||||
return;
|
||||
}
|
||||
|
||||
rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
|
||||
|
@ -3778,16 +3749,10 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
|
|||
meson8b_clk_regmaps[i]->map = map;
|
||||
|
||||
/*
|
||||
* always skip CLKID_UNUSED and also skip XTAL if the .dtb provides the
|
||||
* XTAL clock as input.
|
||||
* register all clks and start with the first used ID (which is
|
||||
* CLKID_PLL_FIXED)
|
||||
*/
|
||||
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++) {
|
||||
for (i = CLKID_PLL_FIXED; i < CLK_NR_CLKS; i++) {
|
||||
/* array might be sparse */
|
||||
if (!clk_hw_onecell_data->hws[i])
|
||||
continue;
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config MSTAR_MSC313_MPLL
|
||||
bool "MStar MPLL driver"
|
||||
depends on ARCH_MSTARV7 || COMPILE_TEST
|
||||
default ARCH_MSTARV7
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Support for the MPLL PLL and dividers block present on
|
||||
MStar/Sigmastar SoCs.
|
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for mstar specific clk
|
||||
#
|
||||
|
||||
obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
|
|
@ -0,0 +1,155 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* MStar MSC313 MPLL driver
|
||||
*
|
||||
* Copyright (C) 2020 Daniel Palmer <daniel@thingy.jp>
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define REG_CONFIG1 0x8
|
||||
#define REG_CONFIG2 0xc
|
||||
|
||||
static const struct regmap_config msc313_mpll_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 16,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static const struct reg_field config1_loop_div_first = REG_FIELD(REG_CONFIG1, 8, 9);
|
||||
static const struct reg_field config1_input_div_first = REG_FIELD(REG_CONFIG1, 4, 5);
|
||||
static const struct reg_field config2_output_div_first = REG_FIELD(REG_CONFIG2, 12, 13);
|
||||
static const struct reg_field config2_loop_div_second = REG_FIELD(REG_CONFIG2, 0, 7);
|
||||
|
||||
static const unsigned int output_dividers[] = {
|
||||
2, 3, 4, 5, 6, 7, 10
|
||||
};
|
||||
|
||||
#define NUMOUTPUTS (ARRAY_SIZE(output_dividers) + 1)
|
||||
|
||||
struct msc313_mpll {
|
||||
struct clk_hw clk_hw;
|
||||
struct regmap_field *input_div;
|
||||
struct regmap_field *loop_div_first;
|
||||
struct regmap_field *loop_div_second;
|
||||
struct regmap_field *output_div;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
};
|
||||
|
||||
#define to_mpll(_hw) container_of(_hw, struct msc313_mpll, clk_hw)
|
||||
|
||||
static unsigned long msc313_mpll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct msc313_mpll *mpll = to_mpll(hw);
|
||||
unsigned int input_div, output_div, loop_first, loop_second;
|
||||
unsigned long output_rate;
|
||||
|
||||
regmap_field_read(mpll->input_div, &input_div);
|
||||
regmap_field_read(mpll->output_div, &output_div);
|
||||
regmap_field_read(mpll->loop_div_first, &loop_first);
|
||||
regmap_field_read(mpll->loop_div_second, &loop_second);
|
||||
|
||||
output_rate = parent_rate / (1 << input_div);
|
||||
output_rate *= (1 << loop_first) * max(loop_second, 1U);
|
||||
output_rate /= max(output_div, 1U);
|
||||
|
||||
return output_rate;
|
||||
}
|
||||
|
||||
static const struct clk_ops msc313_mpll_ops = {
|
||||
.recalc_rate = msc313_mpll_recalc_rate,
|
||||
};
|
||||
|
||||
static const struct clk_parent_data mpll_parent = {
|
||||
.index = 0,
|
||||
};
|
||||
|
||||
static int msc313_mpll_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *base;
|
||||
struct msc313_mpll *mpll;
|
||||
struct clk_init_data clk_init = { };
|
||||
struct device *dev = &pdev->dev;
|
||||
struct regmap *regmap;
|
||||
char *outputname;
|
||||
struct clk_hw *divhw;
|
||||
int ret, i;
|
||||
|
||||
mpll = devm_kzalloc(dev, sizeof(*mpll), GFP_KERNEL);
|
||||
if (!mpll)
|
||||
return -ENOMEM;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
regmap = devm_regmap_init_mmio(dev, base, &msc313_mpll_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
mpll->input_div = devm_regmap_field_alloc(dev, regmap, config1_input_div_first);
|
||||
if (IS_ERR(mpll->input_div))
|
||||
return PTR_ERR(mpll->input_div);
|
||||
mpll->output_div = devm_regmap_field_alloc(dev, regmap, config2_output_div_first);
|
||||
if (IS_ERR(mpll->output_div))
|
||||
return PTR_ERR(mpll->output_div);
|
||||
mpll->loop_div_first = devm_regmap_field_alloc(dev, regmap, config1_loop_div_first);
|
||||
if (IS_ERR(mpll->loop_div_first))
|
||||
return PTR_ERR(mpll->loop_div_first);
|
||||
mpll->loop_div_second = devm_regmap_field_alloc(dev, regmap, config2_loop_div_second);
|
||||
if (IS_ERR(mpll->loop_div_second))
|
||||
return PTR_ERR(mpll->loop_div_second);
|
||||
|
||||
mpll->clk_data = devm_kzalloc(dev, struct_size(mpll->clk_data, hws,
|
||||
ARRAY_SIZE(output_dividers)), GFP_KERNEL);
|
||||
if (!mpll->clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_init.name = dev_name(dev);
|
||||
clk_init.ops = &msc313_mpll_ops;
|
||||
clk_init.parent_data = &mpll_parent;
|
||||
clk_init.num_parents = 1;
|
||||
mpll->clk_hw.init = &clk_init;
|
||||
|
||||
ret = devm_clk_hw_register(dev, &mpll->clk_hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mpll->clk_data->num = NUMOUTPUTS;
|
||||
mpll->clk_data->hws[0] = &mpll->clk_hw;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(output_dividers); i++) {
|
||||
outputname = devm_kasprintf(dev, GFP_KERNEL, "%s_div_%u",
|
||||
clk_init.name, output_dividers[i]);
|
||||
if (!outputname)
|
||||
return -ENOMEM;
|
||||
divhw = devm_clk_hw_register_fixed_factor(dev, outputname,
|
||||
clk_init.name, 0, 1, output_dividers[i]);
|
||||
if (IS_ERR(divhw))
|
||||
return PTR_ERR(divhw);
|
||||
mpll->clk_data->hws[i + 1] = divhw;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, mpll);
|
||||
|
||||
return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
|
||||
mpll->clk_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id msc313_mpll_of_match[] = {
|
||||
{ .compatible = "mstar,msc313-mpll", },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver msc313_mpll_driver = {
|
||||
.driver = {
|
||||
.name = "mstar-msc313-mpll",
|
||||
.of_match_table = msc313_mpll_of_match,
|
||||
},
|
||||
.probe = msc313_mpll_probe,
|
||||
};
|
||||
builtin_platform_driver(msc313_mpll_driver);
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#define APN806_MAX_DIVIDER 32
|
||||
|
||||
/**
|
||||
/*
|
||||
* struct cpu_dfs_regs: CPU DFS register mapping
|
||||
* @divider_reg: full integer ratio from PLL frequency to CPU clock frequency
|
||||
* @force_reg: request to force new ratio regardless of relation to other clocks
|
||||
|
|
|
@ -28,6 +28,14 @@ config QCOM_A53PLL
|
|||
Say Y if you want to support higher CPU frequencies on MSM8916
|
||||
devices.
|
||||
|
||||
config QCOM_A7PLL
|
||||
tristate "SDX55 A7 PLL"
|
||||
help
|
||||
Support for the A7 PLL on SDX55 devices. It provides the CPU with
|
||||
frequencies above 1GHz.
|
||||
Say Y if you want to support higher CPU frequencies on SDX55
|
||||
devices.
|
||||
|
||||
config QCOM_CLK_APCS_MSM8916
|
||||
tristate "MSM8916 APCS Clock Controller"
|
||||
depends on QCOM_APCS_IPC || COMPILE_TEST
|
||||
|
@ -46,6 +54,15 @@ config QCOM_CLK_APCC_MSM8996
|
|||
Say Y if you want to support CPU clock scaling using CPUfreq
|
||||
drivers for dynamic power management.
|
||||
|
||||
config QCOM_CLK_APCS_SDX55
|
||||
tristate "SDX55 APCS Clock Controller"
|
||||
depends on QCOM_APCS_IPC || COMPILE_TEST
|
||||
help
|
||||
Support for the APCS Clock Controller on SDX55 platform. The
|
||||
APCS is managing the mux and divider which feeds the CPUs.
|
||||
Say Y if you want to support CPU frequency scaling on devices
|
||||
such as SDX55.
|
||||
|
||||
config QCOM_CLK_RPM
|
||||
tristate "RPM based Clock Controller"
|
||||
depends on MFD_QCOM_RPM
|
||||
|
@ -317,6 +334,24 @@ config SC_GCC_7180
|
|||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
I2C, USB, UFS, SDCC, etc.
|
||||
|
||||
config SC_GCC_7280
|
||||
tristate "SC7280 Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on SC7280 devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
I2C, USB, UFS, SDCC, PCIe etc.
|
||||
|
||||
config SC_GCC_8180X
|
||||
tristate "SC8180X Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on SC8180X devices.
|
||||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
I2C, USB, UFS, SDCC, etc.
|
||||
|
||||
config SC_LPASS_CORECC_7180
|
||||
tristate "SC7180 LPASS Core Clock Controller"
|
||||
select SC_GCC_7180
|
||||
|
@ -366,6 +401,24 @@ config SDM_GCC_660
|
|||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2C, USB, UFS, SDDC, PCIe, etc.
|
||||
|
||||
config SDM_MMCC_660
|
||||
tristate "SDM660 Multimedia Clock Controller"
|
||||
select SDM_GCC_660
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the multimedia clock controller on SDM660 devices.
|
||||
Say Y if you want to support multimedia devices such as display,
|
||||
graphics, video encode/decode, camera, etc.
|
||||
|
||||
config SDM_GPUCC_660
|
||||
tristate "SDM660 Graphics Clock Controller"
|
||||
select SDM_GCC_660
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the graphics clock controller on SDM630/636/660 devices.
|
||||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics
|
||||
|
||||
config QCS_TURING_404
|
||||
tristate "QCS404 Turing Clock Controller"
|
||||
help
|
||||
|
@ -454,6 +507,14 @@ config SM_GCC_8250
|
|||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config SM_GCC_8350
|
||||
tristate "SM8350 Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on SM8350 devices.
|
||||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config SM_GPUCC_8150
|
||||
tristate "SM8150 Graphics Clock Controller"
|
||||
select SM_GCC_8150
|
||||
|
|
|
@ -44,8 +44,10 @@ 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_A7PLL) += a7-pll.o
|
||||
obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
|
||||
obj-$(CONFIG_QCOM_CLK_APCC_MSM8996) += clk-cpu-8996.o
|
||||
obj-$(CONFIG_QCOM_CLK_APCS_SDX55) += apcs-sdx55.o
|
||||
obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
|
||||
obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
|
||||
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
|
||||
|
@ -55,6 +57,8 @@ obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
|
|||
obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o
|
||||
obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o
|
||||
obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o
|
||||
obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
|
||||
obj-$(CONFIG_SC_LPASS_CORECC_7180) += lpasscorecc-sc7180.o
|
||||
obj-$(CONFIG_SC_MSS_7180) += mss-sc7180.o
|
||||
|
@ -62,6 +66,8 @@ 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
|
||||
obj-$(CONFIG_SDM_MMCC_660) += mmcc-sdm660.o
|
||||
obj-$(CONFIG_SDM_GPUCC_660) += gpucc-sdm660.o
|
||||
obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
|
||||
obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
|
||||
obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
|
||||
|
@ -70,6 +76,7 @@ obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o
|
|||
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
|
||||
obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
|
||||
obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
|
||||
obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
|
||||
obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
|
||||
obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Qualcomm A7 PLL driver
|
||||
*
|
||||
* Copyright (c) 2020, Linaro Limited
|
||||
* Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
|
||||
#define LUCID_PLL_OFF_L_VAL 0x04
|
||||
|
||||
static const struct pll_vco lucid_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll a7pll = {
|
||||
.offset = 0x100,
|
||||
.vco_table = lucid_vco,
|
||||
.num_vco = ARRAY_SIZE(lucid_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "a7pll",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_lucid_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config a7pll_config = {
|
||||
.l = 0x39,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x2261,
|
||||
.config_ctl_hi1_val = 0x029A699C,
|
||||
.user_ctl_val = 0x1,
|
||||
.user_ctl_hi_val = 0x805,
|
||||
};
|
||||
|
||||
static const struct regmap_config a7pll_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x1000,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static int qcom_a7pll_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
u32 l_val;
|
||||
int ret;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
regmap = devm_regmap_init_mmio(dev, base, &a7pll_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* Configure PLL only if the l_val is zero */
|
||||
regmap_read(regmap, a7pll.offset + LUCID_PLL_OFF_L_VAL, &l_val);
|
||||
if (!l_val)
|
||||
clk_lucid_pll_configure(&a7pll, regmap, &a7pll_config);
|
||||
|
||||
ret = devm_clk_register_regmap(dev, &a7pll.clkr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
&a7pll.clkr.hw);
|
||||
}
|
||||
|
||||
static const struct of_device_id qcom_a7pll_match_table[] = {
|
||||
{ .compatible = "qcom,sdx55-a7pll" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver qcom_a7pll_driver = {
|
||||
.probe = qcom_a7pll_probe,
|
||||
.driver = {
|
||||
.name = "qcom-a7pll",
|
||||
.of_match_table = qcom_a7pll_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(qcom_a7pll_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm A7 PLL Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,149 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Qualcomm SDX55 APCS clock controller driver
|
||||
*
|
||||
* Copyright (c) 2020, Linaro Limited
|
||||
* Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-mux-div.h"
|
||||
|
||||
static const u32 apcs_mux_clk_parent_map[] = { 0, 1, 5 };
|
||||
|
||||
static const struct clk_parent_data pdata[] = {
|
||||
{ .fw_name = "ref" },
|
||||
{ .fw_name = "aux" },
|
||||
{ .fw_name = "pll" },
|
||||
};
|
||||
|
||||
/*
|
||||
* We use the notifier function for switching to a temporary safe configuration
|
||||
* (mux and divider), while the A7 PLL is reconfigured.
|
||||
*/
|
||||
static int a7cc_notifier_cb(struct notifier_block *nb, unsigned long event,
|
||||
void *data)
|
||||
{
|
||||
int ret = 0;
|
||||
struct clk_regmap_mux_div *md = container_of(nb,
|
||||
struct clk_regmap_mux_div,
|
||||
clk_nb);
|
||||
if (event == PRE_RATE_CHANGE)
|
||||
/* set the mux and divider to safe frequency (400mhz) */
|
||||
ret = mux_div_set_src_div(md, 1, 2);
|
||||
|
||||
return notifier_from_errno(ret);
|
||||
}
|
||||
|
||||
static int qcom_apcs_sdx55_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *parent = dev->parent;
|
||||
struct device *cpu_dev;
|
||||
struct clk_regmap_mux_div *a7cc;
|
||||
struct regmap *regmap;
|
||||
struct clk_init_data init = { };
|
||||
int ret;
|
||||
|
||||
regmap = dev_get_regmap(parent, NULL);
|
||||
if (!regmap) {
|
||||
dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
a7cc = devm_kzalloc(dev, sizeof(*a7cc), GFP_KERNEL);
|
||||
if (!a7cc)
|
||||
return -ENOMEM;
|
||||
|
||||
init.name = "a7mux";
|
||||
init.parent_data = pdata;
|
||||
init.num_parents = ARRAY_SIZE(pdata);
|
||||
init.ops = &clk_regmap_mux_div_ops;
|
||||
|
||||
a7cc->clkr.hw.init = &init;
|
||||
a7cc->clkr.regmap = regmap;
|
||||
a7cc->reg_offset = 0x8;
|
||||
a7cc->hid_width = 5;
|
||||
a7cc->hid_shift = 0;
|
||||
a7cc->src_width = 3;
|
||||
a7cc->src_shift = 8;
|
||||
a7cc->parent_map = apcs_mux_clk_parent_map;
|
||||
|
||||
a7cc->pclk = devm_clk_get(parent, "pll");
|
||||
if (IS_ERR(a7cc->pclk)) {
|
||||
ret = PTR_ERR(a7cc->pclk);
|
||||
if (ret != -EPROBE_DEFER)
|
||||
dev_err_probe(dev, ret, "Failed to get PLL clk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
a7cc->clk_nb.notifier_call = a7cc_notifier_cb;
|
||||
ret = clk_notifier_register(a7cc->pclk, &a7cc->clk_nb);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Failed to register clock notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_clk_register_regmap(dev, &a7cc->clkr);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Failed to register regmap clock\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
|
||||
&a7cc->clkr.hw);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "Failed to add clock provider\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, a7cc);
|
||||
|
||||
/*
|
||||
* Attach the power domain to cpudev. Since there is no dedicated driver
|
||||
* for CPUs and the SDX55 platform lacks hardware specific CPUFreq
|
||||
* driver, there seems to be no better place to do this. So do it here!
|
||||
*/
|
||||
cpu_dev = get_cpu_device(0);
|
||||
dev_pm_domain_attach(cpu_dev, true);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
clk_notifier_unregister(a7cc->pclk, &a7cc->clk_nb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qcom_apcs_sdx55_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *cpu_dev = get_cpu_device(0);
|
||||
struct clk_regmap_mux_div *a7cc = platform_get_drvdata(pdev);
|
||||
|
||||
clk_notifier_unregister(a7cc->pclk, &a7cc->clk_nb);
|
||||
dev_pm_domain_detach(cpu_dev, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver qcom_apcs_sdx55_clk_driver = {
|
||||
.probe = qcom_apcs_sdx55_clk_probe,
|
||||
.remove = qcom_apcs_sdx55_clk_remove,
|
||||
.driver = {
|
||||
.name = "qcom-sdx55-acps-clk",
|
||||
},
|
||||
};
|
||||
module_platform_driver(qcom_apcs_sdx55_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Qualcomm SDX55 APCS clock driver");
|
|
@ -156,6 +156,12 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
|
|||
/* LUCID PLL specific settings and offsets */
|
||||
#define LUCID_PCAL_DONE BIT(27)
|
||||
|
||||
/* LUCID 5LPE PLL specific settings and offsets */
|
||||
#define LUCID_5LPE_PCAL_DONE BIT(11)
|
||||
#define LUCID_5LPE_ALPHA_PLL_ACK_LATCH BIT(13)
|
||||
#define LUCID_5LPE_PLL_LATCH_INPUT BIT(14)
|
||||
#define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21)
|
||||
|
||||
#define pll_alpha_width(p) \
|
||||
((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \
|
||||
ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH)
|
||||
|
@ -777,15 +783,15 @@ static long alpha_pll_huayra_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
static int trion_pll_is_enabled(struct clk_alpha_pll *pll,
|
||||
struct regmap *regmap)
|
||||
{
|
||||
u32 mode_regval, opmode_regval;
|
||||
u32 mode_val, opmode_val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, PLL_MODE(pll), &mode_regval);
|
||||
ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_regval);
|
||||
ret = regmap_read(regmap, PLL_MODE(pll), &mode_val);
|
||||
ret |= regmap_read(regmap, PLL_OPMODE(pll), &opmode_val);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return ((opmode_regval & PLL_RUN) && (mode_regval & PLL_OUTCTRL));
|
||||
return ((opmode_val & PLL_RUN) && (mode_val & PLL_OUTCTRL));
|
||||
}
|
||||
|
||||
static int clk_trion_pll_is_enabled(struct clk_hw *hw)
|
||||
|
@ -1445,12 +1451,12 @@ EXPORT_SYMBOL_GPL(clk_trion_pll_configure);
|
|||
static int __alpha_pll_trion_prepare(struct clk_hw *hw, u32 pcal_done)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 regval;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/* Return early if calibration is not needed. */
|
||||
regmap_read(pll->clkr.regmap, PLL_STATUS(pll), ®val);
|
||||
if (regval & pcal_done)
|
||||
regmap_read(pll->clkr.regmap, PLL_STATUS(pll), &val);
|
||||
if (val & pcal_done)
|
||||
return 0;
|
||||
|
||||
/* On/off to calibrate */
|
||||
|
@ -1471,12 +1477,12 @@ static int alpha_pll_lucid_prepare(struct clk_hw *hw)
|
|||
return __alpha_pll_trion_prepare(hw, LUCID_PCAL_DONE);
|
||||
}
|
||||
|
||||
static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
static int __alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate, u32 latch_bit, u32 latch_ack)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
unsigned long rrate;
|
||||
u32 regval, l, alpha_width = pll_alpha_width(pll);
|
||||
u32 val, l, alpha_width = pll_alpha_width(pll);
|
||||
u64 a;
|
||||
int ret;
|
||||
|
||||
|
@ -1490,22 +1496,20 @@ static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
|
||||
|
||||
/* Latch the PLL input */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
|
||||
PLL_UPDATE, PLL_UPDATE);
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, latch_bit);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Wait for 2 reference cycles before checking the ACK bit. */
|
||||
udelay(1);
|
||||
regmap_read(pll->clkr.regmap, PLL_MODE(pll), ®val);
|
||||
if (!(regval & ALPHA_PLL_ACK_LATCH)) {
|
||||
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
||||
if (!(val & latch_ack)) {
|
||||
pr_err("Lucid PLL latch failed. Output may be unstable!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Return the latch input to 0 */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll),
|
||||
PLL_UPDATE, 0);
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), latch_bit, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1520,6 +1524,12 @@ static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
return __alpha_pll_trion_set_rate(hw, rate, prate, PLL_UPDATE, ALPHA_PLL_ACK_LATCH);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_trion_ops = {
|
||||
.prepare = alpha_pll_trion_prepare,
|
||||
.enable = clk_trion_pll_enable,
|
||||
|
@ -1600,3 +1610,170 @@ const struct clk_ops clk_alpha_pll_agera_ops = {
|
|||
.set_rate = clk_alpha_pll_agera_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
|
||||
|
||||
static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* If in FSM mode, just vote for it */
|
||||
if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {
|
||||
ret = clk_enable_regmap(hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
return wait_for_pll_enable_lock(pll);
|
||||
}
|
||||
|
||||
/* Check if PLL is already enabled, return if enabled */
|
||||
ret = trion_pll_is_enabled(pll, pll->clkr.regmap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_RUN);
|
||||
|
||||
ret = wait_for_pll_enable_lock(pll);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable the PLL outputs */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, PLL_OUT_MASK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Enable the global PLL outputs */
|
||||
return regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL);
|
||||
}
|
||||
|
||||
static void alpha_pll_lucid_5lpe_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* If in FSM mode, just unvote it */
|
||||
if (val & LUCID_5LPE_ENABLE_VOTE_RUN) {
|
||||
clk_disable_regmap(hw);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable the global PLL output */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* Disable the PLL outputs */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_OUT_MASK, 0);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* Place the PLL mode in STANDBY */
|
||||
regmap_write(pll->clkr.regmap, PLL_OPMODE(pll), PLL_STANDBY);
|
||||
}
|
||||
|
||||
/*
|
||||
* The Lucid 5LPE PLL requires a power-on self-calibration which happens
|
||||
* when the PLL comes out of reset. Calibrate in case it is not completed.
|
||||
*/
|
||||
static int alpha_pll_lucid_5lpe_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
struct clk_hw *p;
|
||||
u32 val = 0;
|
||||
int ret;
|
||||
|
||||
/* Return early if calibration is not needed. */
|
||||
regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
|
||||
if (val & LUCID_5LPE_PCAL_DONE)
|
||||
return 0;
|
||||
|
||||
p = clk_hw_get_parent(hw);
|
||||
if (!p)
|
||||
return -EINVAL;
|
||||
|
||||
ret = alpha_pll_lucid_5lpe_enable(hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
alpha_pll_lucid_5lpe_disable(hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alpha_pll_lucid_5lpe_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
return __alpha_pll_trion_set_rate(hw, rate, prate,
|
||||
LUCID_5LPE_PLL_LATCH_INPUT,
|
||||
LUCID_5LPE_ALPHA_PLL_ACK_LATCH);
|
||||
}
|
||||
|
||||
static int clk_lucid_5lpe_pll_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw);
|
||||
int i, val = 0, div, ret;
|
||||
u32 mask;
|
||||
|
||||
/*
|
||||
* If the PLL is in FSM mode, then treat set_rate callback as a
|
||||
* no-operation.
|
||||
*/
|
||||
ret = regmap_read(pll->clkr.regmap, PLL_USER_CTL(pll), &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (val & LUCID_5LPE_ENABLE_VOTE_RUN)
|
||||
return 0;
|
||||
|
||||
div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
|
||||
for (i = 0; i < pll->num_post_div; i++) {
|
||||
if (pll->post_div_table[i].div == div) {
|
||||
val = pll->post_div_table[i].val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mask = GENMASK(pll->width + pll->post_div_shift - 1, pll->post_div_shift);
|
||||
return regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
|
||||
mask, val << pll->post_div_shift);
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_lucid_5lpe_ops = {
|
||||
.prepare = alpha_pll_lucid_5lpe_prepare,
|
||||
.enable = alpha_pll_lucid_5lpe_enable,
|
||||
.disable = alpha_pll_lucid_5lpe_disable,
|
||||
.is_enabled = clk_trion_pll_is_enabled,
|
||||
.recalc_rate = clk_trion_pll_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_round_rate,
|
||||
.set_rate = alpha_pll_lucid_5lpe_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL(clk_alpha_pll_lucid_5lpe_ops);
|
||||
|
||||
const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops = {
|
||||
.enable = alpha_pll_lucid_5lpe_enable,
|
||||
.disable = alpha_pll_lucid_5lpe_disable,
|
||||
.is_enabled = clk_trion_pll_is_enabled,
|
||||
.recalc_rate = clk_trion_pll_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_round_rate,
|
||||
};
|
||||
EXPORT_SYMBOL(clk_alpha_pll_fixed_lucid_5lpe_ops);
|
||||
|
||||
const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops = {
|
||||
.recalc_rate = clk_alpha_pll_postdiv_fabia_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_postdiv_fabia_round_rate,
|
||||
.set_rate = clk_lucid_5lpe_pll_postdiv_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL(clk_alpha_pll_postdiv_lucid_5lpe_ops);
|
||||
|
|
|
@ -144,6 +144,10 @@ extern const struct clk_ops clk_alpha_pll_lucid_ops;
|
|||
extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_agera_ops;
|
||||
|
||||
extern const struct clk_ops clk_alpha_pll_lucid_5lpe_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops;
|
||||
|
||||
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
|
|
|
@ -153,6 +153,15 @@ struct clk_rcg2 {
|
|||
|
||||
#define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr)
|
||||
|
||||
struct clk_rcg2_gfx3d {
|
||||
u8 div;
|
||||
struct clk_rcg2 rcg;
|
||||
struct clk_hw **hws;
|
||||
};
|
||||
|
||||
#define to_clk_rcg2_gfx3d(_hw) \
|
||||
container_of(to_clk_rcg2(_hw), struct clk_rcg2_gfx3d, rcg)
|
||||
|
||||
extern const struct clk_ops clk_rcg2_ops;
|
||||
extern const struct clk_ops clk_rcg2_floor_ops;
|
||||
extern const struct clk_ops clk_edp_pixel_ops;
|
||||
|
|
|
@ -728,40 +728,51 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw,
|
|||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_rate_request parent_req = { };
|
||||
struct clk_hw *p2, *p8, *p9, *xo;
|
||||
unsigned long p9_rate;
|
||||
struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw);
|
||||
struct clk_hw *xo, *p0, *p1, *p2;
|
||||
unsigned long request, p0_rate;
|
||||
int ret;
|
||||
|
||||
p0 = cgfx->hws[0];
|
||||
p1 = cgfx->hws[1];
|
||||
p2 = cgfx->hws[2];
|
||||
/*
|
||||
* This function does ping-pong the RCG between PLLs: if we don't
|
||||
* have at least one fixed PLL and two variable ones,
|
||||
* then it's not going to work correctly.
|
||||
*/
|
||||
if (WARN_ON(!p0 || !p1 || !p2))
|
||||
return -EINVAL;
|
||||
|
||||
xo = clk_hw_get_parent_by_index(hw, 0);
|
||||
if (req->rate == clk_hw_get_rate(xo)) {
|
||||
req->best_parent_hw = xo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p9 = clk_hw_get_parent_by_index(hw, 2);
|
||||
p2 = clk_hw_get_parent_by_index(hw, 3);
|
||||
p8 = clk_hw_get_parent_by_index(hw, 4);
|
||||
request = req->rate;
|
||||
if (cgfx->div > 1)
|
||||
parent_req.rate = request = request * cgfx->div;
|
||||
|
||||
/* PLL9 is a fixed rate PLL */
|
||||
p9_rate = clk_hw_get_rate(p9);
|
||||
/* This has to be a fixed rate PLL */
|
||||
p0_rate = clk_hw_get_rate(p0);
|
||||
|
||||
parent_req.rate = req->rate = min(req->rate, p9_rate);
|
||||
if (req->rate == p9_rate) {
|
||||
req->rate = req->best_parent_rate = p9_rate;
|
||||
req->best_parent_hw = p9;
|
||||
if (request == p0_rate) {
|
||||
req->rate = req->best_parent_rate = p0_rate;
|
||||
req->best_parent_hw = p0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (req->best_parent_hw == p9) {
|
||||
if (req->best_parent_hw == p0) {
|
||||
/* Are we going back to a previously used rate? */
|
||||
if (clk_hw_get_rate(p8) == req->rate)
|
||||
req->best_parent_hw = p8;
|
||||
else
|
||||
if (clk_hw_get_rate(p2) == request)
|
||||
req->best_parent_hw = p2;
|
||||
} else if (req->best_parent_hw == p8) {
|
||||
req->best_parent_hw = p2;
|
||||
else
|
||||
req->best_parent_hw = p1;
|
||||
} else if (req->best_parent_hw == p2) {
|
||||
req->best_parent_hw = p1;
|
||||
} else {
|
||||
req->best_parent_hw = p8;
|
||||
req->best_parent_hw = p2;
|
||||
}
|
||||
|
||||
ret = __clk_determine_rate(req->best_parent_hw, &parent_req);
|
||||
|
@ -769,6 +780,8 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw,
|
|||
return ret;
|
||||
|
||||
req->rate = req->best_parent_rate = parent_req.rate;
|
||||
if (cgfx->div > 1)
|
||||
req->rate /= cgfx->div;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -776,12 +789,16 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw,
|
|||
static int clk_gfx3d_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate, u8 index)
|
||||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw);
|
||||
struct clk_rcg2 *rcg = &cgfx->rcg;
|
||||
u32 cfg;
|
||||
int ret;
|
||||
|
||||
/* Just mux it, we don't use the division or m/n hardware */
|
||||
cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
/* On some targets, the GFX3D RCG may need to divide PLL frequency */
|
||||
if (cgfx->div > 1)
|
||||
cfg |= ((2 * cgfx->div) - 1) << CFG_SRC_DIV_SHIFT;
|
||||
|
||||
ret = regmap_write(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -87,6 +87,7 @@ EXPORT_SYMBOL_GPL(clk_disable_regmap);
|
|||
/**
|
||||
* devm_clk_register_regmap - register a clk_regmap clock
|
||||
*
|
||||
* @dev: reference to the caller's device
|
||||
* @rclk: clk to operate on
|
||||
*
|
||||
* Clocks that use regmap for their register I/O should register their
|
||||
|
|
|
@ -73,62 +73,6 @@
|
|||
}, \
|
||||
}
|
||||
|
||||
#define DEFINE_CLK_RPM_PXO_BRANCH(_platform, _name, _active, r_id, r) \
|
||||
static struct clk_rpm _platform##_##_active; \
|
||||
static struct clk_rpm _platform##_##_name = { \
|
||||
.rpm_clk_id = (r_id), \
|
||||
.active_only = true, \
|
||||
.peer = &_platform##_##_active, \
|
||||
.rate = (r), \
|
||||
.branch = true, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_rpm_branch_ops, \
|
||||
.name = #_name, \
|
||||
.parent_names = (const char *[]){ "pxo_board" }, \
|
||||
.num_parents = 1, \
|
||||
}, \
|
||||
}; \
|
||||
static struct clk_rpm _platform##_##_active = { \
|
||||
.rpm_clk_id = (r_id), \
|
||||
.peer = &_platform##_##_name, \
|
||||
.rate = (r), \
|
||||
.branch = true, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_rpm_branch_ops, \
|
||||
.name = #_active, \
|
||||
.parent_names = (const char *[]){ "pxo_board" }, \
|
||||
.num_parents = 1, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define DEFINE_CLK_RPM_CXO_BRANCH(_platform, _name, _active, r_id, r) \
|
||||
static struct clk_rpm _platform##_##_active; \
|
||||
static struct clk_rpm _platform##_##_name = { \
|
||||
.rpm_clk_id = (r_id), \
|
||||
.peer = &_platform##_##_active, \
|
||||
.rate = (r), \
|
||||
.branch = true, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_rpm_branch_ops, \
|
||||
.name = #_name, \
|
||||
.parent_names = (const char *[]){ "cxo_board" }, \
|
||||
.num_parents = 1, \
|
||||
}, \
|
||||
}; \
|
||||
static struct clk_rpm _platform##_##_active = { \
|
||||
.rpm_clk_id = (r_id), \
|
||||
.active_only = true, \
|
||||
.peer = &_platform##_##_name, \
|
||||
.rate = (r), \
|
||||
.branch = true, \
|
||||
.hw.init = &(struct clk_init_data){ \
|
||||
.ops = &clk_rpm_branch_ops, \
|
||||
.name = #_active, \
|
||||
.parent_names = (const char *[]){ "cxo_board" }, \
|
||||
.num_parents = 1, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define to_clk_rpm(_hw) container_of(_hw, struct clk_rpm, hw)
|
||||
|
||||
struct rpm_cc;
|
||||
|
@ -450,13 +394,6 @@ static const struct clk_ops clk_rpm_ops = {
|
|||
.recalc_rate = clk_rpm_recalc_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_rpm_branch_ops = {
|
||||
.prepare = clk_rpm_prepare,
|
||||
.unprepare = clk_rpm_unprepare,
|
||||
.round_rate = clk_rpm_round_rate,
|
||||
.recalc_rate = clk_rpm_recalc_rate,
|
||||
};
|
||||
|
||||
/* MSM8660/APQ8060 */
|
||||
DEFINE_CLK_RPM(msm8660, afab_clk, afab_a_clk, QCOM_RPM_APPS_FABRIC_CLK);
|
||||
DEFINE_CLK_RPM(msm8660, sfab_clk, sfab_a_clk, QCOM_RPM_SYS_FABRIC_CLK);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
@ -348,6 +348,10 @@ DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1);
|
|||
DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk1, rf_clk1_ao, "rfclkd1", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk2, rf_clk2_ao, "rfclkd2", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk3, rf_clk3_ao, "rfclkd3", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sc8180x, rf_clk4, rf_clk4_ao, "rfclkd4", 1);
|
||||
DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0");
|
||||
DEFINE_CLK_RPMH_BCM(sdm845, ce, "CE0");
|
||||
|
||||
|
@ -431,6 +435,26 @@ static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
|
|||
.num_clks = ARRAY_SIZE(sc7180_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *sc8180x_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
|
||||
[RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
|
||||
[RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
|
||||
[RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
|
||||
[RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
|
||||
[RPMH_RF_CLK1] = &sc8180x_rf_clk1.hw,
|
||||
[RPMH_RF_CLK1_A] = &sc8180x_rf_clk1_ao.hw,
|
||||
[RPMH_RF_CLK2] = &sc8180x_rf_clk2.hw,
|
||||
[RPMH_RF_CLK2_A] = &sc8180x_rf_clk2_ao.hw,
|
||||
[RPMH_RF_CLK3] = &sc8180x_rf_clk3.hw,
|
||||
[RPMH_RF_CLK3_A] = &sc8180x_rf_clk3_ao.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sc8180x = {
|
||||
.clks = sc8180x_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sc8180x_rpmh_clocks),
|
||||
};
|
||||
|
||||
DEFINE_CLK_RPMH_VRM(sm8250, ln_bb_clk1, ln_bb_clk1_ao, "lnbclka1", 2);
|
||||
|
||||
static struct clk_hw *sm8250_rpmh_clocks[] = {
|
||||
|
@ -486,6 +510,27 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
|
|||
.num_clks = ARRAY_SIZE(sm8350_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *sc7280_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
|
||||
[RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
|
||||
[RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
|
||||
[RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
|
||||
[RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
|
||||
[RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
|
||||
[RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
|
||||
[RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
|
||||
[RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
|
||||
[RPMH_IPA_CLK] = &sdm845_ipa.hw,
|
||||
[RPMH_PKA_CLK] = &sm8350_pka.hw,
|
||||
[RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sc7280 = {
|
||||
.clks = sc7280_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sc7280_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
|
@ -570,11 +615,13 @@ 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,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
|
||||
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
|
||||
{ .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55},
|
||||
{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
|
||||
{ .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
|
||||
{ .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
|
||||
{ .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
|
||||
|
|
|
@ -1276,16 +1276,15 @@ static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct clk_fepll *pll = to_clk_fepll(hw);
|
||||
const struct freq_tbl *f;
|
||||
u32 mask;
|
||||
int ret;
|
||||
|
||||
f = qcom_find_freq(pll->freq_tbl, rate);
|
||||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift;
|
||||
ret = regmap_update_bits(pll->cdiv.clkr.regmap,
|
||||
pll->cdiv.reg, mask,
|
||||
f->pre_div << pll->cdiv.shift);
|
||||
regmap_update_bits(pll->cdiv.clkr.regmap,
|
||||
pll->cdiv.reg, mask,
|
||||
f->pre_div << pll->cdiv.shift);
|
||||
/*
|
||||
* There is no status bit which can be checked for successful CPU
|
||||
* divider update operation so using delay for the same.
|
||||
|
|
|
@ -135,7 +135,7 @@ static struct pll_vco fabia_vco[] = {
|
|||
|
||||
static struct clk_alpha_pll gpll0 = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr = {
|
||||
|
@ -145,58 +145,58 @@ static struct clk_alpha_pll gpll0 = {
|
|||
.name = "gpll0",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll0_out_even = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll0_out_even",
|
||||
.parent_names = (const char *[]){ "gpll0" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll0_out_main = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll0_out_main",
|
||||
.parent_names = (const char *[]){ "gpll0" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll0_out_odd = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll0_out_odd",
|
||||
.parent_names = (const char *[]){ "gpll0" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll0_out_test = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll0_out_test",
|
||||
.parent_names = (const char *[]){ "gpll0" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll1 = {
|
||||
.offset = 0x1000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr = {
|
||||
|
@ -206,58 +206,58 @@ static struct clk_alpha_pll gpll1 = {
|
|||
.name = "gpll1",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll1_out_even = {
|
||||
.offset = 0x1000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll1_out_even",
|
||||
.parent_names = (const char *[]){ "gpll1" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll1_out_main = {
|
||||
.offset = 0x1000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll1_out_main",
|
||||
.parent_names = (const char *[]){ "gpll1" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll1_out_odd = {
|
||||
.offset = 0x1000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll1_out_odd",
|
||||
.parent_names = (const char *[]){ "gpll1" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll1_out_test = {
|
||||
.offset = 0x1000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll1_out_test",
|
||||
.parent_names = (const char *[]){ "gpll1" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll2 = {
|
||||
.offset = 0x2000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr = {
|
||||
|
@ -267,58 +267,58 @@ static struct clk_alpha_pll gpll2 = {
|
|||
.name = "gpll2",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll2_out_even = {
|
||||
.offset = 0x2000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll2_out_even",
|
||||
.parent_names = (const char *[]){ "gpll2" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll2_out_main = {
|
||||
.offset = 0x2000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll2_out_main",
|
||||
.parent_names = (const char *[]){ "gpll2" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll2_out_odd = {
|
||||
.offset = 0x2000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll2_out_odd",
|
||||
.parent_names = (const char *[]){ "gpll2" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll2_out_test = {
|
||||
.offset = 0x2000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll2_out_test",
|
||||
.parent_names = (const char *[]){ "gpll2" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll3 = {
|
||||
.offset = 0x3000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr = {
|
||||
|
@ -328,58 +328,58 @@ static struct clk_alpha_pll gpll3 = {
|
|||
.name = "gpll3",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll3_out_even = {
|
||||
.offset = 0x3000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll3_out_even",
|
||||
.parent_names = (const char *[]){ "gpll3" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll3_out_main = {
|
||||
.offset = 0x3000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll3_out_main",
|
||||
.parent_names = (const char *[]){ "gpll3" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll3_out_odd = {
|
||||
.offset = 0x3000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll3_out_odd",
|
||||
.parent_names = (const char *[]){ "gpll3" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll3_out_test = {
|
||||
.offset = 0x3000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll3_out_test",
|
||||
.parent_names = (const char *[]){ "gpll3" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll4 = {
|
||||
.offset = 0x77000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr = {
|
||||
|
@ -389,52 +389,52 @@ static struct clk_alpha_pll gpll4 = {
|
|||
.name = "gpll4",
|
||||
.parent_names = (const char *[]){ "xo" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll4_out_even = {
|
||||
.offset = 0x77000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll4_out_even",
|
||||
.parent_names = (const char *[]){ "gpll4" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll4_out_main = {
|
||||
.offset = 0x77000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll4_out_main",
|
||||
.parent_names = (const char *[]){ "gpll4" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll4_out_odd = {
|
||||
.offset = 0x77000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll4_out_odd",
|
||||
.parent_names = (const char *[]){ "gpll4" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll4_out_test = {
|
||||
.offset = 0x77000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpll4_out_test",
|
||||
.parent_names = (const char *[]){ "gpll4" },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ops,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1341,6 +1341,22 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mmss_gpll0_clk = {
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x5200c,
|
||||
.enable_mask = BIT(1),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_mmss_gpll0_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"gpll0_out_main",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_gpll0_div_clk_src = {
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
|
@ -2065,6 +2081,12 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = {
|
|||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_gpu_cfg_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
/*
|
||||
* The GPU IOMMU depends on this clock and hypervisor
|
||||
* will crash the SoC if this clock goes down, due to
|
||||
* secure contexts protection.
|
||||
*/
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -2144,6 +2166,25 @@ static struct clk_branch gcc_hmss_trig_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct freq_tbl ftbl_hmss_gpll0_clk_src[] = {
|
||||
F( 300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
|
||||
F( 600000000, P_GPLL0_OUT_MAIN, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 hmss_gpll0_clk_src = {
|
||||
.cmd_rcgr = 0x4805c,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_hmss_gpll0_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data) {
|
||||
.name = "hmss_gpll0_clk_src",
|
||||
.parent_names = gcc_parent_names_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_names_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
|
||||
.halt_reg = 0x9004,
|
||||
.halt_check = BRANCH_HALT,
|
||||
|
@ -2944,6 +2985,8 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
|||
[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
|
||||
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
|
||||
[GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
|
||||
[GCC_MMSS_GPLL0_CLK] = &gcc_mmss_gpll0_clk.clkr,
|
||||
[HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8998_gdscs[] = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
@ -919,19 +919,6 @@ static struct clk_branch gcc_camera_throttle_hf_axi_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_camera_xo_clk = {
|
||||
.halt_reg = 0xb02c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xb02c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_camera_xo_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ce1_ahb_clk = {
|
||||
.halt_reg = 0x4100c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
|
@ -1096,19 +1083,6 @@ static struct clk_branch gcc_disp_throttle_hf_axi_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_disp_xo_clk = {
|
||||
.halt_reg = 0xb030,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xb030,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_disp_xo_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_gp1_clk = {
|
||||
.halt_reg = 0x64000,
|
||||
.halt_check = BRANCH_HALT,
|
||||
|
@ -2159,19 +2133,6 @@ static struct clk_branch gcc_video_throttle_axi_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_video_xo_clk = {
|
||||
.halt_reg = 0xb028,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xb028,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_video_xo_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_cfg_ahb_clk = {
|
||||
.halt_reg = 0x8a000,
|
||||
.halt_check = BRANCH_HALT,
|
||||
|
@ -2304,7 +2265,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
|
|||
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
|
||||
[GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr,
|
||||
[GCC_CAMERA_THROTTLE_HF_AXI_CLK] = &gcc_camera_throttle_hf_axi_clk.clkr,
|
||||
[GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr,
|
||||
[GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr,
|
||||
[GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr,
|
||||
[GCC_CE1_CLK] = &gcc_ce1_clk.clkr,
|
||||
|
@ -2317,7 +2277,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
|
|||
[GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
|
||||
[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
|
||||
[GCC_DISP_THROTTLE_HF_AXI_CLK] = &gcc_disp_throttle_hf_axi_clk.clkr,
|
||||
[GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr,
|
||||
[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
|
||||
[GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
|
||||
[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
|
||||
|
@ -2413,7 +2372,6 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
|
|||
[GCC_VIDEO_AXI_CLK] = &gcc_video_axi_clk.clkr,
|
||||
[GCC_VIDEO_GPLL0_DIV_CLK_SRC] = &gcc_video_gpll0_div_clk_src.clkr,
|
||||
[GCC_VIDEO_THROTTLE_AXI_CLK] = &gcc_video_throttle_axi_clk.clkr,
|
||||
[GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr,
|
||||
[GPLL0] = &gpll0.clkr,
|
||||
[GPLL0_OUT_EVEN] = &gpll0_out_even.clkr,
|
||||
[GPLL6] = &gpll6.clkr,
|
||||
|
@ -2510,6 +2468,9 @@ static int gcc_sc7180_probe(struct platform_device *pdev)
|
|||
regmap_update_bits(regmap, 0x0b004, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x0b008, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x0b00c, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x0b02c, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x0b028, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x0b030, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));
|
||||
|
||||
ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1571,6 +1571,7 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = {
|
|||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_gpu_cfg_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -1684,6 +1685,12 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
|
|||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_mmss_noc_cfg_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
/*
|
||||
* Any access to mmss depends on this clock.
|
||||
* Gating this clock has been shown to crash the system
|
||||
* when mmssnoc_axi_rpm_clk is inited in rpmcc.
|
||||
*/
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -183,7 +183,10 @@ static inline int gdsc_assert_reset(struct gdsc *sc)
|
|||
static inline void gdsc_force_mem_on(struct gdsc *sc)
|
||||
{
|
||||
int i;
|
||||
u32 mask = RETAIN_MEM | RETAIN_PERIPH;
|
||||
u32 mask = RETAIN_MEM;
|
||||
|
||||
if (!(sc->flags & NO_RET_PERIPH))
|
||||
mask |= RETAIN_PERIPH;
|
||||
|
||||
for (i = 0; i < sc->cxc_count; i++)
|
||||
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
|
||||
|
@ -192,7 +195,10 @@ static inline void gdsc_force_mem_on(struct gdsc *sc)
|
|||
static inline void gdsc_clear_mem_on(struct gdsc *sc)
|
||||
{
|
||||
int i;
|
||||
u32 mask = RETAIN_MEM | RETAIN_PERIPH;
|
||||
u32 mask = RETAIN_MEM;
|
||||
|
||||
if (!(sc->flags & NO_RET_PERIPH))
|
||||
mask |= RETAIN_PERIPH;
|
||||
|
||||
for (i = 0; i < sc->cxc_count; i++)
|
||||
regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
|
||||
|
|
|
@ -42,7 +42,7 @@ struct gdsc {
|
|||
#define PWRSTS_ON BIT(2)
|
||||
#define PWRSTS_OFF_ON (PWRSTS_OFF | PWRSTS_ON)
|
||||
#define PWRSTS_RET_ON (PWRSTS_RET | PWRSTS_ON)
|
||||
const u8 flags;
|
||||
const u16 flags;
|
||||
#define VOTABLE BIT(0)
|
||||
#define CLAMP_IO BIT(1)
|
||||
#define HW_CTRL BIT(2)
|
||||
|
@ -51,6 +51,7 @@ struct gdsc {
|
|||
#define POLL_CFG_GDSCR BIT(5)
|
||||
#define ALWAYS_ON BIT(6)
|
||||
#define RETAIN_FF_ENABLE BIT(7)
|
||||
#define NO_RET_PERIPH BIT(8)
|
||||
struct reset_controller_dev *rcdev;
|
||||
unsigned int *resets;
|
||||
unsigned int reset_count;
|
||||
|
|
|
@ -50,6 +50,11 @@ static struct clk_branch gpucc_cxo_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct pll_vco fabia_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
{ 125000000, 1000000000, 1 },
|
||||
};
|
||||
|
||||
static const struct clk_div_table post_div_table_fabia_even[] = {
|
||||
{ 0x0, 1 },
|
||||
{ 0x1, 2 },
|
||||
|
@ -61,11 +66,13 @@ static const struct clk_div_table post_div_table_fabia_even[] = {
|
|||
static struct clk_alpha_pll gpupll0 = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
|
||||
.vco_table = fabia_vco,
|
||||
.num_vco = ARRAY_SIZE(fabia_vco),
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpupll0",
|
||||
.parent_hws = (const struct clk_hw *[]){ &gpucc_cxo_clk.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_fixed_fabia_ops,
|
||||
.ops = &clk_alpha_pll_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -80,6 +87,7 @@ static struct clk_alpha_pll_postdiv gpupll0_out_even = {
|
|||
.name = "gpupll0_out_even",
|
||||
.parent_hws = (const struct clk_hw *[]){ &gpupll0.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_alpha_pll_postdiv_fabia_ops,
|
||||
},
|
||||
};
|
||||
|
@ -253,12 +261,16 @@ static struct gdsc gpu_cx_gdsc = {
|
|||
static struct gdsc gpu_gx_gdsc = {
|
||||
.gdscr = 0x1094,
|
||||
.clamp_io_ctrl = 0x130,
|
||||
.resets = (unsigned int []){ GPU_GX_BCR },
|
||||
.reset_count = 1,
|
||||
.cxcs = (unsigned int []){ 0x1098 },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "gpu_gx",
|
||||
},
|
||||
.parent = &gpu_cx_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = CLAMP_IO | AON_RESET,
|
||||
.pwrsts = PWRSTS_OFF_ON | PWRSTS_RET,
|
||||
.flags = CLAMP_IO | SW_RESET | AON_RESET | NO_RET_PERIPH,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gpucc_msm8998_clocks[] = {
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020, AngeloGioacchino Del Regno
|
||||
* <angelogioacchino.delregno@somainline.org>
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <dt-bindings/clock/qcom,gpucc-sdm660.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "common.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-pll.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-branch.h"
|
||||
#include "gdsc.h"
|
||||
#include "reset.h"
|
||||
|
||||
enum {
|
||||
P_GPU_XO,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_GPLL0_OUT_MAIN,
|
||||
P_GPLL0_OUT_MAIN_DIV,
|
||||
P_GPU_PLL0_PLL_OUT_MAIN,
|
||||
P_GPU_PLL1_PLL_OUT_MAIN,
|
||||
};
|
||||
|
||||
static struct clk_branch gpucc_cxo_clk = {
|
||||
.halt_reg = 0x1020,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1020,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpucc_cxo_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "xo",
|
||||
.name = "xo"
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct pll_vco gpu_vco[] = {
|
||||
{ 1000000000, 2000000000, 0 },
|
||||
{ 500000000, 1000000000, 2 },
|
||||
{ 250000000, 500000000, 3 },
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpu_pll0_pll_out_main = {
|
||||
.offset = 0x0,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.vco_table = gpu_vco,
|
||||
.num_vco = ARRAY_SIZE(gpu_vco),
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_pll0_pll_out_main",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &gpucc_cxo_clk.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpu_pll1_pll_out_main = {
|
||||
.offset = 0x40,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.vco_table = gpu_vco,
|
||||
.num_vco = ARRAY_SIZE(gpu_vco),
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gpu_pll1_pll_out_main",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &gpucc_cxo_clk.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map gpucc_parent_map_1[] = {
|
||||
{ P_GPU_XO, 0 },
|
||||
{ P_GPU_PLL0_PLL_OUT_MAIN, 1 },
|
||||
{ P_GPU_PLL1_PLL_OUT_MAIN, 3 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpucc_parent_data_1[] = {
|
||||
{ .hw = &gpucc_cxo_clk.clkr.hw },
|
||||
{ .hw = &gpu_pll0_pll_out_main.clkr.hw },
|
||||
{ .hw = &gpu_pll1_pll_out_main.clkr.hw },
|
||||
{ .fw_name = "gcc_gpu_gpll0_clk", .name = "gcc_gpu_gpll0_clk" },
|
||||
};
|
||||
|
||||
static struct clk_rcg2_gfx3d gfx3d_clk_src = {
|
||||
.div = 2,
|
||||
.rcg = {
|
||||
.cmd_rcgr = 0x1070,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpucc_parent_map_1,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_clk_src",
|
||||
.parent_data = gpucc_parent_data_1,
|
||||
.num_parents = 4,
|
||||
.ops = &clk_gfx3d_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
},
|
||||
},
|
||||
.hws = (struct clk_hw*[]){
|
||||
&gpucc_cxo_clk.clkr.hw,
|
||||
&gpu_pll0_pll_out_main.clkr.hw,
|
||||
&gpu_pll1_pll_out_main.clkr.hw,
|
||||
}
|
||||
};
|
||||
|
||||
static struct clk_branch gpucc_gfx3d_clk = {
|
||||
.halt_reg = 0x1098,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.hwcg_reg = 0x1098,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1098,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpucc_gfx3d_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &gfx3d_clk_src.rcg.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map gpucc_parent_map_0[] = {
|
||||
{ P_GPU_XO, 0 },
|
||||
{ P_GPLL0_OUT_MAIN, 5 },
|
||||
{ P_GPLL0_OUT_MAIN_DIV, 6 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gpucc_parent_data_0[] = {
|
||||
{ .hw = &gpucc_cxo_clk.clkr.hw },
|
||||
{ .fw_name = "gcc_gpu_gpll0_clk", .name = "gcc_gpu_gpll0_clk" },
|
||||
{ .fw_name = "gcc_gpu_gpll0_div_clk", .name = "gcc_gpu_gpll0_div_clk" },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = {
|
||||
F(19200000, P_GPU_XO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 rbbmtimer_clk_src = {
|
||||
.cmd_rcgr = 0x10b0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpucc_parent_map_0,
|
||||
.freq_tbl = ftbl_rbbmtimer_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "rbbmtimer_clk_src",
|
||||
.parent_data = gpucc_parent_data_0,
|
||||
.num_parents = 3,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_rbcpr_clk_src[] = {
|
||||
F(19200000, P_GPU_XO, 1, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_MAIN_DIV, 6, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 rbcpr_clk_src = {
|
||||
.cmd_rcgr = 0x1030,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gpucc_parent_map_0,
|
||||
.freq_tbl = ftbl_rbcpr_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "rbcpr_clk_src",
|
||||
.parent_data = gpucc_parent_data_0,
|
||||
.num_parents = 3,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpucc_rbbmtimer_clk = {
|
||||
.halt_reg = 0x10d0,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x10d0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpucc_rbbmtimer_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"rbbmtimer_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gpucc_rbcpr_clk = {
|
||||
.halt_reg = 0x1054,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1054,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gpucc_rbcpr_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"rbcpr_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc gpu_cx_gdsc = {
|
||||
.gdscr = 0x1004,
|
||||
.gds_hw_ctrl = 0x1008,
|
||||
.pd = {
|
||||
.name = "gpu_cx",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
static struct gdsc gpu_gx_gdsc = {
|
||||
.gdscr = 0x1094,
|
||||
.clamp_io_ctrl = 0x130,
|
||||
.resets = (unsigned int []){ GPU_GX_BCR },
|
||||
.reset_count = 1,
|
||||
.cxcs = (unsigned int []){ 0x1098 },
|
||||
.cxc_count = 1,
|
||||
.pd = {
|
||||
.name = "gpu_gx",
|
||||
},
|
||||
.parent = &gpu_cx_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF | PWRSTS_ON | PWRSTS_RET,
|
||||
.flags = CLAMP_IO | SW_RESET | AON_RESET | NO_RET_PERIPH,
|
||||
};
|
||||
|
||||
static struct gdsc *gpucc_sdm660_gdscs[] = {
|
||||
[GPU_CX_GDSC] = &gpu_cx_gdsc,
|
||||
[GPU_GX_GDSC] = &gpu_gx_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gpucc_sdm660_resets[] = {
|
||||
[GPU_CX_BCR] = { 0x1000 },
|
||||
[RBCPR_BCR] = { 0x1050 },
|
||||
[GPU_GX_BCR] = { 0x1090 },
|
||||
[SPDM_BCR] = { 0x10E0 },
|
||||
};
|
||||
|
||||
static struct clk_regmap *gpucc_sdm660_clocks[] = {
|
||||
[GPUCC_CXO_CLK] = &gpucc_cxo_clk.clkr,
|
||||
[GPU_PLL0_PLL] = &gpu_pll0_pll_out_main.clkr,
|
||||
[GPU_PLL1_PLL] = &gpu_pll1_pll_out_main.clkr,
|
||||
[GFX3D_CLK_SRC] = &gfx3d_clk_src.rcg.clkr,
|
||||
[RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
|
||||
[RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
|
||||
[GPUCC_RBCPR_CLK] = &gpucc_rbcpr_clk.clkr,
|
||||
[GPUCC_GFX3D_CLK] = &gpucc_gfx3d_clk.clkr,
|
||||
[GPUCC_RBBMTIMER_CLK] = &gpucc_rbbmtimer_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct regmap_config gpucc_660_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x9034,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc gpucc_sdm660_desc = {
|
||||
.config = &gpucc_660_regmap_config,
|
||||
.clks = gpucc_sdm660_clocks,
|
||||
.num_clks = ARRAY_SIZE(gpucc_sdm660_clocks),
|
||||
.resets = gpucc_sdm660_resets,
|
||||
.num_resets = ARRAY_SIZE(gpucc_sdm660_resets),
|
||||
.gdscs = gpucc_sdm660_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(gpucc_sdm660_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id gpucc_sdm660_match_table[] = {
|
||||
{ .compatible = "qcom,gpucc-sdm660" },
|
||||
{ .compatible = "qcom,gpucc-sdm630" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, gpucc_sdm660_match_table);
|
||||
|
||||
static int gpucc_sdm660_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
struct alpha_pll_config gpu_pll_config = {
|
||||
.config_ctl_val = 0x4001055b,
|
||||
.alpha = 0xaaaaab00,
|
||||
.alpha_en_mask = BIT(24),
|
||||
.vco_val = 0x2 << 20,
|
||||
.vco_mask = 0x3 << 20,
|
||||
.main_output_mask = 0x1,
|
||||
};
|
||||
|
||||
regmap = qcom_cc_map(pdev, &gpucc_sdm660_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
/* 800MHz configuration for GPU PLL0 */
|
||||
gpu_pll_config.l = 0x29;
|
||||
gpu_pll_config.alpha_hi = 0xaa;
|
||||
clk_alpha_pll_configure(&gpu_pll0_pll_out_main, regmap, &gpu_pll_config);
|
||||
|
||||
/* 740MHz configuration for GPU PLL1 */
|
||||
gpu_pll_config.l = 0x26;
|
||||
gpu_pll_config.alpha_hi = 0x8a;
|
||||
clk_alpha_pll_configure(&gpu_pll1_pll_out_main, regmap, &gpu_pll_config);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &gpucc_sdm660_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver gpucc_sdm660_driver = {
|
||||
.probe = gpucc_sdm660_probe,
|
||||
.driver = {
|
||||
.name = "gpucc-sdm660",
|
||||
.of_match_table = gpucc_sdm660_match_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(gpucc_sdm660_driver);
|
||||
|
||||
MODULE_DESCRIPTION("Qualcomm SDM630/SDM660 GPUCC Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -33,14 +33,13 @@ struct clk_gfm {
|
|||
void __iomem *gfm_mux;
|
||||
};
|
||||
|
||||
#define GFM_MASK BIT(1)
|
||||
#define to_clk_gfm(_hw) container_of(_hw, struct clk_gfm, hw)
|
||||
|
||||
static u8 clk_gfm_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gfm *clk = to_clk_gfm(hw);
|
||||
|
||||
return readl(clk->gfm_mux) & GFM_MASK;
|
||||
return readl(clk->gfm_mux) & clk->mux_mask;
|
||||
}
|
||||
|
||||
static int clk_gfm_set_parent(struct clk_hw *hw, u8 index)
|
||||
|
@ -51,9 +50,10 @@ static int clk_gfm_set_parent(struct clk_hw *hw, u8 index)
|
|||
val = readl(clk->gfm_mux);
|
||||
|
||||
if (index)
|
||||
val |= GFM_MASK;
|
||||
val |= clk->mux_mask;
|
||||
else
|
||||
val &= ~GFM_MASK;
|
||||
val &= ~clk->mux_mask;
|
||||
|
||||
|
||||
writel(val, clk->gfm_mux);
|
||||
|
||||
|
|
|
@ -74,22 +74,6 @@ static const char * const mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_2_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL2, 3 }
|
||||
};
|
||||
|
||||
static const char * const mmcc_xo_mmpll0_1_2_gpll0[] = {
|
||||
"xo",
|
||||
"mmpll0_vote",
|
||||
"mmpll1_vote",
|
||||
"mmss_gpll0_vote",
|
||||
"mmpll2",
|
||||
};
|
||||
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_3_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
|
|
|
@ -528,16 +528,23 @@ static struct clk_rcg2 maxi_clk_src = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gfx3d_clk_src = {
|
||||
.cmd_rcgr = 0x4000,
|
||||
.hid_width = 5,
|
||||
.parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_clk_src",
|
||||
.parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0,
|
||||
.num_parents = 6,
|
||||
.ops = &clk_gfx3d_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
static struct clk_rcg2_gfx3d gfx3d_clk_src = {
|
||||
.rcg = {
|
||||
.cmd_rcgr = 0x4000,
|
||||
.hid_width = 5,
|
||||
.parent_map = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0_map,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gfx3d_clk_src",
|
||||
.parent_names = mmss_xo_mmpll0_mmpll9_mmpll2_mmpll8_gpll0,
|
||||
.num_parents = 6,
|
||||
.ops = &clk_gfx3d_ops,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
},
|
||||
.hws = (struct clk_hw*[]) {
|
||||
&mmpll9.clkr.hw,
|
||||
&mmpll2.clkr.hw,
|
||||
&mmpll8.clkr.hw
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -3089,7 +3096,7 @@ static struct clk_regmap *mmcc_msm8996_clocks[] = {
|
|||
[AHB_CLK_SRC] = &ahb_clk_src.clkr,
|
||||
[AXI_CLK_SRC] = &axi_clk_src.clkr,
|
||||
[MAXI_CLK_SRC] = &maxi_clk_src.clkr,
|
||||
[GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
|
||||
[GFX3D_CLK_SRC] = &gfx3d_clk_src.rcg.clkr,
|
||||
[RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
|
||||
[ISENSE_CLK_SRC] = &isense_clk_src.clkr,
|
||||
[RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
|
||||
|
|
|
@ -1211,6 +1211,8 @@ static struct clk_rcg2 vfe1_clk_src = {
|
|||
|
||||
static struct clk_branch misc_ahb_clk = {
|
||||
.halt_reg = 0x328,
|
||||
.hwcg_reg = 0x328,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x328,
|
||||
.enable_mask = BIT(0),
|
||||
|
@ -1241,6 +1243,8 @@ static struct clk_branch video_core_clk = {
|
|||
|
||||
static struct clk_branch video_ahb_clk = {
|
||||
.halt_reg = 0x1030,
|
||||
.hwcg_reg = 0x1030,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1030,
|
||||
.enable_mask = BIT(0),
|
||||
|
@ -1315,6 +1319,8 @@ static struct clk_branch video_subcore1_clk = {
|
|||
|
||||
static struct clk_branch mdss_ahb_clk = {
|
||||
.halt_reg = 0x2308,
|
||||
.hwcg_reg = 0x2308,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2308,
|
||||
.enable_mask = BIT(0),
|
||||
|
@ -2496,6 +2502,8 @@ static struct clk_branch mnoc_ahb_clk = {
|
|||
|
||||
static struct clk_branch bimc_smmu_ahb_clk = {
|
||||
.halt_reg = 0xe004,
|
||||
.hwcg_reg = 0xe004,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0xe004,
|
||||
.enable_mask = BIT(0),
|
||||
|
@ -2511,6 +2519,8 @@ static struct clk_branch bimc_smmu_ahb_clk = {
|
|||
|
||||
static struct clk_branch bimc_smmu_axi_clk = {
|
||||
.halt_reg = 0xe008,
|
||||
.hwcg_reg = 0xe008,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0xe008,
|
||||
.enable_mask = BIT(0),
|
||||
|
@ -2653,7 +2663,7 @@ static struct gdsc bimc_smmu_gdsc = {
|
|||
.name = "bimc_smmu",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = HW_CTRL,
|
||||
.flags = HW_CTRL | ALWAYS_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *mmcc_msm8998_clocks[] = {
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче