Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk updates from Stephen Boyd:
"The core framework got some nice improvements this time around. We
gained the ability to get struct clk pointers from a struct clk_hw so
that clk providers can consume the clks they provide, if they need to
do something like that. This has been a long missing part of the clk
provider API that will help us move away from exposing a struct clk
pointer in the struct clk_hw. Tracepoints are added for the
clk_set_rate() "range" functions, similar to the tracepoints we
already have for clk_set_rate() and we added a column to debugfs to
help developers understand the hardware enable state of clks in case
firmware or bootloader state is different than what is expected.
Overall the core changes are mostly improving the clk driver writing
experience.

At the driver level, we have the usual collection of driver updates
and new drivers for new SoCs. This time around the Qualcomm folks
introduced a good handful of clk drivers for various parts of three or
four SoCs. The SiFive folks added a new clk driver for their FU740
SoCs, coming in second on the diffstat and then Atmel AT91 and Amlogic
SoCs had lots of work done after that for various new features. One
last thing to note in the driver area is that the i.MX driver has
gained a new binding to support SCU clks after being on the list for
many months. It uses a two cell binding which is sort of rare in clk
DT bindings. Beyond that we have the usual set of driver fixes and
tweaks that come from more testing and finding out that some
configuration was wrong or that a driver could support being built as
a module.

Summary:

Core:
- Add some trace points for clk_set_rate() "range" functions
- Add hardware enable information to clk_summary debugfs
- Replace clk-provider.h with of_clk.h when possible
- Add devm variant of clk_notifier_register()
- Add clk_hw_get_clk() to generate a struct clk from a struct clk_hw

New Drivers:
- Bindings for Canaan K210 SoC clks
- Support for SiFive FU740 PRCI
- Camera clks on Qualcomm SC7180 SoCs
- GCC and RPMh clks on Qualcomm SDX55 SoCs
- RPMh clks on Qualcomm SM8350 SoCs
- LPASS clks on Qualcomm SM8250 SoCs

Updates:
- DVFS support for AT91 clk driver
- Update git repo branch for Renesas clock drivers
- Add camera (CSI) and video-in (VIN) clocks on Renesas R-Car V3U
- Add RPC (QSPI/HyperFLASH) clocks on Renesas RZ/G2M, RZ/G2N, and RZ/G2E
- Stop using __raw_*() I/O accessors in Renesas clk drivers
- One more conversion of DT bindings to json-schema
- Make i.MX clk-gate2 driver more flexible
- New two cell binding for i.MX SCU clks
- Drop of_match_ptr() in i.MX8 clk drivers
- Add arch dependencies for Rockchip clk drivers
- Fix i2s on Rockchip rk3066
- Add MIPI DSI clks on Amlogic axg and g12 SoCs
- Support modular builds of Amlogic clk drivers
- Fix an Amlogic Video PLL clock dependency
- Samsung Kconfig dependencies updates for better compile test coverage
- Refactoring of the Samsung PLL clocks driver
- Small Tegra driver cleanups
- Minor fixes to Ingenic and VC5 clk drivers
- Cleanup patches to remove unused variables and plug memory leaks"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (134 commits)
dt-binding: clock: Document canaan,k210-clk bindings
dt-bindings: Add Canaan vendor prefix
clk: vc5: Use "idt,voltage-microvolt" instead of "idt,voltage-microvolts"
clk: ingenic: Fix divider calculation with div tables
clk: sunxi-ng: Make sure divider tables have sentinel
clk: s2mps11: Fix a resource leak in error handling paths in the probe function
clk: mvebu: a3700: fix the XTAL MODE pin to MPP1_9
clk: si5351: Wait for bit clear after PLL reset
clk: at91: sam9x60: remove atmel,osc-bypass support
clk: at91: sama7g5: register cpu clock
clk: at91: clk-master: re-factor master clock
clk: at91: sama7g5: do not allow cpu pll to go higher than 1GHz
clk: at91: sama7g5: decrease lower limit for MCK0 rate
clk: at91: sama7g5: remove mck0 from parent list of other clocks
clk: at91: clk-sam9x60-pll: allow runtime changes for pll
clk: at91: sama7g5: add 5th divisor for mck0 layout and characteristics
clk: at91: clk-master: add 5th divisor for mck master
clk: at91: sama7g5: allow SYS and CPU PLLs to be exported and referenced in DT
dt-bindings: clock: at91: add sama7g5 pll defines
clk: at91: sama7g5: fix compilation error
...

+9350 -1521
+53
Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/adi,axi-clkgen.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Binding for Analog Devices AXI clkgen pcore clock generator 8 + 9 + maintainers: 10 + - Lars-Peter Clausen <lars@metafoo.de> 11 + - Michael Hennerich <michael.hennerich@analog.com> 12 + 13 + description: | 14 + The axi_clkgen IP core is a software programmable clock generator, 15 + that can be synthesized on various FPGA platforms. 16 + 17 + Link: https://wiki.analog.com/resources/fpga/docs/axi_clkgen 18 + 19 + properties: 20 + compatible: 21 + enum: 22 + - adi,axi-clkgen-2.00.a 23 + 24 + clocks: 25 + description: 26 + Specifies the reference clock(s) from which the output frequency is 27 + derived. This must either reference one clock if only the first clock 28 + input is connected or two if both clock inputs are connected. 29 + minItems: 1 30 + maxItems: 2 31 + 32 + '#clock-cells': 33 + const: 0 34 + 35 + reg: 36 + maxItems: 1 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - clocks 42 + - '#clock-cells' 43 + 44 + additionalProperties: false 45 + 46 + examples: 47 + - | 48 + clock-controller@ff000000 { 49 + compatible = "adi,axi-clkgen-2.00.a"; 50 + #clock-cells = <0>; 51 + reg = <0xff000000 0x1000>; 52 + clocks = <&osc 1>; 53 + };
-25
Documentation/devicetree/bindings/clock/axi-clkgen.txt
··· 1 - Binding for the axi-clkgen clock generator 2 - 3 - This binding uses the common clock binding[1]. 4 - 5 - [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 - 7 - Required properties: 8 - - compatible : shall be "adi,axi-clkgen-1.00.a" or "adi,axi-clkgen-2.00.a". 9 - - #clock-cells : from common clock binding; Should always be set to 0. 10 - - reg : Address and length of the axi-clkgen register set. 11 - - clocks : Phandle and clock specifier for the parent clock(s). This must 12 - either reference one clock if only the first clock input is connected or two 13 - if both clock inputs are connected. For the later case the clock connected 14 - to the first input must be specified first. 15 - 16 - Optional properties: 17 - - clock-output-names : From common clock binding. 18 - 19 - Example: 20 - clock@ff000000 { 21 - compatible = "adi,axi-clkgen"; 22 - #clock-cells = <0>; 23 - reg = <0xff000000 0x1000>; 24 - clocks = <&osc 1>; 25 - };
+54
Documentation/devicetree/bindings/clock/canaan,k210-clk.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/canaan,k210-clk.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Canaan Kendryte K210 Clock Device Tree Bindings 8 + 9 + maintainers: 10 + - Damien Le Moal <damien.lemoal@wdc.com> 11 + 12 + description: | 13 + Canaan Kendryte K210 SoC clocks driver bindings. The clock 14 + controller node must be defined as a child node of the K210 15 + system controller node. 16 + 17 + See also: 18 + - dt-bindings/clock/k210-clk.h 19 + 20 + properties: 21 + compatible: 22 + const: canaan,k210-clk 23 + 24 + clocks: 25 + description: 26 + Phandle of the SoC 26MHz fixed-rate oscillator clock. 27 + 28 + '#clock-cells': 29 + const: 1 30 + 31 + required: 32 + - compatible 33 + - '#clock-cells' 34 + - clocks 35 + 36 + additionalProperties: false 37 + 38 + examples: 39 + - | 40 + #include <dt-bindings/clock/k210-clk.h> 41 + clocks { 42 + in0: oscillator { 43 + compatible = "fixed-clock"; 44 + #clock-cells = <0>; 45 + clock-frequency = <26000000>; 46 + }; 47 + }; 48 + 49 + /* ... */ 50 + sysclk: clock-controller { 51 + #clock-cells = <1>; 52 + compatible = "canaan,k210-clk"; 53 + clocks = <&in0>; 54 + };
+55
Documentation/devicetree/bindings/clock/fsl,flexspi-clock.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/fsl,flexspi-clock.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Freescale FlexSPI clock driver for Layerscape SoCs 8 + 9 + maintainers: 10 + - Michael Walle <michael@walle.cc> 11 + 12 + description: 13 + The Freescale Layerscape SoCs have a special FlexSPI clock which is 14 + derived from the platform PLL. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - fsl,ls1028a-flexspi-clk 20 + - fsl,lx2160a-flexspi-clk 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + clocks: 26 + maxItems: 1 27 + 28 + '#clock-cells': 29 + const: 0 30 + 31 + clock-output-names: 32 + maxItems: 1 33 + 34 + required: 35 + - compatible 36 + - reg 37 + - clocks 38 + - '#clock-cells' 39 + 40 + additionalProperties: false 41 + 42 + examples: 43 + - | 44 + dcfg { 45 + #address-cells = <1>; 46 + #size-cells = <1>; 47 + 48 + fspi_clk: clock-controller@900 { 49 + compatible = "fsl,ls1028a-flexspi-clk"; 50 + reg = <0x900 0x4>; 51 + #clock-cells = <0>; 52 + clocks = <&parentclk>; 53 + clock-output-names = "fspi_clk"; 54 + }; 55 + };
+58
Documentation/devicetree/bindings/clock/qcom,aoncc-sm8250.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/qcom,aoncc-sm8250.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Clock bindings for LPASS Always ON Clock Controller on SM8250 SoCs 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + 12 + description: | 13 + The clock consumer should specify the desired clock by having the clock 14 + ID in its "clocks" phandle cell. 15 + See include/dt-bindings/clock/qcom,sm8250-lpass-aoncc.h for the full list 16 + of Audio Clock controller clock IDs. 17 + 18 + properties: 19 + compatible: 20 + const: qcom,sm8250-lpass-aon 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + '#clock-cells': 26 + const: 1 27 + 28 + clocks: 29 + items: 30 + - description: LPASS Core voting clock 31 + - description: Glitch Free Mux register clock 32 + 33 + clock-names: 34 + items: 35 + - const: core 36 + - const: bus 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - '#clock-cells' 42 + - clocks 43 + - clock-names 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/clock/qcom,sm8250-lpass-aoncc.h> 50 + #include <dt-bindings/sound/qcom,q6afe.h> 51 + clock-controller@3800000 { 52 + #clock-cells = <1>; 53 + compatible = "qcom,sm8250-lpass-aon"; 54 + reg = <0x03380000 0x40000>; 55 + clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, 56 + <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>; 57 + clock-names = "core", "bus"; 58 + };
+58
Documentation/devicetree/bindings/clock/qcom,audiocc-sm8250.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/qcom,audiocc-sm8250.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Clock bindings for LPASS Audio Clock Controller on SM8250 SoCs 8 + 9 + maintainers: 10 + - Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 11 + 12 + description: | 13 + The clock consumer should specify the desired clock by having the clock 14 + ID in its "clocks" phandle cell. 15 + See include/dt-bindings/clock/qcom,sm8250-lpass-audiocc.h for the full list 16 + of Audio Clock controller clock IDs. 17 + 18 + properties: 19 + compatible: 20 + const: qcom,sm8250-lpass-audiocc 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + '#clock-cells': 26 + const: 1 27 + 28 + clocks: 29 + items: 30 + - description: LPASS Core voting clock 31 + - description: Glitch Free Mux register clock 32 + 33 + clock-names: 34 + items: 35 + - const: core 36 + - const: bus 37 + 38 + required: 39 + - compatible 40 + - reg 41 + - '#clock-cells' 42 + - clocks 43 + - clock-names 44 + 45 + additionalProperties: false 46 + 47 + examples: 48 + - | 49 + #include <dt-bindings/clock/qcom,sm8250-lpass-audiocc.h> 50 + #include <dt-bindings/sound/qcom,q6afe.h> 51 + clock-controller@3300000 { 52 + #clock-cells = <1>; 53 + compatible = "qcom,sm8250-lpass-audiocc"; 54 + reg = <0x03300000 0x30000>; 55 + clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>, 56 + <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>; 57 + clock-names = "core", "bus"; 58 + };
+77
Documentation/devicetree/bindings/clock/qcom,gcc-sdx55.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/qcom,gcc-sdx55.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Global Clock & Reset Controller Binding for SDX55 8 + 9 + maintainers: 10 + - Vinod Koul <vkoul@kernel.org> 11 + - Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> 12 + 13 + description: | 14 + Qualcomm global clock control module which supports the clocks, resets and 15 + power domains on SDX55 16 + 17 + See also: 18 + - dt-bindings/clock/qcom,gcc-sdx55.h 19 + 20 + properties: 21 + compatible: 22 + const: qcom,gcc-sdx55 23 + 24 + clocks: 25 + items: 26 + - description: Board XO source 27 + - description: Sleep clock source 28 + - description: PLL test clock source (Optional clock) 29 + minItems: 2 30 + maxItems: 3 31 + 32 + clock-names: 33 + items: 34 + - const: bi_tcxo 35 + - const: sleep_clk 36 + - const: core_bi_pll_test_se # Optional clock 37 + minItems: 2 38 + maxItems: 3 39 + 40 + '#clock-cells': 41 + const: 1 42 + 43 + '#reset-cells': 44 + const: 1 45 + 46 + '#power-domain-cells': 47 + const: 1 48 + 49 + reg: 50 + maxItems: 1 51 + 52 + required: 53 + - compatible 54 + - clocks 55 + - clock-names 56 + - reg 57 + - '#clock-cells' 58 + - '#reset-cells' 59 + - '#power-domain-cells' 60 + 61 + additionalProperties: false 62 + 63 + examples: 64 + - | 65 + #include <dt-bindings/clock/qcom,rpmh.h> 66 + clock-controller@100000 { 67 + compatible = "qcom,gcc-sdx55"; 68 + reg = <0x00100000 0x1f0000>; 69 + clocks = <&rpmhcc RPMH_CXO_CLK>, 70 + <&sleep_clk>, <&pll_test_clk>; 71 + clock-names = "bi_tcxo", "sleep_clk", "core_bi_pll_test_se"; 72 + #clock-cells = <1>; 73 + #reset-cells = <1>; 74 + #power-domain-cells = <1>; 75 + }; 76 + 77 + ...
+2
Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
··· 19 19 enum: 20 20 - qcom,sc7180-rpmh-clk 21 21 - qcom,sdm845-rpmh-clk 22 + - qcom,sdx55-rpmh-clk 22 23 - qcom,sm8150-rpmh-clk 23 24 - qcom,sm8250-rpmh-clk 25 + - qcom,sm8350-rpmh-clk 24 26 25 27 clocks: 26 28 maxItems: 1
+73
Documentation/devicetree/bindings/clock/qcom,sc7180-camcc.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Qualcomm Camera Clock & Reset Controller Binding for SC7180 8 + 9 + maintainers: 10 + - Taniya Das <tdas@codeaurora.org> 11 + 12 + description: | 13 + Qualcomm camera clock control module which supports the clocks, resets and 14 + power domains on SC7180. 15 + 16 + See also: 17 + - dt-bindings/clock/qcom,camcc-sc7180.h 18 + 19 + properties: 20 + compatible: 21 + const: qcom,sc7180-camcc 22 + 23 + clocks: 24 + items: 25 + - description: Board XO source 26 + - description: Camera_ahb clock from GCC 27 + - description: Camera XO clock from GCC 28 + 29 + clock-names: 30 + items: 31 + - const: bi_tcxo 32 + - const: iface 33 + - const: xo 34 + 35 + '#clock-cells': 36 + const: 1 37 + 38 + '#reset-cells': 39 + const: 1 40 + 41 + '#power-domain-cells': 42 + const: 1 43 + 44 + reg: 45 + maxItems: 1 46 + 47 + required: 48 + - compatible 49 + - reg 50 + - clocks 51 + - clock-names 52 + - '#clock-cells' 53 + - '#reset-cells' 54 + - '#power-domain-cells' 55 + 56 + additionalProperties: false 57 + 58 + examples: 59 + - | 60 + #include <dt-bindings/clock/qcom,gcc-sc7180.h> 61 + #include <dt-bindings/clock/qcom,rpmh.h> 62 + clock-controller@ad00000 { 63 + compatible = "qcom,sc7180-camcc"; 64 + reg = <0x0ad00000 0x10000>; 65 + clocks = <&rpmhcc RPMH_CXO_CLK>, 66 + <&gcc GCC_CAMERA_AHB_CLK>, 67 + <&gcc GCC_CAMERA_XO_CLK>; 68 + clock-names = "bi_tcxo", "iface", "xo"; 69 + #clock-cells = <1>; 70 + #reset-cells = <1>; 71 + #power-domain-cells = <1>; 72 + }; 73 + ...
-68
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
··· 1 - * Renesas R-Car USB 2.0 clock selector 2 - 3 - This file provides information on what the device node for the R-Car USB 2.0 4 - clock selector. 5 - 6 - If you connect an external clock to the USB_EXTAL pin only, you should set 7 - the clock rate to "usb_extal" node only. 8 - If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module 9 - is not needed because this is default setting. (Of course, you can set the 10 - clock rates to both "usb_extal" and "usb_xtal" nodes. 11 - 12 - Case 1: An external clock connects to R-Car SoC 13 - +----------+ +--- R-Car ---------------------+ 14 - |External |---|USB_EXTAL ---> all usb channels| 15 - |clock | |USB_XTAL | 16 - +----------+ +-------------------------------+ 17 - In this case, we need this driver with "usb_extal" clock. 18 - 19 - Case 2: An oscillator connects to R-Car SoC 20 - +----------+ +--- R-Car ---------------------+ 21 - |Oscillator|---|USB_EXTAL -+-> all usb channels| 22 - | |---|USB_XTAL --+ | 23 - +----------+ +-------------------------------+ 24 - In this case, we don't need this selector. 25 - 26 - Required properties: 27 - - compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of 28 - an R8A7795 SoC. 29 - "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of 30 - an R8A77960 SoC. 31 - "renesas,r8a77961-rcar-usb2-clock-sel" if the device if a part of 32 - an R8A77961 SoC. 33 - "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 34 - compatible device. 35 - 36 - When compatible with the generic version, nodes must list the 37 - SoC-specific version corresponding to the platform first 38 - followed by the generic version. 39 - 40 - - reg: offset and length of the USB 2.0 clock selector register block. 41 - - clocks: A list of phandles and specifier pairs. 42 - - clock-names: Name of the clocks. 43 - - The functional clock of USB 2.0 host side must be "ehci_ohci" 44 - - The functional clock of HS-USB side must be "hs-usb-if" 45 - - The USB_EXTAL clock pin must be "usb_extal" 46 - - The USB_XTAL clock pin must be "usb_xtal" 47 - - #clock-cells: Must be 0 48 - - power-domains: A phandle and symbolic PM domain specifier. 49 - See power/renesas,rcar-sysc.yaml. 50 - - resets: A list of phandles and specifier pairs. 51 - - reset-names: Name of the resets. 52 - - The reset of USB 2.0 host side must be "ehci_ohci" 53 - - The reset of HS-USB side must be "hs-usb-if" 54 - 55 - Example (R-Car H3): 56 - 57 - usb2_clksel: clock-controller@e6590630 { 58 - compatible = "renesas,r8a7795-rcar-usb2-clock-sel", 59 - "renesas,rcar-gen3-usb2-clock-sel"; 60 - reg = <0 0xe6590630 0 0x02>; 61 - clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, 62 - <&usb_extal>, <&usb_xtal>; 63 - clock-names = "ehci_ohci", "hs-usb-if", "usb_extal", "usb_xtal"; 64 - #clock-cells = <0>; 65 - power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; 66 - resets = <&cpg 703>, <&cpg 704>; 67 - reset-names = "ehci_ohci", "hs-usb-if"; 68 - };
+100
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/clock/renesas,rcar-usb2-clock-sel.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Renesas R-Car USB 2.0 clock selector 8 + 9 + maintainers: 10 + - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> 11 + 12 + description: | 13 + If you connect an external clock to the USB_EXTAL pin only, you should set 14 + the clock rate to "usb_extal" node only. 15 + If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module 16 + is not needed because this is default setting. (Of course, you can set the 17 + clock rates to both "usb_extal" and "usb_xtal" nodes. 18 + 19 + Case 1: An external clock connects to R-Car SoC 20 + +----------+ +--- R-Car ---------------------+ 21 + |External |---|USB_EXTAL ---> all usb channels| 22 + |clock | |USB_XTAL | 23 + +----------+ +-------------------------------+ 24 + 25 + In this case, we need this driver with "usb_extal" clock. 26 + 27 + Case 2: An oscillator connects to R-Car SoC 28 + +----------+ +--- R-Car ---------------------+ 29 + |Oscillator|---|USB_EXTAL -+-> all usb channels| 30 + | |---|USB_XTAL --+ | 31 + +----------+ +-------------------------------+ 32 + In this case, we don't need this selector. 33 + 34 + properties: 35 + compatible: 36 + items: 37 + - enum: 38 + - renesas,r8a7795-rcar-usb2-clock-sel # R-Car H3 39 + - renesas,r8a7796-rcar-usb2-clock-sel # R-Car M3-W 40 + - renesas,r8a77961-rcar-usb2-clock-sel # R-Car M3-W+ 41 + - const: renesas,rcar-gen3-usb2-clock-sel 42 + 43 + reg: 44 + maxItems: 1 45 + 46 + clocks: 47 + minItems: 4 48 + maxItems: 4 49 + 50 + clock-names: 51 + items: 52 + - const: ehci_ohci 53 + - const: hs-usb-if 54 + - const: usb_extal 55 + - const: usb_xtal 56 + 57 + '#clock-cells': 58 + const: 0 59 + 60 + power-domains: 61 + maxItems: 1 62 + 63 + resets: 64 + minItems: 2 65 + maxItems: 2 66 + 67 + reset-names: 68 + items: 69 + - const: ehci_ohci 70 + - const: hs-usb-if 71 + 72 + required: 73 + - compatible 74 + - reg 75 + - clocks 76 + - clock-names 77 + - '#clock-cells' 78 + - power-domains 79 + - resets 80 + - reset-names 81 + 82 + additionalProperties: false 83 + 84 + examples: 85 + - | 86 + #include <dt-bindings/clock/r8a7795-cpg-mssr.h> 87 + #include <dt-bindings/power/r8a7795-sysc.h> 88 + 89 + usb2_clksel: clock-controller@e6590630 { 90 + compatible = "renesas,r8a7795-rcar-usb2-clock-sel", 91 + "renesas,rcar-gen3-usb2-clock-sel"; 92 + reg = <0xe6590630 0x02>; 93 + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, 94 + <&usb_extal>, <&usb_xtal>; 95 + clock-names = "ehci_ohci", "hs-usb-if", "usb_extal", "usb_xtal"; 96 + #clock-cells = <0>; 97 + power-domains = <&sysc R8A7795_PD_ALWAYS_ON>; 98 + resets = <&cpg 703>, <&cpg 704>; 99 + reset-names = "ehci_ohci", "hs-usb-if"; 100 + };
+60
Documentation/devicetree/bindings/clock/sifive/fu740-prci.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2020 SiFive, Inc. 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/clock/sifive/fu740-prci.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: SiFive FU740 Power Reset Clock Interrupt Controller (PRCI) 9 + 10 + maintainers: 11 + - Zong Li <zong.li@sifive.com> 12 + - Paul Walmsley <paul.walmsley@sifive.com> 13 + 14 + description: 15 + On the FU740 family of SoCs, most system-wide clock and reset integration 16 + is via the PRCI IP block. 17 + The clock consumer should specify the desired clock via the clock ID 18 + macros defined in include/dt-bindings/clock/sifive-fu740-prci.h. 19 + These macros begin with PRCI_CLK_. 20 + 21 + The hfclk and rtcclk nodes are required, and represent physical 22 + crystals or resonators located on the PCB. These nodes should be present 23 + underneath /, rather than /soc. 24 + 25 + properties: 26 + compatible: 27 + const: sifive,fu740-c000-prci 28 + 29 + reg: 30 + maxItems: 1 31 + 32 + clocks: 33 + items: 34 + - description: high frequency clock. 35 + - description: RTL clock. 36 + 37 + clock-names: 38 + items: 39 + - const: hfclk 40 + - const: rtcclk 41 + 42 + "#clock-cells": 43 + const: 1 44 + 45 + required: 46 + - compatible 47 + - reg 48 + - clocks 49 + - "#clock-cells" 50 + 51 + additionalProperties: false 52 + 53 + examples: 54 + - | 55 + prci: clock-controller@10000000 { 56 + compatible = "sifive,fu740-c000-prci"; 57 + reg = <0x10000000 0x1000>; 58 + clocks = <&hfclk>, <&rtcclk>; 59 + #clock-cells = <1>; 60 + };
+2
Documentation/devicetree/bindings/vendor-prefixes.yaml
··· 187 187 description: CALAO Systems SAS 188 188 "^calxeda,.*": 189 189 description: Calxeda 190 + "^canaan,.*": 191 + description: Canaan, Inc. 190 192 "^caninos,.*": 191 193 description: Caninos Loucos Program 192 194 "^capella,.*":
+1 -1
MAINTAINERS
··· 15108 15108 M: Geert Uytterhoeven <geert+renesas@glider.be> 15109 15109 L: linux-renesas-soc@vger.kernel.org 15110 15110 S: Supported 15111 - T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas 15111 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk 15112 15112 F: Documentation/devicetree/bindings/clock/renesas,* 15113 15113 F: drivers/clk/renesas/ 15114 15114
+1 -1
arch/riscv/Kconfig.socs
··· 5 5 select SERIAL_SIFIVE if TTY 6 6 select SERIAL_SIFIVE_CONSOLE if TTY 7 7 select CLK_SIFIVE 8 - select CLK_SIFIVE_FU540_PRCI 8 + select CLK_SIFIVE_PRCI 9 9 select SIFIVE_PLIC 10 10 help 11 11 This enables support for SiFive SoC platform hardware.
+1 -1
arch/sh/boards/of-generic.c
··· 6 6 */ 7 7 8 8 #include <linux/of.h> 9 + #include <linux/of_clk.h> 9 10 #include <linux/of_fdt.h> 10 11 #include <linux/clocksource.h> 11 12 #include <linux/irqchip.h> 12 - #include <linux/clk-provider.h> 13 13 #include <asm/machvec.h> 14 14 #include <asm/rtc.h> 15 15
+1 -1
arch/xtensa/kernel/time.c
··· 13 13 */ 14 14 15 15 #include <linux/clk.h> 16 - #include <linux/clk-provider.h> 16 + #include <linux/of_clk.h> 17 17 #include <linux/errno.h> 18 18 #include <linux/sched.h> 19 19 #include <linux/time.h>
+10 -1
drivers/clk/Kconfig
··· 188 188 help 189 189 If you say yes here you get support for the CS2000 clock multiplier. 190 190 191 + config COMMON_CLK_FSL_FLEXSPI 192 + tristate "Clock driver for FlexSPI on Layerscape SoCs" 193 + depends on ARCH_LAYERSCAPE || COMPILE_TEST 194 + default ARCH_LAYERSCAPE && SPI_NXP_FLEXSPI 195 + help 196 + On Layerscape SoCs there is a special clock for the FlexSPI 197 + interface. 198 + 191 199 config COMMON_CLK_FSL_SAI 192 200 bool "Clock driver for BCLK of Freescale SAI cores" 193 201 depends on ARCH_LAYERSCAPE || COMPILE_TEST ··· 254 246 255 247 config CLK_QORIQ 256 248 bool "Clock driver for Freescale QorIQ platforms" 257 - depends on (PPC_E500MC || ARM || ARM64 || COMPILE_TEST) && OF 249 + depends on OF 250 + depends on PPC_E500MC || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST 258 251 help 259 252 This adds the clock driver support for Freescale QorIQ platforms 260 253 using common clock framework.
+1
drivers/clk/Makefile
··· 30 30 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 31 31 obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o 32 32 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o 33 + obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o 33 34 obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o 34 35 obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o 35 36 obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
+17 -4
drivers/clk/at91/at91rm9200.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(rm9200_mck_lock); 11 + 10 12 struct sck { 11 13 char *n; 12 14 char *p; ··· 139 137 parent_names[1] = "mainck"; 140 138 parent_names[2] = "pllack"; 141 139 parent_names[3] = "pllbck"; 142 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 143 - &at91rm9200_master_layout, 144 - &rm9200_mck_characteristics); 140 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 141 + parent_names, 142 + &at91rm9200_master_layout, 143 + &rm9200_mck_characteristics, 144 + &rm9200_mck_lock, CLK_SET_RATE_GATE, 145 + INT_MIN); 146 + if (IS_ERR(hw)) 147 + goto err_free; 148 + 149 + hw = at91_clk_register_master_div(regmap, "masterck_div", 150 + "masterck_pres", 151 + &at91rm9200_master_layout, 152 + &rm9200_mck_characteristics, 153 + &rm9200_mck_lock, CLK_SET_RATE_GATE); 145 154 if (IS_ERR(hw)) 146 155 goto err_free; 147 156 ··· 194 181 for (i = 0; i < ARRAY_SIZE(at91rm9200_periphck); i++) { 195 182 hw = at91_clk_register_peripheral(regmap, 196 183 at91rm9200_periphck[i].n, 197 - "masterck", 184 + "masterck_div", 198 185 at91rm9200_periphck[i].id); 199 186 if (IS_ERR(hw)) 200 187 goto err_free;
+20 -6
drivers/clk/at91/at91sam9260.c
··· 32 32 bool has_slck; 33 33 }; 34 34 35 + static DEFINE_SPINLOCK(at91sam9260_mck_lock); 36 + 35 37 static const struct clk_master_characteristics sam9260_mck_characteristics = { 36 38 .output = { .min = 0, .max = 105000000 }, 37 39 .divisors = { 1, 2, 4, 0 }, ··· 220 218 { .n = "pck1", .p = "prog1", .id = 9 }, 221 219 { .n = "pck2", .p = "prog2", .id = 10 }, 222 220 { .n = "pck3", .p = "prog3", .id = 11 }, 223 - { .n = "hclk0", .p = "masterck", .id = 16 }, 224 - { .n = "hclk1", .p = "masterck", .id = 17 }, 221 + { .n = "hclk0", .p = "masterck_div", .id = 16 }, 222 + { .n = "hclk1", .p = "masterck_div", .id = 17 }, 225 223 }; 226 224 227 225 static const struct pck at91sam9261_periphck[] = { ··· 415 413 parent_names[1] = "mainck"; 416 414 parent_names[2] = "pllack"; 417 415 parent_names[3] = "pllbck"; 418 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 419 - &at91rm9200_master_layout, 420 - data->mck_characteristics); 416 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 417 + parent_names, 418 + &at91rm9200_master_layout, 419 + data->mck_characteristics, 420 + &at91sam9260_mck_lock, 421 + CLK_SET_RATE_GATE, INT_MIN); 422 + if (IS_ERR(hw)) 423 + goto err_free; 424 + 425 + hw = at91_clk_register_master_div(regmap, "masterck_div", 426 + "masterck_pres", 427 + &at91rm9200_master_layout, 428 + data->mck_characteristics, 429 + &at91sam9260_mck_lock, 430 + CLK_SET_RATE_GATE); 421 431 if (IS_ERR(hw)) 422 432 goto err_free; 423 433 ··· 471 457 for (i = 0; i < data->num_pck; i++) { 472 458 hw = at91_clk_register_peripheral(regmap, 473 459 data->pck[i].n, 474 - "masterck", 460 + "masterck_div", 475 461 data->pck[i].id); 476 462 if (IS_ERR(hw)) 477 463 goto err_free;
+23 -9
drivers/clk/at91/at91sam9g45.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(at91sam9g45_mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 0, .max = 133333333 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 42 40 char *p; 43 41 u8 id; 44 42 } at91sam9g45_systemck[] = { 45 - { .n = "ddrck", .p = "masterck", .id = 2 }, 46 - { .n = "uhpck", .p = "usbck", .id = 6 }, 47 - { .n = "pck0", .p = "prog0", .id = 8 }, 48 - { .n = "pck1", .p = "prog1", .id = 9 }, 43 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 44 + { .n = "uhpck", .p = "usbck", .id = 6 }, 45 + { .n = "pck0", .p = "prog0", .id = 8 }, 46 + { .n = "pck1", .p = "prog1", .id = 9 }, 49 47 }; 50 48 51 49 struct pck { ··· 150 148 parent_names[1] = "mainck"; 151 149 parent_names[2] = "plladivck"; 152 150 parent_names[3] = "utmick"; 153 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 154 - &at91rm9200_master_layout, 155 - &mck_characteristics); 151 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 152 + parent_names, 153 + &at91rm9200_master_layout, 154 + &mck_characteristics, 155 + &at91sam9g45_mck_lock, 156 + CLK_SET_RATE_GATE, INT_MIN); 157 + if (IS_ERR(hw)) 158 + goto err_free; 159 + 160 + hw = at91_clk_register_master_div(regmap, "masterck_div", 161 + "masterck_pres", 162 + &at91rm9200_master_layout, 163 + &mck_characteristics, 164 + &at91sam9g45_mck_lock, 165 + CLK_SET_RATE_GATE); 156 166 if (IS_ERR(hw)) 157 167 goto err_free; 158 168 ··· 180 166 parent_names[1] = "mainck"; 181 167 parent_names[2] = "plladivck"; 182 168 parent_names[3] = "utmick"; 183 - parent_names[4] = "masterck"; 169 + parent_names[4] = "masterck_div"; 184 170 for (i = 0; i < 2; i++) { 185 171 char name[6]; 186 172 ··· 209 195 for (i = 0; i < ARRAY_SIZE(at91sam9g45_periphck); i++) { 210 196 hw = at91_clk_register_peripheral(regmap, 211 197 at91sam9g45_periphck[i].n, 212 - "masterck", 198 + "masterck_div", 213 199 at91sam9g45_periphck[i].id); 214 200 if (IS_ERR(hw)) 215 201 goto err_free;
+25 -11
drivers/clk/at91/at91sam9n12.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(at91sam9n12_mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 0, .max = 133333333 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 56 54 char *p; 57 55 u8 id; 58 56 } at91sam9n12_systemck[] = { 59 - { .n = "ddrck", .p = "masterck", .id = 2 }, 60 - { .n = "lcdck", .p = "masterck", .id = 3 }, 61 - { .n = "uhpck", .p = "usbck", .id = 6 }, 62 - { .n = "udpck", .p = "usbck", .id = 7 }, 63 - { .n = "pck0", .p = "prog0", .id = 8 }, 64 - { .n = "pck1", .p = "prog1", .id = 9 }, 57 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 58 + { .n = "lcdck", .p = "masterck_div", .id = 3 }, 59 + { .n = "uhpck", .p = "usbck", .id = 6 }, 60 + { .n = "udpck", .p = "usbck", .id = 7 }, 61 + { .n = "pck0", .p = "prog0", .id = 8 }, 62 + { .n = "pck1", .p = "prog1", .id = 9 }, 65 63 }; 66 64 67 65 static const struct clk_pcr_layout at91sam9n12_pcr_layout = { ··· 177 175 parent_names[1] = "mainck"; 178 176 parent_names[2] = "plladivck"; 179 177 parent_names[3] = "pllbck"; 180 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 181 - &at91sam9x5_master_layout, 182 - &mck_characteristics); 178 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 179 + parent_names, 180 + &at91sam9x5_master_layout, 181 + &mck_characteristics, 182 + &at91sam9n12_mck_lock, 183 + CLK_SET_RATE_GATE, INT_MIN); 184 + if (IS_ERR(hw)) 185 + goto err_free; 186 + 187 + hw = at91_clk_register_master_div(regmap, "masterck_div", 188 + "masterck_pres", 189 + &at91sam9x5_master_layout, 190 + &mck_characteristics, 191 + &at91sam9n12_mck_lock, 192 + CLK_SET_RATE_GATE); 183 193 if (IS_ERR(hw)) 184 194 goto err_free; 185 195 ··· 205 191 parent_names[1] = "mainck"; 206 192 parent_names[2] = "plladivck"; 207 193 parent_names[3] = "pllbck"; 208 - parent_names[4] = "masterck"; 194 + parent_names[4] = "masterck_div"; 209 195 for (i = 0; i < 2; i++) { 210 196 char name[6]; 211 197 ··· 235 221 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 236 222 &at91sam9n12_pcr_layout, 237 223 at91sam9n12_periphck[i].n, 238 - "masterck", 224 + "masterck_div", 239 225 at91sam9n12_periphck[i].id, 240 226 &range, INT_MIN); 241 227 if (IS_ERR(hw))
+18 -5
drivers/clk/at91/at91sam9rl.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(sam9rl_mck_lock); 11 + 10 12 static const struct clk_master_characteristics sam9rl_mck_characteristics = { 11 13 .output = { .min = 0, .max = 94000000 }, 12 14 .divisors = { 1, 2, 4, 0 }, ··· 119 117 parent_names[1] = "mainck"; 120 118 parent_names[2] = "pllack"; 121 119 parent_names[3] = "utmick"; 122 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 123 - &at91rm9200_master_layout, 124 - &sam9rl_mck_characteristics); 120 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 121 + parent_names, 122 + &at91rm9200_master_layout, 123 + &sam9rl_mck_characteristics, 124 + &sam9rl_mck_lock, CLK_SET_RATE_GATE, 125 + INT_MIN); 126 + if (IS_ERR(hw)) 127 + goto err_free; 128 + 129 + hw = at91_clk_register_master_div(regmap, "masterck_div", 130 + "masterck_pres", 131 + &at91rm9200_master_layout, 132 + &sam9rl_mck_characteristics, 133 + &sam9rl_mck_lock, CLK_SET_RATE_GATE); 125 134 if (IS_ERR(hw)) 126 135 goto err_free; 127 136 ··· 142 129 parent_names[1] = "mainck"; 143 130 parent_names[2] = "pllack"; 144 131 parent_names[3] = "utmick"; 145 - parent_names[4] = "masterck"; 132 + parent_names[4] = "masterck_div"; 146 133 for (i = 0; i < 2; i++) { 147 134 char name[6]; 148 135 ··· 171 158 for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) { 172 159 hw = at91_clk_register_peripheral(regmap, 173 160 at91sam9rl_periphck[i].n, 174 - "masterck", 161 + "masterck_div", 175 162 at91sam9rl_periphck[i].id); 176 163 if (IS_ERR(hw)) 177 164 goto err_free;
+20 -8
drivers/clk/at91/at91sam9x5.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 0, .max = 133333333 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 43 41 char *p; 44 42 u8 id; 45 43 } at91sam9x5_systemck[] = { 46 - { .n = "ddrck", .p = "masterck", .id = 2 }, 44 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 47 45 { .n = "smdck", .p = "smdclk", .id = 4 }, 48 46 { .n = "uhpck", .p = "usbck", .id = 6 }, 49 47 { .n = "udpck", .p = "usbck", .id = 7 }, ··· 198 196 parent_names[1] = "mainck"; 199 197 parent_names[2] = "plladivck"; 200 198 parent_names[3] = "utmick"; 201 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 202 - &at91sam9x5_master_layout, 203 - &mck_characteristics); 199 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 200 + parent_names, 201 + &at91sam9x5_master_layout, 202 + &mck_characteristics, &mck_lock, 203 + CLK_SET_RATE_GATE, INT_MIN); 204 + if (IS_ERR(hw)) 205 + goto err_free; 206 + 207 + hw = at91_clk_register_master_div(regmap, "masterck_div", 208 + "masterck_pres", 209 + &at91sam9x5_master_layout, 210 + &mck_characteristics, &mck_lock, 211 + CLK_SET_RATE_GATE); 204 212 if (IS_ERR(hw)) 205 213 goto err_free; 206 214 ··· 230 218 parent_names[1] = "mainck"; 231 219 parent_names[2] = "plladivck"; 232 220 parent_names[3] = "utmick"; 233 - parent_names[4] = "masterck"; 221 + parent_names[4] = "masterck_div"; 234 222 for (i = 0; i < 2; i++) { 235 223 char name[6]; 236 224 ··· 257 245 } 258 246 259 247 if (has_lcdck) { 260 - hw = at91_clk_register_system(regmap, "lcdck", "masterck", 3); 248 + hw = at91_clk_register_system(regmap, "lcdck", "masterck_div", 3); 261 249 if (IS_ERR(hw)) 262 250 goto err_free; 263 251 ··· 268 256 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 269 257 &at91sam9x5_pcr_layout, 270 258 at91sam9x5_periphck[i].n, 271 - "masterck", 259 + "masterck_div", 272 260 at91sam9x5_periphck[i].id, 273 261 &range, INT_MIN); 274 262 if (IS_ERR(hw)) ··· 281 269 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 282 270 &at91sam9x5_pcr_layout, 283 271 extra_pcks[i].n, 284 - "masterck", 272 + "masterck_div", 285 273 extra_pcks[i].id, 286 274 &range, INT_MIN); 287 275 if (IS_ERR(hw))
+316 -71
drivers/clk/at91/clk-master.c
··· 15 15 #define MASTER_PRES_MASK 0x7 16 16 #define MASTER_PRES_MAX MASTER_PRES_MASK 17 17 #define MASTER_DIV_SHIFT 8 18 - #define MASTER_DIV_MASK 0x3 18 + #define MASTER_DIV_MASK 0x7 19 19 20 20 #define PMC_MCR 0x30 21 21 #define PMC_MCR_ID_MSK GENMASK(3, 0) ··· 58 58 static int clk_master_prepare(struct clk_hw *hw) 59 59 { 60 60 struct clk_master *master = to_clk_master(hw); 61 + unsigned long flags; 62 + 63 + spin_lock_irqsave(master->lock, flags); 61 64 62 65 while (!clk_master_ready(master)) 63 66 cpu_relax(); 67 + 68 + spin_unlock_irqrestore(master->lock, flags); 64 69 65 70 return 0; 66 71 } ··· 73 68 static int clk_master_is_prepared(struct clk_hw *hw) 74 69 { 75 70 struct clk_master *master = to_clk_master(hw); 71 + unsigned long flags; 72 + bool status; 76 73 77 - return clk_master_ready(master); 74 + spin_lock_irqsave(master->lock, flags); 75 + status = clk_master_ready(master); 76 + spin_unlock_irqrestore(master->lock, flags); 77 + 78 + return status; 78 79 } 79 80 80 - static unsigned long clk_master_recalc_rate(struct clk_hw *hw, 81 - unsigned long parent_rate) 81 + static unsigned long clk_master_div_recalc_rate(struct clk_hw *hw, 82 + unsigned long parent_rate) 82 83 { 83 - u8 pres; 84 84 u8 div; 85 - unsigned long rate = parent_rate; 85 + unsigned long flags, rate = parent_rate; 86 86 struct clk_master *master = to_clk_master(hw); 87 87 const struct clk_master_layout *layout = master->layout; 88 88 const struct clk_master_characteristics *characteristics = 89 89 master->characteristics; 90 90 unsigned int mckr; 91 91 92 + spin_lock_irqsave(master->lock, flags); 92 93 regmap_read(master->regmap, master->layout->offset, &mckr); 94 + spin_unlock_irqrestore(master->lock, flags); 95 + 93 96 mckr &= layout->mask; 94 97 95 - pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; 96 98 div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; 97 - 98 - if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) 99 - rate /= 3; 100 - else 101 - rate >>= pres; 102 99 103 100 rate /= characteristics->divisors[div]; 104 101 105 102 if (rate < characteristics->output.min) 106 - pr_warn("master clk is underclocked"); 103 + pr_warn("master clk div is underclocked"); 107 104 else if (rate > characteristics->output.max) 108 - pr_warn("master clk is overclocked"); 105 + pr_warn("master clk div is overclocked"); 109 106 110 107 return rate; 111 108 } 112 109 113 - static u8 clk_master_get_parent(struct clk_hw *hw) 114 - { 115 - struct clk_master *master = to_clk_master(hw); 116 - unsigned int mckr; 117 - 118 - regmap_read(master->regmap, master->layout->offset, &mckr); 119 - 120 - return mckr & AT91_PMC_CSS; 121 - } 122 - 123 - static const struct clk_ops master_ops = { 110 + static const struct clk_ops master_div_ops = { 124 111 .prepare = clk_master_prepare, 125 112 .is_prepared = clk_master_is_prepared, 126 - .recalc_rate = clk_master_recalc_rate, 127 - .get_parent = clk_master_get_parent, 113 + .recalc_rate = clk_master_div_recalc_rate, 128 114 }; 129 115 130 - struct clk_hw * __init 131 - at91_clk_register_master(struct regmap *regmap, 132 - const char *name, int num_parents, 133 - const char **parent_names, 134 - const struct clk_master_layout *layout, 135 - const struct clk_master_characteristics *characteristics) 136 - { 137 - struct clk_master *master; 138 - struct clk_init_data init; 139 - struct clk_hw *hw; 140 - int ret; 141 - 142 - if (!name || !num_parents || !parent_names) 143 - return ERR_PTR(-EINVAL); 144 - 145 - master = kzalloc(sizeof(*master), GFP_KERNEL); 146 - if (!master) 147 - return ERR_PTR(-ENOMEM); 148 - 149 - init.name = name; 150 - init.ops = &master_ops; 151 - init.parent_names = parent_names; 152 - init.num_parents = num_parents; 153 - init.flags = 0; 154 - 155 - master->hw.init = &init; 156 - master->layout = layout; 157 - master->characteristics = characteristics; 158 - master->regmap = regmap; 159 - 160 - hw = &master->hw; 161 - ret = clk_hw_register(NULL, &master->hw); 162 - if (ret) { 163 - kfree(master); 164 - hw = ERR_PTR(ret); 165 - } 166 - 167 - return hw; 168 - } 169 - 170 - static unsigned long 171 - clk_sama7g5_master_recalc_rate(struct clk_hw *hw, 172 - unsigned long parent_rate) 116 + static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, 117 + unsigned long parent_rate) 173 118 { 174 119 struct clk_master *master = to_clk_master(hw); 120 + const struct clk_master_characteristics *characteristics = 121 + master->characteristics; 122 + unsigned long flags; 123 + int div, i; 175 124 176 - return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); 125 + div = DIV_ROUND_CLOSEST(parent_rate, rate); 126 + if (div > ARRAY_SIZE(characteristics->divisors)) 127 + return -EINVAL; 128 + 129 + for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { 130 + if (!characteristics->divisors[i]) 131 + break; 132 + 133 + if (div == characteristics->divisors[i]) { 134 + div = i; 135 + break; 136 + } 137 + } 138 + 139 + if (i == ARRAY_SIZE(characteristics->divisors)) 140 + return -EINVAL; 141 + 142 + spin_lock_irqsave(master->lock, flags); 143 + regmap_update_bits(master->regmap, master->layout->offset, 144 + (MASTER_DIV_MASK << MASTER_DIV_SHIFT), 145 + (div << MASTER_DIV_SHIFT)); 146 + while (!clk_master_ready(master)) 147 + cpu_relax(); 148 + spin_unlock_irqrestore(master->lock, flags); 149 + 150 + return 0; 177 151 } 152 + 153 + static int clk_master_div_determine_rate(struct clk_hw *hw, 154 + struct clk_rate_request *req) 155 + { 156 + struct clk_master *master = to_clk_master(hw); 157 + const struct clk_master_characteristics *characteristics = 158 + master->characteristics; 159 + struct clk_hw *parent; 160 + unsigned long parent_rate, tmp_rate, best_rate = 0; 161 + int i, best_diff = INT_MIN, tmp_diff; 162 + 163 + parent = clk_hw_get_parent(hw); 164 + if (!parent) 165 + return -EINVAL; 166 + 167 + parent_rate = clk_hw_get_rate(parent); 168 + if (!parent_rate) 169 + return -EINVAL; 170 + 171 + for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { 172 + if (!characteristics->divisors[i]) 173 + break; 174 + 175 + tmp_rate = DIV_ROUND_CLOSEST_ULL(parent_rate, 176 + characteristics->divisors[i]); 177 + tmp_diff = abs(tmp_rate - req->rate); 178 + 179 + if (!best_rate || best_diff > tmp_diff) { 180 + best_diff = tmp_diff; 181 + best_rate = tmp_rate; 182 + } 183 + 184 + if (!best_diff) 185 + break; 186 + } 187 + 188 + req->best_parent_rate = best_rate; 189 + req->best_parent_hw = parent; 190 + req->rate = best_rate; 191 + 192 + return 0; 193 + } 194 + 195 + static const struct clk_ops master_div_ops_chg = { 196 + .prepare = clk_master_prepare, 197 + .is_prepared = clk_master_is_prepared, 198 + .recalc_rate = clk_master_div_recalc_rate, 199 + .determine_rate = clk_master_div_determine_rate, 200 + .set_rate = clk_master_div_set_rate, 201 + }; 178 202 179 203 static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, 180 204 struct clk_hw *parent, ··· 227 193 req->best_parent_rate = parent_rate; 228 194 req->best_parent_hw = parent; 229 195 } 196 + } 197 + 198 + static int clk_master_pres_determine_rate(struct clk_hw *hw, 199 + struct clk_rate_request *req) 200 + { 201 + struct clk_master *master = to_clk_master(hw); 202 + struct clk_rate_request req_parent = *req; 203 + const struct clk_master_characteristics *characteristics = 204 + master->characteristics; 205 + struct clk_hw *parent; 206 + long best_rate = LONG_MIN, best_diff = LONG_MIN; 207 + u32 pres; 208 + int i; 209 + 210 + if (master->chg_pid < 0) 211 + return -EOPNOTSUPP; 212 + 213 + parent = clk_hw_get_parent_by_index(hw, master->chg_pid); 214 + if (!parent) 215 + return -EOPNOTSUPP; 216 + 217 + for (i = 0; i <= MASTER_PRES_MAX; i++) { 218 + if (characteristics->have_div3_pres && i == MASTER_PRES_MAX) 219 + pres = 3; 220 + else 221 + pres = 1 << i; 222 + 223 + req_parent.rate = req->rate * pres; 224 + if (__clk_determine_rate(parent, &req_parent)) 225 + continue; 226 + 227 + clk_sama7g5_master_best_diff(req, parent, req_parent.rate, 228 + &best_diff, &best_rate, pres); 229 + if (!best_diff) 230 + break; 231 + } 232 + 233 + return 0; 234 + } 235 + 236 + static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, 237 + unsigned long parent_rate) 238 + { 239 + struct clk_master *master = to_clk_master(hw); 240 + unsigned long flags; 241 + unsigned int pres; 242 + 243 + pres = DIV_ROUND_CLOSEST(parent_rate, rate); 244 + if (pres > MASTER_PRES_MAX) 245 + return -EINVAL; 246 + 247 + else if (pres == 3) 248 + pres = MASTER_PRES_MAX; 249 + else 250 + pres = ffs(pres) - 1; 251 + 252 + spin_lock_irqsave(master->lock, flags); 253 + regmap_update_bits(master->regmap, master->layout->offset, 254 + (MASTER_PRES_MASK << master->layout->pres_shift), 255 + (pres << master->layout->pres_shift)); 256 + 257 + while (!clk_master_ready(master)) 258 + cpu_relax(); 259 + spin_unlock_irqrestore(master->lock, flags); 260 + 261 + return 0; 262 + } 263 + 264 + static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, 265 + unsigned long parent_rate) 266 + { 267 + struct clk_master *master = to_clk_master(hw); 268 + const struct clk_master_characteristics *characteristics = 269 + master->characteristics; 270 + unsigned long flags; 271 + unsigned int val, pres; 272 + 273 + spin_lock_irqsave(master->lock, flags); 274 + regmap_read(master->regmap, master->layout->offset, &val); 275 + spin_unlock_irqrestore(master->lock, flags); 276 + 277 + pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; 278 + if (pres == 3 && characteristics->have_div3_pres) 279 + pres = 3; 280 + else 281 + pres = (1 << pres); 282 + 283 + return DIV_ROUND_CLOSEST_ULL(parent_rate, pres); 284 + } 285 + 286 + static u8 clk_master_pres_get_parent(struct clk_hw *hw) 287 + { 288 + struct clk_master *master = to_clk_master(hw); 289 + unsigned long flags; 290 + unsigned int mckr; 291 + 292 + spin_lock_irqsave(master->lock, flags); 293 + regmap_read(master->regmap, master->layout->offset, &mckr); 294 + spin_unlock_irqrestore(master->lock, flags); 295 + 296 + return mckr & AT91_PMC_CSS; 297 + } 298 + 299 + static const struct clk_ops master_pres_ops = { 300 + .prepare = clk_master_prepare, 301 + .is_prepared = clk_master_is_prepared, 302 + .recalc_rate = clk_master_pres_recalc_rate, 303 + .get_parent = clk_master_pres_get_parent, 304 + }; 305 + 306 + static const struct clk_ops master_pres_ops_chg = { 307 + .prepare = clk_master_prepare, 308 + .is_prepared = clk_master_is_prepared, 309 + .determine_rate = clk_master_pres_determine_rate, 310 + .recalc_rate = clk_master_pres_recalc_rate, 311 + .get_parent = clk_master_pres_get_parent, 312 + .set_rate = clk_master_pres_set_rate, 313 + }; 314 + 315 + static struct clk_hw * __init 316 + at91_clk_register_master_internal(struct regmap *regmap, 317 + const char *name, int num_parents, 318 + const char **parent_names, 319 + const struct clk_master_layout *layout, 320 + const struct clk_master_characteristics *characteristics, 321 + const struct clk_ops *ops, spinlock_t *lock, u32 flags, 322 + int chg_pid) 323 + { 324 + struct clk_master *master; 325 + struct clk_init_data init; 326 + struct clk_hw *hw; 327 + int ret; 328 + 329 + if (!name || !num_parents || !parent_names || !lock) 330 + return ERR_PTR(-EINVAL); 331 + 332 + master = kzalloc(sizeof(*master), GFP_KERNEL); 333 + if (!master) 334 + return ERR_PTR(-ENOMEM); 335 + 336 + init.name = name; 337 + init.ops = ops; 338 + init.parent_names = parent_names; 339 + init.num_parents = num_parents; 340 + init.flags = flags; 341 + 342 + master->hw.init = &init; 343 + master->layout = layout; 344 + master->characteristics = characteristics; 345 + master->regmap = regmap; 346 + master->chg_pid = chg_pid; 347 + master->lock = lock; 348 + 349 + hw = &master->hw; 350 + ret = clk_hw_register(NULL, &master->hw); 351 + if (ret) { 352 + kfree(master); 353 + hw = ERR_PTR(ret); 354 + } 355 + 356 + return hw; 357 + } 358 + 359 + struct clk_hw * __init 360 + at91_clk_register_master_pres(struct regmap *regmap, 361 + const char *name, int num_parents, 362 + const char **parent_names, 363 + const struct clk_master_layout *layout, 364 + const struct clk_master_characteristics *characteristics, 365 + spinlock_t *lock, u32 flags, int chg_pid) 366 + { 367 + const struct clk_ops *ops; 368 + 369 + if (flags & CLK_SET_RATE_GATE) 370 + ops = &master_pres_ops; 371 + else 372 + ops = &master_pres_ops_chg; 373 + 374 + return at91_clk_register_master_internal(regmap, name, num_parents, 375 + parent_names, layout, 376 + characteristics, ops, 377 + lock, flags, chg_pid); 378 + } 379 + 380 + struct clk_hw * __init 381 + at91_clk_register_master_div(struct regmap *regmap, 382 + const char *name, const char *parent_name, 383 + const struct clk_master_layout *layout, 384 + const struct clk_master_characteristics *characteristics, 385 + spinlock_t *lock, u32 flags) 386 + { 387 + const struct clk_ops *ops; 388 + 389 + if (flags & CLK_SET_RATE_GATE) 390 + ops = &master_div_ops; 391 + else 392 + ops = &master_div_ops_chg; 393 + 394 + return at91_clk_register_master_internal(regmap, name, 1, 395 + &parent_name, layout, 396 + characteristics, ops, 397 + lock, flags, -EINVAL); 398 + } 399 + 400 + static unsigned long 401 + clk_sama7g5_master_recalc_rate(struct clk_hw *hw, 402 + unsigned long parent_rate) 403 + { 404 + struct clk_master *master = to_clk_master(hw); 405 + 406 + return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); 230 407 } 231 408 232 409 static int clk_sama7g5_master_determine_rate(struct clk_hw *hw,
+127 -18
drivers/clk/at91/clk-sam9x60-pll.c
··· 229 229 return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); 230 230 } 231 231 232 + static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, 233 + unsigned long parent_rate) 234 + { 235 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 236 + struct sam9x60_frac *frac = to_sam9x60_frac(core); 237 + struct regmap *regmap = core->regmap; 238 + unsigned long irqflags; 239 + unsigned int val, cfrac, cmul; 240 + long ret; 241 + 242 + ret = sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); 243 + if (ret <= 0) 244 + return ret; 245 + 246 + spin_lock_irqsave(core->lock, irqflags); 247 + 248 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, 249 + core->id); 250 + regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); 251 + cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; 252 + cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; 253 + 254 + if (cmul == frac->mul && cfrac == frac->frac) 255 + goto unlock; 256 + 257 + regmap_write(regmap, AT91_PMC_PLL_CTRL1, 258 + (frac->mul << core->layout->mul_shift) | 259 + (frac->frac << core->layout->frac_shift)); 260 + 261 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 262 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 263 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 264 + 265 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, 266 + AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, 267 + AT91_PMC_PLL_CTRL0_ENLOCK | 268 + AT91_PMC_PLL_CTRL0_ENPLL); 269 + 270 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 271 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 272 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 273 + 274 + while (!sam9x60_pll_ready(regmap, core->id)) 275 + cpu_relax(); 276 + 277 + unlock: 278 + spin_unlock_irqrestore(core->lock, irqflags); 279 + 280 + return ret; 281 + } 282 + 232 283 static const struct clk_ops sam9x60_frac_pll_ops = { 233 284 .prepare = sam9x60_frac_pll_prepare, 234 285 .unprepare = sam9x60_frac_pll_unprepare, ··· 287 236 .recalc_rate = sam9x60_frac_pll_recalc_rate, 288 237 .round_rate = sam9x60_frac_pll_round_rate, 289 238 .set_rate = sam9x60_frac_pll_set_rate, 239 + }; 240 + 241 + static const struct clk_ops sam9x60_frac_pll_ops_chg = { 242 + .prepare = sam9x60_frac_pll_prepare, 243 + .unprepare = sam9x60_frac_pll_unprepare, 244 + .is_prepared = sam9x60_frac_pll_is_prepared, 245 + .recalc_rate = sam9x60_frac_pll_recalc_rate, 246 + .round_rate = sam9x60_frac_pll_round_rate, 247 + .set_rate = sam9x60_frac_pll_set_rate_chg, 290 248 }; 291 249 292 250 static int sam9x60_div_pll_prepare(struct clk_hw *hw) ··· 444 384 return 0; 445 385 } 446 386 387 + static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, 388 + unsigned long parent_rate) 389 + { 390 + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); 391 + struct sam9x60_div *div = to_sam9x60_div(core); 392 + struct regmap *regmap = core->regmap; 393 + unsigned long irqflags; 394 + unsigned int val, cdiv; 395 + 396 + div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1; 397 + 398 + spin_lock_irqsave(core->lock, irqflags); 399 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, 400 + core->id); 401 + regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 402 + cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; 403 + 404 + /* Stop if nothing changed. */ 405 + if (cdiv == div->div) 406 + goto unlock; 407 + 408 + regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, 409 + core->layout->div_mask, 410 + (div->div << core->layout->div_shift)); 411 + 412 + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 413 + AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, 414 + AT91_PMC_PLL_UPDT_UPDATE | core->id); 415 + 416 + while (!sam9x60_pll_ready(regmap, core->id)) 417 + cpu_relax(); 418 + 419 + unlock: 420 + spin_unlock_irqrestore(core->lock, irqflags); 421 + 422 + return 0; 423 + } 424 + 447 425 static const struct clk_ops sam9x60_div_pll_ops = { 448 426 .prepare = sam9x60_div_pll_prepare, 449 427 .unprepare = sam9x60_div_pll_unprepare, ··· 491 393 .set_rate = sam9x60_div_pll_set_rate, 492 394 }; 493 395 396 + static const struct clk_ops sam9x60_div_pll_ops_chg = { 397 + .prepare = sam9x60_div_pll_prepare, 398 + .unprepare = sam9x60_div_pll_unprepare, 399 + .is_prepared = sam9x60_div_pll_is_prepared, 400 + .recalc_rate = sam9x60_div_pll_recalc_rate, 401 + .round_rate = sam9x60_div_pll_round_rate, 402 + .set_rate = sam9x60_div_pll_set_rate_chg, 403 + }; 404 + 494 405 struct clk_hw * __init 495 406 sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, 496 407 const char *name, const char *parent_name, 497 408 struct clk_hw *parent_hw, u8 id, 498 409 const struct clk_pll_characteristics *characteristics, 499 - const struct clk_pll_layout *layout, bool critical) 410 + const struct clk_pll_layout *layout, u32 flags) 500 411 { 501 412 struct sam9x60_frac *frac; 502 413 struct clk_hw *hw; 503 414 struct clk_init_data init; 504 - unsigned long parent_rate, flags; 415 + unsigned long parent_rate, irqflags; 505 416 unsigned int val; 506 417 int ret; 507 418 ··· 524 417 init.name = name; 525 418 init.parent_names = &parent_name; 526 419 init.num_parents = 1; 527 - init.ops = &sam9x60_frac_pll_ops; 528 - init.flags = CLK_SET_RATE_GATE; 529 - if (critical) 530 - init.flags |= CLK_IS_CRITICAL; 420 + if (flags & CLK_SET_RATE_GATE) 421 + init.ops = &sam9x60_frac_pll_ops; 422 + else 423 + init.ops = &sam9x60_frac_pll_ops_chg; 424 + 425 + init.flags = flags; 531 426 532 427 frac->core.id = id; 533 428 frac->core.hw.init = &init; ··· 538 429 frac->core.regmap = regmap; 539 430 frac->core.lock = lock; 540 431 541 - spin_lock_irqsave(frac->core.lock, flags); 432 + spin_lock_irqsave(frac->core.lock, irqflags); 542 433 if (sam9x60_pll_ready(regmap, id)) { 543 434 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 544 435 AT91_PMC_PLL_UPDT_ID_MSK, id); ··· 566 457 goto free; 567 458 } 568 459 } 569 - spin_unlock_irqrestore(frac->core.lock, flags); 460 + spin_unlock_irqrestore(frac->core.lock, irqflags); 570 461 571 462 hw = &frac->core.hw; 572 463 ret = clk_hw_register(NULL, hw); ··· 578 469 return hw; 579 470 580 471 free: 581 - spin_unlock_irqrestore(frac->core.lock, flags); 472 + spin_unlock_irqrestore(frac->core.lock, irqflags); 582 473 kfree(frac); 583 474 return hw; 584 475 } ··· 587 478 sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, 588 479 const char *name, const char *parent_name, u8 id, 589 480 const struct clk_pll_characteristics *characteristics, 590 - const struct clk_pll_layout *layout, bool critical) 481 + const struct clk_pll_layout *layout, u32 flags) 591 482 { 592 483 struct sam9x60_div *div; 593 484 struct clk_hw *hw; 594 485 struct clk_init_data init; 595 - unsigned long flags; 486 + unsigned long irqflags; 596 487 unsigned int val; 597 488 int ret; 598 489 ··· 606 497 init.name = name; 607 498 init.parent_names = &parent_name; 608 499 init.num_parents = 1; 609 - init.ops = &sam9x60_div_pll_ops; 610 - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 611 - CLK_SET_RATE_PARENT; 612 - if (critical) 613 - init.flags |= CLK_IS_CRITICAL; 500 + if (flags & CLK_SET_RATE_GATE) 501 + init.ops = &sam9x60_div_pll_ops; 502 + else 503 + init.ops = &sam9x60_div_pll_ops_chg; 504 + init.flags = flags; 614 505 615 506 div->core.id = id; 616 507 div->core.hw.init = &init; ··· 619 510 div->core.regmap = regmap; 620 511 div->core.lock = lock; 621 512 622 - spin_lock_irqsave(div->core.lock, flags); 513 + spin_lock_irqsave(div->core.lock, irqflags); 623 514 624 515 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 625 516 AT91_PMC_PLL_UPDT_ID_MSK, id); 626 517 regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 627 518 div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); 628 519 629 - spin_unlock_irqrestore(div->core.lock, flags); 520 + spin_unlock_irqrestore(div->core.lock, irqflags); 630 521 631 522 hw = &div->core.hw; 632 523 ret = clk_hw_register(NULL, hw);
+12 -3
drivers/clk/at91/dt-compat.c
··· 24 24 25 25 #define GCK_INDEX_DT_AUDIO_PLL 5 26 26 27 + static DEFINE_SPINLOCK(mck_lock); 28 + 27 29 #ifdef CONFIG_HAVE_AT91_AUDIO_PLL 28 30 static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) 29 31 { ··· 390 388 if (IS_ERR(regmap)) 391 389 return; 392 390 393 - hw = at91_clk_register_master(regmap, name, num_parents, 394 - parent_names, layout, 395 - characteristics); 391 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", num_parents, 392 + parent_names, layout, 393 + characteristics, &mck_lock, 394 + CLK_SET_RATE_GATE, INT_MIN); 395 + if (IS_ERR(hw)) 396 + goto out_free_characteristics; 397 + 398 + hw = at91_clk_register_master_div(regmap, name, "masterck_pres", 399 + layout, characteristics, 400 + &mck_lock, CLK_SET_RATE_GATE); 396 401 if (IS_ERR(hw)) 397 402 goto out_free_characteristics; 398 403
+15 -7
drivers/clk/at91/pmc.h
··· 48 48 49 49 struct clk_master_characteristics { 50 50 struct clk_range output; 51 - u32 divisors[4]; 51 + u32 divisors[5]; 52 52 u8 have_div3_pres; 53 53 }; 54 54 ··· 155 155 const char **parent_names, int num_parents); 156 156 157 157 struct clk_hw * __init 158 - at91_clk_register_master(struct regmap *regmap, const char *name, 159 - int num_parents, const char **parent_names, 160 - const struct clk_master_layout *layout, 161 - const struct clk_master_characteristics *characteristics); 158 + at91_clk_register_master_pres(struct regmap *regmap, const char *name, 159 + int num_parents, const char **parent_names, 160 + const struct clk_master_layout *layout, 161 + const struct clk_master_characteristics *characteristics, 162 + spinlock_t *lock, u32 flags, int chg_pid); 163 + 164 + struct clk_hw * __init 165 + at91_clk_register_master_div(struct regmap *regmap, const char *name, 166 + const char *parent_names, 167 + const struct clk_master_layout *layout, 168 + const struct clk_master_characteristics *characteristics, 169 + spinlock_t *lock, u32 flags); 162 170 163 171 struct clk_hw * __init 164 172 at91_clk_sama7g5_register_master(struct regmap *regmap, ··· 198 190 sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, 199 191 const char *name, const char *parent_name, u8 id, 200 192 const struct clk_pll_characteristics *characteristics, 201 - const struct clk_pll_layout *layout, bool critical); 193 + const struct clk_pll_layout *layout, u32 flags); 202 194 203 195 struct clk_hw * __init 204 196 sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, 205 197 const char *name, const char *parent_name, 206 198 struct clk_hw *parent_hw, u8 id, 207 199 const struct clk_pll_characteristics *characteristics, 208 - const struct clk_pll_layout *layout, bool critical); 200 + const struct clk_pll_layout *layout, u32 flags); 209 201 210 202 struct clk_hw * __init 211 203 at91_clk_register_programmable(struct regmap *regmap, const char *name,
+35 -16
drivers/clk/at91/sam9x60.c
··· 8 8 #include "pmc.h" 9 9 10 10 static DEFINE_SPINLOCK(pmc_pll_lock); 11 + static DEFINE_SPINLOCK(mck_lock); 11 12 12 13 static const struct clk_master_characteristics mck_characteristics = { 13 14 .output = { .min = 140000000, .max = 200000000 }, ··· 77 76 char *p; 78 77 u8 id; 79 78 } sam9x60_systemck[] = { 80 - { .n = "ddrck", .p = "masterck", .id = 2 }, 79 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 81 80 { .n = "uhpck", .p = "usbck", .id = 6 }, 82 81 { .n = "pck0", .p = "prog0", .id = 8 }, 83 82 { .n = "pck1", .p = "prog1", .id = 9 }, 84 - { .n = "qspick", .p = "masterck", .id = 19 }, 83 + { .n = "qspick", .p = "masterck_div", .id = 19 }, 85 84 }; 86 85 87 86 static const struct { ··· 175 174 struct regmap *regmap; 176 175 struct clk_hw *hw; 177 176 int i; 178 - bool bypass; 179 177 180 178 i = of_property_match_string(np, "clock-names", "td_slck"); 181 179 if (i < 0) ··· 209 209 if (IS_ERR(hw)) 210 210 goto err_free; 211 211 212 - bypass = of_property_read_bool(np, "atmel,osc-bypass"); 213 - 214 - hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, 215 - bypass); 212 + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, 0); 216 213 if (IS_ERR(hw)) 217 214 goto err_free; 218 215 main_osc_hw = hw; ··· 225 228 hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "pllack_fracck", 226 229 "mainck", sam9x60_pmc->chws[PMC_MAIN], 227 230 0, &plla_characteristics, 228 - &pll_frac_layout, true); 231 + &pll_frac_layout, 232 + /* 233 + * This feeds pllack_divck which 234 + * feeds CPU. It should not be 235 + * disabled. 236 + */ 237 + CLK_IS_CRITICAL | CLK_SET_RATE_GATE); 229 238 if (IS_ERR(hw)) 230 239 goto err_free; 231 240 232 241 hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "pllack_divck", 233 242 "pllack_fracck", 0, &plla_characteristics, 234 - &pll_div_layout, true); 243 + &pll_div_layout, 244 + /* 245 + * This feeds CPU. It should not 246 + * be disabled. 247 + */ 248 + CLK_IS_CRITICAL | CLK_SET_RATE_GATE); 235 249 if (IS_ERR(hw)) 236 250 goto err_free; 237 251 ··· 251 243 hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "upllck_fracck", 252 244 "main_osc", main_osc_hw, 1, 253 245 &upll_characteristics, 254 - &pll_frac_layout, false); 246 + &pll_frac_layout, CLK_SET_RATE_GATE); 255 247 if (IS_ERR(hw)) 256 248 goto err_free; 257 249 258 250 hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "upllck_divck", 259 251 "upllck_fracck", 1, &upll_characteristics, 260 - &pll_div_layout, false); 252 + &pll_div_layout, 253 + CLK_SET_RATE_GATE | 254 + CLK_SET_PARENT_GATE | 255 + CLK_SET_RATE_PARENT); 261 256 if (IS_ERR(hw)) 262 257 goto err_free; 263 258 ··· 269 258 parent_names[0] = md_slck_name; 270 259 parent_names[1] = "mainck"; 271 260 parent_names[2] = "pllack_divck"; 272 - hw = at91_clk_register_master(regmap, "masterck", 3, parent_names, 273 - &sam9x60_master_layout, 274 - &mck_characteristics); 261 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 3, 262 + parent_names, &sam9x60_master_layout, 263 + &mck_characteristics, &mck_lock, 264 + CLK_SET_RATE_GATE, INT_MIN); 265 + if (IS_ERR(hw)) 266 + goto err_free; 267 + 268 + hw = at91_clk_register_master_div(regmap, "masterck_div", 269 + "masterck_pres", &sam9x60_master_layout, 270 + &mck_characteristics, &mck_lock, 271 + CLK_SET_RATE_GATE); 275 272 if (IS_ERR(hw)) 276 273 goto err_free; 277 274 ··· 295 276 parent_names[0] = md_slck_name; 296 277 parent_names[1] = td_slck_name; 297 278 parent_names[2] = "mainck"; 298 - parent_names[3] = "masterck"; 279 + parent_names[3] = "masterck_div"; 299 280 parent_names[4] = "pllack_divck"; 300 281 parent_names[5] = "upllck_divck"; 301 282 for (i = 0; i < 2; i++) { ··· 327 308 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 328 309 &sam9x60_pcr_layout, 329 310 sam9x60_periphck[i].n, 330 - "masterck", 311 + "masterck_div", 331 312 sam9x60_periphck[i].id, 332 313 &range, INT_MIN); 333 314 if (IS_ERR(hw))
+27 -15
drivers/clk/at91/sama5d2.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 124000000, .max = 166000000 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 42 40 char *p; 43 41 u8 id; 44 42 } sama5d2_systemck[] = { 45 - { .n = "ddrck", .p = "masterck", .id = 2 }, 46 - { .n = "lcdck", .p = "masterck", .id = 3 }, 47 - { .n = "uhpck", .p = "usbck", .id = 6 }, 48 - { .n = "udpck", .p = "usbck", .id = 7 }, 49 - { .n = "pck0", .p = "prog0", .id = 8 }, 50 - { .n = "pck1", .p = "prog1", .id = 9 }, 51 - { .n = "pck2", .p = "prog2", .id = 10 }, 52 - { .n = "iscck", .p = "masterck", .id = 18 }, 43 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 44 + { .n = "lcdck", .p = "masterck_div", .id = 3 }, 45 + { .n = "uhpck", .p = "usbck", .id = 6 }, 46 + { .n = "udpck", .p = "usbck", .id = 7 }, 47 + { .n = "pck0", .p = "prog0", .id = 8 }, 48 + { .n = "pck1", .p = "prog1", .id = 9 }, 49 + { .n = "pck2", .p = "prog2", .id = 10 }, 50 + { .n = "iscck", .p = "masterck_div", .id = 18 }, 53 51 }; 54 52 55 53 static const struct { ··· 237 235 parent_names[1] = "mainck"; 238 236 parent_names[2] = "plladivck"; 239 237 parent_names[3] = "utmick"; 240 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 241 - &at91sam9x5_master_layout, 242 - &mck_characteristics); 238 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 239 + parent_names, 240 + &at91sam9x5_master_layout, 241 + &mck_characteristics, &mck_lock, 242 + CLK_SET_RATE_GATE, INT_MIN); 243 + if (IS_ERR(hw)) 244 + goto err_free; 245 + 246 + hw = at91_clk_register_master_div(regmap, "masterck_div", 247 + "masterck_pres", 248 + &at91sam9x5_master_layout, 249 + &mck_characteristics, &mck_lock, 250 + CLK_SET_RATE_GATE); 243 251 if (IS_ERR(hw)) 244 252 goto err_free; 245 253 246 254 sama5d2_pmc->chws[PMC_MCK] = hw; 247 255 248 - hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck"); 256 + hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck_div"); 249 257 if (IS_ERR(hw)) 250 258 goto err_free; 251 259 ··· 271 259 parent_names[1] = "mainck"; 272 260 parent_names[2] = "plladivck"; 273 261 parent_names[3] = "utmick"; 274 - parent_names[4] = "masterck"; 262 + parent_names[4] = "masterck_div"; 275 263 parent_names[5] = "audiopll_pmcck"; 276 264 for (i = 0; i < 3; i++) { 277 265 char name[6]; ··· 302 290 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 303 291 &sama5d2_pcr_layout, 304 292 sama5d2_periphck[i].n, 305 - "masterck", 293 + "masterck_div", 306 294 sama5d2_periphck[i].id, 307 295 &range, INT_MIN); 308 296 if (IS_ERR(hw)) ··· 329 317 parent_names[1] = "mainck"; 330 318 parent_names[2] = "plladivck"; 331 319 parent_names[3] = "utmick"; 332 - parent_names[4] = "masterck"; 320 + parent_names[4] = "masterck_div"; 333 321 parent_names[5] = "audiopll_pmcck"; 334 322 for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) { 335 323 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
+25 -13
drivers/clk/at91/sama5d3.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 0, .max = 166000000 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 42 40 char *p; 43 41 u8 id; 44 42 } sama5d3_systemck[] = { 45 - { .n = "ddrck", .p = "masterck", .id = 2 }, 46 - { .n = "lcdck", .p = "masterck", .id = 3 }, 47 - { .n = "smdck", .p = "smdclk", .id = 4 }, 48 - { .n = "uhpck", .p = "usbck", .id = 6 }, 49 - { .n = "udpck", .p = "usbck", .id = 7 }, 50 - { .n = "pck0", .p = "prog0", .id = 8 }, 51 - { .n = "pck1", .p = "prog1", .id = 9 }, 52 - { .n = "pck2", .p = "prog2", .id = 10 }, 43 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 44 + { .n = "lcdck", .p = "masterck_div", .id = 3 }, 45 + { .n = "smdck", .p = "smdclk", .id = 4 }, 46 + { .n = "uhpck", .p = "usbck", .id = 6 }, 47 + { .n = "udpck", .p = "usbck", .id = 7 }, 48 + { .n = "pck0", .p = "prog0", .id = 8 }, 49 + { .n = "pck1", .p = "prog1", .id = 9 }, 50 + { .n = "pck2", .p = "prog2", .id = 10 }, 53 51 }; 54 52 55 53 static const struct { ··· 172 170 parent_names[1] = "mainck"; 173 171 parent_names[2] = "plladivck"; 174 172 parent_names[3] = "utmick"; 175 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 176 - &at91sam9x5_master_layout, 177 - &mck_characteristics); 173 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 174 + parent_names, 175 + &at91sam9x5_master_layout, 176 + &mck_characteristics, &mck_lock, 177 + CLK_SET_RATE_GATE, INT_MIN); 178 + if (IS_ERR(hw)) 179 + goto err_free; 180 + 181 + hw = at91_clk_register_master_div(regmap, "masterck_div", 182 + "masterck_pres", 183 + &at91sam9x5_master_layout, 184 + &mck_characteristics, &mck_lock, 185 + CLK_SET_RATE_GATE); 178 186 if (IS_ERR(hw)) 179 187 goto err_free; 180 188 ··· 204 192 parent_names[1] = "mainck"; 205 193 parent_names[2] = "plladivck"; 206 194 parent_names[3] = "utmick"; 207 - parent_names[4] = "masterck"; 195 + parent_names[4] = "masterck_div"; 208 196 for (i = 0; i < 3; i++) { 209 197 char name[6]; 210 198 ··· 234 222 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 235 223 &sama5d3_pcr_layout, 236 224 sama5d3_periphck[i].n, 237 - "masterck", 225 + "masterck_div", 238 226 sama5d3_periphck[i].id, 239 227 &sama5d3_periphck[i].r, 240 228 INT_MIN);
+26 -14
drivers/clk/at91/sama5d4.c
··· 7 7 8 8 #include "pmc.h" 9 9 10 + static DEFINE_SPINLOCK(mck_lock); 11 + 10 12 static const struct clk_master_characteristics mck_characteristics = { 11 13 .output = { .min = 125000000, .max = 200000000 }, 12 14 .divisors = { 1, 2, 4, 3 }, ··· 41 39 char *p; 42 40 u8 id; 43 41 } sama5d4_systemck[] = { 44 - { .n = "ddrck", .p = "masterck", .id = 2 }, 45 - { .n = "lcdck", .p = "masterck", .id = 3 }, 46 - { .n = "smdck", .p = "smdclk", .id = 4 }, 47 - { .n = "uhpck", .p = "usbck", .id = 6 }, 48 - { .n = "udpck", .p = "usbck", .id = 7 }, 49 - { .n = "pck0", .p = "prog0", .id = 8 }, 50 - { .n = "pck1", .p = "prog1", .id = 9 }, 51 - { .n = "pck2", .p = "prog2", .id = 10 }, 42 + { .n = "ddrck", .p = "masterck_div", .id = 2 }, 43 + { .n = "lcdck", .p = "masterck_div", .id = 3 }, 44 + { .n = "smdck", .p = "smdclk", .id = 4 }, 45 + { .n = "uhpck", .p = "usbck", .id = 6 }, 46 + { .n = "udpck", .p = "usbck", .id = 7 }, 47 + { .n = "pck0", .p = "prog0", .id = 8 }, 48 + { .n = "pck1", .p = "prog1", .id = 9 }, 49 + { .n = "pck2", .p = "prog2", .id = 10 }, 52 50 }; 53 51 54 52 static const struct { ··· 187 185 parent_names[1] = "mainck"; 188 186 parent_names[2] = "plladivck"; 189 187 parent_names[3] = "utmick"; 190 - hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, 191 - &at91sam9x5_master_layout, 192 - &mck_characteristics); 188 + hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, 189 + parent_names, 190 + &at91sam9x5_master_layout, 191 + &mck_characteristics, &mck_lock, 192 + CLK_SET_RATE_GATE, INT_MIN); 193 + if (IS_ERR(hw)) 194 + goto err_free; 195 + 196 + hw = at91_clk_register_master_div(regmap, "masterck_div", 197 + "masterck_pres", 198 + &at91sam9x5_master_layout, 199 + &mck_characteristics, &mck_lock, 200 + CLK_SET_RATE_GATE); 193 201 if (IS_ERR(hw)) 194 202 goto err_free; 195 203 196 204 sama5d4_pmc->chws[PMC_MCK] = hw; 197 205 198 - hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck"); 206 + hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck_div"); 199 207 if (IS_ERR(hw)) 200 208 goto err_free; 201 209 ··· 227 215 parent_names[1] = "mainck"; 228 216 parent_names[2] = "plladivck"; 229 217 parent_names[3] = "utmick"; 230 - parent_names[4] = "masterck"; 218 + parent_names[4] = "masterck_div"; 231 219 for (i = 0; i < 3; i++) { 232 220 char name[6]; 233 221 ··· 257 245 hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, 258 246 &sama5d4_pcr_layout, 259 247 sama5d4_periphck[i].n, 260 - "masterck", 248 + "masterck_div", 261 249 sama5d4_periphck[i].id, 262 250 &range, INT_MIN); 263 251 if (IS_ERR(hw))
+149 -74
drivers/clk/at91/sama7g5.c
··· 32 32 } while (0) 33 33 34 34 static DEFINE_SPINLOCK(pmc_pll_lock); 35 + static DEFINE_SPINLOCK(pmc_mck0_lock); 35 36 static DEFINE_SPINLOCK(pmc_mckX_lock); 36 37 37 38 /** ··· 90 89 .endiv_shift = 30, 91 90 }; 92 91 92 + /* 93 + * CPU PLL output range. 94 + * Notice: The upper limit has been setup to 1000000002 due to hardware 95 + * block which cannot output exactly 1GHz. 96 + */ 97 + static const struct clk_range cpu_pll_outputs[] = { 98 + { .min = 2343750, .max = 1000000002 }, 99 + }; 100 + 101 + /* PLL output range. */ 102 + static const struct clk_range pll_outputs[] = { 103 + { .min = 2343750, .max = 1200000000 }, 104 + }; 105 + 106 + /* CPU PLL characteristics. */ 107 + static const struct clk_pll_characteristics cpu_pll_characteristics = { 108 + .input = { .min = 12000000, .max = 50000000 }, 109 + .num_output = ARRAY_SIZE(cpu_pll_outputs), 110 + .output = cpu_pll_outputs, 111 + }; 112 + 113 + /* PLL characteristics. */ 114 + static const struct clk_pll_characteristics pll_characteristics = { 115 + .input = { .min = 12000000, .max = 50000000 }, 116 + .num_output = ARRAY_SIZE(pll_outputs), 117 + .output = pll_outputs, 118 + }; 119 + 93 120 /** 94 121 * PLL clocks description 95 122 * @n: clock name 96 123 * @p: clock parent 97 124 * @l: clock layout 125 + * @c: clock characteristics 98 126 * @t: clock type 99 - * @f: true if clock is critical and cannot be disabled 127 + * @f: clock flags 100 128 * @eid: export index in sama7g5->chws[] array 101 129 */ 102 130 static const struct { 103 131 const char *n; 104 132 const char *p; 105 133 const struct clk_pll_layout *l; 134 + const struct clk_pll_characteristics *c; 135 + unsigned long f; 106 136 u8 t; 107 - u8 c; 108 137 u8 eid; 109 138 } sama7g5_plls[][PLL_ID_MAX] = { 110 139 [PLL_ID_CPU] = { 111 140 { .n = "cpupll_fracck", 112 141 .p = "mainck", 113 142 .l = &pll_layout_frac, 143 + .c = &cpu_pll_characteristics, 114 144 .t = PLL_TYPE_FRAC, 115 - .c = 1, }, 145 + /* 146 + * This feeds cpupll_divpmcck which feeds CPU. It should 147 + * not be disabled. 148 + */ 149 + .f = CLK_IS_CRITICAL, }, 116 150 117 151 { .n = "cpupll_divpmcck", 118 152 .p = "cpupll_fracck", 119 153 .l = &pll_layout_divpmc, 154 + .c = &cpu_pll_characteristics, 120 155 .t = PLL_TYPE_DIV, 121 - .c = 1, }, 156 + /* This feeds CPU. It should not be disabled. */ 157 + .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, 158 + .eid = PMC_CPUPLL, }, 122 159 }, 123 160 124 161 [PLL_ID_SYS] = { 125 162 { .n = "syspll_fracck", 126 163 .p = "mainck", 127 164 .l = &pll_layout_frac, 165 + .c = &pll_characteristics, 128 166 .t = PLL_TYPE_FRAC, 129 - .c = 1, }, 167 + /* 168 + * This feeds syspll_divpmcck which may feed critial parts 169 + * of the systems like timers. Therefore it should not be 170 + * disabled. 171 + */ 172 + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, 130 173 131 174 { .n = "syspll_divpmcck", 132 175 .p = "syspll_fracck", 133 176 .l = &pll_layout_divpmc, 177 + .c = &pll_characteristics, 134 178 .t = PLL_TYPE_DIV, 135 - .c = 1, }, 179 + /* 180 + * This may feed critial parts of the systems like timers. 181 + * Therefore it should not be disabled. 182 + */ 183 + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 184 + .eid = PMC_SYSPLL, }, 136 185 }, 137 186 138 187 [PLL_ID_DDR] = { 139 188 { .n = "ddrpll_fracck", 140 189 .p = "mainck", 141 190 .l = &pll_layout_frac, 191 + .c = &pll_characteristics, 142 192 .t = PLL_TYPE_FRAC, 143 - .c = 1, }, 193 + /* 194 + * This feeds ddrpll_divpmcck which feeds DDR. It should not 195 + * be disabled. 196 + */ 197 + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, 144 198 145 199 { .n = "ddrpll_divpmcck", 146 200 .p = "ddrpll_fracck", 147 201 .l = &pll_layout_divpmc, 202 + .c = &pll_characteristics, 148 203 .t = PLL_TYPE_DIV, 149 - .c = 1, }, 204 + /* This feeds DDR. It should not be disabled. */ 205 + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, 150 206 }, 151 207 152 208 [PLL_ID_IMG] = { 153 209 { .n = "imgpll_fracck", 154 210 .p = "mainck", 155 211 .l = &pll_layout_frac, 156 - .t = PLL_TYPE_FRAC, }, 212 + .c = &pll_characteristics, 213 + .t = PLL_TYPE_FRAC, 214 + .f = CLK_SET_RATE_GATE, }, 157 215 158 216 { .n = "imgpll_divpmcck", 159 217 .p = "imgpll_fracck", 160 218 .l = &pll_layout_divpmc, 161 - .t = PLL_TYPE_DIV, }, 219 + .c = &pll_characteristics, 220 + .t = PLL_TYPE_DIV, 221 + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 222 + CLK_SET_RATE_PARENT, }, 162 223 }, 163 224 164 225 [PLL_ID_BAUD] = { 165 226 { .n = "baudpll_fracck", 166 227 .p = "mainck", 167 228 .l = &pll_layout_frac, 168 - .t = PLL_TYPE_FRAC, }, 229 + .c = &pll_characteristics, 230 + .t = PLL_TYPE_FRAC, 231 + .f = CLK_SET_RATE_GATE, }, 169 232 170 233 { .n = "baudpll_divpmcck", 171 234 .p = "baudpll_fracck", 172 235 .l = &pll_layout_divpmc, 173 - .t = PLL_TYPE_DIV, }, 236 + .c = &pll_characteristics, 237 + .t = PLL_TYPE_DIV, 238 + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 239 + CLK_SET_RATE_PARENT, }, 174 240 }, 175 241 176 242 [PLL_ID_AUDIO] = { 177 243 { .n = "audiopll_fracck", 178 244 .p = "main_xtal", 179 245 .l = &pll_layout_frac, 180 - .t = PLL_TYPE_FRAC, }, 246 + .c = &pll_characteristics, 247 + .t = PLL_TYPE_FRAC, 248 + .f = CLK_SET_RATE_GATE, }, 181 249 182 250 { .n = "audiopll_divpmcck", 183 251 .p = "audiopll_fracck", 184 252 .l = &pll_layout_divpmc, 253 + .c = &pll_characteristics, 185 254 .t = PLL_TYPE_DIV, 186 - .eid = PMC_I2S0_MUX, }, 255 + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 256 + CLK_SET_RATE_PARENT, 257 + .eid = PMC_AUDIOPMCPLL, }, 187 258 188 259 { .n = "audiopll_diviock", 189 260 .p = "audiopll_fracck", 190 261 .l = &pll_layout_divio, 262 + .c = &pll_characteristics, 191 263 .t = PLL_TYPE_DIV, 192 - .eid = PMC_I2S1_MUX, }, 264 + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 265 + CLK_SET_RATE_PARENT, 266 + .eid = PMC_AUDIOIOPLL, }, 193 267 }, 194 268 195 269 [PLL_ID_ETH] = { 196 270 { .n = "ethpll_fracck", 197 271 .p = "main_xtal", 198 272 .l = &pll_layout_frac, 199 - .t = PLL_TYPE_FRAC, }, 273 + .c = &pll_characteristics, 274 + .t = PLL_TYPE_FRAC, 275 + .f = CLK_SET_RATE_GATE, }, 200 276 201 277 { .n = "ethpll_divpmcck", 202 278 .p = "ethpll_fracck", 203 279 .l = &pll_layout_divpmc, 204 - .t = PLL_TYPE_DIV, }, 280 + .c = &pll_characteristics, 281 + .t = PLL_TYPE_DIV, 282 + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 283 + CLK_SET_RATE_PARENT, }, 205 284 }, 206 285 }; 207 286 ··· 326 245 .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", }, 327 246 .ep_mux_table = { 5, 6, 7, }, 328 247 .ep_count = 3, 329 - .ep_chg_id = 6, }, 248 + .ep_chg_id = 5, }, 330 249 331 250 { .n = "mck4", 332 251 .id = 4, ··· 359 278 }; 360 279 361 280 /* Mux table for programmable clocks. */ 362 - static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, }; 281 + static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, }; 363 282 364 283 /** 365 284 * Peripheral clock description ··· 482 401 .pp = { "audiopll_divpmcck", }, 483 402 .pp_mux_table = { 9, }, 484 403 .pp_count = 1, 485 - .pp_chg_id = 4, }, 404 + .pp_chg_id = 3, }, 486 405 487 406 { .n = "csi_gclk", 488 407 .id = 33, ··· 594 513 .pp = { "ethpll_divpmcck", }, 595 514 .pp_mux_table = { 10, }, 596 515 .pp_count = 1, 597 - .pp_chg_id = 4, }, 516 + .pp_chg_id = 3, }, 598 517 599 518 { .n = "gmac1_gclk", 600 519 .id = 52, ··· 626 545 .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 627 546 .pp_mux_table = { 5, 9, }, 628 547 .pp_count = 2, 629 - .pp_chg_id = 5, }, 548 + .pp_chg_id = 4, }, 630 549 631 550 { .n = "i2smcc1_gclk", 632 551 .id = 58, ··· 634 553 .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 635 554 .pp_mux_table = { 5, 9, }, 636 555 .pp_count = 2, 637 - .pp_chg_id = 5, }, 556 + .pp_chg_id = 4, }, 638 557 639 558 { .n = "mcan0_gclk", 640 559 .id = 61, ··· 776 695 .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 777 696 .pp_mux_table = { 5, 8, }, 778 697 .pp_count = 2, 779 - .pp_chg_id = 5, }, 698 + .pp_chg_id = 4, }, 780 699 781 700 { .n = "sdmmc1_gclk", 782 701 .id = 81, ··· 784 703 .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 785 704 .pp_mux_table = { 5, 8, }, 786 705 .pp_count = 2, 787 - .pp_chg_id = 5, }, 706 + .pp_chg_id = 4, }, 788 707 789 708 { .n = "sdmmc2_gclk", 790 709 .id = 82, ··· 792 711 .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, 793 712 .pp_mux_table = { 5, 8, }, 794 713 .pp_count = 2, 795 - .pp_chg_id = 5, }, 714 + .pp_chg_id = 4, }, 796 715 797 716 { .n = "spdifrx_gclk", 798 717 .id = 84, ··· 800 719 .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 801 720 .pp_mux_table = { 5, 9, }, 802 721 .pp_count = 2, 803 - .pp_chg_id = 5, }, 722 + .pp_chg_id = 4, }, 804 723 805 724 { .n = "spdiftx_gclk", 806 725 .id = 85, ··· 808 727 .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, 809 728 .pp_mux_table = { 5, 9, }, 810 729 .pp_count = 2, 811 - .pp_chg_id = 5, }, 730 + .pp_chg_id = 4, }, 812 731 813 732 { .n = "tcb0_ch0_gclk", 814 733 .id = 88, ··· 839 758 .pp_chg_id = INT_MIN, }, 840 759 }; 841 760 842 - /* PLL output range. */ 843 - static const struct clk_range pll_outputs[] = { 844 - { .min = 2343750, .max = 1200000000 }, 845 - }; 846 - 847 - /* PLL characteristics. */ 848 - static const struct clk_pll_characteristics pll_characteristics = { 849 - .input = { .min = 12000000, .max = 50000000 }, 850 - .num_output = ARRAY_SIZE(pll_outputs), 851 - .output = pll_outputs, 852 - }; 853 - 854 761 /* MCK0 characteristics. */ 855 762 static const struct clk_master_characteristics mck0_characteristics = { 856 - .output = { .min = 140000000, .max = 200000000 }, 857 - .divisors = { 1, 2, 4, 3 }, 763 + .output = { .min = 50000000, .max = 200000000 }, 764 + .divisors = { 1, 2, 4, 3, 5 }, 858 765 .have_div3_pres = 1, 859 766 }; 860 767 861 768 /* MCK0 layout. */ 862 769 static const struct clk_master_layout mck0_layout = { 863 - .mask = 0x373, 770 + .mask = 0x773, 864 771 .pres_shift = 4, 865 772 .offset = 0x28, 866 773 }; ··· 904 835 if (IS_ERR(regmap)) 905 836 return; 906 837 907 - sama7g5_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1, 838 + sama7g5_pmc = pmc_data_allocate(PMC_CPU + 1, 908 839 nck(sama7g5_systemck), 909 840 nck(sama7g5_periphck), 910 - nck(sama7g5_gck)); 841 + nck(sama7g5_gck), 8); 911 842 if (!sama7g5_pmc) 912 843 return; 913 844 ··· 955 886 hw = sam9x60_clk_register_frac_pll(regmap, 956 887 &pmc_pll_lock, sama7g5_plls[i][j].n, 957 888 sama7g5_plls[i][j].p, parent_hw, i, 958 - &pll_characteristics, 889 + sama7g5_plls[i][j].c, 959 890 sama7g5_plls[i][j].l, 960 - sama7g5_plls[i][j].c); 891 + sama7g5_plls[i][j].f); 961 892 break; 962 893 963 894 case PLL_TYPE_DIV: 964 895 hw = sam9x60_clk_register_div_pll(regmap, 965 896 &pmc_pll_lock, sama7g5_plls[i][j].n, 966 897 sama7g5_plls[i][j].p, i, 967 - &pll_characteristics, 898 + sama7g5_plls[i][j].c, 968 899 sama7g5_plls[i][j].l, 969 - sama7g5_plls[i][j].c); 900 + sama7g5_plls[i][j].f); 970 901 break; 971 902 972 903 default: ··· 981 912 } 982 913 } 983 914 984 - parent_names[0] = md_slck_name; 985 - parent_names[1] = "mainck"; 986 - parent_names[2] = "cpupll_divpmcck"; 987 - parent_names[3] = "syspll_divpmcck"; 988 - hw = at91_clk_register_master(regmap, "mck0", 4, parent_names, 989 - &mck0_layout, &mck0_characteristics); 915 + parent_names[0] = "cpupll_divpmcck"; 916 + hw = at91_clk_register_master_pres(regmap, "cpuck", 1, parent_names, 917 + &mck0_layout, &mck0_characteristics, 918 + &pmc_mck0_lock, 919 + CLK_SET_RATE_PARENT, 0); 920 + if (IS_ERR(hw)) 921 + goto err_free; 922 + 923 + sama7g5_pmc->chws[PMC_CPU] = hw; 924 + 925 + hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", 926 + &mck0_layout, &mck0_characteristics, 927 + &pmc_mck0_lock, 0); 990 928 if (IS_ERR(hw)) 991 929 goto err_free; 992 930 ··· 1002 926 parent_names[0] = md_slck_name; 1003 927 parent_names[1] = td_slck_name; 1004 928 parent_names[2] = "mainck"; 1005 - parent_names[3] = "mck0"; 1006 929 for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { 1007 - u8 num_parents = 4 + sama7g5_mckx[i].ep_count; 930 + u8 num_parents = 3 + sama7g5_mckx[i].ep_count; 1008 931 u32 *mux_table; 1009 932 1010 933 mux_table = kmalloc_array(num_parents, sizeof(*mux_table), ··· 1011 936 if (!mux_table) 1012 937 goto err_free; 1013 938 1014 - SAMA7G5_INIT_TABLE(mux_table, 4); 1015 - SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_mckx[i].ep_mux_table, 939 + SAMA7G5_INIT_TABLE(mux_table, 3); 940 + SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table, 1016 941 sama7g5_mckx[i].ep_count); 1017 - SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_mckx[i].ep, 942 + SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_mckx[i].ep, 1018 943 sama7g5_mckx[i].ep_count); 1019 944 1020 945 hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n, ··· 1037 962 parent_names[0] = md_slck_name; 1038 963 parent_names[1] = td_slck_name; 1039 964 parent_names[2] = "mainck"; 1040 - parent_names[3] = "mck0"; 1041 - parent_names[4] = "syspll_divpmcck"; 1042 - parent_names[5] = "ddrpll_divpmcck"; 1043 - parent_names[6] = "imgpll_divpmcck"; 1044 - parent_names[7] = "baudpll_divpmcck"; 1045 - parent_names[8] = "audiopll_divpmcck"; 1046 - parent_names[9] = "ethpll_divpmcck"; 965 + parent_names[3] = "syspll_divpmcck"; 966 + parent_names[4] = "ddrpll_divpmcck"; 967 + parent_names[5] = "imgpll_divpmcck"; 968 + parent_names[6] = "baudpll_divpmcck"; 969 + parent_names[7] = "audiopll_divpmcck"; 970 + parent_names[8] = "ethpll_divpmcck"; 1047 971 for (i = 0; i < 8; i++) { 1048 972 char name[6]; 1049 973 1050 974 snprintf(name, sizeof(name), "prog%d", i); 1051 975 1052 976 hw = at91_clk_register_programmable(regmap, name, parent_names, 1053 - 10, i, 977 + 9, i, 1054 978 &programmable_layout, 1055 979 sama7g5_prog_mux_table); 1056 980 if (IS_ERR(hw)) 1057 981 goto err_free; 982 + 983 + sama7g5_pmc->pchws[i] = hw; 1058 984 } 1059 985 1060 986 for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) { ··· 1086 1010 parent_names[0] = md_slck_name; 1087 1011 parent_names[1] = td_slck_name; 1088 1012 parent_names[2] = "mainck"; 1089 - parent_names[3] = "mck0"; 1090 1013 for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { 1091 - u8 num_parents = 4 + sama7g5_gck[i].pp_count; 1014 + u8 num_parents = 3 + sama7g5_gck[i].pp_count; 1092 1015 u32 *mux_table; 1093 1016 1094 1017 mux_table = kmalloc_array(num_parents, sizeof(*mux_table), ··· 1095 1020 if (!mux_table) 1096 1021 goto err_free; 1097 1022 1098 - SAMA7G5_INIT_TABLE(mux_table, 4); 1099 - SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_gck[i].pp_mux_table, 1023 + SAMA7G5_INIT_TABLE(mux_table, 3); 1024 + SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table, 1100 1025 sama7g5_gck[i].pp_count); 1101 - SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_gck[i].pp, 1026 + SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_gck[i].pp, 1102 1027 sama7g5_gck[i].pp_count); 1103 1028 1104 1029 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, ··· 1127 1052 kfree(alloc_mem); 1128 1053 } 1129 1054 1130 - pmc_data_free(sama7g5_pmc); 1055 + kfree(sama7g5_pmc); 1131 1056 } 1132 1057 1133 1058 /* Some clks are used for a clocksource */
+2 -2
drivers/clk/bcm/clk-bcm2711-dvp.c
··· 25 25 static int clk_dvp_probe(struct platform_device *pdev) 26 26 { 27 27 struct clk_hw_onecell_data *data; 28 - struct resource *res; 29 28 struct clk_dvp *dvp; 30 29 void __iomem *base; 31 30 int ret; ··· 41 42 return -ENOMEM; 42 43 data = dvp->data; 43 44 44 - base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 45 + base = devm_platform_ioremap_resource(pdev, 0); 45 46 if (IS_ERR(base)) 46 47 return PTR_ERR(base); 47 48 ··· 107 108 { .compatible = "brcm,brcm2711-dvp", }, 108 109 { /* sentinel */ } 109 110 }; 111 + MODULE_DEVICE_TABLE(of, clk_dvp_dt_ids); 110 112 111 113 static struct platform_driver clk_dvp_driver = { 112 114 .probe = clk_dvp_probe,
+39 -25
drivers/clk/clk-axi-clkgen.c
··· 46 46 #define MMCM_CLK_DIV_DIVIDE BIT(11) 47 47 #define MMCM_CLK_DIV_NOCOUNT BIT(12) 48 48 49 + struct axi_clkgen_limits { 50 + unsigned int fpfd_min; 51 + unsigned int fpfd_max; 52 + unsigned int fvco_min; 53 + unsigned int fvco_max; 54 + }; 55 + 49 56 struct axi_clkgen { 50 57 void __iomem *base; 51 58 struct clk_hw clk_hw; 59 + struct axi_clkgen_limits limits; 52 60 }; 53 61 54 62 static uint32_t axi_clkgen_lookup_filter(unsigned int m) ··· 108 100 return 0x1f1f00fa; 109 101 } 110 102 111 - static const unsigned int fpfd_min = 10000; 112 - static const unsigned int fpfd_max = 300000; 113 - static const unsigned int fvco_min = 600000; 114 - static const unsigned int fvco_max = 1200000; 103 + static const struct axi_clkgen_limits axi_clkgen_zynq_default_limits = { 104 + .fpfd_min = 10000, 105 + .fpfd_max = 300000, 106 + .fvco_min = 600000, 107 + .fvco_max = 1200000, 108 + }; 115 109 116 - static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout, 110 + static void axi_clkgen_calc_params(const struct axi_clkgen_limits *limits, 111 + unsigned long fin, unsigned long fout, 117 112 unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout) 118 113 { 119 114 unsigned long d, d_min, d_max, _d_min, _d_max; ··· 133 122 *best_m = 0; 134 123 *best_dout = 0; 135 124 136 - d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1); 137 - d_max = min_t(unsigned long, fin / fpfd_min, 80); 125 + d_min = max_t(unsigned long, DIV_ROUND_UP(fin, limits->fpfd_max), 1); 126 + d_max = min_t(unsigned long, fin / limits->fpfd_min, 80); 138 127 139 128 again: 140 - fvco_min_fract = fvco_min << fract_shift; 141 - fvco_max_fract = fvco_max << fract_shift; 129 + fvco_min_fract = limits->fvco_min << fract_shift; 130 + fvco_max_fract = limits->fvco_max << fract_shift; 142 131 143 132 m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min_fract, fin) * d_min, 1); 144 133 m_max = min_t(unsigned long, fvco_max_fract * d_max / fin, 64 << fract_shift); ··· 330 319 unsigned long rate, unsigned long parent_rate) 331 320 { 332 321 struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw); 322 + const struct axi_clkgen_limits *limits = &axi_clkgen->limits; 333 323 unsigned int d, m, dout; 334 324 struct axi_clkgen_div_params params; 335 325 uint32_t power = 0; ··· 340 328 if (parent_rate == 0 || rate == 0) 341 329 return -EINVAL; 342 330 343 - axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout); 331 + axi_clkgen_calc_params(limits, parent_rate, rate, &d, &m, &dout); 344 332 345 333 if (d == 0 || dout == 0 || m == 0) 346 334 return -EINVAL; ··· 380 368 static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate, 381 369 unsigned long *parent_rate) 382 370 { 371 + struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(hw); 372 + const struct axi_clkgen_limits *limits = &axi_clkgen->limits; 383 373 unsigned int d, m, dout; 384 374 unsigned long long tmp; 385 375 386 - axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout); 376 + axi_clkgen_calc_params(limits, *parent_rate, rate, &d, &m, &dout); 387 377 388 378 if (d == 0 || dout == 0 || m == 0) 389 379 return -EINVAL; ··· 496 482 .get_parent = axi_clkgen_get_parent, 497 483 }; 498 484 499 - static const struct of_device_id axi_clkgen_ids[] = { 500 - { 501 - .compatible = "adi,axi-clkgen-2.00.a", 502 - }, 503 - { }, 504 - }; 505 - MODULE_DEVICE_TABLE(of, axi_clkgen_ids); 506 - 507 485 static int axi_clkgen_probe(struct platform_device *pdev) 508 486 { 509 - const struct of_device_id *id; 487 + const struct axi_clkgen_limits *dflt_limits; 510 488 struct axi_clkgen *axi_clkgen; 511 489 struct clk_init_data init; 512 490 const char *parent_names[2]; ··· 507 501 unsigned int i; 508 502 int ret; 509 503 510 - if (!pdev->dev.of_node) 511 - return -ENODEV; 512 - 513 - id = of_match_node(axi_clkgen_ids, pdev->dev.of_node); 514 - if (!id) 504 + dflt_limits = device_get_match_data(&pdev->dev); 505 + if (!dflt_limits) 515 506 return -ENODEV; 516 507 517 508 axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL); ··· 529 526 if (!parent_names[i]) 530 527 return -EINVAL; 531 528 } 529 + 530 + memcpy(&axi_clkgen->limits, dflt_limits, sizeof(axi_clkgen->limits)); 532 531 533 532 clk_name = pdev->dev.of_node->name; 534 533 of_property_read_string(pdev->dev.of_node, "clock-output-names", ··· 558 553 559 554 return 0; 560 555 } 556 + 557 + static const struct of_device_id axi_clkgen_ids[] = { 558 + { 559 + .compatible = "adi,axi-clkgen-2.00.a", 560 + .data = &axi_clkgen_zynq_default_limits, 561 + }, 562 + { } 563 + }; 564 + MODULE_DEVICE_TABLE(of, axi_clkgen_ids); 561 565 562 566 static struct platform_driver axi_clkgen_driver = { 563 567 .driver = {
+50
drivers/clk/clk-composite.c
··· 4 4 */ 5 5 6 6 #include <linux/clk-provider.h> 7 + #include <linux/device.h> 7 8 #include <linux/err.h> 8 9 #include <linux/slab.h> 9 10 ··· 406 405 kfree(composite); 407 406 } 408 407 EXPORT_SYMBOL_GPL(clk_hw_unregister_composite); 408 + 409 + static void devm_clk_hw_release_composite(struct device *dev, void *res) 410 + { 411 + clk_hw_unregister_composite(*(struct clk_hw **)res); 412 + } 413 + 414 + static struct clk_hw *__devm_clk_hw_register_composite(struct device *dev, 415 + const char *name, const char * const *parent_names, 416 + const struct clk_parent_data *pdata, int num_parents, 417 + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 418 + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 419 + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 420 + unsigned long flags) 421 + { 422 + struct clk_hw **ptr, *hw; 423 + 424 + ptr = devres_alloc(devm_clk_hw_release_composite, sizeof(*ptr), 425 + GFP_KERNEL); 426 + if (!ptr) 427 + return ERR_PTR(-ENOMEM); 428 + 429 + hw = __clk_hw_register_composite(dev, name, parent_names, pdata, 430 + num_parents, mux_hw, mux_ops, rate_hw, 431 + rate_ops, gate_hw, gate_ops, flags); 432 + 433 + if (!IS_ERR(hw)) { 434 + *ptr = hw; 435 + devres_add(dev, ptr); 436 + } else { 437 + devres_free(ptr); 438 + } 439 + 440 + return hw; 441 + } 442 + 443 + struct clk_hw *devm_clk_hw_register_composite_pdata(struct device *dev, 444 + const char *name, 445 + const struct clk_parent_data *parent_data, 446 + int num_parents, 447 + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 448 + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 449 + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 450 + unsigned long flags) 451 + { 452 + return __devm_clk_hw_register_composite(dev, name, NULL, parent_data, 453 + num_parents, mux_hw, mux_ops, 454 + rate_hw, rate_ops, gate_hw, 455 + gate_ops, flags); 456 + }
+34
drivers/clk/clk-divider.c
··· 8 8 */ 9 9 10 10 #include <linux/clk-provider.h> 11 + #include <linux/device.h> 11 12 #include <linux/module.h> 12 13 #include <linux/slab.h> 13 14 #include <linux/io.h> ··· 579 578 kfree(div); 580 579 } 581 580 EXPORT_SYMBOL_GPL(clk_hw_unregister_divider); 581 + 582 + static void devm_clk_hw_release_divider(struct device *dev, void *res) 583 + { 584 + clk_hw_unregister_divider(*(struct clk_hw **)res); 585 + } 586 + 587 + struct clk_hw *__devm_clk_hw_register_divider(struct device *dev, 588 + struct device_node *np, const char *name, 589 + const char *parent_name, const struct clk_hw *parent_hw, 590 + const struct clk_parent_data *parent_data, unsigned long flags, 591 + void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, 592 + const struct clk_div_table *table, spinlock_t *lock) 593 + { 594 + struct clk_hw **ptr, *hw; 595 + 596 + ptr = devres_alloc(devm_clk_hw_release_divider, sizeof(*ptr), GFP_KERNEL); 597 + if (!ptr) 598 + return ERR_PTR(-ENOMEM); 599 + 600 + hw = __clk_hw_register_divider(dev, np, name, parent_name, parent_hw, 601 + parent_data, flags, reg, shift, width, 602 + clk_divider_flags, table, lock); 603 + 604 + if (!IS_ERR(hw)) { 605 + *ptr = hw; 606 + devres_add(dev, ptr); 607 + } else { 608 + devres_free(ptr); 609 + } 610 + 611 + return hw; 612 + } 613 + EXPORT_SYMBOL_GPL(__devm_clk_hw_register_divider);
+106
drivers/clk/clk-fsl-flexspi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Layerscape FlexSPI clock driver 4 + * 5 + * Copyright 2020 Michael Walle <michael@walle.cc> 6 + */ 7 + 8 + #include <linux/clk-provider.h> 9 + #include <linux/io.h> 10 + #include <linux/module.h> 11 + #include <linux/platform_device.h> 12 + 13 + static const struct clk_div_table ls1028a_flexspi_divs[] = { 14 + { .val = 0, .div = 1, }, 15 + { .val = 1, .div = 2, }, 16 + { .val = 2, .div = 3, }, 17 + { .val = 3, .div = 4, }, 18 + { .val = 4, .div = 5, }, 19 + { .val = 5, .div = 6, }, 20 + { .val = 6, .div = 7, }, 21 + { .val = 7, .div = 8, }, 22 + { .val = 11, .div = 12, }, 23 + { .val = 15, .div = 16, }, 24 + { .val = 16, .div = 20, }, 25 + { .val = 17, .div = 24, }, 26 + { .val = 18, .div = 28, }, 27 + { .val = 19, .div = 32, }, 28 + { .val = 20, .div = 80, }, 29 + {} 30 + }; 31 + 32 + static const struct clk_div_table lx2160a_flexspi_divs[] = { 33 + { .val = 1, .div = 2, }, 34 + { .val = 3, .div = 4, }, 35 + { .val = 5, .div = 6, }, 36 + { .val = 7, .div = 8, }, 37 + { .val = 11, .div = 12, }, 38 + { .val = 15, .div = 16, }, 39 + { .val = 16, .div = 20, }, 40 + { .val = 17, .div = 24, }, 41 + { .val = 18, .div = 28, }, 42 + { .val = 19, .div = 32, }, 43 + { .val = 20, .div = 80, }, 44 + {} 45 + }; 46 + 47 + static int fsl_flexspi_clk_probe(struct platform_device *pdev) 48 + { 49 + struct device *dev = &pdev->dev; 50 + struct device_node *np = dev->of_node; 51 + const char *clk_name = np->name; 52 + const char *clk_parent; 53 + struct resource *res; 54 + void __iomem *reg; 55 + struct clk_hw *hw; 56 + const struct clk_div_table *divs; 57 + 58 + divs = device_get_match_data(dev); 59 + if (!divs) 60 + return -ENOENT; 61 + 62 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 63 + if (!res) 64 + return -ENOENT; 65 + 66 + /* 67 + * Can't use devm_ioremap_resource() or devm_of_iomap() because the 68 + * resource might already be taken by the parent device. 69 + */ 70 + reg = devm_ioremap(dev, res->start, resource_size(res)); 71 + if (!reg) 72 + return -ENOMEM; 73 + 74 + clk_parent = of_clk_get_parent_name(np, 0); 75 + if (!clk_parent) 76 + return -EINVAL; 77 + 78 + of_property_read_string(np, "clock-output-names", &clk_name); 79 + 80 + hw = devm_clk_hw_register_divider_table(dev, clk_name, clk_parent, 0, 81 + reg, 0, 5, 0, divs, NULL); 82 + if (IS_ERR(hw)) 83 + return PTR_ERR(hw); 84 + 85 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw); 86 + } 87 + 88 + static const struct of_device_id fsl_flexspi_clk_dt_ids[] = { 89 + { .compatible = "fsl,ls1028a-flexspi-clk", .data = &ls1028a_flexspi_divs }, 90 + { .compatible = "fsl,lx2160a-flexspi-clk", .data = &lx2160a_flexspi_divs }, 91 + {} 92 + }; 93 + MODULE_DEVICE_TABLE(of, fsl_flexspi_clk_dt_ids); 94 + 95 + static struct platform_driver fsl_flexspi_clk_driver = { 96 + .driver = { 97 + .name = "fsl-flexspi-clk", 98 + .of_match_table = fsl_flexspi_clk_dt_ids, 99 + }, 100 + .probe = fsl_flexspi_clk_probe, 101 + }; 102 + module_platform_driver(fsl_flexspi_clk_driver); 103 + 104 + MODULE_DESCRIPTION("FlexSPI clock driver for Layerscape SoCs"); 105 + MODULE_AUTHOR("Michael Walle <michael@walle.cc>"); 106 + MODULE_LICENSE("GPL");
+7 -7
drivers/clk/clk-fsl-sai.c
··· 58 58 /* set clock direction, we are the BCLK master */ 59 59 writel(CR2_BCD, base + I2S_CR2); 60 60 61 - hw = clk_hw_register_composite_pdata(dev, dev->of_node->name, 62 - &pdata, 1, NULL, NULL, 63 - &sai_clk->div.hw, 64 - &clk_divider_ops, 65 - &sai_clk->gate.hw, 66 - &clk_gate_ops, 67 - CLK_SET_RATE_GATE); 61 + hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name, 62 + &pdata, 1, NULL, NULL, 63 + &sai_clk->div.hw, 64 + &clk_divider_ops, 65 + &sai_clk->gate.hw, 66 + &clk_gate_ops, 67 + CLK_SET_RATE_GATE); 68 68 if (IS_ERR(hw)) 69 69 return PTR_ERR(hw); 70 70
+1 -1
drivers/clk/clk-pwm.c
··· 147 147 .remove = clk_pwm_remove, 148 148 .driver = { 149 149 .name = "pwm-clock", 150 - .of_match_table = of_match_ptr(clk_pwm_dt_ids), 150 + .of_match_table = clk_pwm_dt_ids, 151 151 }, 152 152 }; 153 153
+7 -6
drivers/clk/clk-qoriq.c
··· 7 7 8 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 9 10 + #include <dt-bindings/clock/fsl,qoriq-clockgen.h> 10 11 #include <linux/clk.h> 11 12 #include <linux/clk-provider.h> 12 13 #include <linux/clkdev.h> ··· 1369 1368 idx = clkspec->args[1]; 1370 1369 1371 1370 switch (type) { 1372 - case 0: 1371 + case QORIQ_CLK_SYSCLK: 1373 1372 if (idx != 0) 1374 1373 goto bad_args; 1375 1374 clk = cg->sysclk; 1376 1375 break; 1377 - case 1: 1376 + case QORIQ_CLK_CMUX: 1378 1377 if (idx >= ARRAY_SIZE(cg->cmux)) 1379 1378 goto bad_args; 1380 1379 clk = cg->cmux[idx]; 1381 1380 break; 1382 - case 2: 1381 + case QORIQ_CLK_HWACCEL: 1383 1382 if (idx >= ARRAY_SIZE(cg->hwaccel)) 1384 1383 goto bad_args; 1385 1384 clk = cg->hwaccel[idx]; 1386 1385 break; 1387 - case 3: 1386 + case QORIQ_CLK_FMAN: 1388 1387 if (idx >= ARRAY_SIZE(cg->fman)) 1389 1388 goto bad_args; 1390 1389 clk = cg->fman[idx]; 1391 1390 break; 1392 - case 4: 1391 + case QORIQ_CLK_PLATFORM_PLL: 1393 1392 pll = &cg->pll[PLATFORM_PLL]; 1394 1393 if (idx >= ARRAY_SIZE(pll->div)) 1395 1394 goto bad_args; 1396 1395 clk = pll->div[idx].clk; 1397 1396 break; 1398 - case 5: 1397 + case QORIQ_CLK_CORECLK: 1399 1398 if (idx != 0) 1400 1399 goto bad_args; 1401 1400 clk = cg->coreclk;
+1
drivers/clk/clk-s2mps11.c
··· 195 195 return ret; 196 196 197 197 err_reg: 198 + of_node_put(s2mps11_clks[0].clk_np); 198 199 while (--i >= 0) 199 200 clkdev_drop(s2mps11_clks[i].lookup); 200 201
+1 -1
drivers/clk/clk-scpi.c
··· 129 129 .set_rate = scpi_dvfs_set_rate, 130 130 }; 131 131 132 - static const struct of_device_id scpi_clk_match[] = { 132 + static const struct of_device_id scpi_clk_match[] __maybe_unused = { 133 133 { .compatible = "arm,scpi-dvfs-clocks", .data = &scpi_dvfs_ops, }, 134 134 { .compatible = "arm,scpi-variable-clocks", .data = &scpi_clk_ops, }, 135 135 {}
+10 -3
drivers/clk/clk-si5351.c
··· 902 902 static void _si5351_clkout_reset_pll(struct si5351_driver_data *drvdata, int num) 903 903 { 904 904 u8 val = si5351_reg_read(drvdata, SI5351_CLK0_CTRL + num); 905 + u8 mask = val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B : 906 + SI5351_PLL_RESET_A; 907 + unsigned int v; 908 + int err; 905 909 906 910 switch (val & SI5351_CLK_INPUT_MASK) { 907 911 case SI5351_CLK_INPUT_XTAL: ··· 913 909 return; /* pll not used, no need to reset */ 914 910 } 915 911 916 - si5351_reg_write(drvdata, SI5351_PLL_RESET, 917 - val & SI5351_CLK_PLL_SELECT ? SI5351_PLL_RESET_B : 918 - SI5351_PLL_RESET_A); 912 + si5351_reg_write(drvdata, SI5351_PLL_RESET, mask); 913 + 914 + err = regmap_read_poll_timeout(drvdata->regmap, SI5351_PLL_RESET, v, 915 + !(v & mask), 0, 20000); 916 + if (err < 0) 917 + dev_err(&drvdata->client->dev, "Reset bit didn't clear\n"); 919 918 920 919 dev_dbg(&drvdata->client->dev, "%s - %s: pll = %d\n", 921 920 __func__, clk_hw_get_name(&drvdata->clkout[num].hw),
+2 -2
drivers/clk/clk-versaclock5.c
··· 739 739 { 740 740 u32 value; 741 741 742 - if (!of_property_read_u32(np_output, 743 - "idt,voltage-microvolts", &value)) { 742 + if (!of_property_read_u32(np_output, "idt,voltage-microvolt", 743 + &value)) { 744 744 clk_out->clk_output_cfg0_mask |= VC5_CLK_OUTPUT_CFG0_PWR_MASK; 745 745 switch (value) { 746 746 case 1800000:
+121 -11
drivers/clk/clk.c
··· 420 420 static void clk_core_fill_parent_index(struct clk_core *core, u8 index) 421 421 { 422 422 struct clk_parent_map *entry = &core->parents[index]; 423 - struct clk_core *parent = ERR_PTR(-ENOENT); 423 + struct clk_core *parent; 424 424 425 425 if (entry->hw) { 426 426 parent = entry->hw->core; ··· 2314 2314 if (!clk) 2315 2315 return 0; 2316 2316 2317 + trace_clk_set_rate_range(clk->core, min, max); 2318 + 2317 2319 if (min > max) { 2318 2320 pr_err("%s: clk %s dev %s con %s: invalid range [%lu, %lu]\n", 2319 2321 __func__, clk->core->name, clk->dev_id, clk->con_id, ··· 2383 2381 if (!clk) 2384 2382 return 0; 2385 2383 2384 + trace_clk_set_min_rate(clk->core, rate); 2385 + 2386 2386 return clk_set_rate_range(clk, rate, clk->max_rate); 2387 2387 } 2388 2388 EXPORT_SYMBOL_GPL(clk_set_min_rate); ··· 2400 2396 { 2401 2397 if (!clk) 2402 2398 return 0; 2399 + 2400 + trace_clk_set_max_rate(clk->core, rate); 2403 2401 2404 2402 return clk_set_rate_range(clk, clk->min_rate, rate); 2405 2403 } ··· 2937 2931 else 2938 2932 seq_puts(s, "-----"); 2939 2933 2940 - seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000)); 2934 + seq_printf(s, " %6d", clk_core_get_scaled_duty_cycle(c, 100000)); 2935 + 2936 + if (c->ops->is_enabled) 2937 + seq_printf(s, " %9c\n", clk_core_is_enabled(c) ? 'Y' : 'N'); 2938 + else if (!c->ops->enable) 2939 + seq_printf(s, " %9c\n", 'Y'); 2940 + else 2941 + seq_printf(s, " %9c\n", '?'); 2941 2942 } 2942 2943 2943 2944 static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, ··· 2963 2950 struct clk_core *c; 2964 2951 struct hlist_head **lists = (struct hlist_head **)s->private; 2965 2952 2966 - seq_puts(s, " enable prepare protect duty\n"); 2967 - seq_puts(s, " clock count count count rate accuracy phase cycle\n"); 2968 - seq_puts(s, "---------------------------------------------------------------------------------------------\n"); 2953 + seq_puts(s, " enable prepare protect duty hardware\n"); 2954 + seq_puts(s, " clock count count count rate accuracy phase cycle enable\n"); 2955 + seq_puts(s, "-------------------------------------------------------------------------------------------------------\n"); 2969 2956 2970 2957 clk_prepare_lock(); 2971 2958 ··· 3680 3667 return clk; 3681 3668 } 3682 3669 3670 + /** 3671 + * clk_hw_get_clk - get clk consumer given an clk_hw 3672 + * @hw: clk_hw associated with the clk being consumed 3673 + * @con_id: connection ID string on device 3674 + * 3675 + * Returns: new clk consumer 3676 + * This is the function to be used by providers which need 3677 + * to get a consumer clk and act on the clock element 3678 + * Calls to this function must be balanced with calls clk_put() 3679 + */ 3680 + struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id) 3681 + { 3682 + struct device *dev = hw->core->dev; 3683 + 3684 + return clk_hw_create_clk(dev, hw, dev_name(dev), con_id); 3685 + } 3686 + EXPORT_SYMBOL(clk_hw_get_clk); 3687 + 3683 3688 static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist) 3684 3689 { 3685 3690 const char *dst; ··· 4099 4068 } 4100 4069 EXPORT_SYMBOL_GPL(clk_hw_unregister); 4101 4070 4102 - static void devm_clk_release(struct device *dev, void *res) 4071 + static void devm_clk_unregister_cb(struct device *dev, void *res) 4103 4072 { 4104 4073 clk_unregister(*(struct clk **)res); 4105 4074 } 4106 4075 4107 - static void devm_clk_hw_release(struct device *dev, void *res) 4076 + static void devm_clk_hw_unregister_cb(struct device *dev, void *res) 4108 4077 { 4109 4078 clk_hw_unregister(*(struct clk_hw **)res); 4110 4079 } ··· 4124 4093 struct clk *clk; 4125 4094 struct clk **clkp; 4126 4095 4127 - clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL); 4096 + clkp = devres_alloc(devm_clk_unregister_cb, sizeof(*clkp), GFP_KERNEL); 4128 4097 if (!clkp) 4129 4098 return ERR_PTR(-ENOMEM); 4130 4099 ··· 4154 4123 struct clk_hw **hwp; 4155 4124 int ret; 4156 4125 4157 - hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL); 4126 + hwp = devres_alloc(devm_clk_hw_unregister_cb, sizeof(*hwp), GFP_KERNEL); 4158 4127 if (!hwp) 4159 4128 return -ENOMEM; 4160 4129 ··· 4198 4167 */ 4199 4168 void devm_clk_unregister(struct device *dev, struct clk *clk) 4200 4169 { 4201 - WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk)); 4170 + WARN_ON(devres_release(dev, devm_clk_unregister_cb, devm_clk_match, clk)); 4202 4171 } 4203 4172 EXPORT_SYMBOL_GPL(devm_clk_unregister); 4204 4173 ··· 4213 4182 */ 4214 4183 void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw) 4215 4184 { 4216 - WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match, 4185 + WARN_ON(devres_release(dev, devm_clk_hw_unregister_cb, devm_clk_hw_match, 4217 4186 hw)); 4218 4187 } 4219 4188 EXPORT_SYMBOL_GPL(devm_clk_hw_unregister); 4189 + 4190 + static void devm_clk_release(struct device *dev, void *res) 4191 + { 4192 + clk_put(*(struct clk **)res); 4193 + } 4194 + 4195 + /** 4196 + * devm_clk_hw_get_clk - resource managed clk_hw_get_clk() 4197 + * @dev: device that is registering this clock 4198 + * @hw: clk_hw associated with the clk being consumed 4199 + * @con_id: connection ID string on device 4200 + * 4201 + * Managed clk_hw_get_clk(). Clocks got with this function are 4202 + * automatically clk_put() on driver detach. See clk_put() 4203 + * for more information. 4204 + */ 4205 + struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw, 4206 + const char *con_id) 4207 + { 4208 + struct clk *clk; 4209 + struct clk **clkp; 4210 + 4211 + /* This should not happen because it would mean we have drivers 4212 + * passing around clk_hw pointers instead of having the caller use 4213 + * proper clk_get() style APIs 4214 + */ 4215 + WARN_ON_ONCE(dev != hw->core->dev); 4216 + 4217 + clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL); 4218 + if (!clkp) 4219 + return ERR_PTR(-ENOMEM); 4220 + 4221 + clk = clk_hw_get_clk(hw, con_id); 4222 + if (!IS_ERR(clk)) { 4223 + *clkp = clk; 4224 + devres_add(dev, clkp); 4225 + } else { 4226 + devres_free(clkp); 4227 + } 4228 + 4229 + return clk; 4230 + } 4231 + EXPORT_SYMBOL_GPL(devm_clk_hw_get_clk); 4220 4232 4221 4233 /* 4222 4234 * clkdev helpers ··· 4407 4333 return ret; 4408 4334 } 4409 4335 EXPORT_SYMBOL_GPL(clk_notifier_unregister); 4336 + 4337 + struct clk_notifier_devres { 4338 + struct clk *clk; 4339 + struct notifier_block *nb; 4340 + }; 4341 + 4342 + static void devm_clk_notifier_release(struct device *dev, void *res) 4343 + { 4344 + struct clk_notifier_devres *devres = res; 4345 + 4346 + clk_notifier_unregister(devres->clk, devres->nb); 4347 + } 4348 + 4349 + int devm_clk_notifier_register(struct device *dev, struct clk *clk, 4350 + struct notifier_block *nb) 4351 + { 4352 + struct clk_notifier_devres *devres; 4353 + int ret; 4354 + 4355 + devres = devres_alloc(devm_clk_notifier_release, 4356 + sizeof(*devres), GFP_KERNEL); 4357 + 4358 + if (!devres) 4359 + return -ENOMEM; 4360 + 4361 + ret = clk_notifier_register(clk, nb); 4362 + if (!ret) { 4363 + devres->clk = clk; 4364 + devres->nb = nb; 4365 + } else { 4366 + devres_free(devres); 4367 + } 4368 + 4369 + return ret; 4370 + } 4371 + EXPORT_SYMBOL_GPL(devm_clk_notifier_register); 4410 4372 4411 4373 #ifdef CONFIG_OF 4412 4374 static void clk_core_reparent_orphans(void)
+32 -36
drivers/clk/imx/clk-gate2.c
··· 30 30 void __iomem *reg; 31 31 u8 bit_idx; 32 32 u8 cgr_val; 33 + u8 cgr_mask; 33 34 u8 flags; 34 35 spinlock_t *lock; 35 36 unsigned int *share_count; ··· 38 37 39 38 #define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw) 40 39 41 - static int clk_gate2_enable(struct clk_hw *hw) 40 + static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable) 42 41 { 43 42 struct clk_gate2 *gate = to_clk_gate2(hw); 44 43 u32 reg; 44 + 45 + reg = readl(gate->reg); 46 + reg &= ~(gate->cgr_mask << gate->bit_idx); 47 + if (enable) 48 + reg |= (gate->cgr_val & gate->cgr_mask) << gate->bit_idx; 49 + writel(reg, gate->reg); 50 + } 51 + 52 + static int clk_gate2_enable(struct clk_hw *hw) 53 + { 54 + struct clk_gate2 *gate = to_clk_gate2(hw); 45 55 unsigned long flags; 46 - int ret = 0; 47 56 48 57 spin_lock_irqsave(gate->lock, flags); 49 58 50 59 if (gate->share_count && (*gate->share_count)++ > 0) 51 60 goto out; 52 61 53 - if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) { 54 - ret = clk_gate_ops.enable(hw); 55 - } else { 56 - reg = readl(gate->reg); 57 - reg &= ~(3 << gate->bit_idx); 58 - reg |= gate->cgr_val << gate->bit_idx; 59 - writel(reg, gate->reg); 60 - } 61 - 62 + clk_gate2_do_shared_clks(hw, true); 62 63 out: 63 64 spin_unlock_irqrestore(gate->lock, flags); 64 65 65 - return ret; 66 + return 0; 66 67 } 67 68 68 69 static void clk_gate2_disable(struct clk_hw *hw) 69 70 { 70 71 struct clk_gate2 *gate = to_clk_gate2(hw); 71 - u32 reg; 72 72 unsigned long flags; 73 73 74 74 spin_lock_irqsave(gate->lock, flags); ··· 81 79 goto out; 82 80 } 83 81 84 - if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) { 85 - clk_gate_ops.disable(hw); 86 - } else { 87 - reg = readl(gate->reg); 88 - reg &= ~(3 << gate->bit_idx); 89 - writel(reg, gate->reg); 90 - } 91 - 82 + clk_gate2_do_shared_clks(hw, false); 92 83 out: 93 84 spin_unlock_irqrestore(gate->lock, flags); 94 85 } 95 86 96 - static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx) 87 + static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx, 88 + u8 cgr_val, u8 cgr_mask) 97 89 { 98 90 u32 val = readl(reg); 99 91 100 - if (((val >> bit_idx) & 1) == 1) 92 + if (((val >> bit_idx) & cgr_mask) == cgr_val) 101 93 return 1; 102 94 103 95 return 0; ··· 100 104 static int clk_gate2_is_enabled(struct clk_hw *hw) 101 105 { 102 106 struct clk_gate2 *gate = to_clk_gate2(hw); 107 + unsigned long flags; 108 + int ret = 0; 103 109 104 - if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) 105 - return clk_gate_ops.is_enabled(hw); 110 + spin_lock_irqsave(gate->lock, flags); 106 111 107 - return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); 112 + ret = clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx, 113 + gate->cgr_val, gate->cgr_mask); 114 + 115 + spin_unlock_irqrestore(gate->lock, flags); 116 + 117 + return ret; 108 118 } 109 119 110 120 static void clk_gate2_disable_unused(struct clk_hw *hw) 111 121 { 112 122 struct clk_gate2 *gate = to_clk_gate2(hw); 113 123 unsigned long flags; 114 - u32 reg; 115 - 116 - if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) 117 - return; 118 124 119 125 spin_lock_irqsave(gate->lock, flags); 120 126 121 - if (!gate->share_count || *gate->share_count == 0) { 122 - reg = readl(gate->reg); 123 - reg &= ~(3 << gate->bit_idx); 124 - writel(reg, gate->reg); 125 - } 127 + if (!gate->share_count || *gate->share_count == 0) 128 + clk_gate2_do_shared_clks(hw, false); 126 129 127 130 spin_unlock_irqrestore(gate->lock, flags); 128 131 } ··· 135 140 136 141 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, 137 142 const char *parent_name, unsigned long flags, 138 - void __iomem *reg, u8 bit_idx, u8 cgr_val, 143 + void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask, 139 144 u8 clk_gate2_flags, spinlock_t *lock, 140 145 unsigned int *share_count) 141 146 { ··· 152 157 gate->reg = reg; 153 158 gate->bit_idx = bit_idx; 154 159 gate->cgr_val = cgr_val; 160 + gate->cgr_mask = cgr_mask; 155 161 gate->flags = clk_gate2_flags; 156 162 gate->lock = lock; 157 163 gate->share_count = share_count;
+1 -1
drivers/clk/imx/clk-imx8mm.c
··· 653 653 * reloading the driver will crash or break devices. 654 654 */ 655 655 .suppress_bind_attrs = true, 656 - .of_match_table = of_match_ptr(imx8mm_clk_of_match), 656 + .of_match_table = imx8mm_clk_of_match, 657 657 }, 658 658 }; 659 659 module_platform_driver(imx8mm_clk_driver);
+1 -1
drivers/clk/imx/clk-imx8mn.c
··· 604 604 * reloading the driver will crash or break devices. 605 605 */ 606 606 .suppress_bind_attrs = true, 607 - .of_match_table = of_match_ptr(imx8mn_clk_of_match), 607 + .of_match_table = imx8mn_clk_of_match, 608 608 }, 609 609 }; 610 610 module_platform_driver(imx8mn_clk_driver);
+2 -2
drivers/clk/imx/clk-imx8mp.c
··· 425 425 static int imx8mp_clocks_probe(struct platform_device *pdev) 426 426 { 427 427 struct device *dev = &pdev->dev; 428 - struct device_node *np = dev->of_node; 428 + struct device_node *np; 429 429 void __iomem *anatop_base, *ccm_base; 430 430 int i; 431 431 ··· 763 763 * reloading the driver will crash or break devices. 764 764 */ 765 765 .suppress_bind_attrs = true, 766 - .of_match_table = of_match_ptr(imx8mp_clk_of_match), 766 + .of_match_table = imx8mp_clk_of_match, 767 767 }, 768 768 }; 769 769 module_platform_driver(imx8mp_clk_driver);
+1 -1
drivers/clk/imx/clk-imx8mq.c
··· 639 639 * reloading the driver will crash or break devices. 640 640 */ 641 641 .suppress_bind_attrs = true, 642 - .of_match_table = of_match_ptr(imx8mq_clk_of_match), 642 + .of_match_table = imx8mq_clk_of_match, 643 643 }, 644 644 }; 645 645 module_platform_driver(imx8mq_clk_driver);
+139
drivers/clk/imx/clk-imx8qxp-lpcg.c
··· 9 9 #include <linux/io.h> 10 10 #include <linux/module.h> 11 11 #include <linux/of.h> 12 + #include <linux/of_address.h> 12 13 #include <linux/of_device.h> 13 14 #include <linux/platform_device.h> 15 + #include <linux/pm_runtime.h> 14 16 #include <linux/slab.h> 15 17 16 18 #include "clk-scu.h" ··· 159 157 .num_max = IMX_LSIO_LPCG_CLK_END, 160 158 }; 161 159 160 + #define IMX_LPCG_MAX_CLKS 8 161 + 162 + static struct clk_hw *imx_lpcg_of_clk_src_get(struct of_phandle_args *clkspec, 163 + void *data) 164 + { 165 + struct clk_hw_onecell_data *hw_data = data; 166 + unsigned int idx = clkspec->args[0] / 4; 167 + 168 + if (idx >= hw_data->num) { 169 + pr_err("%s: invalid index %u\n", __func__, idx); 170 + return ERR_PTR(-EINVAL); 171 + } 172 + 173 + return hw_data->hws[idx]; 174 + } 175 + 176 + static int imx_lpcg_parse_clks_from_dt(struct platform_device *pdev, 177 + struct device_node *np) 178 + { 179 + const char *output_names[IMX_LPCG_MAX_CLKS]; 180 + const char *parent_names[IMX_LPCG_MAX_CLKS]; 181 + unsigned int bit_offset[IMX_LPCG_MAX_CLKS]; 182 + struct clk_hw_onecell_data *clk_data; 183 + struct clk_hw **clk_hws; 184 + struct resource *res; 185 + void __iomem *base; 186 + int count; 187 + int idx; 188 + int ret; 189 + int i; 190 + 191 + if (!of_device_is_compatible(np, "fsl,imx8qxp-lpcg")) 192 + return -EINVAL; 193 + 194 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 195 + base = devm_ioremap_resource(&pdev->dev, res); 196 + if (IS_ERR(base)) 197 + return PTR_ERR(base); 198 + 199 + count = of_property_count_u32_elems(np, "clock-indices"); 200 + if (count < 0) { 201 + dev_err(&pdev->dev, "failed to count clocks\n"); 202 + return -EINVAL; 203 + } 204 + 205 + /* 206 + * A trick here is that we set the num of clks to the MAX instead 207 + * of the count from clock-indices because one LPCG supports up to 208 + * 8 clock outputs which each of them is fixed to 4 bits. Then we can 209 + * easily get the clock by clk-indices (bit-offset) / 4. 210 + * And the cost is very limited few pointers. 211 + */ 212 + 213 + clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, 214 + IMX_LPCG_MAX_CLKS), GFP_KERNEL); 215 + if (!clk_data) 216 + return -ENOMEM; 217 + 218 + clk_data->num = IMX_LPCG_MAX_CLKS; 219 + clk_hws = clk_data->hws; 220 + 221 + ret = of_property_read_u32_array(np, "clock-indices", bit_offset, 222 + count); 223 + if (ret < 0) { 224 + dev_err(&pdev->dev, "failed to read clock-indices\n"); 225 + return -EINVAL; 226 + } 227 + 228 + ret = of_clk_parent_fill(np, parent_names, count); 229 + if (ret != count) { 230 + dev_err(&pdev->dev, "failed to get clock parent names\n"); 231 + return count; 232 + } 233 + 234 + ret = of_property_read_string_array(np, "clock-output-names", 235 + output_names, count); 236 + if (ret != count) { 237 + dev_err(&pdev->dev, "failed to read clock-output-names\n"); 238 + return -EINVAL; 239 + } 240 + 241 + pm_runtime_get_noresume(&pdev->dev); 242 + pm_runtime_set_active(&pdev->dev); 243 + pm_runtime_set_autosuspend_delay(&pdev->dev, 500); 244 + pm_runtime_use_autosuspend(&pdev->dev); 245 + pm_runtime_enable(&pdev->dev); 246 + 247 + for (i = 0; i < count; i++) { 248 + idx = bit_offset[i] / 4; 249 + if (idx > IMX_LPCG_MAX_CLKS) { 250 + dev_warn(&pdev->dev, "invalid bit offset of clock %d\n", 251 + i); 252 + ret = -EINVAL; 253 + goto unreg; 254 + } 255 + 256 + clk_hws[idx] = imx_clk_lpcg_scu_dev(&pdev->dev, output_names[i], 257 + parent_names[i], 0, base, 258 + bit_offset[i], false); 259 + if (IS_ERR(clk_hws[idx])) { 260 + dev_warn(&pdev->dev, "failed to register clock %d\n", 261 + idx); 262 + ret = PTR_ERR(clk_hws[idx]); 263 + goto unreg; 264 + } 265 + } 266 + 267 + ret = devm_of_clk_add_hw_provider(&pdev->dev, imx_lpcg_of_clk_src_get, 268 + clk_data); 269 + if (ret) 270 + goto unreg; 271 + 272 + pm_runtime_mark_last_busy(&pdev->dev); 273 + pm_runtime_put_autosuspend(&pdev->dev); 274 + 275 + return 0; 276 + 277 + unreg: 278 + while (--i >= 0) { 279 + idx = bit_offset[i] / 4; 280 + if (clk_hws[idx]) 281 + imx_clk_lpcg_scu_unregister(clk_hws[idx]); 282 + } 283 + 284 + pm_runtime_disable(&pdev->dev); 285 + 286 + return ret; 287 + } 288 + 162 289 static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev) 163 290 { 164 291 struct device *dev = &pdev->dev; ··· 298 167 struct resource *res; 299 168 struct clk_hw **clks; 300 169 void __iomem *base; 170 + int ret; 301 171 int i; 172 + 173 + /* try new binding to parse clocks from device tree first */ 174 + ret = imx_lpcg_parse_clks_from_dt(pdev, np); 175 + if (!ret) 176 + return 0; 302 177 303 178 ss_lpcg = of_device_get_match_data(dev); 304 179 if (!ss_lpcg) ··· 356 219 { .compatible = "fsl,imx8qxp-lpcg-adma", &imx8qxp_ss_adma, }, 357 220 { .compatible = "fsl,imx8qxp-lpcg-conn", &imx8qxp_ss_conn, }, 358 221 { .compatible = "fsl,imx8qxp-lpcg-lsio", &imx8qxp_ss_lsio, }, 222 + { .compatible = "fsl,imx8qxp-lpcg", NULL }, 359 223 { /* sentinel */ } 360 224 }; 361 225 ··· 364 226 .driver = { 365 227 .name = "imx8qxp-lpcg-clk", 366 228 .of_match_table = imx8qxp_lpcg_match, 229 + .pm = &imx_clk_lpcg_scu_pm_ops, 367 230 .suppress_bind_attrs = true, 368 231 }, 369 232 .probe = imx8qxp_lpcg_clk_probe,
+76 -60
drivers/clk/imx/clk-imx8qxp.c
··· 22 22 struct device_node *ccm_node = pdev->dev.of_node; 23 23 struct clk_hw_onecell_data *clk_data; 24 24 struct clk_hw **clks; 25 + u32 clk_cells; 25 26 int ret, i; 26 27 27 - ret = imx_clk_scu_init(); 28 + ret = imx_clk_scu_init(ccm_node); 28 29 if (ret) 29 30 return ret; 30 31 ··· 33 32 IMX_SCU_CLK_END), GFP_KERNEL); 34 33 if (!clk_data) 35 34 return -ENOMEM; 35 + 36 + if (of_property_read_u32(ccm_node, "#clock-cells", &clk_cells)) 37 + return -EINVAL; 36 38 37 39 clk_data->num = IMX_SCU_CLK_END; 38 40 clks = clk_data->hws; ··· 59 55 clks[IMX_LSIO_BUS_CLK] = clk_hw_register_fixed_rate(NULL, "lsio_bus_clk_root", NULL, 0, 100000000); 60 56 61 57 /* ARM core */ 62 - clks[IMX_A35_CLK] = imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU); 58 + clks[IMX_A35_CLK] = imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU, clk_cells); 63 59 64 60 /* LSIO SS */ 65 - clks[IMX_LSIO_PWM0_CLK] = imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER); 66 - clks[IMX_LSIO_PWM1_CLK] = imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER); 67 - clks[IMX_LSIO_PWM2_CLK] = imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER); 68 - clks[IMX_LSIO_PWM3_CLK] = imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER); 69 - clks[IMX_LSIO_PWM4_CLK] = imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER); 70 - clks[IMX_LSIO_PWM5_CLK] = imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER); 71 - clks[IMX_LSIO_PWM6_CLK] = imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER); 72 - clks[IMX_LSIO_PWM7_CLK] = imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER); 73 - clks[IMX_LSIO_GPT0_CLK] = imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER); 74 - clks[IMX_LSIO_GPT1_CLK] = imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER); 75 - clks[IMX_LSIO_GPT2_CLK] = imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER); 76 - clks[IMX_LSIO_GPT3_CLK] = imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER); 77 - clks[IMX_LSIO_GPT4_CLK] = imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER); 78 - clks[IMX_LSIO_FSPI0_CLK] = imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER); 79 - clks[IMX_LSIO_FSPI1_CLK] = imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER); 61 + clks[IMX_LSIO_PWM0_CLK] = imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); 62 + clks[IMX_LSIO_PWM1_CLK] = imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER, clk_cells); 63 + clks[IMX_LSIO_PWM2_CLK] = imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER, clk_cells); 64 + clks[IMX_LSIO_PWM3_CLK] = imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER, clk_cells); 65 + clks[IMX_LSIO_PWM4_CLK] = imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER, clk_cells); 66 + clks[IMX_LSIO_PWM5_CLK] = imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER, clk_cells); 67 + clks[IMX_LSIO_PWM6_CLK] = imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER, clk_cells); 68 + clks[IMX_LSIO_PWM7_CLK] = imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER, clk_cells); 69 + clks[IMX_LSIO_GPT0_CLK] = imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER, clk_cells); 70 + clks[IMX_LSIO_GPT1_CLK] = imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER, clk_cells); 71 + clks[IMX_LSIO_GPT2_CLK] = imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER, clk_cells); 72 + clks[IMX_LSIO_GPT3_CLK] = imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER, clk_cells); 73 + clks[IMX_LSIO_GPT4_CLK] = imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER, clk_cells); 74 + clks[IMX_LSIO_FSPI0_CLK] = imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER, clk_cells); 75 + clks[IMX_LSIO_FSPI1_CLK] = imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER, clk_cells); 80 76 81 77 /* ADMA SS */ 82 - clks[IMX_ADMA_UART0_CLK] = imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER); 83 - clks[IMX_ADMA_UART1_CLK] = imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER); 84 - clks[IMX_ADMA_UART2_CLK] = imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER); 85 - clks[IMX_ADMA_UART3_CLK] = imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER); 86 - clks[IMX_ADMA_SPI0_CLK] = imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER); 87 - clks[IMX_ADMA_SPI1_CLK] = imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER); 88 - clks[IMX_ADMA_SPI2_CLK] = imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER); 89 - clks[IMX_ADMA_SPI3_CLK] = imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER); 90 - clks[IMX_ADMA_CAN0_CLK] = imx_clk_scu("can0_clk", IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER); 91 - clks[IMX_ADMA_I2C0_CLK] = imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER); 92 - clks[IMX_ADMA_I2C1_CLK] = imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER); 93 - clks[IMX_ADMA_I2C2_CLK] = imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER); 94 - clks[IMX_ADMA_I2C3_CLK] = imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER); 95 - clks[IMX_ADMA_FTM0_CLK] = imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER); 96 - clks[IMX_ADMA_FTM1_CLK] = imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER); 97 - clks[IMX_ADMA_ADC0_CLK] = imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER); 98 - clks[IMX_ADMA_PWM_CLK] = imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER); 99 - clks[IMX_ADMA_LCD_CLK] = imx_clk_scu("lcd_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER); 78 + clks[IMX_ADMA_UART0_CLK] = imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER, clk_cells); 79 + clks[IMX_ADMA_UART1_CLK] = imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER, clk_cells); 80 + clks[IMX_ADMA_UART2_CLK] = imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER, clk_cells); 81 + clks[IMX_ADMA_UART3_CLK] = imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER, clk_cells); 82 + clks[IMX_ADMA_SPI0_CLK] = imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER, clk_cells); 83 + clks[IMX_ADMA_SPI1_CLK] = imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER, clk_cells); 84 + clks[IMX_ADMA_SPI2_CLK] = imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER, clk_cells); 85 + clks[IMX_ADMA_SPI3_CLK] = imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER, clk_cells); 86 + clks[IMX_ADMA_CAN0_CLK] = imx_clk_scu("can0_clk", IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER, clk_cells); 87 + clks[IMX_ADMA_I2C0_CLK] = imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER, clk_cells); 88 + clks[IMX_ADMA_I2C1_CLK] = imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER, clk_cells); 89 + clks[IMX_ADMA_I2C2_CLK] = imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER, clk_cells); 90 + clks[IMX_ADMA_I2C3_CLK] = imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER, clk_cells); 91 + clks[IMX_ADMA_FTM0_CLK] = imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER, clk_cells); 92 + clks[IMX_ADMA_FTM1_CLK] = imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER, clk_cells); 93 + clks[IMX_ADMA_ADC0_CLK] = imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER, clk_cells); 94 + clks[IMX_ADMA_PWM_CLK] = imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); 95 + clks[IMX_ADMA_LCD_CLK] = imx_clk_scu("lcd_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER, clk_cells); 100 96 101 97 /* Connectivity */ 102 - clks[IMX_CONN_SDHC0_CLK] = imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER); 103 - clks[IMX_CONN_SDHC1_CLK] = imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER); 104 - clks[IMX_CONN_SDHC2_CLK] = imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER); 105 - clks[IMX_CONN_ENET0_ROOT_CLK] = imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER); 106 - clks[IMX_CONN_ENET0_BYPASS_CLK] = imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS); 107 - clks[IMX_CONN_ENET0_RGMII_CLK] = imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0); 108 - clks[IMX_CONN_ENET1_ROOT_CLK] = imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER); 109 - clks[IMX_CONN_ENET1_BYPASS_CLK] = imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS); 110 - clks[IMX_CONN_ENET1_RGMII_CLK] = imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0); 111 - clks[IMX_CONN_GPMI_BCH_IO_CLK] = imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS); 112 - clks[IMX_CONN_GPMI_BCH_CLK] = imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER); 113 - clks[IMX_CONN_USB2_ACLK] = imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER); 114 - clks[IMX_CONN_USB2_BUS_CLK] = imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS); 115 - clks[IMX_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC); 98 + clks[IMX_CONN_SDHC0_CLK] = imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER, clk_cells); 99 + clks[IMX_CONN_SDHC1_CLK] = imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER, clk_cells); 100 + clks[IMX_CONN_SDHC2_CLK] = imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER, clk_cells); 101 + clks[IMX_CONN_ENET0_ROOT_CLK] = imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER, clk_cells); 102 + clks[IMX_CONN_ENET0_BYPASS_CLK] = imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS, clk_cells); 103 + clks[IMX_CONN_ENET0_RGMII_CLK] = imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0, clk_cells); 104 + clks[IMX_CONN_ENET1_ROOT_CLK] = imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER, clk_cells); 105 + clks[IMX_CONN_ENET1_BYPASS_CLK] = imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS, clk_cells); 106 + clks[IMX_CONN_ENET1_RGMII_CLK] = imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0, clk_cells); 107 + clks[IMX_CONN_GPMI_BCH_IO_CLK] = imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS, clk_cells); 108 + clks[IMX_CONN_GPMI_BCH_CLK] = imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER, clk_cells); 109 + clks[IMX_CONN_USB2_ACLK] = imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER, clk_cells); 110 + clks[IMX_CONN_USB2_BUS_CLK] = imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS, clk_cells); 111 + clks[IMX_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC, clk_cells); 116 112 117 113 /* Display controller SS */ 118 - clks[IMX_DC0_DISP0_CLK] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0); 119 - clks[IMX_DC0_DISP1_CLK] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1); 114 + clks[IMX_DC0_DISP0_CLK] = imx_clk_scu("dc0_disp0_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells); 115 + clks[IMX_DC0_DISP1_CLK] = imx_clk_scu("dc0_disp1_clk", IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells); 120 116 121 117 /* MIPI-LVDS SS */ 122 - clks[IMX_MIPI0_I2C0_CLK] = imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2); 123 - clks[IMX_MIPI0_I2C1_CLK] = imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2); 118 + 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); 119 + 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); 124 120 125 121 /* MIPI CSI SS */ 126 - clks[IMX_CSI0_CORE_CLK] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER); 127 - clks[IMX_CSI0_ESC_CLK] = imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC); 128 - clks[IMX_CSI0_I2C0_CLK] = imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER); 129 - clks[IMX_CSI0_PWM0_CLK] = imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER); 122 + clks[IMX_CSI0_CORE_CLK] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER, clk_cells); 123 + clks[IMX_CSI0_ESC_CLK] = imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC, clk_cells); 124 + clks[IMX_CSI0_I2C0_CLK] = imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER, clk_cells); 125 + clks[IMX_CSI0_PWM0_CLK] = imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); 130 126 131 127 /* GPU SS */ 132 - clks[IMX_GPU0_CORE_CLK] = imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER); 133 - clks[IMX_GPU0_SHADER_CLK] = imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC); 128 + clks[IMX_GPU0_CORE_CLK] = imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER, clk_cells); 129 + clks[IMX_GPU0_SHADER_CLK] = imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC, clk_cells); 134 130 135 131 for (i = 0; i < clk_data->num; i++) { 136 132 if (IS_ERR(clks[i])) ··· 138 134 i, PTR_ERR(clks[i])); 139 135 } 140 136 141 - return of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data); 137 + if (clk_cells == 2) { 138 + ret = of_clk_add_hw_provider(ccm_node, imx_scu_of_clk_src_get, imx_scu_clks); 139 + if (ret) 140 + imx_clk_scu_unregister(); 141 + } else { 142 + /* 143 + * legacy binding code path doesn't unregister here because 144 + * it will be removed later. 145 + */ 146 + ret = of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data); 147 + } 148 + 149 + return ret; 142 150 } 143 151 144 152 static const struct of_device_id imx8qxp_match[] = {
+49 -4
drivers/clk/imx/clk-lpcg-scu.c
··· 34 34 void __iomem *reg; 35 35 u8 bit_idx; 36 36 bool hw_gate; 37 + 38 + /* for state save&restore */ 39 + u32 state; 37 40 }; 38 41 39 42 #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw) ··· 84 81 .disable = clk_lpcg_scu_disable, 85 82 }; 86 83 87 - struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, 88 - unsigned long flags, void __iomem *reg, 89 - u8 bit_idx, bool hw_gate) 84 + struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name, 85 + const char *parent_name, unsigned long flags, 86 + void __iomem *reg, u8 bit_idx, bool hw_gate) 90 87 { 91 88 struct clk_lpcg_scu *clk; 92 89 struct clk_init_data init; ··· 110 107 clk->hw.init = &init; 111 108 112 109 hw = &clk->hw; 113 - ret = clk_hw_register(NULL, hw); 110 + ret = clk_hw_register(dev, hw); 114 111 if (ret) { 115 112 kfree(clk); 116 113 hw = ERR_PTR(ret); 117 114 } 118 115 116 + if (dev) 117 + dev_set_drvdata(dev, clk); 118 + 119 119 return hw; 120 120 } 121 + 122 + void imx_clk_lpcg_scu_unregister(struct clk_hw *hw) 123 + { 124 + struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw); 125 + 126 + clk_hw_unregister(&clk->hw); 127 + kfree(clk); 128 + } 129 + 130 + static int __maybe_unused imx_clk_lpcg_scu_suspend(struct device *dev) 131 + { 132 + struct clk_lpcg_scu *clk = dev_get_drvdata(dev); 133 + 134 + clk->state = readl_relaxed(clk->reg); 135 + dev_dbg(dev, "save lpcg state 0x%x\n", clk->state); 136 + 137 + return 0; 138 + } 139 + 140 + static int __maybe_unused imx_clk_lpcg_scu_resume(struct device *dev) 141 + { 142 + struct clk_lpcg_scu *clk = dev_get_drvdata(dev); 143 + 144 + /* 145 + * FIXME: Sometimes writes don't work unless the CPU issues 146 + * them twice 147 + */ 148 + 149 + writel(clk->state, clk->reg); 150 + writel(clk->state, clk->reg); 151 + dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state); 152 + 153 + return 0; 154 + } 155 + 156 + const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops = { 157 + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_lpcg_scu_suspend, 158 + imx_clk_lpcg_scu_resume) 159 + };
+1 -1
drivers/clk/imx/clk-pll14xx.c
··· 416 416 __func__, name); 417 417 kfree(pll); 418 418 return ERR_PTR(-EINVAL); 419 - }; 419 + } 420 420 421 421 pll->base = base; 422 422 pll->hw.init = &init;
+222 -5
drivers/clk/imx/clk-scu.c
··· 8 8 #include <linux/arm-smccc.h> 9 9 #include <linux/clk-provider.h> 10 10 #include <linux/err.h> 11 + #include <linux/of_platform.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/pm_domain.h> 14 + #include <linux/pm_runtime.h> 11 15 #include <linux/slab.h> 12 16 13 17 #include "clk-scu.h" ··· 20 16 #define IMX_SIP_SET_CPUFREQ 0x00 21 17 22 18 static struct imx_sc_ipc *ccm_ipc_handle; 19 + static struct device_node *pd_np; 20 + static struct platform_driver imx_clk_scu_driver; 21 + 22 + struct imx_scu_clk_node { 23 + const char *name; 24 + u32 rsrc; 25 + u8 clk_type; 26 + const char * const *parents; 27 + int num_parents; 28 + 29 + struct clk_hw *hw; 30 + struct list_head node; 31 + }; 32 + 33 + struct list_head imx_scu_clks[IMX_SC_R_LAST]; 23 34 24 35 /* 25 36 * struct clk_scu - Description of one SCU clock ··· 46 27 struct clk_hw hw; 47 28 u16 rsrc_id; 48 29 u8 clk_type; 30 + 31 + /* for state save&restore */ 32 + bool is_enabled; 33 + u32 rate; 49 34 }; 50 35 51 36 /* ··· 151 128 return container_of(hw, struct clk_scu, hw); 152 129 } 153 130 154 - int imx_clk_scu_init(void) 131 + int imx_clk_scu_init(struct device_node *np) 155 132 { 156 - return imx_scu_get_handle(&ccm_ipc_handle); 133 + u32 clk_cells; 134 + int ret, i; 135 + 136 + ret = imx_scu_get_handle(&ccm_ipc_handle); 137 + if (ret) 138 + return ret; 139 + 140 + of_property_read_u32(np, "#clock-cells", &clk_cells); 141 + 142 + if (clk_cells == 2) { 143 + for (i = 0; i < IMX_SC_R_LAST; i++) 144 + INIT_LIST_HEAD(&imx_scu_clks[i]); 145 + 146 + /* pd_np will be used to attach power domains later */ 147 + pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd"); 148 + if (!pd_np) 149 + return -EINVAL; 150 + } 151 + 152 + return platform_driver_register(&imx_clk_scu_driver); 157 153 } 158 154 159 155 /* ··· 386 344 .unprepare = clk_scu_unprepare, 387 345 }; 388 346 389 - struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, 390 - int num_parents, u32 rsrc_id, u8 clk_type) 347 + struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, 348 + const char * const *parents, int num_parents, 349 + u32 rsrc_id, u8 clk_type) 391 350 { 392 351 struct clk_init_data init; 393 352 struct clk_scu *clk; ··· 422 379 clk->hw.init = &init; 423 380 424 381 hw = &clk->hw; 425 - ret = clk_hw_register(NULL, hw); 382 + ret = clk_hw_register(dev, hw); 426 383 if (ret) { 427 384 kfree(clk); 428 385 hw = ERR_PTR(ret); 429 386 } 430 387 388 + if (dev) 389 + dev_set_drvdata(dev, clk); 390 + 431 391 return hw; 392 + } 393 + 394 + struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec, 395 + void *data) 396 + { 397 + unsigned int rsrc = clkspec->args[0]; 398 + unsigned int idx = clkspec->args[1]; 399 + struct list_head *scu_clks = data; 400 + struct imx_scu_clk_node *clk; 401 + 402 + list_for_each_entry(clk, &scu_clks[rsrc], node) { 403 + if (clk->clk_type == idx) 404 + return clk->hw; 405 + } 406 + 407 + return ERR_PTR(-ENODEV); 408 + } 409 + 410 + static int imx_clk_scu_probe(struct platform_device *pdev) 411 + { 412 + struct device *dev = &pdev->dev; 413 + struct imx_scu_clk_node *clk = dev_get_platdata(dev); 414 + struct clk_hw *hw; 415 + int ret; 416 + 417 + pm_runtime_set_suspended(dev); 418 + pm_runtime_set_autosuspend_delay(dev, 50); 419 + pm_runtime_use_autosuspend(&pdev->dev); 420 + pm_runtime_enable(dev); 421 + 422 + ret = pm_runtime_get_sync(dev); 423 + if (ret) { 424 + pm_runtime_disable(dev); 425 + return ret; 426 + } 427 + 428 + hw = __imx_clk_scu(dev, clk->name, clk->parents, clk->num_parents, 429 + clk->rsrc, clk->clk_type); 430 + if (IS_ERR(hw)) { 431 + pm_runtime_disable(dev); 432 + return PTR_ERR(hw); 433 + } 434 + 435 + clk->hw = hw; 436 + list_add_tail(&clk->node, &imx_scu_clks[clk->rsrc]); 437 + 438 + pm_runtime_mark_last_busy(&pdev->dev); 439 + pm_runtime_put_autosuspend(&pdev->dev); 440 + 441 + dev_dbg(dev, "register SCU clock rsrc:%d type:%d\n", clk->rsrc, 442 + clk->clk_type); 443 + 444 + return 0; 445 + } 446 + 447 + static int __maybe_unused imx_clk_scu_suspend(struct device *dev) 448 + { 449 + struct clk_scu *clk = dev_get_drvdata(dev); 450 + 451 + clk->rate = clk_hw_get_rate(&clk->hw); 452 + clk->is_enabled = clk_hw_is_enabled(&clk->hw); 453 + 454 + if (clk->rate) 455 + dev_dbg(dev, "save rate %d\n", clk->rate); 456 + 457 + if (clk->is_enabled) 458 + dev_dbg(dev, "save enabled state\n"); 459 + 460 + return 0; 461 + } 462 + 463 + static int __maybe_unused imx_clk_scu_resume(struct device *dev) 464 + { 465 + struct clk_scu *clk = dev_get_drvdata(dev); 466 + int ret = 0; 467 + 468 + if (clk->rate) { 469 + ret = clk_scu_set_rate(&clk->hw, clk->rate, 0); 470 + dev_dbg(dev, "restore rate %d %s\n", clk->rate, 471 + !ret ? "success" : "failed"); 472 + } 473 + 474 + if (clk->is_enabled) { 475 + ret = clk_scu_prepare(&clk->hw); 476 + dev_dbg(dev, "restore enabled state %s\n", 477 + !ret ? "success" : "failed"); 478 + } 479 + 480 + return ret; 481 + } 482 + 483 + static const struct dev_pm_ops imx_clk_scu_pm_ops = { 484 + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(imx_clk_scu_suspend, 485 + imx_clk_scu_resume) 486 + }; 487 + 488 + static struct platform_driver imx_clk_scu_driver = { 489 + .driver = { 490 + .name = "imx-scu-clk", 491 + .suppress_bind_attrs = true, 492 + .pm = &imx_clk_scu_pm_ops, 493 + }, 494 + .probe = imx_clk_scu_probe, 495 + }; 496 + 497 + static int imx_clk_scu_attach_pd(struct device *dev, u32 rsrc_id) 498 + { 499 + struct of_phandle_args genpdspec = { 500 + .np = pd_np, 501 + .args_count = 1, 502 + .args[0] = rsrc_id, 503 + }; 504 + 505 + if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 || 506 + rsrc_id == IMX_SC_R_A72) 507 + return 0; 508 + 509 + return of_genpd_add_device(&genpdspec, dev); 510 + } 511 + 512 + struct clk_hw *imx_clk_scu_alloc_dev(const char *name, 513 + const char * const *parents, 514 + int num_parents, u32 rsrc_id, u8 clk_type) 515 + { 516 + struct imx_scu_clk_node clk = { 517 + .name = name, 518 + .rsrc = rsrc_id, 519 + .clk_type = clk_type, 520 + .parents = parents, 521 + .num_parents = num_parents, 522 + }; 523 + struct platform_device *pdev; 524 + int ret; 525 + 526 + pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); 527 + if (!pdev) { 528 + pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n", 529 + name, rsrc_id, clk_type); 530 + return ERR_PTR(-ENOMEM); 531 + } 532 + 533 + ret = platform_device_add_data(pdev, &clk, sizeof(clk)); 534 + if (ret) { 535 + platform_device_put(pdev); 536 + return ERR_PTR(ret); 537 + } 538 + 539 + pdev->driver_override = "imx-scu-clk"; 540 + 541 + ret = imx_clk_scu_attach_pd(&pdev->dev, rsrc_id); 542 + if (ret) 543 + pr_warn("%s: failed to attached the power domain %d\n", 544 + name, ret); 545 + 546 + platform_device_add(pdev); 547 + 548 + /* For API backwards compatiblilty, simply return NULL for success */ 549 + return NULL; 550 + } 551 + 552 + void imx_clk_scu_unregister(void) 553 + { 554 + struct imx_scu_clk_node *clk; 555 + int i; 556 + 557 + for (i = 0; i < IMX_SC_R_LAST; i++) { 558 + list_for_each_entry(clk, &imx_scu_clks[i], node) { 559 + clk_hw_unregister(clk->hw); 560 + kfree(clk); 561 + } 562 + } 432 563 }
+46 -10
drivers/clk/imx/clk-scu.h
··· 8 8 #define __IMX_CLK_SCU_H 9 9 10 10 #include <linux/firmware/imx/sci.h> 11 + #include <linux/of.h> 11 12 12 - int imx_clk_scu_init(void); 13 + extern struct list_head imx_scu_clks[]; 14 + extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops; 13 15 14 - struct clk_hw *__imx_clk_scu(const char *name, const char * const *parents, 15 - int num_parents, u32 rsrc_id, u8 clk_type); 16 + int imx_clk_scu_init(struct device_node *np); 17 + struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec, 18 + void *data); 19 + struct clk_hw *imx_clk_scu_alloc_dev(const char *name, 20 + const char * const *parents, 21 + int num_parents, u32 rsrc_id, u8 clk_type); 22 + 23 + struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, 24 + const char * const *parents, int num_parents, 25 + u32 rsrc_id, u8 clk_type); 26 + 27 + void imx_clk_scu_unregister(void); 28 + 29 + struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name, 30 + const char *parent_name, unsigned long flags, 31 + void __iomem *reg, u8 bit_idx, bool hw_gate); 32 + void imx_clk_lpcg_scu_unregister(struct clk_hw *hw); 16 33 17 34 static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, 18 - u8 clk_type) 35 + u8 clk_type, u8 clk_cells) 19 36 { 20 - return __imx_clk_scu(name, NULL, 0, rsrc_id, clk_type); 37 + if (clk_cells == 2) 38 + return imx_clk_scu_alloc_dev(name, NULL, 0, rsrc_id, clk_type); 39 + else 40 + return __imx_clk_scu(NULL, name, NULL, 0, rsrc_id, clk_type); 21 41 } 22 42 23 43 static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents, 24 - int num_parents, u32 rsrc_id, u8 clk_type) 44 + int num_parents, u32 rsrc_id, u8 clk_type, 45 + u8 clk_cells) 25 46 { 26 - return __imx_clk_scu(name, parents, num_parents, rsrc_id, clk_type); 47 + if (clk_cells == 2) 48 + return imx_clk_scu_alloc_dev(name, parents, num_parents, rsrc_id, clk_type); 49 + else 50 + return __imx_clk_scu(NULL, name, parents, num_parents, rsrc_id, clk_type); 27 51 } 28 52 29 - struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, 30 - unsigned long flags, void __iomem *reg, 31 - u8 bit_idx, bool hw_gate); 53 + static inline struct clk_hw *imx_clk_lpcg_scu_dev(struct device *dev, const char *name, 54 + const char *parent_name, unsigned long flags, 55 + void __iomem *reg, u8 bit_idx, bool hw_gate) 56 + { 57 + return __imx_clk_lpcg_scu(dev, name, parent_name, flags, reg, 58 + bit_idx, hw_gate); 59 + } 60 + 61 + static inline struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *parent_name, 62 + unsigned long flags, void __iomem *reg, 63 + u8 bit_idx, bool hw_gate) 64 + { 65 + return __imx_clk_lpcg_scu(NULL, name, parent_name, flags, reg, 66 + bit_idx, hw_gate); 67 + } 32 68 #endif
+12 -15
drivers/clk/imx/clk.h
··· 6 6 #include <linux/spinlock.h> 7 7 #include <linux/clk-provider.h> 8 8 9 - #define IMX_CLK_GATE2_SINGLE_BIT 1 10 - 11 9 extern spinlock_t imx_ccm_lock; 12 10 13 11 void imx_check_clocks(struct clk *clks[], unsigned int count); ··· 66 68 to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)) 67 69 68 70 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 69 - cgr_val, clk_gate_flags, lock, share_count) \ 71 + cgr_val, cgr_mask, clk_gate_flags, lock, share_count) \ 70 72 to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \ 71 - cgr_val, clk_gate_flags, lock, share_count)) 73 + cgr_val, cgr_mask, clk_gate_flags, lock, share_count)) 72 74 73 75 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \ 74 76 to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)) ··· 196 198 197 199 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, 198 200 const char *parent_name, unsigned long flags, 199 - void __iomem *reg, u8 bit_idx, u8 cgr_val, 201 + void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask, 200 202 u8 clk_gate_flags, spinlock_t *lock, 201 203 unsigned int *share_count); 202 204 ··· 349 351 void __iomem *reg, u8 shift) 350 352 { 351 353 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 352 - shift, 0x3, 0, &imx_ccm_lock, NULL); 354 + shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 353 355 } 354 356 355 357 static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const char *parent, 356 358 void __iomem *reg, u8 shift, unsigned long flags) 357 359 { 358 360 return clk_hw_register_gate2(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg, 359 - shift, 0x3, 0, &imx_ccm_lock, NULL); 361 + shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 360 362 } 361 363 362 364 static inline struct clk_hw *imx_clk_hw_gate2_shared(const char *name, ··· 364 366 unsigned int *share_count) 365 367 { 366 368 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 367 - shift, 0x3, 0, &imx_ccm_lock, share_count); 369 + shift, 0x3, 0x3, 0, &imx_ccm_lock, share_count); 368 370 } 369 371 370 372 static inline struct clk_hw *imx_clk_hw_gate2_shared2(const char *name, ··· 372 374 unsigned int *share_count) 373 375 { 374 376 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 375 - CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0, 377 + CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 0x3, 0, 376 378 &imx_ccm_lock, share_count); 377 379 } 378 380 ··· 382 384 unsigned int *share_count) 383 385 { 384 386 return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT | 385 - CLK_OPS_PARENT_ENABLE, reg, shift, 0x3, 386 - IMX_CLK_GATE2_SINGLE_BIT, 387 - &imx_ccm_lock, share_count); 387 + CLK_OPS_PARENT_ENABLE, reg, shift, 0x1, 388 + 0x1, 0, &imx_ccm_lock, share_count); 388 389 } 389 390 390 391 static inline struct clk *imx_clk_gate2_cgr(const char *name, 391 392 const char *parent, void __iomem *reg, u8 shift, u8 cgr_val) 392 393 { 393 394 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 394 - shift, cgr_val, 0, &imx_ccm_lock, NULL); 395 + shift, cgr_val, 0x3, 0, &imx_ccm_lock, NULL); 395 396 } 396 397 397 398 static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *parent, ··· 418 421 { 419 422 return clk_hw_register_gate2(NULL, name, parent, 420 423 CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 421 - reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 424 + reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 422 425 } 423 426 424 427 static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name, ··· 427 430 { 428 431 return clk_hw_register_gate2(NULL, name, parent, 429 432 flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 430 - reg, shift, 0x3, 0, &imx_ccm_lock, NULL); 433 + reg, shift, 0x3, 0x3, 0, &imx_ccm_lock, NULL); 431 434 } 432 435 433 436 #define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
+10 -4
drivers/clk/ingenic/cgu.c
··· 392 392 ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info, 393 393 unsigned int div) 394 394 { 395 - unsigned int i; 395 + unsigned int i, best_i = 0, best = (unsigned int)-1; 396 396 397 397 for (i = 0; i < (1 << clk_info->div.bits) 398 398 && clk_info->div.div_table[i]; i++) { 399 - if (clk_info->div.div_table[i] >= div) 400 - return i; 399 + if (clk_info->div.div_table[i] >= div && 400 + clk_info->div.div_table[i] < best) { 401 + best = clk_info->div.div_table[i]; 402 + best_i = i; 403 + 404 + if (div == best) 405 + break; 406 + } 401 407 } 402 408 403 - return i - 1; 409 + return best_i; 404 410 } 405 411 406 412 static unsigned
+1 -1
drivers/clk/mediatek/clk-mux.c
··· 155 155 .set_parent = mtk_clk_mux_set_parent_setclr_lock, 156 156 }; 157 157 158 - struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, 158 + static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, 159 159 struct regmap *regmap, 160 160 spinlock_t *lock) 161 161 {
-4
drivers/clk/mediatek/clk-mux.h
··· 77 77 _width, _gate, _upd_ofs, _upd, \ 78 78 CLK_SET_RATE_PARENT) 79 79 80 - struct clk *mtk_clk_register_mux(const struct mtk_mux *mux, 81 - struct regmap *regmap, 82 - spinlock_t *lock); 83 - 84 80 int mtk_clk_register_muxes(const struct mtk_mux *muxes, 85 81 int num, struct device_node *node, 86 82 spinlock_t *lock,
+4 -3
drivers/clk/meson/Kconfig
··· 58 58 want peripherals and CPU frequency scaling to work. 59 59 60 60 config COMMON_CLK_GXBB 61 - bool "GXBB and GXL SoC clock controllers support" 61 + tristate "GXBB and GXL SoC clock controllers support" 62 62 depends on ARM64 63 63 default y 64 64 select COMMON_CLK_MESON_REGMAP ··· 74 74 Say Y if you want peripherals and CPU frequency scaling to work. 75 75 76 76 config COMMON_CLK_AXG 77 - bool "AXG SoC clock controllers support" 77 + tristate "AXG SoC clock controllers support" 78 78 depends on ARM64 79 79 default y 80 80 select COMMON_CLK_MESON_REGMAP ··· 100 100 aka axg, Say Y if you want audio subsystem to work. 101 101 102 102 config COMMON_CLK_G12A 103 - bool "G12 and SM1 SoC clock controllers support" 103 + tristate "G12 and SM1 SoC clock controllers support" 104 104 depends on ARM64 105 105 default y 106 106 select COMMON_CLK_MESON_REGMAP ··· 110 110 select COMMON_CLK_MESON_AO_CLKC 111 111 select COMMON_CLK_MESON_EE_CLKC 112 112 select COMMON_CLK_MESON_CPU_DYNDIV 113 + select COMMON_CLK_MESON_VID_PLL_DIV 113 114 select MFD_SYSCON 114 115 help 115 116 Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
+4 -1
drivers/clk/meson/axg-aoclk.c
··· 12 12 #include <linux/platform_device.h> 13 13 #include <linux/reset-controller.h> 14 14 #include <linux/mfd/syscon.h> 15 + #include <linux/module.h> 15 16 #include "meson-aoclk.h" 16 17 #include "axg-aoclk.h" 17 18 ··· 327 326 }, 328 327 { } 329 328 }; 329 + MODULE_DEVICE_TABLE(of, axg_aoclkc_match_table); 330 330 331 331 static struct platform_driver axg_aoclkc_driver = { 332 332 .probe = meson_aoclkc_probe, ··· 337 335 }, 338 336 }; 339 337 340 - builtin_platform_driver(axg_aoclkc_driver); 338 + module_platform_driver(axg_aoclkc_driver); 339 + MODULE_LICENSE("GPL v2");
+823 -1
drivers/clk/meson/axg.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/of_device.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/module.h> 16 17 17 18 #include "clk-regmap.h" 18 19 #include "clk-pll.h" ··· 1027 1026 }, 1028 1027 }; 1029 1028 1029 + /* VPU Clock */ 1030 + 1031 + static const struct clk_hw *axg_vpu_parent_hws[] = { 1032 + &axg_fclk_div4.hw, 1033 + &axg_fclk_div3.hw, 1034 + &axg_fclk_div5.hw, 1035 + &axg_fclk_div7.hw, 1036 + }; 1037 + 1038 + static struct clk_regmap axg_vpu_0_sel = { 1039 + .data = &(struct clk_regmap_mux_data){ 1040 + .offset = HHI_VPU_CLK_CNTL, 1041 + .mask = 0x3, 1042 + .shift = 9, 1043 + }, 1044 + .hw.init = &(struct clk_init_data){ 1045 + .name = "vpu_0_sel", 1046 + .ops = &clk_regmap_mux_ops, 1047 + .parent_hws = axg_vpu_parent_hws, 1048 + .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), 1049 + /* We need a specific parent for VPU clock source, let it be set in DT */ 1050 + .flags = CLK_SET_RATE_NO_REPARENT, 1051 + }, 1052 + }; 1053 + 1054 + static struct clk_regmap axg_vpu_0_div = { 1055 + .data = &(struct clk_regmap_div_data){ 1056 + .offset = HHI_VPU_CLK_CNTL, 1057 + .shift = 0, 1058 + .width = 7, 1059 + }, 1060 + .hw.init = &(struct clk_init_data){ 1061 + .name = "vpu_0_div", 1062 + .ops = &clk_regmap_divider_ops, 1063 + .parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_sel.hw }, 1064 + .num_parents = 1, 1065 + .flags = CLK_SET_RATE_PARENT, 1066 + }, 1067 + }; 1068 + 1069 + static struct clk_regmap axg_vpu_0 = { 1070 + .data = &(struct clk_regmap_gate_data){ 1071 + .offset = HHI_VPU_CLK_CNTL, 1072 + .bit_idx = 8, 1073 + }, 1074 + .hw.init = &(struct clk_init_data) { 1075 + .name = "vpu_0", 1076 + .ops = &clk_regmap_gate_ops, 1077 + .parent_hws = (const struct clk_hw *[]) { &axg_vpu_0_div.hw }, 1078 + .num_parents = 1, 1079 + /* 1080 + * We want to avoid CCF to disable the VPU clock if 1081 + * display has been set by Bootloader 1082 + */ 1083 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1084 + }, 1085 + }; 1086 + 1087 + static struct clk_regmap axg_vpu_1_sel = { 1088 + .data = &(struct clk_regmap_mux_data){ 1089 + .offset = HHI_VPU_CLK_CNTL, 1090 + .mask = 0x3, 1091 + .shift = 25, 1092 + }, 1093 + .hw.init = &(struct clk_init_data){ 1094 + .name = "vpu_1_sel", 1095 + .ops = &clk_regmap_mux_ops, 1096 + .parent_hws = axg_vpu_parent_hws, 1097 + .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), 1098 + /* We need a specific parent for VPU clock source, let it be set in DT */ 1099 + .flags = CLK_SET_RATE_NO_REPARENT, 1100 + }, 1101 + }; 1102 + 1103 + static struct clk_regmap axg_vpu_1_div = { 1104 + .data = &(struct clk_regmap_div_data){ 1105 + .offset = HHI_VPU_CLK_CNTL, 1106 + .shift = 16, 1107 + .width = 7, 1108 + }, 1109 + .hw.init = &(struct clk_init_data){ 1110 + .name = "vpu_1_div", 1111 + .ops = &clk_regmap_divider_ops, 1112 + .parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_sel.hw }, 1113 + .num_parents = 1, 1114 + .flags = CLK_SET_RATE_PARENT, 1115 + }, 1116 + }; 1117 + 1118 + static struct clk_regmap axg_vpu_1 = { 1119 + .data = &(struct clk_regmap_gate_data){ 1120 + .offset = HHI_VPU_CLK_CNTL, 1121 + .bit_idx = 24, 1122 + }, 1123 + .hw.init = &(struct clk_init_data) { 1124 + .name = "vpu_1", 1125 + .ops = &clk_regmap_gate_ops, 1126 + .parent_hws = (const struct clk_hw *[]) { &axg_vpu_1_div.hw }, 1127 + .num_parents = 1, 1128 + /* 1129 + * We want to avoid CCF to disable the VPU clock if 1130 + * display has been set by Bootloader 1131 + */ 1132 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1133 + }, 1134 + }; 1135 + 1136 + static struct clk_regmap axg_vpu = { 1137 + .data = &(struct clk_regmap_mux_data){ 1138 + .offset = HHI_VPU_CLK_CNTL, 1139 + .mask = 1, 1140 + .shift = 31, 1141 + }, 1142 + .hw.init = &(struct clk_init_data){ 1143 + .name = "vpu", 1144 + .ops = &clk_regmap_mux_ops, 1145 + .parent_hws = (const struct clk_hw *[]) { 1146 + &axg_vpu_0.hw, 1147 + &axg_vpu_1.hw 1148 + }, 1149 + .num_parents = 2, 1150 + .flags = CLK_SET_RATE_NO_REPARENT, 1151 + }, 1152 + }; 1153 + 1154 + /* VAPB Clock */ 1155 + 1156 + static struct clk_regmap axg_vapb_0_sel = { 1157 + .data = &(struct clk_regmap_mux_data){ 1158 + .offset = HHI_VAPBCLK_CNTL, 1159 + .mask = 0x3, 1160 + .shift = 9, 1161 + }, 1162 + .hw.init = &(struct clk_init_data){ 1163 + .name = "vapb_0_sel", 1164 + .ops = &clk_regmap_mux_ops, 1165 + .parent_hws = axg_vpu_parent_hws, 1166 + .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), 1167 + .flags = CLK_SET_RATE_NO_REPARENT, 1168 + }, 1169 + }; 1170 + 1171 + static struct clk_regmap axg_vapb_0_div = { 1172 + .data = &(struct clk_regmap_div_data){ 1173 + .offset = HHI_VAPBCLK_CNTL, 1174 + .shift = 0, 1175 + .width = 7, 1176 + }, 1177 + .hw.init = &(struct clk_init_data){ 1178 + .name = "vapb_0_div", 1179 + .ops = &clk_regmap_divider_ops, 1180 + .parent_hws = (const struct clk_hw *[]) { 1181 + &axg_vapb_0_sel.hw 1182 + }, 1183 + .num_parents = 1, 1184 + .flags = CLK_SET_RATE_PARENT, 1185 + }, 1186 + }; 1187 + 1188 + static struct clk_regmap axg_vapb_0 = { 1189 + .data = &(struct clk_regmap_gate_data){ 1190 + .offset = HHI_VAPBCLK_CNTL, 1191 + .bit_idx = 8, 1192 + }, 1193 + .hw.init = &(struct clk_init_data) { 1194 + .name = "vapb_0", 1195 + .ops = &clk_regmap_gate_ops, 1196 + .parent_hws = (const struct clk_hw *[]) { 1197 + &axg_vapb_0_div.hw 1198 + }, 1199 + .num_parents = 1, 1200 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1201 + }, 1202 + }; 1203 + 1204 + static struct clk_regmap axg_vapb_1_sel = { 1205 + .data = &(struct clk_regmap_mux_data){ 1206 + .offset = HHI_VAPBCLK_CNTL, 1207 + .mask = 0x3, 1208 + .shift = 25, 1209 + }, 1210 + .hw.init = &(struct clk_init_data){ 1211 + .name = "vapb_1_sel", 1212 + .ops = &clk_regmap_mux_ops, 1213 + .parent_hws = axg_vpu_parent_hws, 1214 + .num_parents = ARRAY_SIZE(axg_vpu_parent_hws), 1215 + .flags = CLK_SET_RATE_NO_REPARENT, 1216 + }, 1217 + }; 1218 + 1219 + static struct clk_regmap axg_vapb_1_div = { 1220 + .data = &(struct clk_regmap_div_data){ 1221 + .offset = HHI_VAPBCLK_CNTL, 1222 + .shift = 16, 1223 + .width = 7, 1224 + }, 1225 + .hw.init = &(struct clk_init_data){ 1226 + .name = "vapb_1_div", 1227 + .ops = &clk_regmap_divider_ops, 1228 + .parent_hws = (const struct clk_hw *[]) { 1229 + &axg_vapb_1_sel.hw 1230 + }, 1231 + .num_parents = 1, 1232 + .flags = CLK_SET_RATE_PARENT, 1233 + }, 1234 + }; 1235 + 1236 + static struct clk_regmap axg_vapb_1 = { 1237 + .data = &(struct clk_regmap_gate_data){ 1238 + .offset = HHI_VAPBCLK_CNTL, 1239 + .bit_idx = 24, 1240 + }, 1241 + .hw.init = &(struct clk_init_data) { 1242 + .name = "vapb_1", 1243 + .ops = &clk_regmap_gate_ops, 1244 + .parent_hws = (const struct clk_hw *[]) { 1245 + &axg_vapb_1_div.hw 1246 + }, 1247 + .num_parents = 1, 1248 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1249 + }, 1250 + }; 1251 + 1252 + static struct clk_regmap axg_vapb_sel = { 1253 + .data = &(struct clk_regmap_mux_data){ 1254 + .offset = HHI_VAPBCLK_CNTL, 1255 + .mask = 1, 1256 + .shift = 31, 1257 + }, 1258 + .hw.init = &(struct clk_init_data){ 1259 + .name = "vapb_sel", 1260 + .ops = &clk_regmap_mux_ops, 1261 + .parent_hws = (const struct clk_hw *[]) { 1262 + &axg_vapb_0.hw, 1263 + &axg_vapb_1.hw 1264 + }, 1265 + .num_parents = 2, 1266 + .flags = CLK_SET_RATE_NO_REPARENT, 1267 + }, 1268 + }; 1269 + 1270 + static struct clk_regmap axg_vapb = { 1271 + .data = &(struct clk_regmap_gate_data){ 1272 + .offset = HHI_VAPBCLK_CNTL, 1273 + .bit_idx = 30, 1274 + }, 1275 + .hw.init = &(struct clk_init_data) { 1276 + .name = "vapb", 1277 + .ops = &clk_regmap_gate_ops, 1278 + .parent_hws = (const struct clk_hw *[]) { &axg_vapb_sel.hw }, 1279 + .num_parents = 1, 1280 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1281 + }, 1282 + }; 1283 + 1284 + /* Video Clocks */ 1285 + 1286 + static const struct clk_hw *axg_vclk_parent_hws[] = { 1287 + &axg_gp0_pll.hw, 1288 + &axg_fclk_div4.hw, 1289 + &axg_fclk_div3.hw, 1290 + &axg_fclk_div5.hw, 1291 + &axg_fclk_div2.hw, 1292 + &axg_fclk_div7.hw, 1293 + &axg_mpll1.hw, 1294 + }; 1295 + 1296 + static struct clk_regmap axg_vclk_sel = { 1297 + .data = &(struct clk_regmap_mux_data){ 1298 + .offset = HHI_VID_CLK_CNTL, 1299 + .mask = 0x7, 1300 + .shift = 16, 1301 + }, 1302 + .hw.init = &(struct clk_init_data){ 1303 + .name = "vclk_sel", 1304 + .ops = &clk_regmap_mux_ops, 1305 + .parent_hws = axg_vclk_parent_hws, 1306 + .num_parents = ARRAY_SIZE(axg_vclk_parent_hws), 1307 + .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, 1308 + }, 1309 + }; 1310 + 1311 + static struct clk_regmap axg_vclk2_sel = { 1312 + .data = &(struct clk_regmap_mux_data){ 1313 + .offset = HHI_VIID_CLK_CNTL, 1314 + .mask = 0x7, 1315 + .shift = 16, 1316 + }, 1317 + .hw.init = &(struct clk_init_data){ 1318 + .name = "vclk2_sel", 1319 + .ops = &clk_regmap_mux_ops, 1320 + .parent_hws = axg_vclk_parent_hws, 1321 + .num_parents = ARRAY_SIZE(axg_vclk_parent_hws), 1322 + .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, 1323 + }, 1324 + }; 1325 + 1326 + static struct clk_regmap axg_vclk_input = { 1327 + .data = &(struct clk_regmap_gate_data){ 1328 + .offset = HHI_VID_CLK_DIV, 1329 + .bit_idx = 16, 1330 + }, 1331 + .hw.init = &(struct clk_init_data) { 1332 + .name = "vclk_input", 1333 + .ops = &clk_regmap_gate_ops, 1334 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk_sel.hw }, 1335 + .num_parents = 1, 1336 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1337 + }, 1338 + }; 1339 + 1340 + static struct clk_regmap axg_vclk2_input = { 1341 + .data = &(struct clk_regmap_gate_data){ 1342 + .offset = HHI_VIID_CLK_DIV, 1343 + .bit_idx = 16, 1344 + }, 1345 + .hw.init = &(struct clk_init_data) { 1346 + .name = "vclk2_input", 1347 + .ops = &clk_regmap_gate_ops, 1348 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2_sel.hw }, 1349 + .num_parents = 1, 1350 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1351 + }, 1352 + }; 1353 + 1354 + static struct clk_regmap axg_vclk_div = { 1355 + .data = &(struct clk_regmap_div_data){ 1356 + .offset = HHI_VID_CLK_DIV, 1357 + .shift = 0, 1358 + .width = 8, 1359 + }, 1360 + .hw.init = &(struct clk_init_data){ 1361 + .name = "vclk_div", 1362 + .ops = &clk_regmap_divider_ops, 1363 + .parent_hws = (const struct clk_hw *[]) { 1364 + &axg_vclk_input.hw 1365 + }, 1366 + .num_parents = 1, 1367 + .flags = CLK_GET_RATE_NOCACHE, 1368 + }, 1369 + }; 1370 + 1371 + static struct clk_regmap axg_vclk2_div = { 1372 + .data = &(struct clk_regmap_div_data){ 1373 + .offset = HHI_VIID_CLK_DIV, 1374 + .shift = 0, 1375 + .width = 8, 1376 + }, 1377 + .hw.init = &(struct clk_init_data){ 1378 + .name = "vclk2_div", 1379 + .ops = &clk_regmap_divider_ops, 1380 + .parent_hws = (const struct clk_hw *[]) { 1381 + &axg_vclk2_input.hw 1382 + }, 1383 + .num_parents = 1, 1384 + .flags = CLK_GET_RATE_NOCACHE, 1385 + }, 1386 + }; 1387 + 1388 + static struct clk_regmap axg_vclk = { 1389 + .data = &(struct clk_regmap_gate_data){ 1390 + .offset = HHI_VID_CLK_CNTL, 1391 + .bit_idx = 19, 1392 + }, 1393 + .hw.init = &(struct clk_init_data) { 1394 + .name = "vclk", 1395 + .ops = &clk_regmap_gate_ops, 1396 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk_div.hw }, 1397 + .num_parents = 1, 1398 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1399 + }, 1400 + }; 1401 + 1402 + static struct clk_regmap axg_vclk2 = { 1403 + .data = &(struct clk_regmap_gate_data){ 1404 + .offset = HHI_VIID_CLK_CNTL, 1405 + .bit_idx = 19, 1406 + }, 1407 + .hw.init = &(struct clk_init_data) { 1408 + .name = "vclk2", 1409 + .ops = &clk_regmap_gate_ops, 1410 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2_div.hw }, 1411 + .num_parents = 1, 1412 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1413 + }, 1414 + }; 1415 + 1416 + static struct clk_regmap axg_vclk_div1 = { 1417 + .data = &(struct clk_regmap_gate_data){ 1418 + .offset = HHI_VID_CLK_CNTL, 1419 + .bit_idx = 0, 1420 + }, 1421 + .hw.init = &(struct clk_init_data) { 1422 + .name = "vclk_div1", 1423 + .ops = &clk_regmap_gate_ops, 1424 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw }, 1425 + .num_parents = 1, 1426 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1427 + }, 1428 + }; 1429 + 1430 + static struct clk_regmap axg_vclk_div2_en = { 1431 + .data = &(struct clk_regmap_gate_data){ 1432 + .offset = HHI_VID_CLK_CNTL, 1433 + .bit_idx = 1, 1434 + }, 1435 + .hw.init = &(struct clk_init_data) { 1436 + .name = "vclk_div2_en", 1437 + .ops = &clk_regmap_gate_ops, 1438 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw }, 1439 + .num_parents = 1, 1440 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1441 + }, 1442 + }; 1443 + 1444 + static struct clk_regmap axg_vclk_div4_en = { 1445 + .data = &(struct clk_regmap_gate_data){ 1446 + .offset = HHI_VID_CLK_CNTL, 1447 + .bit_idx = 2, 1448 + }, 1449 + .hw.init = &(struct clk_init_data) { 1450 + .name = "vclk_div4_en", 1451 + .ops = &clk_regmap_gate_ops, 1452 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw }, 1453 + .num_parents = 1, 1454 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1455 + }, 1456 + }; 1457 + 1458 + static struct clk_regmap axg_vclk_div6_en = { 1459 + .data = &(struct clk_regmap_gate_data){ 1460 + .offset = HHI_VID_CLK_CNTL, 1461 + .bit_idx = 3, 1462 + }, 1463 + .hw.init = &(struct clk_init_data) { 1464 + .name = "vclk_div6_en", 1465 + .ops = &clk_regmap_gate_ops, 1466 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw }, 1467 + .num_parents = 1, 1468 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1469 + }, 1470 + }; 1471 + 1472 + static struct clk_regmap axg_vclk_div12_en = { 1473 + .data = &(struct clk_regmap_gate_data){ 1474 + .offset = HHI_VID_CLK_CNTL, 1475 + .bit_idx = 4, 1476 + }, 1477 + .hw.init = &(struct clk_init_data) { 1478 + .name = "vclk_div12_en", 1479 + .ops = &clk_regmap_gate_ops, 1480 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk.hw }, 1481 + .num_parents = 1, 1482 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1483 + }, 1484 + }; 1485 + 1486 + static struct clk_regmap axg_vclk2_div1 = { 1487 + .data = &(struct clk_regmap_gate_data){ 1488 + .offset = HHI_VIID_CLK_CNTL, 1489 + .bit_idx = 0, 1490 + }, 1491 + .hw.init = &(struct clk_init_data) { 1492 + .name = "vclk2_div1", 1493 + .ops = &clk_regmap_gate_ops, 1494 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw }, 1495 + .num_parents = 1, 1496 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1497 + }, 1498 + }; 1499 + 1500 + static struct clk_regmap axg_vclk2_div2_en = { 1501 + .data = &(struct clk_regmap_gate_data){ 1502 + .offset = HHI_VIID_CLK_CNTL, 1503 + .bit_idx = 1, 1504 + }, 1505 + .hw.init = &(struct clk_init_data) { 1506 + .name = "vclk2_div2_en", 1507 + .ops = &clk_regmap_gate_ops, 1508 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw }, 1509 + .num_parents = 1, 1510 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1511 + }, 1512 + }; 1513 + 1514 + static struct clk_regmap axg_vclk2_div4_en = { 1515 + .data = &(struct clk_regmap_gate_data){ 1516 + .offset = HHI_VIID_CLK_CNTL, 1517 + .bit_idx = 2, 1518 + }, 1519 + .hw.init = &(struct clk_init_data) { 1520 + .name = "vclk2_div4_en", 1521 + .ops = &clk_regmap_gate_ops, 1522 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw }, 1523 + .num_parents = 1, 1524 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1525 + }, 1526 + }; 1527 + 1528 + static struct clk_regmap axg_vclk2_div6_en = { 1529 + .data = &(struct clk_regmap_gate_data){ 1530 + .offset = HHI_VIID_CLK_CNTL, 1531 + .bit_idx = 3, 1532 + }, 1533 + .hw.init = &(struct clk_init_data) { 1534 + .name = "vclk2_div6_en", 1535 + .ops = &clk_regmap_gate_ops, 1536 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw }, 1537 + .num_parents = 1, 1538 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1539 + }, 1540 + }; 1541 + 1542 + static struct clk_regmap axg_vclk2_div12_en = { 1543 + .data = &(struct clk_regmap_gate_data){ 1544 + .offset = HHI_VIID_CLK_CNTL, 1545 + .bit_idx = 4, 1546 + }, 1547 + .hw.init = &(struct clk_init_data) { 1548 + .name = "vclk2_div12_en", 1549 + .ops = &clk_regmap_gate_ops, 1550 + .parent_hws = (const struct clk_hw *[]) { &axg_vclk2.hw }, 1551 + .num_parents = 1, 1552 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1553 + }, 1554 + }; 1555 + 1556 + static struct clk_fixed_factor axg_vclk_div2 = { 1557 + .mult = 1, 1558 + .div = 2, 1559 + .hw.init = &(struct clk_init_data){ 1560 + .name = "vclk_div2", 1561 + .ops = &clk_fixed_factor_ops, 1562 + .parent_hws = (const struct clk_hw *[]) { 1563 + &axg_vclk_div2_en.hw 1564 + }, 1565 + .num_parents = 1, 1566 + }, 1567 + }; 1568 + 1569 + static struct clk_fixed_factor axg_vclk_div4 = { 1570 + .mult = 1, 1571 + .div = 4, 1572 + .hw.init = &(struct clk_init_data){ 1573 + .name = "vclk_div4", 1574 + .ops = &clk_fixed_factor_ops, 1575 + .parent_hws = (const struct clk_hw *[]) { 1576 + &axg_vclk_div4_en.hw 1577 + }, 1578 + .num_parents = 1, 1579 + }, 1580 + }; 1581 + 1582 + static struct clk_fixed_factor axg_vclk_div6 = { 1583 + .mult = 1, 1584 + .div = 6, 1585 + .hw.init = &(struct clk_init_data){ 1586 + .name = "vclk_div6", 1587 + .ops = &clk_fixed_factor_ops, 1588 + .parent_hws = (const struct clk_hw *[]) { 1589 + &axg_vclk_div6_en.hw 1590 + }, 1591 + .num_parents = 1, 1592 + }, 1593 + }; 1594 + 1595 + static struct clk_fixed_factor axg_vclk_div12 = { 1596 + .mult = 1, 1597 + .div = 12, 1598 + .hw.init = &(struct clk_init_data){ 1599 + .name = "vclk_div12", 1600 + .ops = &clk_fixed_factor_ops, 1601 + .parent_hws = (const struct clk_hw *[]) { 1602 + &axg_vclk_div12_en.hw 1603 + }, 1604 + .num_parents = 1, 1605 + }, 1606 + }; 1607 + 1608 + static struct clk_fixed_factor axg_vclk2_div2 = { 1609 + .mult = 1, 1610 + .div = 2, 1611 + .hw.init = &(struct clk_init_data){ 1612 + .name = "vclk2_div2", 1613 + .ops = &clk_fixed_factor_ops, 1614 + .parent_hws = (const struct clk_hw *[]) { 1615 + &axg_vclk2_div2_en.hw 1616 + }, 1617 + .num_parents = 1, 1618 + }, 1619 + }; 1620 + 1621 + static struct clk_fixed_factor axg_vclk2_div4 = { 1622 + .mult = 1, 1623 + .div = 4, 1624 + .hw.init = &(struct clk_init_data){ 1625 + .name = "vclk2_div4", 1626 + .ops = &clk_fixed_factor_ops, 1627 + .parent_hws = (const struct clk_hw *[]) { 1628 + &axg_vclk2_div4_en.hw 1629 + }, 1630 + .num_parents = 1, 1631 + }, 1632 + }; 1633 + 1634 + static struct clk_fixed_factor axg_vclk2_div6 = { 1635 + .mult = 1, 1636 + .div = 6, 1637 + .hw.init = &(struct clk_init_data){ 1638 + .name = "vclk2_div6", 1639 + .ops = &clk_fixed_factor_ops, 1640 + .parent_hws = (const struct clk_hw *[]) { 1641 + &axg_vclk2_div6_en.hw 1642 + }, 1643 + .num_parents = 1, 1644 + }, 1645 + }; 1646 + 1647 + static struct clk_fixed_factor axg_vclk2_div12 = { 1648 + .mult = 1, 1649 + .div = 12, 1650 + .hw.init = &(struct clk_init_data){ 1651 + .name = "vclk2_div12", 1652 + .ops = &clk_fixed_factor_ops, 1653 + .parent_hws = (const struct clk_hw *[]) { 1654 + &axg_vclk2_div12_en.hw 1655 + }, 1656 + .num_parents = 1, 1657 + }, 1658 + }; 1659 + 1660 + static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; 1661 + static const struct clk_hw *axg_cts_parent_hws[] = { 1662 + &axg_vclk_div1.hw, 1663 + &axg_vclk_div2.hw, 1664 + &axg_vclk_div4.hw, 1665 + &axg_vclk_div6.hw, 1666 + &axg_vclk_div12.hw, 1667 + &axg_vclk2_div1.hw, 1668 + &axg_vclk2_div2.hw, 1669 + &axg_vclk2_div4.hw, 1670 + &axg_vclk2_div6.hw, 1671 + &axg_vclk2_div12.hw, 1672 + }; 1673 + 1674 + static struct clk_regmap axg_cts_encl_sel = { 1675 + .data = &(struct clk_regmap_mux_data){ 1676 + .offset = HHI_VIID_CLK_DIV, 1677 + .mask = 0xf, 1678 + .shift = 12, 1679 + .table = mux_table_cts_sel, 1680 + }, 1681 + .hw.init = &(struct clk_init_data){ 1682 + .name = "cts_encl_sel", 1683 + .ops = &clk_regmap_mux_ops, 1684 + .parent_hws = axg_cts_parent_hws, 1685 + .num_parents = ARRAY_SIZE(axg_cts_parent_hws), 1686 + .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE, 1687 + }, 1688 + }; 1689 + 1690 + static struct clk_regmap axg_cts_encl = { 1691 + .data = &(struct clk_regmap_gate_data){ 1692 + .offset = HHI_VID_CLK_CNTL2, 1693 + .bit_idx = 3, 1694 + }, 1695 + .hw.init = &(struct clk_init_data) { 1696 + .name = "cts_encl", 1697 + .ops = &clk_regmap_gate_ops, 1698 + .parent_hws = (const struct clk_hw *[]) { 1699 + &axg_cts_encl_sel.hw 1700 + }, 1701 + .num_parents = 1, 1702 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1703 + }, 1704 + }; 1705 + 1706 + /* MIPI DSI Host Clock */ 1707 + 1708 + static u32 mux_table_axg_vdin_meas[] = { 0, 1, 2, 3, 6, 7 }; 1709 + static const struct clk_parent_data axg_vdin_meas_parent_data[] = { 1710 + { .fw_name = "xtal", }, 1711 + { .hw = &axg_fclk_div4.hw }, 1712 + { .hw = &axg_fclk_div3.hw }, 1713 + { .hw = &axg_fclk_div5.hw }, 1714 + { .hw = &axg_fclk_div2.hw }, 1715 + { .hw = &axg_fclk_div7.hw }, 1716 + }; 1717 + 1718 + static struct clk_regmap axg_vdin_meas_sel = { 1719 + .data = &(struct clk_regmap_mux_data){ 1720 + .offset = HHI_VDIN_MEAS_CLK_CNTL, 1721 + .mask = 0x7, 1722 + .shift = 21, 1723 + .flags = CLK_MUX_ROUND_CLOSEST, 1724 + .table = mux_table_axg_vdin_meas, 1725 + }, 1726 + .hw.init = &(struct clk_init_data){ 1727 + .name = "vdin_meas_sel", 1728 + .ops = &clk_regmap_mux_ops, 1729 + .parent_data = axg_vdin_meas_parent_data, 1730 + .num_parents = ARRAY_SIZE(axg_vdin_meas_parent_data), 1731 + .flags = CLK_SET_RATE_PARENT, 1732 + }, 1733 + }; 1734 + 1735 + static struct clk_regmap axg_vdin_meas_div = { 1736 + .data = &(struct clk_regmap_div_data){ 1737 + .offset = HHI_VDIN_MEAS_CLK_CNTL, 1738 + .shift = 12, 1739 + .width = 7, 1740 + }, 1741 + .hw.init = &(struct clk_init_data){ 1742 + .name = "vdin_meas_div", 1743 + .ops = &clk_regmap_divider_ops, 1744 + .parent_hws = (const struct clk_hw *[]) { 1745 + &axg_vdin_meas_sel.hw }, 1746 + .num_parents = 1, 1747 + .flags = CLK_SET_RATE_PARENT, 1748 + }, 1749 + }; 1750 + 1751 + static struct clk_regmap axg_vdin_meas = { 1752 + .data = &(struct clk_regmap_gate_data){ 1753 + .offset = HHI_VDIN_MEAS_CLK_CNTL, 1754 + .bit_idx = 20, 1755 + }, 1756 + .hw.init = &(struct clk_init_data) { 1757 + .name = "vdin_meas", 1758 + .ops = &clk_regmap_gate_ops, 1759 + .parent_hws = (const struct clk_hw *[]) { 1760 + &axg_vdin_meas_div.hw }, 1761 + .num_parents = 1, 1762 + .flags = CLK_SET_RATE_PARENT, 1763 + }, 1764 + }; 1765 + 1030 1766 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 1031 1767 9, 10, 11, 13, 14, }; 1032 1768 static const struct clk_parent_data gen_clk_parent_data[] = { ··· 1984 1246 [CLKID_HIFI_PLL_DCO] = &axg_hifi_pll_dco.hw, 1985 1247 [CLKID_PCIE_PLL_DCO] = &axg_pcie_pll_dco.hw, 1986 1248 [CLKID_PCIE_PLL_OD] = &axg_pcie_pll_od.hw, 1249 + [CLKID_VPU_0_DIV] = &axg_vpu_0_div.hw, 1250 + [CLKID_VPU_0_SEL] = &axg_vpu_0_sel.hw, 1251 + [CLKID_VPU_0] = &axg_vpu_0.hw, 1252 + [CLKID_VPU_1_DIV] = &axg_vpu_1_div.hw, 1253 + [CLKID_VPU_1_SEL] = &axg_vpu_1_sel.hw, 1254 + [CLKID_VPU_1] = &axg_vpu_1.hw, 1255 + [CLKID_VPU] = &axg_vpu.hw, 1256 + [CLKID_VAPB_0_DIV] = &axg_vapb_0_div.hw, 1257 + [CLKID_VAPB_0_SEL] = &axg_vapb_0_sel.hw, 1258 + [CLKID_VAPB_0] = &axg_vapb_0.hw, 1259 + [CLKID_VAPB_1_DIV] = &axg_vapb_1_div.hw, 1260 + [CLKID_VAPB_1_SEL] = &axg_vapb_1_sel.hw, 1261 + [CLKID_VAPB_1] = &axg_vapb_1.hw, 1262 + [CLKID_VAPB_SEL] = &axg_vapb_sel.hw, 1263 + [CLKID_VAPB] = &axg_vapb.hw, 1264 + [CLKID_VCLK] = &axg_vclk.hw, 1265 + [CLKID_VCLK2] = &axg_vclk2.hw, 1266 + [CLKID_VCLK_SEL] = &axg_vclk_sel.hw, 1267 + [CLKID_VCLK2_SEL] = &axg_vclk2_sel.hw, 1268 + [CLKID_VCLK_INPUT] = &axg_vclk_input.hw, 1269 + [CLKID_VCLK2_INPUT] = &axg_vclk2_input.hw, 1270 + [CLKID_VCLK_DIV] = &axg_vclk_div.hw, 1271 + [CLKID_VCLK2_DIV] = &axg_vclk2_div.hw, 1272 + [CLKID_VCLK_DIV2_EN] = &axg_vclk_div2_en.hw, 1273 + [CLKID_VCLK_DIV4_EN] = &axg_vclk_div4_en.hw, 1274 + [CLKID_VCLK_DIV6_EN] = &axg_vclk_div6_en.hw, 1275 + [CLKID_VCLK_DIV12_EN] = &axg_vclk_div12_en.hw, 1276 + [CLKID_VCLK2_DIV2_EN] = &axg_vclk2_div2_en.hw, 1277 + [CLKID_VCLK2_DIV4_EN] = &axg_vclk2_div4_en.hw, 1278 + [CLKID_VCLK2_DIV6_EN] = &axg_vclk2_div6_en.hw, 1279 + [CLKID_VCLK2_DIV12_EN] = &axg_vclk2_div12_en.hw, 1280 + [CLKID_VCLK_DIV1] = &axg_vclk_div1.hw, 1281 + [CLKID_VCLK_DIV2] = &axg_vclk_div2.hw, 1282 + [CLKID_VCLK_DIV4] = &axg_vclk_div4.hw, 1283 + [CLKID_VCLK_DIV6] = &axg_vclk_div6.hw, 1284 + [CLKID_VCLK_DIV12] = &axg_vclk_div12.hw, 1285 + [CLKID_VCLK2_DIV1] = &axg_vclk2_div1.hw, 1286 + [CLKID_VCLK2_DIV2] = &axg_vclk2_div2.hw, 1287 + [CLKID_VCLK2_DIV4] = &axg_vclk2_div4.hw, 1288 + [CLKID_VCLK2_DIV6] = &axg_vclk2_div6.hw, 1289 + [CLKID_VCLK2_DIV12] = &axg_vclk2_div12.hw, 1290 + [CLKID_CTS_ENCL_SEL] = &axg_cts_encl_sel.hw, 1291 + [CLKID_CTS_ENCL] = &axg_cts_encl.hw, 1292 + [CLKID_VDIN_MEAS_SEL] = &axg_vdin_meas_sel.hw, 1293 + [CLKID_VDIN_MEAS_DIV] = &axg_vdin_meas_div.hw, 1294 + [CLKID_VDIN_MEAS] = &axg_vdin_meas.hw, 1987 1295 [NR_CLKS] = NULL, 1988 1296 }, 1989 1297 .num = NR_CLKS, ··· 2125 1341 &axg_hifi_pll_dco, 2126 1342 &axg_pcie_pll_dco, 2127 1343 &axg_pcie_pll_od, 1344 + &axg_vpu_0_div, 1345 + &axg_vpu_0_sel, 1346 + &axg_vpu_0, 1347 + &axg_vpu_1_div, 1348 + &axg_vpu_1_sel, 1349 + &axg_vpu_1, 1350 + &axg_vpu, 1351 + &axg_vapb_0_div, 1352 + &axg_vapb_0_sel, 1353 + &axg_vapb_0, 1354 + &axg_vapb_1_div, 1355 + &axg_vapb_1_sel, 1356 + &axg_vapb_1, 1357 + &axg_vapb_sel, 1358 + &axg_vapb, 1359 + &axg_vclk, 1360 + &axg_vclk2, 1361 + &axg_vclk_sel, 1362 + &axg_vclk2_sel, 1363 + &axg_vclk_input, 1364 + &axg_vclk2_input, 1365 + &axg_vclk_div, 1366 + &axg_vclk2_div, 1367 + &axg_vclk_div2_en, 1368 + &axg_vclk_div4_en, 1369 + &axg_vclk_div6_en, 1370 + &axg_vclk_div12_en, 1371 + &axg_vclk2_div2_en, 1372 + &axg_vclk2_div4_en, 1373 + &axg_vclk2_div6_en, 1374 + &axg_vclk2_div12_en, 1375 + &axg_cts_encl_sel, 1376 + &axg_cts_encl, 1377 + &axg_vdin_meas_sel, 1378 + &axg_vdin_meas_div, 1379 + &axg_vdin_meas, 2128 1380 }; 2129 1381 2130 1382 static const struct meson_eeclkc_data axg_clkc_data = { ··· 2174 1354 { .compatible = "amlogic,axg-clkc", .data = &axg_clkc_data }, 2175 1355 {} 2176 1356 }; 1357 + MODULE_DEVICE_TABLE(of, clkc_match_table); 2177 1358 2178 1359 static struct platform_driver axg_driver = { 2179 1360 .probe = meson_eeclkc_probe, ··· 2184 1363 }, 2185 1364 }; 2186 1365 2187 - builtin_platform_driver(axg_driver); 1366 + module_platform_driver(axg_driver); 1367 + MODULE_LICENSE("GPL v2");
+22 -1
drivers/clk/meson/axg.h
··· 139 139 #define CLKID_HIFI_PLL_DCO 88 140 140 #define CLKID_PCIE_PLL_DCO 89 141 141 #define CLKID_PCIE_PLL_OD 90 142 + #define CLKID_VPU_0_DIV 91 143 + #define CLKID_VPU_1_DIV 94 144 + #define CLKID_VAPB_0_DIV 98 145 + #define CLKID_VAPB_1_DIV 101 146 + #define CLKID_VCLK_SEL 108 147 + #define CLKID_VCLK2_SEL 109 148 + #define CLKID_VCLK_INPUT 110 149 + #define CLKID_VCLK2_INPUT 111 150 + #define CLKID_VCLK_DIV 112 151 + #define CLKID_VCLK2_DIV 113 152 + #define CLKID_VCLK_DIV2_EN 114 153 + #define CLKID_VCLK_DIV4_EN 115 154 + #define CLKID_VCLK_DIV6_EN 116 155 + #define CLKID_VCLK_DIV12_EN 117 156 + #define CLKID_VCLK2_DIV2_EN 118 157 + #define CLKID_VCLK2_DIV4_EN 119 158 + #define CLKID_VCLK2_DIV6_EN 120 159 + #define CLKID_VCLK2_DIV12_EN 121 160 + #define CLKID_CTS_ENCL_SEL 132 161 + #define CLKID_VDIN_MEAS_SEL 134 162 + #define CLKID_VDIN_MEAS_DIV 135 142 163 143 - #define NR_CLKS 91 164 + #define NR_CLKS 137 144 165 145 166 /* include the CLKIDs that have been made part of the DT binding */ 146 167 #include <dt-bindings/clock/axg-clkc.h>
+4 -1
drivers/clk/meson/g12a-aoclk.c
··· 12 12 #include <linux/platform_device.h> 13 13 #include <linux/reset-controller.h> 14 14 #include <linux/mfd/syscon.h> 15 + #include <linux/module.h> 15 16 #include "meson-aoclk.h" 16 17 #include "g12a-aoclk.h" 17 18 ··· 462 461 }, 463 462 { } 464 463 }; 464 + MODULE_DEVICE_TABLE(of, g12a_aoclkc_match_table); 465 465 466 466 static struct platform_driver g12a_aoclkc_driver = { 467 467 .probe = meson_aoclkc_probe, ··· 472 470 }, 473 471 }; 474 472 475 - builtin_platform_driver(g12a_aoclkc_driver); 473 + module_platform_driver(g12a_aoclkc_driver); 474 + MODULE_LICENSE("GPL v2");
+130 -51
drivers/clk/meson/g12a.c
··· 15 15 #include <linux/of_device.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/clk.h> 18 + #include <linux/module.h> 18 19 19 20 #include "clk-mpll.h" 20 21 #include "clk-pll.h" ··· 3658 3657 }, 3659 3658 }; 3660 3659 3660 + /* MIPI DSI Host Clocks */ 3661 + 3662 + static const struct clk_hw *g12a_mipi_dsi_pxclk_parent_hws[] = { 3663 + &g12a_vid_pll.hw, 3664 + &g12a_gp0_pll.hw, 3665 + &g12a_hifi_pll.hw, 3666 + &g12a_mpll1.hw, 3667 + &g12a_fclk_div2.hw, 3668 + &g12a_fclk_div2p5.hw, 3669 + &g12a_fclk_div3.hw, 3670 + &g12a_fclk_div7.hw, 3671 + }; 3672 + 3673 + static struct clk_regmap g12a_mipi_dsi_pxclk_sel = { 3674 + .data = &(struct clk_regmap_mux_data){ 3675 + .offset = HHI_MIPIDSI_PHY_CLK_CNTL, 3676 + .mask = 0x7, 3677 + .shift = 12, 3678 + .flags = CLK_MUX_ROUND_CLOSEST, 3679 + }, 3680 + .hw.init = &(struct clk_init_data){ 3681 + .name = "mipi_dsi_pxclk_sel", 3682 + .ops = &clk_regmap_mux_ops, 3683 + .parent_hws = g12a_mipi_dsi_pxclk_parent_hws, 3684 + .num_parents = ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_hws), 3685 + .flags = CLK_SET_RATE_NO_REPARENT, 3686 + }, 3687 + }; 3688 + 3689 + static struct clk_regmap g12a_mipi_dsi_pxclk_div = { 3690 + .data = &(struct clk_regmap_div_data){ 3691 + .offset = HHI_MIPIDSI_PHY_CLK_CNTL, 3692 + .shift = 0, 3693 + .width = 7, 3694 + }, 3695 + .hw.init = &(struct clk_init_data){ 3696 + .name = "mipi_dsi_pxclk_div", 3697 + .ops = &clk_regmap_divider_ops, 3698 + .parent_hws = (const struct clk_hw *[]) { 3699 + &g12a_mipi_dsi_pxclk_sel.hw 3700 + }, 3701 + .num_parents = 1, 3702 + .flags = CLK_SET_RATE_PARENT, 3703 + }, 3704 + }; 3705 + 3706 + static struct clk_regmap g12a_mipi_dsi_pxclk = { 3707 + .data = &(struct clk_regmap_gate_data){ 3708 + .offset = HHI_MIPIDSI_PHY_CLK_CNTL, 3709 + .bit_idx = 8, 3710 + }, 3711 + .hw.init = &(struct clk_init_data) { 3712 + .name = "mipi_dsi_pxclk", 3713 + .ops = &clk_regmap_gate_ops, 3714 + .parent_hws = (const struct clk_hw *[]) { 3715 + &g12a_mipi_dsi_pxclk_div.hw 3716 + }, 3717 + .num_parents = 1, 3718 + .flags = CLK_SET_RATE_PARENT, 3719 + }, 3720 + }; 3721 + 3661 3722 /* HDMI Clocks */ 3662 3723 3663 3724 static const struct clk_parent_data g12a_hdmi_parent_data[] = { ··· 4465 4402 [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, 4466 4403 [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, 4467 4404 [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, 4405 + [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw, 4406 + [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw, 4407 + [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw, 4468 4408 [NR_CLKS] = NULL, 4469 4409 }, 4470 4410 .num = NR_CLKS, ··· 4723 4657 [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, 4724 4658 [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, 4725 4659 [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, 4660 + [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw, 4661 + [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw, 4662 + [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw, 4726 4663 [NR_CLKS] = NULL, 4727 4664 }, 4728 4665 .num = NR_CLKS, ··· 4972 4903 [CLKID_NNA_CORE_CLK_SEL] = &sm1_nna_core_clk_sel.hw, 4973 4904 [CLKID_NNA_CORE_CLK_DIV] = &sm1_nna_core_clk_div.hw, 4974 4905 [CLKID_NNA_CORE_CLK] = &sm1_nna_core_clk.hw, 4906 + [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw, 4907 + [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw, 4908 + [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw, 4975 4909 [NR_CLKS] = NULL, 4976 4910 }, 4977 4911 .num = NR_CLKS, ··· 5222 5150 &sm1_nna_core_clk_sel, 5223 5151 &sm1_nna_core_clk_div, 5224 5152 &sm1_nna_core_clk, 5153 + &g12a_mipi_dsi_pxclk_sel, 5154 + &g12a_mipi_dsi_pxclk_div, 5155 + &g12a_mipi_dsi_pxclk, 5225 5156 }; 5226 5157 5227 5158 static const struct reg_sequence g12a_init_regs[] = { 5228 5159 { .reg = HHI_MPLL_CNTL0, .def = 0x00000543 }, 5229 5160 }; 5230 5161 5231 - static int meson_g12a_dvfs_setup_common(struct platform_device *pdev, 5162 + #define DVFS_CON_ID "dvfs" 5163 + 5164 + static int meson_g12a_dvfs_setup_common(struct device *dev, 5232 5165 struct clk_hw **hws) 5233 5166 { 5234 - const char *notifier_clk_name; 5235 5167 struct clk *notifier_clk; 5236 5168 struct clk_hw *xtal; 5237 5169 int ret; ··· 5244 5168 5245 5169 /* Setup clock notifier for cpu_clk_postmux0 */ 5246 5170 g12a_cpu_clk_postmux0_nb_data.xtal = xtal; 5247 - notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw); 5248 - notifier_clk = __clk_lookup(notifier_clk_name); 5249 - ret = clk_notifier_register(notifier_clk, 5250 - &g12a_cpu_clk_postmux0_nb_data.nb); 5171 + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_postmux0.hw, 5172 + DVFS_CON_ID); 5173 + ret = devm_clk_notifier_register(dev, notifier_clk, 5174 + &g12a_cpu_clk_postmux0_nb_data.nb); 5251 5175 if (ret) { 5252 - dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n"); 5176 + dev_err(dev, "failed to register the cpu_clk_postmux0 notifier\n"); 5253 5177 return ret; 5254 5178 } 5255 5179 5256 5180 /* Setup clock notifier for cpu_clk_dyn mux */ 5257 - notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw); 5258 - notifier_clk = __clk_lookup(notifier_clk_name); 5259 - ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); 5181 + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_dyn.hw, 5182 + DVFS_CON_ID); 5183 + ret = devm_clk_notifier_register(dev, notifier_clk, 5184 + &g12a_cpu_clk_mux_nb); 5260 5185 if (ret) { 5261 - dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n"); 5186 + dev_err(dev, "failed to register the cpu_clk_dyn notifier\n"); 5262 5187 return ret; 5263 5188 } 5264 5189 ··· 5269 5192 static int meson_g12b_dvfs_setup(struct platform_device *pdev) 5270 5193 { 5271 5194 struct clk_hw **hws = g12b_hw_onecell_data.hws; 5272 - const char *notifier_clk_name; 5195 + struct device *dev = &pdev->dev; 5273 5196 struct clk *notifier_clk; 5274 5197 struct clk_hw *xtal; 5275 5198 int ret; 5276 5199 5277 - ret = meson_g12a_dvfs_setup_common(pdev, hws); 5200 + ret = meson_g12a_dvfs_setup_common(dev, hws); 5278 5201 if (ret) 5279 5202 return ret; 5280 5203 5281 5204 xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0); 5282 5205 5283 5206 /* Setup clock notifier for cpu_clk mux */ 5284 - notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw); 5285 - notifier_clk = __clk_lookup(notifier_clk_name); 5286 - ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); 5207 + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpu_clk.hw, 5208 + DVFS_CON_ID); 5209 + ret = devm_clk_notifier_register(dev, notifier_clk, 5210 + &g12a_cpu_clk_mux_nb); 5287 5211 if (ret) { 5288 - dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); 5212 + dev_err(dev, "failed to register the cpu_clk notifier\n"); 5289 5213 return ret; 5290 5214 } 5291 5215 5292 5216 /* Setup clock notifier for sys1_pll */ 5293 - notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw); 5294 - notifier_clk = __clk_lookup(notifier_clk_name); 5295 - ret = clk_notifier_register(notifier_clk, 5296 - &g12b_cpu_clk_sys1_pll_nb_data.nb); 5217 + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_sys1_pll.hw, 5218 + DVFS_CON_ID); 5219 + ret = devm_clk_notifier_register(dev, notifier_clk, 5220 + &g12b_cpu_clk_sys1_pll_nb_data.nb); 5297 5221 if (ret) { 5298 - dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n"); 5222 + dev_err(dev, "failed to register the sys1_pll notifier\n"); 5299 5223 return ret; 5300 5224 } 5301 5225 ··· 5304 5226 5305 5227 /* Setup clock notifier for cpub_clk_postmux0 */ 5306 5228 g12b_cpub_clk_postmux0_nb_data.xtal = xtal; 5307 - notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw); 5308 - notifier_clk = __clk_lookup(notifier_clk_name); 5309 - ret = clk_notifier_register(notifier_clk, 5310 - &g12b_cpub_clk_postmux0_nb_data.nb); 5229 + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_postmux0.hw, 5230 + DVFS_CON_ID); 5231 + ret = devm_clk_notifier_register(dev, notifier_clk, 5232 + &g12b_cpub_clk_postmux0_nb_data.nb); 5311 5233 if (ret) { 5312 - dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n"); 5234 + dev_err(dev, "failed to register the cpub_clk_postmux0 notifier\n"); 5313 5235 return ret; 5314 5236 } 5315 5237 5316 5238 /* Setup clock notifier for cpub_clk_dyn mux */ 5317 - notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw); 5318 - notifier_clk = __clk_lookup(notifier_clk_name); 5319 - ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); 5239 + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn.hw, "dvfs"); 5240 + ret = devm_clk_notifier_register(dev, notifier_clk, 5241 + &g12a_cpu_clk_mux_nb); 5320 5242 if (ret) { 5321 - dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n"); 5243 + dev_err(dev, "failed to register the cpub_clk_dyn notifier\n"); 5322 5244 return ret; 5323 5245 } 5324 5246 5325 5247 /* Setup clock notifier for cpub_clk mux */ 5326 - notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw); 5327 - notifier_clk = __clk_lookup(notifier_clk_name); 5328 - ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); 5248 + notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk.hw, DVFS_CON_ID); 5249 + ret = devm_clk_notifier_register(dev, notifier_clk, 5250 + &g12a_cpu_clk_mux_nb); 5329 5251 if (ret) { 5330 - dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n"); 5252 + dev_err(dev, "failed to register the cpub_clk notifier\n"); 5331 5253 return ret; 5332 5254 } 5333 5255 5334 5256 /* Setup clock notifier for sys_pll */ 5335 - notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); 5336 - notifier_clk = __clk_lookup(notifier_clk_name); 5337 - ret = clk_notifier_register(notifier_clk, 5338 - &g12b_cpub_clk_sys_pll_nb_data.nb); 5257 + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID); 5258 + ret = devm_clk_notifier_register(dev, notifier_clk, 5259 + &g12b_cpub_clk_sys_pll_nb_data.nb); 5339 5260 if (ret) { 5340 - dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); 5261 + dev_err(dev, "failed to register the sys_pll notifier\n"); 5341 5262 return ret; 5342 5263 } 5343 5264 ··· 5346 5269 static int meson_g12a_dvfs_setup(struct platform_device *pdev) 5347 5270 { 5348 5271 struct clk_hw **hws = g12a_hw_onecell_data.hws; 5349 - const char *notifier_clk_name; 5272 + struct device *dev = &pdev->dev; 5350 5273 struct clk *notifier_clk; 5351 5274 int ret; 5352 5275 5353 - ret = meson_g12a_dvfs_setup_common(pdev, hws); 5276 + ret = meson_g12a_dvfs_setup_common(dev, hws); 5354 5277 if (ret) 5355 5278 return ret; 5356 5279 5357 5280 /* Setup clock notifier for cpu_clk mux */ 5358 - notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw); 5359 - notifier_clk = __clk_lookup(notifier_clk_name); 5360 - ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb); 5281 + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk.hw, DVFS_CON_ID); 5282 + ret = devm_clk_notifier_register(dev, notifier_clk, 5283 + &g12a_cpu_clk_mux_nb); 5361 5284 if (ret) { 5362 - dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n"); 5285 + dev_err(dev, "failed to register the cpu_clk notifier\n"); 5363 5286 return ret; 5364 5287 } 5365 5288 5366 5289 /* Setup clock notifier for sys_pll */ 5367 - notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw); 5368 - notifier_clk = __clk_lookup(notifier_clk_name); 5369 - ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb); 5290 + notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID); 5291 + ret = devm_clk_notifier_register(dev, notifier_clk, 5292 + &g12a_sys_pll_nb_data.nb); 5370 5293 if (ret) { 5371 - dev_err(&pdev->dev, "failed to register the sys_pll notifier\n"); 5294 + dev_err(dev, "failed to register the sys_pll notifier\n"); 5372 5295 return ret; 5373 5296 } 5374 5297 ··· 5447 5370 }, 5448 5371 {} 5449 5372 }; 5373 + MODULE_DEVICE_TABLE(of, clkc_match_table); 5450 5374 5451 5375 static struct platform_driver g12a_driver = { 5452 5376 .probe = meson_g12a_probe, ··· 5457 5379 }, 5458 5380 }; 5459 5381 5460 - builtin_platform_driver(g12a_driver); 5382 + module_platform_driver(g12a_driver); 5383 + MODULE_LICENSE("GPL v2");
+2 -1
drivers/clk/meson/g12a.h
··· 264 264 #define CLKID_NNA_AXI_CLK_DIV 263 265 265 #define CLKID_NNA_CORE_CLK_SEL 265 266 266 #define CLKID_NNA_CORE_CLK_DIV 266 267 + #define CLKID_MIPI_DSI_PXCLK_DIV 268 267 268 268 - #define NR_CLKS 268 269 + #define NR_CLKS 271 269 270 270 271 /* include the CLKIDs that have been made part of the DT binding */ 271 272 #include <dt-bindings/clock/g12a-clkc.h>
+4 -1
drivers/clk/meson/gxbb-aoclk.c
··· 5 5 */ 6 6 #include <linux/platform_device.h> 7 7 #include <linux/mfd/syscon.h> 8 + #include <linux/module.h> 8 9 #include "meson-aoclk.h" 9 10 #include "gxbb-aoclk.h" 10 11 ··· 288 287 }, 289 288 { } 290 289 }; 290 + MODULE_DEVICE_TABLE(of, gxbb_aoclkc_match_table); 291 291 292 292 static struct platform_driver gxbb_aoclkc_driver = { 293 293 .probe = meson_aoclkc_probe, ··· 297 295 .of_match_table = gxbb_aoclkc_match_table, 298 296 }, 299 297 }; 300 - builtin_platform_driver(gxbb_aoclkc_driver); 298 + module_platform_driver(gxbb_aoclkc_driver); 299 + MODULE_LICENSE("GPL v2");
+4 -1
drivers/clk/meson/gxbb.c
··· 8 8 #include <linux/init.h> 9 9 #include <linux/of_device.h> 10 10 #include <linux/platform_device.h> 11 + #include <linux/module.h> 11 12 12 13 #include "gxbb.h" 13 14 #include "clk-regmap.h" ··· 3520 3519 { .compatible = "amlogic,gxl-clkc", .data = &gxl_clkc_data }, 3521 3520 {}, 3522 3521 }; 3522 + MODULE_DEVICE_TABLE(of, clkc_match_table); 3523 3523 3524 3524 static struct platform_driver gxbb_driver = { 3525 3525 .probe = meson_eeclkc_probe, ··· 3530 3528 }, 3531 3529 }; 3532 3530 3533 - builtin_platform_driver(gxbb_driver); 3531 + module_platform_driver(gxbb_driver); 3532 + MODULE_LICENSE("GPL v2");
+4
drivers/clk/meson/meson-aoclk.c
··· 14 14 #include <linux/reset-controller.h> 15 15 #include <linux/mfd/syscon.h> 16 16 #include <linux/of_device.h> 17 + #include <linux/module.h> 18 + 17 19 #include <linux/slab.h> 18 20 #include "meson-aoclk.h" 19 21 ··· 86 84 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 87 85 (void *) data->hw_data); 88 86 } 87 + EXPORT_SYMBOL_GPL(meson_aoclkc_probe); 88 + MODULE_LICENSE("GPL v2");
+3
drivers/clk/meson/meson-eeclk.c
··· 9 9 #include <linux/platform_device.h> 10 10 #include <linux/mfd/syscon.h> 11 11 #include <linux/regmap.h> 12 + #include <linux/module.h> 12 13 13 14 #include "clk-regmap.h" 14 15 #include "meson-eeclk.h" ··· 55 54 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 56 55 data->hw_onecell_data); 57 56 } 57 + EXPORT_SYMBOL_GPL(meson_eeclkc_probe); 58 + MODULE_LICENSE("GPL v2");
+2 -2
drivers/clk/mvebu/armada-37xx-xtal.c
··· 13 13 #include <linux/platform_device.h> 14 14 #include <linux/regmap.h> 15 15 16 - #define NB_GPIO1_LATCH 0xC 17 - #define XTAL_MODE BIT(31) 16 + #define NB_GPIO1_LATCH 0x8 17 + #define XTAL_MODE BIT(9) 18 18 19 19 static int armada_3700_xtal_clock_probe(struct platform_device *pdev) 20 20 {
+24 -1
drivers/clk/qcom/Kconfig
··· 44 44 help 45 45 Support for the CPU clock controller on msm8996 devices. 46 46 Say Y if you want to support CPU clock scaling using CPUfreq 47 - drivers for dyanmic power management. 47 + drivers for dynamic power management. 48 48 49 49 config QCOM_CLK_RPM 50 50 tristate "RPM based Clock Controller" ··· 290 290 Say Y if you want to use multimedia devices or peripheral 291 291 devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc. 292 292 293 + config SC_CAMCC_7180 294 + tristate "SC7180 Camera Clock Controller" 295 + select SC_GCC_7180 296 + help 297 + Support for the camera clock controller on Qualcomm Technologies, Inc 298 + SC7180 devices. 299 + Say Y if you want to support camera devices and functionality such as 300 + capturing pictures. 301 + 293 302 config SC_DISPCC_7180 294 303 tristate "SC7180 Display Clock Controller" 295 304 select SC_GCC_7180 ··· 422 413 Say Y if you want to use the LPASS branch clocks of the LPASS clock 423 414 controller to reset the LPASS subsystem. 424 415 416 + config SDX_GCC_55 417 + tristate "SDX55 Global Clock Controller" 418 + select QCOM_GDSC 419 + help 420 + Support for the global clock controller on SDX55 devices. 421 + Say Y if you want to use peripheral devices such as UART, 422 + SPI, I2C, USB, SD/UFS, PCIe etc. 423 + 425 424 config SM_DISPCC_8250 426 425 tristate "SM8150 and SM8250 Display Clock Controller" 427 426 depends on SM_GCC_8150 || SM_GCC_8250 ··· 518 501 help 519 502 Support for the Krait CPU clocks on Qualcomm devices. 520 503 Say Y if you want to support CPU frequency scaling. 504 + 505 + config CLK_GFM_LPASS_SM8250 506 + tristate "SM8250 GFM LPASS Clocks" 507 + help 508 + Support for the Glitch Free Mux (GFM) Low power audio 509 + subsystem (LPASS) clocks found on SM8250 SoCs. 521 510 522 511 endif
+3
drivers/clk/qcom/Makefile
··· 19 19 # Keep alphabetically sorted by config 20 20 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o 21 21 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o 22 + obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o 22 23 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o 23 24 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o 24 25 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o ··· 52 51 obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o 53 52 obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o 54 53 obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o 54 + obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o 55 55 obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o 56 56 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o 57 57 obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o ··· 66 64 obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o 67 65 obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o 68 66 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o 67 + obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o 69 68 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o 70 69 obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o 71 70 obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
+1732
drivers/clk/qcom/camcc-sc7180.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/err.h> 8 + #include <linux/module.h> 9 + #include <linux/of.h> 10 + #include <linux/of_device.h> 11 + #include <linux/pm_clock.h> 12 + #include <linux/pm_runtime.h> 13 + #include <linux/regmap.h> 14 + 15 + #include <dt-bindings/clock/qcom,camcc-sc7180.h> 16 + 17 + #include "clk-alpha-pll.h" 18 + #include "clk-branch.h" 19 + #include "clk-rcg.h" 20 + #include "clk-regmap.h" 21 + #include "common.h" 22 + #include "gdsc.h" 23 + #include "reset.h" 24 + 25 + enum { 26 + P_BI_TCXO, 27 + P_CAM_CC_PLL0_OUT_EVEN, 28 + P_CAM_CC_PLL1_OUT_EVEN, 29 + P_CAM_CC_PLL2_OUT_AUX, 30 + P_CAM_CC_PLL2_OUT_EARLY, 31 + P_CAM_CC_PLL3_OUT_MAIN, 32 + P_CORE_BI_PLL_TEST_SE, 33 + }; 34 + 35 + static const struct pll_vco agera_vco[] = { 36 + { 600000000, 3300000000UL, 0 }, 37 + }; 38 + 39 + static const struct pll_vco fabia_vco[] = { 40 + { 249600000, 2000000000UL, 0 }, 41 + }; 42 + 43 + /* 600MHz configuration */ 44 + static const struct alpha_pll_config cam_cc_pll0_config = { 45 + .l = 0x1f, 46 + .alpha = 0x4000, 47 + .config_ctl_val = 0x20485699, 48 + .config_ctl_hi_val = 0x00002067, 49 + .test_ctl_val = 0x40000000, 50 + .user_ctl_hi_val = 0x00004805, 51 + .user_ctl_val = 0x00000001, 52 + }; 53 + 54 + static struct clk_alpha_pll cam_cc_pll0 = { 55 + .offset = 0x0, 56 + .vco_table = fabia_vco, 57 + .num_vco = ARRAY_SIZE(fabia_vco), 58 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 59 + .clkr = { 60 + .hw.init = &(struct clk_init_data){ 61 + .name = "cam_cc_pll0", 62 + .parent_data = &(const struct clk_parent_data){ 63 + .fw_name = "bi_tcxo", 64 + }, 65 + .num_parents = 1, 66 + .ops = &clk_alpha_pll_fabia_ops, 67 + }, 68 + }, 69 + }; 70 + 71 + /* 860MHz configuration */ 72 + static const struct alpha_pll_config cam_cc_pll1_config = { 73 + .l = 0x2a, 74 + .alpha = 0x1555, 75 + .config_ctl_val = 0x20485699, 76 + .config_ctl_hi_val = 0x00002067, 77 + .test_ctl_val = 0x40000000, 78 + .user_ctl_hi_val = 0x00004805, 79 + }; 80 + 81 + static struct clk_alpha_pll cam_cc_pll1 = { 82 + .offset = 0x1000, 83 + .vco_table = fabia_vco, 84 + .num_vco = ARRAY_SIZE(fabia_vco), 85 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 86 + .clkr = { 87 + .hw.init = &(struct clk_init_data){ 88 + .name = "cam_cc_pll1", 89 + .parent_data = &(const struct clk_parent_data){ 90 + .fw_name = "bi_tcxo", 91 + }, 92 + .num_parents = 1, 93 + .ops = &clk_alpha_pll_fabia_ops, 94 + }, 95 + }, 96 + }; 97 + 98 + /* 1920MHz configuration */ 99 + static const struct alpha_pll_config cam_cc_pll2_config = { 100 + .l = 0x64, 101 + .config_ctl_val = 0x20000800, 102 + .config_ctl_hi_val = 0x400003D2, 103 + .test_ctl_val = 0x04000400, 104 + .test_ctl_hi_val = 0x00004000, 105 + .user_ctl_val = 0x0000030F, 106 + }; 107 + 108 + static struct clk_alpha_pll cam_cc_pll2 = { 109 + .offset = 0x2000, 110 + .vco_table = agera_vco, 111 + .num_vco = ARRAY_SIZE(agera_vco), 112 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_AGERA], 113 + .clkr = { 114 + .hw.init = &(struct clk_init_data){ 115 + .name = "cam_cc_pll2", 116 + .parent_data = &(const struct clk_parent_data){ 117 + .fw_name = "bi_tcxo", 118 + }, 119 + .num_parents = 1, 120 + .ops = &clk_alpha_pll_agera_ops, 121 + }, 122 + }, 123 + }; 124 + 125 + static struct clk_fixed_factor cam_cc_pll2_out_early = { 126 + .mult = 1, 127 + .div = 2, 128 + .hw.init = &(struct clk_init_data){ 129 + .name = "cam_cc_pll2_out_early", 130 + .parent_names = (const char *[]){ "cam_cc_pll2" }, 131 + .num_parents = 1, 132 + .ops = &clk_fixed_factor_ops, 133 + }, 134 + }; 135 + 136 + static const struct clk_div_table post_div_table_cam_cc_pll2_out_aux[] = { 137 + { 0x3, 4 }, 138 + { } 139 + }; 140 + 141 + static struct clk_alpha_pll_postdiv cam_cc_pll2_out_aux = { 142 + .offset = 0x2000, 143 + .post_div_shift = 8, 144 + .post_div_table = post_div_table_cam_cc_pll2_out_aux, 145 + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_aux), 146 + .width = 2, 147 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_AGERA], 148 + .clkr.hw.init = &(struct clk_init_data){ 149 + .name = "cam_cc_pll2_out_aux", 150 + .parent_data = &(const struct clk_parent_data){ 151 + .hw = &cam_cc_pll2.clkr.hw, 152 + }, 153 + .num_parents = 1, 154 + .flags = CLK_SET_RATE_PARENT, 155 + .ops = &clk_alpha_pll_postdiv_ops, 156 + }, 157 + }; 158 + 159 + /* 1080MHz configuration */ 160 + static const struct alpha_pll_config cam_cc_pll3_config = { 161 + .l = 0x38, 162 + .alpha = 0x4000, 163 + .config_ctl_val = 0x20485699, 164 + .config_ctl_hi_val = 0x00002067, 165 + .test_ctl_val = 0x40000000, 166 + .user_ctl_hi_val = 0x00004805, 167 + }; 168 + 169 + static struct clk_alpha_pll cam_cc_pll3 = { 170 + .offset = 0x3000, 171 + .vco_table = fabia_vco, 172 + .num_vco = ARRAY_SIZE(fabia_vco), 173 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 174 + .clkr = { 175 + .hw.init = &(struct clk_init_data){ 176 + .name = "cam_cc_pll3", 177 + .parent_data = &(const struct clk_parent_data){ 178 + .fw_name = "bi_tcxo", 179 + }, 180 + .num_parents = 1, 181 + .ops = &clk_alpha_pll_fabia_ops, 182 + }, 183 + }, 184 + }; 185 + 186 + static const struct parent_map cam_cc_parent_map_0[] = { 187 + { P_BI_TCXO, 0 }, 188 + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, 189 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 190 + { P_CORE_BI_PLL_TEST_SE, 7 }, 191 + }; 192 + 193 + static const struct clk_parent_data cam_cc_parent_data_0[] = { 194 + { .fw_name = "bi_tcxo" }, 195 + { .hw = &cam_cc_pll1.clkr.hw }, 196 + { .hw = &cam_cc_pll0.clkr.hw }, 197 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 198 + }; 199 + 200 + static const struct parent_map cam_cc_parent_map_1[] = { 201 + { P_BI_TCXO, 0 }, 202 + { P_CAM_CC_PLL2_OUT_AUX, 1 }, 203 + { P_CORE_BI_PLL_TEST_SE, 7 }, 204 + }; 205 + 206 + static const struct clk_parent_data cam_cc_parent_data_1[] = { 207 + { .fw_name = "bi_tcxo" }, 208 + { .hw = &cam_cc_pll2_out_aux.clkr.hw }, 209 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 210 + }; 211 + 212 + static const struct parent_map cam_cc_parent_map_2[] = { 213 + { P_BI_TCXO, 0 }, 214 + { P_CAM_CC_PLL2_OUT_EARLY, 4 }, 215 + { P_CAM_CC_PLL3_OUT_MAIN, 5 }, 216 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 217 + { P_CORE_BI_PLL_TEST_SE, 7 }, 218 + }; 219 + 220 + static const struct clk_parent_data cam_cc_parent_data_2[] = { 221 + { .fw_name = "bi_tcxo" }, 222 + { .hw = &cam_cc_pll2_out_early.hw }, 223 + { .hw = &cam_cc_pll3.clkr.hw }, 224 + { .hw = &cam_cc_pll0.clkr.hw }, 225 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 226 + }; 227 + 228 + static const struct parent_map cam_cc_parent_map_3[] = { 229 + { P_BI_TCXO, 0 }, 230 + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, 231 + { P_CAM_CC_PLL2_OUT_EARLY, 4 }, 232 + { P_CAM_CC_PLL3_OUT_MAIN, 5 }, 233 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 234 + { P_CORE_BI_PLL_TEST_SE, 7 }, 235 + }; 236 + 237 + static const struct clk_parent_data cam_cc_parent_data_3[] = { 238 + { .fw_name = "bi_tcxo" }, 239 + { .hw = &cam_cc_pll1.clkr.hw }, 240 + { .hw = &cam_cc_pll2_out_early.hw }, 241 + { .hw = &cam_cc_pll3.clkr.hw }, 242 + { .hw = &cam_cc_pll0.clkr.hw }, 243 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 244 + }; 245 + 246 + static const struct parent_map cam_cc_parent_map_4[] = { 247 + { P_BI_TCXO, 0 }, 248 + { P_CAM_CC_PLL3_OUT_MAIN, 5 }, 249 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 250 + { P_CORE_BI_PLL_TEST_SE, 7 }, 251 + }; 252 + 253 + static const struct clk_parent_data cam_cc_parent_data_4[] = { 254 + { .fw_name = "bi_tcxo" }, 255 + { .hw = &cam_cc_pll3.clkr.hw }, 256 + { .hw = &cam_cc_pll0.clkr.hw }, 257 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 258 + }; 259 + 260 + static const struct parent_map cam_cc_parent_map_5[] = { 261 + { P_BI_TCXO, 0 }, 262 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 263 + { P_CORE_BI_PLL_TEST_SE, 7 }, 264 + }; 265 + 266 + static const struct clk_parent_data cam_cc_parent_data_5[] = { 267 + { .fw_name = "bi_tcxo" }, 268 + { .hw = &cam_cc_pll0.clkr.hw }, 269 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 270 + }; 271 + 272 + static const struct parent_map cam_cc_parent_map_6[] = { 273 + { P_BI_TCXO, 0 }, 274 + { P_CAM_CC_PLL1_OUT_EVEN, 2 }, 275 + { P_CAM_CC_PLL3_OUT_MAIN, 5 }, 276 + { P_CAM_CC_PLL0_OUT_EVEN, 6 }, 277 + { P_CORE_BI_PLL_TEST_SE, 7 }, 278 + }; 279 + 280 + static const struct clk_parent_data cam_cc_parent_data_6[] = { 281 + { .fw_name = "bi_tcxo" }, 282 + { .hw = &cam_cc_pll1.clkr.hw }, 283 + { .hw = &cam_cc_pll3.clkr.hw }, 284 + { .hw = &cam_cc_pll0.clkr.hw }, 285 + { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" }, 286 + }; 287 + 288 + static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { 289 + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), 290 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 291 + F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0), 292 + F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0), 293 + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), 294 + { } 295 + }; 296 + 297 + static struct clk_rcg2 cam_cc_bps_clk_src = { 298 + .cmd_rcgr = 0x6010, 299 + .mnd_width = 0, 300 + .hid_width = 5, 301 + .parent_map = cam_cc_parent_map_2, 302 + .freq_tbl = ftbl_cam_cc_bps_clk_src, 303 + .clkr.hw.init = &(struct clk_init_data){ 304 + .name = "cam_cc_bps_clk_src", 305 + .parent_data = cam_cc_parent_data_2, 306 + .num_parents = 5, 307 + .ops = &clk_rcg2_ops, 308 + }, 309 + }; 310 + 311 + static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { 312 + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), 313 + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), 314 + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), 315 + { } 316 + }; 317 + 318 + static struct clk_rcg2 cam_cc_cci_0_clk_src = { 319 + .cmd_rcgr = 0xb0d8, 320 + .mnd_width = 8, 321 + .hid_width = 5, 322 + .parent_map = cam_cc_parent_map_5, 323 + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, 324 + .clkr.hw.init = &(struct clk_init_data){ 325 + .name = "cam_cc_cci_0_clk_src", 326 + .parent_data = cam_cc_parent_data_5, 327 + .num_parents = 3, 328 + .ops = &clk_rcg2_ops, 329 + }, 330 + }; 331 + 332 + static struct clk_rcg2 cam_cc_cci_1_clk_src = { 333 + .cmd_rcgr = 0xb14c, 334 + .mnd_width = 8, 335 + .hid_width = 5, 336 + .parent_map = cam_cc_parent_map_5, 337 + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, 338 + .clkr.hw.init = &(struct clk_init_data){ 339 + .name = "cam_cc_cci_1_clk_src", 340 + .parent_data = cam_cc_parent_data_5, 341 + .num_parents = 3, 342 + .ops = &clk_rcg2_ops, 343 + }, 344 + }; 345 + 346 + static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { 347 + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), 348 + F(270000000, P_CAM_CC_PLL3_OUT_MAIN, 4, 0, 0), 349 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 350 + { } 351 + }; 352 + 353 + static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { 354 + .cmd_rcgr = 0x9064, 355 + .mnd_width = 0, 356 + .hid_width = 5, 357 + .parent_map = cam_cc_parent_map_3, 358 + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, 359 + .clkr.hw.init = &(struct clk_init_data){ 360 + .name = "cam_cc_cphy_rx_clk_src", 361 + .parent_data = cam_cc_parent_data_3, 362 + .num_parents = 6, 363 + .ops = &clk_rcg2_ops, 364 + }, 365 + }; 366 + 367 + static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { 368 + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), 369 + { } 370 + }; 371 + 372 + static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { 373 + .cmd_rcgr = 0x5004, 374 + .mnd_width = 0, 375 + .hid_width = 5, 376 + .parent_map = cam_cc_parent_map_0, 377 + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, 378 + .clkr.hw.init = &(struct clk_init_data){ 379 + .name = "cam_cc_csi0phytimer_clk_src", 380 + .parent_data = cam_cc_parent_data_0, 381 + .num_parents = 4, 382 + .ops = &clk_rcg2_ops, 383 + }, 384 + }; 385 + 386 + static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { 387 + .cmd_rcgr = 0x5028, 388 + .mnd_width = 0, 389 + .hid_width = 5, 390 + .parent_map = cam_cc_parent_map_0, 391 + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, 392 + .clkr.hw.init = &(struct clk_init_data){ 393 + .name = "cam_cc_csi1phytimer_clk_src", 394 + .parent_data = cam_cc_parent_data_0, 395 + .num_parents = 4, 396 + .ops = &clk_rcg2_ops, 397 + }, 398 + }; 399 + 400 + static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { 401 + .cmd_rcgr = 0x504c, 402 + .mnd_width = 0, 403 + .hid_width = 5, 404 + .parent_map = cam_cc_parent_map_0, 405 + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, 406 + .clkr.hw.init = &(struct clk_init_data){ 407 + .name = "cam_cc_csi2phytimer_clk_src", 408 + .parent_data = cam_cc_parent_data_0, 409 + .num_parents = 4, 410 + .ops = &clk_rcg2_ops, 411 + }, 412 + }; 413 + 414 + static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { 415 + .cmd_rcgr = 0x5070, 416 + .mnd_width = 0, 417 + .hid_width = 5, 418 + .parent_map = cam_cc_parent_map_0, 419 + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, 420 + .clkr.hw.init = &(struct clk_init_data){ 421 + .name = "cam_cc_csi3phytimer_clk_src", 422 + .parent_data = cam_cc_parent_data_0, 423 + .num_parents = 4, 424 + .ops = &clk_rcg2_ops, 425 + }, 426 + }; 427 + 428 + static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { 429 + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), 430 + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), 431 + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), 432 + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), 433 + { } 434 + }; 435 + 436 + static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { 437 + .cmd_rcgr = 0x603c, 438 + .mnd_width = 0, 439 + .hid_width = 5, 440 + .parent_map = cam_cc_parent_map_0, 441 + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, 442 + .clkr.hw.init = &(struct clk_init_data){ 443 + .name = "cam_cc_fast_ahb_clk_src", 444 + .parent_data = cam_cc_parent_data_0, 445 + .num_parents = 4, 446 + .ops = &clk_rcg2_ops, 447 + }, 448 + }; 449 + 450 + static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = { 451 + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), 452 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 453 + F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0), 454 + F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0), 455 + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), 456 + { } 457 + }; 458 + 459 + static struct clk_rcg2 cam_cc_icp_clk_src = { 460 + .cmd_rcgr = 0xb088, 461 + .mnd_width = 0, 462 + .hid_width = 5, 463 + .parent_map = cam_cc_parent_map_2, 464 + .freq_tbl = ftbl_cam_cc_icp_clk_src, 465 + .clkr.hw.init = &(struct clk_init_data){ 466 + .name = "cam_cc_icp_clk_src", 467 + .parent_data = cam_cc_parent_data_2, 468 + .num_parents = 5, 469 + .ops = &clk_rcg2_ops, 470 + }, 471 + }; 472 + 473 + static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { 474 + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), 475 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 476 + F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0), 477 + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), 478 + { } 479 + }; 480 + 481 + static struct clk_rcg2 cam_cc_ife_0_clk_src = { 482 + .cmd_rcgr = 0x9010, 483 + .mnd_width = 0, 484 + .hid_width = 5, 485 + .parent_map = cam_cc_parent_map_4, 486 + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, 487 + .clkr.hw.init = &(struct clk_init_data){ 488 + .name = "cam_cc_ife_0_clk_src", 489 + .parent_data = cam_cc_parent_data_4, 490 + .num_parents = 4, 491 + .ops = &clk_rcg2_ops, 492 + }, 493 + }; 494 + 495 + static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = { 496 + F(150000000, P_CAM_CC_PLL0_OUT_EVEN, 4, 0, 0), 497 + F(270000000, P_CAM_CC_PLL3_OUT_MAIN, 4, 0, 0), 498 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 499 + F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0), 500 + { } 501 + }; 502 + 503 + static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { 504 + .cmd_rcgr = 0x903c, 505 + .mnd_width = 0, 506 + .hid_width = 5, 507 + .parent_map = cam_cc_parent_map_3, 508 + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, 509 + .clkr.hw.init = &(struct clk_init_data){ 510 + .name = "cam_cc_ife_0_csid_clk_src", 511 + .parent_data = cam_cc_parent_data_3, 512 + .num_parents = 6, 513 + .ops = &clk_rcg2_ops, 514 + }, 515 + }; 516 + 517 + static struct clk_rcg2 cam_cc_ife_1_clk_src = { 518 + .cmd_rcgr = 0xa010, 519 + .mnd_width = 0, 520 + .hid_width = 5, 521 + .parent_map = cam_cc_parent_map_4, 522 + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, 523 + .clkr.hw.init = &(struct clk_init_data){ 524 + .name = "cam_cc_ife_1_clk_src", 525 + .parent_data = cam_cc_parent_data_4, 526 + .num_parents = 4, 527 + .ops = &clk_rcg2_ops, 528 + }, 529 + }; 530 + 531 + static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { 532 + .cmd_rcgr = 0xa034, 533 + .mnd_width = 0, 534 + .hid_width = 5, 535 + .parent_map = cam_cc_parent_map_3, 536 + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, 537 + .clkr.hw.init = &(struct clk_init_data){ 538 + .name = "cam_cc_ife_1_csid_clk_src", 539 + .parent_data = cam_cc_parent_data_3, 540 + .num_parents = 6, 541 + .ops = &clk_rcg2_ops, 542 + }, 543 + }; 544 + 545 + static struct clk_rcg2 cam_cc_ife_lite_clk_src = { 546 + .cmd_rcgr = 0xb004, 547 + .mnd_width = 0, 548 + .hid_width = 5, 549 + .parent_map = cam_cc_parent_map_4, 550 + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, 551 + .clkr.hw.init = &(struct clk_init_data){ 552 + .name = "cam_cc_ife_lite_clk_src", 553 + .parent_data = cam_cc_parent_data_4, 554 + .num_parents = 4, 555 + .flags = CLK_SET_RATE_PARENT, 556 + .ops = &clk_rcg2_ops, 557 + }, 558 + }; 559 + 560 + static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { 561 + .cmd_rcgr = 0xb024, 562 + .mnd_width = 0, 563 + .hid_width = 5, 564 + .parent_map = cam_cc_parent_map_3, 565 + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, 566 + .clkr.hw.init = &(struct clk_init_data){ 567 + .name = "cam_cc_ife_lite_csid_clk_src", 568 + .parent_data = cam_cc_parent_data_3, 569 + .num_parents = 6, 570 + .ops = &clk_rcg2_ops, 571 + }, 572 + }; 573 + 574 + static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = { 575 + F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0), 576 + F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0), 577 + F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0), 578 + F(540000000, P_CAM_CC_PLL3_OUT_MAIN, 2, 0, 0), 579 + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), 580 + { } 581 + }; 582 + 583 + static struct clk_rcg2 cam_cc_ipe_0_clk_src = { 584 + .cmd_rcgr = 0x7010, 585 + .mnd_width = 0, 586 + .hid_width = 5, 587 + .parent_map = cam_cc_parent_map_2, 588 + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, 589 + .clkr.hw.init = &(struct clk_init_data){ 590 + .name = "cam_cc_ipe_0_clk_src", 591 + .parent_data = cam_cc_parent_data_2, 592 + .num_parents = 5, 593 + .ops = &clk_rcg2_ops, 594 + }, 595 + }; 596 + 597 + static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = { 598 + F(66666667, P_CAM_CC_PLL0_OUT_EVEN, 9, 0, 0), 599 + F(133333333, P_CAM_CC_PLL0_OUT_EVEN, 4.5, 0, 0), 600 + F(216000000, P_CAM_CC_PLL3_OUT_MAIN, 5, 0, 0), 601 + F(320000000, P_CAM_CC_PLL2_OUT_EARLY, 3, 0, 0), 602 + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), 603 + { } 604 + }; 605 + 606 + static struct clk_rcg2 cam_cc_jpeg_clk_src = { 607 + .cmd_rcgr = 0xb04c, 608 + .mnd_width = 0, 609 + .hid_width = 5, 610 + .parent_map = cam_cc_parent_map_2, 611 + .freq_tbl = ftbl_cam_cc_jpeg_clk_src, 612 + .clkr.hw.init = &(struct clk_init_data){ 613 + .name = "cam_cc_jpeg_clk_src", 614 + .parent_data = cam_cc_parent_data_2, 615 + .num_parents = 5, 616 + .ops = &clk_rcg2_ops, 617 + }, 618 + }; 619 + 620 + static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = { 621 + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), 622 + F(216000000, P_CAM_CC_PLL3_OUT_MAIN, 5, 0, 0), 623 + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), 624 + F(404000000, P_CAM_CC_PLL1_OUT_EVEN, 2, 0, 0), 625 + { } 626 + }; 627 + 628 + static struct clk_rcg2 cam_cc_lrme_clk_src = { 629 + .cmd_rcgr = 0xb0f8, 630 + .mnd_width = 0, 631 + .hid_width = 5, 632 + .parent_map = cam_cc_parent_map_6, 633 + .freq_tbl = ftbl_cam_cc_lrme_clk_src, 634 + .clkr.hw.init = &(struct clk_init_data){ 635 + .name = "cam_cc_lrme_clk_src", 636 + .parent_data = cam_cc_parent_data_6, 637 + .num_parents = 5, 638 + .ops = &clk_rcg2_ops, 639 + }, 640 + }; 641 + 642 + static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { 643 + F(19200000, P_BI_TCXO, 1, 0, 0), 644 + F(24000000, P_CAM_CC_PLL2_OUT_AUX, 10, 1, 2), 645 + F(64000000, P_CAM_CC_PLL2_OUT_AUX, 7.5, 0, 0), 646 + { } 647 + }; 648 + 649 + static struct clk_rcg2 cam_cc_mclk0_clk_src = { 650 + .cmd_rcgr = 0x4004, 651 + .mnd_width = 8, 652 + .hid_width = 5, 653 + .parent_map = cam_cc_parent_map_1, 654 + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, 655 + .clkr.hw.init = &(struct clk_init_data){ 656 + .name = "cam_cc_mclk0_clk_src", 657 + .parent_data = cam_cc_parent_data_1, 658 + .num_parents = 3, 659 + .ops = &clk_rcg2_ops, 660 + }, 661 + }; 662 + 663 + static struct clk_rcg2 cam_cc_mclk1_clk_src = { 664 + .cmd_rcgr = 0x4024, 665 + .mnd_width = 8, 666 + .hid_width = 5, 667 + .parent_map = cam_cc_parent_map_1, 668 + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, 669 + .clkr.hw.init = &(struct clk_init_data){ 670 + .name = "cam_cc_mclk1_clk_src", 671 + .parent_data = cam_cc_parent_data_1, 672 + .num_parents = 3, 673 + .ops = &clk_rcg2_ops, 674 + }, 675 + }; 676 + 677 + static struct clk_rcg2 cam_cc_mclk2_clk_src = { 678 + .cmd_rcgr = 0x4044, 679 + .mnd_width = 8, 680 + .hid_width = 5, 681 + .parent_map = cam_cc_parent_map_1, 682 + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, 683 + .clkr.hw.init = &(struct clk_init_data){ 684 + .name = "cam_cc_mclk2_clk_src", 685 + .parent_data = cam_cc_parent_data_1, 686 + .num_parents = 3, 687 + .ops = &clk_rcg2_ops, 688 + }, 689 + }; 690 + 691 + static struct clk_rcg2 cam_cc_mclk3_clk_src = { 692 + .cmd_rcgr = 0x4064, 693 + .mnd_width = 8, 694 + .hid_width = 5, 695 + .parent_map = cam_cc_parent_map_1, 696 + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, 697 + .clkr.hw.init = &(struct clk_init_data){ 698 + .name = "cam_cc_mclk3_clk_src", 699 + .parent_data = cam_cc_parent_data_1, 700 + .num_parents = 3, 701 + .ops = &clk_rcg2_ops, 702 + }, 703 + }; 704 + 705 + static struct clk_rcg2 cam_cc_mclk4_clk_src = { 706 + .cmd_rcgr = 0x4084, 707 + .mnd_width = 8, 708 + .hid_width = 5, 709 + .parent_map = cam_cc_parent_map_1, 710 + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, 711 + .clkr.hw.init = &(struct clk_init_data){ 712 + .name = "cam_cc_mclk4_clk_src", 713 + .parent_data = cam_cc_parent_data_1, 714 + .num_parents = 3, 715 + .ops = &clk_rcg2_ops, 716 + }, 717 + }; 718 + 719 + static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { 720 + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), 721 + { } 722 + }; 723 + 724 + static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { 725 + .cmd_rcgr = 0x6058, 726 + .mnd_width = 0, 727 + .hid_width = 5, 728 + .parent_map = cam_cc_parent_map_0, 729 + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, 730 + .clkr.hw.init = &(struct clk_init_data){ 731 + .name = "cam_cc_slow_ahb_clk_src", 732 + .parent_data = cam_cc_parent_data_0, 733 + .num_parents = 4, 734 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 735 + .ops = &clk_rcg2_ops, 736 + }, 737 + }; 738 + 739 + static struct clk_branch cam_cc_bps_ahb_clk = { 740 + .halt_reg = 0x6070, 741 + .halt_check = BRANCH_HALT, 742 + .clkr = { 743 + .enable_reg = 0x6070, 744 + .enable_mask = BIT(0), 745 + .hw.init = &(struct clk_init_data){ 746 + .name = "cam_cc_bps_ahb_clk", 747 + .parent_data = &(const struct clk_parent_data){ 748 + .hw = &cam_cc_slow_ahb_clk_src.clkr.hw, 749 + }, 750 + .num_parents = 1, 751 + .flags = CLK_SET_RATE_PARENT, 752 + .ops = &clk_branch2_ops, 753 + }, 754 + }, 755 + }; 756 + 757 + static struct clk_branch cam_cc_bps_areg_clk = { 758 + .halt_reg = 0x6054, 759 + .halt_check = BRANCH_HALT, 760 + .clkr = { 761 + .enable_reg = 0x6054, 762 + .enable_mask = BIT(0), 763 + .hw.init = &(struct clk_init_data){ 764 + .name = "cam_cc_bps_areg_clk", 765 + .parent_data = &(const struct clk_parent_data){ 766 + .hw = &cam_cc_fast_ahb_clk_src.clkr.hw, 767 + }, 768 + .num_parents = 1, 769 + .flags = CLK_SET_RATE_PARENT, 770 + .ops = &clk_branch2_ops, 771 + }, 772 + }, 773 + }; 774 + 775 + static struct clk_branch cam_cc_bps_axi_clk = { 776 + .halt_reg = 0x6038, 777 + .halt_check = BRANCH_HALT, 778 + .clkr = { 779 + .enable_reg = 0x6038, 780 + .enable_mask = BIT(0), 781 + .hw.init = &(struct clk_init_data){ 782 + .name = "cam_cc_bps_axi_clk", 783 + .ops = &clk_branch2_ops, 784 + }, 785 + }, 786 + }; 787 + 788 + static struct clk_branch cam_cc_bps_clk = { 789 + .halt_reg = 0x6028, 790 + .halt_check = BRANCH_HALT, 791 + .clkr = { 792 + .enable_reg = 0x6028, 793 + .enable_mask = BIT(0), 794 + .hw.init = &(struct clk_init_data){ 795 + .name = "cam_cc_bps_clk", 796 + .parent_data = &(const struct clk_parent_data){ 797 + .hw = &cam_cc_bps_clk_src.clkr.hw, 798 + }, 799 + .num_parents = 1, 800 + .flags = CLK_SET_RATE_PARENT, 801 + .ops = &clk_branch2_ops, 802 + }, 803 + }, 804 + }; 805 + 806 + static struct clk_branch cam_cc_camnoc_axi_clk = { 807 + .halt_reg = 0xb124, 808 + .halt_check = BRANCH_HALT, 809 + .clkr = { 810 + .enable_reg = 0xb124, 811 + .enable_mask = BIT(0), 812 + .hw.init = &(struct clk_init_data){ 813 + .name = "cam_cc_camnoc_axi_clk", 814 + .ops = &clk_branch2_ops, 815 + }, 816 + }, 817 + }; 818 + 819 + static struct clk_branch cam_cc_cci_0_clk = { 820 + .halt_reg = 0xb0f0, 821 + .halt_check = BRANCH_HALT, 822 + .clkr = { 823 + .enable_reg = 0xb0f0, 824 + .enable_mask = BIT(0), 825 + .hw.init = &(struct clk_init_data){ 826 + .name = "cam_cc_cci_0_clk", 827 + .parent_data = &(const struct clk_parent_data){ 828 + .hw = &cam_cc_cci_0_clk_src.clkr.hw, 829 + }, 830 + .num_parents = 1, 831 + .flags = CLK_SET_RATE_PARENT, 832 + .ops = &clk_branch2_ops, 833 + }, 834 + }, 835 + }; 836 + 837 + static struct clk_branch cam_cc_cci_1_clk = { 838 + .halt_reg = 0xb164, 839 + .halt_check = BRANCH_HALT, 840 + .clkr = { 841 + .enable_reg = 0xb164, 842 + .enable_mask = BIT(0), 843 + .hw.init = &(struct clk_init_data){ 844 + .name = "cam_cc_cci_1_clk", 845 + .parent_data = &(const struct clk_parent_data){ 846 + .hw = &cam_cc_cci_1_clk_src.clkr.hw, 847 + }, 848 + .num_parents = 1, 849 + .flags = CLK_SET_RATE_PARENT, 850 + .ops = &clk_branch2_ops, 851 + }, 852 + }, 853 + }; 854 + 855 + static struct clk_branch cam_cc_core_ahb_clk = { 856 + .halt_reg = 0xb144, 857 + .halt_check = BRANCH_HALT_DELAY, 858 + .clkr = { 859 + .enable_reg = 0xb144, 860 + .enable_mask = BIT(0), 861 + .hw.init = &(struct clk_init_data){ 862 + .name = "cam_cc_core_ahb_clk", 863 + .parent_data = &(const struct clk_parent_data){ 864 + .hw = &cam_cc_slow_ahb_clk_src.clkr.hw, 865 + }, 866 + .num_parents = 1, 867 + .flags = CLK_SET_RATE_PARENT, 868 + .ops = &clk_branch2_ops, 869 + }, 870 + }, 871 + }; 872 + 873 + static struct clk_branch cam_cc_cpas_ahb_clk = { 874 + .halt_reg = 0xb11c, 875 + .halt_check = BRANCH_HALT, 876 + .clkr = { 877 + .enable_reg = 0xb11c, 878 + .enable_mask = BIT(0), 879 + .hw.init = &(struct clk_init_data){ 880 + .name = "cam_cc_cpas_ahb_clk", 881 + .parent_data = &(const struct clk_parent_data){ 882 + .hw = &cam_cc_slow_ahb_clk_src.clkr.hw, 883 + }, 884 + .num_parents = 1, 885 + .flags = CLK_SET_RATE_PARENT, 886 + .ops = &clk_branch2_ops, 887 + }, 888 + }, 889 + }; 890 + 891 + static struct clk_branch cam_cc_csi0phytimer_clk = { 892 + .halt_reg = 0x501c, 893 + .halt_check = BRANCH_HALT, 894 + .clkr = { 895 + .enable_reg = 0x501c, 896 + .enable_mask = BIT(0), 897 + .hw.init = &(struct clk_init_data){ 898 + .name = "cam_cc_csi0phytimer_clk", 899 + .parent_data = &(const struct clk_parent_data){ 900 + .hw = &cam_cc_csi0phytimer_clk_src.clkr.hw, 901 + }, 902 + .num_parents = 1, 903 + .flags = CLK_SET_RATE_PARENT, 904 + .ops = &clk_branch2_ops, 905 + }, 906 + }, 907 + }; 908 + 909 + static struct clk_branch cam_cc_csi1phytimer_clk = { 910 + .halt_reg = 0x5040, 911 + .halt_check = BRANCH_HALT, 912 + .clkr = { 913 + .enable_reg = 0x5040, 914 + .enable_mask = BIT(0), 915 + .hw.init = &(struct clk_init_data){ 916 + .name = "cam_cc_csi1phytimer_clk", 917 + .parent_data = &(const struct clk_parent_data){ 918 + .hw = &cam_cc_csi1phytimer_clk_src.clkr.hw, 919 + }, 920 + .num_parents = 1, 921 + .flags = CLK_SET_RATE_PARENT, 922 + .ops = &clk_branch2_ops, 923 + }, 924 + }, 925 + }; 926 + 927 + static struct clk_branch cam_cc_csi2phytimer_clk = { 928 + .halt_reg = 0x5064, 929 + .halt_check = BRANCH_HALT, 930 + .clkr = { 931 + .enable_reg = 0x5064, 932 + .enable_mask = BIT(0), 933 + .hw.init = &(struct clk_init_data){ 934 + .name = "cam_cc_csi2phytimer_clk", 935 + .parent_data = &(const struct clk_parent_data){ 936 + .hw = &cam_cc_csi2phytimer_clk_src.clkr.hw, 937 + }, 938 + .num_parents = 1, 939 + .flags = CLK_SET_RATE_PARENT, 940 + .ops = &clk_branch2_ops, 941 + }, 942 + }, 943 + }; 944 + 945 + static struct clk_branch cam_cc_csi3phytimer_clk = { 946 + .halt_reg = 0x5088, 947 + .halt_check = BRANCH_HALT, 948 + .clkr = { 949 + .enable_reg = 0x5088, 950 + .enable_mask = BIT(0), 951 + .hw.init = &(struct clk_init_data){ 952 + .name = "cam_cc_csi3phytimer_clk", 953 + .parent_data = &(const struct clk_parent_data){ 954 + .hw = &cam_cc_csi3phytimer_clk_src.clkr.hw, 955 + }, 956 + .num_parents = 1, 957 + .flags = CLK_SET_RATE_PARENT, 958 + .ops = &clk_branch2_ops, 959 + }, 960 + }, 961 + }; 962 + 963 + static struct clk_branch cam_cc_csiphy0_clk = { 964 + .halt_reg = 0x5020, 965 + .halt_check = BRANCH_HALT, 966 + .clkr = { 967 + .enable_reg = 0x5020, 968 + .enable_mask = BIT(0), 969 + .hw.init = &(struct clk_init_data){ 970 + .name = "cam_cc_csiphy0_clk", 971 + .parent_data = &(const struct clk_parent_data){ 972 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 973 + }, 974 + .num_parents = 1, 975 + .flags = CLK_SET_RATE_PARENT, 976 + .ops = &clk_branch2_ops, 977 + }, 978 + }, 979 + }; 980 + 981 + static struct clk_branch cam_cc_csiphy1_clk = { 982 + .halt_reg = 0x5044, 983 + .halt_check = BRANCH_HALT, 984 + .clkr = { 985 + .enable_reg = 0x5044, 986 + .enable_mask = BIT(0), 987 + .hw.init = &(struct clk_init_data){ 988 + .name = "cam_cc_csiphy1_clk", 989 + .parent_data = &(const struct clk_parent_data){ 990 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 991 + }, 992 + .num_parents = 1, 993 + .flags = CLK_SET_RATE_PARENT, 994 + .ops = &clk_branch2_ops, 995 + }, 996 + }, 997 + }; 998 + 999 + static struct clk_branch cam_cc_csiphy2_clk = { 1000 + .halt_reg = 0x5068, 1001 + .halt_check = BRANCH_HALT, 1002 + .clkr = { 1003 + .enable_reg = 0x5068, 1004 + .enable_mask = BIT(0), 1005 + .hw.init = &(struct clk_init_data){ 1006 + .name = "cam_cc_csiphy2_clk", 1007 + .parent_data = &(const struct clk_parent_data){ 1008 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 1009 + }, 1010 + .num_parents = 1, 1011 + .flags = CLK_SET_RATE_PARENT, 1012 + .ops = &clk_branch2_ops, 1013 + }, 1014 + }, 1015 + }; 1016 + 1017 + static struct clk_branch cam_cc_csiphy3_clk = { 1018 + .halt_reg = 0x508c, 1019 + .halt_check = BRANCH_HALT, 1020 + .clkr = { 1021 + .enable_reg = 0x508c, 1022 + .enable_mask = BIT(0), 1023 + .hw.init = &(struct clk_init_data){ 1024 + .name = "cam_cc_csiphy3_clk", 1025 + .parent_data = &(const struct clk_parent_data){ 1026 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 1027 + }, 1028 + .num_parents = 1, 1029 + .flags = CLK_SET_RATE_PARENT, 1030 + .ops = &clk_branch2_ops, 1031 + }, 1032 + }, 1033 + }; 1034 + 1035 + static struct clk_branch cam_cc_icp_clk = { 1036 + .halt_reg = 0xb0a0, 1037 + .halt_check = BRANCH_HALT, 1038 + .clkr = { 1039 + .enable_reg = 0xb0a0, 1040 + .enable_mask = BIT(0), 1041 + .hw.init = &(struct clk_init_data){ 1042 + .name = "cam_cc_icp_clk", 1043 + .parent_data = &(const struct clk_parent_data){ 1044 + .hw = &cam_cc_icp_clk_src.clkr.hw, 1045 + }, 1046 + .num_parents = 1, 1047 + .flags = CLK_SET_RATE_PARENT, 1048 + .ops = &clk_branch2_ops, 1049 + }, 1050 + }, 1051 + }; 1052 + 1053 + static struct clk_branch cam_cc_ife_0_axi_clk = { 1054 + .halt_reg = 0x9080, 1055 + .halt_check = BRANCH_HALT, 1056 + .clkr = { 1057 + .enable_reg = 0x9080, 1058 + .enable_mask = BIT(0), 1059 + .hw.init = &(struct clk_init_data){ 1060 + .name = "cam_cc_ife_0_axi_clk", 1061 + .ops = &clk_branch2_ops, 1062 + }, 1063 + }, 1064 + }; 1065 + 1066 + static struct clk_branch cam_cc_ife_0_clk = { 1067 + .halt_reg = 0x9028, 1068 + .halt_check = BRANCH_HALT, 1069 + .clkr = { 1070 + .enable_reg = 0x9028, 1071 + .enable_mask = BIT(0), 1072 + .hw.init = &(struct clk_init_data){ 1073 + .name = "cam_cc_ife_0_clk", 1074 + .parent_data = &(const struct clk_parent_data){ 1075 + .hw = &cam_cc_ife_0_clk_src.clkr.hw, 1076 + }, 1077 + .num_parents = 1, 1078 + .flags = CLK_SET_RATE_PARENT, 1079 + .ops = &clk_branch2_ops, 1080 + }, 1081 + }, 1082 + }; 1083 + 1084 + static struct clk_branch cam_cc_ife_0_cphy_rx_clk = { 1085 + .halt_reg = 0x907c, 1086 + .halt_check = BRANCH_HALT, 1087 + .clkr = { 1088 + .enable_reg = 0x907c, 1089 + .enable_mask = BIT(0), 1090 + .hw.init = &(struct clk_init_data){ 1091 + .name = "cam_cc_ife_0_cphy_rx_clk", 1092 + .parent_data = &(const struct clk_parent_data){ 1093 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 1094 + }, 1095 + .num_parents = 1, 1096 + .flags = CLK_SET_RATE_PARENT, 1097 + .ops = &clk_branch2_ops, 1098 + }, 1099 + }, 1100 + }; 1101 + 1102 + static struct clk_branch cam_cc_ife_0_csid_clk = { 1103 + .halt_reg = 0x9054, 1104 + .halt_check = BRANCH_HALT, 1105 + .clkr = { 1106 + .enable_reg = 0x9054, 1107 + .enable_mask = BIT(0), 1108 + .hw.init = &(struct clk_init_data){ 1109 + .name = "cam_cc_ife_0_csid_clk", 1110 + .parent_data = &(const struct clk_parent_data){ 1111 + .hw = &cam_cc_ife_0_csid_clk_src.clkr.hw, 1112 + }, 1113 + .num_parents = 1, 1114 + .flags = CLK_SET_RATE_PARENT, 1115 + .ops = &clk_branch2_ops, 1116 + }, 1117 + }, 1118 + }; 1119 + 1120 + static struct clk_branch cam_cc_ife_0_dsp_clk = { 1121 + .halt_reg = 0x9038, 1122 + .halt_check = BRANCH_HALT, 1123 + .clkr = { 1124 + .enable_reg = 0x9038, 1125 + .enable_mask = BIT(0), 1126 + .hw.init = &(struct clk_init_data){ 1127 + .name = "cam_cc_ife_0_dsp_clk", 1128 + .parent_data = &(const struct clk_parent_data){ 1129 + .hw = &cam_cc_ife_0_clk_src.clkr.hw, 1130 + }, 1131 + .num_parents = 1, 1132 + .flags = CLK_SET_RATE_PARENT, 1133 + .ops = &clk_branch2_ops, 1134 + }, 1135 + }, 1136 + }; 1137 + 1138 + static struct clk_branch cam_cc_ife_1_axi_clk = { 1139 + .halt_reg = 0xa058, 1140 + .halt_check = BRANCH_HALT, 1141 + .clkr = { 1142 + .enable_reg = 0xa058, 1143 + .enable_mask = BIT(0), 1144 + .hw.init = &(struct clk_init_data){ 1145 + .name = "cam_cc_ife_1_axi_clk", 1146 + .ops = &clk_branch2_ops, 1147 + }, 1148 + }, 1149 + }; 1150 + 1151 + static struct clk_branch cam_cc_ife_1_clk = { 1152 + .halt_reg = 0xa028, 1153 + .halt_check = BRANCH_HALT, 1154 + .clkr = { 1155 + .enable_reg = 0xa028, 1156 + .enable_mask = BIT(0), 1157 + .hw.init = &(struct clk_init_data){ 1158 + .name = "cam_cc_ife_1_clk", 1159 + .parent_data = &(const struct clk_parent_data){ 1160 + .hw = &cam_cc_ife_1_clk_src.clkr.hw, 1161 + }, 1162 + .num_parents = 1, 1163 + .flags = CLK_SET_RATE_PARENT, 1164 + .ops = &clk_branch2_ops, 1165 + }, 1166 + }, 1167 + }; 1168 + 1169 + static struct clk_branch cam_cc_ife_1_cphy_rx_clk = { 1170 + .halt_reg = 0xa054, 1171 + .halt_check = BRANCH_HALT, 1172 + .clkr = { 1173 + .enable_reg = 0xa054, 1174 + .enable_mask = BIT(0), 1175 + .hw.init = &(struct clk_init_data){ 1176 + .name = "cam_cc_ife_1_cphy_rx_clk", 1177 + .parent_data = &(const struct clk_parent_data){ 1178 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 1179 + }, 1180 + .num_parents = 1, 1181 + .flags = CLK_SET_RATE_PARENT, 1182 + .ops = &clk_branch2_ops, 1183 + }, 1184 + }, 1185 + }; 1186 + 1187 + static struct clk_branch cam_cc_ife_1_csid_clk = { 1188 + .halt_reg = 0xa04c, 1189 + .halt_check = BRANCH_HALT, 1190 + .clkr = { 1191 + .enable_reg = 0xa04c, 1192 + .enable_mask = BIT(0), 1193 + .hw.init = &(struct clk_init_data){ 1194 + .name = "cam_cc_ife_1_csid_clk", 1195 + .parent_data = &(const struct clk_parent_data){ 1196 + .hw = &cam_cc_ife_1_csid_clk_src.clkr.hw, 1197 + }, 1198 + .num_parents = 1, 1199 + .flags = CLK_SET_RATE_PARENT, 1200 + .ops = &clk_branch2_ops, 1201 + }, 1202 + }, 1203 + }; 1204 + 1205 + static struct clk_branch cam_cc_ife_1_dsp_clk = { 1206 + .halt_reg = 0xa030, 1207 + .halt_check = BRANCH_HALT, 1208 + .clkr = { 1209 + .enable_reg = 0xa030, 1210 + .enable_mask = BIT(0), 1211 + .hw.init = &(struct clk_init_data){ 1212 + .name = "cam_cc_ife_1_dsp_clk", 1213 + .parent_data = &(const struct clk_parent_data){ 1214 + .hw = &cam_cc_ife_1_clk_src.clkr.hw, 1215 + }, 1216 + .num_parents = 1, 1217 + .flags = CLK_SET_RATE_PARENT, 1218 + .ops = &clk_branch2_ops, 1219 + }, 1220 + }, 1221 + }; 1222 + 1223 + static struct clk_branch cam_cc_ife_lite_clk = { 1224 + .halt_reg = 0xb01c, 1225 + .halt_check = BRANCH_HALT, 1226 + .clkr = { 1227 + .enable_reg = 0xb01c, 1228 + .enable_mask = BIT(0), 1229 + .hw.init = &(struct clk_init_data){ 1230 + .name = "cam_cc_ife_lite_clk", 1231 + .parent_data = &(const struct clk_parent_data){ 1232 + .hw = &cam_cc_ife_lite_clk_src.clkr.hw, 1233 + }, 1234 + .num_parents = 1, 1235 + .flags = CLK_SET_RATE_PARENT, 1236 + .ops = &clk_branch2_ops, 1237 + }, 1238 + }, 1239 + }; 1240 + 1241 + static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { 1242 + .halt_reg = 0xb044, 1243 + .halt_check = BRANCH_HALT, 1244 + .clkr = { 1245 + .enable_reg = 0xb044, 1246 + .enable_mask = BIT(0), 1247 + .hw.init = &(struct clk_init_data){ 1248 + .name = "cam_cc_ife_lite_cphy_rx_clk", 1249 + .parent_data = &(const struct clk_parent_data){ 1250 + .hw = &cam_cc_cphy_rx_clk_src.clkr.hw, 1251 + }, 1252 + .num_parents = 1, 1253 + .flags = CLK_SET_RATE_PARENT, 1254 + .ops = &clk_branch2_ops, 1255 + }, 1256 + }, 1257 + }; 1258 + 1259 + static struct clk_branch cam_cc_ife_lite_csid_clk = { 1260 + .halt_reg = 0xb03c, 1261 + .halt_check = BRANCH_HALT, 1262 + .clkr = { 1263 + .enable_reg = 0xb03c, 1264 + .enable_mask = BIT(0), 1265 + .hw.init = &(struct clk_init_data){ 1266 + .name = "cam_cc_ife_lite_csid_clk", 1267 + .parent_data = &(const struct clk_parent_data){ 1268 + .hw = &cam_cc_ife_lite_csid_clk_src.clkr.hw, 1269 + }, 1270 + .num_parents = 1, 1271 + .flags = CLK_SET_RATE_PARENT, 1272 + .ops = &clk_branch2_ops, 1273 + }, 1274 + }, 1275 + }; 1276 + 1277 + static struct clk_branch cam_cc_ipe_0_ahb_clk = { 1278 + .halt_reg = 0x7040, 1279 + .halt_check = BRANCH_HALT, 1280 + .clkr = { 1281 + .enable_reg = 0x7040, 1282 + .enable_mask = BIT(0), 1283 + .hw.init = &(struct clk_init_data){ 1284 + .name = "cam_cc_ipe_0_ahb_clk", 1285 + .parent_data = &(const struct clk_parent_data){ 1286 + .hw = &cam_cc_slow_ahb_clk_src.clkr.hw, 1287 + }, 1288 + .num_parents = 1, 1289 + .flags = CLK_SET_RATE_PARENT, 1290 + .ops = &clk_branch2_ops, 1291 + }, 1292 + }, 1293 + }; 1294 + 1295 + static struct clk_branch cam_cc_ipe_0_areg_clk = { 1296 + .halt_reg = 0x703c, 1297 + .halt_check = BRANCH_HALT, 1298 + .clkr = { 1299 + .enable_reg = 0x703c, 1300 + .enable_mask = BIT(0), 1301 + .hw.init = &(struct clk_init_data){ 1302 + .name = "cam_cc_ipe_0_areg_clk", 1303 + .parent_data = &(const struct clk_parent_data){ 1304 + .hw = &cam_cc_fast_ahb_clk_src.clkr.hw, 1305 + }, 1306 + .num_parents = 1, 1307 + .flags = CLK_SET_RATE_PARENT, 1308 + .ops = &clk_branch2_ops, 1309 + }, 1310 + }, 1311 + }; 1312 + 1313 + static struct clk_branch cam_cc_ipe_0_axi_clk = { 1314 + .halt_reg = 0x7038, 1315 + .halt_check = BRANCH_HALT, 1316 + .clkr = { 1317 + .enable_reg = 0x7038, 1318 + .enable_mask = BIT(0), 1319 + .hw.init = &(struct clk_init_data){ 1320 + .name = "cam_cc_ipe_0_axi_clk", 1321 + .ops = &clk_branch2_ops, 1322 + }, 1323 + }, 1324 + }; 1325 + 1326 + static struct clk_branch cam_cc_ipe_0_clk = { 1327 + .halt_reg = 0x7028, 1328 + .halt_check = BRANCH_HALT, 1329 + .clkr = { 1330 + .enable_reg = 0x7028, 1331 + .enable_mask = BIT(0), 1332 + .hw.init = &(struct clk_init_data){ 1333 + .name = "cam_cc_ipe_0_clk", 1334 + .parent_data = &(const struct clk_parent_data){ 1335 + .hw = &cam_cc_ipe_0_clk_src.clkr.hw, 1336 + }, 1337 + .num_parents = 1, 1338 + .flags = CLK_SET_RATE_PARENT, 1339 + .ops = &clk_branch2_ops, 1340 + }, 1341 + }, 1342 + }; 1343 + 1344 + static struct clk_branch cam_cc_jpeg_clk = { 1345 + .halt_reg = 0xb064, 1346 + .halt_check = BRANCH_HALT, 1347 + .clkr = { 1348 + .enable_reg = 0xb064, 1349 + .enable_mask = BIT(0), 1350 + .hw.init = &(struct clk_init_data){ 1351 + .name = "cam_cc_jpeg_clk", 1352 + .parent_data = &(const struct clk_parent_data){ 1353 + .hw = &cam_cc_jpeg_clk_src.clkr.hw, 1354 + }, 1355 + .num_parents = 1, 1356 + .flags = CLK_SET_RATE_PARENT, 1357 + .ops = &clk_branch2_ops, 1358 + }, 1359 + }, 1360 + }; 1361 + 1362 + static struct clk_branch cam_cc_lrme_clk = { 1363 + .halt_reg = 0xb110, 1364 + .halt_check = BRANCH_HALT, 1365 + .clkr = { 1366 + .enable_reg = 0xb110, 1367 + .enable_mask = BIT(0), 1368 + .hw.init = &(struct clk_init_data){ 1369 + .name = "cam_cc_lrme_clk", 1370 + .parent_data = &(const struct clk_parent_data){ 1371 + .hw = &cam_cc_lrme_clk_src.clkr.hw, 1372 + }, 1373 + .num_parents = 1, 1374 + .flags = CLK_SET_RATE_PARENT, 1375 + .ops = &clk_branch2_ops, 1376 + }, 1377 + }, 1378 + }; 1379 + 1380 + static struct clk_branch cam_cc_mclk0_clk = { 1381 + .halt_reg = 0x401c, 1382 + .halt_check = BRANCH_HALT, 1383 + .clkr = { 1384 + .enable_reg = 0x401c, 1385 + .enable_mask = BIT(0), 1386 + .hw.init = &(struct clk_init_data){ 1387 + .name = "cam_cc_mclk0_clk", 1388 + .parent_data = &(const struct clk_parent_data){ 1389 + .hw = &cam_cc_mclk0_clk_src.clkr.hw, 1390 + }, 1391 + .num_parents = 1, 1392 + .flags = CLK_SET_RATE_PARENT, 1393 + .ops = &clk_branch2_ops, 1394 + }, 1395 + }, 1396 + }; 1397 + 1398 + static struct clk_branch cam_cc_mclk1_clk = { 1399 + .halt_reg = 0x403c, 1400 + .halt_check = BRANCH_HALT, 1401 + .clkr = { 1402 + .enable_reg = 0x403c, 1403 + .enable_mask = BIT(0), 1404 + .hw.init = &(struct clk_init_data){ 1405 + .name = "cam_cc_mclk1_clk", 1406 + .parent_data = &(const struct clk_parent_data){ 1407 + .hw = &cam_cc_mclk1_clk_src.clkr.hw, 1408 + }, 1409 + .num_parents = 1, 1410 + .flags = CLK_SET_RATE_PARENT, 1411 + .ops = &clk_branch2_ops, 1412 + }, 1413 + }, 1414 + }; 1415 + 1416 + static struct clk_branch cam_cc_mclk2_clk = { 1417 + .halt_reg = 0x405c, 1418 + .halt_check = BRANCH_HALT, 1419 + .clkr = { 1420 + .enable_reg = 0x405c, 1421 + .enable_mask = BIT(0), 1422 + .hw.init = &(struct clk_init_data){ 1423 + .name = "cam_cc_mclk2_clk", 1424 + .parent_data = &(const struct clk_parent_data){ 1425 + .hw = &cam_cc_mclk2_clk_src.clkr.hw, 1426 + }, 1427 + .num_parents = 1, 1428 + .flags = CLK_SET_RATE_PARENT, 1429 + .ops = &clk_branch2_ops, 1430 + }, 1431 + }, 1432 + }; 1433 + 1434 + static struct clk_branch cam_cc_mclk3_clk = { 1435 + .halt_reg = 0x407c, 1436 + .halt_check = BRANCH_HALT, 1437 + .clkr = { 1438 + .enable_reg = 0x407c, 1439 + .enable_mask = BIT(0), 1440 + .hw.init = &(struct clk_init_data){ 1441 + .name = "cam_cc_mclk3_clk", 1442 + .parent_data = &(const struct clk_parent_data){ 1443 + .hw = &cam_cc_mclk3_clk_src.clkr.hw, 1444 + }, 1445 + .num_parents = 1, 1446 + .flags = CLK_SET_RATE_PARENT, 1447 + .ops = &clk_branch2_ops, 1448 + }, 1449 + }, 1450 + }; 1451 + 1452 + static struct clk_branch cam_cc_mclk4_clk = { 1453 + .halt_reg = 0x409c, 1454 + .halt_check = BRANCH_HALT, 1455 + .clkr = { 1456 + .enable_reg = 0x409c, 1457 + .enable_mask = BIT(0), 1458 + .hw.init = &(struct clk_init_data){ 1459 + .name = "cam_cc_mclk4_clk", 1460 + .parent_data = &(const struct clk_parent_data){ 1461 + .hw = &cam_cc_mclk4_clk_src.clkr.hw, 1462 + }, 1463 + .num_parents = 1, 1464 + .flags = CLK_SET_RATE_PARENT, 1465 + .ops = &clk_branch2_ops, 1466 + }, 1467 + }, 1468 + }; 1469 + 1470 + static struct clk_branch cam_cc_soc_ahb_clk = { 1471 + .halt_reg = 0xb140, 1472 + .halt_check = BRANCH_HALT, 1473 + .clkr = { 1474 + .enable_reg = 0xb140, 1475 + .enable_mask = BIT(0), 1476 + .hw.init = &(struct clk_init_data){ 1477 + .name = "cam_cc_soc_ahb_clk", 1478 + .ops = &clk_branch2_ops, 1479 + }, 1480 + }, 1481 + }; 1482 + 1483 + static struct clk_branch cam_cc_sys_tmr_clk = { 1484 + .halt_reg = 0xb0a8, 1485 + .halt_check = BRANCH_HALT, 1486 + .clkr = { 1487 + .enable_reg = 0xb0a8, 1488 + .enable_mask = BIT(0), 1489 + .hw.init = &(struct clk_init_data){ 1490 + .name = "cam_cc_sys_tmr_clk", 1491 + .ops = &clk_branch2_ops, 1492 + }, 1493 + }, 1494 + }; 1495 + 1496 + static struct gdsc bps_gdsc = { 1497 + .gdscr = 0x6004, 1498 + .pd = { 1499 + .name = "bps_gdsc", 1500 + }, 1501 + .pwrsts = PWRSTS_OFF_ON, 1502 + .flags = HW_CTRL, 1503 + }; 1504 + 1505 + static struct gdsc ife_0_gdsc = { 1506 + .gdscr = 0x9004, 1507 + .pd = { 1508 + .name = "ife_0_gdsc", 1509 + }, 1510 + .pwrsts = PWRSTS_OFF_ON, 1511 + }; 1512 + 1513 + static struct gdsc ife_1_gdsc = { 1514 + .gdscr = 0xa004, 1515 + .pd = { 1516 + .name = "ife_1_gdsc", 1517 + }, 1518 + .pwrsts = PWRSTS_OFF_ON, 1519 + }; 1520 + 1521 + static struct gdsc ipe_0_gdsc = { 1522 + .gdscr = 0x7004, 1523 + .pd = { 1524 + .name = "ipe_0_gdsc", 1525 + }, 1526 + .pwrsts = PWRSTS_OFF_ON, 1527 + .flags = HW_CTRL, 1528 + }; 1529 + 1530 + static struct gdsc titan_top_gdsc = { 1531 + .gdscr = 0xb134, 1532 + .pd = { 1533 + .name = "titan_top_gdsc", 1534 + }, 1535 + .pwrsts = PWRSTS_OFF_ON, 1536 + }; 1537 + 1538 + static struct clk_hw *cam_cc_sc7180_hws[] = { 1539 + [CAM_CC_PLL2_OUT_EARLY] = &cam_cc_pll2_out_early.hw, 1540 + }; 1541 + 1542 + static struct clk_regmap *cam_cc_sc7180_clocks[] = { 1543 + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, 1544 + [CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr, 1545 + [CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr, 1546 + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, 1547 + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, 1548 + [CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr, 1549 + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, 1550 + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, 1551 + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, 1552 + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, 1553 + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, 1554 + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, 1555 + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, 1556 + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, 1557 + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, 1558 + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, 1559 + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, 1560 + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, 1561 + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, 1562 + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, 1563 + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, 1564 + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, 1565 + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, 1566 + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, 1567 + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, 1568 + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, 1569 + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, 1570 + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, 1571 + [CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.clkr, 1572 + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, 1573 + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, 1574 + [CAM_CC_IFE_0_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr, 1575 + [CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr, 1576 + [CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr, 1577 + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, 1578 + [CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_clk.clkr, 1579 + [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr, 1580 + [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr, 1581 + [CAM_CC_IFE_1_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr, 1582 + [CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr, 1583 + [CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr, 1584 + [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr, 1585 + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, 1586 + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, 1587 + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, 1588 + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, 1589 + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, 1590 + [CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr, 1591 + [CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr, 1592 + [CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr, 1593 + [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr, 1594 + [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr, 1595 + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, 1596 + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, 1597 + [CAM_CC_LRME_CLK] = &cam_cc_lrme_clk.clkr, 1598 + [CAM_CC_LRME_CLK_SRC] = &cam_cc_lrme_clk_src.clkr, 1599 + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, 1600 + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, 1601 + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, 1602 + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, 1603 + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, 1604 + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, 1605 + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, 1606 + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, 1607 + [CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr, 1608 + [CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr, 1609 + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, 1610 + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, 1611 + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, 1612 + [CAM_CC_PLL2_OUT_AUX] = &cam_cc_pll2_out_aux.clkr, 1613 + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, 1614 + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, 1615 + [CAM_CC_SOC_AHB_CLK] = &cam_cc_soc_ahb_clk.clkr, 1616 + [CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr, 1617 + }; 1618 + static struct gdsc *cam_cc_sc7180_gdscs[] = { 1619 + [BPS_GDSC] = &bps_gdsc, 1620 + [IFE_0_GDSC] = &ife_0_gdsc, 1621 + [IFE_1_GDSC] = &ife_1_gdsc, 1622 + [IPE_0_GDSC] = &ipe_0_gdsc, 1623 + [TITAN_TOP_GDSC] = &titan_top_gdsc, 1624 + }; 1625 + 1626 + static const struct regmap_config cam_cc_sc7180_regmap_config = { 1627 + .reg_bits = 32, 1628 + .reg_stride = 4, 1629 + .val_bits = 32, 1630 + .max_register = 0xd028, 1631 + .fast_io = true, 1632 + }; 1633 + 1634 + static const struct qcom_cc_desc cam_cc_sc7180_desc = { 1635 + .config = &cam_cc_sc7180_regmap_config, 1636 + .clk_hws = cam_cc_sc7180_hws, 1637 + .num_clk_hws = ARRAY_SIZE(cam_cc_sc7180_hws), 1638 + .clks = cam_cc_sc7180_clocks, 1639 + .num_clks = ARRAY_SIZE(cam_cc_sc7180_clocks), 1640 + .gdscs = cam_cc_sc7180_gdscs, 1641 + .num_gdscs = ARRAY_SIZE(cam_cc_sc7180_gdscs), 1642 + }; 1643 + 1644 + static const struct of_device_id cam_cc_sc7180_match_table[] = { 1645 + { .compatible = "qcom,sc7180-camcc" }, 1646 + { } 1647 + }; 1648 + MODULE_DEVICE_TABLE(of, cam_cc_sc7180_match_table); 1649 + 1650 + static int cam_cc_sc7180_probe(struct platform_device *pdev) 1651 + { 1652 + struct regmap *regmap; 1653 + int ret; 1654 + 1655 + pm_runtime_enable(&pdev->dev); 1656 + ret = pm_clk_create(&pdev->dev); 1657 + if (ret < 0) 1658 + return ret; 1659 + 1660 + ret = pm_clk_add(&pdev->dev, "xo"); 1661 + if (ret < 0) { 1662 + dev_err(&pdev->dev, "Failed to acquire XO clock\n"); 1663 + goto disable_pm_runtime; 1664 + } 1665 + 1666 + ret = pm_clk_add(&pdev->dev, "iface"); 1667 + if (ret < 0) { 1668 + dev_err(&pdev->dev, "Failed to acquire iface clock\n"); 1669 + goto disable_pm_runtime; 1670 + } 1671 + 1672 + ret = pm_runtime_get(&pdev->dev); 1673 + if (ret) 1674 + goto destroy_pm_clk; 1675 + 1676 + regmap = qcom_cc_map(pdev, &cam_cc_sc7180_desc); 1677 + if (IS_ERR(regmap)) { 1678 + ret = PTR_ERR(regmap); 1679 + pm_runtime_put(&pdev->dev); 1680 + goto destroy_pm_clk; 1681 + } 1682 + 1683 + clk_fabia_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config); 1684 + clk_fabia_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config); 1685 + clk_agera_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); 1686 + clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); 1687 + 1688 + ret = qcom_cc_really_probe(pdev, &cam_cc_sc7180_desc, regmap); 1689 + pm_runtime_put(&pdev->dev); 1690 + if (ret < 0) { 1691 + dev_err(&pdev->dev, "Failed to register CAM CC clocks\n"); 1692 + goto destroy_pm_clk; 1693 + } 1694 + 1695 + return 0; 1696 + 1697 + destroy_pm_clk: 1698 + pm_clk_destroy(&pdev->dev); 1699 + 1700 + disable_pm_runtime: 1701 + pm_runtime_disable(&pdev->dev); 1702 + 1703 + return ret; 1704 + } 1705 + 1706 + static const struct dev_pm_ops cam_cc_pm_ops = { 1707 + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 1708 + }; 1709 + 1710 + static struct platform_driver cam_cc_sc7180_driver = { 1711 + .probe = cam_cc_sc7180_probe, 1712 + .driver = { 1713 + .name = "cam_cc-sc7180", 1714 + .of_match_table = cam_cc_sc7180_match_table, 1715 + .pm = &cam_cc_pm_ops, 1716 + }, 1717 + }; 1718 + 1719 + static int __init cam_cc_sc7180_init(void) 1720 + { 1721 + return platform_driver_register(&cam_cc_sc7180_driver); 1722 + } 1723 + subsys_initcall(cam_cc_sc7180_init); 1724 + 1725 + static void __exit cam_cc_sc7180_exit(void) 1726 + { 1727 + platform_driver_unregister(&cam_cc_sc7180_driver); 1728 + } 1729 + module_exit(cam_cc_sc7180_exit); 1730 + 1731 + MODULE_DESCRIPTION("QTI CAM_CC SC7180 Driver"); 1732 + MODULE_LICENSE("GPL v2");
+128 -89
drivers/clk/qcom/clk-alpha-pll.c
··· 116 116 [PLL_OFF_OPMODE] = 0x38, 117 117 [PLL_OFF_ALPHA_VAL] = 0x40, 118 118 }, 119 + [CLK_ALPHA_PLL_TYPE_AGERA] = { 120 + [PLL_OFF_L_VAL] = 0x04, 121 + [PLL_OFF_ALPHA_VAL] = 0x08, 122 + [PLL_OFF_USER_CTL] = 0x0c, 123 + [PLL_OFF_CONFIG_CTL] = 0x10, 124 + [PLL_OFF_CONFIG_CTL_U] = 0x14, 125 + [PLL_OFF_TEST_CTL] = 0x18, 126 + [PLL_OFF_TEST_CTL_U] = 0x1c, 127 + [PLL_OFF_STATUS] = 0x2c, 128 + }, 119 129 }; 120 130 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); 121 131 ··· 216 206 217 207 #define wait_for_pll_update_ack_clear(pll) \ 218 208 wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear") 209 + 210 + static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg, 211 + unsigned int val) 212 + { 213 + if (val) 214 + regmap_write(regmap, reg, val); 215 + } 219 216 220 217 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 221 218 const struct alpha_pll_config *config) ··· 1021 1004 { 1022 1005 u32 val, mask; 1023 1006 1024 - if (config->l) 1025 - regmap_write(regmap, PLL_L_VAL(pll), config->l); 1026 - 1027 - if (config->alpha) 1028 - regmap_write(regmap, PLL_FRAC(pll), config->alpha); 1029 - 1030 - if (config->config_ctl_val) 1031 - regmap_write(regmap, PLL_CONFIG_CTL(pll), 1007 + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); 1008 + clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha); 1009 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), 1032 1010 config->config_ctl_val); 1033 - 1034 - if (config->config_ctl_hi_val) 1035 - regmap_write(regmap, PLL_CONFIG_CTL_U(pll), 1011 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), 1036 1012 config->config_ctl_hi_val); 1037 - 1038 - if (config->user_ctl_val) 1039 - regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); 1040 - 1041 - if (config->user_ctl_hi_val) 1042 - regmap_write(regmap, PLL_USER_CTL_U(pll), 1013 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), 1014 + config->user_ctl_val); 1015 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), 1043 1016 config->user_ctl_hi_val); 1044 - 1045 - if (config->test_ctl_val) 1046 - regmap_write(regmap, PLL_TEST_CTL(pll), 1017 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), 1047 1018 config->test_ctl_val); 1048 - 1049 - if (config->test_ctl_hi_val) 1050 - regmap_write(regmap, PLL_TEST_CTL_U(pll), 1019 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), 1051 1020 config->test_ctl_hi_val); 1052 1021 1053 1022 if (config->post_div_mask) { ··· 1148 1145 return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); 1149 1146 } 1150 1147 1148 + /* 1149 + * Due to limited number of bits for fractional rate programming, the 1150 + * rounded up rate could be marginally higher than the requested rate. 1151 + */ 1152 + static int alpha_pll_check_rate_margin(struct clk_hw *hw, 1153 + unsigned long rrate, unsigned long rate) 1154 + { 1155 + unsigned long rate_margin = rate + PLL_RATE_MARGIN; 1156 + 1157 + if (rrate > rate_margin || rrate < rate) { 1158 + pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", 1159 + clk_hw_get_name(hw), rrate, rate, rate_margin); 1160 + return -EINVAL; 1161 + } 1162 + 1163 + return 0; 1164 + } 1165 + 1151 1166 static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, 1152 1167 unsigned long prate) 1153 1168 { 1154 1169 struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1155 1170 u32 l, alpha_width = pll_alpha_width(pll); 1171 + unsigned long rrate; 1172 + int ret; 1156 1173 u64 a; 1157 - unsigned long rrate, max = rate + PLL_RATE_MARGIN; 1158 1174 1159 1175 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); 1160 1176 1161 - /* 1162 - * Due to limited number of bits for fractional rate programming, the 1163 - * rounded up rate could be marginally higher than the requested rate. 1164 - */ 1165 - if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { 1166 - pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n", 1167 - clk_hw_get_name(hw), rrate, rate, max); 1168 - return -EINVAL; 1169 - } 1177 + ret = alpha_pll_check_rate_margin(hw, rrate, rate); 1178 + if (ret < 0) 1179 + return ret; 1170 1180 1171 1181 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); 1172 1182 regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a); ··· 1222 1206 1223 1207 rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw), 1224 1208 &cal_l, &a, alpha_width); 1225 - /* 1226 - * Due to a limited number of bits for fractional rate programming, the 1227 - * rounded up rate could be marginally higher than the requested rate. 1228 - */ 1229 - if (rrate > (cal_freq + PLL_RATE_MARGIN) || rrate < cal_freq) 1230 - return -EINVAL; 1209 + 1210 + ret = alpha_pll_check_rate_margin(hw, rrate, cal_freq); 1211 + if (ret < 0) 1212 + return ret; 1231 1213 1232 1214 /* Setup PLL for calibration frequency */ 1233 1215 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); ··· 1402 1388 void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 1403 1389 const struct alpha_pll_config *config) 1404 1390 { 1405 - if (config->l) 1406 - regmap_write(regmap, PLL_L_VAL(pll), config->l); 1407 - 1391 + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); 1408 1392 regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); 1409 - 1410 - if (config->alpha) 1411 - regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); 1412 - 1413 - if (config->config_ctl_val) 1414 - regmap_write(regmap, PLL_CONFIG_CTL(pll), 1415 - config->config_ctl_val); 1416 - 1417 - if (config->config_ctl_hi_val) 1418 - regmap_write(regmap, PLL_CONFIG_CTL_U(pll), 1419 - config->config_ctl_hi_val); 1420 - 1421 - if (config->config_ctl_hi1_val) 1422 - regmap_write(regmap, PLL_CONFIG_CTL_U1(pll), 1423 - config->config_ctl_hi1_val); 1424 - 1425 - if (config->user_ctl_val) 1426 - regmap_write(regmap, PLL_USER_CTL(pll), 1427 - config->user_ctl_val); 1428 - 1429 - if (config->user_ctl_hi_val) 1430 - regmap_write(regmap, PLL_USER_CTL_U(pll), 1431 - config->user_ctl_hi_val); 1432 - 1433 - if (config->user_ctl_hi1_val) 1434 - regmap_write(regmap, PLL_USER_CTL_U1(pll), 1435 - config->user_ctl_hi1_val); 1436 - 1437 - if (config->test_ctl_val) 1438 - regmap_write(regmap, PLL_TEST_CTL(pll), 1439 - config->test_ctl_val); 1440 - 1441 - if (config->test_ctl_hi_val) 1442 - regmap_write(regmap, PLL_TEST_CTL_U(pll), 1443 - config->test_ctl_hi_val); 1444 - 1445 - if (config->test_ctl_hi1_val) 1446 - regmap_write(regmap, PLL_TEST_CTL_U1(pll), 1447 - config->test_ctl_hi1_val); 1393 + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); 1394 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), 1395 + config->config_ctl_val); 1396 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), 1397 + config->config_ctl_hi_val); 1398 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), 1399 + config->config_ctl_hi1_val); 1400 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), 1401 + config->user_ctl_val); 1402 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), 1403 + config->user_ctl_hi_val); 1404 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), 1405 + config->user_ctl_hi1_val); 1406 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), 1407 + config->test_ctl_val); 1408 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), 1409 + config->test_ctl_hi_val); 1410 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), 1411 + config->test_ctl_hi1_val); 1448 1412 1449 1413 regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS, 1450 1414 PLL_UPDATE_BYPASS); ··· 1482 1490 1483 1491 rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); 1484 1492 1485 - /* 1486 - * Due to a limited number of bits for fractional rate programming, the 1487 - * rounded up rate could be marginally higher than the requested rate. 1488 - */ 1489 - if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) { 1490 - pr_err("Call set rate on the PLL with rounded rates!\n"); 1491 - return -EINVAL; 1492 - } 1493 + ret = alpha_pll_check_rate_margin(hw, rrate, rate); 1494 + if (ret < 0) 1495 + return ret; 1493 1496 1494 1497 regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); 1495 1498 regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); ··· 1548 1561 .set_rate = clk_alpha_pll_postdiv_fabia_set_rate, 1549 1562 }; 1550 1563 EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops); 1564 + 1565 + void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 1566 + const struct alpha_pll_config *config) 1567 + { 1568 + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); 1569 + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); 1570 + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), 1571 + config->user_ctl_val); 1572 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), 1573 + config->config_ctl_val); 1574 + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), 1575 + config->config_ctl_hi_val); 1576 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), 1577 + config->test_ctl_val); 1578 + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), 1579 + config->test_ctl_hi_val); 1580 + } 1581 + EXPORT_SYMBOL_GPL(clk_agera_pll_configure); 1582 + 1583 + static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate, 1584 + unsigned long prate) 1585 + { 1586 + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); 1587 + u32 l, alpha_width = pll_alpha_width(pll); 1588 + int ret; 1589 + unsigned long rrate; 1590 + u64 a; 1591 + 1592 + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); 1593 + ret = alpha_pll_check_rate_margin(hw, rrate, rate); 1594 + if (ret < 0) 1595 + return ret; 1596 + 1597 + /* change L_VAL without having to go through the power on sequence */ 1598 + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); 1599 + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); 1600 + 1601 + if (clk_hw_is_enabled(hw)) 1602 + return wait_for_pll_enable_lock(pll); 1603 + 1604 + return 0; 1605 + } 1606 + 1607 + const struct clk_ops clk_alpha_pll_agera_ops = { 1608 + .enable = clk_alpha_pll_enable, 1609 + .disable = clk_alpha_pll_disable, 1610 + .is_enabled = clk_alpha_pll_is_enabled, 1611 + .recalc_rate = alpha_pll_fabia_recalc_rate, 1612 + .round_rate = clk_alpha_pll_round_rate, 1613 + .set_rate = clk_alpha_pll_agera_set_rate, 1614 + }; 1615 + EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
+4
drivers/clk/qcom/clk-alpha-pll.h
··· 15 15 CLK_ALPHA_PLL_TYPE_FABIA, 16 16 CLK_ALPHA_PLL_TYPE_TRION, 17 17 CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, 18 + CLK_ALPHA_PLL_TYPE_AGERA, 18 19 CLK_ALPHA_PLL_TYPE_MAX, 19 20 }; 20 21 ··· 142 141 extern const struct clk_ops clk_alpha_pll_lucid_ops; 143 142 #define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops 144 143 extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops; 144 + extern const struct clk_ops clk_alpha_pll_agera_ops; 145 145 146 146 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 147 147 const struct alpha_pll_config *config); ··· 150 148 const struct alpha_pll_config *config); 151 149 void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 152 150 const struct alpha_pll_config *config); 151 + void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, 152 + const struct alpha_pll_config *config); 153 153 #define clk_lucid_pll_configure(pll, regmap, config) \ 154 154 clk_trion_pll_configure(pll, regmap, config) 155 155
+56
drivers/clk/qcom/clk-rpmh.c
··· 349 349 DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); 350 350 DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1); 351 351 DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0"); 352 + DEFINE_CLK_RPMH_BCM(sdm845, ce, "CE0"); 352 353 353 354 static struct clk_hw *sdm845_rpmh_clocks[] = { 354 355 [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, ··· 365 364 [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, 366 365 [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, 367 366 [RPMH_IPA_CLK] = &sdm845_ipa.hw, 367 + [RPMH_CE_CLK] = &sdm845_ce.hw, 368 368 }; 369 369 370 370 static const struct clk_rpmh_desc clk_rpmh_sdm845 = { 371 371 .clks = sdm845_rpmh_clocks, 372 372 .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), 373 + }; 374 + 375 + DEFINE_CLK_RPMH_VRM(sdx55, rf_clk1, rf_clk1_ao, "rfclkd1", 1); 376 + DEFINE_CLK_RPMH_VRM(sdx55, rf_clk2, rf_clk2_ao, "rfclkd2", 1); 377 + DEFINE_CLK_RPMH_BCM(sdx55, qpic_clk, "QP0"); 378 + 379 + static struct clk_hw *sdx55_rpmh_clocks[] = { 380 + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, 381 + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, 382 + [RPMH_RF_CLK1] = &sdx55_rf_clk1.hw, 383 + [RPMH_RF_CLK1_A] = &sdx55_rf_clk1_ao.hw, 384 + [RPMH_RF_CLK2] = &sdx55_rf_clk2.hw, 385 + [RPMH_RF_CLK2_A] = &sdx55_rf_clk2_ao.hw, 386 + [RPMH_QPIC_CLK] = &sdx55_qpic_clk.hw, 387 + }; 388 + 389 + static const struct clk_rpmh_desc clk_rpmh_sdx55 = { 390 + .clks = sdx55_rpmh_clocks, 391 + .num_clks = ARRAY_SIZE(sdx55_rpmh_clocks), 373 392 }; 374 393 375 394 static struct clk_hw *sm8150_rpmh_clocks[] = { ··· 451 430 static const struct clk_rpmh_desc clk_rpmh_sm8250 = { 452 431 .clks = sm8250_rpmh_clocks, 453 432 .num_clks = ARRAY_SIZE(sm8250_rpmh_clocks), 433 + }; 434 + 435 + DEFINE_CLK_RPMH_VRM(sm8350, div_clk1, div_clk1_ao, "divclka1", 2); 436 + DEFINE_CLK_RPMH_VRM(sm8350, rf_clk4, rf_clk4_ao, "rfclka4", 1); 437 + DEFINE_CLK_RPMH_VRM(sm8350, rf_clk5, rf_clk5_ao, "rfclka5", 1); 438 + DEFINE_CLK_RPMH_BCM(sm8350, pka, "PKA0"); 439 + DEFINE_CLK_RPMH_BCM(sm8350, hwkm, "HK0"); 440 + 441 + static struct clk_hw *sm8350_rpmh_clocks[] = { 442 + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, 443 + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, 444 + [RPMH_DIV_CLK1] = &sm8350_div_clk1.hw, 445 + [RPMH_DIV_CLK1_A] = &sm8350_div_clk1_ao.hw, 446 + [RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw, 447 + [RPMH_LN_BB_CLK1_A] = &sm8250_ln_bb_clk1_ao.hw, 448 + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, 449 + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, 450 + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, 451 + [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, 452 + [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, 453 + [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, 454 + [RPMH_RF_CLK4] = &sm8350_rf_clk4.hw, 455 + [RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw, 456 + [RPMH_RF_CLK5] = &sm8350_rf_clk5.hw, 457 + [RPMH_RF_CLK5_A] = &sm8350_rf_clk5_ao.hw, 458 + [RPMH_IPA_CLK] = &sdm845_ipa.hw, 459 + [RPMH_PKA_CLK] = &sm8350_pka.hw, 460 + [RPMH_HWKM_CLK] = &sm8350_hwkm.hw, 461 + }; 462 + 463 + static const struct clk_rpmh_desc clk_rpmh_sm8350 = { 464 + .clks = sm8350_rpmh_clocks, 465 + .num_clks = ARRAY_SIZE(sm8350_rpmh_clocks), 454 466 }; 455 467 456 468 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, ··· 571 517 static const struct of_device_id clk_rpmh_match_table[] = { 572 518 { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180}, 573 519 { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, 520 + { .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55}, 574 521 { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150}, 575 522 { .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250}, 523 + { .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350}, 576 524 { } 577 525 }; 578 526 MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
+1
drivers/clk/qcom/dispcc-sm8250.c
··· 963 963 }, 964 964 .pwrsts = PWRSTS_OFF_ON, 965 965 .flags = HW_CTRL, 966 + .supply = "mmcx", 966 967 }; 967 968 968 969 static struct clk_regmap *disp_cc_sm8250_clocks[] = {
+3 -2
drivers/clk/qcom/gcc-sc7180.c
··· 642 642 .name = "gcc_sdcc1_ice_core_clk_src", 643 643 .parent_data = gcc_parent_data_0, 644 644 .num_parents = 4, 645 - .ops = &clk_rcg2_ops, 645 + .ops = &clk_rcg2_floor_ops, 646 646 }, 647 647 }; 648 648 ··· 651 651 F(9600000, P_BI_TCXO, 2, 0, 0), 652 652 F(19200000, P_BI_TCXO, 1, 0, 0), 653 653 F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), 654 + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), 654 655 F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), 655 656 F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0), 656 657 { } ··· 667 666 .name = "gcc_sdcc2_apps_clk_src", 668 667 .parent_data = gcc_parent_data_5, 669 668 .num_parents = 5, 670 - .ops = &clk_rcg2_ops, 669 + .ops = &clk_rcg2_floor_ops, 671 670 }, 672 671 }; 673 672
+1659
drivers/clk/qcom/gcc-sdx55.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2020, Linaro Ltd. 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include <linux/module.h> 9 + #include <linux/platform_device.h> 10 + #include <linux/regmap.h> 11 + 12 + #include <dt-bindings/clock/qcom,gcc-sdx55.h> 13 + 14 + #include "common.h" 15 + #include "clk-alpha-pll.h" 16 + #include "clk-branch.h" 17 + #include "clk-pll.h" 18 + #include "clk-rcg.h" 19 + #include "clk-regmap.h" 20 + #include "gdsc.h" 21 + #include "reset.h" 22 + 23 + enum { 24 + P_BI_TCXO, 25 + P_CORE_BI_PLL_TEST_SE, 26 + P_GPLL0_OUT_EVEN, 27 + P_GPLL0_OUT_MAIN, 28 + P_GPLL4_OUT_EVEN, 29 + P_GPLL5_OUT_MAIN, 30 + P_SLEEP_CLK, 31 + }; 32 + 33 + static const struct pll_vco lucid_vco[] = { 34 + { 249600000, 2000000000, 0 }, 35 + }; 36 + 37 + static struct clk_alpha_pll gpll0 = { 38 + .offset = 0x0, 39 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 40 + .vco_table = lucid_vco, 41 + .num_vco = ARRAY_SIZE(lucid_vco), 42 + .clkr = { 43 + .enable_reg = 0x6d000, 44 + .enable_mask = BIT(0), 45 + .hw.init = &(struct clk_init_data){ 46 + .name = "gpll0", 47 + .parent_data = &(const struct clk_parent_data){ 48 + .fw_name = "bi_tcxo", 49 + }, 50 + .num_parents = 1, 51 + .ops = &clk_alpha_pll_fixed_lucid_ops, 52 + }, 53 + }, 54 + }; 55 + 56 + static const struct clk_div_table post_div_table_lucid_even[] = { 57 + { 0x0, 1 }, 58 + { 0x1, 2 }, 59 + { 0x3, 4 }, 60 + { 0x7, 8 }, 61 + { } 62 + }; 63 + 64 + static struct clk_alpha_pll_postdiv gpll0_out_even = { 65 + .offset = 0x0, 66 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 67 + .post_div_shift = 8, 68 + .post_div_table = post_div_table_lucid_even, 69 + .num_post_div = ARRAY_SIZE(post_div_table_lucid_even), 70 + .width = 4, 71 + .clkr.hw.init = &(struct clk_init_data){ 72 + .name = "gpll0_out_even", 73 + .parent_data = &(const struct clk_parent_data){ 74 + .hw = &gpll0.clkr.hw, 75 + }, 76 + .num_parents = 1, 77 + .ops = &clk_alpha_pll_postdiv_lucid_ops, 78 + }, 79 + }; 80 + 81 + static struct clk_alpha_pll gpll4 = { 82 + .offset = 0x76000, 83 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 84 + .vco_table = lucid_vco, 85 + .num_vco = ARRAY_SIZE(lucid_vco), 86 + .clkr = { 87 + .enable_reg = 0x6d000, 88 + .enable_mask = BIT(4), 89 + .hw.init = &(struct clk_init_data){ 90 + .name = "gpll4", 91 + .parent_data = &(const struct clk_parent_data){ 92 + .fw_name = "bi_tcxo", 93 + }, 94 + .num_parents = 1, 95 + .ops = &clk_alpha_pll_fixed_lucid_ops, 96 + }, 97 + }, 98 + }; 99 + 100 + static struct clk_alpha_pll_postdiv gpll4_out_even = { 101 + .offset = 0x76000, 102 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 103 + .post_div_shift = 8, 104 + .post_div_table = post_div_table_lucid_even, 105 + .num_post_div = ARRAY_SIZE(post_div_table_lucid_even), 106 + .width = 4, 107 + .clkr.hw.init = &(struct clk_init_data){ 108 + .name = "gpll4_out_even", 109 + .parent_data = &(const struct clk_parent_data){ 110 + .hw = &gpll4.clkr.hw, 111 + }, 112 + .num_parents = 1, 113 + .ops = &clk_alpha_pll_postdiv_lucid_ops, 114 + }, 115 + }; 116 + 117 + static struct clk_alpha_pll gpll5 = { 118 + .offset = 0x74000, 119 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 120 + .vco_table = lucid_vco, 121 + .num_vco = ARRAY_SIZE(lucid_vco), 122 + .clkr = { 123 + .enable_reg = 0x6d000, 124 + .enable_mask = BIT(5), 125 + .hw.init = &(struct clk_init_data){ 126 + .name = "gpll5", 127 + .parent_data = &(const struct clk_parent_data){ 128 + .fw_name = "bi_tcxo", 129 + }, 130 + .num_parents = 1, 131 + .ops = &clk_alpha_pll_fixed_lucid_ops, 132 + }, 133 + }, 134 + }; 135 + 136 + static const struct parent_map gcc_parent_map_0[] = { 137 + { P_BI_TCXO, 0 }, 138 + { P_GPLL0_OUT_MAIN, 1 }, 139 + { P_GPLL0_OUT_EVEN, 6 }, 140 + { P_CORE_BI_PLL_TEST_SE, 7 }, 141 + }; 142 + 143 + static const struct clk_parent_data gcc_parents_0[] = { 144 + { .fw_name = "bi_tcxo" }, 145 + { .hw = &gpll0.clkr.hw }, 146 + { .hw = &gpll0_out_even.clkr.hw }, 147 + { .fw_name = "core_bi_pll_test_se" }, 148 + }; 149 + 150 + static const struct clk_parent_data gcc_parents_0_ao[] = { 151 + { .fw_name = "bi_tcxo_ao" }, 152 + { .hw = &gpll0.clkr.hw }, 153 + { .hw = &gpll0_out_even.clkr.hw }, 154 + { .fw_name = "core_bi_pll_test_se" }, 155 + }; 156 + 157 + static const struct parent_map gcc_parent_map_2[] = { 158 + { P_BI_TCXO, 0 }, 159 + { P_GPLL0_OUT_MAIN, 1 }, 160 + { P_GPLL4_OUT_EVEN, 2 }, 161 + { P_GPLL5_OUT_MAIN, 5 }, 162 + { P_GPLL0_OUT_EVEN, 6 }, 163 + { P_CORE_BI_PLL_TEST_SE, 7 }, 164 + }; 165 + 166 + static const struct clk_parent_data gcc_parents_2[] = { 167 + { .fw_name = "bi_tcxo" }, 168 + { .hw = &gpll0.clkr.hw }, 169 + { .hw = &gpll4_out_even.clkr.hw }, 170 + { .hw = &gpll5.clkr.hw }, 171 + { .hw = &gpll0_out_even.clkr.hw }, 172 + { .fw_name = "core_bi_pll_test_se" }, 173 + }; 174 + 175 + static const struct parent_map gcc_parent_map_3[] = { 176 + { P_BI_TCXO, 0 }, 177 + { P_GPLL0_OUT_MAIN, 1 }, 178 + { P_SLEEP_CLK, 5 }, 179 + { P_GPLL0_OUT_EVEN, 6 }, 180 + { P_CORE_BI_PLL_TEST_SE, 7 }, 181 + }; 182 + 183 + static const struct clk_parent_data gcc_parents_3[] = { 184 + { .fw_name = "bi_tcxo" }, 185 + { .hw = &gpll0.clkr.hw }, 186 + { .fw_name = "sleep_clk", .name = "sleep_clk" }, 187 + { .hw = &gpll0_out_even.clkr.hw }, 188 + { .fw_name = "core_bi_pll_test_se" }, 189 + }; 190 + 191 + static const struct parent_map gcc_parent_map_4[] = { 192 + { P_BI_TCXO, 0 }, 193 + { P_SLEEP_CLK, 5 }, 194 + { P_CORE_BI_PLL_TEST_SE, 7 }, 195 + }; 196 + 197 + static const struct clk_parent_data gcc_parents_4[] = { 198 + { .fw_name = "bi_tcxo" }, 199 + { .fw_name = "sleep_clk", .name = "sleep_clk" }, 200 + { .fw_name = "core_bi_pll_test_se" }, 201 + }; 202 + 203 + static const struct parent_map gcc_parent_map_5[] = { 204 + { P_BI_TCXO, 0 }, 205 + { P_GPLL0_OUT_MAIN, 1 }, 206 + { P_GPLL4_OUT_EVEN, 2 }, 207 + { P_GPLL0_OUT_EVEN, 6 }, 208 + { P_CORE_BI_PLL_TEST_SE, 7 }, 209 + }; 210 + 211 + static const struct clk_parent_data gcc_parents_5[] = { 212 + { .fw_name = "bi_tcxo" }, 213 + { .hw = &gpll0.clkr.hw }, 214 + { .hw = &gpll4_out_even.clkr.hw }, 215 + { .hw = &gpll0_out_even.clkr.hw }, 216 + { .fw_name = "core_bi_pll_test_se" }, 217 + }; 218 + 219 + static const struct freq_tbl ftbl_gcc_blsp1_qup1_i2c_apps_clk_src[] = { 220 + F(9600000, P_BI_TCXO, 2, 0, 0), 221 + F(19200000, P_BI_TCXO, 1, 0, 0), 222 + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), 223 + { } 224 + }; 225 + 226 + static struct clk_rcg2 gcc_blsp1_qup1_i2c_apps_clk_src = { 227 + .cmd_rcgr = 0x11024, 228 + .mnd_width = 8, 229 + .hid_width = 5, 230 + .parent_map = gcc_parent_map_0, 231 + .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src, 232 + .clkr.hw.init = &(struct clk_init_data){ 233 + .name = "gcc_blsp1_qup1_i2c_apps_clk_src", 234 + .parent_data = gcc_parents_0, 235 + .num_parents = 4, 236 + .ops = &clk_rcg2_ops, 237 + }, 238 + }; 239 + 240 + static const struct freq_tbl ftbl_gcc_blsp1_qup1_spi_apps_clk_src[] = { 241 + F(960000, P_BI_TCXO, 10, 1, 2), 242 + F(4800000, P_BI_TCXO, 4, 0, 0), 243 + F(9600000, P_BI_TCXO, 2, 0, 0), 244 + F(15000000, P_GPLL0_OUT_EVEN, 5, 1, 4), 245 + F(19200000, P_BI_TCXO, 1, 0, 0), 246 + F(24000000, P_GPLL0_OUT_MAIN, 12.5, 1, 2), 247 + F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2), 248 + F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0), 249 + { } 250 + }; 251 + 252 + static struct clk_rcg2 gcc_blsp1_qup1_spi_apps_clk_src = { 253 + .cmd_rcgr = 0x1100c, 254 + .mnd_width = 8, 255 + .hid_width = 5, 256 + .parent_map = gcc_parent_map_0, 257 + .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src, 258 + .clkr.hw.init = &(struct clk_init_data){ 259 + .name = "gcc_blsp1_qup1_spi_apps_clk_src", 260 + .parent_data = gcc_parents_0, 261 + .num_parents = 4, 262 + .ops = &clk_rcg2_ops, 263 + }, 264 + }; 265 + 266 + static struct clk_rcg2 gcc_blsp1_qup2_i2c_apps_clk_src = { 267 + .cmd_rcgr = 0x13024, 268 + .mnd_width = 8, 269 + .hid_width = 5, 270 + .parent_map = gcc_parent_map_0, 271 + .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src, 272 + .clkr.hw.init = &(struct clk_init_data){ 273 + .name = "gcc_blsp1_qup2_i2c_apps_clk_src", 274 + .parent_data = gcc_parents_0, 275 + .num_parents = 4, 276 + .ops = &clk_rcg2_ops, 277 + }, 278 + }; 279 + 280 + static struct clk_rcg2 gcc_blsp1_qup2_spi_apps_clk_src = { 281 + .cmd_rcgr = 0x1300c, 282 + .mnd_width = 8, 283 + .hid_width = 5, 284 + .parent_map = gcc_parent_map_0, 285 + .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src, 286 + .clkr.hw.init = &(struct clk_init_data){ 287 + .name = "gcc_blsp1_qup2_spi_apps_clk_src", 288 + .parent_data = gcc_parents_0, 289 + .num_parents = 4, 290 + .ops = &clk_rcg2_ops, 291 + }, 292 + }; 293 + 294 + static struct clk_rcg2 gcc_blsp1_qup3_i2c_apps_clk_src = { 295 + .cmd_rcgr = 0x15024, 296 + .mnd_width = 8, 297 + .hid_width = 5, 298 + .parent_map = gcc_parent_map_0, 299 + .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src, 300 + .clkr.hw.init = &(struct clk_init_data){ 301 + .name = "gcc_blsp1_qup3_i2c_apps_clk_src", 302 + .parent_data = gcc_parents_0, 303 + .num_parents = 4, 304 + .ops = &clk_rcg2_ops, 305 + }, 306 + }; 307 + 308 + static struct clk_rcg2 gcc_blsp1_qup3_spi_apps_clk_src = { 309 + .cmd_rcgr = 0x1500c, 310 + .mnd_width = 8, 311 + .hid_width = 5, 312 + .parent_map = gcc_parent_map_0, 313 + .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src, 314 + .clkr.hw.init = &(struct clk_init_data){ 315 + .name = "gcc_blsp1_qup3_spi_apps_clk_src", 316 + .parent_data = gcc_parents_0, 317 + .num_parents = 4, 318 + .ops = &clk_rcg2_ops, 319 + }, 320 + }; 321 + 322 + static struct clk_rcg2 gcc_blsp1_qup4_i2c_apps_clk_src = { 323 + .cmd_rcgr = 0x17024, 324 + .mnd_width = 8, 325 + .hid_width = 5, 326 + .parent_map = gcc_parent_map_0, 327 + .freq_tbl = ftbl_gcc_blsp1_qup1_i2c_apps_clk_src, 328 + .clkr.hw.init = &(struct clk_init_data){ 329 + .name = "gcc_blsp1_qup4_i2c_apps_clk_src", 330 + .parent_data = gcc_parents_0, 331 + .num_parents = 4, 332 + .ops = &clk_rcg2_ops, 333 + }, 334 + }; 335 + 336 + static struct clk_rcg2 gcc_blsp1_qup4_spi_apps_clk_src = { 337 + .cmd_rcgr = 0x1700c, 338 + .mnd_width = 8, 339 + .hid_width = 5, 340 + .parent_map = gcc_parent_map_0, 341 + .freq_tbl = ftbl_gcc_blsp1_qup1_spi_apps_clk_src, 342 + .clkr.hw.init = &(struct clk_init_data){ 343 + .name = "gcc_blsp1_qup4_spi_apps_clk_src", 344 + .parent_data = gcc_parents_0, 345 + .num_parents = 4, 346 + .ops = &clk_rcg2_ops, 347 + }, 348 + }; 349 + 350 + static const struct freq_tbl ftbl_gcc_blsp1_uart1_apps_clk_src[] = { 351 + F(3686400, P_GPLL0_OUT_EVEN, 1, 192, 15625), 352 + F(7372800, P_GPLL0_OUT_EVEN, 1, 384, 15625), 353 + F(9600000, P_BI_TCXO, 2, 0, 0), 354 + F(14745600, P_GPLL0_OUT_EVEN, 1, 768, 15625), 355 + F(16000000, P_GPLL0_OUT_EVEN, 1, 4, 75), 356 + F(19200000, P_BI_TCXO, 1, 0, 0), 357 + F(19354839, P_GPLL0_OUT_MAIN, 15.5, 1, 2), 358 + F(20000000, P_GPLL0_OUT_MAIN, 15, 1, 2), 359 + F(20689655, P_GPLL0_OUT_MAIN, 14.5, 1, 2), 360 + F(21428571, P_GPLL0_OUT_MAIN, 14, 1, 2), 361 + F(22222222, P_GPLL0_OUT_MAIN, 13.5, 1, 2), 362 + F(23076923, P_GPLL0_OUT_MAIN, 13, 1, 2), 363 + F(24000000, P_GPLL0_OUT_MAIN, 5, 1, 5), 364 + F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2), 365 + F(26086957, P_GPLL0_OUT_MAIN, 11.5, 1, 2), 366 + F(27272727, P_GPLL0_OUT_MAIN, 11, 1, 2), 367 + F(28571429, P_GPLL0_OUT_MAIN, 10.5, 1, 2), 368 + F(32000000, P_GPLL0_OUT_MAIN, 1, 4, 75), 369 + F(40000000, P_GPLL0_OUT_MAIN, 15, 0, 0), 370 + F(46400000, P_GPLL0_OUT_MAIN, 1, 29, 375), 371 + F(48000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0), 372 + F(51200000, P_GPLL0_OUT_MAIN, 1, 32, 375), 373 + F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 75), 374 + F(58982400, P_GPLL0_OUT_MAIN, 1, 1536, 15625), 375 + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), 376 + F(63157895, P_GPLL0_OUT_MAIN, 9.5, 0, 0), 377 + { } 378 + }; 379 + 380 + static struct clk_rcg2 gcc_blsp1_uart1_apps_clk_src = { 381 + .cmd_rcgr = 0x1200c, 382 + .mnd_width = 16, 383 + .hid_width = 5, 384 + .parent_map = gcc_parent_map_0, 385 + .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src, 386 + .clkr.hw.init = &(struct clk_init_data){ 387 + .name = "gcc_blsp1_uart1_apps_clk_src", 388 + .parent_data = gcc_parents_0, 389 + .num_parents = 4, 390 + .ops = &clk_rcg2_ops, 391 + }, 392 + }; 393 + 394 + static struct clk_rcg2 gcc_blsp1_uart2_apps_clk_src = { 395 + .cmd_rcgr = 0x1400c, 396 + .mnd_width = 16, 397 + .hid_width = 5, 398 + .parent_map = gcc_parent_map_0, 399 + .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src, 400 + .clkr.hw.init = &(struct clk_init_data){ 401 + .name = "gcc_blsp1_uart2_apps_clk_src", 402 + .parent_data = gcc_parents_0, 403 + .num_parents = 4, 404 + .ops = &clk_rcg2_ops, 405 + }, 406 + }; 407 + 408 + static struct clk_rcg2 gcc_blsp1_uart3_apps_clk_src = { 409 + .cmd_rcgr = 0x1600c, 410 + .mnd_width = 16, 411 + .hid_width = 5, 412 + .parent_map = gcc_parent_map_0, 413 + .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src, 414 + .clkr.hw.init = &(struct clk_init_data){ 415 + .name = "gcc_blsp1_uart3_apps_clk_src", 416 + .parent_data = gcc_parents_0, 417 + .num_parents = 4, 418 + .ops = &clk_rcg2_ops, 419 + }, 420 + }; 421 + 422 + static struct clk_rcg2 gcc_blsp1_uart4_apps_clk_src = { 423 + .cmd_rcgr = 0x1800c, 424 + .mnd_width = 16, 425 + .hid_width = 5, 426 + .parent_map = gcc_parent_map_0, 427 + .freq_tbl = ftbl_gcc_blsp1_uart1_apps_clk_src, 428 + .clkr.hw.init = &(struct clk_init_data){ 429 + .name = "gcc_blsp1_uart4_apps_clk_src", 430 + .parent_data = gcc_parents_0, 431 + .num_parents = 4, 432 + .ops = &clk_rcg2_ops, 433 + }, 434 + }; 435 + 436 + static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = { 437 + F(19200000, P_BI_TCXO, 1, 0, 0), 438 + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), 439 + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), 440 + F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0), 441 + { } 442 + }; 443 + 444 + static struct clk_rcg2 gcc_cpuss_ahb_clk_src = { 445 + .cmd_rcgr = 0x24010, 446 + .mnd_width = 0, 447 + .hid_width = 5, 448 + .parent_map = gcc_parent_map_0, 449 + .freq_tbl = ftbl_gcc_cpuss_ahb_clk_src, 450 + .clkr.hw.init = &(struct clk_init_data){ 451 + .name = "gcc_cpuss_ahb_clk_src", 452 + .parent_data = gcc_parents_0_ao, 453 + .num_parents = 4, 454 + .ops = &clk_rcg2_ops, 455 + }, 456 + }; 457 + 458 + static const struct freq_tbl ftbl_gcc_cpuss_rbcpr_clk_src[] = { 459 + F(19200000, P_BI_TCXO, 1, 0, 0), 460 + { } 461 + }; 462 + 463 + static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = { 464 + .cmd_rcgr = 0x2402c, 465 + .mnd_width = 0, 466 + .hid_width = 5, 467 + .parent_map = gcc_parent_map_0, 468 + .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, 469 + .clkr.hw.init = &(struct clk_init_data){ 470 + .name = "gcc_cpuss_rbcpr_clk_src", 471 + .parent_data = gcc_parents_0_ao, 472 + .num_parents = 4, 473 + .ops = &clk_rcg2_ops, 474 + }, 475 + }; 476 + 477 + static const struct freq_tbl ftbl_gcc_emac_clk_src[] = { 478 + F(2500000, P_BI_TCXO, 1, 25, 192), 479 + F(5000000, P_BI_TCXO, 1, 25, 96), 480 + F(19200000, P_BI_TCXO, 1, 0, 0), 481 + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), 482 + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), 483 + F(250000000, P_GPLL4_OUT_EVEN, 2, 0, 0), 484 + { } 485 + }; 486 + 487 + static struct clk_rcg2 gcc_emac_clk_src = { 488 + .cmd_rcgr = 0x47020, 489 + .mnd_width = 8, 490 + .hid_width = 5, 491 + .parent_map = gcc_parent_map_5, 492 + .freq_tbl = ftbl_gcc_emac_clk_src, 493 + .clkr.hw.init = &(struct clk_init_data){ 494 + .name = "gcc_emac_clk_src", 495 + .parent_data = gcc_parents_5, 496 + .num_parents = 5, 497 + .ops = &clk_rcg2_ops, 498 + }, 499 + }; 500 + 501 + static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = { 502 + F(19200000, P_BI_TCXO, 1, 0, 0), 503 + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), 504 + F(230400000, P_GPLL5_OUT_MAIN, 3.5, 0, 0), 505 + { } 506 + }; 507 + 508 + static struct clk_rcg2 gcc_emac_ptp_clk_src = { 509 + .cmd_rcgr = 0x47038, 510 + .mnd_width = 0, 511 + .hid_width = 5, 512 + .parent_map = gcc_parent_map_2, 513 + .freq_tbl = ftbl_gcc_emac_ptp_clk_src, 514 + .clkr.hw.init = &(struct clk_init_data){ 515 + .name = "gcc_emac_ptp_clk_src", 516 + .parent_data = gcc_parents_2, 517 + .num_parents = 6, 518 + .ops = &clk_rcg2_ops, 519 + }, 520 + }; 521 + 522 + static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { 523 + F(19200000, P_BI_TCXO, 1, 0, 0), 524 + F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0), 525 + F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0), 526 + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), 527 + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 528 + { } 529 + }; 530 + 531 + static struct clk_rcg2 gcc_gp1_clk_src = { 532 + .cmd_rcgr = 0x2b004, 533 + .mnd_width = 8, 534 + .hid_width = 5, 535 + .parent_map = gcc_parent_map_3, 536 + .freq_tbl = ftbl_gcc_gp1_clk_src, 537 + .clkr.hw.init = &(struct clk_init_data){ 538 + .name = "gcc_gp1_clk_src", 539 + .parent_data = gcc_parents_3, 540 + .num_parents = 5, 541 + .ops = &clk_rcg2_ops, 542 + }, 543 + }; 544 + 545 + static struct clk_rcg2 gcc_gp2_clk_src = { 546 + .cmd_rcgr = 0x2c004, 547 + .mnd_width = 8, 548 + .hid_width = 5, 549 + .parent_map = gcc_parent_map_3, 550 + .freq_tbl = ftbl_gcc_gp1_clk_src, 551 + .clkr.hw.init = &(struct clk_init_data){ 552 + .name = "gcc_gp2_clk_src", 553 + .parent_data = gcc_parents_3, 554 + .num_parents = 5, 555 + .ops = &clk_rcg2_ops, 556 + }, 557 + }; 558 + 559 + static struct clk_rcg2 gcc_gp3_clk_src = { 560 + .cmd_rcgr = 0x2d004, 561 + .mnd_width = 8, 562 + .hid_width = 5, 563 + .parent_map = gcc_parent_map_3, 564 + .freq_tbl = ftbl_gcc_gp1_clk_src, 565 + .clkr.hw.init = &(struct clk_init_data){ 566 + .name = "gcc_gp3_clk_src", 567 + .parent_data = gcc_parents_3, 568 + .num_parents = 5, 569 + .ops = &clk_rcg2_ops, 570 + }, 571 + }; 572 + 573 + static struct clk_rcg2 gcc_pcie_aux_phy_clk_src = { 574 + .cmd_rcgr = 0x37034, 575 + .mnd_width = 16, 576 + .hid_width = 5, 577 + .parent_map = gcc_parent_map_4, 578 + .freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src, 579 + .clkr.hw.init = &(struct clk_init_data){ 580 + .name = "gcc_pcie_aux_phy_clk_src", 581 + .parent_data = gcc_parents_4, 582 + .num_parents = 3, 583 + .ops = &clk_rcg2_ops, 584 + }, 585 + }; 586 + 587 + static const struct freq_tbl ftbl_gcc_pcie_rchng_phy_clk_src[] = { 588 + F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0), 589 + { } 590 + }; 591 + 592 + static struct clk_rcg2 gcc_pcie_rchng_phy_clk_src = { 593 + .cmd_rcgr = 0x37050, 594 + .mnd_width = 0, 595 + .hid_width = 5, 596 + .parent_map = gcc_parent_map_3, 597 + .freq_tbl = ftbl_gcc_pcie_rchng_phy_clk_src, 598 + .clkr.hw.init = &(struct clk_init_data){ 599 + .name = "gcc_pcie_rchng_phy_clk_src", 600 + .parent_data = gcc_parents_3, 601 + .num_parents = 5, 602 + .ops = &clk_rcg2_ops, 603 + }, 604 + }; 605 + 606 + static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { 607 + F(9600000, P_BI_TCXO, 2, 0, 0), 608 + F(19200000, P_BI_TCXO, 1, 0, 0), 609 + F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0), 610 + { } 611 + }; 612 + 613 + static struct clk_rcg2 gcc_pdm2_clk_src = { 614 + .cmd_rcgr = 0x19010, 615 + .mnd_width = 0, 616 + .hid_width = 5, 617 + .parent_map = gcc_parent_map_0, 618 + .freq_tbl = ftbl_gcc_pdm2_clk_src, 619 + .clkr.hw.init = &(struct clk_init_data){ 620 + .name = "gcc_pdm2_clk_src", 621 + .parent_data = gcc_parents_0, 622 + .num_parents = 4, 623 + .ops = &clk_rcg2_ops, 624 + }, 625 + }; 626 + 627 + static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { 628 + .cmd_rcgr = 0xf00c, 629 + .mnd_width = 8, 630 + .hid_width = 5, 631 + .parent_map = gcc_parent_map_0, 632 + .freq_tbl = ftbl_gcc_gp1_clk_src, 633 + .clkr.hw.init = &(struct clk_init_data){ 634 + .name = "gcc_sdcc1_apps_clk_src", 635 + .parent_data = gcc_parents_0, 636 + .num_parents = 4, 637 + .ops = &clk_rcg2_ops, 638 + }, 639 + }; 640 + 641 + static const struct freq_tbl ftbl_gcc_usb30_master_clk_src[] = { 642 + F(200000000, P_GPLL0_OUT_EVEN, 1.5, 0, 0), 643 + { } 644 + }; 645 + 646 + static struct clk_rcg2 gcc_usb30_master_clk_src = { 647 + .cmd_rcgr = 0xb024, 648 + .mnd_width = 8, 649 + .hid_width = 5, 650 + .parent_map = gcc_parent_map_0, 651 + .freq_tbl = ftbl_gcc_usb30_master_clk_src, 652 + .clkr.hw.init = &(struct clk_init_data){ 653 + .name = "gcc_usb30_master_clk_src", 654 + .parent_data = gcc_parents_0, 655 + .num_parents = 4, 656 + .ops = &clk_rcg2_ops, 657 + }, 658 + }; 659 + 660 + static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src[] = { 661 + F(19200000, P_BI_TCXO, 1, 0, 0), 662 + { } 663 + }; 664 + 665 + static struct clk_rcg2 gcc_usb30_mock_utmi_clk_src = { 666 + .cmd_rcgr = 0xb03c, 667 + .mnd_width = 0, 668 + .hid_width = 5, 669 + .parent_map = gcc_parent_map_0, 670 + .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk_src, 671 + .clkr.hw.init = &(struct clk_init_data){ 672 + .name = "gcc_usb30_mock_utmi_clk_src", 673 + .parent_data = gcc_parents_0, 674 + .num_parents = 4, 675 + .ops = &clk_rcg2_ops, 676 + }, 677 + }; 678 + 679 + static const struct freq_tbl ftbl_gcc_usb3_phy_aux_clk_src[] = { 680 + F(1000000, P_BI_TCXO, 1, 5, 96), 681 + F(19200000, P_BI_TCXO, 1, 0, 0), 682 + { } 683 + }; 684 + 685 + static struct clk_rcg2 gcc_usb3_phy_aux_clk_src = { 686 + .cmd_rcgr = 0xb064, 687 + .mnd_width = 16, 688 + .hid_width = 5, 689 + .parent_map = gcc_parent_map_4, 690 + .freq_tbl = ftbl_gcc_usb3_phy_aux_clk_src, 691 + .clkr.hw.init = &(struct clk_init_data){ 692 + .name = "gcc_usb3_phy_aux_clk_src", 693 + .parent_data = gcc_parents_4, 694 + .num_parents = 3, 695 + .ops = &clk_rcg2_ops, 696 + }, 697 + }; 698 + 699 + static struct clk_branch gcc_ahb_pcie_link_clk = { 700 + .halt_reg = 0x22004, 701 + .halt_check = BRANCH_HALT, 702 + .clkr = { 703 + .enable_reg = 0x22004, 704 + .enable_mask = BIT(0), 705 + .hw.init = &(struct clk_init_data){ 706 + .name = "gcc_ahb_pcie_link_clk", 707 + .ops = &clk_branch2_ops, 708 + }, 709 + }, 710 + }; 711 + 712 + static struct clk_branch gcc_blsp1_ahb_clk = { 713 + .halt_reg = 0x10004, 714 + .halt_check = BRANCH_HALT_VOTED, 715 + .clkr = { 716 + .enable_reg = 0x6d008, 717 + .enable_mask = BIT(14), 718 + .hw.init = &(struct clk_init_data){ 719 + .name = "gcc_blsp1_ahb_clk", 720 + .ops = &clk_branch2_ops, 721 + }, 722 + }, 723 + }; 724 + 725 + static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { 726 + .halt_reg = 0x11008, 727 + .halt_check = BRANCH_HALT, 728 + .clkr = { 729 + .enable_reg = 0x11008, 730 + .enable_mask = BIT(0), 731 + .hw.init = &(struct clk_init_data){ 732 + .name = "gcc_blsp1_qup1_i2c_apps_clk", 733 + .parent_hws = (const struct clk_hw *[]){ 734 + &gcc_blsp1_qup1_i2c_apps_clk_src.clkr.hw }, 735 + .num_parents = 1, 736 + .flags = CLK_SET_RATE_PARENT, 737 + .ops = &clk_branch2_ops, 738 + }, 739 + }, 740 + }; 741 + 742 + static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { 743 + .halt_reg = 0x11004, 744 + .halt_check = BRANCH_HALT, 745 + .clkr = { 746 + .enable_reg = 0x11004, 747 + .enable_mask = BIT(0), 748 + .hw.init = &(struct clk_init_data){ 749 + .name = "gcc_blsp1_qup1_spi_apps_clk", 750 + .parent_hws = (const struct clk_hw *[]){ 751 + &gcc_blsp1_qup1_spi_apps_clk_src.clkr.hw }, 752 + .num_parents = 1, 753 + .flags = CLK_SET_RATE_PARENT, 754 + .ops = &clk_branch2_ops, 755 + }, 756 + }, 757 + }; 758 + 759 + static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { 760 + .halt_reg = 0x13008, 761 + .halt_check = BRANCH_HALT, 762 + .clkr = { 763 + .enable_reg = 0x13008, 764 + .enable_mask = BIT(0), 765 + .hw.init = &(struct clk_init_data){ 766 + .name = "gcc_blsp1_qup2_i2c_apps_clk", 767 + .parent_hws = (const struct clk_hw *[]){ 768 + &gcc_blsp1_qup2_i2c_apps_clk_src.clkr.hw }, 769 + .num_parents = 1, 770 + .flags = CLK_SET_RATE_PARENT, 771 + .ops = &clk_branch2_ops, 772 + }, 773 + }, 774 + }; 775 + 776 + static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { 777 + .halt_reg = 0x13004, 778 + .halt_check = BRANCH_HALT, 779 + .clkr = { 780 + .enable_reg = 0x13004, 781 + .enable_mask = BIT(0), 782 + .hw.init = &(struct clk_init_data){ 783 + .name = "gcc_blsp1_qup2_spi_apps_clk", 784 + .parent_hws = (const struct clk_hw *[]){ 785 + &gcc_blsp1_qup2_spi_apps_clk_src.clkr.hw }, 786 + .num_parents = 1, 787 + .flags = CLK_SET_RATE_PARENT, 788 + .ops = &clk_branch2_ops, 789 + }, 790 + }, 791 + }; 792 + 793 + static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { 794 + .halt_reg = 0x15008, 795 + .halt_check = BRANCH_HALT, 796 + .clkr = { 797 + .enable_reg = 0x15008, 798 + .enable_mask = BIT(0), 799 + .hw.init = &(struct clk_init_data){ 800 + .name = "gcc_blsp1_qup3_i2c_apps_clk", 801 + .parent_hws = (const struct clk_hw *[]){ 802 + &gcc_blsp1_qup3_i2c_apps_clk_src.clkr.hw }, 803 + .num_parents = 1, 804 + .flags = CLK_SET_RATE_PARENT, 805 + .ops = &clk_branch2_ops, 806 + }, 807 + }, 808 + }; 809 + 810 + static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { 811 + .halt_reg = 0x15004, 812 + .halt_check = BRANCH_HALT, 813 + .clkr = { 814 + .enable_reg = 0x15004, 815 + .enable_mask = BIT(0), 816 + .hw.init = &(struct clk_init_data){ 817 + .name = "gcc_blsp1_qup3_spi_apps_clk", 818 + .parent_hws = (const struct clk_hw *[]){ 819 + &gcc_blsp1_qup3_spi_apps_clk_src.clkr.hw }, 820 + .num_parents = 1, 821 + .flags = CLK_SET_RATE_PARENT, 822 + .ops = &clk_branch2_ops, 823 + }, 824 + }, 825 + }; 826 + 827 + static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { 828 + .halt_reg = 0x17008, 829 + .halt_check = BRANCH_HALT, 830 + .clkr = { 831 + .enable_reg = 0x17008, 832 + .enable_mask = BIT(0), 833 + .hw.init = &(struct clk_init_data){ 834 + .name = "gcc_blsp1_qup4_i2c_apps_clk", 835 + .parent_hws = (const struct clk_hw *[]){ 836 + &gcc_blsp1_qup4_i2c_apps_clk_src.clkr.hw }, 837 + .num_parents = 1, 838 + .flags = CLK_SET_RATE_PARENT, 839 + .ops = &clk_branch2_ops, 840 + }, 841 + }, 842 + }; 843 + 844 + static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { 845 + .halt_reg = 0x17004, 846 + .halt_check = BRANCH_HALT, 847 + .clkr = { 848 + .enable_reg = 0x17004, 849 + .enable_mask = BIT(0), 850 + .hw.init = &(struct clk_init_data){ 851 + .name = "gcc_blsp1_qup4_spi_apps_clk", 852 + .parent_hws = (const struct clk_hw *[]){ 853 + &gcc_blsp1_qup4_spi_apps_clk_src.clkr.hw }, 854 + .num_parents = 1, 855 + .flags = CLK_SET_RATE_PARENT, 856 + .ops = &clk_branch2_ops, 857 + }, 858 + }, 859 + }; 860 + 861 + static struct clk_branch gcc_blsp1_uart1_apps_clk = { 862 + .halt_reg = 0x12004, 863 + .halt_check = BRANCH_HALT, 864 + .clkr = { 865 + .enable_reg = 0x12004, 866 + .enable_mask = BIT(0), 867 + .hw.init = &(struct clk_init_data){ 868 + .name = "gcc_blsp1_uart1_apps_clk", 869 + .parent_hws = (const struct clk_hw *[]){ 870 + &gcc_blsp1_uart1_apps_clk_src.clkr.hw }, 871 + .num_parents = 1, 872 + .flags = CLK_SET_RATE_PARENT, 873 + .ops = &clk_branch2_ops, 874 + }, 875 + }, 876 + }; 877 + 878 + static struct clk_branch gcc_blsp1_uart2_apps_clk = { 879 + .halt_reg = 0x14004, 880 + .halt_check = BRANCH_HALT, 881 + .clkr = { 882 + .enable_reg = 0x14004, 883 + .enable_mask = BIT(0), 884 + .hw.init = &(struct clk_init_data){ 885 + .name = "gcc_blsp1_uart2_apps_clk", 886 + .parent_hws = (const struct clk_hw *[]){ 887 + &gcc_blsp1_uart2_apps_clk_src.clkr.hw }, 888 + .num_parents = 1, 889 + .flags = CLK_SET_RATE_PARENT, 890 + .ops = &clk_branch2_ops, 891 + }, 892 + }, 893 + }; 894 + 895 + static struct clk_branch gcc_blsp1_uart3_apps_clk = { 896 + .halt_reg = 0x16004, 897 + .halt_check = BRANCH_HALT, 898 + .clkr = { 899 + .enable_reg = 0x16004, 900 + .enable_mask = BIT(0), 901 + .hw.init = &(struct clk_init_data){ 902 + .name = "gcc_blsp1_uart3_apps_clk", 903 + .parent_hws = (const struct clk_hw *[]){ 904 + &gcc_blsp1_uart3_apps_clk_src.clkr.hw }, 905 + .num_parents = 1, 906 + .flags = CLK_SET_RATE_PARENT, 907 + .ops = &clk_branch2_ops, 908 + }, 909 + }, 910 + }; 911 + 912 + static struct clk_branch gcc_blsp1_uart4_apps_clk = { 913 + .halt_reg = 0x18004, 914 + .halt_check = BRANCH_HALT, 915 + .clkr = { 916 + .enable_reg = 0x18004, 917 + .enable_mask = BIT(0), 918 + .hw.init = &(struct clk_init_data){ 919 + .name = "gcc_blsp1_uart4_apps_clk", 920 + .parent_hws = (const struct clk_hw *[]){ 921 + &gcc_blsp1_uart4_apps_clk_src.clkr.hw }, 922 + .num_parents = 1, 923 + .flags = CLK_SET_RATE_PARENT, 924 + .ops = &clk_branch2_ops, 925 + }, 926 + }, 927 + }; 928 + 929 + static struct clk_branch gcc_boot_rom_ahb_clk = { 930 + .halt_reg = 0x1c004, 931 + .halt_check = BRANCH_HALT_VOTED, 932 + .hwcg_reg = 0x1c004, 933 + .hwcg_bit = 1, 934 + .clkr = { 935 + .enable_reg = 0x6d008, 936 + .enable_mask = BIT(10), 937 + .hw.init = &(struct clk_init_data){ 938 + .name = "gcc_boot_rom_ahb_clk", 939 + .ops = &clk_branch2_ops, 940 + }, 941 + }, 942 + }; 943 + 944 + static struct clk_branch gcc_ce1_ahb_clk = { 945 + .halt_reg = 0x2100c, 946 + .halt_check = BRANCH_HALT_VOTED, 947 + .hwcg_reg = 0x2100c, 948 + .hwcg_bit = 1, 949 + .clkr = { 950 + .enable_reg = 0x6d008, 951 + .enable_mask = BIT(3), 952 + .hw.init = &(struct clk_init_data){ 953 + .name = "gcc_ce1_ahb_clk", 954 + .ops = &clk_branch2_ops, 955 + }, 956 + }, 957 + }; 958 + 959 + static struct clk_branch gcc_ce1_axi_clk = { 960 + .halt_reg = 0x21008, 961 + .halt_check = BRANCH_HALT_VOTED, 962 + .clkr = { 963 + .enable_reg = 0x6d008, 964 + .enable_mask = BIT(4), 965 + .hw.init = &(struct clk_init_data){ 966 + .name = "gcc_ce1_axi_clk", 967 + .ops = &clk_branch2_ops, 968 + }, 969 + }, 970 + }; 971 + 972 + static struct clk_branch gcc_ce1_clk = { 973 + .halt_reg = 0x21004, 974 + .halt_check = BRANCH_HALT_VOTED, 975 + .clkr = { 976 + .enable_reg = 0x6d008, 977 + .enable_mask = BIT(5), 978 + .hw.init = &(struct clk_init_data){ 979 + .name = "gcc_ce1_clk", 980 + .ops = &clk_branch2_ops, 981 + }, 982 + }, 983 + }; 984 + 985 + static struct clk_branch gcc_cpuss_rbcpr_clk = { 986 + .halt_reg = 0x24008, 987 + .halt_check = BRANCH_HALT, 988 + .clkr = { 989 + .enable_reg = 0x24008, 990 + .enable_mask = BIT(0), 991 + .hw.init = &(struct clk_init_data){ 992 + .name = "gcc_cpuss_rbcpr_clk", 993 + .parent_hws = (const struct clk_hw *[]){ 994 + &gcc_cpuss_rbcpr_clk_src.clkr.hw }, 995 + .num_parents = 1, 996 + .flags = CLK_SET_RATE_PARENT, 997 + .ops = &clk_branch2_ops, 998 + }, 999 + }, 1000 + }; 1001 + 1002 + static struct clk_branch gcc_eth_axi_clk = { 1003 + .halt_reg = 0x4701c, 1004 + .halt_check = BRANCH_HALT, 1005 + .clkr = { 1006 + .enable_reg = 0x4701c, 1007 + .enable_mask = BIT(0), 1008 + .hw.init = &(struct clk_init_data){ 1009 + .name = "gcc_eth_axi_clk", 1010 + .ops = &clk_branch2_ops, 1011 + }, 1012 + }, 1013 + }; 1014 + 1015 + static struct clk_branch gcc_eth_ptp_clk = { 1016 + .halt_reg = 0x47018, 1017 + .halt_check = BRANCH_HALT, 1018 + .clkr = { 1019 + .enable_reg = 0x47018, 1020 + .enable_mask = BIT(0), 1021 + .hw.init = &(struct clk_init_data){ 1022 + .name = "gcc_eth_ptp_clk", 1023 + .parent_hws = (const struct clk_hw *[]){ 1024 + &gcc_emac_ptp_clk_src.clkr.hw }, 1025 + .num_parents = 1, 1026 + .flags = CLK_SET_RATE_PARENT, 1027 + .ops = &clk_branch2_ops, 1028 + }, 1029 + }, 1030 + }; 1031 + 1032 + static struct clk_branch gcc_eth_rgmii_clk = { 1033 + .halt_reg = 0x47010, 1034 + .halt_check = BRANCH_HALT, 1035 + .clkr = { 1036 + .enable_reg = 0x47010, 1037 + .enable_mask = BIT(0), 1038 + .hw.init = &(struct clk_init_data){ 1039 + .name = "gcc_eth_rgmii_clk", 1040 + .parent_hws = (const struct clk_hw *[]){ 1041 + &gcc_emac_clk_src.clkr.hw }, 1042 + .num_parents = 1, 1043 + .flags = CLK_SET_RATE_PARENT, 1044 + .ops = &clk_branch2_ops, 1045 + }, 1046 + }, 1047 + }; 1048 + 1049 + static struct clk_branch gcc_eth_slave_ahb_clk = { 1050 + .halt_reg = 0x47014, 1051 + .halt_check = BRANCH_HALT, 1052 + .clkr = { 1053 + .enable_reg = 0x47014, 1054 + .enable_mask = BIT(0), 1055 + .hw.init = &(struct clk_init_data){ 1056 + .name = "gcc_eth_slave_ahb_clk", 1057 + .ops = &clk_branch2_ops, 1058 + }, 1059 + }, 1060 + }; 1061 + 1062 + static struct clk_branch gcc_gp1_clk = { 1063 + .halt_reg = 0x2b000, 1064 + .halt_check = BRANCH_HALT, 1065 + .clkr = { 1066 + .enable_reg = 0x2b000, 1067 + .enable_mask = BIT(0), 1068 + .hw.init = &(struct clk_init_data){ 1069 + .name = "gcc_gp1_clk", 1070 + .parent_hws = (const struct clk_hw *[]){ 1071 + &gcc_gp1_clk_src.clkr.hw }, 1072 + .num_parents = 1, 1073 + .flags = CLK_SET_RATE_PARENT, 1074 + .ops = &clk_branch2_ops, 1075 + }, 1076 + }, 1077 + }; 1078 + 1079 + static struct clk_branch gcc_gp2_clk = { 1080 + .halt_reg = 0x2c000, 1081 + .halt_check = BRANCH_HALT, 1082 + .clkr = { 1083 + .enable_reg = 0x2c000, 1084 + .enable_mask = BIT(0), 1085 + .hw.init = &(struct clk_init_data){ 1086 + .name = "gcc_gp2_clk", 1087 + .parent_hws = (const struct clk_hw *[]){ 1088 + &gcc_gp2_clk_src.clkr.hw }, 1089 + .num_parents = 1, 1090 + .flags = CLK_SET_RATE_PARENT, 1091 + .ops = &clk_branch2_ops, 1092 + }, 1093 + }, 1094 + }; 1095 + 1096 + static struct clk_branch gcc_gp3_clk = { 1097 + .halt_reg = 0x2d000, 1098 + .halt_check = BRANCH_HALT, 1099 + .clkr = { 1100 + .enable_reg = 0x2d000, 1101 + .enable_mask = BIT(0), 1102 + .hw.init = &(struct clk_init_data){ 1103 + .name = "gcc_gp3_clk", 1104 + .parent_hws = (const struct clk_hw *[]){ 1105 + &gcc_gp3_clk_src.clkr.hw }, 1106 + .num_parents = 1, 1107 + .flags = CLK_SET_RATE_PARENT, 1108 + .ops = &clk_branch2_ops, 1109 + }, 1110 + }, 1111 + }; 1112 + 1113 + static struct clk_branch gcc_pcie_0_clkref_clk = { 1114 + .halt_reg = 0x88004, 1115 + .halt_check = BRANCH_HALT_DELAY, 1116 + .clkr = { 1117 + .enable_reg = 0x88004, 1118 + .enable_mask = BIT(0), 1119 + .hw.init = &(struct clk_init_data){ 1120 + .name = "gcc_pcie_0_clkref_clk", 1121 + .ops = &clk_branch2_ops, 1122 + }, 1123 + }, 1124 + }; 1125 + 1126 + static struct clk_branch gcc_pcie_aux_clk = { 1127 + .halt_reg = 0x37024, 1128 + .halt_check = BRANCH_HALT_DELAY, 1129 + .clkr = { 1130 + .enable_reg = 0x6d010, 1131 + .enable_mask = BIT(3), 1132 + .hw.init = &(struct clk_init_data){ 1133 + .name = "gcc_pcie_aux_clk", 1134 + .ops = &clk_branch2_ops, 1135 + }, 1136 + }, 1137 + }; 1138 + 1139 + static struct clk_branch gcc_pcie_cfg_ahb_clk = { 1140 + .halt_reg = 0x3701c, 1141 + .halt_check = BRANCH_HALT_VOTED, 1142 + .clkr = { 1143 + .enable_reg = 0x6d010, 1144 + .enable_mask = BIT(2), 1145 + .hw.init = &(struct clk_init_data){ 1146 + .name = "gcc_pcie_cfg_ahb_clk", 1147 + .ops = &clk_branch2_ops, 1148 + }, 1149 + }, 1150 + }; 1151 + 1152 + static struct clk_branch gcc_pcie_mstr_axi_clk = { 1153 + .halt_reg = 0x37018, 1154 + .halt_check = BRANCH_HALT_VOTED, 1155 + .clkr = { 1156 + .enable_reg = 0x6d010, 1157 + .enable_mask = BIT(1), 1158 + .hw.init = &(struct clk_init_data){ 1159 + .name = "gcc_pcie_mstr_axi_clk", 1160 + .ops = &clk_branch2_ops, 1161 + }, 1162 + }, 1163 + }; 1164 + 1165 + static struct clk_branch gcc_pcie_pipe_clk = { 1166 + .halt_reg = 0x3702c, 1167 + .halt_check = BRANCH_HALT_DELAY, 1168 + .clkr = { 1169 + .enable_reg = 0x6d010, 1170 + .enable_mask = BIT(4), 1171 + .hw.init = &(struct clk_init_data){ 1172 + .name = "gcc_pcie_pipe_clk", 1173 + .ops = &clk_branch2_ops, 1174 + }, 1175 + }, 1176 + }; 1177 + 1178 + static struct clk_branch gcc_pcie_rchng_phy_clk = { 1179 + .halt_reg = 0x37020, 1180 + .halt_check = BRANCH_HALT_VOTED, 1181 + .clkr = { 1182 + .enable_reg = 0x6d010, 1183 + .enable_mask = BIT(7), 1184 + .hw.init = &(struct clk_init_data){ 1185 + .name = "gcc_pcie_rchng_phy_clk", 1186 + .parent_hws = (const struct clk_hw *[]){ 1187 + &gcc_pcie_rchng_phy_clk_src.clkr.hw }, 1188 + .num_parents = 1, 1189 + .flags = CLK_SET_RATE_PARENT, 1190 + .ops = &clk_branch2_ops, 1191 + }, 1192 + }, 1193 + }; 1194 + 1195 + static struct clk_branch gcc_pcie_sleep_clk = { 1196 + .halt_reg = 0x37028, 1197 + .halt_check = BRANCH_HALT_VOTED, 1198 + .clkr = { 1199 + .enable_reg = 0x6d010, 1200 + .enable_mask = BIT(6), 1201 + .hw.init = &(struct clk_init_data){ 1202 + .name = "gcc_pcie_sleep_clk", 1203 + .parent_hws = (const struct clk_hw *[]){ 1204 + &gcc_pcie_aux_phy_clk_src.clkr.hw }, 1205 + .num_parents = 1, 1206 + .flags = CLK_SET_RATE_PARENT, 1207 + .ops = &clk_branch2_ops, 1208 + }, 1209 + }, 1210 + }; 1211 + 1212 + static struct clk_branch gcc_pcie_slv_axi_clk = { 1213 + .halt_reg = 0x37014, 1214 + .halt_check = BRANCH_HALT_VOTED, 1215 + .hwcg_reg = 0x37014, 1216 + .hwcg_bit = 1, 1217 + .clkr = { 1218 + .enable_reg = 0x6d010, 1219 + .enable_mask = BIT(0), 1220 + .hw.init = &(struct clk_init_data){ 1221 + .name = "gcc_pcie_slv_axi_clk", 1222 + .ops = &clk_branch2_ops, 1223 + }, 1224 + }, 1225 + }; 1226 + 1227 + static struct clk_branch gcc_pcie_slv_q2a_axi_clk = { 1228 + .halt_reg = 0x37010, 1229 + .halt_check = BRANCH_HALT_VOTED, 1230 + .clkr = { 1231 + .enable_reg = 0x6d010, 1232 + .enable_mask = BIT(5), 1233 + .hw.init = &(struct clk_init_data){ 1234 + .name = "gcc_pcie_slv_q2a_axi_clk", 1235 + .ops = &clk_branch2_ops, 1236 + }, 1237 + }, 1238 + }; 1239 + 1240 + static struct clk_branch gcc_pdm2_clk = { 1241 + .halt_reg = 0x1900c, 1242 + .halt_check = BRANCH_HALT, 1243 + .clkr = { 1244 + .enable_reg = 0x1900c, 1245 + .enable_mask = BIT(0), 1246 + .hw.init = &(struct clk_init_data){ 1247 + .name = "gcc_pdm2_clk", 1248 + .parent_hws = (const struct clk_hw *[]){ 1249 + &gcc_pdm2_clk_src.clkr.hw }, 1250 + .num_parents = 1, 1251 + .flags = CLK_SET_RATE_PARENT, 1252 + .ops = &clk_branch2_ops, 1253 + }, 1254 + }, 1255 + }; 1256 + 1257 + static struct clk_branch gcc_pdm_ahb_clk = { 1258 + .halt_reg = 0x19004, 1259 + .halt_check = BRANCH_HALT, 1260 + .hwcg_reg = 0x19004, 1261 + .hwcg_bit = 1, 1262 + .clkr = { 1263 + .enable_reg = 0x19004, 1264 + .enable_mask = BIT(0), 1265 + .hw.init = &(struct clk_init_data){ 1266 + .name = "gcc_pdm_ahb_clk", 1267 + .ops = &clk_branch2_ops, 1268 + }, 1269 + }, 1270 + }; 1271 + 1272 + static struct clk_branch gcc_pdm_xo4_clk = { 1273 + .halt_reg = 0x19008, 1274 + .halt_check = BRANCH_HALT, 1275 + .clkr = { 1276 + .enable_reg = 0x19008, 1277 + .enable_mask = BIT(0), 1278 + .hw.init = &(struct clk_init_data){ 1279 + .name = "gcc_pdm_xo4_clk", 1280 + .ops = &clk_branch2_ops, 1281 + }, 1282 + }, 1283 + }; 1284 + 1285 + static struct clk_branch gcc_sdcc1_ahb_clk = { 1286 + .halt_reg = 0xf008, 1287 + .halt_check = BRANCH_HALT, 1288 + .clkr = { 1289 + .enable_reg = 0xf008, 1290 + .enable_mask = BIT(0), 1291 + .hw.init = &(struct clk_init_data){ 1292 + .name = "gcc_sdcc1_ahb_clk", 1293 + .ops = &clk_branch2_ops, 1294 + }, 1295 + }, 1296 + }; 1297 + 1298 + static struct clk_branch gcc_sdcc1_apps_clk = { 1299 + .halt_reg = 0xf004, 1300 + .halt_check = BRANCH_HALT, 1301 + .clkr = { 1302 + .enable_reg = 0xf004, 1303 + .enable_mask = BIT(0), 1304 + .hw.init = &(struct clk_init_data){ 1305 + .name = "gcc_sdcc1_apps_clk", 1306 + .parent_hws = (const struct clk_hw *[]){ 1307 + &gcc_sdcc1_apps_clk_src.clkr.hw }, 1308 + .num_parents = 1, 1309 + .flags = CLK_SET_RATE_PARENT, 1310 + .ops = &clk_branch2_ops, 1311 + }, 1312 + }, 1313 + }; 1314 + 1315 + static struct clk_branch gcc_usb30_master_clk = { 1316 + .halt_reg = 0xb010, 1317 + .halt_check = BRANCH_HALT, 1318 + .clkr = { 1319 + .enable_reg = 0xb010, 1320 + .enable_mask = BIT(0), 1321 + .hw.init = &(struct clk_init_data){ 1322 + .name = "gcc_usb30_master_clk", 1323 + .parent_hws = (const struct clk_hw *[]){ 1324 + &gcc_usb30_master_clk_src.clkr.hw }, 1325 + .num_parents = 1, 1326 + .flags = CLK_SET_RATE_PARENT, 1327 + .ops = &clk_branch2_ops, 1328 + }, 1329 + }, 1330 + }; 1331 + 1332 + static struct clk_branch gcc_usb30_mock_utmi_clk = { 1333 + .halt_reg = 0xb020, 1334 + .halt_check = BRANCH_HALT, 1335 + .clkr = { 1336 + .enable_reg = 0xb020, 1337 + .enable_mask = BIT(0), 1338 + .hw.init = &(struct clk_init_data){ 1339 + .name = "gcc_usb30_mock_utmi_clk", 1340 + .parent_hws = (const struct clk_hw *[]){ 1341 + &gcc_usb30_mock_utmi_clk_src.clkr.hw }, 1342 + .num_parents = 1, 1343 + .flags = CLK_SET_RATE_PARENT, 1344 + .ops = &clk_branch2_ops, 1345 + }, 1346 + }, 1347 + }; 1348 + 1349 + static struct clk_branch gcc_usb30_mstr_axi_clk = { 1350 + .halt_reg = 0xb014, 1351 + .halt_check = BRANCH_HALT, 1352 + .clkr = { 1353 + .enable_reg = 0xb014, 1354 + .enable_mask = BIT(0), 1355 + .hw.init = &(struct clk_init_data){ 1356 + .name = "gcc_usb30_mstr_axi_clk", 1357 + .ops = &clk_branch2_ops, 1358 + }, 1359 + }, 1360 + }; 1361 + 1362 + static struct clk_branch gcc_usb30_sleep_clk = { 1363 + .halt_reg = 0xb01c, 1364 + .halt_check = BRANCH_HALT, 1365 + .clkr = { 1366 + .enable_reg = 0xb01c, 1367 + .enable_mask = BIT(0), 1368 + .hw.init = &(struct clk_init_data){ 1369 + .name = "gcc_usb30_sleep_clk", 1370 + .ops = &clk_branch2_ops, 1371 + }, 1372 + }, 1373 + }; 1374 + 1375 + static struct clk_branch gcc_usb30_slv_ahb_clk = { 1376 + .halt_reg = 0xb018, 1377 + .halt_check = BRANCH_HALT, 1378 + .clkr = { 1379 + .enable_reg = 0xb018, 1380 + .enable_mask = BIT(0), 1381 + .hw.init = &(struct clk_init_data){ 1382 + .name = "gcc_usb30_slv_ahb_clk", 1383 + .ops = &clk_branch2_ops, 1384 + }, 1385 + }, 1386 + }; 1387 + 1388 + static struct clk_branch gcc_usb3_phy_aux_clk = { 1389 + .halt_reg = 0xb058, 1390 + .halt_check = BRANCH_HALT, 1391 + .clkr = { 1392 + .enable_reg = 0xb058, 1393 + .enable_mask = BIT(0), 1394 + .hw.init = &(struct clk_init_data){ 1395 + .name = "gcc_usb3_phy_aux_clk", 1396 + .parent_hws = (const struct clk_hw *[]){ 1397 + &gcc_usb3_phy_aux_clk_src.clkr.hw }, 1398 + .num_parents = 1, 1399 + .flags = CLK_SET_RATE_PARENT, 1400 + .ops = &clk_branch2_ops, 1401 + }, 1402 + }, 1403 + }; 1404 + 1405 + static struct clk_branch gcc_usb3_phy_pipe_clk = { 1406 + .halt_reg = 0xb05c, 1407 + .halt_check = BRANCH_HALT_DELAY, 1408 + .clkr = { 1409 + .enable_reg = 0xb05c, 1410 + .enable_mask = BIT(0), 1411 + .hw.init = &(struct clk_init_data){ 1412 + .name = "gcc_usb3_phy_pipe_clk", 1413 + .ops = &clk_branch2_ops, 1414 + }, 1415 + }, 1416 + }; 1417 + 1418 + static struct clk_branch gcc_usb3_prim_clkref_clk = { 1419 + .halt_reg = 0x88000, 1420 + .halt_check = BRANCH_HALT_DELAY, 1421 + .clkr = { 1422 + .enable_reg = 0x88000, 1423 + .enable_mask = BIT(0), 1424 + .hw.init = &(struct clk_init_data){ 1425 + .name = "gcc_usb3_prim_clkref_clk", 1426 + .ops = &clk_branch2_ops, 1427 + }, 1428 + }, 1429 + }; 1430 + 1431 + static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { 1432 + .halt_reg = 0xe004, 1433 + .halt_check = BRANCH_HALT, 1434 + .hwcg_reg = 0xe004, 1435 + .hwcg_bit = 1, 1436 + .clkr = { 1437 + .enable_reg = 0xe004, 1438 + .enable_mask = BIT(0), 1439 + .hw.init = &(struct clk_init_data){ 1440 + .name = "gcc_usb_phy_cfg_ahb2phy_clk", 1441 + .ops = &clk_branch2_ops, 1442 + }, 1443 + }, 1444 + }; 1445 + 1446 + static struct clk_branch gcc_xo_pcie_link_clk = { 1447 + .halt_reg = 0x22008, 1448 + .halt_check = BRANCH_HALT, 1449 + .clkr = { 1450 + .enable_reg = 0x22008, 1451 + .enable_mask = BIT(0), 1452 + .hw.init = &(struct clk_init_data){ 1453 + .name = "gcc_xo_pcie_link_clk", 1454 + .ops = &clk_branch2_ops, 1455 + }, 1456 + }, 1457 + }; 1458 + 1459 + static struct gdsc usb30_gdsc = { 1460 + .gdscr = 0x0b004, 1461 + .pd = { 1462 + .name = "usb30_gdsc", 1463 + }, 1464 + .pwrsts = PWRSTS_OFF_ON, 1465 + }; 1466 + 1467 + static struct gdsc pcie_gdsc = { 1468 + .gdscr = 0x37004, 1469 + .pd = { 1470 + .name = "pcie_gdsc", 1471 + }, 1472 + .pwrsts = PWRSTS_OFF_ON, 1473 + }; 1474 + 1475 + static struct gdsc emac_gdsc = { 1476 + .gdscr = 0x47004, 1477 + .pd = { 1478 + .name = "emac_gdsc", 1479 + }, 1480 + .pwrsts = PWRSTS_OFF_ON, 1481 + }; 1482 + 1483 + static struct clk_regmap *gcc_sdx55_clocks[] = { 1484 + [GCC_AHB_PCIE_LINK_CLK] = &gcc_ahb_pcie_link_clk.clkr, 1485 + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, 1486 + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, 1487 + [GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC] = 1488 + &gcc_blsp1_qup1_i2c_apps_clk_src.clkr, 1489 + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, 1490 + [GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC] = 1491 + &gcc_blsp1_qup1_spi_apps_clk_src.clkr, 1492 + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, 1493 + [GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC] = 1494 + &gcc_blsp1_qup2_i2c_apps_clk_src.clkr, 1495 + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, 1496 + [GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC] = 1497 + &gcc_blsp1_qup2_spi_apps_clk_src.clkr, 1498 + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, 1499 + [GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC] = 1500 + &gcc_blsp1_qup3_i2c_apps_clk_src.clkr, 1501 + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, 1502 + [GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC] = 1503 + &gcc_blsp1_qup3_spi_apps_clk_src.clkr, 1504 + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, 1505 + [GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC] = 1506 + &gcc_blsp1_qup4_i2c_apps_clk_src.clkr, 1507 + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, 1508 + [GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC] = 1509 + &gcc_blsp1_qup4_spi_apps_clk_src.clkr, 1510 + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, 1511 + [GCC_BLSP1_UART1_APPS_CLK_SRC] = &gcc_blsp1_uart1_apps_clk_src.clkr, 1512 + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, 1513 + [GCC_BLSP1_UART2_APPS_CLK_SRC] = &gcc_blsp1_uart2_apps_clk_src.clkr, 1514 + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, 1515 + [GCC_BLSP1_UART3_APPS_CLK_SRC] = &gcc_blsp1_uart3_apps_clk_src.clkr, 1516 + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, 1517 + [GCC_BLSP1_UART4_APPS_CLK_SRC] = &gcc_blsp1_uart4_apps_clk_src.clkr, 1518 + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, 1519 + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, 1520 + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, 1521 + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, 1522 + [GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr, 1523 + [GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr, 1524 + [GCC_CPUSS_RBCPR_CLK_SRC] = &gcc_cpuss_rbcpr_clk_src.clkr, 1525 + [GCC_EMAC_CLK_SRC] = &gcc_emac_clk_src.clkr, 1526 + [GCC_EMAC_PTP_CLK_SRC] = &gcc_emac_ptp_clk_src.clkr, 1527 + [GCC_ETH_AXI_CLK] = &gcc_eth_axi_clk.clkr, 1528 + [GCC_ETH_PTP_CLK] = &gcc_eth_ptp_clk.clkr, 1529 + [GCC_ETH_RGMII_CLK] = &gcc_eth_rgmii_clk.clkr, 1530 + [GCC_ETH_SLAVE_AHB_CLK] = &gcc_eth_slave_ahb_clk.clkr, 1531 + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, 1532 + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, 1533 + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, 1534 + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, 1535 + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, 1536 + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, 1537 + [GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr, 1538 + [GCC_PCIE_AUX_CLK] = &gcc_pcie_aux_clk.clkr, 1539 + [GCC_PCIE_AUX_PHY_CLK_SRC] = &gcc_pcie_aux_phy_clk_src.clkr, 1540 + [GCC_PCIE_CFG_AHB_CLK] = &gcc_pcie_cfg_ahb_clk.clkr, 1541 + [GCC_PCIE_MSTR_AXI_CLK] = &gcc_pcie_mstr_axi_clk.clkr, 1542 + [GCC_PCIE_PIPE_CLK] = &gcc_pcie_pipe_clk.clkr, 1543 + [GCC_PCIE_RCHNG_PHY_CLK] = &gcc_pcie_rchng_phy_clk.clkr, 1544 + [GCC_PCIE_RCHNG_PHY_CLK_SRC] = &gcc_pcie_rchng_phy_clk_src.clkr, 1545 + [GCC_PCIE_SLEEP_CLK] = &gcc_pcie_sleep_clk.clkr, 1546 + [GCC_PCIE_SLV_AXI_CLK] = &gcc_pcie_slv_axi_clk.clkr, 1547 + [GCC_PCIE_SLV_Q2A_AXI_CLK] = &gcc_pcie_slv_q2a_axi_clk.clkr, 1548 + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, 1549 + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, 1550 + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, 1551 + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, 1552 + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, 1553 + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, 1554 + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, 1555 + [GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr, 1556 + [GCC_USB30_MASTER_CLK_SRC] = &gcc_usb30_master_clk_src.clkr, 1557 + [GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr, 1558 + [GCC_USB30_MOCK_UTMI_CLK_SRC] = &gcc_usb30_mock_utmi_clk_src.clkr, 1559 + [GCC_USB30_MSTR_AXI_CLK] = &gcc_usb30_mstr_axi_clk.clkr, 1560 + [GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr, 1561 + [GCC_USB30_SLV_AHB_CLK] = &gcc_usb30_slv_ahb_clk.clkr, 1562 + [GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr, 1563 + [GCC_USB3_PHY_AUX_CLK_SRC] = &gcc_usb3_phy_aux_clk_src.clkr, 1564 + [GCC_USB3_PHY_PIPE_CLK] = &gcc_usb3_phy_pipe_clk.clkr, 1565 + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, 1566 + [GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr, 1567 + [GCC_XO_PCIE_LINK_CLK] = &gcc_xo_pcie_link_clk.clkr, 1568 + [GPLL0] = &gpll0.clkr, 1569 + [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, 1570 + [GPLL4] = &gpll4.clkr, 1571 + [GPLL4_OUT_EVEN] = &gpll4_out_even.clkr, 1572 + [GPLL5] = &gpll5.clkr, 1573 + }; 1574 + 1575 + static const struct qcom_reset_map gcc_sdx55_resets[] = { 1576 + [GCC_EMAC_BCR] = { 0x47000 }, 1577 + [GCC_PCIE_BCR] = { 0x37000 }, 1578 + [GCC_PCIE_LINK_DOWN_BCR] = { 0x77000 }, 1579 + [GCC_PCIE_PHY_BCR] = { 0x39000 }, 1580 + [GCC_PCIE_PHY_COM_BCR] = { 0x78004 }, 1581 + [GCC_QUSB2PHY_BCR] = { 0xd000 }, 1582 + [GCC_USB30_BCR] = { 0xb000 }, 1583 + [GCC_USB3_PHY_BCR] = { 0xc000 }, 1584 + [GCC_USB3PHY_PHY_BCR] = { 0xc004 }, 1585 + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0xe000 }, 1586 + }; 1587 + 1588 + static struct gdsc *gcc_sdx55_gdscs[] = { 1589 + [USB30_GDSC] = &usb30_gdsc, 1590 + [PCIE_GDSC] = &pcie_gdsc, 1591 + [EMAC_GDSC] = &emac_gdsc, 1592 + }; 1593 + 1594 + static const struct regmap_config gcc_sdx55_regmap_config = { 1595 + .reg_bits = 32, 1596 + .reg_stride = 4, 1597 + .val_bits = 32, 1598 + .max_register = 0x9b040, 1599 + .fast_io = true, 1600 + }; 1601 + 1602 + static const struct qcom_cc_desc gcc_sdx55_desc = { 1603 + .config = &gcc_sdx55_regmap_config, 1604 + .clks = gcc_sdx55_clocks, 1605 + .num_clks = ARRAY_SIZE(gcc_sdx55_clocks), 1606 + .resets = gcc_sdx55_resets, 1607 + .num_resets = ARRAY_SIZE(gcc_sdx55_resets), 1608 + .gdscs = gcc_sdx55_gdscs, 1609 + .num_gdscs = ARRAY_SIZE(gcc_sdx55_gdscs), 1610 + }; 1611 + 1612 + static const struct of_device_id gcc_sdx55_match_table[] = { 1613 + { .compatible = "qcom,gcc-sdx55" }, 1614 + { } 1615 + }; 1616 + MODULE_DEVICE_TABLE(of, gcc_sdx55_match_table); 1617 + 1618 + static int gcc_sdx55_probe(struct platform_device *pdev) 1619 + { 1620 + struct regmap *regmap; 1621 + 1622 + regmap = qcom_cc_map(pdev, &gcc_sdx55_desc); 1623 + if (IS_ERR(regmap)) 1624 + return PTR_ERR(regmap); 1625 + 1626 + /* 1627 + * Keep the clocks always-ON as they are critical to the functioning 1628 + * of the system: 1629 + * GCC_SYS_NOC_CPUSS_AHB_CLK, GCC_CPUSS_AHB_CLK, GCC_CPUSS_GNOC_CLK 1630 + */ 1631 + regmap_update_bits(regmap, 0x6d008, BIT(0), BIT(0)); 1632 + regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21)); 1633 + regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22)); 1634 + 1635 + return qcom_cc_really_probe(pdev, &gcc_sdx55_desc, regmap); 1636 + } 1637 + 1638 + static struct platform_driver gcc_sdx55_driver = { 1639 + .probe = gcc_sdx55_probe, 1640 + .driver = { 1641 + .name = "gcc-sdx55", 1642 + .of_match_table = gcc_sdx55_match_table, 1643 + }, 1644 + }; 1645 + 1646 + static int __init gcc_sdx55_init(void) 1647 + { 1648 + return platform_driver_register(&gcc_sdx55_driver); 1649 + } 1650 + subsys_initcall(gcc_sdx55_init); 1651 + 1652 + static void __exit gcc_sdx55_exit(void) 1653 + { 1654 + platform_driver_unregister(&gcc_sdx55_driver); 1655 + } 1656 + module_exit(gcc_sdx55_exit); 1657 + 1658 + MODULE_DESCRIPTION("QTI GCC SDX55 Driver"); 1659 + MODULE_LICENSE("GPL v2");
+320
drivers/clk/qcom/lpass-gfm-sm8250.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * LPASS Audio CC and Always ON CC Glitch Free Mux clock driver 4 + * 5 + * Copyright (c) 2020 Linaro Ltd. 6 + * Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> 7 + */ 8 + 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/io.h> 13 + #include <linux/slab.h> 14 + #include <linux/err.h> 15 + #include <linux/pm_clock.h> 16 + #include <linux/pm_runtime.h> 17 + #include <linux/device.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/of_device.h> 20 + #include <dt-bindings/clock/qcom,sm8250-lpass-audiocc.h> 21 + #include <dt-bindings/clock/qcom,sm8250-lpass-aoncc.h> 22 + 23 + struct lpass_gfm { 24 + struct device *dev; 25 + void __iomem *base; 26 + }; 27 + 28 + struct clk_gfm { 29 + unsigned int mux_reg; 30 + unsigned int mux_mask; 31 + struct clk_hw hw; 32 + struct lpass_gfm *priv; 33 + void __iomem *gfm_mux; 34 + }; 35 + 36 + #define GFM_MASK BIT(1) 37 + #define to_clk_gfm(_hw) container_of(_hw, struct clk_gfm, hw) 38 + 39 + static u8 clk_gfm_get_parent(struct clk_hw *hw) 40 + { 41 + struct clk_gfm *clk = to_clk_gfm(hw); 42 + 43 + return readl(clk->gfm_mux) & GFM_MASK; 44 + } 45 + 46 + static int clk_gfm_set_parent(struct clk_hw *hw, u8 index) 47 + { 48 + struct clk_gfm *clk = to_clk_gfm(hw); 49 + unsigned int val; 50 + 51 + val = readl(clk->gfm_mux); 52 + 53 + if (index) 54 + val |= GFM_MASK; 55 + else 56 + val &= ~GFM_MASK; 57 + 58 + writel(val, clk->gfm_mux); 59 + 60 + return 0; 61 + } 62 + 63 + static const struct clk_ops clk_gfm_ops = { 64 + .get_parent = clk_gfm_get_parent, 65 + .set_parent = clk_gfm_set_parent, 66 + .determine_rate = __clk_mux_determine_rate, 67 + }; 68 + 69 + static struct clk_gfm lpass_gfm_va_mclk = { 70 + .mux_reg = 0x20000, 71 + .mux_mask = BIT(0), 72 + .hw.init = &(struct clk_init_data) { 73 + .name = "VA_MCLK", 74 + .ops = &clk_gfm_ops, 75 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 76 + .num_parents = 2, 77 + .parent_data = (const struct clk_parent_data[]){ 78 + { 79 + .index = 0, 80 + .fw_name = "LPASS_CLK_ID_TX_CORE_MCLK", 81 + }, { 82 + .index = 1, 83 + .fw_name = "LPASS_CLK_ID_VA_CORE_MCLK", 84 + }, 85 + }, 86 + }, 87 + }; 88 + 89 + static struct clk_gfm lpass_gfm_tx_npl = { 90 + .mux_reg = 0x20000, 91 + .mux_mask = BIT(0), 92 + .hw.init = &(struct clk_init_data) { 93 + .name = "TX_NPL", 94 + .ops = &clk_gfm_ops, 95 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 96 + .parent_data = (const struct clk_parent_data[]){ 97 + { 98 + .index = 0, 99 + .fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK", 100 + }, { 101 + .index = 1, 102 + .fw_name = "LPASS_CLK_ID_VA_CORE_2X_MCLK", 103 + }, 104 + }, 105 + .num_parents = 2, 106 + }, 107 + }; 108 + 109 + static struct clk_gfm lpass_gfm_wsa_mclk = { 110 + .mux_reg = 0x220d8, 111 + .mux_mask = BIT(0), 112 + .hw.init = &(struct clk_init_data) { 113 + .name = "WSA_MCLK", 114 + .ops = &clk_gfm_ops, 115 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 116 + .parent_data = (const struct clk_parent_data[]){ 117 + { 118 + .index = 0, 119 + .fw_name = "LPASS_CLK_ID_TX_CORE_MCLK", 120 + }, { 121 + .index = 1, 122 + .fw_name = "LPASS_CLK_ID_WSA_CORE_MCLK", 123 + }, 124 + }, 125 + .num_parents = 2, 126 + }, 127 + }; 128 + 129 + static struct clk_gfm lpass_gfm_wsa_npl = { 130 + .mux_reg = 0x220d8, 131 + .mux_mask = BIT(0), 132 + .hw.init = &(struct clk_init_data) { 133 + .name = "WSA_NPL", 134 + .ops = &clk_gfm_ops, 135 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 136 + .parent_data = (const struct clk_parent_data[]){ 137 + { 138 + .index = 0, 139 + .fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK", 140 + }, { 141 + .index = 1, 142 + .fw_name = "LPASS_CLK_ID_WSA_CORE_NPL_MCLK", 143 + }, 144 + }, 145 + .num_parents = 2, 146 + }, 147 + }; 148 + 149 + static struct clk_gfm lpass_gfm_rx_mclk_mclk2 = { 150 + .mux_reg = 0x240d8, 151 + .mux_mask = BIT(0), 152 + .hw.init = &(struct clk_init_data) { 153 + .name = "RX_MCLK_MCLK2", 154 + .ops = &clk_gfm_ops, 155 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 156 + .parent_data = (const struct clk_parent_data[]){ 157 + { 158 + .index = 0, 159 + .fw_name = "LPASS_CLK_ID_TX_CORE_MCLK", 160 + }, { 161 + .index = 1, 162 + .fw_name = "LPASS_CLK_ID_RX_CORE_MCLK", 163 + }, 164 + }, 165 + .num_parents = 2, 166 + }, 167 + }; 168 + 169 + static struct clk_gfm lpass_gfm_rx_npl = { 170 + .mux_reg = 0x240d8, 171 + .mux_mask = BIT(0), 172 + .hw.init = &(struct clk_init_data) { 173 + .name = "RX_NPL", 174 + .ops = &clk_gfm_ops, 175 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 176 + .parent_data = (const struct clk_parent_data[]){ 177 + { 178 + .index = 0, 179 + .fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK", 180 + }, { 181 + .index = 1, 182 + .fw_name = "LPASS_CLK_ID_RX_CORE_NPL_MCLK", 183 + }, 184 + }, 185 + .num_parents = 2, 186 + }, 187 + }; 188 + 189 + static struct clk_gfm *aoncc_gfm_clks[] = { 190 + [LPASS_CDC_VA_MCLK] = &lpass_gfm_va_mclk, 191 + [LPASS_CDC_TX_NPL] = &lpass_gfm_tx_npl, 192 + }; 193 + 194 + static struct clk_hw_onecell_data aoncc_hw_onecell_data = { 195 + .hws = { 196 + [LPASS_CDC_VA_MCLK] = &lpass_gfm_va_mclk.hw, 197 + [LPASS_CDC_TX_NPL] = &lpass_gfm_tx_npl.hw, 198 + }, 199 + .num = ARRAY_SIZE(aoncc_gfm_clks), 200 + }; 201 + 202 + static struct clk_gfm *audiocc_gfm_clks[] = { 203 + [LPASS_CDC_WSA_NPL] = &lpass_gfm_wsa_npl, 204 + [LPASS_CDC_WSA_MCLK] = &lpass_gfm_wsa_mclk, 205 + [LPASS_CDC_RX_NPL] = &lpass_gfm_rx_npl, 206 + [LPASS_CDC_RX_MCLK_MCLK2] = &lpass_gfm_rx_mclk_mclk2, 207 + }; 208 + 209 + static struct clk_hw_onecell_data audiocc_hw_onecell_data = { 210 + .hws = { 211 + [LPASS_CDC_WSA_NPL] = &lpass_gfm_wsa_npl.hw, 212 + [LPASS_CDC_WSA_MCLK] = &lpass_gfm_wsa_mclk.hw, 213 + [LPASS_CDC_RX_NPL] = &lpass_gfm_rx_npl.hw, 214 + [LPASS_CDC_RX_MCLK_MCLK2] = &lpass_gfm_rx_mclk_mclk2.hw, 215 + }, 216 + .num = ARRAY_SIZE(audiocc_gfm_clks), 217 + }; 218 + 219 + struct lpass_gfm_data { 220 + struct clk_hw_onecell_data *onecell_data; 221 + struct clk_gfm **gfm_clks; 222 + }; 223 + 224 + static struct lpass_gfm_data audiocc_data = { 225 + .onecell_data = &audiocc_hw_onecell_data, 226 + .gfm_clks = audiocc_gfm_clks, 227 + }; 228 + 229 + static struct lpass_gfm_data aoncc_data = { 230 + .onecell_data = &aoncc_hw_onecell_data, 231 + .gfm_clks = aoncc_gfm_clks, 232 + }; 233 + 234 + static int lpass_gfm_clk_driver_probe(struct platform_device *pdev) 235 + { 236 + const struct lpass_gfm_data *data; 237 + struct device *dev = &pdev->dev; 238 + struct clk_gfm *gfm; 239 + struct lpass_gfm *cc; 240 + int err, i; 241 + 242 + data = of_device_get_match_data(dev); 243 + if (!data) 244 + return -EINVAL; 245 + 246 + cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL); 247 + if (!cc) 248 + return -ENOMEM; 249 + 250 + cc->base = devm_platform_ioremap_resource(pdev, 0); 251 + if (IS_ERR(cc->base)) 252 + return PTR_ERR(cc->base); 253 + 254 + pm_runtime_enable(dev); 255 + err = pm_clk_create(dev); 256 + if (err) 257 + goto pm_clk_err; 258 + 259 + err = of_pm_clk_add_clks(dev); 260 + if (err < 0) { 261 + dev_dbg(dev, "Failed to get lpass core voting clocks\n"); 262 + goto clk_reg_err; 263 + } 264 + 265 + for (i = 0; i < data->onecell_data->num; i++) { 266 + if (!data->gfm_clks[i]) 267 + continue; 268 + 269 + gfm = data->gfm_clks[i]; 270 + gfm->priv = cc; 271 + gfm->gfm_mux = cc->base; 272 + gfm->gfm_mux = gfm->gfm_mux + data->gfm_clks[i]->mux_reg; 273 + 274 + err = devm_clk_hw_register(dev, &data->gfm_clks[i]->hw); 275 + if (err) 276 + goto clk_reg_err; 277 + 278 + } 279 + 280 + err = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 281 + data->onecell_data); 282 + if (err) 283 + goto clk_reg_err; 284 + 285 + return 0; 286 + 287 + clk_reg_err: 288 + pm_clk_destroy(dev); 289 + pm_clk_err: 290 + pm_runtime_disable(dev); 291 + return err; 292 + } 293 + 294 + static const struct of_device_id lpass_gfm_clk_match_table[] = { 295 + { 296 + .compatible = "qcom,sm8250-lpass-aoncc", 297 + .data = &aoncc_data, 298 + }, 299 + { 300 + .compatible = "qcom,sm8250-lpass-audiocc", 301 + .data = &audiocc_data, 302 + }, 303 + { } 304 + }; 305 + MODULE_DEVICE_TABLE(of, lpass_gfm_clk_match_table); 306 + 307 + static const struct dev_pm_ops lpass_gfm_pm_ops = { 308 + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 309 + }; 310 + 311 + static struct platform_driver lpass_gfm_clk_driver = { 312 + .probe = lpass_gfm_clk_driver_probe, 313 + .driver = { 314 + .name = "lpass-gfm-clk", 315 + .of_match_table = lpass_gfm_clk_match_table, 316 + .pm = &lpass_gfm_pm_ops, 317 + }, 318 + }; 319 + module_platform_driver(lpass_gfm_clk_driver); 320 + MODULE_LICENSE("GPL v2");
+91 -48
drivers/clk/qcom/lpasscorecc-sc7180.c
··· 356 356 .num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs), 357 357 }; 358 358 359 + static void lpass_pm_runtime_disable(void *data) 360 + { 361 + pm_runtime_disable(data); 362 + } 363 + 364 + static void lpass_pm_clk_destroy(void *data) 365 + { 366 + pm_clk_destroy(data); 367 + } 368 + 369 + static int lpass_create_pm_clks(struct platform_device *pdev) 370 + { 371 + int ret; 372 + 373 + pm_runtime_use_autosuspend(&pdev->dev); 374 + pm_runtime_set_autosuspend_delay(&pdev->dev, 500); 375 + pm_runtime_enable(&pdev->dev); 376 + 377 + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev); 378 + if (ret) 379 + return ret; 380 + 381 + ret = pm_clk_create(&pdev->dev); 382 + if (ret) 383 + return ret; 384 + ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev); 385 + if (ret) 386 + return ret; 387 + 388 + ret = pm_clk_add(&pdev->dev, "iface"); 389 + if (ret < 0) 390 + dev_err(&pdev->dev, "failed to acquire iface clock\n"); 391 + 392 + return ret; 393 + } 394 + 359 395 static int lpass_core_cc_sc7180_probe(struct platform_device *pdev) 360 396 { 361 397 const struct qcom_cc_desc *desc; 362 398 struct regmap *regmap; 363 399 int ret; 400 + 401 + ret = lpass_create_pm_clks(pdev); 402 + if (ret) 403 + return ret; 364 404 365 405 lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc"; 366 406 desc = &lpass_audio_hm_sc7180_desc; ··· 426 386 clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap, 427 387 &lpass_lpaaudio_dig_pll_config); 428 388 429 - return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); 389 + ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap); 390 + 391 + pm_runtime_mark_last_busy(&pdev->dev); 392 + pm_runtime_put_autosuspend(&pdev->dev); 393 + 394 + return ret; 430 395 } 431 396 432 397 static int lpass_hm_core_probe(struct platform_device *pdev) 433 398 { 434 399 const struct qcom_cc_desc *desc; 400 + int ret; 401 + 402 + ret = lpass_create_pm_clks(pdev); 403 + if (ret) 404 + return ret; 435 405 436 406 lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core"; 437 407 desc = &lpass_core_hm_sc7180_desc; ··· 449 399 return qcom_cc_probe_by_index(pdev, 0, desc); 450 400 } 451 401 452 - static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { 402 + static const struct of_device_id lpass_hm_sc7180_match_table[] = { 453 403 { 454 404 .compatible = "qcom,sc7180-lpasshm", 455 - .data = lpass_hm_core_probe, 456 405 }, 406 + { } 407 + }; 408 + MODULE_DEVICE_TABLE(of, lpass_hm_sc7180_match_table); 409 + 410 + static const struct of_device_id lpass_core_cc_sc7180_match_table[] = { 457 411 { 458 412 .compatible = "qcom,sc7180-lpasscorecc", 459 - .data = lpass_core_cc_sc7180_probe, 460 413 }, 461 414 { } 462 415 }; 463 416 MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table); 464 - 465 - static int lpass_core_sc7180_probe(struct platform_device *pdev) 466 - { 467 - int (*clk_probe)(struct platform_device *p); 468 - int ret; 469 - 470 - pm_runtime_enable(&pdev->dev); 471 - ret = pm_clk_create(&pdev->dev); 472 - if (ret) 473 - goto disable_pm_runtime; 474 - 475 - ret = pm_clk_add(&pdev->dev, "iface"); 476 - if (ret < 0) { 477 - dev_err(&pdev->dev, "failed to acquire iface clock\n"); 478 - goto destroy_pm_clk; 479 - } 480 - 481 - ret = -EINVAL; 482 - clk_probe = of_device_get_match_data(&pdev->dev); 483 - if (!clk_probe) 484 - goto destroy_pm_clk; 485 - 486 - ret = clk_probe(pdev); 487 - if (ret) 488 - goto destroy_pm_clk; 489 - 490 - return 0; 491 - 492 - destroy_pm_clk: 493 - pm_clk_destroy(&pdev->dev); 494 - 495 - disable_pm_runtime: 496 - pm_runtime_disable(&pdev->dev); 497 - 498 - return ret; 499 - } 500 417 501 418 static const struct dev_pm_ops lpass_core_cc_pm_ops = { 502 419 SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 503 420 }; 504 421 505 422 static struct platform_driver lpass_core_cc_sc7180_driver = { 506 - .probe = lpass_core_sc7180_probe, 423 + .probe = lpass_core_cc_sc7180_probe, 507 424 .driver = { 508 425 .name = "lpass_core_cc-sc7180", 509 426 .of_match_table = lpass_core_cc_sc7180_match_table, ··· 478 461 }, 479 462 }; 480 463 481 - static int __init lpass_core_cc_sc7180_init(void) 482 - { 483 - return platform_driver_register(&lpass_core_cc_sc7180_driver); 484 - } 485 - subsys_initcall(lpass_core_cc_sc7180_init); 464 + static const struct dev_pm_ops lpass_hm_pm_ops = { 465 + SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL) 466 + }; 486 467 487 - static void __exit lpass_core_cc_sc7180_exit(void) 468 + static struct platform_driver lpass_hm_sc7180_driver = { 469 + .probe = lpass_hm_core_probe, 470 + .driver = { 471 + .name = "lpass_hm-sc7180", 472 + .of_match_table = lpass_hm_sc7180_match_table, 473 + .pm = &lpass_hm_pm_ops, 474 + }, 475 + }; 476 + 477 + static int __init lpass_sc7180_init(void) 488 478 { 479 + int ret; 480 + 481 + ret = platform_driver_register(&lpass_core_cc_sc7180_driver); 482 + if (ret) 483 + return ret; 484 + 485 + ret = platform_driver_register(&lpass_hm_sc7180_driver); 486 + if (ret) { 487 + platform_driver_unregister(&lpass_core_cc_sc7180_driver); 488 + return ret; 489 + } 490 + 491 + return 0; 492 + } 493 + subsys_initcall(lpass_sc7180_init); 494 + 495 + static void __exit lpass_sc7180_exit(void) 496 + { 497 + platform_driver_unregister(&lpass_hm_sc7180_driver); 489 498 platform_driver_unregister(&lpass_core_cc_sc7180_driver); 490 499 } 491 - module_exit(lpass_core_cc_sc7180_exit); 500 + module_exit(lpass_sc7180_exit); 492 501 493 502 MODULE_DESCRIPTION("QTI LPASS_CORE_CC SC7180 Driver"); 494 503 MODULE_LICENSE("GPL v2");
+1 -1
drivers/clk/renesas/clk-sh73a0.c
··· 121 121 (phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR); 122 122 123 123 parent_name = phy_no ? "dsi1pck" : "dsi0pck"; 124 - mult = __raw_readl(dsi_reg); 124 + mult = readl(dsi_reg); 125 125 if (!(mult & 0x8000)) 126 126 mult = 1; 127 127 else
+8
drivers/clk/renesas/r8a774a1-cpg-mssr.c
··· 41 41 CLK_S2, 42 42 CLK_S3, 43 43 CLK_SDSRC, 44 + CLK_RPCSRC, 44 45 CLK_RINT, 45 46 46 47 /* Module Clocks */ ··· 68 67 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), 69 68 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), 70 69 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), 70 + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), 71 + 72 + DEF_BASE("rpc", R8A774A1_CLK_RPC, CLK_TYPE_GEN3_RPC, 73 + CLK_RPCSRC), 74 + DEF_BASE("rpcd2", R8A774A1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, 75 + R8A774A1_CLK_RPC), 71 76 72 77 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 73 78 ··· 207 200 DEF_MOD("can-fd", 914, R8A774A1_CLK_S3D2), 208 201 DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), 209 202 DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), 203 + DEF_MOD("rpc-if", 917, R8A774A1_CLK_RPCD2), 210 204 DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), 211 205 DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), 212 206 DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP),
+8
drivers/clk/renesas/r8a774b1-cpg-mssr.c
··· 40 40 CLK_S2, 41 41 CLK_S3, 42 42 CLK_SDSRC, 43 + CLK_RPCSRC, 43 44 CLK_RINT, 44 45 45 46 /* Module Clocks */ ··· 66 65 DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), 67 66 DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), 68 67 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), 68 + DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1), 69 + 70 + DEF_BASE("rpc", R8A774B1_CLK_RPC, CLK_TYPE_GEN3_RPC, 71 + CLK_RPCSRC), 72 + DEF_BASE("rpcd2", R8A774B1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, 73 + R8A774B1_CLK_RPC), 69 74 70 75 DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), 71 76 ··· 203 196 DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2), 204 197 DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4), 205 198 DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4), 199 + DEF_MOD("rpc-if", 917, R8A774B1_CLK_RPCD2), 206 200 DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6), 207 201 DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6), 208 202 DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP),
+9
drivers/clk/renesas/r8a774c0-cpg-mssr.c
··· 44 44 CLK_S2, 45 45 CLK_S3, 46 46 CLK_SDSRC, 47 + CLK_RPCSRC, 47 48 CLK_RINT, 48 49 CLK_OCO, 49 50 ··· 74 73 DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), 75 74 DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), 76 75 DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), 76 + 77 + DEF_FIXED_RPCSRC_E3(".rpcsrc", CLK_RPCSRC, CLK_PLL0, CLK_PLL1), 78 + 79 + DEF_BASE("rpc", R8A774C0_CLK_RPC, CLK_TYPE_GEN3_RPC, 80 + CLK_RPCSRC), 81 + DEF_BASE("rpcd2", R8A774C0_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2, 82 + R8A774C0_CLK_RPC), 77 83 78 84 DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), 79 85 ··· 207 199 DEF_MOD("can-fd", 914, R8A774C0_CLK_S3D2), 208 200 DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4), 209 201 DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4), 202 + DEF_MOD("rpc-if", 917, R8A774C0_CLK_RPCD2), 210 203 DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), 211 204 DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), 212 205 DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP),
+47 -4
drivers/clk/renesas/r8a779a0-cpg-mssr.c
··· 26 26 #include <dt-bindings/clock/r8a779a0-cpg-mssr.h> 27 27 28 28 #include "renesas-cpg-mssr.h" 29 - #include "rcar-gen3-cpg.h" 30 29 31 30 enum rcar_r8a779a0_clk_types { 32 31 CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM, ··· 83 84 DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \ 84 85 .offset = _offset) 85 86 87 + #define DEF_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \ 88 + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_MDSEL, \ 89 + (_parent0) << 16 | (_parent1), \ 90 + .div = (_div0) << 16 | (_div1), .offset = _md) 91 + 92 + #define DEF_OSC(_name, _id, _parent, _div) \ 93 + DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_OSC, _parent, .div = _div) 94 + 86 95 static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = { 87 96 /* External Clock Inputs */ 88 97 DEF_INPUT("extal", CLK_EXTAL), ··· 143 136 DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878), 144 137 DEF_DIV6P1("csi0", R8A779A0_CLK_CSI0, CLK_PLL5_DIV4, 0x880), 145 138 146 - DEF_GEN3_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), 147 - DEF_GEN3_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), 139 + DEF_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8), 140 + DEF_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1), 148 141 }; 149 142 150 143 static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { 144 + DEF_MOD("csi40", 331, R8A779A0_CLK_CSI0), 145 + DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0), 146 + DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0), 147 + DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0), 151 148 DEF_MOD("scif0", 702, R8A779A0_CLK_S1D8), 152 149 DEF_MOD("scif1", 703, R8A779A0_CLK_S1D8), 153 150 DEF_MOD("scif3", 704, R8A779A0_CLK_S1D8), 154 151 DEF_MOD("scif4", 705, R8A779A0_CLK_S1D8), 152 + DEF_MOD("vin00", 730, R8A779A0_CLK_S1D1), 153 + DEF_MOD("vin01", 731, R8A779A0_CLK_S1D1), 154 + DEF_MOD("vin02", 800, R8A779A0_CLK_S1D1), 155 + DEF_MOD("vin03", 801, R8A779A0_CLK_S1D1), 156 + DEF_MOD("vin04", 802, R8A779A0_CLK_S1D1), 157 + DEF_MOD("vin05", 803, R8A779A0_CLK_S1D1), 158 + DEF_MOD("vin06", 804, R8A779A0_CLK_S1D1), 159 + DEF_MOD("vin07", 805, R8A779A0_CLK_S1D1), 160 + DEF_MOD("vin10", 806, R8A779A0_CLK_S1D1), 161 + DEF_MOD("vin11", 807, R8A779A0_CLK_S1D1), 162 + DEF_MOD("vin12", 808, R8A779A0_CLK_S1D1), 163 + DEF_MOD("vin13", 809, R8A779A0_CLK_S1D1), 164 + DEF_MOD("vin14", 810, R8A779A0_CLK_S1D1), 165 + DEF_MOD("vin15", 811, R8A779A0_CLK_S1D1), 166 + DEF_MOD("vin16", 812, R8A779A0_CLK_S1D1), 167 + DEF_MOD("vin17", 813, R8A779A0_CLK_S1D1), 168 + DEF_MOD("vin20", 814, R8A779A0_CLK_S1D1), 169 + DEF_MOD("vin21", 815, R8A779A0_CLK_S1D1), 170 + DEF_MOD("vin22", 816, R8A779A0_CLK_S1D1), 171 + DEF_MOD("vin23", 817, R8A779A0_CLK_S1D1), 172 + DEF_MOD("vin24", 818, R8A779A0_CLK_S1D1), 173 + DEF_MOD("vin25", 819, R8A779A0_CLK_S1D1), 174 + DEF_MOD("vin26", 820, R8A779A0_CLK_S1D1), 175 + DEF_MOD("vin27", 821, R8A779A0_CLK_S1D1), 176 + DEF_MOD("vin30", 822, R8A779A0_CLK_S1D1), 177 + DEF_MOD("vin31", 823, R8A779A0_CLK_S1D1), 178 + DEF_MOD("vin32", 824, R8A779A0_CLK_S1D1), 179 + DEF_MOD("vin33", 825, R8A779A0_CLK_S1D1), 180 + DEF_MOD("vin34", 826, R8A779A0_CLK_S1D1), 181 + DEF_MOD("vin35", 827, R8A779A0_CLK_S1D1), 182 + DEF_MOD("vin36", 828, R8A779A0_CLK_S1D1), 183 + DEF_MOD("vin37", 829, R8A779A0_CLK_S1D1), 155 184 }; 156 185 157 186 static spinlock_t cpg_lock; ··· 196 153 static unsigned int cpg_clk_extalr __initdata; 197 154 static u32 cpg_mode __initdata; 198 155 199 - struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev, 156 + static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev, 200 157 const struct cpg_core_clk *core, const struct cpg_mssr_info *info, 201 158 struct clk **clks, void __iomem *base, 202 159 struct raw_notifier_head *notifiers)
+53 -26
drivers/clk/renesas/rcar-gen3-cpg.c
··· 224 224 #define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK) 225 225 #define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0) 226 226 227 - #define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \ 227 + #define CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) \ 228 228 { \ 229 229 .val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \ 230 - ((stp_ck) ? CPG_SD_STP_CK : 0) | \ 231 230 ((sd_srcfc) << 2) | \ 232 231 ((sd_fc) << 0), \ 233 232 .div = (sd_div), \ ··· 246 247 }; 247 248 248 249 /* SDn divider 249 - * sd_srcfc sd_fc div 250 - * stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc 251 - *------------------------------------------------------------------- 252 - * 0 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP) 253 - * 0 0 1 (2) 1 (4) 8 : SDR50 254 - * 1 0 2 (4) 1 (4) 16 : HS / SDR25 255 - * 1 0 3 (8) 1 (4) 32 : NS / SDR12 256 - * 1 0 4 (16) 1 (4) 64 257 - * 0 0 0 (1) 0 (2) 2 258 - * 0 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP) 259 - * 1 0 2 (4) 0 (2) 8 260 - * 1 0 3 (8) 0 (2) 16 261 - * 1 0 4 (16) 0 (2) 32 250 + * sd_srcfc sd_fc div 251 + * stp_hck (div) (div) = sd_srcfc x sd_fc 252 + *--------------------------------------------------------- 253 + * 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP) 254 + * 0 1 (2) 1 (4) 8 : SDR50 255 + * 1 2 (4) 1 (4) 16 : HS / SDR25 256 + * 1 3 (8) 1 (4) 32 : NS / SDR12 257 + * 1 4 (16) 1 (4) 64 258 + * 0 0 (1) 0 (2) 2 259 + * 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP) 260 + * 1 2 (4) 0 (2) 8 261 + * 1 3 (8) 0 (2) 16 262 + * 1 4 (16) 0 (2) 32 262 263 * 263 264 * NOTE: There is a quirk option to ignore the first row of the dividers 264 265 * table when searching for suitable settings. This is because HS400 on 265 266 * early ES versions of H3 and M3-W requires a specific setting to work. 266 267 */ 267 268 static const struct sd_div_table cpg_sd_div_table[] = { 268 - /* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */ 269 - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4), 270 - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8), 271 - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16), 272 - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32), 273 - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64), 274 - CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2), 275 - CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4), 276 - CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8), 277 - CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16), 278 - CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32), 269 + /* CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) */ 270 + CPG_SD_DIV_TABLE_DATA(0, 0, 1, 4), 271 + CPG_SD_DIV_TABLE_DATA(0, 1, 1, 8), 272 + CPG_SD_DIV_TABLE_DATA(1, 2, 1, 16), 273 + CPG_SD_DIV_TABLE_DATA(1, 3, 1, 32), 274 + CPG_SD_DIV_TABLE_DATA(1, 4, 1, 64), 275 + CPG_SD_DIV_TABLE_DATA(0, 0, 0, 2), 276 + CPG_SD_DIV_TABLE_DATA(0, 1, 0, 4), 277 + CPG_SD_DIV_TABLE_DATA(1, 2, 0, 8), 278 + CPG_SD_DIV_TABLE_DATA(1, 3, 0, 16), 279 + CPG_SD_DIV_TABLE_DATA(1, 4, 0, 32), 279 280 }; 280 281 281 282 #define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw) ··· 694 695 base + CPG_RPCCKCR, 3, 2, 0, 695 696 cpg_rpcsrc_div_table, 696 697 &cpg_lock); 698 + 699 + case CLK_TYPE_GEN3_E3_RPCSRC: 700 + /* 701 + * Register RPCSRC as fixed factor clock based on the 702 + * MD[4:1] pins and CPG_RPCCKCR[4:3] register value for 703 + * which has been set prior to booting the kernel. 704 + */ 705 + value = (readl(base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3; 706 + 707 + switch (value) { 708 + case 0: 709 + div = 5; 710 + break; 711 + case 1: 712 + div = 3; 713 + break; 714 + case 2: 715 + parent = clks[core->parent >> 16]; 716 + if (IS_ERR(parent)) 717 + return ERR_CAST(parent); 718 + div = core->div; 719 + break; 720 + case 3: 721 + default: 722 + div = 2; 723 + break; 724 + } 725 + break; 697 726 698 727 case CLK_TYPE_GEN3_RPC: 699 728 return cpg_rpc_clk_register(core->name, base,
+5
drivers/clk/renesas/rcar-gen3-cpg.h
··· 24 24 CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */ 25 25 CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */ 26 26 CLK_TYPE_GEN3_RPCSRC, 27 + CLK_TYPE_GEN3_E3_RPCSRC, 27 28 CLK_TYPE_GEN3_RPC, 28 29 CLK_TYPE_GEN3_RPCD2, 29 30 ··· 54 53 55 54 #define DEF_GEN3_Z(_name, _id, _type, _parent, _div, _offset) \ 56 55 DEF_BASE(_name, _id, _type, _parent, .div = _div, .offset = _offset) 56 + 57 + #define DEF_FIXED_RPCSRC_E3(_name, _id, _parent0, _parent1) \ 58 + DEF_BASE(_name, _id, CLK_TYPE_GEN3_E3_RPCSRC, \ 59 + (_parent0) << 16 | (_parent1), .div = 8) 57 60 58 61 struct rcar_gen3_cpg_pll_config { 59 62 u8 extal_div;
+1 -1
drivers/clk/renesas/rcar-usb2-clock-sel.c
··· 160 160 if (ret < 0) 161 161 return ret; 162 162 163 - priv->rsts = devm_reset_control_array_get(dev, true, false); 163 + priv->rsts = devm_reset_control_array_get_shared(dev); 164 164 if (IS_ERR(priv->rsts)) 165 165 return PTR_ERR(priv->rsts); 166 166
+2 -1
drivers/clk/renesas/renesas-cpg-mssr.c
··· 119 119 }; 120 120 121 121 /** 122 - * Clock Pulse Generator / Module Standby and Software Reset Private Data 122 + * struct cpg_mssr_priv - Clock Pulse Generator / Module Standby 123 + * and Software Reset Private Data 123 124 * 124 125 * @rcdev: Optional reset controller entity 125 126 * @dev: CPG/MSSR device
+11 -1
drivers/clk/rockchip/Kconfig
··· 11 11 if COMMON_CLK_ROCKCHIP 12 12 config CLK_PX30 13 13 bool "Rockchip PX30 clock controller support" 14 + depends on (ARM64 || COMPILE_TEST) 14 15 default y 15 16 help 16 17 Build the driver for PX30 Clock Driver. 17 18 18 19 config CLK_RV110X 19 20 bool "Rockchip RV110x clock controller support" 21 + depends on (ARM || COMPILE_TEST) 20 22 default y 21 23 help 22 24 Build the driver for RV110x Clock Driver. 23 25 24 26 config CLK_RK3036 25 27 bool "Rockchip RK3036 clock controller support" 28 + depends on (ARM || COMPILE_TEST) 26 29 default y 27 30 help 28 31 Build the driver for RK3036 Clock Driver. 29 32 30 33 config CLK_RK312X 31 34 bool "Rockchip RK312x clock controller support" 35 + depends on (ARM || COMPILE_TEST) 32 36 default y 33 37 help 34 38 Build the driver for RK312x Clock Driver. 35 39 36 40 config CLK_RK3188 37 41 bool "Rockchip RK3188 clock controller support" 42 + depends on (ARM || COMPILE_TEST) 38 43 default y 39 44 help 40 45 Build the driver for RK3188 Clock Driver. 41 46 42 47 config CLK_RK322X 43 48 bool "Rockchip RK322x clock controller support" 49 + depends on (ARM || COMPILE_TEST) 44 50 default y 45 51 help 46 52 Build the driver for RK322x Clock Driver. 47 53 48 54 config CLK_RK3288 49 55 bool "Rockchip RK3288 clock controller support" 50 - depends on ARM 56 + depends on (ARM || COMPILE_TEST) 51 57 default y 52 58 help 53 59 Build the driver for RK3288 Clock Driver. 54 60 55 61 config CLK_RK3308 56 62 bool "Rockchip RK3308 clock controller support" 63 + depends on (ARM64 || COMPILE_TEST) 57 64 default y 58 65 help 59 66 Build the driver for RK3308 Clock Driver. 60 67 61 68 config CLK_RK3328 62 69 bool "Rockchip RK3328 clock controller support" 70 + depends on (ARM64 || COMPILE_TEST) 63 71 default y 64 72 help 65 73 Build the driver for RK3328 Clock Driver. 66 74 67 75 config CLK_RK3368 68 76 bool "Rockchip RK3368 clock controller support" 77 + depends on (ARM64 || COMPILE_TEST) 69 78 default y 70 79 help 71 80 Build the driver for RK3368 Clock Driver. 72 81 73 82 config CLK_RK3399 74 83 tristate "Rockchip RK3399 clock controller support" 84 + depends on (ARM64 || COMPILE_TEST) 75 85 default y 76 86 help 77 87 Build the driver for RK3399 Clock Driver.
+18 -17
drivers/clk/rockchip/clk-rk3188.c
··· 255 255 RK2928_CLKSEL_CON(5), 8, 2, MFLAGS); 256 256 257 257 static struct rockchip_clk_branch common_uart0_fracmux __initdata = 258 - MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, 0, 258 + MUX(SCLK_UART0, "sclk_uart0", mux_sclk_uart0_p, CLK_SET_RATE_PARENT, 259 259 RK2928_CLKSEL_CON(13), 8, 2, MFLAGS); 260 260 261 261 static struct rockchip_clk_branch common_uart1_fracmux __initdata = 262 - MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, 0, 262 + MUX(SCLK_UART1, "sclk_uart1", mux_sclk_uart1_p, CLK_SET_RATE_PARENT, 263 263 RK2928_CLKSEL_CON(14), 8, 2, MFLAGS); 264 264 265 265 static struct rockchip_clk_branch common_uart2_fracmux __initdata = 266 - MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, 0, 266 + MUX(SCLK_UART2, "sclk_uart2", mux_sclk_uart2_p, CLK_SET_RATE_PARENT, 267 267 RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); 268 268 269 269 static struct rockchip_clk_branch common_uart3_fracmux __initdata = 270 - MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, 0, 270 + MUX(SCLK_UART3, "sclk_uart3", mux_sclk_uart3_p, CLK_SET_RATE_PARENT, 271 271 RK2928_CLKSEL_CON(16), 8, 2, MFLAGS); 272 272 273 273 static struct rockchip_clk_branch common_clk_branches[] __initdata = { ··· 408 408 COMPOSITE_NOMUX(0, "uart0_pre", "uart_src", 0, 409 409 RK2928_CLKSEL_CON(13), 0, 7, DFLAGS, 410 410 RK2928_CLKGATE_CON(1), 8, GFLAGS), 411 - COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", 0, 411 + COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_pre", CLK_SET_RATE_PARENT, 412 412 RK2928_CLKSEL_CON(17), 0, 413 413 RK2928_CLKGATE_CON(1), 9, GFLAGS, 414 414 &common_uart0_fracmux), 415 415 COMPOSITE_NOMUX(0, "uart1_pre", "uart_src", 0, 416 416 RK2928_CLKSEL_CON(14), 0, 7, DFLAGS, 417 417 RK2928_CLKGATE_CON(1), 10, GFLAGS), 418 - COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", 0, 418 + COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_pre", CLK_SET_RATE_PARENT, 419 419 RK2928_CLKSEL_CON(18), 0, 420 420 RK2928_CLKGATE_CON(1), 11, GFLAGS, 421 421 &common_uart1_fracmux), 422 422 COMPOSITE_NOMUX(0, "uart2_pre", "uart_src", 0, 423 423 RK2928_CLKSEL_CON(15), 0, 7, DFLAGS, 424 424 RK2928_CLKGATE_CON(1), 12, GFLAGS), 425 - COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", 0, 425 + COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_pre", CLK_SET_RATE_PARENT, 426 426 RK2928_CLKSEL_CON(19), 0, 427 427 RK2928_CLKGATE_CON(1), 13, GFLAGS, 428 428 &common_uart2_fracmux), 429 429 COMPOSITE_NOMUX(0, "uart3_pre", "uart_src", 0, 430 430 RK2928_CLKSEL_CON(16), 0, 7, DFLAGS, 431 431 RK2928_CLKGATE_CON(1), 14, GFLAGS), 432 - COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", 0, 432 + COMPOSITE_FRACMUX(0, "uart3_frac", "uart3_pre", CLK_SET_RATE_PARENT, 433 433 RK2928_CLKSEL_CON(20), 0, 434 434 RK2928_CLKGATE_CON(1), 15, GFLAGS, 435 435 &common_uart3_fracmux), ··· 449 449 450 450 /* hclk_cpu gates */ 451 451 GATE(HCLK_ROM, "hclk_rom", "hclk_cpu", 0, RK2928_CLKGATE_CON(5), 6, GFLAGS), 452 - GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), 453 452 GATE(HCLK_SPDIF, "hclk_spdif", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 1, GFLAGS), 454 453 GATE(0, "hclk_cpubus", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 8, GFLAGS), 455 454 /* hclk_ahb2apb is part of a clk branch */ ··· 542 543 }; 543 544 544 545 static struct rockchip_clk_branch rk3066a_i2s0_fracmux __initdata = 545 - MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, 0, 546 + MUX(SCLK_I2S0, "sclk_i2s0", mux_sclk_i2s0_p, CLK_SET_RATE_PARENT, 546 547 RK2928_CLKSEL_CON(2), 8, 2, MFLAGS); 547 548 548 549 static struct rockchip_clk_branch rk3066a_i2s1_fracmux __initdata = 549 - MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, 0, 550 + MUX(SCLK_I2S1, "sclk_i2s1", mux_sclk_i2s1_p, CLK_SET_RATE_PARENT, 550 551 RK2928_CLKSEL_CON(3), 8, 2, MFLAGS); 551 552 552 553 static struct rockchip_clk_branch rk3066a_i2s2_fracmux __initdata = 553 - MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, 0, 554 + MUX(SCLK_I2S2, "sclk_i2s2", mux_sclk_i2s2_p, CLK_SET_RATE_PARENT, 554 555 RK2928_CLKSEL_CON(4), 8, 2, MFLAGS); 555 556 556 557 static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = { ··· 614 615 COMPOSITE_NOMUX(0, "i2s0_pre", "i2s_src", 0, 615 616 RK2928_CLKSEL_CON(2), 0, 7, DFLAGS, 616 617 RK2928_CLKGATE_CON(0), 7, GFLAGS), 617 - COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", 0, 618 + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_pre", CLK_SET_RATE_PARENT, 618 619 RK2928_CLKSEL_CON(6), 0, 619 620 RK2928_CLKGATE_CON(0), 8, GFLAGS, 620 621 &rk3066a_i2s0_fracmux), 621 622 COMPOSITE_NOMUX(0, "i2s1_pre", "i2s_src", 0, 622 623 RK2928_CLKSEL_CON(3), 0, 7, DFLAGS, 623 624 RK2928_CLKGATE_CON(0), 9, GFLAGS), 624 - COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", 0, 625 + COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_pre", CLK_SET_RATE_PARENT, 625 626 RK2928_CLKSEL_CON(7), 0, 626 627 RK2928_CLKGATE_CON(0), 10, GFLAGS, 627 628 &rk3066a_i2s1_fracmux), 628 629 COMPOSITE_NOMUX(0, "i2s2_pre", "i2s_src", 0, 629 630 RK2928_CLKSEL_CON(4), 0, 7, DFLAGS, 630 631 RK2928_CLKGATE_CON(0), 11, GFLAGS), 631 - COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", 0, 632 + COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_pre", CLK_SET_RATE_PARENT, 632 633 RK2928_CLKSEL_CON(8), 0, 633 634 RK2928_CLKGATE_CON(0), 12, GFLAGS, 634 635 &rk3066a_i2s2_fracmux), 635 636 636 - GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), 637 - GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 637 + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 638 + GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), 639 + GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), 638 640 GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), 639 641 GATE(HCLK_HDMI, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), 640 642 ··· 728 728 RK2928_CLKGATE_CON(0), 10, GFLAGS, 729 729 &rk3188_i2s0_fracmux), 730 730 731 + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), 731 732 GATE(0, "hclk_imem0", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), 732 733 GATE(0, "hclk_imem1", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 15, GFLAGS), 733 734
+1 -2
drivers/clk/rockchip/clk.c
··· 603 603 for (i = 0; i < nclocks; i++) { 604 604 struct clk *clk = __clk_lookup(clocks[i]); 605 605 606 - if (clk) 607 - clk_prepare_enable(clk); 606 + clk_prepare_enable(clk); 608 607 } 609 608 } 610 609 EXPORT_SYMBOL_GPL(rockchip_clk_protect_critical);
+65 -2
drivers/clk/samsung/Kconfig
··· 2 2 # Recent Exynos platforms should just select COMMON_CLK_SAMSUNG: 3 3 config COMMON_CLK_SAMSUNG 4 4 bool "Samsung Exynos clock controller support" if COMPILE_TEST 5 - # Clocks on ARM64 SoCs (e.g. Exynos5433, Exynos7) are chosen by 6 - # EXYNOS_ARM64_COMMON_CLK to avoid building them on ARMv7: 5 + select S3C64XX_COMMON_CLK if ARM && ARCH_S3C64XX 6 + select S5PV210_COMMON_CLK if ARM && ARCH_S5PV210 7 + select EXYNOS_3250_COMMON_CLK if ARM && SOC_EXYNOS3250 8 + select EXYNOS_4_COMMON_CLK if ARM && ARCH_EXYNOS4 9 + select EXYNOS_5250_COMMON_CLK if ARM && SOC_EXYNOS5250 10 + select EXYNOS_5260_COMMON_CLK if ARM && SOC_EXYNOS5260 11 + select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410 12 + select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420 7 13 select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS 14 + 15 + config S3C64XX_COMMON_CLK 16 + bool "Samsung S3C64xx clock controller support" if COMPILE_TEST 17 + depends on COMMON_CLK_SAMSUNG 18 + help 19 + Support for the clock controller present on the Samsung S3C64xx SoCs. 20 + Choose Y here only if you build for this SoC. 21 + 22 + config S5PV210_COMMON_CLK 23 + bool "Samsung S5Pv210 clock controller support" if COMPILE_TEST 24 + depends on COMMON_CLK_SAMSUNG 25 + help 26 + Support for the clock controller present on the Samsung S5Pv210 SoCs. 27 + Choose Y here only if you build for this SoC. 28 + 29 + config EXYNOS_3250_COMMON_CLK 30 + bool "Samsung Exynos3250 clock controller support" if COMPILE_TEST 31 + depends on COMMON_CLK_SAMSUNG 32 + help 33 + Support for the clock controller present on the Samsung 34 + Exynos3250 SoCs. Choose Y here only if you build for this SoC. 35 + 36 + config EXYNOS_4_COMMON_CLK 37 + bool "Samsung Exynos4 clock controller support" if COMPILE_TEST 38 + depends on COMMON_CLK_SAMSUNG 39 + help 40 + Support for the clock controller present on the Samsung 41 + Exynos4212 and Exynos4412 SoCs. Choose Y here only if you build for 42 + this SoC. 43 + 44 + config EXYNOS_5250_COMMON_CLK 45 + bool "Samsung Exynos5250 clock controller support" if COMPILE_TEST 46 + depends on COMMON_CLK_SAMSUNG 47 + help 48 + Support for the clock controller present on the Samsung 49 + Exynos5250 SoCs. Choose Y here only if you build for this SoC. 50 + 51 + config EXYNOS_5260_COMMON_CLK 52 + bool "Samsung Exynos5260 clock controller support" if COMPILE_TEST 53 + depends on COMMON_CLK_SAMSUNG 54 + help 55 + Support for the clock controller present on the Samsung 56 + Exynos5260 SoCs. Choose Y here only if you build for this SoC. 57 + 58 + config EXYNOS_5410_COMMON_CLK 59 + bool "Samsung Exynos5410 clock controller support" if COMPILE_TEST 60 + depends on COMMON_CLK_SAMSUNG 61 + help 62 + Support for the clock controller present on the Samsung 63 + Exynos5410 SoCs. Choose Y here only if you build for this SoC. 64 + 65 + config EXYNOS_5420_COMMON_CLK 66 + bool "Samsung Exynos5420 clock controller support" if COMPILE_TEST 67 + depends on COMMON_CLK_SAMSUNG 68 + help 69 + Support for the clock controller present on the Samsung 70 + Exynos5420 SoCs. Choose Y here only if you build for this SoC. 8 71 9 72 config EXYNOS_ARM64_COMMON_CLK 10 73 bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST
+11 -11
drivers/clk/samsung/Makefile
··· 4 4 # 5 5 6 6 obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o 7 - obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o 8 - obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o 9 - obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o 10 - obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o 11 - obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o 12 - obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o 13 - obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o 14 - obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o 15 - obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o 7 + obj-$(CONFIG_EXYNOS_3250_COMMON_CLK) += clk-exynos3250.o 8 + obj-$(CONFIG_EXYNOS_4_COMMON_CLK) += clk-exynos4.o 9 + obj-$(CONFIG_EXYNOS_4_COMMON_CLK) += clk-exynos4412-isp.o 10 + obj-$(CONFIG_EXYNOS_5250_COMMON_CLK) += clk-exynos5250.o 11 + obj-$(CONFIG_EXYNOS_5250_COMMON_CLK) += clk-exynos5-subcmu.o 12 + obj-$(CONFIG_EXYNOS_5260_COMMON_CLK) += clk-exynos5260.o 13 + obj-$(CONFIG_EXYNOS_5410_COMMON_CLK) += clk-exynos5410.o 14 + obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5420.o 15 + obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5-subcmu.o 16 16 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o 17 17 obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o 18 18 obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o ··· 21 21 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o 22 22 obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o 23 23 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o 24 - obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o 25 - obj-$(CONFIG_ARCH_S5PV210) += clk-s5pv210.o clk-s5pv210-audss.o 24 + obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o 25 + obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
+71 -76
drivers/clk/samsung/clk-pll.c
··· 8 8 9 9 #include <linux/errno.h> 10 10 #include <linux/hrtimer.h> 11 + #include <linux/iopoll.h> 11 12 #include <linux/delay.h> 12 13 #include <linux/slab.h> 14 + #include <linux/timekeeping.h> 13 15 #include <linux/clk-provider.h> 14 16 #include <linux/io.h> 15 17 #include "clk.h" 16 18 #include "clk-pll.h" 17 19 18 - #define PLL_TIMEOUT_MS 10 20 + #define PLL_TIMEOUT_US 20000U 21 + #define PLL_TIMEOUT_LOOPS 1000000U 19 22 20 23 struct samsung_clk_pll { 21 24 struct clk_hw hw; ··· 66 63 return rate_table[i - 1].rate; 67 64 } 68 65 66 + static bool pll_early_timeout = true; 67 + 68 + static int __init samsung_pll_disable_early_timeout(void) 69 + { 70 + pll_early_timeout = false; 71 + return 0; 72 + } 73 + arch_initcall(samsung_pll_disable_early_timeout); 74 + 75 + /* Wait until the PLL is locked */ 76 + static int samsung_pll_lock_wait(struct samsung_clk_pll *pll, 77 + unsigned int reg_mask) 78 + { 79 + int i, ret; 80 + u32 val; 81 + 82 + /* 83 + * This function might be called when the timekeeping API can't be used 84 + * to detect timeouts. One situation is when the clocksource is not yet 85 + * initialized, another when the timekeeping is suspended. udelay() also 86 + * cannot be used when the clocksource is not running on arm64, since 87 + * the current timer is used as cycle counter. So a simple busy loop 88 + * is used here in that special cases. The limit of iterations has been 89 + * derived from experimental measurements of various PLLs on multiple 90 + * Exynos SoC variants. Single register read time was usually in range 91 + * 0.4...1.5 us, never less than 0.4 us. 92 + */ 93 + if (pll_early_timeout || timekeeping_suspended) { 94 + i = PLL_TIMEOUT_LOOPS; 95 + while (i-- > 0) { 96 + if (readl_relaxed(pll->con_reg) & reg_mask) 97 + return 0; 98 + 99 + cpu_relax(); 100 + } 101 + ret = -ETIMEDOUT; 102 + } else { 103 + ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val, 104 + val & reg_mask, 0, PLL_TIMEOUT_US); 105 + } 106 + 107 + if (ret < 0) 108 + pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw)); 109 + 110 + return ret; 111 + } 112 + 69 113 static int samsung_pll3xxx_enable(struct clk_hw *hw) 70 114 { 71 115 struct samsung_clk_pll *pll = to_clk_pll(hw); ··· 122 72 tmp |= BIT(pll->enable_offs); 123 73 writel_relaxed(tmp, pll->con_reg); 124 74 125 - /* wait lock time */ 126 - do { 127 - cpu_relax(); 128 - tmp = readl_relaxed(pll->con_reg); 129 - } while (!(tmp & BIT(pll->lock_offs))); 130 - 131 - return 0; 75 + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); 132 76 } 133 77 134 78 static void samsung_pll3xxx_disable(struct clk_hw *hw) ··· 284 240 (rate->sdiv << PLL35XX_SDIV_SHIFT); 285 241 writel_relaxed(tmp, pll->con_reg); 286 242 287 - /* Wait until the PLL is locked if it is enabled. */ 288 - if (tmp & BIT(pll->enable_offs)) { 289 - do { 290 - cpu_relax(); 291 - tmp = readl_relaxed(pll->con_reg); 292 - } while (!(tmp & BIT(pll->lock_offs))); 293 - } 243 + /* Wait for PLL lock if the PLL is enabled */ 244 + if (tmp & BIT(pll->enable_offs)) 245 + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); 246 + 294 247 return 0; 295 248 } 296 249 ··· 359 318 unsigned long parent_rate) 360 319 { 361 320 struct samsung_clk_pll *pll = to_clk_pll(hw); 362 - u32 tmp, pll_con0, pll_con1; 321 + u32 pll_con0, pll_con1; 363 322 const struct samsung_pll_rate_table *rate; 364 323 365 324 rate = samsung_get_pll_settings(pll, drate); ··· 397 356 pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT; 398 357 writel_relaxed(pll_con1, pll->con_reg + 4); 399 358 400 - /* wait_lock_time */ 401 - if (pll_con0 & BIT(pll->enable_offs)) { 402 - do { 403 - cpu_relax(); 404 - tmp = readl_relaxed(pll->con_reg); 405 - } while (!(tmp & BIT(pll->lock_offs))); 406 - } 359 + if (pll_con0 & BIT(pll->enable_offs)) 360 + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); 407 361 408 362 return 0; 409 363 } ··· 473 437 struct samsung_clk_pll *pll = to_clk_pll(hw); 474 438 const struct samsung_pll_rate_table *rate; 475 439 u32 con0, con1; 476 - ktime_t start; 477 440 478 441 /* Get required rate settings from table */ 479 442 rate = samsung_get_pll_settings(pll, drate); ··· 523 488 writel_relaxed(con1, pll->con_reg + 0x4); 524 489 writel_relaxed(con0, pll->con_reg); 525 490 526 - /* Wait for locking. */ 527 - start = ktime_get(); 528 - while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) { 529 - ktime_t delta = ktime_sub(ktime_get(), start); 530 - 531 - if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) { 532 - pr_err("%s: could not lock PLL %s\n", 533 - __func__, clk_hw_get_name(hw)); 534 - return -EFAULT; 535 - } 536 - 537 - cpu_relax(); 538 - } 539 - 540 - return 0; 491 + /* Wait for PLL lock */ 492 + return samsung_pll_lock_wait(pll, PLL45XX_LOCKED); 541 493 } 542 494 543 495 static const struct clk_ops samsung_pll45xx_clk_ops = { ··· 610 588 struct samsung_clk_pll *pll = to_clk_pll(hw); 611 589 const struct samsung_pll_rate_table *rate; 612 590 u32 con0, con1, lock; 613 - ktime_t start; 614 591 615 592 /* Get required rate settings from table */ 616 593 rate = samsung_get_pll_settings(pll, drate); ··· 668 647 writel_relaxed(con0, pll->con_reg); 669 648 writel_relaxed(con1, pll->con_reg + 0x4); 670 649 671 - /* Wait for locking. */ 672 - start = ktime_get(); 673 - while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) { 674 - ktime_t delta = ktime_sub(ktime_get(), start); 675 - 676 - if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) { 677 - pr_err("%s: could not lock PLL %s\n", 678 - __func__, clk_hw_get_name(hw)); 679 - return -EFAULT; 680 - } 681 - 682 - cpu_relax(); 683 - } 684 - 685 - return 0; 650 + /* Wait for PLL lock */ 651 + return samsung_pll_lock_wait(pll, PLL46XX_LOCKED); 686 652 } 687 653 688 654 static const struct clk_ops samsung_pll46xx_clk_ops = { ··· 1043 1035 (rate->sdiv << PLL2550XX_S_SHIFT); 1044 1036 writel_relaxed(tmp, pll->con_reg); 1045 1037 1046 - /* wait_lock_time */ 1047 - do { 1048 - cpu_relax(); 1049 - tmp = readl_relaxed(pll->con_reg); 1050 - } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK 1051 - << PLL2550XX_LOCK_STAT_SHIFT))); 1052 - 1053 - return 0; 1038 + /* Wait for PLL lock */ 1039 + return samsung_pll_lock_wait(pll, 1040 + PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT); 1054 1041 } 1055 1042 1056 1043 static const struct clk_ops samsung_pll2550xx_clk_ops = { ··· 1135 1132 con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT); 1136 1133 writel_relaxed(con1, pll->con_reg + 4); 1137 1134 1138 - do { 1139 - cpu_relax(); 1140 - con0 = readl_relaxed(pll->con_reg); 1141 - } while (!(con0 & (PLL2650X_LOCK_STAT_MASK 1142 - << PLL2650X_LOCK_STAT_SHIFT))); 1143 - 1144 - return 0; 1135 + /* Wait for PLL lock */ 1136 + return samsung_pll_lock_wait(pll, 1137 + PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT); 1145 1138 } 1146 1139 1147 1140 static const struct clk_ops samsung_pll2650x_clk_ops = { ··· 1195 1196 unsigned long parent_rate) 1196 1197 { 1197 1198 struct samsung_clk_pll *pll = to_clk_pll(hw); 1198 - u32 tmp, pll_con0, pll_con2; 1199 + u32 pll_con0, pll_con2; 1199 1200 const struct samsung_pll_rate_table *rate; 1200 1201 1201 1202 rate = samsung_get_pll_settings(pll, drate); ··· 1228 1229 writel_relaxed(pll_con0, pll->con_reg); 1229 1230 writel_relaxed(pll_con2, pll->con_reg + 8); 1230 1231 1231 - do { 1232 - tmp = readl_relaxed(pll->con_reg); 1233 - } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT))); 1234 - 1235 - return 0; 1232 + return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT); 1236 1233 } 1237 1234 1238 1235 static const struct clk_ops samsung_pll2650xx_clk_ops = {
+4 -4
drivers/clk/sifive/Kconfig
··· 8 8 9 9 if CLK_SIFIVE 10 10 11 - config CLK_SIFIVE_FU540_PRCI 12 - bool "PRCI driver for SiFive FU540 SoCs" 11 + config CLK_SIFIVE_PRCI 12 + bool "PRCI driver for SiFive SoCs" 13 13 select CLK_ANALOGBITS_WRPLL_CLN28HPC 14 14 help 15 15 Supports the Power Reset Clock interface (PRCI) IP block found in 16 - FU540 SoCs. If this kernel is meant to run on a SiFive FU540 SoC, 17 - enable this driver. 16 + FU540/FU740 SoCs. If this kernel is meant to run on a SiFive FU540/ 17 + FU740 SoCs, enable this driver. 18 18 19 19 endif
+1 -1
drivers/clk/sifive/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 - obj-$(CONFIG_CLK_SIFIVE_FU540_PRCI) += fu540-prci.o 2 + obj-$(CONFIG_CLK_SIFIVE_PRCI) += sifive-prci.o fu540-prci.o fu740-prci.o
+32 -573
drivers/clk/sifive/fu540-prci.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 3 * Copyright (C) 2018-2019 SiFive, Inc. 4 - * Wesley Terpstra 5 - * Paul Walmsley 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 - * 11 - * This program is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - * GNU General Public License for more details. 4 + * Copyright (C) 2018-2019 Wesley Terpstra 5 + * Copyright (C) 2018-2019 Paul Walmsley 6 + * Copyright (C) 2020 Zong Li 15 7 * 16 8 * The FU540 PRCI implements clock and reset control for the SiFive 17 9 * FU540-C000 chip. This driver assumes that it has sole control ··· 16 24 * - SiFive FU540-C000 manual v1p0, Chapter 7 "Clocking and Reset" 17 25 */ 18 26 19 - #include <dt-bindings/clock/sifive-fu540-prci.h> 20 - #include <linux/clkdev.h> 21 - #include <linux/clk-provider.h> 22 - #include <linux/clk/analogbits-wrpll-cln28hpc.h> 23 - #include <linux/delay.h> 24 - #include <linux/err.h> 25 - #include <linux/io.h> 26 27 #include <linux/module.h> 27 - #include <linux/of.h> 28 - #include <linux/of_clk.h> 29 - #include <linux/platform_device.h> 30 - #include <linux/slab.h> 31 28 32 - /* 33 - * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects: 34 - * hfclk and rtcclk 35 - */ 36 - #define EXPECTED_CLK_PARENT_COUNT 2 29 + #include <dt-bindings/clock/sifive-fu540-prci.h> 37 30 38 - /* 39 - * Register offsets and bitmasks 40 - */ 31 + #include "fu540-prci.h" 32 + #include "sifive-prci.h" 41 33 42 - /* COREPLLCFG0 */ 43 - #define PRCI_COREPLLCFG0_OFFSET 0x4 44 - # define PRCI_COREPLLCFG0_DIVR_SHIFT 0 45 - # define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT) 46 - # define PRCI_COREPLLCFG0_DIVF_SHIFT 6 47 - # define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT) 48 - # define PRCI_COREPLLCFG0_DIVQ_SHIFT 15 49 - # define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT) 50 - # define PRCI_COREPLLCFG0_RANGE_SHIFT 18 51 - # define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT) 52 - # define PRCI_COREPLLCFG0_BYPASS_SHIFT 24 53 - # define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT) 54 - # define PRCI_COREPLLCFG0_FSE_SHIFT 25 55 - # define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT) 56 - # define PRCI_COREPLLCFG0_LOCK_SHIFT 31 57 - # define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) 58 - 59 - /* DDRPLLCFG0 */ 60 - #define PRCI_DDRPLLCFG0_OFFSET 0xc 61 - # define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 62 - # define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT) 63 - # define PRCI_DDRPLLCFG0_DIVF_SHIFT 6 64 - # define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT) 65 - # define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15 66 - # define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT) 67 - # define PRCI_DDRPLLCFG0_RANGE_SHIFT 18 68 - # define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT) 69 - # define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24 70 - # define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT) 71 - # define PRCI_DDRPLLCFG0_FSE_SHIFT 25 72 - # define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT) 73 - # define PRCI_DDRPLLCFG0_LOCK_SHIFT 31 74 - # define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT) 75 - 76 - /* DDRPLLCFG1 */ 77 - #define PRCI_DDRPLLCFG1_OFFSET 0x10 78 - # define PRCI_DDRPLLCFG1_CKE_SHIFT 24 79 - # define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) 80 - 81 - /* GEMGXLPLLCFG0 */ 82 - #define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c 83 - # define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0 84 - # define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT) 85 - # define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6 86 - # define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT) 87 - # define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15 88 - # define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT) 89 - # define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18 90 - # define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT) 91 - # define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24 92 - # define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT) 93 - # define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25 94 - # define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT) 95 - # define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31 96 - # define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT) 97 - 98 - /* GEMGXLPLLCFG1 */ 99 - #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 100 - # define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 24 101 - # define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) 102 - 103 - /* CORECLKSEL */ 104 - #define PRCI_CORECLKSEL_OFFSET 0x24 105 - # define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0 106 - # define PRCI_CORECLKSEL_CORECLKSEL_MASK (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT) 107 - 108 - /* DEVICESRESETREG */ 109 - #define PRCI_DEVICESRESETREG_OFFSET 0x28 110 - # define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0 111 - # define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT) 112 - # define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1 113 - # define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT) 114 - # define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2 115 - # define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT) 116 - # define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3 117 - # define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT) 118 - # define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5 119 - # define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) 120 - 121 - /* CLKMUXSTATUSREG */ 122 - #define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c 123 - # define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 124 - # define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) 125 - 126 - /* 127 - * Private structures 128 - */ 129 - 130 - /** 131 - * struct __prci_data - per-device-instance data 132 - * @va: base virtual address of the PRCI IP block 133 - * @hw_clks: encapsulates struct clk_hw records 134 - * 135 - * PRCI per-device instance data 136 - */ 137 - struct __prci_data { 138 - void __iomem *va; 139 - struct clk_hw_onecell_data hw_clks; 140 - }; 141 - 142 - /** 143 - * struct __prci_wrpll_data - WRPLL configuration and integration data 144 - * @c: WRPLL current configuration record 145 - * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL) 146 - * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL) 147 - * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address 148 - * 149 - * @enable_bypass and @disable_bypass are used for WRPLL instances 150 - * that contain a separate external glitchless clock mux downstream 151 - * from the PLL. The WRPLL internal bypass mux is not glitchless. 152 - */ 153 - struct __prci_wrpll_data { 154 - struct wrpll_cfg c; 155 - void (*enable_bypass)(struct __prci_data *pd); 156 - void (*disable_bypass)(struct __prci_data *pd); 157 - u8 cfg0_offs; 158 - }; 159 - 160 - /** 161 - * struct __prci_clock - describes a clock device managed by PRCI 162 - * @name: user-readable clock name string - should match the manual 163 - * @parent_name: parent name for this clock 164 - * @ops: struct clk_ops for the Linux clock framework to use for control 165 - * @hw: Linux-private clock data 166 - * @pwd: WRPLL-specific data, associated with this clock (if not NULL) 167 - * @pd: PRCI-specific data associated with this clock (if not NULL) 168 - * 169 - * PRCI clock data. Used by the PRCI driver to register PRCI-provided 170 - * clocks to the Linux clock infrastructure. 171 - */ 172 - struct __prci_clock { 173 - const char *name; 174 - const char *parent_name; 175 - const struct clk_ops *ops; 176 - struct clk_hw hw; 177 - struct __prci_wrpll_data *pwd; 178 - struct __prci_data *pd; 179 - }; 180 - 181 - #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw) 182 - 183 - /* 184 - * Private functions 185 - */ 186 - 187 - /** 188 - * __prci_readl() - read from a PRCI register 189 - * @pd: PRCI context 190 - * @offs: register offset to read from (in bytes, from PRCI base address) 191 - * 192 - * Read the register located at offset @offs from the base virtual 193 - * address of the PRCI register target described by @pd, and return 194 - * the value to the caller. 195 - * 196 - * Context: Any context. 197 - * 198 - * Return: the contents of the register described by @pd and @offs. 199 - */ 200 - static u32 __prci_readl(struct __prci_data *pd, u32 offs) 201 - { 202 - return readl_relaxed(pd->va + offs); 203 - } 204 - 205 - static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd) 206 - { 207 - writel_relaxed(v, pd->va + offs); 208 - } 209 - 210 - /* WRPLL-related private functions */ 211 - 212 - /** 213 - * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters 214 - * @c: ptr to a struct wrpll_cfg record to write config into 215 - * @r: value read from the PRCI PLL configuration register 216 - * 217 - * Given a value @r read from an FU540 PRCI PLL configuration register, 218 - * split it into fields and populate it into the WRPLL configuration record 219 - * pointed to by @c. 220 - * 221 - * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros 222 - * have the same register layout. 223 - * 224 - * Context: Any context. 225 - */ 226 - static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r) 227 - { 228 - u32 v; 229 - 230 - v = r & PRCI_COREPLLCFG0_DIVR_MASK; 231 - v >>= PRCI_COREPLLCFG0_DIVR_SHIFT; 232 - c->divr = v; 233 - 234 - v = r & PRCI_COREPLLCFG0_DIVF_MASK; 235 - v >>= PRCI_COREPLLCFG0_DIVF_SHIFT; 236 - c->divf = v; 237 - 238 - v = r & PRCI_COREPLLCFG0_DIVQ_MASK; 239 - v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT; 240 - c->divq = v; 241 - 242 - v = r & PRCI_COREPLLCFG0_RANGE_MASK; 243 - v >>= PRCI_COREPLLCFG0_RANGE_SHIFT; 244 - c->range = v; 245 - 246 - c->flags &= (WRPLL_FLAGS_INT_FEEDBACK_MASK | 247 - WRPLL_FLAGS_EXT_FEEDBACK_MASK); 248 - 249 - /* external feedback mode not supported */ 250 - c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK; 251 - } 252 - 253 - /** 254 - * __prci_wrpll_pack() - pack PLL configuration parameters into a register value 255 - * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg 256 - * 257 - * Using a set of WRPLL configuration values pointed to by @c, 258 - * assemble a PRCI PLL configuration register value, and return it to 259 - * the caller. 260 - * 261 - * Context: Any context. Caller must ensure that the contents of the 262 - * record pointed to by @c do not change during the execution 263 - * of this function. 264 - * 265 - * Returns: a value suitable for writing into a PRCI PLL configuration 266 - * register 267 - */ 268 - static u32 __prci_wrpll_pack(const struct wrpll_cfg *c) 269 - { 270 - u32 r = 0; 271 - 272 - r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT; 273 - r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT; 274 - r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT; 275 - r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT; 276 - 277 - /* external feedback mode not supported */ 278 - r |= PRCI_COREPLLCFG0_FSE_MASK; 279 - 280 - return r; 281 - } 282 - 283 - /** 284 - * __prci_wrpll_read_cfg() - read the WRPLL configuration from the PRCI 285 - * @pd: PRCI context 286 - * @pwd: PRCI WRPLL metadata 287 - * 288 - * Read the current configuration of the PLL identified by @pwd from 289 - * the PRCI identified by @pd, and store it into the local configuration 290 - * cache in @pwd. 291 - * 292 - * Context: Any context. Caller must prevent the records pointed to by 293 - * @pd and @pwd from changing during execution. 294 - */ 295 - static void __prci_wrpll_read_cfg(struct __prci_data *pd, 296 - struct __prci_wrpll_data *pwd) 297 - { 298 - __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); 299 - } 300 - 301 - /** 302 - * __prci_wrpll_write_cfg() - write WRPLL configuration into the PRCI 303 - * @pd: PRCI context 304 - * @pwd: PRCI WRPLL metadata 305 - * @c: WRPLL configuration record to write 306 - * 307 - * Write the WRPLL configuration described by @c into the WRPLL 308 - * configuration register identified by @pwd in the PRCI instance 309 - * described by @c. Make a cached copy of the WRPLL's current 310 - * configuration so it can be used by other code. 311 - * 312 - * Context: Any context. Caller must prevent the records pointed to by 313 - * @pd and @pwd from changing during execution. 314 - */ 315 - static void __prci_wrpll_write_cfg(struct __prci_data *pd, 316 - struct __prci_wrpll_data *pwd, 317 - struct wrpll_cfg *c) 318 - { 319 - __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); 320 - 321 - memcpy(&pwd->c, c, sizeof(*c)); 322 - } 323 - 324 - /* Core clock mux control */ 325 - 326 - /** 327 - * __prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK 328 - * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg 329 - * 330 - * Switch the CORECLK mux to the HFCLK input source; return once complete. 331 - * 332 - * Context: Any context. Caller must prevent concurrent changes to the 333 - * PRCI_CORECLKSEL_OFFSET register. 334 - */ 335 - static void __prci_coreclksel_use_hfclk(struct __prci_data *pd) 336 - { 337 - u32 r; 338 - 339 - r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); 340 - r |= PRCI_CORECLKSEL_CORECLKSEL_MASK; 341 - __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); 342 - 343 - r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ 344 - } 345 - 346 - /** 347 - * __prci_coreclksel_use_corepll() - switch the CORECLK mux to output COREPLL 348 - * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg 349 - * 350 - * Switch the CORECLK mux to the PLL output clock; return once complete. 351 - * 352 - * Context: Any context. Caller must prevent concurrent changes to the 353 - * PRCI_CORECLKSEL_OFFSET register. 354 - */ 355 - static void __prci_coreclksel_use_corepll(struct __prci_data *pd) 356 - { 357 - u32 r; 358 - 359 - r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); 360 - r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK; 361 - __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); 362 - 363 - r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ 364 - } 365 - 366 - /* 367 - * Linux clock framework integration 368 - * 369 - * See the Linux clock framework documentation for more information on 370 - * these functions. 371 - */ 372 - 373 - static unsigned long sifive_fu540_prci_wrpll_recalc_rate(struct clk_hw *hw, 374 - unsigned long parent_rate) 375 - { 376 - struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 377 - struct __prci_wrpll_data *pwd = pc->pwd; 378 - 379 - return wrpll_calc_output_rate(&pwd->c, parent_rate); 380 - } 381 - 382 - static long sifive_fu540_prci_wrpll_round_rate(struct clk_hw *hw, 383 - unsigned long rate, 384 - unsigned long *parent_rate) 385 - { 386 - struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 387 - struct __prci_wrpll_data *pwd = pc->pwd; 388 - struct wrpll_cfg c; 389 - 390 - memcpy(&c, &pwd->c, sizeof(c)); 391 - 392 - wrpll_configure_for_rate(&c, rate, *parent_rate); 393 - 394 - return wrpll_calc_output_rate(&c, *parent_rate); 395 - } 396 - 397 - static int sifive_fu540_prci_wrpll_set_rate(struct clk_hw *hw, 398 - unsigned long rate, 399 - unsigned long parent_rate) 400 - { 401 - struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 402 - struct __prci_wrpll_data *pwd = pc->pwd; 403 - struct __prci_data *pd = pc->pd; 404 - int r; 405 - 406 - r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); 407 - if (r) 408 - return r; 409 - 410 - if (pwd->enable_bypass) 411 - pwd->enable_bypass(pd); 412 - 413 - __prci_wrpll_write_cfg(pd, pwd, &pwd->c); 414 - 415 - udelay(wrpll_calc_max_lock_us(&pwd->c)); 416 - 417 - if (pwd->disable_bypass) 418 - pwd->disable_bypass(pd); 419 - 420 - return 0; 421 - } 422 - 423 - static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = { 424 - .set_rate = sifive_fu540_prci_wrpll_set_rate, 425 - .round_rate = sifive_fu540_prci_wrpll_round_rate, 426 - .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, 427 - }; 428 - 429 - static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = { 430 - .recalc_rate = sifive_fu540_prci_wrpll_recalc_rate, 431 - }; 432 - 433 - /* TLCLKSEL clock integration */ 434 - 435 - static unsigned long sifive_fu540_prci_tlclksel_recalc_rate(struct clk_hw *hw, 436 - unsigned long parent_rate) 437 - { 438 - struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 439 - struct __prci_data *pd = pc->pd; 440 - u32 v; 441 - u8 div; 442 - 443 - v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET); 444 - v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK; 445 - div = v ? 1 : 2; 446 - 447 - return div_u64(parent_rate, div); 448 - } 449 - 450 - static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = { 451 - .recalc_rate = sifive_fu540_prci_tlclksel_recalc_rate, 452 - }; 453 - 454 - /* 455 - * PRCI integration data for each WRPLL instance 456 - */ 34 + /* PRCI integration data for each WRPLL instance */ 457 35 458 36 static struct __prci_wrpll_data __prci_corepll_data = { 459 37 .cfg0_offs = PRCI_COREPLLCFG0_OFFSET, 460 - .enable_bypass = __prci_coreclksel_use_hfclk, 461 - .disable_bypass = __prci_coreclksel_use_corepll, 38 + .cfg1_offs = PRCI_COREPLLCFG1_OFFSET, 39 + .enable_bypass = sifive_prci_coreclksel_use_hfclk, 40 + .disable_bypass = sifive_prci_coreclksel_use_corepll, 462 41 }; 463 42 464 43 static struct __prci_wrpll_data __prci_ddrpll_data = { 465 44 .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, 45 + .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET, 466 46 }; 467 47 468 48 static struct __prci_wrpll_data __prci_gemgxlpll_data = { 469 49 .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, 50 + .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET, 470 51 }; 471 52 472 - /* 473 - * List of clock controls provided by the PRCI 474 - */ 53 + /* Linux clock framework integration */ 475 54 476 - static struct __prci_clock __prci_init_clocks[] = { 55 + static const struct clk_ops sifive_fu540_prci_wrpll_clk_ops = { 56 + .set_rate = sifive_prci_wrpll_set_rate, 57 + .round_rate = sifive_prci_wrpll_round_rate, 58 + .recalc_rate = sifive_prci_wrpll_recalc_rate, 59 + .enable = sifive_prci_clock_enable, 60 + .disable = sifive_prci_clock_disable, 61 + .is_enabled = sifive_clk_is_enabled, 62 + }; 63 + 64 + static const struct clk_ops sifive_fu540_prci_wrpll_ro_clk_ops = { 65 + .recalc_rate = sifive_prci_wrpll_recalc_rate, 66 + }; 67 + 68 + static const struct clk_ops sifive_fu540_prci_tlclksel_clk_ops = { 69 + .recalc_rate = sifive_prci_tlclksel_recalc_rate, 70 + }; 71 + 72 + /* List of clock controls provided by the PRCI */ 73 + struct __prci_clock __prci_init_clocks_fu540[] = { 477 74 [PRCI_CLK_COREPLL] = { 478 75 .name = "corepll", 479 76 .parent_name = "hfclk", ··· 87 506 .ops = &sifive_fu540_prci_tlclksel_clk_ops, 88 507 }, 89 508 }; 90 - 91 - /** 92 - * __prci_register_clocks() - register clock controls in the PRCI with Linux 93 - * @dev: Linux struct device * 94 - * 95 - * Register the list of clock controls described in __prci_init_plls[] with 96 - * the Linux clock framework. 97 - * 98 - * Return: 0 upon success or a negative error code upon failure. 99 - */ 100 - static int __prci_register_clocks(struct device *dev, struct __prci_data *pd) 101 - { 102 - struct clk_init_data init = { }; 103 - struct __prci_clock *pic; 104 - int parent_count, i, r; 105 - 106 - parent_count = of_clk_get_parent_count(dev->of_node); 107 - if (parent_count != EXPECTED_CLK_PARENT_COUNT) { 108 - dev_err(dev, "expected only two parent clocks, found %d\n", 109 - parent_count); 110 - return -EINVAL; 111 - } 112 - 113 - /* Register PLLs */ 114 - for (i = 0; i < ARRAY_SIZE(__prci_init_clocks); ++i) { 115 - pic = &__prci_init_clocks[i]; 116 - 117 - init.name = pic->name; 118 - init.parent_names = &pic->parent_name; 119 - init.num_parents = 1; 120 - init.ops = pic->ops; 121 - pic->hw.init = &init; 122 - 123 - pic->pd = pd; 124 - 125 - if (pic->pwd) 126 - __prci_wrpll_read_cfg(pd, pic->pwd); 127 - 128 - r = devm_clk_hw_register(dev, &pic->hw); 129 - if (r) { 130 - dev_warn(dev, "Failed to register clock %s: %d\n", 131 - init.name, r); 132 - return r; 133 - } 134 - 135 - r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); 136 - if (r) { 137 - dev_warn(dev, "Failed to register clkdev for %s: %d\n", 138 - init.name, r); 139 - return r; 140 - } 141 - 142 - pd->hw_clks.hws[i] = &pic->hw; 143 - } 144 - 145 - pd->hw_clks.num = i; 146 - 147 - r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 148 - &pd->hw_clks); 149 - if (r) { 150 - dev_err(dev, "could not add hw_provider: %d\n", r); 151 - return r; 152 - } 153 - 154 - return 0; 155 - } 156 - 157 - /* 158 - * Linux device model integration 159 - * 160 - * See the Linux device model documentation for more information about 161 - * these functions. 162 - */ 163 - static int sifive_fu540_prci_probe(struct platform_device *pdev) 164 - { 165 - struct device *dev = &pdev->dev; 166 - struct resource *res; 167 - struct __prci_data *pd; 168 - int r; 169 - 170 - pd = devm_kzalloc(dev, 171 - struct_size(pd, hw_clks.hws, 172 - ARRAY_SIZE(__prci_init_clocks)), 173 - GFP_KERNEL); 174 - if (!pd) 175 - return -ENOMEM; 176 - 177 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 178 - pd->va = devm_ioremap_resource(dev, res); 179 - if (IS_ERR(pd->va)) 180 - return PTR_ERR(pd->va); 181 - 182 - r = __prci_register_clocks(dev, pd); 183 - if (r) { 184 - dev_err(dev, "could not register clocks: %d\n", r); 185 - return r; 186 - } 187 - 188 - dev_dbg(dev, "SiFive FU540 PRCI probed\n"); 189 - 190 - return 0; 191 - } 192 - 193 - static const struct of_device_id sifive_fu540_prci_of_match[] = { 194 - { .compatible = "sifive,fu540-c000-prci", }, 195 - {} 196 - }; 197 - MODULE_DEVICE_TABLE(of, sifive_fu540_prci_of_match); 198 - 199 - static struct platform_driver sifive_fu540_prci_driver = { 200 - .driver = { 201 - .name = "sifive-fu540-prci", 202 - .of_match_table = sifive_fu540_prci_of_match, 203 - }, 204 - .probe = sifive_fu540_prci_probe, 205 - }; 206 - 207 - static int __init sifive_fu540_prci_init(void) 208 - { 209 - return platform_driver_register(&sifive_fu540_prci_driver); 210 - } 211 - core_initcall(sifive_fu540_prci_init);
+21
drivers/clk/sifive/fu540-prci.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2020 SiFive, Inc. 4 + * Zong Li 5 + */ 6 + 7 + #ifndef __SIFIVE_CLK_FU540_PRCI_H 8 + #define __SIFIVE_CLK_FU540_PRCI_H 9 + 10 + #include "sifive-prci.h" 11 + 12 + #define NUM_CLOCK_FU540 4 13 + 14 + extern struct __prci_clock __prci_init_clocks_fu540[NUM_CLOCK_FU540]; 15 + 16 + static const struct prci_clk_desc prci_clk_fu540 = { 17 + .clks = __prci_init_clocks_fu540, 18 + .num_clks = ARRAY_SIZE(__prci_init_clocks_fu540), 19 + }; 20 + 21 + #endif /* __SIFIVE_CLK_FU540_PRCI_H */
+123
drivers/clk/sifive/fu740-prci.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 SiFive, Inc. 4 + * Copyright (C) 2020 Zong Li 5 + */ 6 + 7 + #include <linux/module.h> 8 + 9 + #include <dt-bindings/clock/sifive-fu740-prci.h> 10 + 11 + #include "fu540-prci.h" 12 + #include "sifive-prci.h" 13 + 14 + /* PRCI integration data for each WRPLL instance */ 15 + 16 + static struct __prci_wrpll_data __prci_corepll_data = { 17 + .cfg0_offs = PRCI_COREPLLCFG0_OFFSET, 18 + .cfg1_offs = PRCI_COREPLLCFG1_OFFSET, 19 + .enable_bypass = sifive_prci_coreclksel_use_hfclk, 20 + .disable_bypass = sifive_prci_coreclksel_use_final_corepll, 21 + }; 22 + 23 + static struct __prci_wrpll_data __prci_ddrpll_data = { 24 + .cfg0_offs = PRCI_DDRPLLCFG0_OFFSET, 25 + .cfg1_offs = PRCI_DDRPLLCFG1_OFFSET, 26 + }; 27 + 28 + static struct __prci_wrpll_data __prci_gemgxlpll_data = { 29 + .cfg0_offs = PRCI_GEMGXLPLLCFG0_OFFSET, 30 + .cfg1_offs = PRCI_GEMGXLPLLCFG1_OFFSET, 31 + }; 32 + 33 + static struct __prci_wrpll_data __prci_dvfscorepll_data = { 34 + .cfg0_offs = PRCI_DVFSCOREPLLCFG0_OFFSET, 35 + .cfg1_offs = PRCI_DVFSCOREPLLCFG1_OFFSET, 36 + .enable_bypass = sifive_prci_corepllsel_use_corepll, 37 + .disable_bypass = sifive_prci_corepllsel_use_dvfscorepll, 38 + }; 39 + 40 + static struct __prci_wrpll_data __prci_hfpclkpll_data = { 41 + .cfg0_offs = PRCI_HFPCLKPLLCFG0_OFFSET, 42 + .cfg1_offs = PRCI_HFPCLKPLLCFG1_OFFSET, 43 + .enable_bypass = sifive_prci_hfpclkpllsel_use_hfclk, 44 + .disable_bypass = sifive_prci_hfpclkpllsel_use_hfpclkpll, 45 + }; 46 + 47 + static struct __prci_wrpll_data __prci_cltxpll_data = { 48 + .cfg0_offs = PRCI_CLTXPLLCFG0_OFFSET, 49 + .cfg1_offs = PRCI_CLTXPLLCFG1_OFFSET, 50 + }; 51 + 52 + /* Linux clock framework integration */ 53 + 54 + static const struct clk_ops sifive_fu740_prci_wrpll_clk_ops = { 55 + .set_rate = sifive_prci_wrpll_set_rate, 56 + .round_rate = sifive_prci_wrpll_round_rate, 57 + .recalc_rate = sifive_prci_wrpll_recalc_rate, 58 + .enable = sifive_prci_clock_enable, 59 + .disable = sifive_prci_clock_disable, 60 + .is_enabled = sifive_clk_is_enabled, 61 + }; 62 + 63 + static const struct clk_ops sifive_fu740_prci_wrpll_ro_clk_ops = { 64 + .recalc_rate = sifive_prci_wrpll_recalc_rate, 65 + }; 66 + 67 + static const struct clk_ops sifive_fu740_prci_tlclksel_clk_ops = { 68 + .recalc_rate = sifive_prci_tlclksel_recalc_rate, 69 + }; 70 + 71 + static const struct clk_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { 72 + .recalc_rate = sifive_prci_hfpclkplldiv_recalc_rate, 73 + }; 74 + 75 + /* List of clock controls provided by the PRCI */ 76 + struct __prci_clock __prci_init_clocks_fu740[] = { 77 + [PRCI_CLK_COREPLL] = { 78 + .name = "corepll", 79 + .parent_name = "hfclk", 80 + .ops = &sifive_fu740_prci_wrpll_clk_ops, 81 + .pwd = &__prci_corepll_data, 82 + }, 83 + [PRCI_CLK_DDRPLL] = { 84 + .name = "ddrpll", 85 + .parent_name = "hfclk", 86 + .ops = &sifive_fu740_prci_wrpll_ro_clk_ops, 87 + .pwd = &__prci_ddrpll_data, 88 + }, 89 + [PRCI_CLK_GEMGXLPLL] = { 90 + .name = "gemgxlpll", 91 + .parent_name = "hfclk", 92 + .ops = &sifive_fu740_prci_wrpll_clk_ops, 93 + .pwd = &__prci_gemgxlpll_data, 94 + }, 95 + [PRCI_CLK_DVFSCOREPLL] = { 96 + .name = "dvfscorepll", 97 + .parent_name = "hfclk", 98 + .ops = &sifive_fu740_prci_wrpll_clk_ops, 99 + .pwd = &__prci_dvfscorepll_data, 100 + }, 101 + [PRCI_CLK_HFPCLKPLL] = { 102 + .name = "hfpclkpll", 103 + .parent_name = "hfclk", 104 + .ops = &sifive_fu740_prci_wrpll_clk_ops, 105 + .pwd = &__prci_hfpclkpll_data, 106 + }, 107 + [PRCI_CLK_CLTXPLL] = { 108 + .name = "cltxpll", 109 + .parent_name = "hfclk", 110 + .ops = &sifive_fu740_prci_wrpll_clk_ops, 111 + .pwd = &__prci_cltxpll_data, 112 + }, 113 + [PRCI_CLK_TLCLK] = { 114 + .name = "tlclk", 115 + .parent_name = "corepll", 116 + .ops = &sifive_fu740_prci_tlclksel_clk_ops, 117 + }, 118 + [PRCI_CLK_PCLK] = { 119 + .name = "pclk", 120 + .parent_name = "hfpclkpll", 121 + .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops, 122 + }, 123 + };
+21
drivers/clk/sifive/fu740-prci.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2020 SiFive, Inc. 4 + * Zong Li 5 + */ 6 + 7 + #ifndef __SIFIVE_CLK_FU740_PRCI_H 8 + #define __SIFIVE_CLK_FU740_PRCI_H 9 + 10 + #include "sifive-prci.h" 11 + 12 + #define NUM_CLOCK_FU740 8 13 + 14 + extern struct __prci_clock __prci_init_clocks_fu740[NUM_CLOCK_FU740]; 15 + 16 + static const struct prci_clk_desc prci_clk_fu740 = { 17 + .clks = __prci_init_clocks_fu740, 18 + .num_clks = ARRAY_SIZE(__prci_init_clocks_fu740), 19 + }; 20 + 21 + #endif /* __SIFIVE_CLK_FU740_PRCI_H */
+574
drivers/clk/sifive/sifive-prci.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2020 SiFive, Inc. 4 + * Copyright (C) 2020 Zong Li 5 + */ 6 + 7 + #include <linux/clkdev.h> 8 + #include <linux/delay.h> 9 + #include <linux/io.h> 10 + #include <linux/of_device.h> 11 + #include "sifive-prci.h" 12 + #include "fu540-prci.h" 13 + #include "fu740-prci.h" 14 + 15 + /* 16 + * Private functions 17 + */ 18 + 19 + /** 20 + * __prci_readl() - read from a PRCI register 21 + * @pd: PRCI context 22 + * @offs: register offset to read from (in bytes, from PRCI base address) 23 + * 24 + * Read the register located at offset @offs from the base virtual 25 + * address of the PRCI register target described by @pd, and return 26 + * the value to the caller. 27 + * 28 + * Context: Any context. 29 + * 30 + * Return: the contents of the register described by @pd and @offs. 31 + */ 32 + static u32 __prci_readl(struct __prci_data *pd, u32 offs) 33 + { 34 + return readl_relaxed(pd->va + offs); 35 + } 36 + 37 + static void __prci_writel(u32 v, u32 offs, struct __prci_data *pd) 38 + { 39 + writel_relaxed(v, pd->va + offs); 40 + } 41 + 42 + /* WRPLL-related private functions */ 43 + 44 + /** 45 + * __prci_wrpll_unpack() - unpack WRPLL configuration registers into parameters 46 + * @c: ptr to a struct wrpll_cfg record to write config into 47 + * @r: value read from the PRCI PLL configuration register 48 + * 49 + * Given a value @r read from an FU740 PRCI PLL configuration register, 50 + * split it into fields and populate it into the WRPLL configuration record 51 + * pointed to by @c. 52 + * 53 + * The COREPLLCFG0 macros are used below, but the other *PLLCFG0 macros 54 + * have the same register layout. 55 + * 56 + * Context: Any context. 57 + */ 58 + static void __prci_wrpll_unpack(struct wrpll_cfg *c, u32 r) 59 + { 60 + u32 v; 61 + 62 + v = r & PRCI_COREPLLCFG0_DIVR_MASK; 63 + v >>= PRCI_COREPLLCFG0_DIVR_SHIFT; 64 + c->divr = v; 65 + 66 + v = r & PRCI_COREPLLCFG0_DIVF_MASK; 67 + v >>= PRCI_COREPLLCFG0_DIVF_SHIFT; 68 + c->divf = v; 69 + 70 + v = r & PRCI_COREPLLCFG0_DIVQ_MASK; 71 + v >>= PRCI_COREPLLCFG0_DIVQ_SHIFT; 72 + c->divq = v; 73 + 74 + v = r & PRCI_COREPLLCFG0_RANGE_MASK; 75 + v >>= PRCI_COREPLLCFG0_RANGE_SHIFT; 76 + c->range = v; 77 + 78 + c->flags &= 79 + (WRPLL_FLAGS_INT_FEEDBACK_MASK | WRPLL_FLAGS_EXT_FEEDBACK_MASK); 80 + 81 + /* external feedback mode not supported */ 82 + c->flags |= WRPLL_FLAGS_INT_FEEDBACK_MASK; 83 + } 84 + 85 + /** 86 + * __prci_wrpll_pack() - pack PLL configuration parameters into a register value 87 + * @c: pointer to a struct wrpll_cfg record containing the PLL's cfg 88 + * 89 + * Using a set of WRPLL configuration values pointed to by @c, 90 + * assemble a PRCI PLL configuration register value, and return it to 91 + * the caller. 92 + * 93 + * Context: Any context. Caller must ensure that the contents of the 94 + * record pointed to by @c do not change during the execution 95 + * of this function. 96 + * 97 + * Returns: a value suitable for writing into a PRCI PLL configuration 98 + * register 99 + */ 100 + static u32 __prci_wrpll_pack(const struct wrpll_cfg *c) 101 + { 102 + u32 r = 0; 103 + 104 + r |= c->divr << PRCI_COREPLLCFG0_DIVR_SHIFT; 105 + r |= c->divf << PRCI_COREPLLCFG0_DIVF_SHIFT; 106 + r |= c->divq << PRCI_COREPLLCFG0_DIVQ_SHIFT; 107 + r |= c->range << PRCI_COREPLLCFG0_RANGE_SHIFT; 108 + 109 + /* external feedback mode not supported */ 110 + r |= PRCI_COREPLLCFG0_FSE_MASK; 111 + 112 + return r; 113 + } 114 + 115 + /** 116 + * __prci_wrpll_read_cfg0() - read the WRPLL configuration from the PRCI 117 + * @pd: PRCI context 118 + * @pwd: PRCI WRPLL metadata 119 + * 120 + * Read the current configuration of the PLL identified by @pwd from 121 + * the PRCI identified by @pd, and store it into the local configuration 122 + * cache in @pwd. 123 + * 124 + * Context: Any context. Caller must prevent the records pointed to by 125 + * @pd and @pwd from changing during execution. 126 + */ 127 + static void __prci_wrpll_read_cfg0(struct __prci_data *pd, 128 + struct __prci_wrpll_data *pwd) 129 + { 130 + __prci_wrpll_unpack(&pwd->c, __prci_readl(pd, pwd->cfg0_offs)); 131 + } 132 + 133 + /** 134 + * __prci_wrpll_write_cfg0() - write WRPLL configuration into the PRCI 135 + * @pd: PRCI context 136 + * @pwd: PRCI WRPLL metadata 137 + * @c: WRPLL configuration record to write 138 + * 139 + * Write the WRPLL configuration described by @c into the WRPLL 140 + * configuration register identified by @pwd in the PRCI instance 141 + * described by @c. Make a cached copy of the WRPLL's current 142 + * configuration so it can be used by other code. 143 + * 144 + * Context: Any context. Caller must prevent the records pointed to by 145 + * @pd and @pwd from changing during execution. 146 + */ 147 + static void __prci_wrpll_write_cfg0(struct __prci_data *pd, 148 + struct __prci_wrpll_data *pwd, 149 + struct wrpll_cfg *c) 150 + { 151 + __prci_writel(__prci_wrpll_pack(c), pwd->cfg0_offs, pd); 152 + 153 + memcpy(&pwd->c, c, sizeof(*c)); 154 + } 155 + 156 + /** 157 + * __prci_wrpll_write_cfg1() - write Clock enable/disable configuration 158 + * into the PRCI 159 + * @pd: PRCI context 160 + * @pwd: PRCI WRPLL metadata 161 + * @enable: Clock enable or disable value 162 + */ 163 + static void __prci_wrpll_write_cfg1(struct __prci_data *pd, 164 + struct __prci_wrpll_data *pwd, 165 + u32 enable) 166 + { 167 + __prci_writel(enable, pwd->cfg1_offs, pd); 168 + } 169 + 170 + /* 171 + * Linux clock framework integration 172 + * 173 + * See the Linux clock framework documentation for more information on 174 + * these functions. 175 + */ 176 + 177 + unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, 178 + unsigned long parent_rate) 179 + { 180 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 181 + struct __prci_wrpll_data *pwd = pc->pwd; 182 + 183 + return wrpll_calc_output_rate(&pwd->c, parent_rate); 184 + } 185 + 186 + long sifive_prci_wrpll_round_rate(struct clk_hw *hw, 187 + unsigned long rate, 188 + unsigned long *parent_rate) 189 + { 190 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 191 + struct __prci_wrpll_data *pwd = pc->pwd; 192 + struct wrpll_cfg c; 193 + 194 + memcpy(&c, &pwd->c, sizeof(c)); 195 + 196 + wrpll_configure_for_rate(&c, rate, *parent_rate); 197 + 198 + return wrpll_calc_output_rate(&c, *parent_rate); 199 + } 200 + 201 + int sifive_prci_wrpll_set_rate(struct clk_hw *hw, 202 + unsigned long rate, unsigned long parent_rate) 203 + { 204 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 205 + struct __prci_wrpll_data *pwd = pc->pwd; 206 + struct __prci_data *pd = pc->pd; 207 + int r; 208 + 209 + r = wrpll_configure_for_rate(&pwd->c, rate, parent_rate); 210 + if (r) 211 + return r; 212 + 213 + if (pwd->enable_bypass) 214 + pwd->enable_bypass(pd); 215 + 216 + __prci_wrpll_write_cfg0(pd, pwd, &pwd->c); 217 + 218 + udelay(wrpll_calc_max_lock_us(&pwd->c)); 219 + 220 + return 0; 221 + } 222 + 223 + int sifive_clk_is_enabled(struct clk_hw *hw) 224 + { 225 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 226 + struct __prci_wrpll_data *pwd = pc->pwd; 227 + struct __prci_data *pd = pc->pd; 228 + u32 r; 229 + 230 + r = __prci_readl(pd, pwd->cfg1_offs); 231 + 232 + if (r & PRCI_COREPLLCFG1_CKE_MASK) 233 + return 1; 234 + else 235 + return 0; 236 + } 237 + 238 + int sifive_prci_clock_enable(struct clk_hw *hw) 239 + { 240 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 241 + struct __prci_wrpll_data *pwd = pc->pwd; 242 + struct __prci_data *pd = pc->pd; 243 + 244 + if (sifive_clk_is_enabled(hw)) 245 + return 0; 246 + 247 + __prci_wrpll_write_cfg1(pd, pwd, PRCI_COREPLLCFG1_CKE_MASK); 248 + 249 + if (pwd->disable_bypass) 250 + pwd->disable_bypass(pd); 251 + 252 + return 0; 253 + } 254 + 255 + void sifive_prci_clock_disable(struct clk_hw *hw) 256 + { 257 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 258 + struct __prci_wrpll_data *pwd = pc->pwd; 259 + struct __prci_data *pd = pc->pd; 260 + u32 r; 261 + 262 + if (pwd->enable_bypass) 263 + pwd->enable_bypass(pd); 264 + 265 + r = __prci_readl(pd, pwd->cfg1_offs); 266 + r &= ~PRCI_COREPLLCFG1_CKE_MASK; 267 + 268 + __prci_wrpll_write_cfg1(pd, pwd, r); 269 + } 270 + 271 + /* TLCLKSEL clock integration */ 272 + 273 + unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, 274 + unsigned long parent_rate) 275 + { 276 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 277 + struct __prci_data *pd = pc->pd; 278 + u32 v; 279 + u8 div; 280 + 281 + v = __prci_readl(pd, PRCI_CLKMUXSTATUSREG_OFFSET); 282 + v &= PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK; 283 + div = v ? 1 : 2; 284 + 285 + return div_u64(parent_rate, div); 286 + } 287 + 288 + /* HFPCLK clock integration */ 289 + 290 + unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw, 291 + unsigned long parent_rate) 292 + { 293 + struct __prci_clock *pc = clk_hw_to_prci_clock(hw); 294 + struct __prci_data *pd = pc->pd; 295 + u32 div = __prci_readl(pd, PRCI_HFPCLKPLLDIV_OFFSET); 296 + 297 + return div_u64(parent_rate, div + 2); 298 + } 299 + 300 + /* 301 + * Core clock mux control 302 + */ 303 + 304 + /** 305 + * sifive_prci_coreclksel_use_hfclk() - switch the CORECLK mux to output HFCLK 306 + * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg 307 + * 308 + * Switch the CORECLK mux to the HFCLK input source; return once complete. 309 + * 310 + * Context: Any context. Caller must prevent concurrent changes to the 311 + * PRCI_CORECLKSEL_OFFSET register. 312 + */ 313 + void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd) 314 + { 315 + u32 r; 316 + 317 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); 318 + r |= PRCI_CORECLKSEL_CORECLKSEL_MASK; 319 + __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); 320 + 321 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ 322 + } 323 + 324 + /** 325 + * sifive_prci_coreclksel_use_corepll() - switch the CORECLK mux to output 326 + * COREPLL 327 + * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg 328 + * 329 + * Switch the CORECLK mux to the COREPLL output clock; return once complete. 330 + * 331 + * Context: Any context. Caller must prevent concurrent changes to the 332 + * PRCI_CORECLKSEL_OFFSET register. 333 + */ 334 + void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd) 335 + { 336 + u32 r; 337 + 338 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); 339 + r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK; 340 + __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); 341 + 342 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ 343 + } 344 + 345 + /** 346 + * sifive_prci_coreclksel_use_final_corepll() - switch the CORECLK mux to output 347 + * FINAL_COREPLL 348 + * @pd: struct __prci_data * for the PRCI containing the CORECLK mux reg 349 + * 350 + * Switch the CORECLK mux to the final COREPLL output clock; return once 351 + * complete. 352 + * 353 + * Context: Any context. Caller must prevent concurrent changes to the 354 + * PRCI_CORECLKSEL_OFFSET register. 355 + */ 356 + void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd) 357 + { 358 + u32 r; 359 + 360 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); 361 + r &= ~PRCI_CORECLKSEL_CORECLKSEL_MASK; 362 + __prci_writel(r, PRCI_CORECLKSEL_OFFSET, pd); 363 + 364 + r = __prci_readl(pd, PRCI_CORECLKSEL_OFFSET); /* barrier */ 365 + } 366 + 367 + /** 368 + * sifive_prci_corepllsel_use_dvfscorepll() - switch the COREPLL mux to 369 + * output DVFS_COREPLL 370 + * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg 371 + * 372 + * Switch the COREPLL mux to the DVFSCOREPLL output clock; return once complete. 373 + * 374 + * Context: Any context. Caller must prevent concurrent changes to the 375 + * PRCI_COREPLLSEL_OFFSET register. 376 + */ 377 + void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd) 378 + { 379 + u32 r; 380 + 381 + r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); 382 + r |= PRCI_COREPLLSEL_COREPLLSEL_MASK; 383 + __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd); 384 + 385 + r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); /* barrier */ 386 + } 387 + 388 + /** 389 + * sifive_prci_corepllsel_use_corepll() - switch the COREPLL mux to 390 + * output COREPLL 391 + * @pd: struct __prci_data * for the PRCI containing the COREPLL mux reg 392 + * 393 + * Switch the COREPLL mux to the COREPLL output clock; return once complete. 394 + * 395 + * Context: Any context. Caller must prevent concurrent changes to the 396 + * PRCI_COREPLLSEL_OFFSET register. 397 + */ 398 + void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd) 399 + { 400 + u32 r; 401 + 402 + r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); 403 + r &= ~PRCI_COREPLLSEL_COREPLLSEL_MASK; 404 + __prci_writel(r, PRCI_COREPLLSEL_OFFSET, pd); 405 + 406 + r = __prci_readl(pd, PRCI_COREPLLSEL_OFFSET); /* barrier */ 407 + } 408 + 409 + /** 410 + * sifive_prci_hfpclkpllsel_use_hfclk() - switch the HFPCLKPLL mux to 411 + * output HFCLK 412 + * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg 413 + * 414 + * Switch the HFPCLKPLL mux to the HFCLK input source; return once complete. 415 + * 416 + * Context: Any context. Caller must prevent concurrent changes to the 417 + * PRCI_HFPCLKPLLSEL_OFFSET register. 418 + */ 419 + void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd) 420 + { 421 + u32 r; 422 + 423 + r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); 424 + r |= PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK; 425 + __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd); 426 + 427 + r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */ 428 + } 429 + 430 + /** 431 + * sifive_prci_hfpclkpllsel_use_hfpclkpll() - switch the HFPCLKPLL mux to 432 + * output HFPCLKPLL 433 + * @pd: struct __prci_data * for the PRCI containing the HFPCLKPLL mux reg 434 + * 435 + * Switch the HFPCLKPLL mux to the HFPCLKPLL output clock; return once complete. 436 + * 437 + * Context: Any context. Caller must prevent concurrent changes to the 438 + * PRCI_HFPCLKPLLSEL_OFFSET register. 439 + */ 440 + void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd) 441 + { 442 + u32 r; 443 + 444 + r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); 445 + r &= ~PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK; 446 + __prci_writel(r, PRCI_HFPCLKPLLSEL_OFFSET, pd); 447 + 448 + r = __prci_readl(pd, PRCI_HFPCLKPLLSEL_OFFSET); /* barrier */ 449 + } 450 + 451 + /** 452 + * __prci_register_clocks() - register clock controls in the PRCI 453 + * @dev: Linux struct device 454 + * @pd: The pointer for PRCI per-device instance data 455 + * @desc: The pointer for the information of clocks of each SoCs 456 + * 457 + * Register the list of clock controls described in __prci_init_clocks[] with 458 + * the Linux clock framework. 459 + * 460 + * Return: 0 upon success or a negative error code upon failure. 461 + */ 462 + static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, 463 + const struct prci_clk_desc *desc) 464 + { 465 + struct clk_init_data init = { }; 466 + struct __prci_clock *pic; 467 + int parent_count, i, r; 468 + 469 + parent_count = of_clk_get_parent_count(dev->of_node); 470 + if (parent_count != EXPECTED_CLK_PARENT_COUNT) { 471 + dev_err(dev, "expected only two parent clocks, found %d\n", 472 + parent_count); 473 + return -EINVAL; 474 + } 475 + 476 + /* Register PLLs */ 477 + for (i = 0; i < desc->num_clks; ++i) { 478 + pic = &(desc->clks[i]); 479 + 480 + init.name = pic->name; 481 + init.parent_names = &pic->parent_name; 482 + init.num_parents = 1; 483 + init.ops = pic->ops; 484 + pic->hw.init = &init; 485 + 486 + pic->pd = pd; 487 + 488 + if (pic->pwd) 489 + __prci_wrpll_read_cfg0(pd, pic->pwd); 490 + 491 + r = devm_clk_hw_register(dev, &pic->hw); 492 + if (r) { 493 + dev_warn(dev, "Failed to register clock %s: %d\n", 494 + init.name, r); 495 + return r; 496 + } 497 + 498 + r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev)); 499 + if (r) { 500 + dev_warn(dev, "Failed to register clkdev for %s: %d\n", 501 + init.name, r); 502 + return r; 503 + } 504 + 505 + pd->hw_clks.hws[i] = &pic->hw; 506 + } 507 + 508 + pd->hw_clks.num = i; 509 + 510 + r = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 511 + &pd->hw_clks); 512 + if (r) { 513 + dev_err(dev, "could not add hw_provider: %d\n", r); 514 + return r; 515 + } 516 + 517 + return 0; 518 + } 519 + 520 + /** 521 + * sifive_prci_init() - initialize prci data and check parent count 522 + * @pdev: platform device pointer for the prci 523 + * 524 + * Return: 0 upon success or a negative error code upon failure. 525 + */ 526 + static int sifive_prci_probe(struct platform_device *pdev) 527 + { 528 + struct device *dev = &pdev->dev; 529 + struct resource *res; 530 + struct __prci_data *pd; 531 + const struct prci_clk_desc *desc; 532 + int r; 533 + 534 + desc = of_device_get_match_data(&pdev->dev); 535 + 536 + pd = devm_kzalloc(dev, struct_size(pd, hw_clks.hws, desc->num_clks), GFP_KERNEL); 537 + if (!pd) 538 + return -ENOMEM; 539 + 540 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 541 + pd->va = devm_ioremap_resource(dev, res); 542 + if (IS_ERR(pd->va)) 543 + return PTR_ERR(pd->va); 544 + 545 + r = __prci_register_clocks(dev, pd, desc); 546 + if (r) { 547 + dev_err(dev, "could not register clocks: %d\n", r); 548 + return r; 549 + } 550 + 551 + dev_dbg(dev, "SiFive PRCI probed\n"); 552 + 553 + return 0; 554 + } 555 + 556 + static const struct of_device_id sifive_prci_of_match[] = { 557 + {.compatible = "sifive,fu540-c000-prci", .data = &prci_clk_fu540}, 558 + {.compatible = "sifive,fu740-c000-prci", .data = &prci_clk_fu740}, 559 + {} 560 + }; 561 + 562 + static struct platform_driver sifive_prci_driver = { 563 + .driver = { 564 + .name = "sifive-clk-prci", 565 + .of_match_table = sifive_prci_of_match, 566 + }, 567 + .probe = sifive_prci_probe, 568 + }; 569 + 570 + static int __init sifive_prci_init(void) 571 + { 572 + return platform_driver_register(&sifive_prci_driver); 573 + } 574 + core_initcall(sifive_prci_init);
+299
drivers/clk/sifive/sifive-prci.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2018-2019 SiFive, Inc. 4 + * Wesley Terpstra 5 + * Paul Walmsley 6 + * Zong Li 7 + */ 8 + 9 + #ifndef __SIFIVE_CLK_SIFIVE_PRCI_H 10 + #define __SIFIVE_CLK_SIFIVE_PRCI_H 11 + 12 + #include <linux/clk/analogbits-wrpll-cln28hpc.h> 13 + #include <linux/clk-provider.h> 14 + #include <linux/platform_device.h> 15 + 16 + /* 17 + * EXPECTED_CLK_PARENT_COUNT: how many parent clocks this driver expects: 18 + * hfclk and rtcclk 19 + */ 20 + #define EXPECTED_CLK_PARENT_COUNT 2 21 + 22 + /* 23 + * Register offsets and bitmasks 24 + */ 25 + 26 + /* COREPLLCFG0 */ 27 + #define PRCI_COREPLLCFG0_OFFSET 0x4 28 + #define PRCI_COREPLLCFG0_DIVR_SHIFT 0 29 + #define PRCI_COREPLLCFG0_DIVR_MASK (0x3f << PRCI_COREPLLCFG0_DIVR_SHIFT) 30 + #define PRCI_COREPLLCFG0_DIVF_SHIFT 6 31 + #define PRCI_COREPLLCFG0_DIVF_MASK (0x1ff << PRCI_COREPLLCFG0_DIVF_SHIFT) 32 + #define PRCI_COREPLLCFG0_DIVQ_SHIFT 15 33 + #define PRCI_COREPLLCFG0_DIVQ_MASK (0x7 << PRCI_COREPLLCFG0_DIVQ_SHIFT) 34 + #define PRCI_COREPLLCFG0_RANGE_SHIFT 18 35 + #define PRCI_COREPLLCFG0_RANGE_MASK (0x7 << PRCI_COREPLLCFG0_RANGE_SHIFT) 36 + #define PRCI_COREPLLCFG0_BYPASS_SHIFT 24 37 + #define PRCI_COREPLLCFG0_BYPASS_MASK (0x1 << PRCI_COREPLLCFG0_BYPASS_SHIFT) 38 + #define PRCI_COREPLLCFG0_FSE_SHIFT 25 39 + #define PRCI_COREPLLCFG0_FSE_MASK (0x1 << PRCI_COREPLLCFG0_FSE_SHIFT) 40 + #define PRCI_COREPLLCFG0_LOCK_SHIFT 31 41 + #define PRCI_COREPLLCFG0_LOCK_MASK (0x1 << PRCI_COREPLLCFG0_LOCK_SHIFT) 42 + 43 + /* COREPLLCFG1 */ 44 + #define PRCI_COREPLLCFG1_OFFSET 0x8 45 + #define PRCI_COREPLLCFG1_CKE_SHIFT 31 46 + #define PRCI_COREPLLCFG1_CKE_MASK (0x1 << PRCI_COREPLLCFG1_CKE_SHIFT) 47 + 48 + /* DDRPLLCFG0 */ 49 + #define PRCI_DDRPLLCFG0_OFFSET 0xc 50 + #define PRCI_DDRPLLCFG0_DIVR_SHIFT 0 51 + #define PRCI_DDRPLLCFG0_DIVR_MASK (0x3f << PRCI_DDRPLLCFG0_DIVR_SHIFT) 52 + #define PRCI_DDRPLLCFG0_DIVF_SHIFT 6 53 + #define PRCI_DDRPLLCFG0_DIVF_MASK (0x1ff << PRCI_DDRPLLCFG0_DIVF_SHIFT) 54 + #define PRCI_DDRPLLCFG0_DIVQ_SHIFT 15 55 + #define PRCI_DDRPLLCFG0_DIVQ_MASK (0x7 << PRCI_DDRPLLCFG0_DIVQ_SHIFT) 56 + #define PRCI_DDRPLLCFG0_RANGE_SHIFT 18 57 + #define PRCI_DDRPLLCFG0_RANGE_MASK (0x7 << PRCI_DDRPLLCFG0_RANGE_SHIFT) 58 + #define PRCI_DDRPLLCFG0_BYPASS_SHIFT 24 59 + #define PRCI_DDRPLLCFG0_BYPASS_MASK (0x1 << PRCI_DDRPLLCFG0_BYPASS_SHIFT) 60 + #define PRCI_DDRPLLCFG0_FSE_SHIFT 25 61 + #define PRCI_DDRPLLCFG0_FSE_MASK (0x1 << PRCI_DDRPLLCFG0_FSE_SHIFT) 62 + #define PRCI_DDRPLLCFG0_LOCK_SHIFT 31 63 + #define PRCI_DDRPLLCFG0_LOCK_MASK (0x1 << PRCI_DDRPLLCFG0_LOCK_SHIFT) 64 + 65 + /* DDRPLLCFG1 */ 66 + #define PRCI_DDRPLLCFG1_OFFSET 0x10 67 + #define PRCI_DDRPLLCFG1_CKE_SHIFT 31 68 + #define PRCI_DDRPLLCFG1_CKE_MASK (0x1 << PRCI_DDRPLLCFG1_CKE_SHIFT) 69 + 70 + /* GEMGXLPLLCFG0 */ 71 + #define PRCI_GEMGXLPLLCFG0_OFFSET 0x1c 72 + #define PRCI_GEMGXLPLLCFG0_DIVR_SHIFT 0 73 + #define PRCI_GEMGXLPLLCFG0_DIVR_MASK (0x3f << PRCI_GEMGXLPLLCFG0_DIVR_SHIFT) 74 + #define PRCI_GEMGXLPLLCFG0_DIVF_SHIFT 6 75 + #define PRCI_GEMGXLPLLCFG0_DIVF_MASK (0x1ff << PRCI_GEMGXLPLLCFG0_DIVF_SHIFT) 76 + #define PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT 15 77 + #define PRCI_GEMGXLPLLCFG0_DIVQ_MASK (0x7 << PRCI_GEMGXLPLLCFG0_DIVQ_SHIFT) 78 + #define PRCI_GEMGXLPLLCFG0_RANGE_SHIFT 18 79 + #define PRCI_GEMGXLPLLCFG0_RANGE_MASK (0x7 << PRCI_GEMGXLPLLCFG0_RANGE_SHIFT) 80 + #define PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT 24 81 + #define PRCI_GEMGXLPLLCFG0_BYPASS_MASK (0x1 << PRCI_GEMGXLPLLCFG0_BYPASS_SHIFT) 82 + #define PRCI_GEMGXLPLLCFG0_FSE_SHIFT 25 83 + #define PRCI_GEMGXLPLLCFG0_FSE_MASK (0x1 << PRCI_GEMGXLPLLCFG0_FSE_SHIFT) 84 + #define PRCI_GEMGXLPLLCFG0_LOCK_SHIFT 31 85 + #define PRCI_GEMGXLPLLCFG0_LOCK_MASK (0x1 << PRCI_GEMGXLPLLCFG0_LOCK_SHIFT) 86 + 87 + /* GEMGXLPLLCFG1 */ 88 + #define PRCI_GEMGXLPLLCFG1_OFFSET 0x20 89 + #define PRCI_GEMGXLPLLCFG1_CKE_SHIFT 31 90 + #define PRCI_GEMGXLPLLCFG1_CKE_MASK (0x1 << PRCI_GEMGXLPLLCFG1_CKE_SHIFT) 91 + 92 + /* CORECLKSEL */ 93 + #define PRCI_CORECLKSEL_OFFSET 0x24 94 + #define PRCI_CORECLKSEL_CORECLKSEL_SHIFT 0 95 + #define PRCI_CORECLKSEL_CORECLKSEL_MASK \ 96 + (0x1 << PRCI_CORECLKSEL_CORECLKSEL_SHIFT) 97 + 98 + /* DEVICESRESETREG */ 99 + #define PRCI_DEVICESRESETREG_OFFSET 0x28 100 + #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT 0 101 + #define PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_MASK \ 102 + (0x1 << PRCI_DEVICESRESETREG_DDR_CTRL_RST_N_SHIFT) 103 + #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT 1 104 + #define PRCI_DEVICESRESETREG_DDR_AXI_RST_N_MASK \ 105 + (0x1 << PRCI_DEVICESRESETREG_DDR_AXI_RST_N_SHIFT) 106 + #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT 2 107 + #define PRCI_DEVICESRESETREG_DDR_AHB_RST_N_MASK \ 108 + (0x1 << PRCI_DEVICESRESETREG_DDR_AHB_RST_N_SHIFT) 109 + #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT 3 110 + #define PRCI_DEVICESRESETREG_DDR_PHY_RST_N_MASK \ 111 + (0x1 << PRCI_DEVICESRESETREG_DDR_PHY_RST_N_SHIFT) 112 + #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT 5 113 + #define PRCI_DEVICESRESETREG_GEMGXL_RST_N_MASK \ 114 + (0x1 << PRCI_DEVICESRESETREG_GEMGXL_RST_N_SHIFT) 115 + #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT 6 116 + #define PRCI_DEVICESRESETREG_CHIPLINK_RST_N_MASK \ 117 + (0x1 << PRCI_DEVICESRESETREG_CHIPLINK_RST_N_SHIFT) 118 + 119 + /* CLKMUXSTATUSREG */ 120 + #define PRCI_CLKMUXSTATUSREG_OFFSET 0x2c 121 + #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT 1 122 + #define PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_MASK \ 123 + (0x1 << PRCI_CLKMUXSTATUSREG_TLCLKSEL_STATUS_SHIFT) 124 + 125 + /* CLTXPLLCFG0 */ 126 + #define PRCI_CLTXPLLCFG0_OFFSET 0x30 127 + #define PRCI_CLTXPLLCFG0_DIVR_SHIFT 0 128 + #define PRCI_CLTXPLLCFG0_DIVR_MASK (0x3f << PRCI_CLTXPLLCFG0_DIVR_SHIFT) 129 + #define PRCI_CLTXPLLCFG0_DIVF_SHIFT 6 130 + #define PRCI_CLTXPLLCFG0_DIVF_MASK (0x1ff << PRCI_CLTXPLLCFG0_DIVF_SHIFT) 131 + #define PRCI_CLTXPLLCFG0_DIVQ_SHIFT 15 132 + #define PRCI_CLTXPLLCFG0_DIVQ_MASK (0x7 << PRCI_CLTXPLLCFG0_DIVQ_SHIFT) 133 + #define PRCI_CLTXPLLCFG0_RANGE_SHIFT 18 134 + #define PRCI_CLTXPLLCFG0_RANGE_MASK (0x7 << PRCI_CLTXPLLCFG0_RANGE_SHIFT) 135 + #define PRCI_CLTXPLLCFG0_BYPASS_SHIFT 24 136 + #define PRCI_CLTXPLLCFG0_BYPASS_MASK (0x1 << PRCI_CLTXPLLCFG0_BYPASS_SHIFT) 137 + #define PRCI_CLTXPLLCFG0_FSE_SHIFT 25 138 + #define PRCI_CLTXPLLCFG0_FSE_MASK (0x1 << PRCI_CLTXPLLCFG0_FSE_SHIFT) 139 + #define PRCI_CLTXPLLCFG0_LOCK_SHIFT 31 140 + #define PRCI_CLTXPLLCFG0_LOCK_MASK (0x1 << PRCI_CLTXPLLCFG0_LOCK_SHIFT) 141 + 142 + /* CLTXPLLCFG1 */ 143 + #define PRCI_CLTXPLLCFG1_OFFSET 0x34 144 + #define PRCI_CLTXPLLCFG1_CKE_SHIFT 31 145 + #define PRCI_CLTXPLLCFG1_CKE_MASK (0x1 << PRCI_CLTXPLLCFG1_CKE_SHIFT) 146 + 147 + /* DVFSCOREPLLCFG0 */ 148 + #define PRCI_DVFSCOREPLLCFG0_OFFSET 0x38 149 + 150 + /* DVFSCOREPLLCFG1 */ 151 + #define PRCI_DVFSCOREPLLCFG1_OFFSET 0x3c 152 + #define PRCI_DVFSCOREPLLCFG1_CKE_SHIFT 31 153 + #define PRCI_DVFSCOREPLLCFG1_CKE_MASK (0x1 << PRCI_DVFSCOREPLLCFG1_CKE_SHIFT) 154 + 155 + /* COREPLLSEL */ 156 + #define PRCI_COREPLLSEL_OFFSET 0x40 157 + #define PRCI_COREPLLSEL_COREPLLSEL_SHIFT 0 158 + #define PRCI_COREPLLSEL_COREPLLSEL_MASK \ 159 + (0x1 << PRCI_COREPLLSEL_COREPLLSEL_SHIFT) 160 + 161 + /* HFPCLKPLLCFG0 */ 162 + #define PRCI_HFPCLKPLLCFG0_OFFSET 0x50 163 + #define PRCI_HFPCLKPLL_CFG0_DIVR_SHIFT 0 164 + #define PRCI_HFPCLKPLL_CFG0_DIVR_MASK \ 165 + (0x3f << PRCI_HFPCLKPLLCFG0_DIVR_SHIFT) 166 + #define PRCI_HFPCLKPLL_CFG0_DIVF_SHIFT 6 167 + #define PRCI_HFPCLKPLL_CFG0_DIVF_MASK \ 168 + (0x1ff << PRCI_HFPCLKPLLCFG0_DIVF_SHIFT) 169 + #define PRCI_HFPCLKPLL_CFG0_DIVQ_SHIFT 15 170 + #define PRCI_HFPCLKPLL_CFG0_DIVQ_MASK \ 171 + (0x7 << PRCI_HFPCLKPLLCFG0_DIVQ_SHIFT) 172 + #define PRCI_HFPCLKPLL_CFG0_RANGE_SHIFT 18 173 + #define PRCI_HFPCLKPLL_CFG0_RANGE_MASK \ 174 + (0x7 << PRCI_HFPCLKPLLCFG0_RANGE_SHIFT) 175 + #define PRCI_HFPCLKPLL_CFG0_BYPASS_SHIFT 24 176 + #define PRCI_HFPCLKPLL_CFG0_BYPASS_MASK \ 177 + (0x1 << PRCI_HFPCLKPLLCFG0_BYPASS_SHIFT) 178 + #define PRCI_HFPCLKPLL_CFG0_FSE_SHIFT 25 179 + #define PRCI_HFPCLKPLL_CFG0_FSE_MASK \ 180 + (0x1 << PRCI_HFPCLKPLLCFG0_FSE_SHIFT) 181 + #define PRCI_HFPCLKPLL_CFG0_LOCK_SHIFT 31 182 + #define PRCI_HFPCLKPLL_CFG0_LOCK_MASK \ 183 + (0x1 << PRCI_HFPCLKPLLCFG0_LOCK_SHIFT) 184 + 185 + /* HFPCLKPLLCFG1 */ 186 + #define PRCI_HFPCLKPLLCFG1_OFFSET 0x54 187 + #define PRCI_HFPCLKPLLCFG1_CKE_SHIFT 31 188 + #define PRCI_HFPCLKPLLCFG1_CKE_MASK \ 189 + (0x1 << PRCI_HFPCLKPLLCFG1_CKE_SHIFT) 190 + 191 + /* HFPCLKPLLSEL */ 192 + #define PRCI_HFPCLKPLLSEL_OFFSET 0x58 193 + #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT 0 194 + #define PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_MASK \ 195 + (0x1 << PRCI_HFPCLKPLLSEL_HFPCLKPLLSEL_SHIFT) 196 + 197 + /* HFPCLKPLLDIV */ 198 + #define PRCI_HFPCLKPLLDIV_OFFSET 0x5c 199 + 200 + /* PRCIPLL */ 201 + #define PRCI_PRCIPLL_OFFSET 0xe0 202 + 203 + /* PROCMONCFG */ 204 + #define PRCI_PROCMONCFG_OFFSET 0xf0 205 + 206 + /* 207 + * Private structures 208 + */ 209 + 210 + /** 211 + * struct __prci_data - per-device-instance data 212 + * @va: base virtual address of the PRCI IP block 213 + * @hw_clks: encapsulates struct clk_hw records 214 + * 215 + * PRCI per-device instance data 216 + */ 217 + struct __prci_data { 218 + void __iomem *va; 219 + struct clk_hw_onecell_data hw_clks; 220 + }; 221 + 222 + /** 223 + * struct __prci_wrpll_data - WRPLL configuration and integration data 224 + * @c: WRPLL current configuration record 225 + * @enable_bypass: fn ptr to code to bypass the WRPLL (if applicable; else NULL) 226 + * @disable_bypass: fn ptr to code to not bypass the WRPLL (or NULL) 227 + * @cfg0_offs: WRPLL CFG0 register offset (in bytes) from the PRCI base address 228 + * @cfg1_offs: WRPLL CFG1 register offset (in bytes) from the PRCI base address 229 + * 230 + * @enable_bypass and @disable_bypass are used for WRPLL instances 231 + * that contain a separate external glitchless clock mux downstream 232 + * from the PLL. The WRPLL internal bypass mux is not glitchless. 233 + */ 234 + struct __prci_wrpll_data { 235 + struct wrpll_cfg c; 236 + void (*enable_bypass)(struct __prci_data *pd); 237 + void (*disable_bypass)(struct __prci_data *pd); 238 + u8 cfg0_offs; 239 + u8 cfg1_offs; 240 + }; 241 + 242 + /** 243 + * struct __prci_clock - describes a clock device managed by PRCI 244 + * @name: user-readable clock name string - should match the manual 245 + * @parent_name: parent name for this clock 246 + * @ops: struct clk_ops for the Linux clock framework to use for control 247 + * @hw: Linux-private clock data 248 + * @pwd: WRPLL-specific data, associated with this clock (if not NULL) 249 + * @pd: PRCI-specific data associated with this clock (if not NULL) 250 + * 251 + * PRCI clock data. Used by the PRCI driver to register PRCI-provided 252 + * clocks to the Linux clock infrastructure. 253 + */ 254 + struct __prci_clock { 255 + const char *name; 256 + const char *parent_name; 257 + const struct clk_ops *ops; 258 + struct clk_hw hw; 259 + struct __prci_wrpll_data *pwd; 260 + struct __prci_data *pd; 261 + }; 262 + 263 + #define clk_hw_to_prci_clock(pwd) container_of(pwd, struct __prci_clock, hw) 264 + 265 + /* 266 + * struct prci_clk_desc - describes the information of clocks of each SoCs 267 + * @clks: point to a array of __prci_clock 268 + * @num_clks: the number of element of clks 269 + */ 270 + struct prci_clk_desc { 271 + struct __prci_clock *clks; 272 + size_t num_clks; 273 + }; 274 + 275 + /* Core clock mux control */ 276 + void sifive_prci_coreclksel_use_hfclk(struct __prci_data *pd); 277 + void sifive_prci_coreclksel_use_corepll(struct __prci_data *pd); 278 + void sifive_prci_coreclksel_use_final_corepll(struct __prci_data *pd); 279 + void sifive_prci_corepllsel_use_dvfscorepll(struct __prci_data *pd); 280 + void sifive_prci_corepllsel_use_corepll(struct __prci_data *pd); 281 + void sifive_prci_hfpclkpllsel_use_hfclk(struct __prci_data *pd); 282 + void sifive_prci_hfpclkpllsel_use_hfpclkpll(struct __prci_data *pd); 283 + 284 + /* Linux clock framework integration */ 285 + long sifive_prci_wrpll_round_rate(struct clk_hw *hw, unsigned long rate, 286 + unsigned long *parent_rate); 287 + int sifive_prci_wrpll_set_rate(struct clk_hw *hw, unsigned long rate, 288 + unsigned long parent_rate); 289 + int sifive_clk_is_enabled(struct clk_hw *hw); 290 + int sifive_prci_clock_enable(struct clk_hw *hw); 291 + void sifive_prci_clock_disable(struct clk_hw *hw); 292 + unsigned long sifive_prci_wrpll_recalc_rate(struct clk_hw *hw, 293 + unsigned long parent_rate); 294 + unsigned long sifive_prci_tlclksel_recalc_rate(struct clk_hw *hw, 295 + unsigned long parent_rate); 296 + unsigned long sifive_prci_hfpclkplldiv_recalc_rate(struct clk_hw *hw, 297 + unsigned long parent_rate); 298 + 299 + #endif /* __SIFIVE_CLK_SIFIVE_PRCI_H */
+1
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
··· 389 389 { .val = 1, .div = 2 }, 390 390 { .val = 2, .div = 4 }, 391 391 { .val = 3, .div = 6 }, 392 + { /* Sentinel */ }, 392 393 }; 393 394 static const char * const ths_parents[] = { "osc24M" }; 394 395 static struct ccu_div ths_clk = {
+1
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
··· 322 322 { .val = 1, .div = 2 }, 323 323 { .val = 2, .div = 4 }, 324 324 { .val = 3, .div = 6 }, 325 + { /* Sentinel */ }, 325 326 }; 326 327 static SUNXI_CCU_DIV_TABLE_WITH_GATE(ths_clk, "ths", "osc24M", 327 328 0x074, 0, 2, ths_div_table, BIT(31), 0);
+3 -3
drivers/clk/tegra/clk-bpmp.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Copyright (C) 2016 NVIDIA Corporation 3 + * Copyright (C) 2016-2020 NVIDIA Corporation 4 4 */ 5 5 6 6 #include <linux/clk-provider.h> ··· 174 174 int err; 175 175 176 176 memset(&request, 0, sizeof(request)); 177 - request.rate = rate; 177 + request.rate = min_t(u64, rate, S64_MAX); 178 178 179 179 memset(&msg, 0, sizeof(msg)); 180 180 msg.cmd = CMD_CLK_ROUND_RATE; ··· 256 256 struct tegra_bpmp_clk_message msg; 257 257 258 258 memset(&request, 0, sizeof(request)); 259 - request.rate = rate; 259 + request.rate = min_t(u64, rate, S64_MAX); 260 260 261 261 memset(&msg, 0, sizeof(msg)); 262 262 msg.cmd = CMD_CLK_SET_RATE;
+2 -2
drivers/clk/tegra/clk-dfll.c
··· 1856 1856 &td->reg_init_uV); 1857 1857 if (!ret) { 1858 1858 dev_err(td->dev, "couldn't get initialized voltage\n"); 1859 - return ret; 1859 + return -EINVAL; 1860 1860 } 1861 1861 1862 1862 ret = read_dt_param(td, "nvidia,pwm-period-nanoseconds", &pwm_period); 1863 1863 if (!ret) { 1864 1864 dev_err(td->dev, "couldn't get PWM period\n"); 1865 - return ret; 1865 + return -EINVAL; 1866 1866 } 1867 1867 td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES - 1); 1868 1868
+1
drivers/clk/tegra/clk-id.h
··· 227 227 tegra_clk_sdmmc4, 228 228 tegra_clk_sdmmc4_8, 229 229 tegra_clk_se, 230 + tegra_clk_se_10, 230 231 tegra_clk_soc_therm, 231 232 tegra_clk_soc_therm_8, 232 233 tegra_clk_sor0,
+1 -1
drivers/clk/tegra/clk-tegra-periph.c
··· 630 630 INT8("host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_8), 631 631 INT8("host1x", mux_pllc4_out1_pllc_pllc4_out2_pllp_clkm_plla_pllc4_out0, CLK_SOURCE_HOST1X, 28, 0, tegra_clk_host1x_9), 632 632 INT8("se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), 633 - INT8("se", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se), 633 + INT8("se", mux_pllp_pllc2_c_c3_clkm, CLK_SOURCE_SE, 127, TEGRA_PERIPH_ON_APB, tegra_clk_se_10), 634 634 INT8("2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, 0, tegra_clk_gr2d_8), 635 635 INT8("3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, 0, tegra_clk_gr3d_8), 636 636 INT8("vic03", mux_pllm_pllc_pllp_plla_pllc2_c3_clkm, CLK_SOURCE_VIC03, 178, 0, tegra_clk_vic03),
+11 -1
drivers/clk/ti/clk-54xx.c
··· 605 605 int __init omap5xxx_dt_clk_init(void) 606 606 { 607 607 int rc; 608 - struct clk *abe_dpll_ref, *abe_dpll, *sys_32k_ck, *usb_dpll; 608 + struct clk *abe_dpll_ref, *abe_dpll, *abe_dpll_byp, *sys_32k_ck, *usb_dpll; 609 609 610 610 ti_dt_clocks_register(omap54xx_clks); 611 611 ··· 616 616 abe_dpll_ref = clk_get_sys(NULL, "abe_dpll_clk_mux"); 617 617 sys_32k_ck = clk_get_sys(NULL, "sys_32k_ck"); 618 618 rc = clk_set_parent(abe_dpll_ref, sys_32k_ck); 619 + 620 + /* 621 + * This must also be set to sys_32k_ck to match or 622 + * the ABE DPLL will not lock on a warm reboot when 623 + * ABE timers are used. 624 + */ 625 + abe_dpll_byp = clk_get_sys(NULL, "abe_dpll_bypass_clk_mux"); 626 + if (!rc) 627 + rc = clk_set_parent(abe_dpll_byp, sys_32k_ck); 628 + 619 629 abe_dpll = clk_get_sys(NULL, "dpll_abe_ck"); 620 630 if (!rc) 621 631 rc = clk_set_rate(abe_dpll, OMAP5_DPLL_ABE_DEFFREQ);
+9 -2
drivers/clk/ti/fapll.c
··· 498 498 { 499 499 struct clk_init_data *init; 500 500 struct fapll_synth *synth; 501 + struct clk *clk = ERR_PTR(-ENOMEM); 501 502 502 503 init = kzalloc(sizeof(*init), GFP_KERNEL); 503 504 if (!init) ··· 521 520 synth->hw.init = init; 522 521 synth->clk_pll = pll_clk; 523 522 524 - return clk_register(NULL, &synth->hw); 523 + clk = clk_register(NULL, &synth->hw); 524 + if (IS_ERR(clk)) { 525 + pr_err("failed to register clock\n"); 526 + goto free; 527 + } 528 + 529 + return clk; 525 530 526 531 free: 527 532 kfree(synth); 528 533 kfree(init); 529 534 530 - return ERR_PTR(-ENOMEM); 535 + return clk; 531 536 } 532 537 533 538 static void __init ti_fapll_setup(struct device_node *node)
+11
include/dt-bindings/clock/at91.h
··· 25 25 #define PMC_PLLBCK 8 26 26 #define PMC_AUDIOPLLCK 9 27 27 28 + /* SAMA7G5 */ 29 + #define PMC_CPUPLL (PMC_MAIN + 1) 30 + #define PMC_SYSPLL (PMC_MAIN + 2) 31 + #define PMC_DDRPLL (PMC_MAIN + 3) 32 + #define PMC_IMGPLL (PMC_MAIN + 4) 33 + #define PMC_BAUDPLL (PMC_MAIN + 5) 34 + #define PMC_AUDIOPMCPLL (PMC_MAIN + 6) 35 + #define PMC_AUDIOIOPLL (PMC_MAIN + 7) 36 + #define PMC_ETHPLL (PMC_MAIN + 8) 37 + #define PMC_CPU (PMC_MAIN + 9) 38 + 28 39 #ifndef AT91_PMC_MOSCS 29 40 #define AT91_PMC_MOSCS 0 /* MOSCS Flag */ 30 41 #define AT91_PMC_LOCKA 1 /* PLLA Lock */
+15
include/dt-bindings/clock/fsl,qoriq-clockgen.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef DT_CLOCK_FSL_QORIQ_CLOCKGEN_H 4 + #define DT_CLOCK_FSL_QORIQ_CLOCKGEN_H 5 + 6 + #define QORIQ_CLK_SYSCLK 0 7 + #define QORIQ_CLK_CMUX 1 8 + #define QORIQ_CLK_HWACCEL 2 9 + #define QORIQ_CLK_FMAN 3 10 + #define QORIQ_CLK_PLATFORM_PLL 4 11 + #define QORIQ_CLK_CORECLK 5 12 + 13 + #define QORIQ_CLK_PLL_DIV(x) ((x) - 1) 14 + 15 + #endif /* DT_CLOCK_FSL_QORIQ_CLOCKGEN_H */
+2
include/dt-bindings/clock/g12a-clkc.h
··· 147 147 #define CLKID_SPICC1_SCLK 261 148 148 #define CLKID_NNA_AXI_CLK 264 149 149 #define CLKID_NNA_CORE_CLK 267 150 + #define CLKID_MIPI_DSI_PXCLK_SEL 269 151 + #define CLKID_MIPI_DSI_PXCLK 270 150 152 151 153 #endif /* __G12A_CLKC_H */
+45 -11
include/dt-bindings/clock/k210-clk.h
··· 3 3 * Copyright (C) 2019-20 Sean Anderson <seanga2@gmail.com> 4 4 * Copyright (c) 2020 Western Digital Corporation or its affiliates. 5 5 */ 6 - #ifndef K210_CLK_H 7 - #define K210_CLK_H 6 + #ifndef CLOCK_K210_CLK_H 7 + #define CLOCK_K210_CLK_H 8 8 9 9 /* 10 - * Arbitrary identifiers for clocks. 11 - * The structure is: in0 -> pll0 -> aclk -> cpu 12 - * 13 - * Since we use the hardware defaults for now, set all these to the same clock. 10 + * Kendryte K210 SoC clock identifiers (arbitrary values). 14 11 */ 15 - #define K210_CLK_PLL0 0 16 - #define K210_CLK_PLL1 0 17 - #define K210_CLK_ACLK 0 18 - #define K210_CLK_CPU 0 12 + #define K210_CLK_ACLK 0 13 + #define K210_CLK_CPU 0 14 + #define K210_CLK_SRAM0 1 15 + #define K210_CLK_SRAM1 2 16 + #define K210_CLK_AI 3 17 + #define K210_CLK_DMA 4 18 + #define K210_CLK_FFT 5 19 + #define K210_CLK_ROM 6 20 + #define K210_CLK_DVP 7 21 + #define K210_CLK_APB0 8 22 + #define K210_CLK_APB1 9 23 + #define K210_CLK_APB2 10 24 + #define K210_CLK_I2S0 11 25 + #define K210_CLK_I2S1 12 26 + #define K210_CLK_I2S2 13 27 + #define K210_CLK_I2S0_M 14 28 + #define K210_CLK_I2S1_M 15 29 + #define K210_CLK_I2S2_M 16 30 + #define K210_CLK_WDT0 17 31 + #define K210_CLK_WDT1 18 32 + #define K210_CLK_SPI0 19 33 + #define K210_CLK_SPI1 20 34 + #define K210_CLK_SPI2 21 35 + #define K210_CLK_I2C0 22 36 + #define K210_CLK_I2C1 23 37 + #define K210_CLK_I2C2 24 38 + #define K210_CLK_SPI3 25 39 + #define K210_CLK_TIMER0 26 40 + #define K210_CLK_TIMER1 27 41 + #define K210_CLK_TIMER2 28 42 + #define K210_CLK_GPIO 29 43 + #define K210_CLK_UART1 30 44 + #define K210_CLK_UART2 31 45 + #define K210_CLK_UART3 32 46 + #define K210_CLK_FPIOA 33 47 + #define K210_CLK_SHA 34 48 + #define K210_CLK_AES 35 49 + #define K210_CLK_OTP 36 50 + #define K210_CLK_RTC 37 19 51 20 - #endif /* K210_CLK_H */ 52 + #define K210_NUM_CLKS 38 53 + 54 + #endif /* CLOCK_K210_CLK_H */
+121
include/dt-bindings/clock/qcom,camcc-sc7180.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H 7 + #define _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H 8 + 9 + /* CAM_CC clocks */ 10 + #define CAM_CC_PLL2_OUT_EARLY 0 11 + #define CAM_CC_PLL0 1 12 + #define CAM_CC_PLL1 2 13 + #define CAM_CC_PLL2 3 14 + #define CAM_CC_PLL2_OUT_AUX 4 15 + #define CAM_CC_PLL3 5 16 + #define CAM_CC_CAMNOC_AXI_CLK 6 17 + #define CAM_CC_CCI_0_CLK 7 18 + #define CAM_CC_CCI_0_CLK_SRC 8 19 + #define CAM_CC_CCI_1_CLK 9 20 + #define CAM_CC_CCI_1_CLK_SRC 10 21 + #define CAM_CC_CORE_AHB_CLK 11 22 + #define CAM_CC_CPAS_AHB_CLK 12 23 + #define CAM_CC_CPHY_RX_CLK_SRC 13 24 + #define CAM_CC_CSI0PHYTIMER_CLK 14 25 + #define CAM_CC_CSI0PHYTIMER_CLK_SRC 15 26 + #define CAM_CC_CSI1PHYTIMER_CLK 16 27 + #define CAM_CC_CSI1PHYTIMER_CLK_SRC 17 28 + #define CAM_CC_CSI2PHYTIMER_CLK 18 29 + #define CAM_CC_CSI2PHYTIMER_CLK_SRC 19 30 + #define CAM_CC_CSI3PHYTIMER_CLK 20 31 + #define CAM_CC_CSI3PHYTIMER_CLK_SRC 21 32 + #define CAM_CC_CSIPHY0_CLK 22 33 + #define CAM_CC_CSIPHY1_CLK 23 34 + #define CAM_CC_CSIPHY2_CLK 24 35 + #define CAM_CC_CSIPHY3_CLK 25 36 + #define CAM_CC_FAST_AHB_CLK_SRC 26 37 + #define CAM_CC_ICP_APB_CLK 27 38 + #define CAM_CC_ICP_ATB_CLK 28 39 + #define CAM_CC_ICP_CLK 29 40 + #define CAM_CC_ICP_CLK_SRC 30 41 + #define CAM_CC_ICP_CTI_CLK 31 42 + #define CAM_CC_ICP_TS_CLK 32 43 + #define CAM_CC_IFE_0_AXI_CLK 33 44 + #define CAM_CC_IFE_0_CLK 34 45 + #define CAM_CC_IFE_0_CLK_SRC 35 46 + #define CAM_CC_IFE_0_CPHY_RX_CLK 36 47 + #define CAM_CC_IFE_0_CSID_CLK 37 48 + #define CAM_CC_IFE_0_CSID_CLK_SRC 38 49 + #define CAM_CC_IFE_0_DSP_CLK 39 50 + #define CAM_CC_IFE_1_AXI_CLK 40 51 + #define CAM_CC_IFE_1_CLK 41 52 + #define CAM_CC_IFE_1_CLK_SRC 42 53 + #define CAM_CC_IFE_1_CPHY_RX_CLK 43 54 + #define CAM_CC_IFE_1_CSID_CLK 44 55 + #define CAM_CC_IFE_1_CSID_CLK_SRC 45 56 + #define CAM_CC_IFE_1_DSP_CLK 46 57 + #define CAM_CC_IFE_LITE_CLK 47 58 + #define CAM_CC_IFE_LITE_CLK_SRC 48 59 + #define CAM_CC_IFE_LITE_CPHY_RX_CLK 49 60 + #define CAM_CC_IFE_LITE_CSID_CLK 50 61 + #define CAM_CC_IFE_LITE_CSID_CLK_SRC 51 62 + #define CAM_CC_IPE_0_AHB_CLK 52 63 + #define CAM_CC_IPE_0_AREG_CLK 53 64 + #define CAM_CC_IPE_0_AXI_CLK 54 65 + #define CAM_CC_IPE_0_CLK 55 66 + #define CAM_CC_IPE_0_CLK_SRC 56 67 + #define CAM_CC_JPEG_CLK 57 68 + #define CAM_CC_JPEG_CLK_SRC 58 69 + #define CAM_CC_LRME_CLK 59 70 + #define CAM_CC_LRME_CLK_SRC 60 71 + #define CAM_CC_MCLK0_CLK 61 72 + #define CAM_CC_MCLK0_CLK_SRC 62 73 + #define CAM_CC_MCLK1_CLK 63 74 + #define CAM_CC_MCLK1_CLK_SRC 64 75 + #define CAM_CC_MCLK2_CLK 65 76 + #define CAM_CC_MCLK2_CLK_SRC 66 77 + #define CAM_CC_MCLK3_CLK 67 78 + #define CAM_CC_MCLK3_CLK_SRC 68 79 + #define CAM_CC_MCLK4_CLK 69 80 + #define CAM_CC_MCLK4_CLK_SRC 70 81 + #define CAM_CC_BPS_AHB_CLK 71 82 + #define CAM_CC_BPS_AREG_CLK 72 83 + #define CAM_CC_BPS_AXI_CLK 73 84 + #define CAM_CC_BPS_CLK 74 85 + #define CAM_CC_BPS_CLK_SRC 75 86 + #define CAM_CC_SLOW_AHB_CLK_SRC 76 87 + #define CAM_CC_SOC_AHB_CLK 77 88 + #define CAM_CC_SYS_TMR_CLK 78 89 + 90 + /* CAM_CC power domains */ 91 + #define BPS_GDSC 0 92 + #define IFE_0_GDSC 1 93 + #define IFE_1_GDSC 2 94 + #define IPE_0_GDSC 3 95 + #define TITAN_TOP_GDSC 4 96 + 97 + /* CAM_CC resets */ 98 + #define CAM_CC_BPS_BCR 0 99 + #define CAM_CC_CAMNOC_BCR 1 100 + #define CAM_CC_CCI_0_BCR 2 101 + #define CAM_CC_CCI_1_BCR 3 102 + #define CAM_CC_CPAS_BCR 4 103 + #define CAM_CC_CSI0PHY_BCR 5 104 + #define CAM_CC_CSI1PHY_BCR 6 105 + #define CAM_CC_CSI2PHY_BCR 7 106 + #define CAM_CC_CSI3PHY_BCR 8 107 + #define CAM_CC_ICP_BCR 9 108 + #define CAM_CC_IFE_0_BCR 10 109 + #define CAM_CC_IFE_1_BCR 11 110 + #define CAM_CC_IFE_LITE_BCR 12 111 + #define CAM_CC_IPE_0_BCR 13 112 + #define CAM_CC_JPEG_BCR 14 113 + #define CAM_CC_LRME_BCR 15 114 + #define CAM_CC_MCLK0_BCR 16 115 + #define CAM_CC_MCLK1_BCR 17 116 + #define CAM_CC_MCLK2_BCR 18 117 + #define CAM_CC_MCLK3_BCR 19 118 + #define CAM_CC_MCLK4_BCR 20 119 + #define CAM_CC_TITAN_TOP_BCR 21 120 + 121 + #endif
+117
include/dt-bindings/clock/qcom,gcc-sdx55.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 + /* 3 + * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2020, Linaro Ltd. 5 + */ 6 + 7 + #ifndef _DT_BINDINGS_CLK_QCOM_GCC_SDX55_H 8 + #define _DT_BINDINGS_CLK_QCOM_GCC_SDX55_H 9 + 10 + #define GPLL0 3 11 + #define GPLL0_OUT_EVEN 4 12 + #define GPLL4 5 13 + #define GPLL4_OUT_EVEN 6 14 + #define GPLL5 7 15 + #define GCC_AHB_PCIE_LINK_CLK 8 16 + #define GCC_BLSP1_AHB_CLK 9 17 + #define GCC_BLSP1_QUP1_I2C_APPS_CLK 10 18 + #define GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC 11 19 + #define GCC_BLSP1_QUP1_SPI_APPS_CLK 12 20 + #define GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC 13 21 + #define GCC_BLSP1_QUP2_I2C_APPS_CLK 14 22 + #define GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC 15 23 + #define GCC_BLSP1_QUP2_SPI_APPS_CLK 16 24 + #define GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC 17 25 + #define GCC_BLSP1_QUP3_I2C_APPS_CLK 18 26 + #define GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC 19 27 + #define GCC_BLSP1_QUP3_SPI_APPS_CLK 20 28 + #define GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC 21 29 + #define GCC_BLSP1_QUP4_I2C_APPS_CLK 22 30 + #define GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC 23 31 + #define GCC_BLSP1_QUP4_SPI_APPS_CLK 24 32 + #define GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC 25 33 + #define GCC_BLSP1_UART1_APPS_CLK 26 34 + #define GCC_BLSP1_UART1_APPS_CLK_SRC 27 35 + #define GCC_BLSP1_UART2_APPS_CLK 28 36 + #define GCC_BLSP1_UART2_APPS_CLK_SRC 29 37 + #define GCC_BLSP1_UART3_APPS_CLK 30 38 + #define GCC_BLSP1_UART3_APPS_CLK_SRC 31 39 + #define GCC_BLSP1_UART4_APPS_CLK 32 40 + #define GCC_BLSP1_UART4_APPS_CLK_SRC 33 41 + #define GCC_BOOT_ROM_AHB_CLK 34 42 + #define GCC_CE1_AHB_CLK 35 43 + #define GCC_CE1_AXI_CLK 36 44 + #define GCC_CE1_CLK 37 45 + #define GCC_CPUSS_AHB_CLK 38 46 + #define GCC_CPUSS_AHB_CLK_SRC 39 47 + #define GCC_CPUSS_GNOC_CLK 40 48 + #define GCC_CPUSS_RBCPR_CLK 41 49 + #define GCC_CPUSS_RBCPR_CLK_SRC 42 50 + #define GCC_EMAC_CLK_SRC 43 51 + #define GCC_EMAC_PTP_CLK_SRC 44 52 + #define GCC_ETH_AXI_CLK 45 53 + #define GCC_ETH_PTP_CLK 46 54 + #define GCC_ETH_RGMII_CLK 47 55 + #define GCC_ETH_SLAVE_AHB_CLK 48 56 + #define GCC_GP1_CLK 49 57 + #define GCC_GP1_CLK_SRC 50 58 + #define GCC_GP2_CLK 51 59 + #define GCC_GP2_CLK_SRC 52 60 + #define GCC_GP3_CLK 53 61 + #define GCC_GP3_CLK_SRC 54 62 + #define GCC_PCIE_0_CLKREF_CLK 55 63 + #define GCC_PCIE_AUX_CLK 56 64 + #define GCC_PCIE_AUX_PHY_CLK_SRC 57 65 + #define GCC_PCIE_CFG_AHB_CLK 58 66 + #define GCC_PCIE_MSTR_AXI_CLK 59 67 + #define GCC_PCIE_PIPE_CLK 60 68 + #define GCC_PCIE_RCHNG_PHY_CLK 61 69 + #define GCC_PCIE_RCHNG_PHY_CLK_SRC 62 70 + #define GCC_PCIE_SLEEP_CLK 63 71 + #define GCC_PCIE_SLV_AXI_CLK 64 72 + #define GCC_PCIE_SLV_Q2A_AXI_CLK 65 73 + #define GCC_PDM2_CLK 66 74 + #define GCC_PDM2_CLK_SRC 67 75 + #define GCC_PDM_AHB_CLK 68 76 + #define GCC_PDM_XO4_CLK 69 77 + #define GCC_SDCC1_AHB_CLK 70 78 + #define GCC_SDCC1_APPS_CLK 71 79 + #define GCC_SDCC1_APPS_CLK_SRC 72 80 + #define GCC_SYS_NOC_CPUSS_AHB_CLK 73 81 + #define GCC_USB30_MASTER_CLK 74 82 + #define GCC_USB30_MASTER_CLK_SRC 75 83 + #define GCC_USB30_MOCK_UTMI_CLK 76 84 + #define GCC_USB30_MOCK_UTMI_CLK_SRC 77 85 + #define GCC_USB30_MSTR_AXI_CLK 78 86 + #define GCC_USB30_SLEEP_CLK 79 87 + #define GCC_USB30_SLV_AHB_CLK 80 88 + #define GCC_USB3_PHY_AUX_CLK 81 89 + #define GCC_USB3_PHY_AUX_CLK_SRC 82 90 + #define GCC_USB3_PHY_PIPE_CLK 83 91 + #define GCC_USB3_PRIM_CLKREF_CLK 84 92 + #define GCC_USB_PHY_CFG_AHB2PHY_CLK 85 93 + #define GCC_XO_DIV4_CLK 86 94 + #define GCC_XO_PCIE_LINK_CLK 87 95 + 96 + #define GCC_EMAC_BCR 0 97 + #define GCC_PCIE_BCR 1 98 + #define GCC_PCIE_LINK_DOWN_BCR 2 99 + #define GCC_PCIE_NOCSR_COM_PHY_BCR 3 100 + #define GCC_PCIE_PHY_BCR 4 101 + #define GCC_PCIE_PHY_CFG_AHB_BCR 5 102 + #define GCC_PCIE_PHY_COM_BCR 6 103 + #define GCC_PCIE_PHY_NOCSR_COM_PHY_BCR 7 104 + #define GCC_PDM_BCR 8 105 + #define GCC_QUSB2PHY_BCR 9 106 + #define GCC_TCSR_PCIE_BCR 10 107 + #define GCC_USB30_BCR 11 108 + #define GCC_USB3_PHY_BCR 12 109 + #define GCC_USB3PHY_PHY_BCR 13 110 + #define GCC_USB_PHY_CFG_AHB2PHY_BCR 14 111 + 112 + /* GCC power domains */ 113 + #define USB30_GDSC 0 114 + #define PCIE_GDSC 1 115 + #define EMAC_GDSC 2 116 + 117 + #endif
+10
include/dt-bindings/clock/qcom,rpmh.h
··· 21 21 #define RPMH_IPA_CLK 12 22 22 #define RPMH_LN_BB_CLK1 13 23 23 #define RPMH_LN_BB_CLK1_A 14 24 + #define RPMH_CE_CLK 15 25 + #define RPMH_QPIC_CLK 16 26 + #define RPMH_DIV_CLK1 17 27 + #define RPMH_DIV_CLK1_A 18 28 + #define RPMH_RF_CLK4 19 29 + #define RPMH_RF_CLK4_A 20 30 + #define RPMH_RF_CLK5 21 31 + #define RPMH_RF_CLK5_A 22 32 + #define RPMH_PKA_CLK 23 33 + #define RPMH_HWKM_CLK 24 24 34 25 35 #endif
+11
include/dt-bindings/clock/qcom,sm8250-lpass-aoncc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H 4 + #define _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H 5 + 6 + /* from AOCC */ 7 + #define LPASS_CDC_VA_MCLK 0 8 + #define LPASS_CDC_TX_NPL 1 9 + #define LPASS_CDC_TX_MCLK 2 10 + 11 + #endif /* _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H */
+13
include/dt-bindings/clock/qcom,sm8250-lpass-audiocc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H 4 + #define _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H 5 + 6 + /* From AudioCC */ 7 + #define LPASS_CDC_WSA_NPL 0 8 + #define LPASS_CDC_WSA_MCLK 1 9 + #define LPASS_CDC_RX_MCLK 2 10 + #define LPASS_CDC_RX_NPL 3 11 + #define LPASS_CDC_RX_MCLK_MCLK2 4 12 + 13 + #endif /* _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H */
+23
include/dt-bindings/clock/sifive-fu740-prci.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (C) 2019 SiFive, Inc. 4 + * Wesley Terpstra 5 + * Paul Walmsley 6 + * Zong Li 7 + */ 8 + 9 + #ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H 10 + #define __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H 11 + 12 + /* Clock indexes for use by Device Tree data and the PRCI driver */ 13 + 14 + #define PRCI_CLK_COREPLL 0 15 + #define PRCI_CLK_DDRPLL 1 16 + #define PRCI_CLK_GEMGXLPLL 2 17 + #define PRCI_CLK_DVFSCOREPLL 3 18 + #define PRCI_CLK_HFPCLKPLL 4 19 + #define PRCI_CLK_CLTXPLL 5 20 + #define PRCI_CLK_TLCLK 6 21 + #define PRCI_CLK_PCLK 7 22 + 23 + #endif /* __DT_BINDINGS_CLOCK_SIFIVE_FU740_PRCI_H */
+39
include/linux/clk-provider.h
··· 639 639 const struct clk_parent_data *parent_data, unsigned long flags, 640 640 void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, 641 641 const struct clk_div_table *table, spinlock_t *lock); 642 + struct clk_hw *__devm_clk_hw_register_divider(struct device *dev, 643 + struct device_node *np, const char *name, 644 + const char *parent_name, const struct clk_hw *parent_hw, 645 + const struct clk_parent_data *parent_data, unsigned long flags, 646 + void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags, 647 + const struct clk_div_table *table, spinlock_t *lock); 642 648 struct clk *clk_register_divider_table(struct device *dev, const char *name, 643 649 const char *parent_name, unsigned long flags, 644 650 void __iomem *reg, u8 shift, u8 width, ··· 785 779 (parent_data), (flags), (reg), (shift), \ 786 780 (width), (clk_divider_flags), (table), \ 787 781 (lock)) 782 + /** 783 + * devm_clk_hw_register_divider_table - register a table based divider clock 784 + * with the clock framework (devres variant) 785 + * @dev: device registering this clock 786 + * @name: name of this clock 787 + * @parent_name: name of clock's parent 788 + * @flags: framework-specific flags 789 + * @reg: register address to adjust divider 790 + * @shift: number of bits to shift the bitfield 791 + * @width: width of the bitfield 792 + * @clk_divider_flags: divider-specific flags for this clock 793 + * @table: array of divider/value pairs ending with a div set to 0 794 + * @lock: shared register lock for this clock 795 + */ 796 + #define devm_clk_hw_register_divider_table(dev, name, parent_name, flags, \ 797 + reg, shift, width, \ 798 + clk_divider_flags, table, lock) \ 799 + __devm_clk_hw_register_divider((dev), NULL, (name), (parent_name), \ 800 + NULL, NULL, (flags), (reg), (shift), \ 801 + (width), (clk_divider_flags), (table), \ 802 + (lock)) 788 803 789 804 void clk_unregister_divider(struct clk *clk); 790 805 void clk_hw_unregister_divider(struct clk_hw *hw); ··· 1089 1062 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 1090 1063 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 1091 1064 unsigned long flags); 1065 + struct clk_hw *devm_clk_hw_register_composite_pdata(struct device *dev, 1066 + const char *name, const struct clk_parent_data *parent_data, 1067 + int num_parents, 1068 + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 1069 + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 1070 + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 1071 + unsigned long flags); 1092 1072 void clk_hw_unregister_composite(struct clk_hw *hw); 1093 1073 1094 1074 struct clk *clk_register(struct device *dev, struct clk_hw *hw); ··· 1122 1088 return (struct clk_hw *)clk; 1123 1089 } 1124 1090 #endif 1091 + 1092 + struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id); 1093 + struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw, 1094 + const char *con_id); 1095 + 1125 1096 unsigned int clk_hw_get_num_parents(const struct clk_hw *hw); 1126 1097 struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw); 1127 1098 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
+19 -1
include/linux/clk.h
··· 110 110 int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); 111 111 112 112 /** 113 + * devm_clk_notifier_register - register a managed rate-change notifier callback 114 + * @dev: device for clock "consumer" 115 + * @clk: clock whose rate we are interested in 116 + * @nb: notifier block with callback function pointer 117 + * 118 + * Returns 0 on success, -EERROR otherwise 119 + */ 120 + int devm_clk_notifier_register(struct device *dev, struct clk *clk, 121 + struct notifier_block *nb); 122 + 123 + /** 113 124 * clk_get_accuracy - obtain the clock accuracy in ppb (parts per billion) 114 125 * for a clock source. 115 126 * @clk: clock source ··· 161 150 int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den); 162 151 163 152 /** 164 - * clk_get_duty_cycle - return the duty cycle ratio of a clock signal 153 + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal 165 154 * @clk: clock signal source 166 155 * @scale: scaling factor to be applied to represent the ratio as an integer 167 156 * ··· 193 182 194 183 static inline int clk_notifier_unregister(struct clk *clk, 195 184 struct notifier_block *nb) 185 + { 186 + return -ENOTSUPP; 187 + } 188 + 189 + static inline int devm_clk_notifier_register(struct device *dev, 190 + struct clk *clk, 191 + struct notifier_block *nb) 196 192 { 197 193 return -ENOTSUPP; 198 194 }
+2 -2
include/linux/clk/samsung.h
··· 10 10 11 11 struct device_node; 12 12 13 - #ifdef CONFIG_ARCH_S3C64XX 13 + #ifdef CONFIG_S3C64XX_COMMON_CLK 14 14 void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, 15 15 unsigned long xusbxti_f, bool s3c6400, 16 16 void __iomem *base); ··· 19 19 unsigned long xtal_f, 20 20 unsigned long xusbxti_f, 21 21 bool s3c6400, void __iomem *base) { } 22 - #endif /* CONFIG_ARCH_S3C64XX */ 22 + #endif /* CONFIG_S3C64XX_COMMON_CLK */ 23 23 24 24 #ifdef CONFIG_S3C2410_COMMON_CLK 25 25 void s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+44
include/trace/events/clk.h
··· 118 118 TP_ARGS(core, rate) 119 119 ); 120 120 121 + DEFINE_EVENT(clk_rate, clk_set_min_rate, 122 + 123 + TP_PROTO(struct clk_core *core, unsigned long rate), 124 + 125 + TP_ARGS(core, rate) 126 + ); 127 + 128 + DEFINE_EVENT(clk_rate, clk_set_max_rate, 129 + 130 + TP_PROTO(struct clk_core *core, unsigned long rate), 131 + 132 + TP_ARGS(core, rate) 133 + ); 134 + 135 + DECLARE_EVENT_CLASS(clk_rate_range, 136 + 137 + TP_PROTO(struct clk_core *core, unsigned long min, unsigned long max), 138 + 139 + TP_ARGS(core, min, max), 140 + 141 + TP_STRUCT__entry( 142 + __string( name, core->name ) 143 + __field(unsigned long, min ) 144 + __field(unsigned long, max ) 145 + ), 146 + 147 + TP_fast_assign( 148 + __assign_str(name, core->name); 149 + __entry->min = min; 150 + __entry->max = max; 151 + ), 152 + 153 + TP_printk("%s min %lu max %lu", __get_str(name), 154 + (unsigned long)__entry->min, 155 + (unsigned long)__entry->max) 156 + ); 157 + 158 + DEFINE_EVENT(clk_rate_range, clk_set_rate_range, 159 + 160 + TP_PROTO(struct clk_core *core, unsigned long min, unsigned long max), 161 + 162 + TP_ARGS(core, min, max) 163 + ); 164 + 121 165 DECLARE_EVENT_CLASS(clk_parent, 122 166 123 167 TP_PROTO(struct clk_core *core, struct clk_core *parent),