diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-01 23:26:16 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-01 23:26:16 +0300 |
commit | 514798d36572fb8eba6ccff3de10c9615063a7f5 (patch) | |
tree | a0cd9a40472747630ce004eec62c5e06b5e14a57 | |
parent | e058a84bfddc42ba356a2316f2cf1141974625c9 (diff) | |
parent | d2b21013bf5fb177c08b2c9c4dfa32ee0fc97b53 (diff) | |
download | linux-514798d36572fb8eba6ccff3de10c9615063a7f5.tar.xz |
Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
Pull clk updates from Stephen Boyd:
"This round has a diffstat dominated by Qualcomm clk drivers. Honestly
though that's just a bunch of data so the diffstat reflects that.
Looking beyond that there's just a bunch of updates all around in
various clk drivers. Renesas and NXP (for i.MX) are two SoC vendors
that have a lot of patches in here.
Overall the driver changes look to be mostly enabling more clks and
non-critical fixes that we could hold until the next merge window.
I'm especially excited about the series from Arnd that graduates
clkdev to be the only implementation of clk_get() and clk_put().
That's a good step in the right direction to migreate eveerything over
to the common clk framework. Now we don't have to worry about clkdev
specific details, they're just part of the clk API now.
Core:
- clkdev is now the only option, i.e. clk_get()/clk_put() is
implemented in only one place in the kernel instead of in
drivers/clk/clkdev.c and in architectures that want their own
implementation
New Drivers:
- Texas Instruments' LMK04832 Ultra Low-Noise JESD204B Compliant
Clock Jitter Cleaner With Dual Loop PLLs
- Qualcomm MDM9607 GCC
- Qualcomm SC8180X display clks
- Qualcomm SM6125 GCC
- Qualcomm SM8250 CAMCC (camera)
- Renesas RZ/G2L SoC
- Hisilicon hi3559A SoC
Updates:
- Stop using clock-output-names in ST clk drivers (yay!)
- Support secure mode of STM32MP1 SoCs
- Improve clock support for Actions S500 SoC
- duty cycle setting support on qcom clks
- Add TI am33xx spread spectrum clock support
- Use determine_rate() for the Amlogic pll ops instead of
round_rate()
- Restrict Amlogic gp0/1 and audio plls range on g12a/sm1
- Improve Amlogic axg-audio controller error on deferral
- Add NNA clocks on Amlogic g12a
- Reduce memory footprint of Rockchip PLL rate tables
- A fix for the newly added Rockchip rk3568 clk driver
- Exported clock for the newly added Rockchip video decoder
- Remove audio ipg clock from i.MX8MP
- Remove deprecated legacy clock binding for i.MX SCU clock driver
- Use common clk-imx8qxp for both i.MX8QXP and i.MX8QM
- Add multiple clocks to clk-imx8qxp driver (enet, hdmi, lcdif,
audio, parallel interface)
- Add dedicated clock ops for i.MX paralel interface
- Different fixes for clocks controlled by ATF on i.MX SoCs
- Add A53/A72 frequency scaling support i.MX clk-scu driver
- Add special case for DCSS clock on suspend for i.MX clk-scu driver
- Add parent save/restore on suspend/resume to i.MX clk-scu driver
- Skip runtime PM enablement for CPU clocks in i.MX clk-scu driver
- Remove the sys1_pll/sys2_pll clock gates for i.MX8MQ and their
bindings
- Tegra clk driver no longer deasserts resets on clk_enable as it
gets in the way of certain power-up sequences
- Fix compile testing for Tegra clk driver
- One patch to fix a divider on the Allwinner v3s Audio PLL
- Add support for CPU core clock boost modes on Renesas R-Car Gen3
- Add ISPCS (Image Signal Processor) clocks on Renesas R-Car V3U
- Switch SH/R-Mobile and R-Car "DIV6" clocks to .determine_rate() and
improve support for multiple parents
- Switch Renesas RZ/N1 divider clocks to .determine_rate()
- Add ZA2 (Audio Clock Generator) clock on Renesas R-Car D3
- Convert ar7 to common clk framework
- Convert ralink to common clk framework"
* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (161 commits)
clk: zynqmp: Handle divider specific read only flag
clk: zynqmp: Use firmware specific mux clock flags
clk: zynqmp: Use firmware specific divider clock flags
clk: zynqmp: Use firmware specific common clock flags
clk: lmk04832: Use of match table
clk: lmk04832: Depend on SPI
clk: stm32mp1: new compatible for secure RCC support
dt-bindings: clock: stm32mp1 new compatible for secure rcc
dt-bindings: reset: add MCU HOLD BOOT ID for SCMI reset domains on stm32mp15
dt-bindings: reset: add IDs for SCMI reset domains on stm32mp15
dt-bindings: clock: add IDs for SCMI clocks on stm32mp15
reset: stm32mp1: remove stm32mp1 reset
clk: hisilicon: Add clock driver for hi3559A SoC
dt-bindings: Document the hi3559a clock bindings
clk: si5341: Add sysfs properties to allow checking/resetting device faults
clk: si5341: Add silabs,iovdd-33 property
clk: si5341: Add silabs,xaxb-ext-clk property
clk: si5341: Allow different output VDD_SEL values
clk: si5341: Update initialization magic
clk: si5341: Check for input clock presence and PLL lock on startup
...
163 files changed, 18191 insertions, 2068 deletions
diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt index 395359dc94fd..fd0061712443 100644 --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt @@ -86,13 +86,11 @@ This binding uses the common clock binding[1]. Required properties: - compatible: Should be one of: - "fsl,imx8qm-clock" - "fsl,imx8qxp-clock" + "fsl,imx8qm-clk" + "fsl,imx8qxp-clk" followed by "fsl,scu-clk" -- #clock-cells: Should be either - 2: Contains the Resource and Clock ID value. - or - 1: Contains the Clock ID value. (DEPRECATED) +- #clock-cells: Should be 2. + Contains the Resource and Clock ID value. - clocks: List of clock specifiers, must contain an entry for each required entry in clock-names - clock-names: Should include entries "xtal_32KHz", "xtal_24MHz" diff --git a/Documentation/devicetree/bindings/clock/gpio-mux-clock.txt b/Documentation/devicetree/bindings/clock/gpio-mux-clock.txt deleted file mode 100644 index 2be1e038ca62..000000000000 --- a/Documentation/devicetree/bindings/clock/gpio-mux-clock.txt +++ /dev/null @@ -1,19 +0,0 @@ -Binding for simple gpio clock multiplexer. - -This binding uses the common clock binding[1]. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: -- compatible : shall be "gpio-mux-clock". -- clocks: list of two references to parent clocks. -- #clock-cells : from common clock binding; shall be set to 0. -- select-gpios : GPIO reference for selecting the parent clock. - -Example: - clock { - compatible = "gpio-mux-clock"; - clocks = <&parentclk1>, <&parentclk2>; - #clock-cells = <0>; - select-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; - }; diff --git a/Documentation/devicetree/bindings/clock/gpio-mux-clock.yaml b/Documentation/devicetree/bindings/clock/gpio-mux-clock.yaml new file mode 100644 index 000000000000..1e21f8b3a4ff --- /dev/null +++ b/Documentation/devicetree/bindings/clock/gpio-mux-clock.yaml @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/gpio-mux-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Simple GPIO clock multiplexer + +maintainers: + - Sergej Sawazki <ce3a@gmx.de> + +properties: + compatible: + const: gpio-mux-clock + + clocks: + items: + - description: First parent clock + - description: Second parent clock + + '#clock-cells': + const: 0 + + select-gpios: + description: GPIO reference for selecting the parent clock. + maxItems: 1 + +required: + - compatible + - clocks + - '#clock-cells' + - select-gpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + clock { + compatible = "gpio-mux-clock"; + clocks = <&parentclk1>, <&parentclk2>; + #clock-cells = <0>; + select-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; + }; diff --git a/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml new file mode 100644 index 000000000000..3ceb29cec704 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/hisilicon,hi3559av100-clock.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/hisilicon,hi3559av100-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon SOC Clock for HI3559AV100 + +maintainers: + - Dongjiu Geng <gengdongjiu@huawei.com> + +description: | + Hisilicon SOC clock control module which supports the clocks, resets and + power domains on HI3559AV100. + + See also: + dt-bindings/clock/hi3559av100-clock.h + +properties: + compatible: + enum: + - hisilicon,hi3559av100-clock + - hisilicon,hi3559av100-shub-clock + + reg: + minItems: 1 + maxItems: 2 + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 2 + description: | + First cell is reset request register offset. + Second cell is bit offset in reset request register. + +required: + - compatible + - reg + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@12010000 { + compatible = "hisilicon,hi3559av100-clock"; + #clock-cells = <1>; + #reset-cells = <2>; + reg = <0x0 0x12010000 0x0 0x10000>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml index c65b9458c0b6..6d6236e02c22 100644 --- a/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml +++ b/Documentation/devicetree/bindings/clock/ingenic,cgu.yaml @@ -22,6 +22,8 @@ select: enum: - ingenic,jz4740-cgu - ingenic,jz4725b-cgu + - ingenic,jz4760-cgu + - ingenic,jz4760b-cgu - ingenic,jz4770-cgu - ingenic,jz4780-cgu - ingenic,x1000-cgu @@ -49,6 +51,8 @@ properties: - enum: - ingenic,jz4740-cgu - ingenic,jz4725b-cgu + - ingenic,jz4760-cgu + - ingenic,jz4760b-cgu - ingenic,jz4770-cgu - ingenic,jz4780-cgu - ingenic,x1000-cgu diff --git a/Documentation/devicetree/bindings/clock/qcom,camcc-sm8250.yaml b/Documentation/devicetree/bindings/clock/qcom,camcc-sm8250.yaml new file mode 100644 index 000000000000..9f239c3960d1 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,camcc-sm8250.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,camcc-sm8250.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Camera Clock & Reset Controller Binding for SM8250 + +maintainers: + - Jonathan Marek <jonathan@marek.ca> + +description: | + Qualcomm camera clock control module which supports the clocks, resets and + power domains on SM8250. + + See also dt-bindings/clock/qcom,camcc-sm8250.h + +properties: + compatible: + const: qcom,sm8250-camcc + + clocks: + items: + - description: Board XO source + - description: Sleep clock source + + clock-names: + items: + - const: bi_tcxo + - const: sleep_clk + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,rpmh.h> + clock-controller@ad00000 { + compatible = "qcom,sm8250-camcc"; + reg = <0x0ad00000 0x10000>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&sleep_clk>; + clock-names = "bi_tcxo", "sleep_clk"; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml index 0cdf53f41f84..6667261dc665 100644 --- a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml @@ -20,6 +20,7 @@ description: | properties: compatible: enum: + - qcom,sc8180x-dispcc - qcom,sm8150-dispcc - qcom,sm8250-dispcc diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm6125.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6125.yaml new file mode 100644 index 000000000000..ab12b391effc --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sm6125.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,gcc-sm6125.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Global Clock & Reset Controller Binding for SM6125 + +maintainers: + - Konrad Dybcio <konrad.dybcio@somainline.org> + +description: | + Qualcomm global clock control module which supports the clocks, resets and + power domains on SM6125. + + See also: + - dt-bindings/clock/qcom,gcc-sm6125.h + +properties: + compatible: + const: qcom,gcc-sm6125 + + clocks: + items: + - description: Board XO source + - description: Sleep clock source + + clock-names: + items: + - const: bi_tcxo + - const: sleep_clk + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + + protected-clocks: + description: + Protected clock specifier list as per common clock binding. + +required: + - compatible + - clocks + - clock-names + - reg + - '#clock-cells' + - '#reset-cells' + - '#power-domain-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,rpmcc.h> + clock-controller@1400000 { + compatible = "qcom,gcc-sm6125"; + reg = <0x01400000 0x1f0000>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + clock-names = "bi_tcxo", "sleep_clk"; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&sleep_clk>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml index 490edad25830..8453eeddf30e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc.yaml @@ -26,9 +26,10 @@ description: | - dt-bindings/reset/qcom,gcc-msm8939.h - dt-bindings/clock/qcom,gcc-msm8660.h - dt-bindings/reset/qcom,gcc-msm8660.h - - dt-bindings/clock/qcom,gcc-msm8974.h - - dt-bindings/reset/qcom,gcc-msm8974.h + - dt-bindings/clock/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974) + - dt-bindings/reset/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974) - dt-bindings/clock/qcom,gcc-msm8994.h + - dt-bindings/clock/qcom,gcc-mdm9607.h - dt-bindings/clock/qcom,gcc-mdm9615.h - dt-bindings/reset/qcom,gcc-mdm9615.h - dt-bindings/clock/qcom,gcc-sdm660.h (qcom,gcc-sdm630 and qcom,gcc-sdm660) @@ -40,6 +41,8 @@ properties: - qcom,gcc-ipq4019 - qcom,gcc-ipq6018 - qcom,gcc-ipq8064 + - qcom,gcc-mdm9607 + - qcom,gcc-msm8226 - qcom,gcc-msm8660 - qcom,gcc-msm8916 - qcom,gcc-msm8939 diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt index b44a0622fb3a..6cf5a7ec2b4c 100644 --- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt +++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.txt @@ -12,6 +12,7 @@ Required properties : "qcom,rpmcc-msm8660", "qcom,rpmcc" "qcom,rpmcc-apq8060", "qcom,rpmcc" + "qcom,rpmcc-msm8226", "qcom,rpmcc" "qcom,rpmcc-msm8916", "qcom,rpmcc" "qcom,rpmcc-msm8936", "qcom,rpmcc" "qcom,rpmcc-msm8974", "qcom,rpmcc" diff --git a/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml new file mode 100644 index 000000000000..30b2e3d0d25d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/renesas,rzg2l-cpg.yaml @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Renesas RZ/G2L Clock Pulse Generator / Module Standby Mode + +maintainers: + - Geert Uytterhoeven <geert+renesas@glider.be> + +description: | + On Renesas RZ/G2L SoC, the CPG (Clock Pulse Generator) and Module + Standby Mode share the same register block. + + They provide the following functionalities: + - The CPG block generates various core clocks, + - The Module Standby Mode block provides two functions: + 1. Module Standby, providing a Clock Domain to control the clock supply + to individual SoC devices, + 2. Reset Control, to perform a software reset of individual SoC devices. + +properties: + compatible: + const: renesas,r9a07g044-cpg # RZ/G2{L,LC} + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + description: + Clock source to CPG can be either from external clock input (EXCLK) or + crystal oscillator (XIN/XOUT). + const: extal + + '#clock-cells': + description: | + - For CPG core clocks, the two clock specifier cells must be "CPG_CORE" + and a core clock reference, as defined in + <dt-bindings/clock/r9a07g044-cpg.h> + - For module clocks, the two clock specifier cells must be "CPG_MOD" and + a module number, as defined in the <dt-bindings/clock/r9a07g044-cpg.h>. + const: 2 + + '#power-domain-cells': + description: + SoC devices that are part of the CPG/Module Standby Mode Clock Domain and + can be power-managed through Module Standby should refer to the CPG device + node in their "power-domains" property, as documented by the generic PM + Domain bindings in Documentation/devicetree/bindings/power/power-domain.yaml. + const: 0 + + '#reset-cells': + description: + The single reset specifier cell must be the module number, as defined in + the <dt-bindings/clock/r9a07g044-cpg.h>. + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#power-domain-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + cpg: clock-controller@11010000 { + compatible = "renesas,r9a07g044-cpg"; + reg = <0x11010000 0x10000>; + clocks = <&extal_clk>; + clock-names = "extal"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/clock/silabs,si5341.txt b/Documentation/devicetree/bindings/clock/silabs,si5341.txt index 504cce3abe46..ce55aba0ce22 100644 --- a/Documentation/devicetree/bindings/clock/silabs,si5341.txt +++ b/Documentation/devicetree/bindings/clock/silabs,si5341.txt @@ -24,9 +24,8 @@ it. The device type, speed grade and revision are determined runtime by probing. -The driver currently only supports XTAL input mode, and does not support any -fancy input configurations. They can still be programmed into the chip and -the driver will leave them "as is". +The driver currently does not support any fancy input configurations. They can +still be programmed into the chip and the driver will leave them "as is". ==I2C device node== @@ -45,9 +44,9 @@ Required properties: corresponding to inputs. Use a fixed clock for the "xtal" input. At least one must be present. - clock-names: One of: "xtal", "in0", "in1", "in2" -- vdd-supply: Regulator node for VDD Optional properties: +- vdd-supply: Regulator node for VDD - vdda-supply: Regulator node for VDDA - vdds-supply: Regulator node for VDDS - silabs,pll-m-num, silabs,pll-m-den: Numerator and denominator for PLL @@ -60,7 +59,14 @@ Optional properties: be initialized, and always performs the soft-reset routine. Since this will temporarily stop all output clocks, don't do this if the chip is generating the CPU clock for example. +- silabs,xaxb-ext-clk: When present, indicates that the XA/XB pins are used + in EXTCLK (external reference clock) rather than XTAL (crystal) mode. - interrupts: Interrupt for INTRb pin. +- silabs,iovdd-33: When present, indicates that the I2C lines are using 3.3V + rather than 1.8V thresholds. +- vddoX-supply (where X is an output index): Regulator node for VDDO for the + specified output. The driver selects the output VDD_SEL setting based on this + voltage. - #address-cells: shall be set to 1. - #size-cells: shall be set to 0. @@ -77,8 +83,6 @@ Required child node properties: - reg: number of clock output. Optional child node properties: -- vdd-supply: Regulator node for VDD for this output. The driver selects default - values for common-mode and amplitude based on the voltage. - silabs,format: Output format, one of: 1 = differential (defaults to LVDS levels) 2 = low-power (defaults to HCSL levels) diff --git a/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml b/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml index 4e385508f516..8b1ecb2ecdd5 100644 --- a/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml +++ b/Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml @@ -54,7 +54,9 @@ properties: compatible: items: - - const: st,stm32mp1-rcc + - enum: + - st,stm32mp1-rcc-secure + - st,stm32mp1-rcc - const: syscon reg: @@ -71,7 +73,7 @@ additionalProperties: false examples: - | rcc: rcc@50000000 { - compatible = "st,stm32mp1-rcc", "syscon"; + compatible = "st,stm32mp1-rcc-secure", "syscon"; reg = <0x50000000 0x1000>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt index f207053e0550..d0fa1e02d06d 100644 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt +++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt @@ -10,7 +10,10 @@ Required properties: - compatible : shall be: "st,clkgen-pll0" + "st,clkgen-pll0-a0" + "st,clkgen-pll0-c0" "st,clkgen-pll1" + "st,clkgen-pll1-c0" "st,stih407-clkgen-plla9" "st,stih418-clkgen-plla9" diff --git a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt index 7ff77fc57dff..55a18939bddd 100644 --- a/Documentation/devicetree/bindings/clock/st/st,flexgen.txt +++ b/Documentation/devicetree/bindings/clock/st/st,flexgen.txt @@ -64,6 +64,16 @@ Required properties: audio use case) "st,flexgen-video", "st,flexgen" (enable clock propagation on parent and activate synchronous mode) + "st,flexgen-stih407-a0" + "st,flexgen-stih410-a0" + "st,flexgen-stih407-c0" + "st,flexgen-stih410-c0" + "st,flexgen-stih418-c0" + "st,flexgen-stih407-d0" + "st,flexgen-stih410-d0" + "st,flexgen-stih407-d2" + "st,flexgen-stih418-d2" + "st,flexgen-stih407-d3" - #clock-cells : from common clock binding; shall be set to 1 (multiple clock outputs). diff --git a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt index d93d49342e60..c4ba2adb0b4f 100644 --- a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt +++ b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt @@ -12,6 +12,9 @@ This binding uses the common clock binding[1]. Required properties: - compatible : shall be: "st,quadfs" + "st,quadfs-d0" + "st,quadfs-d2" + "st,quadfs-d3" "st,quadfs-pll" diff --git a/Documentation/devicetree/bindings/clock/ti,am654-ehrpwm-tbclk.yaml b/Documentation/devicetree/bindings/clock/ti,am654-ehrpwm-tbclk.yaml index 6b419a9878f3..9b537bc876b5 100644 --- a/Documentation/devicetree/bindings/clock/ti,am654-ehrpwm-tbclk.yaml +++ b/Documentation/devicetree/bindings/clock/ti,am654-ehrpwm-tbclk.yaml @@ -12,7 +12,9 @@ maintainers: properties: compatible: items: - - const: ti,am654-ehrpwm-tbclk + - enum: + - ti,am654-ehrpwm-tbclk + - ti,am64-epwm-tbclk - const: syscon "#clock-cells": diff --git a/Documentation/devicetree/bindings/clock/ti,lmk04832.yaml b/Documentation/devicetree/bindings/clock/ti,lmk04832.yaml new file mode 100644 index 000000000000..bd8173848253 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/ti,lmk04832.yaml @@ -0,0 +1,209 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/ti,lmk04832.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Clock bindings for the Texas Instruments LMK04832 + +maintainers: + - Liam Beguin <liambeguin@gmail.com> + +description: | + Devicetree binding for the LMK04832, a clock conditioner with JEDEC JESD204B + support. The LMK04832 is pin compatible with the LMK0482x family. + + Link to datasheet, https://www.ti.com/lit/ds/symlink/lmk04832.pdf + +properties: + compatible: + enum: + - ti,lmk04832 + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + '#clock-cells': + const: 1 + + spi-max-frequency: + maximum: 5000000 + + clocks: + items: + - description: PLL2 reference clock. + + clock-names: + items: + - const: oscin + + reset-gpios: + maxItems: 1 + + ti,spi-4wire-rdbk: + description: | + Select SPI 4wire readback pin configuration. + Available readback pins are, + CLKin_SEL0 0 + CLKin_SEL1 1 + RESET 2 + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + default: 1 + + ti,vco-hz: + description: Optional to set VCO frequency of the PLL in Hertz. + + ti,sysref-ddly: + description: SYSREF digital delay value. + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 8 + maximum: 8191 + default: 8 + + ti,sysref-mux: + description: | + SYSREF Mux configuration. + Available options are, + Normal SYNC 0 + Re-clocked 1 + SYSREF Pulser 2 + SYSREF Continuous 3 + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2, 3] + default: 3 + + ti,sync-mode: + description: SYNC pin configuration. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + default: 1 + + ti,sysref-pulse-count: + description: + Number of SYSREF pulses to send when SYSREF is not in continuous mode. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2, 4, 8] + default: 4 + +patternProperties: + "@[0-9a-d]+$": + type: object + description: + Child nodes used to configure output clocks. + + properties: + reg: + description: + clock output identifier. + minimum: 0 + maximum: 13 + + ti,clkout-fmt: + description: + Clock output format. + Available options are, + Powerdown 0x00 + LVDS 0x01 + HSDS 6 mA 0x02 + HSDS 8 mA 0x03 + LVPECL 1600 mV 0x04 + LVPECL 2000 mV 0x05 + LCPECL 0x06 + CML 16 mA 0x07 + CML 24 mA 0x08 + CML 32 mA 0x09 + CMOS (Off/Inverted) 0x0a + CMOS (Normal/Off) 0x0b + CMOS (Inverted/Inverted) 0x0c + CMOS (Inverted/Normal) 0x0d + CMOS (Normal/Inverted) 0x0e + CMOS (Normal/Normal) 0x0f + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 15 + + ti,clkout-sysref: + description: + Select SYSREF clock path for output clock. + type: boolean + + required: + - reg + + additionalProperties: false + +required: + - compatible + - reg + - '#clock-cells' + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + clocks { + lmk04832_oscin: oscin { + compatible = "fixed-clock"; + + #clock-cells = <0>; + clock-frequency = <122880000>; + clock-output-names = "lmk04832-oscin"; + }; + }; + + spi0 { + #address-cells = <1>; + #size-cells = <0>; + + lmk04832: clock-controller@0 { + #address-cells = <1>; + #size-cells = <0>; + + reg = <0>; + + compatible = "ti,lmk04832"; + spi-max-frequency = <781250>; + + reset-gpios = <&gpio_lmk 0 0 0>; + + #clock-cells = <1>; + clocks = <&lmk04832_oscin>; + clock-names = "oscin"; + + ti,spi-4wire-rdbk = <0>; + ti,vco-hz = <2457600000>; + + assigned-clocks = + <&lmk04832 0>, <&lmk04832 1>, + <&lmk04832 2>, <&lmk04832 3>, + <&lmk04832 4>, + <&lmk04832 6>, <&lmk04832 7>, + <&lmk04832 10>, <&lmk04832 11>; + assigned-clock-rates = + <122880000>, <384000>, + <122880000>, <384000>, + <122880000>, + <153600000>, <384000>, + <614400000>, <384000>; + + clkout0@0 { + reg = <0>; + ti,clkout-fmt = <0x01>; // LVDS + }; + + clkout1@1 { + reg = <1>; + ti,clkout-fmt = <0x01>; // LVDS + ti,clkout-sysref; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/ti/dpll.txt b/Documentation/devicetree/bindings/clock/ti/dpll.txt index df57009ff8e7..37a7cb6ad07d 100644 --- a/Documentation/devicetree/bindings/clock/ti/dpll.txt +++ b/Documentation/devicetree/bindings/clock/ti/dpll.txt @@ -42,6 +42,11 @@ Required properties: "idlest" - contains the idle status register base address "mult-div1" - contains the multiplier / divider register base address "autoidle" - contains the autoidle register base address (optional) + "ssc-deltam" - DPLL supports spread spectrum clocking (SSC), contains + the frequency spreading register base address (optional) + "ssc-modfreq" - DPLL supports spread spectrum clocking (SSC), contains + the modulation frequency register base address + (optional) ti,am3-* dpll types do not have autoidle register ti,omap2-* dpll type does not support idlest / autoidle registers @@ -51,6 +56,14 @@ Optional properties: - ti,low-power-stop : DPLL supports low power stop mode, gating output - ti,low-power-bypass : DPLL output matches rate of parent bypass clock - ti,lock : DPLL locks in programmed rate + - ti,min-div : the minimum divisor to start from to round the DPLL + target rate + - ti,ssc-deltam : DPLL supports spread spectrum clocking, frequency + spreading in permille (10th of a percent) + - ti,ssc-modfreq-hz : DPLL supports spread spectrum clocking, spread + spectrum modulation frequency + - ti,ssc-downspread : DPLL supports spread spectrum clocking, boolean + to enable the downspread feature Examples: dpll_core_ck: dpll_core_ck@44e00490 { @@ -83,3 +96,10 @@ Examples: clocks = <&sys_ck>, <&sys_ck>; reg = <0x0500>, <0x0540>; }; + + dpll_disp_ck: dpll_disp_ck { + #clock-cells = <0>; + compatible = "ti,am3-dpll-no-gate-clock"; + clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; + reg = <0x0498>, <0x0448>, <0x0454>, <0x044c>, <0x0450>; + }; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24804f11302d..809317b5a6c6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -353,7 +353,6 @@ config ARCH_EP93XX select ARM_VIC select GENERIC_IRQ_MULTI_HANDLER select AUTO_ZRELADDR - select CLKDEV_LOOKUP select CLKSRC_MMIO select CPU_ARM920T select GPIOLIB @@ -504,7 +503,6 @@ config ARCH_OMAP1 bool "TI OMAP1" depends on MMU select ARCH_OMAP - select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_IRQ_CHIP select GENERIC_IRQ_MULTI_HANDLER diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi index dced92a8970e..b7b7106f2dee 100644 --- a/arch/arm/boot/dts/am33xx-clocks.dtsi +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi @@ -164,7 +164,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0490>, <0x045c>, <0x0468>; + reg = <0x0490>, <0x045c>, <0x0468>, <0x0460>, <0x0464>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -204,7 +204,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0488>, <0x0420>, <0x042c>; + reg = <0x0488>, <0x0420>, <0x042c>, <0x0424>, <0x0428>; }; dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a8 { @@ -220,7 +220,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0494>, <0x0434>, <0x0440>; + reg = <0x0494>, <0x0434>, <0x0440>, <0x0438>, <0x043c>; }; dpll_ddr_m2_ck: dpll_ddr_m2_ck@4a0 { @@ -244,7 +244,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0498>, <0x0448>, <0x0454>; + reg = <0x0498>, <0x0448>, <0x0454>, <0x044c>, <0x0450>; }; dpll_disp_m2_ck: dpll_disp_m2_ck@4a4 { @@ -261,7 +261,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-j-type-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x048c>, <0x0470>, <0x049c>; + reg = <0x048c>, <0x0470>, <0x049c>, <0x0474>, <0x0478>; }; dpll_per_m2_ck: dpll_per_m2_ck@4ac { diff --git a/arch/arm/boot/dts/am43xx-clocks.dtsi b/arch/arm/boot/dts/am43xx-clocks.dtsi index c726cd8dbdf1..314fc5975acb 100644 --- a/arch/arm/boot/dts/am43xx-clocks.dtsi +++ b/arch/arm/boot/dts/am43xx-clocks.dtsi @@ -204,7 +204,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2d20>, <0x2d24>, <0x2d2c>; + reg = <0x2d20>, <0x2d24>, <0x2d2c>, <0x2d48>, <0x2d4c>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -250,7 +250,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2d60>, <0x2d64>, <0x2d6c>; + reg = <0x2d60>, <0x2d64>, <0x2d6c>, <0x2d88>, <0x2d8c>; }; dpll_mpu_m2_ck: dpll_mpu_m2_ck@2d70 { @@ -276,7 +276,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2da0>, <0x2da4>, <0x2dac>; + reg = <0x2da0>, <0x2da4>, <0x2dac>, <0x2dc8>, <0x2dcc>; }; dpll_ddr_m2_ck: dpll_ddr_m2_ck@2db0 { @@ -294,7 +294,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2e20>, <0x2e24>, <0x2e2c>; + reg = <0x2e20>, <0x2e24>, <0x2e2c>, <0x2e48>, <0x2e4c>; }; dpll_disp_m2_ck: dpll_disp_m2_ck@2e30 { @@ -313,7 +313,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-j-type-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2de0>, <0x2de4>, <0x2dec>; + reg = <0x2de0>, <0x2de4>, <0x2dec>, <0x2e08>, <0x2e0c>; }; dpll_per_m2_ck: dpll_per_m2_ck@2df0 { @@ -557,7 +557,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x2e60>, <0x2e64>, <0x2e6c>; + reg = <0x2e60>, <0x2e64>, <0x2e6c>, <0x2e88>, <0x2e8c>; }; dpll_extdev_m2_ck: dpll_extdev_m2_ck@2e70 { diff --git a/arch/m68k/coldfire/clk.c b/arch/m68k/coldfire/clk.c index 076a9caa9557..2ed841e94111 100644 --- a/arch/m68k/coldfire/clk.c +++ b/arch/m68k/coldfire/clk.c @@ -73,20 +73,6 @@ struct clk_ops clk_ops1 = { #endif /* MCFPM_PPMCR1 */ #endif /* MCFPM_PPMCR0 */ -struct clk *clk_get(struct device *dev, const char *id) -{ - const char *clk_name = dev ? dev_name(dev) : id ? id : NULL; - struct clk *clk; - unsigned i; - - for (i = 0; (clk = mcf_clks[i]) != NULL; ++i) - if (!strcmp(clk->name, clk_name)) - return clk; - pr_warn("clk_get: didn't find clock %s\n", clk_name); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - int clk_enable(struct clk *clk) { unsigned long flags; @@ -117,13 +103,6 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -void clk_put(struct clk *clk) -{ - if (clk->enabled != 0) - pr_warn("clk_put %s still enabled\n", clk->name); -} -EXPORT_SYMBOL(clk_put); - unsigned long clk_get_rate(struct clk *clk) { if (!clk) diff --git a/arch/m68k/coldfire/m5206.c b/arch/m68k/coldfire/m5206.c index 2f14ea95c391..5e726e94b5ab 100644 --- a/arch/m68k/coldfire/m5206.c +++ b/arch/m68k/coldfire/m5206.c @@ -10,6 +10,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -23,21 +24,15 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfi2c0, - NULL +static struct clk_lookup m5206_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -66,6 +61,8 @@ void __init config_BSP(char *commandp, int size) mcf_mapirq2imr(28, MCFINTC_EINT4); mcf_mapirq2imr(31, MCFINTC_EINT7); m5206_i2c_init(); + + clkdev_add_table(m5206_clk_lookup, ARRAY_SIZE(m5206_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m520x.c b/arch/m68k/coldfire/m520x.c index b5b2a267dada..d2f96b40aee1 100644 --- a/arch/m68k/coldfire/m520x.c +++ b/arch/m68k/coldfire/m520x.c @@ -12,6 +12,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -48,31 +49,29 @@ DEFINE_CLK(0, "sys.0", 40, MCF_BUSCLK); DEFINE_CLK(0, "gpio.0", 41, MCF_BUSCLK); DEFINE_CLK(0, "sdram.0", 42, MCF_CLK); -struct clk *mcf_clks[] = { - &__clk_0_2, /* flexbus */ - &__clk_0_12, /* fec.0 */ - &__clk_0_17, /* edma */ - &__clk_0_18, /* intc.0 */ - &__clk_0_21, /* iack.0 */ - &__clk_0_22, /* imx1-i2c.0 */ - &__clk_0_23, /* mcfqspi.0 */ - &__clk_0_24, /* mcfuart.0 */ - &__clk_0_25, /* mcfuart.1 */ - &__clk_0_26, /* mcfuart.2 */ - &__clk_0_28, /* mcftmr.0 */ - &__clk_0_29, /* mcftmr.1 */ - &__clk_0_30, /* mcftmr.2 */ - &__clk_0_31, /* mcftmr.3 */ - - &__clk_0_32, /* mcfpit.0 */ - &__clk_0_33, /* mcfpit.1 */ - &__clk_0_34, /* mcfeport.0 */ - &__clk_0_35, /* mcfwdt.0 */ - &__clk_0_36, /* pll.0 */ - &__clk_0_40, /* sys.0 */ - &__clk_0_41, /* gpio.0 */ - &__clk_0_42, /* sdram.0 */ - NULL, +static struct clk_lookup m520x_clk_lookup[] = { + CLKDEV_INIT(NULL, "flexbus", &__clk_0_2), + CLKDEV_INIT("fec.0", NULL, &__clk_0_12), + CLKDEV_INIT("edma", NULL, &__clk_0_17), + CLKDEV_INIT("intc.0", NULL, &__clk_0_18), + CLKDEV_INIT("iack.0", NULL, &__clk_0_21), + CLKDEV_INIT("imx1-i2c.0", NULL, &__clk_0_22), + CLKDEV_INIT("mcfqspi.0", NULL, &__clk_0_23), + CLKDEV_INIT("mcfuart.0", NULL, &__clk_0_24), + CLKDEV_INIT("mcfuart.1", NULL, &__clk_0_25), + CLKDEV_INIT("mcfuart.2", NULL, &__clk_0_26), + CLKDEV_INIT("mcftmr.0", NULL, &__clk_0_28), + CLKDEV_INIT("mcftmr.1", NULL, &__clk_0_29), + CLKDEV_INIT("mcftmr.2", NULL, &__clk_0_30), + CLKDEV_INIT("mcftmr.3", NULL, &__clk_0_31), + CLKDEV_INIT("mcfpit.0", NULL, &__clk_0_32), + CLKDEV_INIT("mcfpit.1", NULL, &__clk_0_33), + CLKDEV_INIT("mcfeport.0", NULL, &__clk_0_34), + CLKDEV_INIT("mcfwdt.0", NULL, &__clk_0_35), + CLKDEV_INIT(NULL, "pll.0", &__clk_0_36), + CLKDEV_INIT(NULL, "sys.0", &__clk_0_40), + CLKDEV_INIT("gpio.0", NULL, &__clk_0_41), + CLKDEV_INIT("sdram.0", NULL, &__clk_0_42), }; static struct clk * const enable_clks[] __initconst = { @@ -115,6 +114,8 @@ static void __init m520x_clk_init(void) /* make sure these clocks are disabled */ for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) __clk_init_disabled(disable_clks[i]); + + clkdev_add_table(m520x_clk_lookup, ARRAY_SIZE(m520x_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m523x.c b/arch/m68k/coldfire/m523x.c index ddf2496ed117..193c178162c1 100644 --- a/arch/m68k/coldfire/m523x.c +++ b/arch/m68k/coldfire/m523x.c @@ -13,6 +13,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -26,31 +27,20 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK); -DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK); -DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK); -DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcfpit0, - &clk_mcfpit1, - &clk_mcfpit2, - &clk_mcfpit3, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfuart2, - &clk_mcfqspi0, - &clk_fec0, - &clk_mcfi2c0, - NULL + +struct clk_lookup m523x_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcfpit.0", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.1", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.2", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.3", NULL, &clk_pll), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.2", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("fec.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -100,6 +90,8 @@ void __init config_BSP(char *commandp, int size) m523x_fec_init(); m523x_qspi_init(); m523x_i2c_init(); + + clkdev_add_table(m523x_clk_lookup, ARRAY_SIZE(m523x_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m5249.c b/arch/m68k/coldfire/m5249.c index 0590f8c421f1..6d66972de214 100644 --- a/arch/m68k/coldfire/m5249.c +++ b/arch/m68k/coldfire/m5249.c @@ -9,6 +9,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -23,25 +24,17 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c1, "imx1-i2c.1", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfqspi0, - &clk_mcfi2c0, - &clk_mcfi2c1, - NULL + +struct clk_lookup m5249_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.1", NULL, &clk_sys), }; /***************************************************************************/ @@ -137,6 +130,8 @@ void __init config_BSP(char *commandp, int size) #endif m5249_qspi_init(); m5249_i2c_init(); + + clkdev_add_table(m5249_clk_lookup, ARRAY_SIZE(m5249_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m525x.c b/arch/m68k/coldfire/m525x.c index 1772359c416c..2c4d2ca2f20d 100644 --- a/arch/m68k/coldfire/m525x.c +++ b/arch/m68k/coldfire/m525x.c @@ -9,6 +9,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -23,25 +24,17 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c1, "imx1-i2c.1", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfqspi0, - &clk_mcfi2c0, - &clk_mcfi2c1, - NULL + +static struct clk_lookup m525x_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.1", NULL, &clk_sys), }; /***************************************************************************/ @@ -88,6 +81,8 @@ void __init config_BSP(char *commandp, int size) m525x_qspi_init(); m525x_i2c_init(); + + clkdev_add_table(m525x_clk_lookup, ARRAY_SIZE(m525x_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m5272.c b/arch/m68k/coldfire/m5272.c index 6b3ab583c698..734dab657fe3 100644 --- a/arch/m68k/coldfire/m5272.c +++ b/arch/m68k/coldfire/m5272.c @@ -10,6 +10,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -34,27 +35,18 @@ unsigned char ledbank = 0xff; DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcftmr2, "mcftmr.2", MCF_BUSCLK); -DEFINE_CLK(mcftmr3, "mcftmr.3", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcftmr2, - &clk_mcftmr3, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfqspi0, - &clk_fec0, - NULL + +static struct clk_lookup m5272_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.2", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.3", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("fec.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -128,6 +120,7 @@ static int __init init_BSP(void) { m5272_uarts_init(); fixed_phy_add(PHY_POLL, 0, &nettel_fixed_phy_status); + clkdev_add_table(m5272_clk_lookup, ARRAY_SIZE(m5272_clk_lookup)); return 0; } diff --git a/arch/m68k/coldfire/m527x.c b/arch/m68k/coldfire/m527x.c index cad462df6861..037f3e520acc 100644 --- a/arch/m68k/coldfire/m527x.c +++ b/arch/m68k/coldfire/m527x.c @@ -13,6 +13,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -27,33 +28,21 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK); -DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK); -DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK); -DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK); -DEFINE_CLK(fec1, "fec.1", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcfpit0, - &clk_mcfpit1, - &clk_mcfpit2, - &clk_mcfpit3, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfuart2, - &clk_mcfqspi0, - &clk_fec0, - &clk_fec1, - &clk_mcfi2c0, - NULL + +static struct clk_lookup m527x_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcfpit.0", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.1", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.2", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.3", NULL, &clk_pll), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.2", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("fec.0", NULL, &clk_sys), + CLKDEV_INIT("fec.1", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -151,6 +140,7 @@ void __init config_BSP(char *commandp, int size) m527x_fec_init(); m527x_qspi_init(); m527x_i2c_init(); + clkdev_add_table(m527x_clk_lookup, ARRAY_SIZE(m527x_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m528x.c b/arch/m68k/coldfire/m528x.c index 7ad3193887e8..51a6a6236e12 100644 --- a/arch/m68k/coldfire/m528x.c +++ b/arch/m68k/coldfire/m528x.c @@ -13,6 +13,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -28,31 +29,20 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcfpit0, "mcfpit.0", MCF_CLK); -DEFINE_CLK(mcfpit1, "mcfpit.1", MCF_CLK); -DEFINE_CLK(mcfpit2, "mcfpit.2", MCF_CLK); -DEFINE_CLK(mcfpit3, "mcfpit.3", MCF_CLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK); -DEFINE_CLK(mcfqspi0, "mcfqspi.0", MCF_BUSCLK); -DEFINE_CLK(fec0, "fec.0", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcfpit0, - &clk_mcfpit1, - &clk_mcfpit2, - &clk_mcfpit3, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfuart2, - &clk_mcfqspi0, - &clk_fec0, - &clk_mcfi2c0, - NULL + +static struct clk_lookup m528x_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcfpit.0", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.1", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.2", NULL, &clk_pll), + CLKDEV_INIT("mcfpit.3", NULL, &clk_pll), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.2", NULL, &clk_sys), + CLKDEV_INIT("mcfqspi.0", NULL, &clk_sys), + CLKDEV_INIT("fec.0", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -146,6 +136,8 @@ void __init config_BSP(char *commandp, int size) m528x_fec_init(); m528x_qspi_init(); m528x_i2c_init(); + + clkdev_add_table(m528x_clk_lookup, ARRAY_SIZE(m528x_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m5307.c b/arch/m68k/coldfire/m5307.c index 64b4b1fd34ff..4ed2e43ab3ad 100644 --- a/arch/m68k/coldfire/m5307.c +++ b/arch/m68k/coldfire/m5307.c @@ -10,6 +10,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -32,21 +33,15 @@ unsigned char ledbank = 0xff; DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfi2c0, - NULL + +static struct clk_lookup m5307_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -88,6 +83,8 @@ void __init config_BSP(char *commandp, int size) wdebug(MCFDEBUG_CSR, MCFDEBUG_CSR_PSTCLK); #endif m5307_i2c_init(); + + clkdev_add_table(m5307_clk_lookup, ARRAY_SIZE(m5307_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m53xx.c b/arch/m68k/coldfire/m53xx.c index 075722c0c4f0..bd033e1975bf 100644 --- a/arch/m68k/coldfire/m53xx.c +++ b/arch/m68k/coldfire/m53xx.c @@ -13,6 +13,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -65,45 +66,42 @@ DEFINE_CLK(1, "mdha.0", 32, MCF_CLK); DEFINE_CLK(1, "skha.0", 33, MCF_CLK); DEFINE_CLK(1, "rng.0", 34, MCF_CLK); -struct clk *mcf_clks[] = { - &__clk_0_2, /* flexbus */ - &__clk_0_8, /* mcfcan.0 */ - &__clk_0_12, /* fec.0 */ - &__clk_0_17, /* edma */ - &__clk_0_18, /* intc.0 */ - &__clk_0_19, /* intc.1 */ - &__clk_0_21, /* iack.0 */ - &__clk_0_22, /* imx1-i2c.0 */ - &__clk_0_23, /* mcfqspi.0 */ - &__clk_0_24, /* mcfuart.0 */ - &__clk_0_25, /* mcfuart.1 */ - &__clk_0_26, /* mcfuart.2 */ - &__clk_0_28, /* mcftmr.0 */ - &__clk_0_29, /* mcftmr.1 */ - &__clk_0_30, /* mcftmr.2 */ - &__clk_0_31, /* mcftmr.3 */ - - &__clk_0_32, /* mcfpit.0 */ - &__clk_0_33, /* mcfpit.1 */ - &__clk_0_34, /* mcfpit.2 */ - &__clk_0_35, /* mcfpit.3 */ - &__clk_0_36, /* mcfpwm.0 */ - &__clk_0_37, /* mcfeport.0 */ - &__clk_0_38, /* mcfwdt.0 */ - &__clk_0_40, /* sys.0 */ - &__clk_0_41, /* gpio.0 */ - &__clk_0_42, /* mcfrtc.0 */ - &__clk_0_43, /* mcflcd.0 */ - &__clk_0_44, /* mcfusb-otg.0 */ - &__clk_0_45, /* mcfusb-host.0 */ - &__clk_0_46, /* sdram.0 */ - &__clk_0_47, /* ssi.0 */ - &__clk_0_48, /* pll.0 */ - - &__clk_1_32, /* mdha.0 */ - &__clk_1_33, /* skha.0 */ - &__clk_1_34, /* rng.0 */ - NULL, +static struct clk_lookup m53xx_clk_lookup[] = { + CLKDEV_INIT("flexbus", NULL, &__clk_0_2), + CLKDEV_INIT("mcfcan.0", NULL, &__clk_0_8), + CLKDEV_INIT("fec.0", NULL, &__clk_0_12), + CLKDEV_INIT("edma", NULL, &__clk_0_17), + CLKDEV_INIT("intc.0", NULL, &__clk_0_18), + CLKDEV_INIT("intc.1", NULL, &__clk_0_19), + CLKDEV_INIT("iack.0", NULL, &__clk_0_21), + CLKDEV_INIT("imx1-i2c.0", NULL, &__clk_0_22), + CLKDEV_INIT("mcfqspi.0", NULL, &__clk_0_23), + CLKDEV_INIT("mcfuart.0", NULL, &__clk_0_24), + CLKDEV_INIT("mcfuart.1", NULL, &__clk_0_25), + CLKDEV_INIT("mcfuart.2", NULL, &__clk_0_26), + CLKDEV_INIT("mcftmr.0", NULL, &__clk_0_28), + CLKDEV_INIT("mcftmr.1", NULL, &__clk_0_29), + CLKDEV_INIT("mcftmr.2", NULL, &__clk_0_30), + CLKDEV_INIT("mcftmr.3", NULL, &__clk_0_31), + CLKDEV_INIT("mcfpit.0", NULL, &__clk_0_32), + CLKDEV_INIT("mcfpit.1", NULL, &__clk_0_33), + CLKDEV_INIT("mcfpit.2", NULL, &__clk_0_34), + CLKDEV_INIT("mcfpit.3", NULL, &__clk_0_35), + CLKDEV_INIT("mcfpwm.0", NULL, &__clk_0_36), + CLKDEV_INIT("mcfeport.0", NULL, &__clk_0_37), + CLKDEV_INIT("mcfwdt.0", NULL, &__clk_0_38), + CLKDEV_INIT(NULL, "sys.0", &__clk_0_40), + CLKDEV_INIT("gpio.0", NULL, &__clk_0_41), + CLKDEV_INIT("mcfrtc.0", NULL, &__clk_0_42), + CLKDEV_INIT("mcflcd.0", NULL, &__clk_0_43), + CLKDEV_INIT("mcfusb-otg.0", NULL, &__clk_0_44), + CLKDEV_INIT("mcfusb-host.0", NULL, &__clk_0_45), + CLKDEV_INIT("sdram.0", NULL, &__clk_0_46), + CLKDEV_INIT("ssi.0", NULL, &__clk_0_47), + CLKDEV_INIT(NULL, "pll.0", &__clk_0_48), + CLKDEV_INIT("mdha.0", NULL, &__clk_1_32), + CLKDEV_INIT("skha.0", NULL, &__clk_1_33), + CLKDEV_INIT("rng.0", NULL, &__clk_1_34), }; static struct clk * const enable_clks[] __initconst = { @@ -158,6 +156,8 @@ static void __init m53xx_clk_init(void) /* make sure these clocks are disabled */ for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) __clk_init_disabled(disable_clks[i]); + + clkdev_add_table(m53xx_clk_lookup, ARRAY_SIZE(m53xx_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m5407.c b/arch/m68k/coldfire/m5407.c index 0400d76115a1..b32efb3042a2 100644 --- a/arch/m68k/coldfire/m5407.c +++ b/arch/m68k/coldfire/m5407.c @@ -10,6 +10,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -23,21 +24,15 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr0, "mcftmr.0", MCF_BUSCLK); -DEFINE_CLK(mcftmr1, "mcftmr.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcftmr0, - &clk_mcftmr1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfi2c0, - NULL +static struct clk_lookup m5407_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcftmr.0", NULL, &clk_sys), + CLKDEV_INIT("mcftmr.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -63,6 +58,8 @@ void __init config_BSP(char *commandp, int size) mcf_mapirq2imr(29, MCFINTC_EINT5); mcf_mapirq2imr(31, MCFINTC_EINT7); m5407_i2c_init(); + + clkdev_add_table(m5407_clk_lookup, ARRAY_SIZE(m5407_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/coldfire/m5441x.c b/arch/m68k/coldfire/m5441x.c index 1e5259a652d1..ce14693d18b6 100644 --- a/arch/m68k/coldfire/m5441x.c +++ b/arch/m68k/coldfire/m5441x.c @@ -5,6 +5,7 @@ * (C) Copyright Steven King <sfking@fdwdc.com> */ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -78,72 +79,67 @@ DEFINE_CLK(2, "ipg.0", 0, MCF_CLK); DEFINE_CLK(2, "ahb.0", 1, MCF_CLK); DEFINE_CLK(2, "per.0", 2, MCF_CLK); -struct clk *mcf_clks[] = { - &__clk_0_2, - &__clk_0_8, - &__clk_0_9, - &__clk_0_14, - &__clk_0_15, - &__clk_0_17, - &__clk_0_18, - &__clk_0_19, - &__clk_0_20, - &__clk_0_22, - &__clk_0_23, - &__clk_0_24, - &__clk_0_25, - &__clk_0_26, - &__clk_0_27, - &__clk_0_28, - &__clk_0_29, - &__clk_0_30, - &__clk_0_31, - &__clk_0_32, - &__clk_0_33, - &__clk_0_34, - &__clk_0_35, - &__clk_0_37, - &__clk_0_38, - &__clk_0_39, - &__clk_0_42, - &__clk_0_43, - &__clk_0_44, - &__clk_0_45, - &__clk_0_46, - &__clk_0_47, - &__clk_0_48, - &__clk_0_49, - &__clk_0_50, - &__clk_0_51, - &__clk_0_53, - &__clk_0_54, - &__clk_0_55, - &__clk_0_56, - &__clk_0_63, - - &__clk_1_2, - &__clk_1_4, - &__clk_1_5, - &__clk_1_6, - &__clk_1_7, - &__clk_1_24, - &__clk_1_25, - &__clk_1_26, - &__clk_1_27, - &__clk_1_28, - &__clk_1_29, - &__clk_1_34, - &__clk_1_36, - &__clk_1_37, - - &__clk_2_0, - &__clk_2_1, - &__clk_2_2, - - NULL, +static struct clk_lookup m5411x_clk_lookup[] = { + CLKDEV_INIT("flexbus", NULL, &__clk_0_2), + CLKDEV_INIT("mcfcan.0", NULL, &__clk_0_8), + CLKDEV_INIT("mcfcan.1", NULL, &__clk_0_9), + CLKDEV_INIT("imx1-i2c.1", NULL, &__clk_0_14), + CLKDEV_INIT("mcfdspi.1", NULL, &__clk_0_15), + CLKDEV_INIT("edma", NULL, &__clk_0_17), + CLKDEV_INIT("intc.0", NULL, &__clk_0_18), + CLKDEV_INIT("intc.1", NULL, &__clk_0_19), + CLKDEV_INIT("intc.2", NULL, &__clk_0_20), + CLKDEV_INIT("imx1-i2c.0", NULL, &__clk_0_22), + CLKDEV_INIT("fsl-dspi.0", NULL, &__clk_0_23), + CLKDEV_INIT("mcfuart.0", NULL, &__clk_0_24), + CLKDEV_INIT("mcfuart.1", NULL, &__clk_0_25), + CLKDEV_INIT("mcfuart.2", NULL, &__clk_0_26), + CLKDEV_INIT("mcfuart.3", NULL, &__clk_0_27), + CLKDEV_INIT("mcftmr.0", NULL, &__clk_0_28), + CLKDEV_INIT("mcftmr.1", NULL, &__clk_0_29), + CLKDEV_INIT("mcftmr.2", NULL, &__clk_0_30), + CLKDEV_INIT("mcftmr.3", NULL, &__clk_0_31), + CLKDEV_INIT("mcfpit.0", NULL, &__clk_0_32), + CLKDEV_INIT("mcfpit.1", NULL, &__clk_0_33), + CLKDEV_INIT("mcfpit.2", NULL, &__clk_0_34), + CLKDEV_INIT("mcfpit.3", NULL, &__clk_0_35), + CLKDEV_INIT("mcfeport.0", NULL, &__clk_0_37), + CLKDEV_INIT("mcfadc.0", NULL, &__clk_0_38), + CLKDEV_INIT("mcfdac.0", NULL, &__clk_0_39), + CLKDEV_INIT("mcfrtc.0", NULL, &__clk_0_42), + CLKDEV_INIT("mcfsim.0", NULL, &__clk_0_43), + CLKDEV_INIT("mcfusb-otg.0", NULL, &__clk_0_44), + CLKDEV_INIT("mcfusb-host.0", NULL, &__clk_0_45), + CLKDEV_INIT("mcfddr-sram.0", NULL, &__clk_0_46), + CLKDEV_INIT("mcfssi.0", NULL, &__clk_0_47), + CLKDEV_INIT(NULL, "pll.0", &__clk_0_48), + CLKDEV_INIT("mcfrng.0", NULL, &__clk_0_49), + CLKDEV_INIT("mcfssi.1", NULL, &__clk_0_50), + CLKDEV_INIT("sdhci-esdhc-mcf.0", NULL, &__clk_0_51), + CLKDEV_INIT("enet-fec.0", NULL, &__clk_0_53), + CLKDEV_INIT("enet-fec.1", NULL, &__clk_0_54), + CLKDEV_INIT("switch.0", NULL, &__clk_0_55), + CLKDEV_INIT("switch.1", NULL, &__clk_0_56), + CLKDEV_INIT("nand.0", NULL, &__clk_0_63), + CLKDEV_INIT("mcfow.0", NULL, &__clk_1_2), + CLKDEV_INIT("imx1-i2c.2", NULL, &__clk_1_4), + CLKDEV_INIT("imx1-i2c.3", NULL, &__clk_1_5), + CLKDEV_INIT("imx1-i2c.4", NULL, &__clk_1_6), + CLKDEV_INIT("imx1-i2c.5", NULL, &__clk_1_7), + CLKDEV_INIT("mcfuart.4", NULL, &__clk_1_24), + CLKDEV_INIT("mcfuart.5", NULL, &__clk_1_25), + CLKDEV_INIT("mcfuart.6", NULL, &__clk_1_26), + CLKDEV_INIT("mcfuart.7", NULL, &__clk_1_27), + CLKDEV_INIT("mcfuart.8", NULL, &__clk_1_28), + CLKDEV_INIT("mcfuart.9", NULL, &__clk_1_29), + CLKDEV_INIT("mcfpwm.0", NULL, &__clk_1_34), + CLKDEV_INIT(NULL, "sys.0", &__clk_1_36), + CLKDEV_INIT("gpio.0", NULL, &__clk_1_37), + CLKDEV_INIT("ipg.0", NULL, &__clk_2_0), + CLKDEV_INIT("ahb.0", NULL, &__clk_2_1), + CLKDEV_INIT("per.0", NULL, &__clk_2_2), }; - static struct clk * const enable_clks[] __initconst = { /* make sure these clocks are enabled */ &__clk_0_15, /* dspi.1 */ @@ -228,6 +224,8 @@ static void __init m5441x_clk_init(void) /* make sure these clocks are disabled */ for (i = 0; i < ARRAY_SIZE(disable_clks); ++i) __clk_init_disabled(disable_clks[i]); + + clkdev_add_table(m5411x_clk_lookup, ARRAY_SIZE(m5411x_clk_lookup)); } static void __init m5441x_uarts_init(void) diff --git a/arch/m68k/coldfire/m54xx.c b/arch/m68k/coldfire/m54xx.c index 360c723c0ae6..8e3c8fee8327 100644 --- a/arch/m68k/coldfire/m54xx.c +++ b/arch/m68k/coldfire/m54xx.c @@ -9,6 +9,7 @@ /***************************************************************************/ +#include <linux/clkdev.h> #include <linux/kernel.h> #include <linux/param.h> #include <linux/init.h> @@ -32,25 +33,17 @@ DEFINE_CLK(pll, "pll.0", MCF_CLK); DEFINE_CLK(sys, "sys.0", MCF_BUSCLK); -DEFINE_CLK(mcfslt0, "mcfslt.0", MCF_BUSCLK); -DEFINE_CLK(mcfslt1, "mcfslt.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart0, "mcfuart.0", MCF_BUSCLK); -DEFINE_CLK(mcfuart1, "mcfuart.1", MCF_BUSCLK); -DEFINE_CLK(mcfuart2, "mcfuart.2", MCF_BUSCLK); -DEFINE_CLK(mcfuart3, "mcfuart.3", MCF_BUSCLK); -DEFINE_CLK(mcfi2c0, "imx1-i2c.0", MCF_BUSCLK); - -struct clk *mcf_clks[] = { - &clk_pll, - &clk_sys, - &clk_mcfslt0, - &clk_mcfslt1, - &clk_mcfuart0, - &clk_mcfuart1, - &clk_mcfuart2, - &clk_mcfuart3, - &clk_mcfi2c0, - NULL + +static struct clk_lookup m54xx_clk_lookup[] = { + CLKDEV_INIT(NULL, "pll.0", &clk_pll), + CLKDEV_INIT(NULL, "sys.0", &clk_sys), + CLKDEV_INIT("mcfslt.0", NULL, &clk_sys), + CLKDEV_INIT("mcfslt.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.0", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.1", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.2", NULL, &clk_sys), + CLKDEV_INIT("mcfuart.3", NULL, &clk_sys), + CLKDEV_INIT("imx1-i2c.0", NULL, &clk_sys), }; /***************************************************************************/ @@ -100,6 +93,8 @@ void __init config_BSP(char *commandp, int size) mach_sched_init = hw_timer_init; m54xx_uarts_init(); m54xx_i2c_init(); + + clkdev_add_table(m54xx_clk_lookup, ARRAY_SIZE(m54xx_clk_lookup)); } /***************************************************************************/ diff --git a/arch/m68k/include/asm/mcfclk.h b/arch/m68k/include/asm/mcfclk.h index 722627e06d66..4e9a6b827a14 100644 --- a/arch/m68k/include/asm/mcfclk.h +++ b/arch/m68k/include/asm/mcfclk.h @@ -15,15 +15,12 @@ struct clk_ops { }; struct clk { - const char *name; struct clk_ops *clk_ops; unsigned long rate; unsigned long enabled; u8 slot; }; -extern struct clk *mcf_clks[]; - #ifdef MCFPM_PPMCR0 extern struct clk_ops clk_ops0; #ifdef MCFPM_PPMCR1 @@ -34,7 +31,6 @@ extern struct clk_ops clk_ops2; #define DEFINE_CLK(clk_bank, clk_name, clk_slot, clk_rate) \ static struct clk __clk_##clk_bank##_##clk_slot = { \ - .name = clk_name, \ .clk_ops = &clk_ops##clk_bank, \ .rate = clk_rate, \ .slot = clk_slot, \ @@ -45,7 +41,6 @@ void __clk_init_disabled(struct clk *); #else #define DEFINE_CLK(clk_ref, clk_name, clk_rate) \ static struct clk clk_##clk_ref = { \ - .name = clk_name, \ .rate = clk_rate, \ } #endif /* MCFPM_PPMCR0 */ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4704a16c2e44..ed2e3a51c016 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -201,6 +201,7 @@ config MIPS_ALCHEMY config AR7 bool "Texas Instruments AR7" select BOOT_ELF32 + select COMMON_CLK select DMA_NONCOHERENT select CEVT_R4K select CSRC_R4K @@ -215,7 +216,6 @@ config AR7 select SYS_SUPPORTS_ZBOOT_UART16550 select GPIOLIB select VLYNQ - select HAVE_LEGACY_CLK help Support for the Texas Instruments AR7 System-on-a-Chip family: TNETD7100, 7200 and 7300. @@ -332,7 +332,6 @@ config BCM63XX select SWAP_IO_SPACE select GPIOLIB select MIPS_L1_CACHE_SHIFT_4 - select CLKDEV_LOOKUP select HAVE_LEGACY_CLK help Support for BCM63XX based boards @@ -446,7 +445,6 @@ config LANTIQ select GPIOLIB select SWAP_IO_SPACE select BOOT_RAW - select CLKDEV_LOOKUP select HAVE_LEGACY_CLK select USE_OF select PINCTRL @@ -630,6 +628,7 @@ config MACH_NINTENDO64 config RALINK bool "Ralink based machines" select CEVT_R4K + select COMMON_CLK select CSRC_R4K select BOOT_RAW select DMA_NONCOHERENT @@ -642,7 +641,6 @@ config RALINK select SYS_SUPPORTS_MIPS16 select SYS_SUPPORTS_ZBOOT select SYS_HAS_EARLY_PRINTK - select CLKDEV_LOOKUP select ARCH_HAS_RESET_CONTROLLER select RESET_CONTROLLER diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index 95def949c971..c717acbc5506 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c @@ -13,7 +13,9 @@ #include <linux/gcd.h> #include <linux/io.h> #include <linux/err.h> +#include <linux/clkdev.h> #include <linux/clk.h> +#include <linux/clk-provider.h> #include <asm/addrspace.h> #include <asm/mach-ar7/ar7.h> @@ -84,17 +86,17 @@ struct tnetd7200_clocks { struct tnetd7200_clock usb; }; -static struct clk bus_clk = { +struct clk_rate { + u32 rate; +}; +static struct clk_rate bus_clk = { .rate = 125000000, }; -static struct clk cpu_clk = { +static struct clk_rate cpu_clk = { .rate = 150000000, }; -static struct clk dsp_clk; -static struct clk vbus_clk; - static void approximate(int base, int target, int *prediv, int *postdiv, int *mul) { @@ -240,6 +242,8 @@ static void __init tnetd7300_init_clocks(void) struct tnetd7300_clocks *clocks = ioremap(UR8_REGS_CLOCKS, sizeof(struct tnetd7300_clocks)); + u32 dsp_clk; + struct clk *clk; bus_clk.rate = tnetd7300_get_clock(BUS_PLL_SOURCE_SHIFT, &clocks->bus, bootcr, AR7_AFE_CLOCK); @@ -250,12 +254,18 @@ static void __init tnetd7300_init_clocks(void) else cpu_clk.rate = bus_clk.rate; - if (dsp_clk.rate == 250000000) + dsp_clk = tnetd7300_dsp_clock(); + if (dsp_clk == 250000000) tnetd7300_set_clock(DSP_PLL_SOURCE_SHIFT, &clocks->dsp, - bootcr, dsp_clk.rate); + bootcr, dsp_clk); iounmap(clocks); iounmap(bootcr); + + clk = clk_register_fixed_rate(NULL, "cpu", NULL, 0, cpu_clk.rate); + clkdev_create(clk, "cpu", NULL); + clk = clk_register_fixed_rate(NULL, "dsp", NULL, 0, dsp_clk); + clkdev_create(clk, "dsp", NULL); } static void tnetd7200_set_clock(int base, struct tnetd7200_clock *clock, @@ -327,6 +337,7 @@ static void __init tnetd7200_init_clocks(void) int cpu_base, cpu_mul, cpu_prediv, cpu_postdiv; int dsp_base, dsp_mul, dsp_prediv, dsp_postdiv; int usb_base, usb_mul, usb_prediv, usb_postdiv; + struct clk *clk; cpu_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_CPU, bootcr); dsp_base = tnetd7200_get_clock_base(TNETD7200_CLOCK_ID_DSP, bootcr); @@ -395,100 +406,34 @@ static void __init tnetd7200_init_clocks(void) usb_prediv, usb_postdiv, -1, usb_mul, TNETD7200_DEF_USB_CLK); - dsp_clk.rate = cpu_clk.rate; - iounmap(clocks); iounmap(bootcr); -} - -/* - * Linux clock API - */ -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - if (!clk) - return 0; - return clk->rate; -} -EXPORT_SYMBOL(clk_get_rate); - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "bus")) - return &bus_clk; - /* cpmac and vbus share the same rate */ - if (!strcmp(id, "cpmac")) - return &vbus_clk; - if (!strcmp(id, "cpu")) - return &cpu_clk; - if (!strcmp(id, "dsp")) - return &dsp_clk; - if (!strcmp(id, "vbus")) - return &vbus_clk; - return ERR_PTR(-ENOENT); + clk = clk_register_fixed_rate(NULL, "cpu", NULL, 0, cpu_clk.rate); + clkdev_create(clk, "cpu", NULL); + clkdev_create(clk, "dsp", NULL); } -EXPORT_SYMBOL(clk_get); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); void __init ar7_init_clocks(void) { + struct clk *clk; + switch (ar7_chip_id()) { case AR7_CHIP_7100: case AR7_CHIP_7200: tnetd7200_init_clocks(); break; case AR7_CHIP_7300: - dsp_clk.rate = tnetd7300_dsp_clock(); tnetd7300_init_clocks(); break; default: break; } + clk = clk_register_fixed_rate(NULL, "bus", NULL, 0, bus_clk.rate); + clkdev_create(clk, "bus", NULL); /* adjust vbus clock rate */ - vbus_clk.rate = bus_clk.rate / 2; -} - -/* dummy functions, should not be called */ -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - WARN_ON(clk); - return 0; -} -EXPORT_SYMBOL(clk_round_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - WARN_ON(clk); - return 0; -} -EXPORT_SYMBOL(clk_set_rate); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - WARN_ON(clk); - return 0; -} -EXPORT_SYMBOL(clk_set_parent); - -struct clk *clk_get_parent(struct clk *clk) -{ - WARN_ON(clk); - return NULL; + clk = clk_register_fixed_factor(NULL, "vbus", "bus", 0, 1, 2); + clkdev_create(clk, "vbus", NULL); + clkdev_create(clk, "cpmac", "cpmac.1"); + clkdev_create(clk, "cpmac", "cpmac.1"); } -EXPORT_SYMBOL(clk_get_parent); diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index dd09c3bf0601..cbe75ade3277 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h @@ -131,10 +131,6 @@ static inline u8 ar7_chip_rev(void) 0x14))) >> 16) & 0xff; } -struct clk { - unsigned int rate; -}; - static inline int ar7_has_high_cpmac(void) { u16 chip_id = ar7_chip_id(); diff --git a/arch/mips/pic32/Kconfig b/arch/mips/pic32/Kconfig index 7acbb50c1dcd..bb6ab1f3e80d 100644 --- a/arch/mips/pic32/Kconfig +++ b/arch/mips/pic32/Kconfig @@ -17,7 +17,6 @@ config PIC32MZDA select SYS_SUPPORTS_LITTLE_ENDIAN select GPIOLIB select COMMON_CLK - select CLKDEV_LOOKUP select LIBFDT select USE_OF select PINCTRL diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index ec4daa63c5e3..c800bf5559b5 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -28,22 +28,18 @@ choice bool "RT288x" select MIPS_AUTO_PFN_OFFSET select MIPS_L1_CACHE_SHIFT_4 - select HAVE_LEGACY_CLK select HAVE_PCI config SOC_RT305X bool "RT305x" - select HAVE_LEGACY_CLK config SOC_RT3883 bool "RT3883" - select HAVE_LEGACY_CLK select HAVE_PCI config SOC_MT7620 bool "MT7620/8" select CPU_MIPSR2_IRQ_VI - select HAVE_LEGACY_CLK select HAVE_PCI config SOC_MT7621 @@ -54,7 +50,6 @@ choice select SYS_SUPPORTS_MIPS_CPS select SYS_SUPPORTS_HIGHMEM select MIPS_GIC - select COMMON_CLK select CLKSRC_MIPS_GIC select HAVE_PCI if PCI_MT7621 select SOC_BUS diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index f0bcb1051c30..5b02bb7e0829 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c @@ -10,79 +10,21 @@ #include <linux/export.h> #include <linux/clkdev.h> #include <linux/clk.h> +#include <linux/clk-provider.h> #include <asm/time.h> #include "common.h" -struct clk { - struct clk_lookup cl; - unsigned long rate; -}; - void ralink_clk_add(const char *dev, unsigned long rate) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = clk_register_fixed_rate(NULL, dev, NULL, 0, rate); if (!clk) panic("failed to add clock"); - clk->cl.dev_id = dev; - clk->cl.clk = clk; - - clk->rate = rate; - - clkdev_add(&clk->cl); -} - -/* - * Linux clock API - */ -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL_GPL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL_GPL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - if (!clk) - return 0; - - return clk->rate; -} -EXPORT_SYMBOL_GPL(clk_get_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - return -1; -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - return -1; -} -EXPORT_SYMBOL_GPL(clk_round_rate); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - WARN_ON(clk); - return -1; -} -EXPORT_SYMBOL_GPL(clk_set_parent); - -struct clk *clk_get_parent(struct clk *clk) -{ - WARN_ON(clk); - return NULL; + clkdev_create(clk, NULL, "%s", dev); } -EXPORT_SYMBOL_GPL(clk_get_parent); void __init plat_time_init(void) { diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 68129537e350..45a0549421cd 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -14,7 +14,6 @@ config SUPERH select ARCH_HIBERNATION_POSSIBLE if MMU select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_WANT_IPC_PARSE_VERSION - select CLKDEV_LOOKUP select CPU_NO_EFFICIENT_FFS select DMA_DECLARE_COHERENT select GENERIC_ATOMIC64 diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e80918be8e9c..e873f9ea2e65 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -6,10 +6,6 @@ config HAVE_CLK The <linux/clk.h> calls support software clock gating and thus are a key power management tool on many systems. -config CLKDEV_LOOKUP - bool - select HAVE_CLK - config HAVE_CLK_PREPARE bool @@ -26,7 +22,7 @@ menuconfig COMMON_CLK bool "Common Clock Framework" depends on !HAVE_LEGACY_CLK select HAVE_CLK_PREPARE - select CLKDEV_LOOKUP + select HAVE_CLK select SRCU select RATIONAL help @@ -55,6 +51,14 @@ config CLK_HSDK This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs control. +config LMK04832 + tristate "Ti LMK04832 JESD204B Compliant Clock Jitter Cleaner" + depends on SPI + select REGMAP_SPI + help + Say yes here to build support for Texas Instruments' LMK04832 Ultra + Low-Noise JESD204B Compliant Clock Jitter Cleaner With Dual Loop PLLs + config COMMON_CLK_MAX77686 tristate "Clock driver for Maxim 77620/77686/77802 MFD" depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST @@ -335,6 +339,16 @@ config COMMON_CLK_STM32MP157 help Support for stm32mp157 SoC family clocks +config COMMON_CLK_STM32MP157_SCMI + bool "stm32mp157 Clock driver with Trusted Firmware" + depends on COMMON_CLK_STM32MP157 + select COMMON_CLK_SCMI + select ARM_SCMI_PROTOCOL + default y + help + Support for stm32mp157 SoC family clocks with Trusted Firmware using + SCMI protocol. + config COMMON_CLK_STM32F def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746) help @@ -358,10 +372,10 @@ config COMMON_CLK_MMP2_AUDIO config COMMON_CLK_BD718XX tristate "Clock driver for 32K clk gates on ROHM PMICs" - depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828 + depends on MFD_ROHM_BD718XX || MFD_ROHM_BD71828 help - This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and - ROHM BD70528 PMICs clock gates. + This driver supports ROHM BD71837, BD71847, BD71850, BD71815 + and BD71828 PMICs clock gates. config COMMON_CLK_FIXED_MMIO bool "Clock driver for Memory Mapped Fixed values" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5f06879d7fe9..2b91d34c582b 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 # common clock types -obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o -obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o +obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o obj-$(CONFIG_COMMON_CLK) += clk-divider.o obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o @@ -37,6 +36,7 @@ obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o +obj-$(CONFIG_LMK04832) += clk-lmk04832.o obj-$(CONFIG_COMMON_CLK_LOCHNAGAR) += clk-lochnagar.o obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c index 61bb224f6330..57d06e183dff 100644 --- a/drivers/clk/actions/owl-s500.c +++ b/drivers/clk/actions/owl-s500.c @@ -113,6 +113,7 @@ static const char * const sensor_clk_mux_p[] = { "hosc", "bisp_clk" }; static const char * const sd_clk_mux_p[] = { "dev_clk", "nand_pll_clk" }; static const char * const pwm_clk_mux_p[] = { "losc", "hosc" }; static const char * const ahbprediv_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" }; +static const char * const nic_clk_mux_p[] = { "dev_clk", "display_pll_clk", "nand_pll_clk", "ddr_pll_clk" }; static const char * const uart_clk_mux_p[] = { "hosc", "dev_pll_clk" }; static const char * const de_clk_mux_p[] = { "display_pll_clk", "dev_clk" }; static const char * const i2s_clk_mux_p[] = { "audio_pll_clk" }; @@ -127,8 +128,7 @@ static struct clk_factor_table sd_factor_table[] = { { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 }, { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 }, { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 }, - { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 }, - { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 }, + { 24, 1, 25 }, /* bit8: /128 */ { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 }, @@ -137,19 +137,20 @@ static struct clk_factor_table sd_factor_table[] = { { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 }, { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 }, { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 }, - { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 }, - { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 }, + { 280, 1, 25 * 128 }, { 0, 0, 0 }, }; -static struct clk_factor_table bisp_factor_table[] = { - { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, - { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, +static struct clk_factor_table de_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, + { 8, 1, 12 }, { 0, 0, 0 }, }; -static struct clk_factor_table ahb_factor_table[] = { - { 1, 1, 2 }, { 2, 1, 3 }, +static struct clk_factor_table hde_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, { 0, 0, 0 }, }; @@ -158,6 +159,13 @@ static struct clk_div_table rmii_ref_div_table[] = { { 0, 0 }, }; +static struct clk_div_table std12rate_div_table[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 0, 0 }, +}; + static struct clk_div_table i2s_div_table[] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 }, @@ -174,7 +182,6 @@ static struct clk_div_table nand_div_table[] = { /* mux clock */ static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); -static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); /* gate clocks */ static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0); @@ -187,45 +194,60 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); /* divider clocks */ -static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); -static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); +static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, NULL, 0, 0); +static OWL_DIVIDER(apb_clk, "apb_clk", "nic_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); /* factor clocks */ -static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); -static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0); -static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0); +static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0); +static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0); /* composite clocks */ +static OWL_COMP_DIV(nic_clk, "nic_clk", nic_clk_mux_p, + OWL_MUX_HW(CMU_BUSCLK1, 4, 3), + { 0 }, + OWL_DIVIDER_HW(CMU_BUSCLK1, 16, 2, 0, NULL), + 0); + +static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, + OWL_MUX_HW(CMU_BUSCLK1, 8, 3), + { 0 }, + OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL), + CLK_SET_RATE_PARENT); + +static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk", + { 0 }, + 1, 1, 0); + static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VCECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0), - OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), 0); static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VDECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0), - OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), 0); -static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p, +static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p, OWL_MUX_HW(CMU_BISPCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table), + OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table), 0); -static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table), + 0); -static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table), + 0); static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p, OWL_MUX_HW(CMU_SD0CLK, 9, 1), @@ -302,10 +324,14 @@ static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk", OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0), 1, 5, 0); +static OWL_COMP_FIXED_FACTOR(ethernet_clk, "ethernet_clk", "ethernet_pll_clk", + OWL_GATE_HW(CMU_DEVCLKEN1, 22, 0), + 1, 20, 0); + static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART0CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, @@ -317,31 +343,31 @@ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART2CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART3CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART4CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART5CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART6CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p, @@ -436,6 +462,8 @@ static struct owl_clk_common *s500_clks[] = { &apb_clk.common, &dmac_clk.common, &gpio_clk.common, + &nic_clk.common, + ðernet_clk.common, }; static struct clk_hw_onecell_data s500_hw_clks = { @@ -495,6 +523,8 @@ static struct clk_hw_onecell_data s500_hw_clks = { [CLK_APB] = &apb_clk.common.hw, [CLK_DMAC] = &dmac_clk.common.hw, [CLK_GPIO] = &gpio_clk.common.hw, + [CLK_NIC] = &nic_clk.common.hw, + [CLK_ETHERNET] = ðernet_clk.common.hw, }, .num = CLK_NR_CLKS, }; diff --git a/drivers/clk/analogbits/wrpll-cln28hpc.c b/drivers/clk/analogbits/wrpll-cln28hpc.c index 776ead319ae9..3b1947575dcc 100644 --- a/drivers/clk/analogbits/wrpll-cln28hpc.c +++ b/drivers/clk/analogbits/wrpll-cln28hpc.c @@ -198,7 +198,7 @@ static int __wrpll_update_parent_rate(struct wrpll_cfg *c, } /** - * wrpll_configure() - compute PLL configuration for a target rate + * wrpll_configure_for_rate() - compute PLL configuration for a target rate * @c: ptr to a struct wrpll_cfg record to write into * @target_rate: target PLL output clock rate (post-Q-divider) * @parent_rate: PLL input refclk rate (pre-R-divider) diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index d9e70e506d18..ac40b669d60b 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c @@ -15,15 +15,13 @@ /* clk control registers */ /* BD71815 */ #define BD71815_REG_OUT32K 0x1d -/* BD70528 */ -#define BD70528_REG_OUT32K 0x2c /* BD71828 */ #define BD71828_REG_OUT32K 0x4B /* BD71837 and BD71847 */ #define BD718XX_REG_OUT32K 0x2E /* - * BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control + * BD71837, BD71847, and BD71828 all use bit [0] to clk output control */ #define CLK_OUT_EN_MASK BIT(0) @@ -116,10 +114,6 @@ static int bd71837_clk_probe(struct platform_device *pdev) c->reg = BD71828_REG_OUT32K; c->mask = CLK_OUT_EN_MASK; break; - case ROHM_CHIP_TYPE_BD70528: - c->reg = BD70528_REG_OUT32K; - c->mask = CLK_OUT_EN_MASK; - break; case ROHM_CHIP_TYPE_BD71815: c->reg = BD71815_REG_OUT32K; c->mask = CLK_OUT_EN_MASK; @@ -150,7 +144,6 @@ static int bd71837_clk_probe(struct platform_device *pdev) static const struct platform_device_id bd718x7_clk_id[] = { { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 }, { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 }, - { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 }, { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 }, { "bd71815-clk", ROHM_CHIP_TYPE_BD71815 }, { }, @@ -168,6 +161,6 @@ static struct platform_driver bd71837_clk = { module_platform_driver(bd71837_clk); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); -MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and BD70528 chip clk driver"); +MODULE_DESCRIPTION("BD718(15/18/28/37/47/50) and chip clk driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:bd718xx-clk"); diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c new file mode 100644 index 000000000000..c1095e733220 --- /dev/null +++ b/drivers/clk/clk-lmk04832.c @@ -0,0 +1,1599 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * LMK04832 Ultra Low-Noise JESD204B Compliant Clock Jitter Cleaner + * Pin compatible with the LMK0482x family + * + * Datasheet: https://www.ti.com/lit/ds/symlink/lmk04832.pdf + * + * Copyright (c) 2020, Xiphos Systems Corp. + * + */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/debugfs.h> +#include <linux/device.h> +#include <linux/gcd.h> +#include <linux/gpio/consumer.h> +#include <linux/module.h> +#include <linux/uaccess.h> +#include <linux/regmap.h> +#include <linux/spi/spi.h> + +/* 0x000 - 0x00d System Functions */ +#define LMK04832_REG_RST3W 0x000 +#define LMK04832_BIT_RESET BIT(7) +#define LMK04832_BIT_SPI_3WIRE_DIS BIT(4) +#define LMK04832_REG_POWERDOWN 0x002 +#define LMK04832_REG_ID_DEV_TYPE 0x003 +#define LMK04832_REG_ID_PROD_MSB 0x004 +#define LMK04832_REG_ID_PROD_LSB 0x005 +#define LMK04832_REG_ID_MASKREV 0x006 +#define LMK04832_REG_ID_VNDR_MSB 0x00c +#define LMK04832_REG_ID_VNDR_LSB 0x00d + +/* 0x100 - 0x137 Device Clock and SYSREF Clock Output Control */ +#define LMK04832_REG_CLKOUT_CTRL0(ch) (0x100 + (ch >> 1) * 8) +#define LMK04832_BIT_DCLK_DIV_LSB GENMASK(7, 0) +#define LMK04832_REG_CLKOUT_CTRL1(ch) (0x101 + (ch >> 1) * 8) +#define LMK04832_BIT_DCLKX_Y_DDLY_LSB GENMASK(7, 0) +#define LMK04832_REG_CLKOUT_CTRL2(ch) (0x102 + (ch >> 1) * 8) +#define LMK04832_BIT_CLKOUTX_Y_PD BIT(7) +#define LMK04832_BIT_DCLKX_Y_DDLY_PD BIT(4) +#define LMK04832_BIT_DCLKX_Y_DDLY_MSB GENMASK(3, 2) +#define LMK04832_BIT_DCLK_DIV_MSB GENMASK(1, 0) +#define LMK04832_REG_CLKOUT_SRC_MUX(ch) (0x103 + (ch % 2) + (ch >> 1) * 8) +#define LMK04832_BIT_CLKOUT_SRC_MUX BIT(5) +#define LMK04832_REG_CLKOUT_CTRL3(ch) (0x103 + (ch >> 1) * 8) +#define LMK04832_BIT_DCLKX_Y_PD BIT(4) +#define LMK04832_BIT_DCLKX_Y_DCC BIT(2) +#define LMK04832_BIT_DCLKX_Y_HS BIT(0) +#define LMK04832_REG_CLKOUT_CTRL4(ch) (0x104 + (ch >> 1) * 8) +#define LMK04832_BIT_SCLK_PD BIT(4) +#define LMK04832_BIT_SCLKX_Y_DIS_MODE GENMASK(3, 2) +#define LMK04832_REG_SCLKX_Y_ADLY(ch) (0x105 + (ch >> 1) * 8) +#define LMK04832_REG_SCLKX_Y_DDLY(ch) (0x106 + (ch >> 1) * 8) +#define LMK04832_BIT_SCLKX_Y_DDLY GENMASK(3, 0) +#define LMK04832_REG_CLKOUT_FMT(ch) (0x107 + (ch >> 1) * 8) +#define LMK04832_BIT_CLKOUT_FMT(ch) (ch % 2 ? 0xf0 : 0x0f) +#define LMK04832_VAL_CLKOUT_FMT_POWERDOWN 0x00 +#define LMK04832_VAL_CLKOUT_FMT_LVDS 0x01 +#define LMK04832_VAL_CLKOUT_FMT_HSDS6 0x02 +#define LMK04832_VAL_CLKOUT_FMT_HSDS8 0x03 +#define LMK04832_VAL_CLKOUT_FMT_LVPECL1600 0x04 +#define LMK04832_VAL_CLKOUT_FMT_LVPECL2000 0x05 +#define LMK04832_VAL_CLKOUT_FMT_LCPECL 0x06 +#define LMK04832_VAL_CLKOUT_FMT_CML16 0x07 +#define LMK04832_VAL_CLKOUT_FMT_CML24 0x08 +#define LMK04832_VAL_CLKOUT_FMT_CML32 0x09 +#define LMK04832_VAL_CLKOUT_FMT_CMOS_OFF_INV 0x0a +#define LMK04832_VAL_CLKOUT_FMT_CMOS_NOR_OFF 0x0b +#define LMK04832_VAL_CLKOUT_FMT_CMOS_INV_INV 0x0c +#define LMK04832_VAL_CLKOUT_FMT_CMOS_INV_NOR 0x0d +#define LMK04832_VAL_CLKOUT_FMT_CMOS_NOR_INV 0x0e +#define LMK04832_VAL_CLKOUT_FMT_CMOS_NOR_NOR 0x0f + +/* 0x138 - 0x145 SYSREF, SYNC, and Device Config */ +#define LMK04832_REG_VCO_OSCOUT 0x138 +#define LMK04832_BIT_VCO_MUX GENMASK(6, 5) +#define LMK04832_VAL_VCO_MUX_VCO0 0x00 +#define LMK04832_VAL_VCO_MUX_VCO1 0x01 +#define LMK04832_VAL_VCO_MUX_EXT 0x02 +#define LMK04832_REG_SYSREF_OUT 0x139 +#define LMK04832_BIT_SYSREF_REQ_EN BIT(6) +#define LMK04832_BIT_SYSREF_MUX GENMASK(1, 0) +#define LMK04832_VAL_SYSREF_MUX_NORMAL_SYNC 0x00 +#define LMK04832_VAL_SYSREF_MUX_RECLK 0x01 +#define LMK04832_VAL_SYSREF_MUX_PULSER 0x02 +#define LMK04832_VAL_SYSREF_MUX_CONTINUOUS 0x03 +#define LMK04832_REG_SYSREF_DIV_MSB 0x13a +#define LMK04832_BIT_SYSREF_DIV_MSB GENMASK(4, 0) +#define LMK04832_REG_SYSREF_DIV_LSB 0x13b +#define LMK04832_REG_SYSREF_DDLY_MSB 0x13c +#define LMK04832_BIT_SYSREF_DDLY_MSB GENMASK(4, 0) +#define LMK04832_REG_SYSREF_DDLY_LSB 0x13d +#define LMK04832_REG_SYSREF_PULSE_CNT 0x13e +#define LMK04832_REG_FB_CTRL 0x13f +#define LMK04832_BIT_PLL2_RCLK_MUX BIT(7) +#define LMK04832_VAL_PLL2_RCLK_MUX_OSCIN 0x00 +#define LMK04832_VAL_PLL2_RCLK_MUX_CLKIN 0x01 +#define LMK04832_BIT_PLL2_NCLK_MUX BIT(5) +#define LMK04832_VAL_PLL2_NCLK_MUX_PLL2_P 0x00 +#define LMK04832_VAL_PLL2_NCLK_MUX_FB_MUX 0x01 +#define LMK04832_BIT_FB_MUX_EN BIT(0) +#define LMK04832_REG_MAIN_PD 0x140 +#define LMK04832_BIT_PLL1_PD BIT(7) +#define LMK04832_BIT_VCO_LDO_PD BIT(6) +#define LMK04832_BIT_VCO_PD BIT(5) +#define LMK04832_BIT_OSCIN_PD BIT(4) +#define LMK04832_BIT_SYSREF_GBL_PD BIT(3) +#define LMK04832_BIT_SYSREF_PD BIT(2) +#define LMK04832_BIT_SYSREF_DDLY_PD BIT(1) +#define LMK04832_BIT_SYSREF_PLSR_PD BIT(0) +#define LMK04832_REG_SYNC 0x143 +#define LMK04832_BIT_SYNC_CLR BIT(7) +#define LMK04832_BIT_SYNC_1SHOT_EN BIT(6) +#define LMK04832_BIT_SYNC_POL BIT(5) +#define LMK04832_BIT_SYNC_EN BIT(4) +#define LMK04832_BIT_SYNC_MODE GENMASK(1, 0) +#define LMK04832_VAL_SYNC_MODE_OFF 0x00 +#define LMK04832_VAL_SYNC_MODE_ON 0x01 +#define LMK04832_VAL_SYNC_MODE_PULSER_PIN 0x02 +#define LMK04832_VAL_SYNC_MODE_PULSER_SPI 0x03 +#define LMK04832_REG_SYNC_DIS 0x144 + +/* 0x146 - 0x14a CLKin Control */ +#define LMK04832_REG_CLKIN_SEL0 0x148 +#define LMK04832_REG_CLKIN_SEL1 0x149 +#define LMK04832_REG_CLKIN_RST 0x14a +#define LMK04832_BIT_SDIO_RDBK_TYPE BIT(6) +#define LMK04832_BIT_CLKIN_SEL_MUX GENMASK(5, 3) +#define LMK04832_VAL_CLKIN_SEL_MUX_SPI_RDBK 0x06 +#define LMK04832_BIT_CLKIN_SEL_TYPE GENMASK(2, 0) +#define LMK04832_VAL_CLKIN_SEL_TYPE_OUT 0x03 + +/* 0x14b - 0x152 Holdover */ + +/* 0x153 - 0x15f PLL1 Configuration */ + +/* 0x160 - 0x16e PLL2 Configuration */ +#define LMK04832_REG_PLL2_R_MSB 0x160 +#define LMK04832_BIT_PLL2_R_MSB GENMASK(3, 0) +#define LMK04832_REG_PLL2_R_LSB 0x161 +#define LMK04832_REG_PLL2_MISC 0x162 +#define LMK04832_BIT_PLL2_MISC_P GENMASK(7, 5) +#define LMK04832_BIT_PLL2_MISC_REF_2X_EN BIT(0) +#define LMK04832_REG_PLL2_N_CAL_0 0x163 +#define LMK04832_BIT_PLL2_N_CAL_0 GENMASK(1, 0) +#define LMK04832_REG_PLL2_N_CAL_1 0x164 +#define LMK04832_REG_PLL2_N_CAL_2 0x165 +#define LMK04832_REG_PLL2_N_0 0x166 +#define LMK04832_BIT_PLL2_N_0 GENMASK(1, 0) +#define LMK04832_REG_PLL2_N_1 0x167 +#define LMK04832_REG_PLL2_N_2 0x168 +#define LMK04832_REG_PLL2_DLD_CNT_MSB 0x16a +#define LMK04832_REG_PLL2_DLD_CNT_LSB 0x16b +#define LMK04832_REG_PLL2_LD 0x16e +#define LMK04832_BIT_PLL2_LD_MUX GENMASK(7, 3) +#define LMK04832_VAL_PLL2_LD_MUX_PLL2_DLD 0x02 +#define LMK04832_BIT_PLL2_LD_TYPE GENMASK(2, 0) +#define LMK04832_VAL_PLL2_LD_TYPE_OUT_PP 0x03 + +/* 0x16F - 0x555 Misc Registers */ +#define LMK04832_REG_PLL2_PD 0x173 +#define LMK04832_BIT_PLL2_PRE_PD BIT(6) +#define LMK04832_BIT_PLL2_PD BIT(5) +#define LMK04832_REG_PLL1R_RST 0x177 +#define LMK04832_REG_CLR_PLL_LOST 0x182 +#define LMK04832_REG_RB_PLL_LD 0x183 +#define LMK04832_REG_RB_CLK_DAC_VAL_MSB 0x184 +#define LMK04832_REG_RB_DAC_VAL_LSB 0x185 +#define LMK04832_REG_RB_HOLDOVER 0x188 +#define LMK04832_REG_SPI_LOCK 0x555 + +enum lmk04832_device_types { + LMK04832, +}; + +/** + * lmk04832_device_info - Holds static device information that is specific to + * the chip revision + * + * pid: Product Identifier + * maskrev: IC version identifier + * num_channels: Number of available output channels (clkout count) + * vco0_range: {min, max} of the VCO0 operating range (in MHz) + * vco1_range: {min, max} of the VCO1 operating range (in MHz) + */ +struct lmk04832_device_info { + u16 pid; + u8 maskrev; + size_t num_channels; + unsigned int vco0_range[2]; + unsigned int vco1_range[2]; +}; + +static const struct lmk04832_device_info lmk04832_device_info[] = { + [LMK04832] = { + .pid = 0x63d1, /* WARNING PROD_ID is inverted in the datasheet */ + .maskrev = 0x70, + .num_channels = 14, + .vco0_range = { 2440, 2580 }, + .vco1_range = { 2945, 3255 }, + }, +}; + +enum lmk04832_rdbk_type { + RDBK_CLKIN_SEL0, + RDBK_CLKIN_SEL1, + RDBK_RESET, +}; + +struct lmk_dclk { + struct lmk04832 *lmk; + struct clk_hw hw; + u8 id; +}; + +struct lmk_clkout { + struct lmk04832 *lmk; + struct clk_hw hw; + bool sysref; + u32 format; + u8 id; +}; + +/** + * struct lmk04832 - The LMK04832 device structure + * + * @dev: reference to a struct device, linked to the spi_device + * @regmap: struct regmap instance use to access the chip + * @sync_mode: operational mode for SYNC signal + * @sysref_mux: select SYSREF source + * @sysref_pulse_cnt: number of SYSREF pulses generated while not in continuous + * mode. + * @sysref_ddly: SYSREF digital delay value + * @oscin: PLL2 input clock + * @vco: reference to the internal VCO clock + * @sclk: reference to the internal sysref clock (SCLK) + * @vco_rate: user provided VCO rate + * @reset_gpio: reference to the reset GPIO + * @dclk: list of internal device clock references. + * Each pair of clkout clocks share a single device clock (DCLKX_Y) + * @clkout: list of output clock references + * @clk_data: holds clkout related data like clk_hw* and number of clocks + */ +struct lmk04832 { + struct device *dev; + struct regmap *regmap; + + unsigned int sync_mode; + unsigned int sysref_mux; + unsigned int sysref_pulse_cnt; + unsigned int sysref_ddly; + + struct clk *oscin; + struct clk_hw vco; + struct clk_hw sclk; + unsigned int vco_rate; + + struct gpio_desc *reset_gpio; + + struct lmk_dclk *dclk; + struct lmk_clkout *clkout; + struct clk_hw_onecell_data *clk_data; +}; + +static bool lmk04832_regmap_rd_regs(struct device *dev, unsigned int reg) +{ + switch (reg) { + case LMK04832_REG_RST3W ... LMK04832_REG_ID_MASKREV: + fallthrough; + case LMK04832_REG_ID_VNDR_MSB: + fallthrough; + case LMK04832_REG_ID_VNDR_LSB: + fallthrough; + case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB: + fallthrough; + case LMK04832_REG_PLL2_LD: + fallthrough; + case LMK04832_REG_PLL2_PD: + fallthrough; + case LMK04832_REG_PLL1R_RST: + fallthrough; + case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB: + fallthrough; + case LMK04832_REG_RB_HOLDOVER: + fallthrough; + case LMK04832_REG_SPI_LOCK: + return true; + default: + return false; + }; +}; + +static bool lmk04832_regmap_wr_regs(struct device *dev, unsigned int reg) +{ + switch (reg) { + case LMK04832_REG_RST3W: + fallthrough; + case LMK04832_REG_POWERDOWN: + return true; + case LMK04832_REG_ID_DEV_TYPE ... LMK04832_REG_ID_MASKREV: + fallthrough; + case LMK04832_REG_ID_VNDR_MSB: + fallthrough; + case LMK04832_REG_ID_VNDR_LSB: + return false; + case LMK04832_REG_CLKOUT_CTRL0(0) ... LMK04832_REG_PLL2_DLD_CNT_LSB: + fallthrough; + case LMK04832_REG_PLL2_LD: + fallthrough; + case LMK04832_REG_PLL2_PD: + fallthrough; + case LMK04832_REG_PLL1R_RST: + fallthrough; + case LMK04832_REG_CLR_PLL_LOST ... LMK04832_REG_RB_DAC_VAL_LSB: + fallthrough; + case LMK04832_REG_RB_HOLDOVER: + fallthrough; + case LMK04832_REG_SPI_LOCK: + return true; + default: + return false; + }; +}; + +static const struct regmap_config regmap_config = { + .name = "lmk04832", + .reg_bits = 16, + .val_bits = 8, + .use_single_read = 1, + .use_single_write = 1, + .read_flag_mask = 0x80, + .write_flag_mask = 0x00, + .readable_reg = lmk04832_regmap_rd_regs, + .writeable_reg = lmk04832_regmap_wr_regs, + .cache_type = REGCACHE_NONE, + .max_register = LMK04832_REG_SPI_LOCK, +}; + +static int lmk04832_vco_is_enabled(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + unsigned int tmp; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_MAIN_PD, &tmp); + if (ret) + return ret; + + return !(FIELD_GET(LMK04832_BIT_OSCIN_PD, tmp) | + FIELD_GET(LMK04832_BIT_VCO_PD, tmp) | + FIELD_GET(LMK04832_BIT_VCO_LDO_PD, tmp)); +} + +static int lmk04832_vco_prepare(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + int ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_PD, + LMK04832_BIT_PLL2_PRE_PD | + LMK04832_BIT_PLL2_PD, + 0x00); + if (ret) + return ret; + + return regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_VCO_LDO_PD | + LMK04832_BIT_VCO_PD | + LMK04832_BIT_OSCIN_PD, 0x00); +} + +static void lmk04832_vco_unprepare(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + + regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_PD, + LMK04832_BIT_PLL2_PRE_PD | LMK04832_BIT_PLL2_PD, + 0xff); + + /* Don't set LMK04832_BIT_OSCIN_PD since other clocks depend on it */ + regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_VCO_LDO_PD | LMK04832_BIT_VCO_PD, 0xff); +} + +static unsigned long lmk04832_vco_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + unsigned int pll2_p[] = {8, 2, 2, 3, 4, 5, 6, 7}; + unsigned int pll2_n, p, pll2_r; + unsigned int pll2_misc; + unsigned long vco_rate; + u8 tmp[3]; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_PLL2_MISC, &pll2_misc); + if (ret) + return ret; + + p = FIELD_GET(LMK04832_BIT_PLL2_MISC_P, pll2_misc); + + ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_PLL2_N_0, &tmp, 3); + if (ret) + return ret; + + pll2_n = FIELD_PREP(0x030000, tmp[0]) | + FIELD_PREP(0x00ff00, tmp[1]) | + FIELD_PREP(0x0000ff, tmp[2]); + + ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_PLL2_R_MSB, &tmp, 2); + if (ret) + return ret; + + pll2_r = FIELD_PREP(0x0f00, tmp[0]) | + FIELD_PREP(0x00ff, tmp[1]); + + vco_rate = (prate << FIELD_GET(LMK04832_BIT_PLL2_MISC_REF_2X_EN, + pll2_misc)) * pll2_n * pll2_p[p] / pll2_r; + + return vco_rate; +}; + +/** + * lmk04832_check_vco_ranges - Check requested VCO frequency against VCO ranges + * + * @lmk: Reference to the lmk device + * @rate: Desired output rate for the VCO + * + * The LMK04832 has 2 internal VCO, each with independent operating ranges. + * Use the device_info structure to determine which VCO to use based on rate. + * + * Returns VCO_MUX value or negative errno. + */ +static int lmk04832_check_vco_ranges(struct lmk04832 *lmk, unsigned long rate) +{ + struct spi_device *spi = to_spi_device(lmk->dev); + const struct lmk04832_device_info *info; + unsigned long mhz = rate / 1000000; + + info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data]; + + if (mhz >= info->vco0_range[0] && mhz <= info->vco0_range[1]) + return LMK04832_VAL_VCO_MUX_VCO0; + + if (mhz >= info->vco1_range[0] && mhz <= info->vco1_range[1]) + return LMK04832_VAL_VCO_MUX_VCO1; + + dev_err(lmk->dev, "%lu Hz is out of VCO ranges\n", rate); + return -ERANGE; +} + +/** + * lmk04832_calc_pll2_params - Get PLL2 parameters used to set the VCO frequency + * + * @prate: parent rate to the PLL2, usually OSCin + * @rate: Desired output rate for the VCO + * @n: reference to PLL2_N + * @p: reference to PLL2_P + * @r: reference to PLL2_R + * + * This functions assumes LMK04832_BIT_PLL2_MISC_REF_2X_EN is set since it is + * recommended in the datasheet because a higher phase detector frequencies + * makes the design of wider loop bandwidth filters possible. + * + * the VCO rate can be calculated using the following expression: + * + * VCO = OSCin * 2 * PLL2_N * PLL2_P / PLL2_R + * + * Returns vco rate or negative errno. + */ +static long lmk04832_calc_pll2_params(unsigned long prate, unsigned long rate, + unsigned int *n, unsigned int *p, + unsigned int *r) +{ + unsigned int pll2_n, pll2_p, pll2_r; + unsigned long num, div; + + /* Set PLL2_P to a fixed value to simplify optimizations */ + pll2_p = 2; + + div = gcd(rate, prate); + + num = DIV_ROUND_CLOSEST(rate, div); + pll2_r = DIV_ROUND_CLOSEST(prate, div); + + if (num > 4) { + pll2_n = num >> 2; + } else { + pll2_r = pll2_r << 2; + pll2_n = num; + } + + if (pll2_n < 1 || pll2_n > 0x03ffff) + return -EINVAL; + if (pll2_r < 1 || pll2_r > 0xfff) + return -EINVAL; + + *n = pll2_n; + *p = pll2_p; + *r = pll2_r; + + return DIV_ROUND_CLOSEST(prate * 2 * pll2_p * pll2_n, pll2_r); +} + +static long lmk04832_vco_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + unsigned int n, p, r; + long vco_rate; + int ret; + + ret = lmk04832_check_vco_ranges(lmk, rate); + if (ret < 0) + return ret; + + vco_rate = lmk04832_calc_pll2_params(*prate, rate, &n, &p, &r); + if (vco_rate < 0) { + dev_err(lmk->dev, "PLL2 parmeters out of range\n"); + return vco_rate; + } + + if (rate != vco_rate) + return -EINVAL; + + return vco_rate; +}; + +static int lmk04832_vco_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, vco); + unsigned int n, p, r; + long vco_rate; + int vco_mux; + int ret; + + vco_mux = lmk04832_check_vco_ranges(lmk, rate); + if (vco_mux < 0) + return vco_mux; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_VCO_OSCOUT, + LMK04832_BIT_VCO_MUX, + FIELD_PREP(LMK04832_BIT_VCO_MUX, vco_mux)); + if (ret) + return ret; + + vco_rate = lmk04832_calc_pll2_params(prate, rate, &n, &p, &r); + if (vco_rate < 0) { + dev_err(lmk->dev, "failed to determine PLL2 parmeters\n"); + return vco_rate; + } + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_R_MSB, + LMK04832_BIT_PLL2_R_MSB, + FIELD_GET(0x000700, r)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_R_LSB, + FIELD_GET(0x0000ff, r)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_MISC, + LMK04832_BIT_PLL2_MISC_P, + FIELD_PREP(LMK04832_BIT_PLL2_MISC_P, p)); + if (ret) + return ret; + + /* + * PLL2_N registers must be programmed after other PLL2 dividers are + * programed to ensure proper VCO frequency calibration + */ + ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_0, + FIELD_GET(0x030000, n)); + if (ret) + return ret; + ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_1, + FIELD_GET(0x00ff00, n)); + if (ret) + return ret; + + return regmap_write(lmk->regmap, LMK04832_REG_PLL2_N_2, + FIELD_GET(0x0000ff, n)); +}; + +static const struct clk_ops lmk04832_vco_ops = { + .is_enabled = lmk04832_vco_is_enabled, + .prepare = lmk04832_vco_prepare, + .unprepare = lmk04832_vco_unprepare, + .recalc_rate = lmk04832_vco_recalc_rate, + .round_rate = lmk04832_vco_round_rate, + .set_rate = lmk04832_vco_set_rate, +}; + +/* + * lmk04832_register_vco - Initialize the internal VCO and clock distribution + * path in PLL2 single loop mode. + */ +static int lmk04832_register_vco(struct lmk04832 *lmk) +{ + const char *parent_names[1]; + struct clk_init_data init; + int ret; + + init.name = "lmk-vco"; + parent_names[0] = __clk_get_name(lmk->oscin); + init.parent_names = parent_names; + + init.ops = &lmk04832_vco_ops; + init.num_parents = 1; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_VCO_OSCOUT, + LMK04832_BIT_VCO_MUX, + FIELD_PREP(LMK04832_BIT_VCO_MUX, + LMK04832_VAL_VCO_MUX_VCO1)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_FB_CTRL, + LMK04832_BIT_PLL2_RCLK_MUX | + LMK04832_BIT_PLL2_NCLK_MUX, + FIELD_PREP(LMK04832_BIT_PLL2_RCLK_MUX, + LMK04832_VAL_PLL2_RCLK_MUX_OSCIN)| + FIELD_PREP(LMK04832_BIT_PLL2_NCLK_MUX, + LMK04832_VAL_PLL2_NCLK_MUX_PLL2_P)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_PLL2_MISC, + LMK04832_BIT_PLL2_MISC_REF_2X_EN, + LMK04832_BIT_PLL2_MISC_REF_2X_EN); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_PLL2_LD, + FIELD_PREP(LMK04832_BIT_PLL2_LD_MUX, + LMK04832_VAL_PLL2_LD_MUX_PLL2_DLD) | + FIELD_PREP(LMK04832_BIT_PLL2_LD_TYPE, + LMK04832_VAL_PLL2_LD_TYPE_OUT_PP)); + if (ret) + return ret; + + lmk->vco.init = &init; + return devm_clk_hw_register(lmk->dev, &lmk->vco); +} + +static int lmk04832_clkout_set_ddly(struct lmk04832 *lmk, int id) +{ + int dclk_div_adj[] = {0, 0, -2, -2, 0, 3, -1, 0}; + unsigned int sclkx_y_ddly = 10; + unsigned int dclkx_y_ddly; + unsigned int dclkx_y_div; + unsigned int sysref_ddly; + unsigned int dclkx_y_hs; + unsigned int lsb, msb; + int ret; + + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL2(id), + LMK04832_BIT_DCLKX_Y_DDLY_PD, + FIELD_PREP(LMK04832_BIT_DCLKX_Y_DDLY_PD, 0)); + if (ret) + return ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_SYSREF_DDLY_LSB, &lsb); + if (ret) + return ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_SYSREF_DDLY_MSB, &msb); + if (ret) + return ret; + + sysref_ddly = FIELD_GET(LMK04832_BIT_SYSREF_DDLY_MSB, msb) << 8 | lsb; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(id), &lsb); + if (ret) + return ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(id), &msb); + if (ret) + return ret; + + dclkx_y_div = FIELD_GET(LMK04832_BIT_DCLK_DIV_MSB, msb) << 8 | lsb; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL3(id), &lsb); + if (ret) + return ret; + + dclkx_y_hs = FIELD_GET(LMK04832_BIT_DCLKX_Y_HS, lsb); + + dclkx_y_ddly = sysref_ddly + 1 - + dclk_div_adj[dclkx_y_div < 6 ? dclkx_y_div : 7] - + dclkx_y_hs + sclkx_y_ddly; + + if (dclkx_y_ddly < 7 || dclkx_y_ddly > 0x3fff) { + dev_err(lmk->dev, "DCLKX_Y_DDLY out of range (%d)\n", + dclkx_y_ddly); + return -EINVAL; + } + + ret = regmap_write(lmk->regmap, + LMK04832_REG_SCLKX_Y_DDLY(id), + FIELD_GET(LMK04832_BIT_SCLKX_Y_DDLY, sclkx_y_ddly)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_CLKOUT_CTRL1(id), + FIELD_GET(0x00ff, dclkx_y_ddly)); + if (ret) + return ret; + + dev_dbg(lmk->dev, "clkout%02u: sysref_ddly=%u, dclkx_y_ddly=%u, " + "dclk_div_adj=%+d, dclkx_y_hs=%u, sclkx_y_ddly=%u\n", + id, sysref_ddly, dclkx_y_ddly, + dclk_div_adj[dclkx_y_div < 6 ? dclkx_y_div : 7], + dclkx_y_hs, sclkx_y_ddly); + + return regmap_update_bits(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(id), + LMK04832_BIT_DCLKX_Y_DDLY_MSB, + FIELD_GET(0x0300, dclkx_y_ddly)); +} + +/** lmk04832_sclk_sync - Establish deterministic phase relationship between sclk + * and dclk + * + * @lmk: Reference to the lmk device + * + * The synchronization sequence: + * - in the datasheet https://www.ti.com/lit/ds/symlink/lmk04832.pdf, p.31 + * (8.3.3.1 How to enable SYSREF) + * - Ti forum: https://e2e.ti.com/support/clock-and-timing/f/48/t/970972 + * + * Returns 0 or negative errno. + */ +static int lmk04832_sclk_sync_sequence(struct lmk04832 *lmk) +{ + int ret; + int i; + + /* 1. (optional) mute all sysref_outputs during synchronization */ + /* 2. Enable and write device clock digital delay to applicable clocks */ + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_SYSREF_DDLY_PD, + FIELD_PREP(LMK04832_BIT_SYSREF_DDLY_PD, 0)); + if (ret) + return ret; + + for (i = 0; i < lmk->clk_data->num; i += 2) { + ret = lmk04832_clkout_set_ddly(lmk, i); + if (ret) + return ret; + } + + /* + * 3. Configure SYNC_MODE to SYNC_PIN and SYSREF_MUX to Normal SYNC, + * and clear SYSREF_REQ_EN (see 6.) + */ + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT, + LMK04832_BIT_SYSREF_REQ_EN | + LMK04832_BIT_SYSREF_MUX, + FIELD_PREP(LMK04832_BIT_SYSREF_REQ_EN, 0) | + FIELD_PREP(LMK04832_BIT_SYSREF_MUX, + LMK04832_VAL_SYSREF_MUX_NORMAL_SYNC)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_MODE, + FIELD_PREP(LMK04832_BIT_SYNC_MODE, + LMK04832_VAL_SYNC_MODE_ON)); + if (ret) + return ret; + + /* 4. Clear SYNXC_DISx or applicable clocks and clear SYNC_DISSYSREF */ + ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0x00); + if (ret) + return ret; + + /* + * 5. If SCLKX_Y_DDLY != 0, Set SYSREF_CLR=1 for at least 15 clock + * distribution path cycles (VCO cycles), then back to 0. In + * PLL2-only use case, this will be complete in less than one SPI + * transaction. If SYSREF local digital delay is not used, this step + * can be skipped. + */ + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_CLR, + FIELD_PREP(LMK04832_BIT_SYNC_CLR, 0x01)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_CLR, + FIELD_PREP(LMK04832_BIT_SYNC_CLR, 0x00)); + if (ret) + return ret; + + /* + * 6. Toggle SYNC_POL state between inverted and not inverted. + * If you use an external signal on the SYNC pin instead of toggling + * SYNC_POL, make sure that SYSREF_REQ_EN=0 so that the SYSREF_MUX + * does not shift into continuous SYSREF mode. + */ + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_POL, + FIELD_PREP(LMK04832_BIT_SYNC_POL, 0x01)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_POL, + FIELD_PREP(LMK04832_BIT_SYNC_POL, 0x00)); + if (ret) + return ret; + + /* 7. Set all SYNC_DISx=1, including SYNC_DISSYSREF */ + ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0xff); + if (ret) + return ret; + + /* 8. Restore state of SYNC_MODE and SYSREF_MUX to desired values */ + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT, + LMK04832_BIT_SYSREF_MUX, + FIELD_PREP(LMK04832_BIT_SYSREF_MUX, + lmk->sysref_mux)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYNC, + LMK04832_BIT_SYNC_MODE, + FIELD_PREP(LMK04832_BIT_SYNC_MODE, + lmk->sync_mode)); + if (ret) + return ret; + + /* + * 9. (optional) if SCLKx_y_DIS_MODE was used to mute SYSREF outputs + * during the SYNC event, restore SCLKx_y_DIS_MODE=0 for active state, + * or set SYSREF_GBL_PD=0 if SCLKx_y_DIS_MODE is set to a conditional + * option. + */ + + /* + * 10. (optional) To reduce power consumption, after the synchronization + * event is complete, DCLKx_y_DDLY_PD=1 and SYSREF_DDLY_PD=1 disable the + * digital delay counters (which are only used immediately after the + * SYNC pulse to delay the output by some number of VCO counts). + */ + + return ret; +} + +static int lmk04832_sclk_is_enabled(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + unsigned int tmp; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_MAIN_PD, &tmp); + if (ret) + return ret; + + return FIELD_GET(LMK04832_BIT_SYSREF_PD, tmp); +} + +static int lmk04832_sclk_prepare(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + + return regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_SYSREF_PD, 0x00); +} + +static void lmk04832_sclk_unprepare(struct clk_hw *hw) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + + regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_SYSREF_PD, LMK04832_BIT_SYSREF_PD); +} + +static unsigned long lmk04832_sclk_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + unsigned int sysref_div; + u8 tmp[2]; + int ret; + + ret = regmap_bulk_read(lmk->regmap, LMK04832_REG_SYSREF_DIV_MSB, &tmp, 2); + if (ret) + return ret; + + sysref_div = FIELD_GET(LMK04832_BIT_SYSREF_DIV_MSB, tmp[0]) << 8 | + tmp[1]; + + return DIV_ROUND_CLOSEST(prate, sysref_div); +} + +static long lmk04832_sclk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + unsigned long sclk_rate; + unsigned int sysref_div; + + sysref_div = DIV_ROUND_CLOSEST(*prate, rate); + sclk_rate = DIV_ROUND_CLOSEST(*prate, sysref_div); + + if (sysref_div < 0x07 || sysref_div > 0x1fff) { + dev_err(lmk->dev, "SYSREF divider out of range\n"); + return -EINVAL; + } + + if (rate != sclk_rate) + return -EINVAL; + + return sclk_rate; +} + +static int lmk04832_sclk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct lmk04832 *lmk = container_of(hw, struct lmk04832, sclk); + unsigned int sysref_div; + int ret; + + sysref_div = DIV_ROUND_CLOSEST(prate, rate); + + if (sysref_div < 0x07 || sysref_div > 0x1fff) { + dev_err(lmk->dev, "SYSREF divider out of range\n"); + return -EINVAL; + } + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DIV_MSB, + FIELD_GET(0x1f00, sysref_div)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DIV_LSB, + FIELD_GET(0x00ff, sysref_div)); + if (ret) + return ret; + + ret = lmk04832_sclk_sync_sequence(lmk); + if (ret) + dev_err(lmk->dev, "SYNC sequence failed\n"); + + return ret; +} + +static const struct clk_ops lmk04832_sclk_ops = { + .is_enabled = lmk04832_sclk_is_enabled, + .prepare = lmk04832_sclk_prepare, + .unprepare = lmk04832_sclk_unprepare, + .recalc_rate = lmk04832_sclk_recalc_rate, + .round_rate = lmk04832_sclk_round_rate, + .set_rate = lmk04832_sclk_set_rate, +}; + +static int lmk04832_register_sclk(struct lmk04832 *lmk) +{ + const char *parent_names[1]; + struct clk_init_data init; + int ret; + + init.name = "lmk-sclk"; + parent_names[0] = clk_hw_get_name(&lmk->vco); + init.parent_names = parent_names; + + init.ops = &lmk04832_sclk_ops; + init.flags = CLK_SET_RATE_PARENT; + init.num_parents = 1; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_SYSREF_OUT, + LMK04832_BIT_SYSREF_MUX, + FIELD_PREP(LMK04832_BIT_SYSREF_MUX, + lmk->sysref_mux)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DDLY_LSB, + FIELD_GET(0x00ff, lmk->sysref_ddly)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_DDLY_MSB, + FIELD_GET(0x1f00, lmk->sysref_ddly)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYSREF_PULSE_CNT, + ilog2(lmk->sysref_pulse_cnt)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, LMK04832_REG_MAIN_PD, + LMK04832_BIT_SYSREF_DDLY_PD | + LMK04832_BIT_SYSREF_PLSR_PD, + FIELD_PREP(LMK04832_BIT_SYSREF_DDLY_PD, 0) | + FIELD_PREP(LMK04832_BIT_SYSREF_PLSR_PD, 0)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC, + FIELD_PREP(LMK04832_BIT_SYNC_POL, 0) | + FIELD_PREP(LMK04832_BIT_SYNC_EN, 1) | + FIELD_PREP(LMK04832_BIT_SYNC_MODE, lmk->sync_mode)); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, LMK04832_REG_SYNC_DIS, 0xff); + if (ret) + return ret; + + lmk->sclk.init = &init; + return devm_clk_hw_register(lmk->dev, &lmk->sclk); +} + +static int lmk04832_dclk_is_enabled(struct clk_hw *hw) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + unsigned int tmp; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL3(dclk->id), + &tmp); + if (ret) + return ret; + + return !FIELD_GET(LMK04832_BIT_DCLKX_Y_PD, tmp); +} + +static int lmk04832_dclk_prepare(struct clk_hw *hw) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + + return regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL3(dclk->id), + LMK04832_BIT_DCLKX_Y_PD, 0x00); +} + +static void lmk04832_dclk_unprepare(struct clk_hw *hw) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + + regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL3(dclk->id), + LMK04832_BIT_DCLKX_Y_PD, 0xff); +} + +static unsigned long lmk04832_dclk_recalc_rate(struct clk_hw *hw, + unsigned long prate) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + unsigned int dclk_div; + unsigned int lsb, msb; + unsigned long rate; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(dclk->id), + &lsb); + if (ret) + return ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(dclk->id), + &msb); + if (ret) + return ret; + + dclk_div = FIELD_GET(LMK04832_BIT_DCLK_DIV_MSB, msb) << 8 | lsb; + rate = DIV_ROUND_CLOSEST(prate, dclk_div); + + return rate; +}; + +static long lmk04832_dclk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + unsigned long dclk_rate; + unsigned int dclk_div; + + dclk_div = DIV_ROUND_CLOSEST(*prate, rate); + dclk_rate = DIV_ROUND_CLOSEST(*prate, dclk_div); + + if (dclk_div < 1 || dclk_div > 0x3ff) { + dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw)); + return -EINVAL; + } + + if (rate != dclk_rate) + return -EINVAL; + + return dclk_rate; +}; + +static int lmk04832_dclk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct lmk_dclk *dclk = container_of(hw, struct lmk_dclk, hw); + struct lmk04832 *lmk = dclk->lmk; + unsigned int dclk_div; + int ret; + + dclk_div = DIV_ROUND_CLOSEST(prate, rate); + + if (dclk_div > 0x3ff) { + dev_err(lmk->dev, "%s_div out of range\n", clk_hw_get_name(hw)); + return -EINVAL; + } + + /* Enable Duty Cycle Corretion */ + if (dclk_div == 1) { + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL3(dclk->id), + LMK04832_BIT_DCLKX_Y_DCC, + FIELD_PREP(LMK04832_BIT_DCLKX_Y_DCC, 1)); + if (ret) + return ret; + } + + /* + * While using Divide-by-2 or Divide-by-3 for DCLK_X_Y_DIV, SYNC + * procedure requires to first program Divide-by-4 and then back to + * Divide-by-2 or Divide-by-3 before doing SYNC. + */ + if (dclk_div == 2 || dclk_div == 3) { + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL2(dclk->id), + LMK04832_BIT_DCLK_DIV_MSB, 0x00); + if (ret) + return ret; + + ret = regmap_write(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL0(dclk->id), 0x04); + if (ret) + return ret; + } + + ret = regmap_write(lmk->regmap, LMK04832_REG_CLKOUT_CTRL0(dclk->id), + FIELD_GET(0x0ff, dclk_div)); + if (ret) + return ret; + + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL2(dclk->id), + LMK04832_BIT_DCLK_DIV_MSB, + FIELD_GET(0x300, dclk_div)); + if (ret) + return ret; + + ret = lmk04832_sclk_sync_sequence(lmk); + if (ret) + dev_err(lmk->dev, "SYNC sequence failed\n"); + + return ret; +}; + +static const struct clk_ops lmk04832_dclk_ops = { + .is_enabled = lmk04832_dclk_is_enabled, + .prepare = lmk04832_dclk_prepare, + .unprepare = lmk04832_dclk_unprepare, + .recalc_rate = lmk04832_dclk_recalc_rate, + .round_rate = lmk04832_dclk_round_rate, + .set_rate = lmk04832_dclk_set_rate, +}; + +static int lmk04832_clkout_is_enabled(struct clk_hw *hw) +{ + struct lmk_clkout *clkout = container_of(hw, struct lmk_clkout, hw); + struct lmk04832 *lmk = clkout->lmk; + unsigned int clkoutx_y_pd; + unsigned int sclkx_y_pd; + unsigned int tmp; + u32 enabled; + int ret; + u8 fmt; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_CTRL2(clkout->id), + &clkoutx_y_pd); + if (ret) + return ret; + + enabled = !FIELD_GET(LMK04832_BIT_CLKOUTX_Y_PD, clkoutx_y_pd); + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id), + &tmp); + if (ret) + return ret; + + if (FIELD_GET(LMK04832_BIT_CLKOUT_SRC_MUX, tmp)) { + ret = regmap_read(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL4(clkout->id), + &sclkx_y_pd); + if (ret) + return ret; + + enabled = enabled && !FIELD_GET(LMK04832_BIT_SCLK_PD, sclkx_y_pd); + } + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_FMT(clkout->id), + &tmp); + if (ret) + return ret; + + if (clkout->id % 2) + fmt = FIELD_GET(0xf0, tmp); + else + fmt = FIELD_GET(0x0f, tmp); + + return enabled && !fmt; +} + +static int lmk04832_clkout_prepare(struct clk_hw *hw) +{ + struct lmk_clkout *clkout = container_of(hw, struct lmk_clkout, hw); + struct lmk04832 *lmk = clkout->lmk; + unsigned int tmp; + int ret; + + if (clkout->format == LMK04832_VAL_CLKOUT_FMT_POWERDOWN) + dev_err(lmk->dev, "prepared %s but format is powerdown\n", + clk_hw_get_name(hw)); + + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL2(clkout->id), + LMK04832_BIT_CLKOUTX_Y_PD, 0x00); + if (ret) + return ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id), + &tmp); + if (ret) + return ret; + + if (FIELD_GET(LMK04832_BIT_CLKOUT_SRC_MUX, tmp)) { + ret = regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_CTRL4(clkout->id), + LMK04832_BIT_SCLK_PD, 0x00); + if (ret) + return ret; + } + + return regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_FMT(clkout->id), + LMK04832_BIT_CLKOUT_FMT(clkout->id), + clkout->format << 4 * (clkout->id % 2)); +} + +static void lmk04832_clkout_unprepare(struct clk_hw *hw) +{ + struct lmk_clkout *clkout = container_of(hw, struct lmk_clkout, hw); + struct lmk04832 *lmk = clkout->lmk; + + regmap_update_bits(lmk->regmap, LMK04832_REG_CLKOUT_FMT(clkout->id), + LMK04832_BIT_CLKOUT_FMT(clkout->id), + 0x00); +} + +static int lmk04832_clkout_set_parent(struct clk_hw *hw, uint8_t index) +{ + struct lmk_clkout *clkout = container_of(hw, struct lmk_clkout, hw); + struct lmk04832 *lmk = clkout->lmk; + + return regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_SRC_MUX(clkout->id), + LMK04832_BIT_CLKOUT_SRC_MUX, + FIELD_PREP(LMK04832_BIT_CLKOUT_SRC_MUX, + index)); +} + +static uint8_t lmk04832_clkout_get_parent(struct clk_hw *hw) +{ + struct lmk_clkout *clkout = container_of(hw, struct lmk_clkout, hw); + struct lmk04832 *lmk = clkout->lmk; + unsigned int tmp; + int ret; + + ret = regmap_read(lmk->regmap, LMK04832_REG_CLKOUT_SRC_MUX(clkout->id), + &tmp); + if (ret) + return ret; + + return FIELD_GET(LMK04832_BIT_CLKOUT_SRC_MUX, tmp); +} + +static const struct clk_ops lmk04832_clkout_ops = { + .is_enabled = lmk04832_clkout_is_enabled, + .prepare = lmk04832_clkout_prepare, + .unprepare = lmk04832_clkout_unprepare, + .set_parent = lmk04832_clkout_set_parent, + .get_parent = lmk04832_clkout_get_parent, +}; + +static int lmk04832_register_clkout(struct lmk04832 *lmk, const int num) +{ + char name[] = "lmk-clkoutXX"; + char dclk_name[] = "lmk-dclkXX_YY"; + const char *parent_names[2]; + struct clk_init_data init; + int dclk_num = num / 2; + int ret; + + if (num % 2 == 0) { + sprintf(dclk_name, "lmk-dclk%02d_%02d", num, num + 1); + init.name = dclk_name; + parent_names[0] = clk_hw_get_name(&lmk->vco); + init.ops = &lmk04832_dclk_ops; + init.flags = CLK_SET_RATE_PARENT; + init.num_parents = 1; + + lmk->dclk[dclk_num].id = num; + lmk->dclk[dclk_num].lmk = lmk; + lmk->dclk[dclk_num].hw.init = &init; + + ret = devm_clk_hw_register(lmk->dev, &lmk->dclk[dclk_num].hw); + if (ret) + return ret; + } else { + sprintf(dclk_name, "lmk-dclk%02d_%02d", num - 1, num); + } + + if (of_property_read_string_index(lmk->dev->of_node, + "clock-output-names", + num, &init.name)) { + sprintf(name, "lmk-clkout%02d", num); + init.name = name; + } + + parent_names[0] = dclk_name; + parent_names[1] = clk_hw_get_name(&lmk->sclk); + init.parent_names = parent_names; + init.ops = &lmk04832_clkout_ops; + init.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT; + init.num_parents = ARRAY_SIZE(parent_names); + + lmk->clkout[num].id = num; + lmk->clkout[num].lmk = lmk; + lmk->clkout[num].hw.init = &init; + lmk->clk_data->hws[num] = &lmk->clkout[num].hw; + + /* Set initial parent */ + regmap_update_bits(lmk->regmap, + LMK04832_REG_CLKOUT_SRC_MUX(num), + LMK04832_BIT_CLKOUT_SRC_MUX, + FIELD_PREP(LMK04832_BIT_CLKOUT_SRC_MUX, + lmk->clkout[num].sysref)); + + return devm_clk_hw_register(lmk->dev, &lmk->clkout[num].hw); +} + +static int lmk04832_set_spi_rdbk(const struct lmk04832 *lmk, const int rdbk_pin) +{ + int reg; + int ret; + + dev_info(lmk->dev, "setting up 4-wire mode\n"); + ret = regmap_write(lmk->regmap, LMK04832_REG_RST3W, + LMK04832_BIT_SPI_3WIRE_DIS); + if (ret) + return ret; + + switch (rdbk_pin) { + case RDBK_CLKIN_SEL0: + reg = LMK04832_REG_CLKIN_SEL0; + break; + case RDBK_CLKIN_SEL1: + reg = LMK04832_REG_CLKIN_SEL1; + break; + case RDBK_RESET: + reg = LMK04832_REG_CLKIN_RST; + break; + default: + return -EINVAL; + } + + return regmap_write(lmk->regmap, reg, + FIELD_PREP(LMK04832_BIT_CLKIN_SEL_MUX, + LMK04832_VAL_CLKIN_SEL_MUX_SPI_RDBK) | + FIELD_PREP(LMK04832_BIT_CLKIN_SEL_TYPE, + LMK04832_VAL_CLKIN_SEL_TYPE_OUT)); +} + +static int lmk04832_probe(struct spi_device *spi) +{ + const struct lmk04832_device_info *info; + int rdbk_pin = RDBK_CLKIN_SEL1; + struct device_node *child; + struct lmk04832 *lmk; + u8 tmp[3]; + int ret; + int i; + + info = &lmk04832_device_info[spi_get_device_id(spi)->driver_data]; + + lmk = devm_kzalloc(&spi->dev, sizeof(struct lmk04832), GFP_KERNEL); + if (!lmk) + return -ENOMEM; + + lmk->dev = &spi->dev; + + lmk->oscin = devm_clk_get(lmk->dev, "oscin"); + if (IS_ERR(lmk->oscin)) { + dev_err(lmk->dev, "failed to get oscin clock\n"); + return PTR_ERR(lmk->oscin); + } + + ret = clk_prepare_enable(lmk->oscin); + if (ret) + return ret; + + lmk->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", + GPIOD_OUT_LOW); + + lmk->dclk = devm_kcalloc(lmk->dev, info->num_channels >> 1, + sizeof(struct lmk_dclk), GFP_KERNEL); + if (IS_ERR(lmk->dclk)) { + ret = PTR_ERR(lmk->dclk); + goto err_disable_oscin; + } + + lmk->clkout = devm_kcalloc(lmk->dev, info->num_channels, + sizeof(*lmk->clkout), GFP_KERNEL); + if (IS_ERR(lmk->clkout)) { + ret = PTR_ERR(lmk->clkout); + goto err_disable_oscin; + } + + lmk->clk_data = devm_kzalloc(lmk->dev, struct_size(lmk->clk_data, hws, + info->num_channels), + GFP_KERNEL); + if (IS_ERR(lmk->clk_data)) { + ret = PTR_ERR(lmk->clk_data); + goto err_disable_oscin; + } + + device_property_read_u32(lmk->dev, "ti,vco-hz", &lmk->vco_rate); + + lmk->sysref_ddly = 8; + device_property_read_u32(lmk->dev, "ti,sysref-ddly", &lmk->sysref_ddly); + + lmk->sysref_mux = LMK04832_VAL_SYSREF_MUX_CONTINUOUS; + device_property_read_u32(lmk->dev, "ti,sysref-mux", + &lmk->sysref_mux); + + lmk->sync_mode = LMK04832_VAL_SYNC_MODE_OFF; + device_property_read_u32(lmk->dev, "ti,sync-mode", + &lmk->sync_mode); + + lmk->sysref_pulse_cnt = 4; + device_property_read_u32(lmk->dev, "ti,sysref-pulse-count", + &lmk->sysref_pulse_cnt); + + for_each_child_of_node(lmk->dev->of_node, child) { + int reg; + + ret = of_property_read_u32(child, "reg", ®); + if (ret) { + dev_err(lmk->dev, "missing reg property in child: %s\n", + child->full_name); + of_node_put(child); + goto err_disable_oscin; + } + + of_property_read_u32(child, "ti,clkout-fmt", + &lmk->clkout[reg].format); + + if (lmk->clkout[reg].format >= 0x0a && reg % 2 == 0 + && reg != 8 && reg != 10) + dev_err(lmk->dev, "invalid format for clkout%02d\n", + reg); + + lmk->clkout[reg].sysref = + of_property_read_bool(child, "ti,clkout-sysref"); + } + + lmk->regmap = devm_regmap_init_spi(spi, ®map_config); + if (IS_ERR(lmk->regmap)) { + dev_err(lmk->dev, "%s: regmap allocation failed: %ld\n", + + __func__, PTR_ERR(lmk->regmap)); + ret = PTR_ERR(lmk->regmap); + goto err_disable_oscin; + } + + regmap_write(lmk->regmap, LMK04832_REG_RST3W, LMK04832_BIT_RESET); + + if (!(spi->mode & SPI_3WIRE)) { + device_property_read_u32(lmk->dev, "ti,spi-4wire-rdbk", + &rdbk_pin); + ret = lmk04832_set_spi_rdbk(lmk, rdbk_pin); + if (ret) + goto err_disable_oscin; + } + + regmap_bulk_read(lmk->regmap, LMK04832_REG_ID_PROD_MSB, &tmp, 3); + if ((tmp[0] << 8 | tmp[1]) != info->pid || tmp[2] != info->maskrev) { + dev_err(lmk->dev, "unsupported device type: pid 0x%04x, maskrev 0x%02x\n", + tmp[0] << 8 | tmp[1], tmp[2]); + ret = -EINVAL; + goto err_disable_oscin; + } + + ret = lmk04832_register_vco(lmk); + if (ret) { + dev_err(lmk->dev, "failed to init device clock path\n"); + goto err_disable_oscin; + } + + if (lmk->vco_rate) { + dev_info(lmk->dev, "setting VCO rate to %u Hz\n", lmk->vco_rate); + ret = clk_set_rate(lmk->vco.clk, lmk->vco_rate); + if (ret) { + dev_err(lmk->dev, "failed to set VCO rate\n"); + goto err_disable_vco; + } + } + + ret = lmk04832_register_sclk(lmk); + if (ret) { + dev_err(lmk->dev, "failed to init SYNC/SYSREF clock path\n"); + goto err_disable_vco; + } + + for (i = 0; i < info->num_channels; i++) { + ret = lmk04832_register_clkout(lmk, i); + if (ret) { + dev_err(lmk->dev, "failed to register clk %d\n", i); + goto err_disable_vco; + } + } + + lmk->clk_data->num = info->num_channels; + ret = of_clk_add_hw_provider(lmk->dev->of_node, of_clk_hw_onecell_get, + lmk->clk_data); + if (ret) { + dev_err(lmk->dev, "failed to add provider (%d)\n", ret); + goto err_disable_vco; + } + + spi_set_drvdata(spi, lmk); + + return 0; + +err_disable_vco: + clk_disable_unprepare(lmk->vco.clk); + +err_disable_oscin: + clk_disable_unprepare(lmk->oscin); + + return ret; +} + +static int lmk04832_remove(struct spi_device *spi) +{ + struct lmk04832 *lmk = spi_get_drvdata(spi); + + clk_disable_unprepare(lmk->oscin); + of_clk_del_provider(spi->dev.of_node); + + return 0; +} +static const struct spi_device_id lmk04832_id[] = { + { "lmk04832", LMK04832 }, + {} +}; +MODULE_DEVICE_TABLE(spi, lmk04832_id); + +static const struct of_device_id lmk04832_of_id[] = { + { .compatible = "ti,lmk04832" }, + {} +}; +MODULE_DEVICE_TABLE(of, lmk04832_of_id); + +static struct spi_driver lmk04832_driver = { + .driver = { + .name = "lmk04832", + .of_match_table = lmk04832_of_id, + }, + .probe = lmk04832_probe, + .remove = lmk04832_remove, + .id_table = lmk04832_id, +}; +module_spi_driver(lmk04832_driver); + +MODULE_AUTHOR("Liam Beguin <lvb@xiphos.com>"); +MODULE_DESCRIPTION("Texas Instruments LMK04832"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index e0446e66fa64..57ae183982d8 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -19,6 +19,7 @@ #include <linux/i2c.h> #include <linux/module.h> #include <linux/regmap.h> +#include <linux/regulator/consumer.h> #include <linux/slab.h> #include <asm/unaligned.h> @@ -59,6 +60,7 @@ struct clk_si5341_synth { struct clk_si5341_output { struct clk_hw hw; struct clk_si5341 *data; + struct regulator *vddo_reg; u8 index; }; #define to_clk_si5341_output(_hw) \ @@ -78,12 +80,15 @@ struct clk_si5341 { u8 num_outputs; u8 num_synth; u16 chip_id; + bool xaxb_ext_clk; + bool iovdd_33; }; #define to_clk_si5341(_hw) container_of(_hw, struct clk_si5341, hw) struct clk_si5341_output_config { u8 out_format_drv_bits; u8 out_cm_ampl_bits; + u8 vdd_sel_bits; bool synth_master; bool always_on; }; @@ -92,12 +97,23 @@ struct clk_si5341_output_config { #define SI5341_PN_BASE 0x0002 #define SI5341_DEVICE_REV 0x0005 #define SI5341_STATUS 0x000C +#define SI5341_LOS 0x000D +#define SI5341_STATUS_STICKY 0x0011 +#define SI5341_LOS_STICKY 0x0012 #define SI5341_SOFT_RST 0x001C #define SI5341_IN_SEL 0x0021 +#define SI5341_DEVICE_READY 0x00FE #define SI5341_XAXB_CFG 0x090E +#define SI5341_IO_VDD_SEL 0x0943 #define SI5341_IN_EN 0x0949 #define SI5341_INX_TO_PFD_EN 0x094A +/* Status bits */ +#define SI5341_STATUS_SYSINCAL BIT(0) +#define SI5341_STATUS_LOSXAXB BIT(1) +#define SI5341_STATUS_LOSREF BIT(2) +#define SI5341_STATUS_LOL BIT(3) + /* Input selection */ #define SI5341_IN_SEL_MASK 0x06 #define SI5341_IN_SEL_SHIFT 1 @@ -126,6 +142,8 @@ struct clk_si5341_output_config { #define SI5341_OUT_R_REG(output) \ ((output)->data->reg_rdiv_offset[(output)->index]) +#define SI5341_OUT_MUX_VDD_SEL_MASK 0x38 + /* Synthesize N divider */ #define SI5341_SYNTH_N_NUM(x) (0x0302 + ((x) * 11)) #define SI5341_SYNTH_N_DEN(x) (0x0308 + ((x) * 11)) @@ -335,11 +353,12 @@ static const struct si5341_reg_default si5341_reg_defaults[] = { { 0x0804, 0x00 }, /* Not in datasheet */ { 0x090E, 0x02 }, /* XAXB_EXTCLK_EN=0 XAXB_PDNB=1 (use XTAL) */ { 0x091C, 0x04 }, /* ZDM_EN=4 (Normal mode) */ - { 0x0943, 0x00 }, /* IO_VDD_SEL=0 (0=1v8, use 1=3v3) */ { 0x0949, 0x00 }, /* IN_EN (disable input clocks) */ { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */ { 0x0A02, 0x00 }, /* Not in datasheet */ { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */ + { 0x0B57, 0x10 }, /* VCO_RESET_CALCODE (not described in datasheet) */ + { 0x0B58, 0x05 }, /* VCO_RESET_CALCODE (not described in datasheet) */ }; /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */ @@ -512,9 +531,11 @@ static int si5341_clk_reparent(struct clk_si5341 *data, u8 index) if (err < 0) return err; - /* Power up XTAL oscillator and buffer */ + /* Power up XTAL oscillator and buffer, select clock mode */ err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG, - SI5341_XAXB_CFG_PDNB, SI5341_XAXB_CFG_PDNB); + SI5341_XAXB_CFG_PDNB | SI5341_XAXB_CFG_EXTCLK_EN, + SI5341_XAXB_CFG_PDNB | (data->xaxb_ext_clk ? + SI5341_XAXB_CFG_EXTCLK_EN : 0)); if (err < 0) return err; } @@ -623,6 +644,9 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw, SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den); if (err < 0) return err; + /* Check for bogus/uninitialized settings */ + if (!n_num || !n_den) + return 0; /* * n_num and n_den are shifted left as much as possible, so to prevent @@ -806,6 +830,9 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, { unsigned long r; + if (!rate) + return 0; + r = *parent_rate >> 1; /* If rate is an even divisor, no changes to parent required */ @@ -834,11 +861,16 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_si5341_output *output = to_clk_si5341_output(hw); - /* Frequency divider is (r_div + 1) * 2 */ - u32 r_div = (parent_rate / rate) >> 1; + u32 r_div; int err; u8 r[3]; + if (!rate) + return -EINVAL; + + /* Frequency divider is (r_div + 1) * 2 */ + r_div = (parent_rate / rate) >> 1; + if (r_div <= 1) r_div = 0; else if (r_div >= BIT(24)) @@ -1083,7 +1115,7 @@ static const struct si5341_reg_default si5341_preamble[] = { { 0x0B25, 0x00 }, { 0x0502, 0x01 }, { 0x0505, 0x03 }, - { 0x0957, 0x1F }, + { 0x0957, 0x17 }, { 0x0B4E, 0x1A }, }; @@ -1129,6 +1161,11 @@ static int si5341_finalize_defaults(struct clk_si5341 *data) int res; u32 revision; + res = regmap_write(data->regmap, SI5341_IO_VDD_SEL, + data->iovdd_33 ? 1 : 0); + if (res < 0) + return res; + res = regmap_read(data->regmap, SI5341_DEVICE_REV, &revision); if (res < 0) return res; @@ -1189,6 +1226,32 @@ static const struct regmap_range_cfg si5341_regmap_ranges[] = { }, }; +static int si5341_wait_device_ready(struct i2c_client *client) +{ + int count; + + /* Datasheet warns: Any attempt to read or write any register other + * than DEVICE_READY before DEVICE_READY reads as 0x0F may corrupt the + * NVM programming and may corrupt the register contents, as they are + * read from NVM. Note that this includes accesses to the PAGE register. + * Also: DEVICE_READY is available on every register page, so no page + * change is needed to read it. + * Do this outside regmap to avoid automatic PAGE register access. + * May take up to 300ms to complete. + */ + for (count = 0; count < 15; ++count) { + s32 result = i2c_smbus_read_byte_data(client, + SI5341_DEVICE_READY); + if (result < 0) + return result; + if (result == 0x0F) + return 0; + msleep(20); + } + dev_err(&client->dev, "timeout waiting for DEVICE_READY\n"); + return -EIO; +} + static const struct regmap_config si5341_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -1199,11 +1262,11 @@ static const struct regmap_config si5341_regmap_config = { .volatile_table = &si5341_regmap_volatile, }; -static int si5341_dt_parse_dt(struct i2c_client *client, - struct clk_si5341_output_config *config) +static int si5341_dt_parse_dt(struct clk_si5341 *data, + struct clk_si5341_output_config *config) { struct device_node *child; - struct device_node *np = client->dev.of_node; + struct device_node *np = data->i2c_client->dev.of_node; u32 num; u32 val; @@ -1212,13 +1275,13 @@ static int si5341_dt_parse_dt(struct i2c_client *client, for_each_child_of_node(np, child) { if (of_property_read_u32(child, "reg", &num)) { - dev_err(&client->dev, "missing reg property of %s\n", + dev_err(&data->i2c_client->dev, "missing reg property of %s\n", child->name); goto put_child; } if (num >= SI5341_MAX_NUM_OUTPUTS) { - dev_err(&client->dev, "invalid clkout %d\n", num); + dev_err(&data->i2c_client->dev, "invalid clkout %d\n", num); goto put_child; } @@ -1237,7 +1300,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client, config[num].out_format_drv_bits |= 0xc0; break; default: - dev_err(&client->dev, + dev_err(&data->i2c_client->dev, "invalid silabs,format %u for %u\n", val, num); goto put_child; @@ -1250,7 +1313,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client, if (!of_property_read_u32(child, "silabs,common-mode", &val)) { if (val > 0xf) { - dev_err(&client->dev, + dev_err(&data->i2c_client->dev, "invalid silabs,common-mode %u\n", val); goto put_child; @@ -1261,7 +1324,7 @@ static int si5341_dt_parse_dt(struct i2c_client *client, if (!of_property_read_u32(child, "silabs,amplitude", &val)) { if (val > 0xf) { - dev_err(&client->dev, + dev_err(&data->i2c_client->dev, "invalid silabs,amplitude %u\n", val); goto put_child; @@ -1278,6 +1341,34 @@ static int si5341_dt_parse_dt(struct i2c_client *client, config[num].always_on = of_property_read_bool(child, "always-on"); + + config[num].vdd_sel_bits = 0x08; + if (data->clk[num].vddo_reg) { + int vdd = regulator_get_voltage(data->clk[num].vddo_reg); + + switch (vdd) { + case 3300000: + config[num].vdd_sel_bits |= 0 << 4; + break; + case 1800000: + config[num].vdd_sel_bits |= 1 << 4; + break; + case 2500000: + config[num].vdd_sel_bits |= 2 << 4; + break; + default: + dev_err(&data->i2c_client->dev, + "unsupported vddo voltage %d for %s\n", + vdd, child->name); + goto put_child; + } + } else { + /* chip seems to default to 2.5V when not set */ + dev_warn(&data->i2c_client->dev, + "no regulator set, defaulting vdd_sel to 2.5V for %s\n", + child->name); + config[num].vdd_sel_bits |= 2 << 4; + } } return 0; @@ -1366,6 +1457,94 @@ static int si5341_clk_select_active_input(struct clk_si5341 *data) return res; } +static ssize_t input_present_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct clk_si5341 *data = dev_get_drvdata(dev); + u32 status; + int res = regmap_read(data->regmap, SI5341_STATUS, &status); + + if (res < 0) + return res; + res = !(status & SI5341_STATUS_LOSREF); + return snprintf(buf, PAGE_SIZE, "%d\n", res); +} +static DEVICE_ATTR_RO(input_present); + +static ssize_t input_present_sticky_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct clk_si5341 *data = dev_get_drvdata(dev); + u32 status; + int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status); + + if (res < 0) + return res; + res = !(status & SI5341_STATUS_LOSREF); + return snprintf(buf, PAGE_SIZE, "%d\n", res); +} +static DEVICE_ATTR_RO(input_present_sticky); + +static ssize_t pll_locked_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct clk_si5341 *data = dev_get_drvdata(dev); + u32 status; + int res = regmap_read(data->regmap, SI5341_STATUS, &status); + + if (res < 0) + return res; + res = !(status & SI5341_STATUS_LOL); + return snprintf(buf, PAGE_SIZE, "%d\n", res); +} +static DEVICE_ATTR_RO(pll_locked); + +static ssize_t pll_locked_sticky_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct clk_si5341 *data = dev_get_drvdata(dev); + u32 status; + int res = regmap_read(data->regmap, SI5341_STATUS_STICKY, &status); + + if (res < 0) + return res; + res = !(status & SI5341_STATUS_LOL); + return snprintf(buf, PAGE_SIZE, "%d\n", res); +} +static DEVICE_ATTR_RO(pll_locked_sticky); + +static ssize_t clear_sticky_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct clk_si5341 *data = dev_get_drvdata(dev); + long val; + + if (kstrtol(buf, 10, &val)) + return -EINVAL; + if (val) { + int res = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); + + if (res < 0) + return res; + } + return count; +} +static DEVICE_ATTR_WO(clear_sticky); + +static const struct attribute *si5341_attributes[] = { + &dev_attr_input_present.attr, + &dev_attr_input_present_sticky.attr, + &dev_attr_pll_locked.attr, + &dev_attr_pll_locked_sticky.attr, + &dev_attr_clear_sticky.attr, + NULL +}; + static int si5341_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -1378,6 +1557,7 @@ static int si5341_probe(struct i2c_client *client, unsigned int i; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; bool initialization_required; + u32 status; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -1385,6 +1565,11 @@ static int si5341_probe(struct i2c_client *client, data->i2c_client = client; + /* Must be done before otherwise touching hardware */ + err = si5341_wait_device_ready(client); + if (err) + return err; + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { input = devm_clk_get(&client->dev, si5341_input_clock_names[i]); if (IS_ERR(input)) { @@ -1397,9 +1582,33 @@ static int si5341_probe(struct i2c_client *client, } } - err = si5341_dt_parse_dt(client, config); + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + char reg_name[10]; + + snprintf(reg_name, sizeof(reg_name), "vddo%d", i); + data->clk[i].vddo_reg = devm_regulator_get_optional( + &client->dev, reg_name); + if (IS_ERR(data->clk[i].vddo_reg)) { + err = PTR_ERR(data->clk[i].vddo_reg); + data->clk[i].vddo_reg = NULL; + if (err == -ENODEV) + continue; + goto cleanup; + } else { + err = regulator_enable(data->clk[i].vddo_reg); + if (err) { + dev_err(&client->dev, + "failed to enable %s regulator: %d\n", + reg_name, err); + data->clk[i].vddo_reg = NULL; + goto cleanup; + } + } + } + + err = si5341_dt_parse_dt(data, config); if (err) - return err; + goto cleanup; if (of_property_read_string(client->dev.of_node, "clock-output-names", &init.name)) @@ -1407,34 +1616,40 @@ static int si5341_probe(struct i2c_client *client, root_clock_name = init.name; data->regmap = devm_regmap_init_i2c(client, &si5341_regmap_config); - if (IS_ERR(data->regmap)) - return PTR_ERR(data->regmap); + if (IS_ERR(data->regmap)) { + err = PTR_ERR(data->regmap); + goto cleanup; + } i2c_set_clientdata(client, data); err = si5341_probe_chip_id(data); if (err < 0) - return err; + goto cleanup; if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) { initialization_required = true; } else { err = si5341_is_programmed_already(data); if (err < 0) - return err; + goto cleanup; initialization_required = !err; } + data->xaxb_ext_clk = of_property_read_bool(client->dev.of_node, + "silabs,xaxb-ext-clk"); + data->iovdd_33 = of_property_read_bool(client->dev.of_node, + "silabs,iovdd-33"); if (initialization_required) { /* Populate the regmap cache in preparation for "cache only" */ err = si5341_read_settings(data); if (err < 0) - return err; + goto cleanup; err = si5341_send_preamble(data); if (err < 0) - return err; + goto cleanup; /* * We intend to send all 'final' register values in a single @@ -1447,19 +1662,19 @@ static int si5341_probe(struct i2c_client *client, err = si5341_write_multiple(data, si5341_reg_defaults, ARRAY_SIZE(si5341_reg_defaults)); if (err < 0) - return err; + goto cleanup; } /* Input must be up and running at this point */ err = si5341_clk_select_active_input(data); if (err < 0) - return err; + goto cleanup; if (initialization_required) { /* PLL configuration is required */ err = si5341_initialize_pll(data); if (err < 0) - return err; + goto cleanup; } /* Register the PLL */ @@ -1472,7 +1687,7 @@ static int si5341_probe(struct i2c_client *client, err = devm_clk_hw_register(&client->dev, &data->hw); if (err) { dev_err(&client->dev, "clock registration failed\n"); - return err; + goto cleanup; } init.num_parents = 1; @@ -1509,13 +1724,17 @@ static int si5341_probe(struct i2c_client *client, regmap_write(data->regmap, SI5341_OUT_CM(&data->clk[i]), config[i].out_cm_ampl_bits); + regmap_update_bits(data->regmap, + SI5341_OUT_MUX_SEL(&data->clk[i]), + SI5341_OUT_MUX_VDD_SEL_MASK, + config[i].vdd_sel_bits); } err = devm_clk_hw_register(&client->dev, &data->clk[i].hw); kfree(init.name); /* clock framework made a copy of the name */ if (err) { dev_err(&client->dev, "output %u registration failed\n", i); - return err; + goto cleanup; } if (config[i].always_on) clk_prepare(data->clk[i].hw.clk); @@ -1525,7 +1744,7 @@ static int si5341_probe(struct i2c_client *client, data); if (err) { dev_err(&client->dev, "unable to add clk provider\n"); - return err; + goto cleanup; } if (initialization_required) { @@ -1533,11 +1752,33 @@ static int si5341_probe(struct i2c_client *client, regcache_cache_only(data->regmap, false); err = regcache_sync(data->regmap); if (err < 0) - return err; + goto cleanup; err = si5341_finalize_defaults(data); if (err < 0) - return err; + goto cleanup; + } + + /* wait for device to report input clock present and PLL lock */ + err = regmap_read_poll_timeout(data->regmap, SI5341_STATUS, status, + !(status & (SI5341_STATUS_LOSREF | SI5341_STATUS_LOL)), + 10000, 250000); + if (err) { + dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); + goto cleanup; + } + + /* clear sticky alarm bits from initialization */ + err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); + if (err) { + dev_err(&client->dev, "unable to clear sticky status\n"); + goto cleanup; + } + + err = sysfs_create_files(&client->dev.kobj, si5341_attributes); + if (err) { + dev_err(&client->dev, "unable to create sysfs files\n"); + goto cleanup; } /* Free the names, clk framework makes copies */ @@ -1545,6 +1786,28 @@ static int si5341_probe(struct i2c_client *client, devm_kfree(&client->dev, (void *)synth_clock_names[i]); return 0; + +cleanup: + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + if (data->clk[i].vddo_reg) + regulator_disable(data->clk[i].vddo_reg); + } + return err; +} + +static int si5341_remove(struct i2c_client *client) +{ + struct clk_si5341 *data = i2c_get_clientdata(client); + int i; + + sysfs_remove_files(&client->dev.kobj, si5341_attributes); + + for (i = 0; i < SI5341_MAX_NUM_OUTPUTS; ++i) { + if (data->clk[i].vddo_reg) + regulator_disable(data->clk[i].vddo_reg); + } + + return 0; } static const struct i2c_device_id si5341_id[] = { @@ -1573,6 +1836,7 @@ static struct i2c_driver si5341_driver = { .of_match_table = clk_si5341_of_match, }, .probe = si5341_probe, + .remove = si5341_remove, .id_table = si5341_id, }; module_i2c_driver(si5341_driver); diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index a875649df8b8..6adc625e79cb 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -10,8 +10,11 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/reset-controller.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -245,7 +248,7 @@ static const char * const dsi_src[] = { }; static const char * const rtc_src[] = { - "off", "ck_lse", "ck_lsi", "ck_hse_rtc" + "off", "ck_lse", "ck_lsi", "ck_hse" }; static const char * const mco1_src[] = { @@ -469,7 +472,7 @@ static const struct clk_ops mp1_gate_clk_ops = { .is_enabled = clk_gate_is_enabled, }; -static struct clk_hw *_get_stm32_mux(void __iomem *base, +static struct clk_hw *_get_stm32_mux(struct device *dev, void __iomem *base, const struct stm32_mux_cfg *cfg, spinlock_t *lock) { @@ -478,7 +481,7 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base, struct clk_hw *mux_hw; if (cfg->mmux) { - mmux = kzalloc(sizeof(*mmux), GFP_KERNEL); + mmux = devm_kzalloc(dev, sizeof(*mmux), GFP_KERNEL); if (!mmux) return ERR_PTR(-ENOMEM); @@ -493,7 +496,7 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base, cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw; } else { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL); if (!mux) return ERR_PTR(-ENOMEM); @@ -509,13 +512,13 @@ static struct clk_hw *_get_stm32_mux(void __iomem *base, return mux_hw; } -static struct clk_hw *_get_stm32_div(void __iomem *base, +static struct clk_hw *_get_stm32_div(struct device *dev, void __iomem *base, const struct stm32_div_cfg *cfg, spinlock_t *lock) { struct clk_divider *div; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); if (!div) return ERR_PTR(-ENOMEM); @@ -530,16 +533,16 @@ static struct clk_hw *_get_stm32_div(void __iomem *base, return &div->hw; } -static struct clk_hw * -_get_stm32_gate(void __iomem *base, - const struct stm32_gate_cfg *cfg, spinlock_t *lock) +static struct clk_hw *_get_stm32_gate(struct device *dev, void __iomem *base, + const struct stm32_gate_cfg *cfg, + spinlock_t *lock) { struct stm32_clk_mgate *mgate; struct clk_gate *gate; struct clk_hw *gate_hw; if (cfg->mgate) { - mgate = kzalloc(sizeof(*mgate), GFP_KERNEL); + mgate = devm_kzalloc(dev, sizeof(*mgate), GFP_KERNEL); if (!mgate) return ERR_PTR(-ENOMEM); @@ -554,7 +557,7 @@ _get_stm32_gate(void __iomem *base, gate_hw = &mgate->gate.hw; } else { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); if (!gate) return ERR_PTR(-ENOMEM); @@ -592,7 +595,7 @@ clk_stm32_register_gate_ops(struct device *dev, if (cfg->ops) init.ops = cfg->ops; - hw = _get_stm32_gate(base, cfg, lock); + hw = _get_stm32_gate(dev, base, cfg, lock); if (IS_ERR(hw)) return ERR_PTR(-ENOMEM); @@ -623,7 +626,7 @@ clk_stm32_register_composite(struct device *dev, gate_ops = NULL; if (cfg->mux) { - mux_hw = _get_stm32_mux(base, cfg->mux, lock); + mux_hw = _get_stm32_mux(dev, base, cfg->mux, lock); if (!IS_ERR(mux_hw)) { mux_ops = &clk_mux_ops; @@ -634,7 +637,7 @@ clk_stm32_register_composite(struct device *dev, } if (cfg->div) { - div_hw = _get_stm32_div(base, cfg->div, lock); + div_hw = _get_stm32_div(dev, base, cfg->div, lock); if (!IS_ERR(div_hw)) { div_ops = &clk_divider_ops; @@ -645,7 +648,7 @@ clk_stm32_register_composite(struct device *dev, } if (cfg->gate) { - gate_hw = _get_stm32_gate(base, cfg->gate, lock); + gate_hw = _get_stm32_gate(dev, base, cfg->gate, lock); if (!IS_ERR(gate_hw)) { gate_ops = &clk_gate_ops; @@ -731,6 +734,7 @@ struct stm32_pll_obj { spinlock_t *lock; void __iomem *reg; struct clk_hw hw; + struct clk_mux mux; }; #define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw) @@ -745,6 +749,8 @@ struct stm32_pll_obj { #define FRAC_MASK 0x1FFF #define FRAC_SHIFT 3 #define FRACLE BIT(16) +#define PLL_MUX_SHIFT 0 +#define PLL_MUX_MASK 3 static int __pll_is_enabled(struct clk_hw *hw) { @@ -856,16 +862,29 @@ static int pll_is_enabled(struct clk_hw *hw) return ret; } +static u8 pll_get_parent(struct clk_hw *hw) +{ + struct stm32_pll_obj *clk_elem = to_pll(hw); + struct clk_hw *mux_hw = &clk_elem->mux.hw; + + __clk_hw_set_clk(mux_hw, hw); + + return clk_mux_ops.get_parent(mux_hw); +} + static const struct clk_ops pll_ops = { .enable = pll_enable, .disable = pll_disable, .recalc_rate = pll_recalc_rate, .is_enabled = pll_is_enabled, + .get_parent = pll_get_parent, }; static struct clk_hw *clk_register_pll(struct device *dev, const char *name, - const char *parent_name, + const char * const *parent_names, + int num_parents, void __iomem *reg, + void __iomem *mux_reg, unsigned long flags, spinlock_t *lock) { @@ -874,15 +893,22 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name, struct clk_hw *hw; int err; - element = kzalloc(sizeof(*element), GFP_KERNEL); + element = devm_kzalloc(dev, sizeof(*element), GFP_KERNEL); if (!element) return ERR_PTR(-ENOMEM); init.name = name; init.ops = &pll_ops; init.flags = flags; - init.parent_names = &parent_name; - init.num_parents = 1; + init.parent_names = parent_names; + init.num_parents = num_parents; + + element->mux.lock = lock; + element->mux.reg = mux_reg; + element->mux.shift = PLL_MUX_SHIFT; + element->mux.mask = PLL_MUX_MASK; + element->mux.flags = CLK_MUX_READ_ONLY; + element->mux.reg = mux_reg; element->hw.init = &init; element->reg = reg; @@ -891,10 +917,8 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name, hw = &element->hw; err = clk_hw_register(dev, hw); - if (err) { - kfree(element); + if (err) return ERR_PTR(err); - } return hw; } @@ -1005,7 +1029,7 @@ static struct clk_hw *clk_register_cktim(struct device *dev, const char *name, struct clk_hw *hw; int err; - tim_ker = kzalloc(sizeof(*tim_ker), GFP_KERNEL); + tim_ker = devm_kzalloc(dev, sizeof(*tim_ker), GFP_KERNEL); if (!tim_ker) return ERR_PTR(-ENOMEM); @@ -1023,16 +1047,56 @@ static struct clk_hw *clk_register_cktim(struct device *dev, const char *name, hw = &tim_ker->hw; err = clk_hw_register(dev, hw); - if (err) { - kfree(tim_ker); + if (err) return ERR_PTR(err); - } return hw; } +/* The divider of RTC clock concerns only ck_hse clock */ +#define HSE_RTC 3 + +static unsigned long clk_divider_rtc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC)) + return clk_divider_ops.recalc_rate(hw, parent_rate); + + return parent_rate; +} + +static int clk_divider_rtc_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + if (clk_hw_get_parent(hw) == clk_hw_get_parent_by_index(hw, HSE_RTC)) + return clk_divider_ops.set_rate(hw, rate, parent_rate); + + return parent_rate; +} + +static int clk_divider_rtc_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + unsigned long best_parent_rate = req->best_parent_rate; + + if (req->best_parent_hw == clk_hw_get_parent_by_index(hw, HSE_RTC)) { + req->rate = clk_divider_ops.round_rate(hw, req->rate, &best_parent_rate); + req->best_parent_rate = best_parent_rate; + } else { + req->rate = best_parent_rate; + } + + return 0; +} + +static const struct clk_ops rtc_div_clk_ops = { + .recalc_rate = clk_divider_rtc_recalc_rate, + .set_rate = clk_divider_rtc_set_rate, + .determine_rate = clk_divider_rtc_determine_rate +}; + struct stm32_pll_cfg { u32 offset; + u32 muxoff; }; static struct clk_hw *_clk_register_pll(struct device *dev, @@ -1042,8 +1106,11 @@ static struct clk_hw *_clk_register_pll(struct device *dev, { struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg; - return clk_register_pll(dev, cfg->name, cfg->parent_name, - base + stm_pll_cfg->offset, cfg->flags, lock); + return clk_register_pll(dev, cfg->name, cfg->parent_names, + cfg->num_parents, + base + stm_pll_cfg->offset, + base + stm_pll_cfg->muxoff, + cfg->flags, lock); } struct stm32_cktim_cfg { @@ -1153,14 +1220,16 @@ _clk_stm32_register_composite(struct device *dev, .func = _clk_hw_register_mux,\ } -#define PLL(_id, _name, _parent, _flags, _offset)\ +#define PLL(_id, _name, _parents, _flags, _offset_p, _offset_mux)\ {\ .id = _id,\ .name = _name,\ - .parent_name = _parent,\ - .flags = _flags,\ + .parent_names = _parents,\ + .num_parents = ARRAY_SIZE(_parents),\ + .flags = CLK_IGNORE_UNUSED | (_flags),\ .cfg = &(struct stm32_pll_cfg) {\ - .offset = _offset,\ + .offset = _offset_p,\ + .muxoff = _offset_mux,\ },\ .func = _clk_register_pll,\ } @@ -1243,6 +1312,10 @@ _clk_stm32_register_composite(struct device *dev, _STM32_DIV(_div_offset, _div_shift, _div_width,\ _div_flags, _div_table, NULL)\ +#define _DIV_RTC(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\ + _STM32_DIV(_div_offset, _div_shift, _div_width,\ + _div_flags, _div_table, &rtc_div_clk_ops) + #define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\ .mux = &(struct stm32_mux_cfg) {\ &(struct mux_cfg) {\ @@ -1657,36 +1730,26 @@ static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = { }; static const struct clock_config stm32mp1_clock_cfg[] = { - /* Oscillator divider */ - DIV(NO_ID, "clk-hsi-div", "clk-hsi", CLK_DIVIDER_POWER_OF_TWO, - RCC_HSICFGR, 0, 2, CLK_DIVIDER_READ_ONLY), - /* External / Internal Oscillators */ GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0), /* ck_csi is used by IO compensation and should be critical */ GATE_MP1(CK_CSI, "ck_csi", "clk-csi", CLK_IS_CRITICAL, RCC_OCENSETR, 4, 0), - GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0), + COMPOSITE(CK_HSI, "ck_hsi", PARENT("clk-hsi"), 0, + _GATE_MP1(RCC_OCENSETR, 0, 0), + _NO_MUX, + _DIV(RCC_HSICFGR, 0, 2, CLK_DIVIDER_POWER_OF_TWO | + CLK_DIVIDER_READ_ONLY, NULL)), GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0), GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0), FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2), - /* ref clock pll */ - MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR, - 0, 2, CLK_MUX_READ_ONLY), - - MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR, - 0, 2, CLK_MUX_READ_ONLY), - - MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR, - 0, 2, CLK_MUX_READ_ONLY), - /* PLLs */ - PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR), - PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR), - PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR), - PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR), + PLL(PLL1, "pll1", ref12_parents, 0, RCC_PLL1CR, RCC_RCK12SELR), + PLL(PLL2, "pll2", ref12_parents, 0, RCC_PLL2CR, RCC_RCK12SELR), + PLL(PLL3, "pll3", ref3_parents, 0, RCC_PLL3CR, RCC_RCK3SELR), + PLL(PLL4, "pll4", ref4_parents, 0, RCC_PLL4CR, RCC_RCK4SELR), /* ODF */ COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0, @@ -1965,13 +2028,10 @@ static const struct clock_config stm32mp1_clock_cfg[] = { _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)), /* RTC clock */ - DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 6, 0), - - COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE | - CLK_SET_RATE_PARENT, + COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE, _GATE(RCC_BDCR, 20, 0), _MUX(RCC_BDCR, 16, 2, 0), - _NO_DIV), + _DIV_RTC(RCC_RTCDIVR, 0, 6, 0, NULL)), /* MCO clocks */ COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE | @@ -1996,16 +2056,76 @@ static const struct clock_config stm32mp1_clock_cfg[] = { _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)), }; -struct stm32_clock_match_data { +static const u32 stm32mp1_clock_secured[] = { + CK_HSE, + CK_HSI, + CK_CSI, + CK_LSI, + CK_LSE, + PLL1, + PLL2, + PLL1_P, + PLL2_P, + PLL2_Q, + PLL2_R, + CK_MPU, + CK_AXI, + SPI6, + I2C4, + I2C6, + USART1, + RTCAPB, + TZC1, + TZC2, + TZPC, + IWDG1, + BSEC, + STGEN, + GPIOZ, + CRYP1, + HASH1, + RNG1, + BKPSRAM, + RNG1_K, + STGEN_K, + SPI6_K, + I2C4_K, + I2C6_K, + USART1_K, + RTC, +}; + +static bool stm32_check_security(const struct clock_config *cfg) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(stm32mp1_clock_secured); i++) + if (cfg->id == stm32mp1_clock_secured[i]) + return true; + return false; +} + +struct stm32_rcc_match_data { const struct clock_config *cfg; unsigned int num; unsigned int maxbinding; + u32 clear_offset; + bool (*check_security)(const struct clock_config *cfg); }; -static struct stm32_clock_match_data stm32mp1_data = { +static struct stm32_rcc_match_data stm32mp1_data = { .cfg = stm32mp1_clock_cfg, .num = ARRAY_SIZE(stm32mp1_clock_cfg), .maxbinding = STM32MP1_LAST_CLK, + .clear_offset = RCC_CLR, +}; + +static struct stm32_rcc_match_data stm32mp1_data_secure = { + .cfg = stm32mp1_clock_cfg, + .num = ARRAY_SIZE(stm32mp1_clock_cfg), + .maxbinding = STM32MP1_LAST_CLK, + .clear_offset = RCC_CLR, + .check_security = &stm32_check_security }; static const struct of_device_id stm32mp1_match_data[] = { @@ -2013,8 +2133,13 @@ static const struct of_device_id stm32mp1_match_data[] = { .compatible = "st,stm32mp1-rcc", .data = &stm32mp1_data, }, + { + .compatible = "st,stm32mp1-rcc-secure", + .data = &stm32mp1_data_secure, + }, { } }; +MODULE_DEVICE_TABLE(of, stm32mp1_match_data); static int stm32_register_hw_clk(struct device *dev, struct clk_hw_onecell_data *clk_data, @@ -2040,28 +2165,126 @@ static int stm32_register_hw_clk(struct device *dev, return 0; } -static int stm32_rcc_init(struct device_node *np, - void __iomem *base, - const struct of_device_id *match_data) +#define STM32_RESET_ID_MASK GENMASK(15, 0) + +struct stm32_reset_data { + /* reset lock */ + spinlock_t lock; + struct reset_controller_dev rcdev; + void __iomem *membase; + u32 clear_offset; +}; + +static inline struct stm32_reset_data * +to_stm32_reset_data(struct reset_controller_dev *rcdev) { - struct clk_hw_onecell_data *clk_data; - struct clk_hw **hws; - const struct of_device_id *match; - const struct stm32_clock_match_data *data; - int err, n, max_binding; + return container_of(rcdev, struct stm32_reset_data, rcdev); +} - match = of_match_node(match_data, np); - if (!match) { - pr_err("%s: match data not found\n", __func__); - return -ENODEV; +static int stm32_reset_update(struct reset_controller_dev *rcdev, + unsigned long id, bool assert) +{ + struct stm32_reset_data *data = to_stm32_reset_data(rcdev); + int reg_width = sizeof(u32); + int bank = id / (reg_width * BITS_PER_BYTE); + int offset = id % (reg_width * BITS_PER_BYTE); + + if (data->clear_offset) { + void __iomem *addr; + + addr = data->membase + (bank * reg_width); + if (!assert) + addr += data->clear_offset; + + writel(BIT(offset), addr); + + } else { + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&data->lock, flags); + + reg = readl(data->membase + (bank * reg_width)); + + if (assert) + reg |= BIT(offset); + else + reg &= ~BIT(offset); + + writel(reg, data->membase + (bank * reg_width)); + + spin_unlock_irqrestore(&data->lock, flags); } + return 0; +} + +static int stm32_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return stm32_reset_update(rcdev, id, true); +} + +static int stm32_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + return stm32_reset_update(rcdev, id, false); +} + +static int stm32_reset_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct stm32_reset_data *data = to_stm32_reset_data(rcdev); + int reg_width = sizeof(u32); + int bank = id / (reg_width * BITS_PER_BYTE); + int offset = id % (reg_width * BITS_PER_BYTE); + u32 reg; + + reg = readl(data->membase + (bank * reg_width)); + + return !!(reg & BIT(offset)); +} + +static const struct reset_control_ops stm32_reset_ops = { + .assert = stm32_reset_assert, + .deassert = stm32_reset_deassert, + .status = stm32_reset_status, +}; + +static int stm32_rcc_reset_init(struct device *dev, void __iomem *base, + const struct of_device_id *match) +{ + const struct stm32_rcc_match_data *data = match->data; + struct stm32_reset_data *reset_data = NULL; + data = match->data; + reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + if (!reset_data) + return -ENOMEM; + + reset_data->membase = base; + reset_data->rcdev.owner = THIS_MODULE; + reset_data->rcdev.ops = &stm32_reset_ops; + reset_data->rcdev.of_node = dev_of_node(dev); + reset_data->rcdev.nr_resets = STM32_RESET_ID_MASK; + reset_data->clear_offset = data->clear_offset; + + return reset_controller_register(&reset_data->rcdev); +} + +static int stm32_rcc_clock_init(struct device *dev, void __iomem *base, + const struct of_device_id *match) +{ + const struct stm32_rcc_match_data *data = match->data; + struct clk_hw_onecell_data *clk_data; + struct clk_hw **hws; + int err, n, max_binding; + max_binding = data->maxbinding; - clk_data = kzalloc(struct_size(clk_data, hws, max_binding), - GFP_KERNEL); + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, max_binding), + GFP_KERNEL); if (!clk_data) return -ENOMEM; @@ -2073,36 +2296,139 @@ static int stm32_rcc_init(struct device_node *np, hws[n] = ERR_PTR(-ENOENT); for (n = 0; n < data->num; n++) { - err = stm32_register_hw_clk(NULL, clk_data, base, &rlock, + if (data->check_security && data->check_security(&data->cfg[n])) + continue; + + err = stm32_register_hw_clk(dev, clk_data, base, &rlock, &data->cfg[n]); if (err) { - pr_err("%s: can't register %s\n", __func__, - data->cfg[n].name); - - kfree(clk_data); + dev_err(dev, "Can't register clk %s: %d\n", + data->cfg[n].name, err); return err; } } - return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); + return of_clk_add_hw_provider(dev_of_node(dev), of_clk_hw_onecell_get, clk_data); } -static void stm32mp1_rcc_init(struct device_node *np) +static int stm32_rcc_init(struct device *dev, void __iomem *base, + const struct of_device_id *match_data) +{ + const struct of_device_id *match; + int err; + + match = of_match_node(match_data, dev_of_node(dev)); + if (!match) { + dev_err(dev, "match data not found\n"); + return -ENODEV; + } + + /* RCC Reset Configuration */ + err = stm32_rcc_reset_init(dev, base, match); + if (err) { + pr_err("stm32mp1 reset failed to initialize\n"); + return err; + } + + /* RCC Clock Configuration */ + err = stm32_rcc_clock_init(dev, base, match); + if (err) { + pr_err("stm32mp1 clock failed to initialize\n"); + return err; + } + + return 0; +} + +static int stm32mp1_rcc_init(struct device *dev) { void __iomem *base; + int ret; - base = of_iomap(np, 0); + base = of_iomap(dev_of_node(dev), 0); if (!base) { - pr_err("%pOFn: unable to map resource", np); - of_node_put(np); - return; + pr_err("%pOFn: unable to map resource", dev_of_node(dev)); + ret = -ENOMEM; + goto out; } - if (stm32_rcc_init(np, base, stm32mp1_match_data)) { - iounmap(base); - of_node_put(np); + ret = stm32_rcc_init(dev, base, stm32mp1_match_data); + +out: + if (ret) { + if (base) + iounmap(base); + + of_node_put(dev_of_node(dev)); } + + return ret; } -CLK_OF_DECLARE_DRIVER(stm32mp1_rcc, "st,stm32mp1-rcc", stm32mp1_rcc_init); +static int get_clock_deps(struct device *dev) +{ + static const char * const clock_deps_name[] = { + "hsi", "hse", "csi", "lsi", "lse", + }; + size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name); + struct clk **clk_deps; + int i; + + clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL); + if (!clk_deps) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) { + struct clk *clk = of_clk_get_by_name(dev_of_node(dev), + clock_deps_name[i]); + + if (IS_ERR(clk)) { + if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT) + return PTR_ERR(clk); + } else { + /* Device gets a reference count on the clock */ + clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk)); + clk_put(clk); + } + } + + return 0; +} + +static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret = get_clock_deps(dev); + + if (!ret) + ret = stm32mp1_rcc_init(dev); + + return ret; +} + +static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *child, *np = dev_of_node(dev); + + for_each_available_child_of_node(np, child) + of_clk_del_provider(child); + + return 0; +} + +static struct platform_driver stm32mp1_rcc_clocks_driver = { + .driver = { + .name = "stm32mp1_rcc", + .of_match_table = stm32mp1_match_data, + }, + .probe = stm32mp1_rcc_clocks_probe, + .remove = stm32mp1_rcc_clocks_remove, +}; + +static int __init stm32mp1_clocks_init(void) +{ + return platform_driver_register(&stm32mp1_rcc_clocks_driver); +} +core_initcall(stm32mp1_clocks_init); diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 344cd6c61188..3c737742c2a9 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -69,7 +69,10 @@ #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n)) #define VC5_RC_CONTROL0 0x1e #define VC5_RC_CONTROL1 0x1f -/* Register 0x20 is factory reserved */ + +/* These registers are named "Unused Factory Reserved Registers" */ +#define VC5_RESERVED_X0(idx) (0x20 + ((idx) * 0x10)) +#define VC5_RESERVED_X0_BYPASS_SYNC BIT(7) /* bypass_sync<idx> bit */ /* Output divider control for divider 1,2,3,4 */ #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10)) @@ -87,7 +90,6 @@ #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n)) #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n)) #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10)) -/* Registers 0x30, 0x40, 0x50 are factory reserved */ /* Clock control register for clock 1,2 */ #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n)) @@ -140,6 +142,8 @@ #define VC5_HAS_INTERNAL_XTAL BIT(0) /* chip has PFD requency doubler */ #define VC5_HAS_PFD_FREQ_DBL BIT(1) +/* chip has bits to disable FOD sync */ +#define VC5_HAS_BYPASS_SYNC_BIT BIT(2) /* Supported IDT VC5 models. */ enum vc5_model { @@ -582,6 +586,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) int ret; /* + * When enabling a FOD, all currently enabled FODs are briefly + * stopped in order to synchronize all of them. This causes a clock + * disruption to any unrelated chips that might be already using + * other clock outputs. Bypass the sync feature to avoid the issue, + * which is possible on the VersaClock 6E family via reserved + * registers. + */ + if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) { + ret = regmap_update_bits(vc5->regmap, + VC5_RESERVED_X0(hwdata->num), + VC5_RESERVED_X0_BYPASS_SYNC, + VC5_RESERVED_X0_BYPASS_SYNC); + if (ret) + return ret; + } + + /* * If the input mux is disabled, enable it first and * select source from matching FOD. */ @@ -1166,7 +1187,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = { .model = IDT_VC6_5P49V6965, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = 0, + .flags = VC5_HAS_BYPASS_SYNC_BIT, }; static const struct i2c_device_id vc5_id[] = { diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 0f2e3fcf0f19..67f601a41023 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -190,34 +190,6 @@ vclkdev_create(struct clk_hw *hw, const char *con_id, const char *dev_fmt, return cl; } -struct clk_lookup * __ref -clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...) -{ - struct clk_lookup *cl; - va_list ap; - - va_start(ap, dev_fmt); - cl = vclkdev_alloc(__clk_get_hw(clk), con_id, dev_fmt, ap); - va_end(ap); - - return cl; -} -EXPORT_SYMBOL(clkdev_alloc); - -struct clk_lookup * -clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...) -{ - struct clk_lookup *cl; - va_list ap; - - va_start(ap, dev_fmt); - cl = vclkdev_alloc(hw, con_id, dev_fmt, ap); - va_end(ap); - - return cl; -} -EXPORT_SYMBOL(clkdev_hw_alloc); - /** * clkdev_create - allocate and add a clkdev lookup structure * @clk: struct clk to associate with all clk_lookups diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig index 6a9e93a0bb95..5ecc37aaa118 100644 --- a/drivers/clk/hisilicon/Kconfig +++ b/drivers/clk/hisilicon/Kconfig @@ -15,6 +15,13 @@ config COMMON_CLK_HI3519 help Build the clock driver for hi3519. +config COMMON_CLK_HI3559A + bool "Hi3559A Clock Driver" + depends on ARCH_HISI || COMPILE_TEST + default ARCH_HISI + help + Build the clock driver for hi3559a. + config COMMON_CLK_HI3660 bool "Hi3660 Clock Driver" depends on ARCH_HISI || COMPILE_TEST diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile index b2441b99f3d5..2978e56cb876 100644 --- a/drivers/clk/hisilicon/Makefile +++ b/drivers/clk/hisilicon/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o obj-$(CONFIG_COMMON_CLK_HI3516CV300) += crg-hi3516cv300.o obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o +obj-$(CONFIG_COMMON_CLK_HI3559A) += clk-hi3559a.o obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o obj-$(CONFIG_COMMON_CLK_HI3670) += clk-hi3670.o obj-$(CONFIG_COMMON_CLK_HI3798CV200) += crg-hi3798cv200.o diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c new file mode 100644 index 000000000000..b1f19c43b558 --- /dev/null +++ b/drivers/clk/hisilicon/clk-hi3559a.c @@ -0,0 +1,846 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Hisilicon Hi3559A clock driver + * + * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd. + * + * Author: Dongjiu Geng <gengdongjiu@huawei.com> + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/hi3559av100-clock.h> + +#include "clk.h" +#include "crg.h" +#include "reset.h" + +#define CRG_BASE_ADDR 0x18020000 +#define PLL_MASK_WIDTH 24 + +struct hi3559av100_pll_clock { + u32 id; + const char *name; + const char *parent_name; + const u32 ctrl_reg1; + const u8 frac_shift; + const u8 frac_width; + const u8 postdiv1_shift; + const u8 postdiv1_width; + const u8 postdiv2_shift; + const u8 postdiv2_width; + const u32 ctrl_reg2; + const u8 fbdiv_shift; + const u8 fbdiv_width; + const u8 refdiv_shift; + const u8 refdiv_width; +}; + +struct hi3559av100_clk_pll { + struct clk_hw hw; + u32 id; + void __iomem *ctrl_reg1; + u8 frac_shift; + u8 frac_width; + u8 postdiv1_shift; + u8 postdiv1_width; + u8 postdiv2_shift; + u8 postdiv2_width; + void __iomem *ctrl_reg2; + u8 fbdiv_shift; + u8 fbdiv_width; + u8 refdiv_shift; + u8 refdiv_width; +}; + +/* soc clk config */ +static const struct hisi_fixed_rate_clock hi3559av100_fixed_rate_clks_crg[] = { + { HI3559AV100_FIXED_1188M, "1188m", NULL, 0, 1188000000, }, + { HI3559AV100_FIXED_1000M, "1000m", NULL, 0, 1000000000, }, + { HI3559AV100_FIXED_842M, "842m", NULL, 0, 842000000, }, + { HI3559AV100_FIXED_792M, "792m", NULL, 0, 792000000, }, + { HI3559AV100_FIXED_750M, "750m", NULL, 0, 750000000, }, + { HI3559AV100_FIXED_710M, "710m", NULL, 0, 710000000, }, + { HI3559AV100_FIXED_680M, "680m", NULL, 0, 680000000, }, + { HI3559AV100_FIXED_667M, "667m", NULL, 0, 667000000, }, + { HI3559AV100_FIXED_631M, "631m", NULL, 0, 631000000, }, + { HI3559AV100_FIXED_600M, "600m", NULL, 0, 600000000, }, + { HI3559AV100_FIXED_568M, "568m", NULL, 0, 568000000, }, + { HI3559AV100_FIXED_500M, "500m", NULL, 0, 500000000, }, + { HI3559AV100_FIXED_475M, "475m", NULL, 0, 475000000, }, + { HI3559AV100_FIXED_428M, "428m", NULL, 0, 428000000, }, + { HI3559AV100_FIXED_400M, "400m", NULL, 0, 400000000, }, + { HI3559AV100_FIXED_396M, "396m", NULL, 0, 396000000, }, + { HI3559AV100_FIXED_300M, "300m", NULL, 0, 300000000, }, + { HI3559AV100_FIXED_250M, "250m", NULL, 0, 250000000, }, + { HI3559AV100_FIXED_200M, "200m", NULL, 0, 200000000, }, + { HI3559AV100_FIXED_198M, "198m", NULL, 0, 198000000, }, + { HI3559AV100_FIXED_187p5M, "187p5m", NULL, 0, 187500000, }, + { HI3559AV100_FIXED_150M, "150m", NULL, 0, 150000000, }, + { HI3559AV100_FIXED_148p5M, "148p5m", NULL, 0, 1485000000, }, + { HI3559AV100_FIXED_125M, "125m", NULL, 0, 125000000, }, + { HI3559AV100_FIXED_107M, "107m", NULL, 0, 107000000, }, + { HI3559AV100_FIXED_100M, "100m", NULL, 0, 100000000, }, + { HI3559AV100_FIXED_99M, "99m", NULL, 0, 99000000, }, + { HI3559AV100_FIXED_75M, "75m", NULL, 0, 75000000, }, + { HI3559AV100_FIXED_74p25M, "74p25m", NULL, 0, 74250000, }, + { HI3559AV100_FIXED_72M, "72m", NULL, 0, 72000000, }, + { HI3559AV100_FIXED_60M, "60m", NULL, 0, 60000000, }, + { HI3559AV100_FIXED_54M, "54m", NULL, 0, 54000000, }, + { HI3559AV100_FIXED_50M, "50m", NULL, 0, 50000000, }, + { HI3559AV100_FIXED_49p5M, "49p5m", NULL, 0, 49500000, }, + { HI3559AV100_FIXED_37p125M, "37p125m", NULL, 0, 37125000, }, + { HI3559AV100_FIXED_36M, "36m", NULL, 0, 36000000, }, + { HI3559AV100_FIXED_32p4M, "32p4m", NULL, 0, 32400000, }, + { HI3559AV100_FIXED_27M, "27m", NULL, 0, 27000000, }, + { HI3559AV100_FIXED_25M, "25m", NULL, 0, 25000000, }, + { HI3559AV100_FIXED_24M, "24m", NULL, 0, 24000000, }, + { HI3559AV100_FIXED_12M, "12m", NULL, 0, 12000000, }, + { HI3559AV100_FIXED_3M, "3m", NULL, 0, 3000000, }, + { HI3559AV100_FIXED_1p6M, "1p6m", NULL, 0, 1600000, }, + { HI3559AV100_FIXED_400K, "400k", NULL, 0, 400000, }, + { HI3559AV100_FIXED_100K, "100k", NULL, 0, 100000, }, +}; + + +static const char *fmc_mux_p[] __initconst = { + "24m", "75m", "125m", "150m", "200m", "250m", "300m", "400m" +}; + +static const char *mmc_mux_p[] __initconst = { + "100k", "25m", "49p5m", "99m", "187p5m", "150m", "198m", "400k" +}; + +static const char *sysapb_mux_p[] __initconst = { + "24m", "50m", +}; + +static const char *sysbus_mux_p[] __initconst = { + "24m", "300m" +}; + +static const char *uart_mux_p[] __initconst = { "50m", "24m", "3m" }; + +static const char *a73_clksel_mux_p[] __initconst = { + "24m", "apll", "1000m" +}; + +static const u32 fmc_mux_table[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static const u32 mmc_mux_table[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +static const u32 sysapb_mux_table[] = { 0, 1 }; +static const u32 sysbus_mux_table[] = { 0, 1 }; +static const u32 uart_mux_table[] = { 0, 1, 2 }; +static const u32 a73_clksel_mux_table[] = { 0, 1, 2 }; + +static struct hisi_mux_clock hi3559av100_mux_clks_crg[] __initdata = { + { + HI3559AV100_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), + CLK_SET_RATE_PARENT, 0x170, 2, 3, 0, fmc_mux_table, + }, + { + HI3559AV100_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), + CLK_SET_RATE_PARENT, 0x1a8, 24, 3, 0, mmc_mux_table, + }, + { + HI3559AV100_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), + CLK_SET_RATE_PARENT, 0x1ec, 24, 3, 0, mmc_mux_table, + }, + + { + HI3559AV100_MMC2_MUX, "mmc2_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), + CLK_SET_RATE_PARENT, 0x214, 24, 3, 0, mmc_mux_table, + }, + + { + HI3559AV100_MMC3_MUX, "mmc3_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p), + CLK_SET_RATE_PARENT, 0x23c, 24, 3, 0, mmc_mux_table, + }, + + { + HI3559AV100_SYSAPB_MUX, "sysapb_mux", sysapb_mux_p, ARRAY_SIZE(sysapb_mux_p), + CLK_SET_RATE_PARENT, 0xe8, 3, 1, 0, sysapb_mux_table + }, + + { + HI3559AV100_SYSBUS_MUX, "sysbus_mux", sysbus_mux_p, ARRAY_SIZE(sysbus_mux_p), + CLK_SET_RATE_PARENT, 0xe8, 0, 1, 0, sysbus_mux_table + }, + + { + HI3559AV100_UART_MUX, "uart_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p), + CLK_SET_RATE_PARENT, 0x198, 28, 2, 0, uart_mux_table + }, + + { + HI3559AV100_A73_MUX, "a73_mux", a73_clksel_mux_p, ARRAY_SIZE(a73_clksel_mux_p), + CLK_SET_RATE_PARENT, 0xe4, 0, 2, 0, a73_clksel_mux_table + }, +}; + +static struct hisi_gate_clock hi3559av100_gate_clks[] __initdata = { + { + HI3559AV100_FMC_CLK, "clk_fmc", "fmc_mux", + CLK_SET_RATE_PARENT, 0x170, 1, 0, + }, + { + HI3559AV100_MMC0_CLK, "clk_mmc0", "mmc0_mux", + CLK_SET_RATE_PARENT, 0x1a8, 28, 0, + }, + { + HI3559AV100_MMC1_CLK, "clk_mmc1", "mmc1_mux", + CLK_SET_RATE_PARENT, 0x1ec, 28, 0, + }, + { + HI3559AV100_MMC2_CLK, "clk_mmc2", "mmc2_mux", + CLK_SET_RATE_PARENT, 0x214, 28, 0, + }, + { + HI3559AV100_MMC3_CLK, "clk_mmc3", "mmc3_mux", + CLK_SET_RATE_PARENT, 0x23c, 28, 0, + }, + { + HI3559AV100_UART0_CLK, "clk_uart0", "uart_mux", + CLK_SET_RATE_PARENT, 0x198, 23, 0, + }, + { + HI3559AV100_UART1_CLK, "clk_uart1", "uart_mux", + CLK_SET_RATE_PARENT, 0x198, 24, 0, + }, + { + HI3559AV100_UART2_CLK, "clk_uart2", "uart_mux", + CLK_SET_RATE_PARENT, 0x198, 25, 0, + }, + { + HI3559AV100_UART3_CLK, "clk_uart3", "uart_mux", + CLK_SET_RATE_PARENT, 0x198, 26, 0, + }, + { + HI3559AV100_UART4_CLK, "clk_uart4", "uart_mux", + CLK_SET_RATE_PARENT, 0x198, 27, 0, + }, + { + HI3559AV100_ETH_CLK, "clk_eth", NULL, + CLK_SET_RATE_PARENT, 0x0174, 1, 0, + }, + { + HI3559AV100_ETH_MACIF_CLK, "clk_eth_macif", NULL, + CLK_SET_RATE_PARENT, 0x0174, 5, 0, + }, + { + HI3559AV100_ETH1_CLK, "clk_eth1", NULL, + CLK_SET_RATE_PARENT, 0x0174, 3, 0, + }, + { + HI3559AV100_ETH1_MACIF_CLK, "clk_eth1_macif", NULL, + CLK_SET_RATE_PARENT, 0x0174, 7, 0, + }, + { + HI3559AV100_I2C0_CLK, "clk_i2c0", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 16, 0, + }, + { + HI3559AV100_I2C1_CLK, "clk_i2c1", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 17, 0, + }, + { + HI3559AV100_I2C2_CLK, "clk_i2c2", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 18, 0, + }, + { + HI3559AV100_I2C3_CLK, "clk_i2c3", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 19, 0, + }, + { + HI3559AV100_I2C4_CLK, "clk_i2c4", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 20, 0, + }, + { + HI3559AV100_I2C5_CLK, "clk_i2c5", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 21, 0, + }, + { + HI3559AV100_I2C6_CLK, "clk_i2c6", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 22, 0, + }, + { + HI3559AV100_I2C7_CLK, "clk_i2c7", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 23, 0, + }, + { + HI3559AV100_I2C8_CLK, "clk_i2c8", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 24, 0, + }, + { + HI3559AV100_I2C9_CLK, "clk_i2c9", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 25, 0, + }, + { + HI3559AV100_I2C10_CLK, "clk_i2c10", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 26, 0, + }, + { + HI3559AV100_I2C11_CLK, "clk_i2c11", "50m", + CLK_SET_RATE_PARENT, 0x01a0, 27, 0, + }, + { + HI3559AV100_SPI0_CLK, "clk_spi0", "100m", + CLK_SET_RATE_PARENT, 0x0198, 16, 0, + }, + { + HI3559AV100_SPI1_CLK, "clk_spi1", "100m", + CLK_SET_RATE_PARENT, 0x0198, 17, 0, + }, + { + HI3559AV100_SPI2_CLK, "clk_spi2", "100m", + CLK_SET_RATE_PARENT, 0x0198, 18, 0, + }, + { + HI3559AV100_SPI3_CLK, "clk_spi3", "100m", + CLK_SET_RATE_PARENT, 0x0198, 19, 0, + }, + { + HI3559AV100_SPI4_CLK, "clk_spi4", "100m", + CLK_SET_RATE_PARENT, 0x0198, 20, 0, + }, + { + HI3559AV100_SPI5_CLK, "clk_spi5", "100m", + CLK_SET_RATE_PARENT, 0x0198, 21, 0, + }, + { + HI3559AV100_SPI6_CLK, "clk_spi6", "100m", + CLK_SET_RATE_PARENT, 0x0198, 22, 0, + }, + { + HI3559AV100_EDMAC_AXICLK, "axi_clk_edmac", NULL, + CLK_SET_RATE_PARENT, 0x16c, 6, 0, + }, + { + HI3559AV100_EDMAC_CLK, "clk_edmac", NULL, + CLK_SET_RATE_PARENT, 0x16c, 5, 0, + }, + { + HI3559AV100_EDMAC1_AXICLK, "axi_clk_edmac1", NULL, + CLK_SET_RATE_PARENT, 0x16c, 9, 0, + }, + { + HI3559AV100_EDMAC1_CLK, "clk_edmac1", NULL, + CLK_SET_RATE_PARENT, 0x16c, 8, 0, + }, + { + HI3559AV100_VDMAC_CLK, "clk_vdmac", NULL, + CLK_SET_RATE_PARENT, 0x14c, 5, 0, + }, +}; + +static struct hi3559av100_pll_clock hi3559av100_pll_clks[] __initdata = { + { + HI3559AV100_APLL_CLK, "apll", NULL, 0x0, 0, 24, 24, 3, 28, 3, + 0x4, 0, 12, 12, 6 + }, + { + HI3559AV100_GPLL_CLK, "gpll", NULL, 0x20, 0, 24, 24, 3, 28, 3, + 0x24, 0, 12, 12, 6 + }, +}; + +#define to_pll_clk(_hw) container_of(_hw, struct hi3559av100_clk_pll, hw) +static void hi3559av100_calc_pll(u32 *frac_val, u32 *postdiv1_val, + u32 *postdiv2_val, + u32 *fbdiv_val, u32 *refdiv_val, u64 rate) +{ + u64 rem; + + *postdiv1_val = 2; + *postdiv2_val = 1; + + rate = rate * ((*postdiv1_val) * (*postdiv2_val)); + + *frac_val = 0; + rem = do_div(rate, 1000000); + rem = do_div(rate, PLL_MASK_WIDTH); + *fbdiv_val = rate; + *refdiv_val = 1; + rem = rem * (1 << PLL_MASK_WIDTH); + do_div(rem, PLL_MASK_WIDTH); + *frac_val = rem; +} + +static int clk_pll_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct hi3559av100_clk_pll *clk = to_pll_clk(hw); + u32 frac_val, postdiv1_val, postdiv2_val, fbdiv_val, refdiv_val; + u32 val; + + postdiv1_val = postdiv2_val = 0; + + hi3559av100_calc_pll(&frac_val, &postdiv1_val, &postdiv2_val, + &fbdiv_val, &refdiv_val, (u64)rate); + + val = readl_relaxed(clk->ctrl_reg1); + val &= ~(((1 << clk->frac_width) - 1) << clk->frac_shift); + val &= ~(((1 << clk->postdiv1_width) - 1) << clk->postdiv1_shift); + val &= ~(((1 << clk->postdiv2_width) - 1) << clk->postdiv2_shift); + + val |= frac_val << clk->frac_shift; + val |= postdiv1_val << clk->postdiv1_shift; + val |= postdiv2_val << clk->postdiv2_shift; + writel_relaxed(val, clk->ctrl_reg1); + + val = readl_relaxed(clk->ctrl_reg2); + val &= ~(((1 << clk->fbdiv_width) - 1) << clk->fbdiv_shift); + val &= ~(((1 << clk->refdiv_width) - 1) << clk->refdiv_shift); + + val |= fbdiv_val << clk->fbdiv_shift; + val |= refdiv_val << clk->refdiv_shift; + writel_relaxed(val, clk->ctrl_reg2); + + return 0; +} + +static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct hi3559av100_clk_pll *clk = to_pll_clk(hw); + u64 frac_val, fbdiv_val, refdiv_val; + u32 postdiv1_val, postdiv2_val; + u32 val; + u64 tmp, rate; + + val = readl_relaxed(clk->ctrl_reg1); + val = val >> clk->frac_shift; + val &= ((1 << clk->frac_width) - 1); + frac_val = val; + + val = readl_relaxed(clk->ctrl_reg1); + val = val >> clk->postdiv1_shift; + val &= ((1 << clk->postdiv1_width) - 1); + postdiv1_val = val; + + val = readl_relaxed(clk->ctrl_reg1); + val = val >> clk->postdiv2_shift; + val &= ((1 << clk->postdiv2_width) - 1); + postdiv2_val = val; + + val = readl_relaxed(clk->ctrl_reg2); + val = val >> clk->fbdiv_shift; + val &= ((1 << clk->fbdiv_width) - 1); + fbdiv_val = val; + + val = readl_relaxed(clk->ctrl_reg2); + val = val >> clk->refdiv_shift; + val &= ((1 << clk->refdiv_width) - 1); + refdiv_val = val; + + /* rate = 24000000 * (fbdiv + frac / (1<<24) ) / refdiv */ + rate = 0; + tmp = 24000000 * fbdiv_val + (24000000 * frac_val) / (1 << 24); + rate += tmp; + do_div(rate, refdiv_val); + do_div(rate, postdiv1_val * postdiv2_val); + + return rate; +} + +static const struct clk_ops hisi_clk_pll_ops = { + .set_rate = clk_pll_set_rate, + .recalc_rate = clk_pll_recalc_rate, +}; + +static void hisi_clk_register_pll(struct hi3559av100_pll_clock *clks, + int nums, struct hisi_clock_data *data, struct device *dev) +{ + void __iomem *base = data->base; + struct hi3559av100_clk_pll *p_clk = NULL; + struct clk *clk = NULL; + struct clk_init_data init; + int i; + + p_clk = devm_kzalloc(dev, sizeof(*p_clk) * nums, GFP_KERNEL); + + if (!p_clk) + return; + + for (i = 0; i < nums; i++) { + init.name = clks[i].name; + init.flags = 0; + init.parent_names = + (clks[i].parent_name ? &clks[i].parent_name : NULL); + init.num_parents = (clks[i].parent_name ? 1 : 0); + init.ops = &hisi_clk_pll_ops; + + p_clk->ctrl_reg1 = base + clks[i].ctrl_reg1; + p_clk->frac_shift = clks[i].frac_shift; + p_clk->frac_width = clks[i].frac_width; + p_clk->postdiv1_shift = clks[i].postdiv1_shift; + p_clk->postdiv1_width = clks[i].postdiv1_width; + p_clk->postdiv2_shift = clks[i].postdiv2_shift; + p_clk->postdiv2_width = clks[i].postdiv2_width; + + p_clk->ctrl_reg2 = base + clks[i].ctrl_reg2; + p_clk->fbdiv_shift = clks[i].fbdiv_shift; + p_clk->fbdiv_width = clks[i].fbdiv_width; + p_clk->refdiv_shift = clks[i].refdiv_shift; + p_clk->refdiv_width = clks[i].refdiv_width; + p_clk->hw.init = &init; + + clk = clk_register(NULL, &p_clk->hw); + if (IS_ERR(clk)) { + devm_kfree(dev, p_clk); + dev_err(dev, "%s: failed to register clock %s\n", + __func__, clks[i].name); + continue; + } + + data->clk_data.clks[clks[i].id] = clk; + p_clk++; + } +} + +static __init struct hisi_clock_data *hi3559av100_clk_register( + struct platform_device *pdev) +{ + struct hisi_clock_data *clk_data; + int ret; + + clk_data = hisi_clk_alloc(pdev, HI3559AV100_CRG_NR_CLKS); + if (!clk_data) + return ERR_PTR(-ENOMEM); + + ret = hisi_clk_register_fixed_rate(hi3559av100_fixed_rate_clks_crg, + ARRAY_SIZE(hi3559av100_fixed_rate_clks_crg), clk_data); + if (ret) + return ERR_PTR(ret); + + hisi_clk_register_pll(hi3559av100_pll_clks, + ARRAY_SIZE(hi3559av100_pll_clks), clk_data, &pdev->dev); + + ret = hisi_clk_register_mux(hi3559av100_mux_clks_crg, + ARRAY_SIZE(hi3559av100_mux_clks_crg), clk_data); + if (ret) + goto unregister_fixed_rate; + + ret = hisi_clk_register_gate(hi3559av100_gate_clks, + ARRAY_SIZE(hi3559av100_gate_clks), clk_data); + if (ret) + goto unregister_mux; + + ret = of_clk_add_provider(pdev->dev.of_node, + of_clk_src_onecell_get, &clk_data->clk_data); + if (ret) + goto unregister_gate; + + return clk_data; + +unregister_gate: + hisi_clk_unregister_gate(hi3559av100_gate_clks, + ARRAY_SIZE(hi3559av100_gate_clks), clk_data); +unregister_mux: + hisi_clk_unregister_mux(hi3559av100_mux_clks_crg, + ARRAY_SIZE(hi3559av100_mux_clks_crg), clk_data); +unregister_fixed_rate: + hisi_clk_unregister_fixed_rate(hi3559av100_fixed_rate_clks_crg, + ARRAY_SIZE(hi3559av100_fixed_rate_clks_crg), clk_data); + return ERR_PTR(ret); +} + +static __init void hi3559av100_clk_unregister(struct platform_device *pdev) +{ + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + + hisi_clk_unregister_gate(hi3559av100_gate_clks, + ARRAY_SIZE(hi3559av100_gate_clks), crg->clk_data); + hisi_clk_unregister_mux(hi3559av100_mux_clks_crg, + ARRAY_SIZE(hi3559av100_mux_clks_crg), crg->clk_data); + hisi_clk_unregister_fixed_rate(hi3559av100_fixed_rate_clks_crg, + ARRAY_SIZE(hi3559av100_fixed_rate_clks_crg), crg->clk_data); +} + +static const struct hisi_crg_funcs hi3559av100_crg_funcs = { + .register_clks = hi3559av100_clk_register, + .unregister_clks = hi3559av100_clk_unregister, +}; + +static struct hisi_fixed_rate_clock hi3559av100_shub_fixed_rate_clks[] + __initdata = { + { HI3559AV100_SHUB_SOURCE_SOC_24M, "clk_source_24M", NULL, 0, 24000000UL, }, + { HI3559AV100_SHUB_SOURCE_SOC_200M, "clk_source_200M", NULL, 0, 200000000UL, }, + { HI3559AV100_SHUB_SOURCE_SOC_300M, "clk_source_300M", NULL, 0, 300000000UL, }, + { HI3559AV100_SHUB_SOURCE_PLL, "clk_source_PLL", NULL, 0, 192000000UL, }, + { HI3559AV100_SHUB_I2C0_CLK, "clk_shub_i2c0", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C1_CLK, "clk_shub_i2c1", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C2_CLK, "clk_shub_i2c2", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C3_CLK, "clk_shub_i2c3", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C4_CLK, "clk_shub_i2c4", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C5_CLK, "clk_shub_i2c5", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C6_CLK, "clk_shub_i2c6", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_I2C7_CLK, "clk_shub_i2c7", NULL, 0, 48000000UL, }, + { HI3559AV100_SHUB_UART_CLK_32K, "clk_uart_32K", NULL, 0, 32000UL, }, +}; + +/* shub mux clk */ +static u32 shub_source_clk_mux_table[] = {0, 1, 2, 3}; +static const char *shub_source_clk_mux_p[] __initconst = { + "clk_source_24M", "clk_source_200M", "clk_source_300M", "clk_source_PLL" +}; + +static u32 shub_uart_source_clk_mux_table[] = {0, 1, 2, 3}; +static const char *shub_uart_source_clk_mux_p[] __initconst = { + "clk_uart_32K", "clk_uart_div_clk", "clk_uart_div_clk", "clk_source_24M" +}; + +static struct hisi_mux_clock hi3559av100_shub_mux_clks[] __initdata = { + { + HI3559AV100_SHUB_SOURCE_CLK, "shub_clk", shub_source_clk_mux_p, + ARRAY_SIZE(shub_source_clk_mux_p), + 0, 0x0, 0, 2, 0, shub_source_clk_mux_table, + }, + + { + HI3559AV100_SHUB_UART_SOURCE_CLK, "shub_uart_source_clk", + shub_uart_source_clk_mux_p, ARRAY_SIZE(shub_uart_source_clk_mux_p), + 0, 0x1c, 28, 2, 0, shub_uart_source_clk_mux_table, + }, +}; + + +/* shub div clk */ +static struct clk_div_table shub_spi_clk_table[] = {{0, 8}, {1, 4}, {2, 2}}; +static struct clk_div_table shub_uart_div_clk_table[] = {{1, 8}, {2, 4}}; + +static struct hisi_divider_clock hi3559av100_shub_div_clks[] __initdata = { + { HI3559AV100_SHUB_SPI_SOURCE_CLK, "clk_spi_clk", "shub_clk", 0, 0x20, 24, 2, + CLK_DIVIDER_ALLOW_ZERO, shub_spi_clk_table, + }, + { HI3559AV100_SHUB_UART_DIV_CLK, "clk_uart_div_clk", "shub_clk", 0, 0x1c, 28, 2, + CLK_DIVIDER_ALLOW_ZERO, shub_uart_div_clk_table, + }, +}; + +/* shub gate clk */ +static struct hisi_gate_clock hi3559av100_shub_gate_clks[] __initdata = { + { + HI3559AV100_SHUB_SPI0_CLK, "clk_shub_spi0", "clk_spi_clk", + 0, 0x20, 1, 0, + }, + { + HI3559AV100_SHUB_SPI1_CLK, "clk_shub_spi1", "clk_spi_clk", + 0, 0x20, 5, 0, + }, + { + HI3559AV100_SHUB_SPI2_CLK, "clk_shub_spi2", "clk_spi_clk", + 0, 0x20, 9, 0, + }, + + { + HI3559AV100_SHUB_UART0_CLK, "clk_shub_uart0", "shub_uart_source_clk", + 0, 0x1c, 1, 0, + }, + { + HI3559AV100_SHUB_UART1_CLK, "clk_shub_uart1", "shub_uart_source_clk", + 0, 0x1c, 5, 0, + }, + { + HI3559AV100_SHUB_UART2_CLK, "clk_shub_uart2", "shub_uart_source_clk", + 0, 0x1c, 9, 0, + }, + { + HI3559AV100_SHUB_UART3_CLK, "clk_shub_uart3", "shub_uart_source_clk", + 0, 0x1c, 13, 0, + }, + { + HI3559AV100_SHUB_UART4_CLK, "clk_shub_uart4", "shub_uart_source_clk", + 0, 0x1c, 17, 0, + }, + { + HI3559AV100_SHUB_UART5_CLK, "clk_shub_uart5", "shub_uart_source_clk", + 0, 0x1c, 21, 0, + }, + { + HI3559AV100_SHUB_UART6_CLK, "clk_shub_uart6", "shub_uart_source_clk", + 0, 0x1c, 25, 0, + }, + + { + HI3559AV100_SHUB_EDMAC_CLK, "clk_shub_dmac", "shub_clk", + 0, 0x24, 4, 0, + }, +}; + +static int hi3559av100_shub_default_clk_set(void) +{ + void __iomem *crg_base; + unsigned int val; + + crg_base = ioremap(CRG_BASE_ADDR, SZ_4K); + + /* SSP: 192M/2 */ + val = readl_relaxed(crg_base + 0x20); + val |= (0x2 << 24); + writel_relaxed(val, crg_base + 0x20); + + /* UART: 192M/8 */ + val = readl_relaxed(crg_base + 0x1C); + val |= (0x1 << 28); + writel_relaxed(val, crg_base + 0x1C); + + iounmap(crg_base); + crg_base = NULL; + + return 0; +} + +static __init struct hisi_clock_data *hi3559av100_shub_clk_register( + struct platform_device *pdev) +{ + struct hisi_clock_data *clk_data = NULL; + int ret; + + hi3559av100_shub_default_clk_set(); + + clk_data = hisi_clk_alloc(pdev, HI3559AV100_SHUB_NR_CLKS); + if (!clk_data) + return ERR_PTR(-ENOMEM); + + ret = hisi_clk_register_fixed_rate(hi3559av100_shub_fixed_rate_clks, + ARRAY_SIZE(hi3559av100_shub_fixed_rate_clks), clk_data); + if (ret) + return ERR_PTR(ret); + + ret = hisi_clk_register_mux(hi3559av100_shub_mux_clks, + ARRAY_SIZE(hi3559av100_shub_mux_clks), clk_data); + if (ret) + goto unregister_fixed_rate; + + ret = hisi_clk_register_divider(hi3559av100_shub_div_clks, + ARRAY_SIZE(hi3559av100_shub_div_clks), clk_data); + if (ret) + goto unregister_mux; + + ret = hisi_clk_register_gate(hi3559av100_shub_gate_clks, + ARRAY_SIZE(hi3559av100_shub_gate_clks), clk_data); + if (ret) + goto unregister_factor; + + ret = of_clk_add_provider(pdev->dev.of_node, + of_clk_src_onecell_get, &clk_data->clk_data); + if (ret) + goto unregister_gate; + + return clk_data; + +unregister_gate: + hisi_clk_unregister_gate(hi3559av100_shub_gate_clks, + ARRAY_SIZE(hi3559av100_shub_gate_clks), clk_data); +unregister_factor: + hisi_clk_unregister_divider(hi3559av100_shub_div_clks, + ARRAY_SIZE(hi3559av100_shub_div_clks), clk_data); +unregister_mux: + hisi_clk_unregister_mux(hi3559av100_shub_mux_clks, + ARRAY_SIZE(hi3559av100_shub_mux_clks), clk_data); +unregister_fixed_rate: + hisi_clk_unregister_fixed_rate(hi3559av100_shub_fixed_rate_clks, + ARRAY_SIZE(hi3559av100_shub_fixed_rate_clks), clk_data); + return ERR_PTR(ret); +} + +static __init void hi3559av100_shub_clk_unregister(struct platform_device *pdev) +{ + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); + + of_clk_del_provider(pdev->dev.of_node); + + hisi_clk_unregister_gate(hi3559av100_shub_gate_clks, + ARRAY_SIZE(hi3559av100_shub_gate_clks), crg->clk_data); + hisi_clk_unregister_divider(hi3559av100_shub_div_clks, + ARRAY_SIZE(hi3559av100_shub_div_clks), crg->clk_data); + hisi_clk_unregister_mux(hi3559av100_shub_mux_clks, + ARRAY_SIZE(hi3559av100_shub_mux_clks), crg->clk_data); + hisi_clk_unregister_fixed_rate(hi3559av100_shub_fixed_rate_clks, + ARRAY_SIZE(hi3559av100_shub_fixed_rate_clks), crg->clk_data); +} + +static const struct hisi_crg_funcs hi3559av100_shub_crg_funcs = { + .register_clks = hi3559av100_shub_clk_register, + .unregister_clks = hi3559av100_shub_clk_unregister, +}; + +static const struct of_device_id hi3559av100_crg_match_table[] = { + { + .compatible = "hisilicon,hi3559av100-clock", + .data = &hi3559av100_crg_funcs + }, + { + .compatible = "hisilicon,hi3559av100-shub-clock", + .data = &hi3559av100_shub_crg_funcs + }, + { } +}; +MODULE_DEVICE_TABLE(of, hi3559av100_crg_match_table); + +static int hi3559av100_crg_probe(struct platform_device *pdev) +{ + struct hisi_crg_dev *crg; + + crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL); + if (!crg) + return -ENOMEM; + + crg->funcs = of_device_get_match_data(&pdev->dev); + if (!crg->funcs) + return -ENOENT; + + crg->rstc = hisi_reset_init(pdev); + if (!crg->rstc) + return -ENOMEM; + + crg->clk_data = crg->funcs->register_clks(pdev); + if (IS_ERR(crg->clk_data)) { + hisi_reset_exit(crg->rstc); + return PTR_ERR(crg->clk_data); + } + + platform_set_drvdata(pdev, crg); + return 0; +} + +static int hi3559av100_crg_remove(struct platform_device *pdev) +{ + struct hisi_crg_dev *crg = platform_get_drvdata(pdev); + + hisi_reset_exit(crg->rstc); + crg->funcs->unregister_clks(pdev); + return 0; +} + +static struct platform_driver hi3559av100_crg_driver = { + .probe = hi3559av100_crg_probe, + .remove = hi3559av100_crg_remove, + .driver = { + .name = "hi3559av100-clock", + .of_match_table = hi3559av100_crg_match_table, + }, +}; + +static int __init hi3559av100_crg_init(void) +{ + return platform_driver_register(&hi3559av100_crg_driver); +} +core_initcall(hi3559av100_crg_init); + +static void __exit hi3559av100_crg_exit(void) +{ + platform_driver_unregister(&hi3559av100_crg_driver); +} +module_exit(hi3559av100_crg_exit); + + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("HiSilicon Hi3559AV100 CRG Driver"); diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 54d9fdc93599..9361fba7cd4c 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -162,7 +162,7 @@ int hisi_clk_register_mux(const struct hisi_mux_clock *clks, clks[i].num_parents, clks[i].flags, base + clks[i].offset, clks[i].shift, mask, clks[i].mux_flags, - clks[i].table, &hisi_clk_lock); + (u32 *)clks[i].table, &hisi_clk_lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h index 61cbd90d1213..7a9b42e1b027 100644 --- a/drivers/clk/hisilicon/clk.h +++ b/drivers/clk/hisilicon/clk.h @@ -50,7 +50,7 @@ struct hisi_mux_clock { u8 shift; u8 width; u8 mux_flags; - u32 *table; + const u32 *table; const char *alias; }; diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index dd6a737d060b..c24a2acbfa56 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -27,7 +27,8 @@ obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o -clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o +clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \ + clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o obj-$(CONFIG_CLK_IMX1) += clk-imx1.o diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index e39c9c907c38..12837304545d 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -556,7 +556,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev) hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200); hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); - hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1); hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000); hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index b08019e1faf9..c491bc9c61ce 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -358,46 +358,26 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); /* SYS PLL1 fixed output */ - hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); - hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); - hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); - hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); - hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); - hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); - hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); - hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); - hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); - - hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); - hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); - hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); - hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); - hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); - hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); - hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); - hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); - hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); + hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); + hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); + hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8); + hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6); + hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5); + hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4); + hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3); + hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2); + hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1); /* SYS PLL2 fixed output */ - hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); - hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); - hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); - hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); - hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); - hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); - hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); - hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); - hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); - - hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); - hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); - hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); - hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); - hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); - hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); - hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); - hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); - hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); + hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20); + hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10); + hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8); + hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6); + hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5); + hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4); + hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3); + hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2); + hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); hws[IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = imx_clk_hw_divider("audio_pll1_out_monitor", "audio_pll1_bypass", base + 0x78, 0, 3); hws[IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = imx_clk_hw_divider("audio_pll2_out_monitor", "audio_pll2_bypass", base + 0x78, 4, 3); diff --git a/drivers/clk/imx/clk-imx8qm-rsrc.c b/drivers/clk/imx/clk-imx8qm-rsrc.c new file mode 100644 index 000000000000..87e0b6ac027e --- /dev/null +++ b/drivers/clk/imx/clk-imx8qm-rsrc.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019-2021 NXP + * Dong Aisheng <aisheng.dong@nxp.com> + */ + +#include <dt-bindings/firmware/imx/rsrc.h> + +#include "clk-scu.h" + +/* Keep sorted in the ascending order */ +static const u32 imx8qm_clk_scu_rsrc_table[] = { + IMX_SC_R_A53, + IMX_SC_R_A72, + IMX_SC_R_DC_0_VIDEO0, + IMX_SC_R_DC_0_VIDEO1, + IMX_SC_R_DC_0, + IMX_SC_R_DC_0_PLL_0, + IMX_SC_R_DC_0_PLL_1, + IMX_SC_R_DC_1_VIDEO0, + IMX_SC_R_DC_1_VIDEO1, + IMX_SC_R_DC_1, + IMX_SC_R_DC_1_PLL_0, + IMX_SC_R_DC_1_PLL_1, + IMX_SC_R_SPI_0, + IMX_SC_R_SPI_1, + IMX_SC_R_SPI_2, + IMX_SC_R_SPI_3, + IMX_SC_R_UART_0, + IMX_SC_R_UART_1, + IMX_SC_R_UART_2, + IMX_SC_R_UART_3, + IMX_SC_R_UART_4, + IMX_SC_R_EMVSIM_0, + IMX_SC_R_EMVSIM_1, + IMX_SC_R_I2C_0, + IMX_SC_R_I2C_1, + IMX_SC_R_I2C_2, + IMX_SC_R_I2C_3, + IMX_SC_R_I2C_4, + IMX_SC_R_ADC_0, + IMX_SC_R_ADC_1, + IMX_SC_R_FTM_0, + IMX_SC_R_FTM_1, + IMX_SC_R_CAN_0, + IMX_SC_R_GPU_0_PID0, + IMX_SC_R_GPU_1_PID0, + IMX_SC_R_PWM_0, + IMX_SC_R_PWM_1, + IMX_SC_R_PWM_2, + IMX_SC_R_PWM_3, + IMX_SC_R_PWM_4, + IMX_SC_R_PWM_5, + IMX_SC_R_PWM_6, + IMX_SC_R_PWM_7, + IMX_SC_R_GPT_0, + IMX_SC_R_GPT_1, + IMX_SC_R_GPT_2, + IMX_SC_R_GPT_3, + IMX_SC_R_GPT_4, + IMX_SC_R_FSPI_0, + IMX_SC_R_FSPI_1, + IMX_SC_R_SDHC_0, + IMX_SC_R_SDHC_1, + IMX_SC_R_SDHC_2, + IMX_SC_R_ENET_0, + IMX_SC_R_ENET_1, + IMX_SC_R_MLB_0, + IMX_SC_R_USB_2, + IMX_SC_R_NAND, + IMX_SC_R_LVDS_0, + IMX_SC_R_LVDS_0_PWM_0, + IMX_SC_R_LVDS_0_I2C_0, + IMX_SC_R_LVDS_0_I2C_1, + IMX_SC_R_LVDS_1, + IMX_SC_R_LVDS_1_PWM_0, + IMX_SC_R_LVDS_1_I2C_0, + IMX_SC_R_LVDS_1_I2C_1, + IMX_SC_R_M4_0_I2C, + IMX_SC_R_M4_1_I2C, + IMX_SC_R_AUDIO_PLL_0, + IMX_SC_R_VPU_UART, + IMX_SC_R_VPUCORE, + IMX_SC_R_MIPI_0, + IMX_SC_R_MIPI_0_PWM_0, + IMX_SC_R_MIPI_0_I2C_0, + IMX_SC_R_MIPI_0_I2C_1, + IMX_SC_R_MIPI_1, + IMX_SC_R_MIPI_1_PWM_0, + IMX_SC_R_MIPI_1_I2C_0, + IMX_SC_R_MIPI_1_I2C_1, + IMX_SC_R_CSI_0, + IMX_SC_R_CSI_0_PWM_0, + IMX_SC_R_CSI_0_I2C_0, + IMX_SC_R_CSI_1, + IMX_SC_R_CSI_1_PWM_0, + IMX_SC_R_CSI_1_I2C_0, + IMX_SC_R_HDMI, + IMX_SC_R_HDMI_I2S, + IMX_SC_R_HDMI_I2C_0, + IMX_SC_R_HDMI_PLL_0, + IMX_SC_R_HDMI_RX, + IMX_SC_R_HDMI_RX_BYPASS, + IMX_SC_R_HDMI_RX_I2C_0, + IMX_SC_R_AUDIO_PLL_1, + IMX_SC_R_AUDIO_CLK_0, + IMX_SC_R_AUDIO_CLK_1, + IMX_SC_R_HDMI_RX_PWM_0, + IMX_SC_R_HDMI_PLL_1, + IMX_SC_R_VPU, +}; + +const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm = { + .rsrc = imx8qm_clk_scu_rsrc_table, + .num = ARRAY_SIZE(imx8qm_clk_scu_rsrc_table), +}; diff --git a/drivers/clk/imx/clk-imx8qxp-rsrc.c b/drivers/clk/imx/clk-imx8qxp-rsrc.c new file mode 100644 index 000000000000..df09f2a7996d --- /dev/null +++ b/drivers/clk/imx/clk-imx8qxp-rsrc.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019-2021 NXP + * Dong Aisheng <aisheng.dong@nxp.com> + */ + +#include <dt-bindings/firmware/imx/rsrc.h> + +#include "clk-scu.h" + +/* Keep sorted in the ascending order */ +static const u32 imx8qxp_clk_scu_rsrc_table[] = { + IMX_SC_R_DC_0_VIDEO0, + IMX_SC_R_DC_0_VIDEO1, + IMX_SC_R_DC_0, + IMX_SC_R_DC_0_PLL_0, + IMX_SC_R_DC_0_PLL_1, + IMX_SC_R_SPI_0, + IMX_SC_R_SPI_1, + IMX_SC_R_SPI_2, + IMX_SC_R_SPI_3, + IMX_SC_R_UART_0, + IMX_SC_R_UART_1, + IMX_SC_R_UART_2, + IMX_SC_R_UART_3, + IMX_SC_R_I2C_0, + IMX_SC_R_I2C_1, + IMX_SC_R_I2C_2, + IMX_SC_R_I2C_3, + IMX_SC_R_ADC_0, + IMX_SC_R_FTM_0, + IMX_SC_R_FTM_1, + IMX_SC_R_CAN_0, + IMX_SC_R_GPU_0_PID0, + IMX_SC_R_LCD_0, + IMX_SC_R_LCD_0_PWM_0, + IMX_SC_R_PWM_0, + IMX_SC_R_PWM_1, + IMX_SC_R_PWM_2, + IMX_SC_R_PWM_3, + IMX_SC_R_PWM_4, + IMX_SC_R_PWM_5, + IMX_SC_R_PWM_6, + IMX_SC_R_PWM_7, + IMX_SC_R_GPT_0, + IMX_SC_R_GPT_1, + IMX_SC_R_GPT_2, + IMX_SC_R_GPT_3, + IMX_SC_R_GPT_4, + IMX_SC_R_FSPI_0, + IMX_SC_R_FSPI_1, + IMX_SC_R_SDHC_0, + IMX_SC_R_SDHC_1, + IMX_SC_R_SDHC_2, + IMX_SC_R_ENET_0, + IMX_SC_R_ENET_1, + IMX_SC_R_MLB_0, + IMX_SC_R_USB_2, + IMX_SC_R_NAND, + IMX_SC_R_LVDS_0, + IMX_SC_R_LVDS_1, + IMX_SC_R_M4_0_I2C, + IMX_SC_R_ELCDIF_PLL, + IMX_SC_R_AUDIO_PLL_0, + IMX_SC_R_PI_0, + IMX_SC_R_PI_0_PLL, + IMX_SC_R_MIPI_0, + IMX_SC_R_MIPI_0_PWM_0, + IMX_SC_R_MIPI_0_I2C_0, + IMX_SC_R_MIPI_0_I2C_1, + IMX_SC_R_MIPI_1, + IMX_SC_R_MIPI_1_PWM_0, + IMX_SC_R_MIPI_1_I2C_0, + IMX_SC_R_MIPI_1_I2C_1, + IMX_SC_R_CSI_0, + IMX_SC_R_CSI_0_PWM_0, + IMX_SC_R_CSI_0_I2C_0, + IMX_SC_R_AUDIO_PLL_1, + IMX_SC_R_AUDIO_CLK_0, + IMX_SC_R_AUDIO_CLK_1, + IMX_SC_R_A35, + IMX_SC_R_VPU_DEC_0, + IMX_SC_R_VPU_ENC_0, +}; + +const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp = { + .rsrc = imx8qxp_clk_scu_rsrc_table, + .num = ARRAY_SIZE(imx8qxp_clk_scu_rsrc_table), +}; diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index fbf1170c09ed..c53a688d8ccc 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018 NXP + * Copyright 2018-2021 NXP * Dong Aisheng <aisheng.dong@nxp.com> */ @@ -9,12 +9,12 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/slab.h> #include "clk-scu.h" -#include <dt-bindings/clock/imx8-clock.h> #include <dt-bindings/firmware/imx/rsrc.h> static const char *dc0_sels[] = { @@ -25,159 +25,278 @@ static const char *dc0_sels[] = { "dc0_bypass0_clk", }; +static const char * const dc1_sels[] = { + "clk_dummy", + "clk_dummy", + "dc1_pll0_clk", + "dc1_pll1_clk", + "dc1_bypass0_clk", +}; + +static const char * const enet0_rgmii_txc_sels[] = { + "enet0_ref_div", + "clk_dummy", +}; + +static const char * const enet1_rgmii_txc_sels[] = { + "enet1_ref_div", + "clk_dummy", +}; + +static const char * const hdmi_sels[] = { + "clk_dummy", + "hdmi_dig_pll_clk", + "clk_dummy", + "clk_dummy", + "hdmi_av_pll_clk", +}; + +static const char * const hdmi_rx_sels[] = { + "clk_dummy", + "hdmi_rx_dig_pll_clk", + "clk_dummy", + "clk_dummy", + "hdmi_rx_bypass_clk", +}; + +static const char * const lcd_pxl_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "lcd_pxl_bypass_div_clk", +}; + +static const char * const mipi_sels[] = { + "clk_dummy", + "clk_dummy", + "mipi_pll_div2_clk", + "clk_dummy", + "clk_dummy", +}; + +static const char * const lcd_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "elcdif_pll", +}; + +static const char * const pi_pll0_sels[] = { + "clk_dummy", + "pi_dpll_clk", + "clk_dummy", + "clk_dummy", + "clk_dummy", +}; + static int imx8qxp_clk_probe(struct platform_device *pdev) { struct device_node *ccm_node = pdev->dev.of_node; - struct clk_hw_onecell_data *clk_data; - struct clk_hw **clks; - u32 clk_cells; - int ret, i; + const struct imx_clk_scu_rsrc_table *rsrc_table; + int ret; - ret = imx_clk_scu_init(ccm_node); + rsrc_table = of_device_get_match_data(&pdev->dev); + ret = imx_clk_scu_init(ccm_node, rsrc_table); if (ret) return ret; - clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, - IMX_SCU_CLK_END), GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - if (of_property_read_u32(ccm_node, "#clock-cells", &clk_cells)) - return -EINVAL; - - clk_data->num = IMX_SCU_CLK_END; - clks = clk_data->hws; - - /* Fixed clocks */ - clks[IMX_CLK_DUMMY] = clk_hw_register_fixed_rate(NULL, "dummy", NULL, 0, 0); - clks[IMX_ADMA_IPG_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "dma_ipg_clk_root", NULL, 0, 120000000); - clks[IMX_CONN_AXI_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_axi_clk_root", NULL, 0, 333333333); - clks[IMX_CONN_AHB_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_ahb_clk_root", NULL, 0, 166666666); - clks[IMX_CONN_IPG_CLK_ROOT] = clk_hw_register_fixed_rate(NULL, "conn_ipg_clk_root", NULL, 0, 83333333); - clks[IMX_DC_AXI_EXT_CLK] = clk_hw_register_fixed_rate(NULL, "dc_axi_ext_clk_root", NULL, 0, 800000000); - clks[IMX_DC_AXI_INT_CLK] = clk_hw_register_fixed_rate(NULL, "dc_axi_int_clk_root", NULL, 0, 400000000); - clks[IMX_DC_CFG_CLK] = clk_hw_register_fixed_rate(NULL, "dc_cfg_clk_root", NULL, 0, 100000000); - clks[IMX_MIPI_IPG_CLK] = clk_hw_register_fixed_rate(NULL, "mipi_ipg_clk_root", NULL, 0, 120000000); - clks[IMX_IMG_AXI_CLK] = clk_hw_register_fixed_rate(NULL, "img_axi_clk_root", NULL, 0, 400000000); - clks[IMX_IMG_IPG_CLK] = clk_hw_register_fixed_rate(NULL, "img_ipg_clk_root", NULL, 0, 200000000); - clks[IMX_IMG_PXL_CLK] = clk_hw_register_fixed_rate(NULL, "img_pxl_clk_root", NULL, 0, 600000000); - clks[IMX_HSIO_AXI_CLK] = clk_hw_register_fixed_rate(NULL, "hsio_axi_clk_root", NULL, 0, 400000000); - clks[IMX_HSIO_PER_CLK] = clk_hw_register_fixed_rate(NULL, "hsio_per_clk_root", NULL, 0, 133333333); - clks[IMX_LSIO_MEM_CLK] = clk_hw_register_fixed_rate(NULL, "lsio_mem_clk_root", NULL, 0, 200000000); - clks[IMX_LSIO_BUS_CLK] = clk_hw_register_fixed_rate(NULL, "lsio_bus_clk_root", NULL, 0, 100000000); - /* ARM core */ - clks[IMX_A35_CLK] = imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU, clk_cells); + imx_clk_scu("a35_clk", IMX_SC_R_A35, IMX_SC_PM_CLK_CPU); + imx_clk_scu("a53_clk", IMX_SC_R_A53, IMX_SC_PM_CLK_CPU); + imx_clk_scu("a72_clk", IMX_SC_R_A72, IMX_SC_PM_CLK_CPU); /* LSIO SS */ - clks[IMX_LSIO_PWM0_CLK] = imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM1_CLK] = imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM2_CLK] = imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM3_CLK] = imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM4_CLK] = imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM5_CLK] = imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM6_CLK] = imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_PWM7_CLK] = imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_GPT0_CLK] = imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_GPT1_CLK] = imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_GPT2_CLK] = imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_GPT3_CLK] = imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_GPT4_CLK] = imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_FSPI0_CLK] = imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_LSIO_FSPI1_CLK] = imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER, clk_cells); - - /* ADMA SS */ - clks[IMX_ADMA_UART0_CLK] = imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_UART1_CLK] = imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_UART2_CLK] = imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_UART3_CLK] = imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_SPI0_CLK] = imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_SPI1_CLK] = imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_SPI2_CLK] = imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_SPI3_CLK] = imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_CAN0_CLK] = imx_clk_scu("can0_clk", IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_I2C0_CLK] = imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_I2C1_CLK] = imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_I2C2_CLK] = imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_I2C3_CLK] = imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_FTM0_CLK] = imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_FTM1_CLK] = imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_ADC0_CLK] = imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_PWM_CLK] = imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_ADMA_LCD_CLK] = imx_clk_scu("lcd_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER, clk_cells); + imx_clk_scu("pwm0_clk", IMX_SC_R_PWM_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm1_clk", IMX_SC_R_PWM_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm2_clk", IMX_SC_R_PWM_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm3_clk", IMX_SC_R_PWM_3, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm4_clk", IMX_SC_R_PWM_4, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm5_clk", IMX_SC_R_PWM_5, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm6_clk", IMX_SC_R_PWM_6, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm7_clk", IMX_SC_R_PWM_7, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpt0_clk", IMX_SC_R_GPT_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpt1_clk", IMX_SC_R_GPT_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpt2_clk", IMX_SC_R_GPT_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpt3_clk", IMX_SC_R_GPT_3, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpt4_clk", IMX_SC_R_GPT_4, IMX_SC_PM_CLK_PER); + imx_clk_scu("fspi0_clk", IMX_SC_R_FSPI_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("fspi1_clk", IMX_SC_R_FSPI_1, IMX_SC_PM_CLK_PER); + + /* DMA SS */ + imx_clk_scu("uart0_clk", IMX_SC_R_UART_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("uart1_clk", IMX_SC_R_UART_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("uart2_clk", IMX_SC_R_UART_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("uart3_clk", IMX_SC_R_UART_3, IMX_SC_PM_CLK_PER); + imx_clk_scu("uart4_clk", IMX_SC_R_UART_4, IMX_SC_PM_CLK_PER); + imx_clk_scu("sim0_clk", IMX_SC_R_EMVSIM_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("spi0_clk", IMX_SC_R_SPI_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("spi1_clk", IMX_SC_R_SPI_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("spi2_clk", IMX_SC_R_SPI_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("spi3_clk", IMX_SC_R_SPI_3, IMX_SC_PM_CLK_PER); + imx_clk_scu("can0_clk", IMX_SC_R_CAN_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("can1_clk", IMX_SC_R_CAN_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("can2_clk", IMX_SC_R_CAN_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("i2c0_clk", IMX_SC_R_I2C_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("i2c1_clk", IMX_SC_R_I2C_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("i2c2_clk", IMX_SC_R_I2C_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("i2c3_clk", IMX_SC_R_I2C_3, IMX_SC_PM_CLK_PER); + imx_clk_scu("i2c4_clk", IMX_SC_R_I2C_4, IMX_SC_PM_CLK_PER); + imx_clk_scu("ftm0_clk", IMX_SC_R_FTM_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("ftm1_clk", IMX_SC_R_FTM_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("adc1_clk", IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER); + imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER); + imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL); + + /* Audio SS */ + imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL); + imx_clk_scu("audio_pll1_clk", IMX_SC_R_AUDIO_PLL_1, IMX_SC_PM_CLK_PLL); + imx_clk_scu("audio_pll_div_clk0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("audio_pll_div_clk1_clk", IMX_SC_R_AUDIO_PLL_1, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("audio_rec_clk0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_MISC1); + imx_clk_scu("audio_rec_clk1_clk", IMX_SC_R_AUDIO_PLL_1, IMX_SC_PM_CLK_MISC1); /* Connectivity */ - clks[IMX_CONN_SDHC0_CLK] = imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_SDHC1_CLK] = imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_SDHC2_CLK] = imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_ENET0_ROOT_CLK] = imx_clk_scu("enet0_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_ENET0_BYPASS_CLK] = imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS, clk_cells); - clks[IMX_CONN_ENET0_RGMII_CLK] = imx_clk_scu("enet0_rgmii_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0, clk_cells); - clks[IMX_CONN_ENET1_ROOT_CLK] = imx_clk_scu("enet1_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_ENET1_BYPASS_CLK] = imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS, clk_cells); - clks[IMX_CONN_ENET1_RGMII_CLK] = imx_clk_scu("enet1_rgmii_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0, clk_cells); - 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); - clks[IMX_CONN_GPMI_BCH_CLK] = imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CONN_USB2_ACLK] = imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER, clk_cells); - 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); - clks[IMX_CONN_USB2_LPM_CLK] = imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC, clk_cells); + imx_clk_scu("sdhc0_clk", IMX_SC_R_SDHC_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("sdhc1_clk", IMX_SC_R_SDHC_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("sdhc2_clk", IMX_SC_R_SDHC_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("enet0_root_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_PER); + imx_clk_divider_gpr_scu("enet0_ref_div", "enet0_root_clk", IMX_SC_R_ENET_0, IMX_SC_C_CLKDIV); + imx_clk_mux_gpr_scu("enet0_rgmii_txc_sel", enet0_rgmii_txc_sels, ARRAY_SIZE(enet0_rgmii_txc_sels), IMX_SC_R_ENET_0, IMX_SC_C_TXCLK); + imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS); + imx_clk_gate_gpr_scu("enet0_ref_50_clk", "clk_dummy", IMX_SC_R_ENET_0, IMX_SC_C_DISABLE_50, true); + imx_clk_scu("enet0_rgmii_rx_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("enet1_root_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER); + imx_clk_divider_gpr_scu("enet1_ref_div", "enet1_root_clk", IMX_SC_R_ENET_1, IMX_SC_C_CLKDIV); + imx_clk_mux_gpr_scu("enet1_rgmii_txc_sel", enet1_rgmii_txc_sels, ARRAY_SIZE(enet1_rgmii_txc_sels), IMX_SC_R_ENET_1, IMX_SC_C_TXCLK); + imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS); + imx_clk_gate_gpr_scu("enet1_ref_50_clk", "clk_dummy", IMX_SC_R_ENET_1, IMX_SC_C_DISABLE_50, true); + imx_clk_scu("enet1_rgmii_rx_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER); + imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER); + imx_clk_scu("usb3_bus_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC); /* Display controller SS */ - clks[IMX_DC0_DISP0_CLK] = imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0, clk_cells); - clks[IMX_DC0_DISP1_CLK] = imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1, clk_cells); - clks[IMX_DC0_PLL0_CLK] = imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL, clk_cells); - clks[IMX_DC0_PLL1_CLK] = imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL, clk_cells); - clks[IMX_DC0_BYPASS0_CLK] = imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS, clk_cells); - clks[IMX_DC0_BYPASS1_CLK] = imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS, clk_cells); + imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1); + imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL); + imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL); + imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS); + + imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0); + imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1); + imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL); + imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL); + imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS); /* MIPI-LVDS SS */ - clks[IMX_MIPI0_LVDS_PIXEL_CLK] = imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI0_LVDS_BYPASS_CLK] = imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS, clk_cells); - clks[IMX_MIPI0_LVDS_PHY_CLK] = imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3, clk_cells); - clks[IMX_MIPI0_I2C0_CLK] = imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI0_I2C1_CLK] = imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI0_PWM0_CLK] = imx_clk_scu("mipi0_pwm0_clk", IMX_SC_R_MIPI_0_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_MIPI1_LVDS_PIXEL_CLK] = imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI1_LVDS_BYPASS_CLK] = imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS, clk_cells); - clks[IMX_MIPI1_LVDS_PHY_CLK] = imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3, clk_cells); - clks[IMX_MIPI1_I2C0_CLK] = imx_clk_scu("mipi1_i2c0_clk", IMX_SC_R_MIPI_1_I2C_0, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI1_I2C1_CLK] = imx_clk_scu("mipi1_i2c1_clk", IMX_SC_R_MIPI_1_I2C_1, IMX_SC_PM_CLK_MISC2, clk_cells); - clks[IMX_MIPI1_PWM0_CLK] = imx_clk_scu("mipi1_pwm0_clk", IMX_SC_R_MIPI_1_PWM_0, IMX_SC_PM_CLK_PER, clk_cells); + imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS); + imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY); + imx_clk_scu("mipi0_i2c0_clk", IMX_SC_R_MIPI_0_I2C_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi0_i2c1_clk", IMX_SC_R_MIPI_0_I2C_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi0_pwm0_clk", IMX_SC_R_MIPI_0_PWM_0, IMX_SC_PM_CLK_PER); + + imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); + + imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS); + imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS); + imx_clk_scu2("mipi1_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PHY); + imx_clk_scu("mipi1_i2c0_clk", IMX_SC_R_MIPI_1_I2C_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi1_i2c1_clk", IMX_SC_R_MIPI_1_I2C_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("mipi1_pwm0_clk", IMX_SC_R_MIPI_1_PWM_0, IMX_SC_PM_CLK_PER); + + imx_clk_scu("lvds0_i2c0_clk", IMX_SC_R_LVDS_0_I2C_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("lvds0_i2c1_clk", IMX_SC_R_LVDS_0_I2C_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("lvds0_pwm0_clk", IMX_SC_R_LVDS_0_PWM_0, IMX_SC_PM_CLK_PER); + + imx_clk_scu("lvds1_i2c0_clk", IMX_SC_R_LVDS_1_I2C_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("lvds1_i2c1_clk", IMX_SC_R_LVDS_1_I2C_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("lvds1_pwm0_clk", IMX_SC_R_LVDS_1_PWM_0, IMX_SC_PM_CLK_PER); /* MIPI CSI SS */ - clks[IMX_CSI0_CORE_CLK] = imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_CSI0_ESC_CLK] = imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC, clk_cells); - 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); - 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); + imx_clk_scu("mipi_csi0_core_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi_csi0_esc_clk", IMX_SC_R_CSI_0, IMX_SC_PM_CLK_MISC); + imx_clk_scu("mipi_csi0_i2c0_clk", IMX_SC_R_CSI_0_I2C_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi_csi0_pwm0_clk", IMX_SC_R_CSI_0_PWM_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi_csi1_core_clk", IMX_SC_R_CSI_1, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi_csi1_esc_clk", IMX_SC_R_CSI_1, IMX_SC_PM_CLK_MISC); + imx_clk_scu("mipi_csi1_i2c0_clk", IMX_SC_R_CSI_1_I2C_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("mipi_csi1_pwm0_clk", IMX_SC_R_CSI_1_PWM_0, IMX_SC_PM_CLK_PER); + + /* Parallel Interface SS */ + imx_clk_scu("pi_dpll_clk", IMX_SC_R_PI_0_PLL, IMX_SC_PM_CLK_PLL); + imx_clk_scu2("pi_per_div_clk", pi_pll0_sels, ARRAY_SIZE(pi_pll0_sels), IMX_SC_R_PI_0, IMX_SC_PM_CLK_PER); + imx_clk_scu("pi_mclk_div_clk", IMX_SC_R_PI_0, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("pi_i2c0_div_clk", IMX_SC_R_PI_0_I2C_0, IMX_SC_PM_CLK_PER); /* GPU SS */ - clks[IMX_GPU0_CORE_CLK] = imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER, clk_cells); - clks[IMX_GPU0_SHADER_CLK] = imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC, clk_cells); - - for (i = 0; i < clk_data->num; i++) { - if (IS_ERR(clks[i])) - pr_warn("i.MX clk %u: register failed with %ld\n", - i, PTR_ERR(clks[i])); - } - - if (clk_cells == 2) { - ret = of_clk_add_hw_provider(ccm_node, imx_scu_of_clk_src_get, imx_scu_clks); - if (ret) - imx_clk_scu_unregister(); - } else { - /* - * legacy binding code path doesn't unregister here because - * it will be removed later. - */ - ret = of_clk_add_hw_provider(ccm_node, of_clk_hw_onecell_get, clk_data); - } + imx_clk_scu("gpu_core0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpu_shader0_clk", IMX_SC_R_GPU_0_PID0, IMX_SC_PM_CLK_MISC); + + imx_clk_scu("gpu_core1_clk", IMX_SC_R_GPU_1_PID0, IMX_SC_PM_CLK_PER); + imx_clk_scu("gpu_shader1_clk", IMX_SC_R_GPU_1_PID0, IMX_SC_PM_CLK_MISC); + + /* CM40 SS */ + imx_clk_scu("cm40_i2c_div", IMX_SC_R_M4_0_I2C, IMX_SC_PM_CLK_PER); + imx_clk_scu("cm40_lpuart_div", IMX_SC_R_M4_0_UART, IMX_SC_PM_CLK_PER); + + /* CM41 SS */ + imx_clk_scu("cm41_i2c_div", IMX_SC_R_M4_1_I2C, IMX_SC_PM_CLK_PER); + + /* HDMI TX SS */ + imx_clk_scu("hdmi_dig_pll_clk", IMX_SC_R_HDMI_PLL_0, IMX_SC_PM_CLK_PLL); + imx_clk_scu("hdmi_av_pll_clk", IMX_SC_R_HDMI_PLL_1, IMX_SC_PM_CLK_PLL); + imx_clk_scu2("hdmi_pixel_mux_clk", hdmi_sels, ARRAY_SIZE(hdmi_sels), IMX_SC_R_HDMI, IMX_SC_PM_CLK_MISC0); + imx_clk_scu2("hdmi_pixel_link_clk", hdmi_sels, ARRAY_SIZE(hdmi_sels), IMX_SC_R_HDMI, IMX_SC_PM_CLK_MISC1); + imx_clk_scu("hdmi_ipg_clk", IMX_SC_R_HDMI, IMX_SC_PM_CLK_MISC4); + imx_clk_scu("hdmi_i2c0_clk", IMX_SC_R_HDMI_I2C_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("hdmi_hdp_core_clk", IMX_SC_R_HDMI, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("hdmi_pxl_clk", hdmi_sels, ARRAY_SIZE(hdmi_sels), IMX_SC_R_HDMI, IMX_SC_PM_CLK_MISC3); + imx_clk_scu("hdmi_i2s_bypass_clk", IMX_SC_R_HDMI_I2S, IMX_SC_PM_CLK_BYPASS); + imx_clk_scu("hdmi_i2s_clk", IMX_SC_R_HDMI_I2S, IMX_SC_PM_CLK_MISC0); + + /* HDMI RX SS */ + imx_clk_scu("hdmi_rx_i2s_bypass_clk", IMX_SC_R_HDMI_RX_BYPASS, IMX_SC_PM_CLK_MISC0); + imx_clk_scu("hdmi_rx_spdif_bypass_clk", IMX_SC_R_HDMI_RX_BYPASS, IMX_SC_PM_CLK_MISC1); + imx_clk_scu("hdmi_rx_bypass_clk", IMX_SC_R_HDMI_RX_BYPASS, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("hdmi_rx_i2c0_clk", IMX_SC_R_HDMI_RX_I2C_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("hdmi_rx_pwm_clk", IMX_SC_R_HDMI_RX_PWM_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu("hdmi_rx_spdif_clk", IMX_SC_R_HDMI_RX, IMX_SC_PM_CLK_MISC0); + imx_clk_scu2("hdmi_rx_hd_ref_clk", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), IMX_SC_R_HDMI_RX, IMX_SC_PM_CLK_MISC1); + imx_clk_scu2("hdmi_rx_hd_core_clk", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), IMX_SC_R_HDMI_RX, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("hdmi_rx_pxl_clk", hdmi_rx_sels, ARRAY_SIZE(hdmi_rx_sels), IMX_SC_R_HDMI_RX, IMX_SC_PM_CLK_MISC3); + imx_clk_scu("hdmi_rx_i2s_clk", IMX_SC_R_HDMI_RX, IMX_SC_PM_CLK_MISC4); + + ret = of_clk_add_hw_provider(ccm_node, imx_scu_of_clk_src_get, imx_scu_clks); + if (ret) + imx_clk_scu_unregister(); return ret; } static const struct of_device_id imx8qxp_match[] = { { .compatible = "fsl,scu-clk", }, - { .compatible = "fsl,imx8qxp-clk", }, + { .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, }, + { .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, }, { /* sentinel */ } }; diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index f89b4da10e80..083da31dc3ea 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -1,11 +1,12 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright 2018 NXP + * Copyright 2018-2021 NXP * Dong Aisheng <aisheng.dong@nxp.com> */ #include <dt-bindings/firmware/imx/rsrc.h> #include <linux/arm-smccc.h> +#include <linux/bsearch.h> #include <linux/clk-provider.h> #include <linux/err.h> #include <linux/of_platform.h> @@ -22,6 +23,7 @@ static struct imx_sc_ipc *ccm_ipc_handle; static struct device_node *pd_np; static struct platform_driver imx_clk_scu_driver; +static const struct imx_clk_scu_rsrc_table *rsrc_table; struct imx_scu_clk_node { const char *name; @@ -48,11 +50,29 @@ struct clk_scu { u8 clk_type; /* for state save&restore */ + struct clk_hw *parent; + u8 parent_index; bool is_enabled; u32 rate; }; /* + * struct clk_gpr_scu - Description of one SCU GPR clock + * @hw: the common clk_hw + * @rsrc_id: resource ID of this SCU clock + * @gpr_id: GPR ID index to control the divider + */ +struct clk_gpr_scu { + struct clk_hw hw; + u16 rsrc_id; + u8 gpr_id; + u8 flags; + bool gate_invert; +}; + +#define to_clk_gpr_scu(_hw) container_of(_hw, struct clk_gpr_scu, hw) + +/* * struct imx_sc_msg_req_set_clock_rate - clock set rate protocol * @hdr: SCU protocol header * @rate: rate to set @@ -151,7 +171,26 @@ static inline struct clk_scu *to_clk_scu(struct clk_hw *hw) return container_of(hw, struct clk_scu, hw); } -int imx_clk_scu_init(struct device_node *np) +static inline int imx_scu_clk_search_cmp(const void *rsrc, const void *rsrc_p) +{ + return *(u32 *)rsrc - *(u32 *)rsrc_p; +} + +static bool imx_scu_clk_is_valid(u32 rsrc_id) +{ + void *p; + + if (!rsrc_table) + return true; + + p = bsearch(&rsrc_id, rsrc_table->rsrc, rsrc_table->num, + sizeof(rsrc_table->rsrc[0]), imx_scu_clk_search_cmp); + + return p != NULL; +} + +int imx_clk_scu_init(struct device_node *np, + const struct imx_clk_scu_rsrc_table *data) { u32 clk_cells; int ret, i; @@ -170,6 +209,8 @@ int imx_clk_scu_init(struct device_node *np) pd_np = of_find_compatible_node(NULL, NULL, "fsl,scu-pd"); if (!pd_np) return -EINVAL; + + rsrc_table = data; } return platform_driver_register(&imx_clk_scu_driver); @@ -234,8 +275,10 @@ static int clk_scu_atf_set_cpu_rate(struct clk_hw *hw, unsigned long rate, struct arm_smccc_res res; unsigned long cluster_id; - if (clk->rsrc_id == IMX_SC_R_A35) + if (clk->rsrc_id == IMX_SC_R_A35 || clk->rsrc_id == IMX_SC_R_A53) cluster_id = 0; + else if (clk->rsrc_id == IMX_SC_R_A72) + cluster_id = 1; else return -EINVAL; @@ -296,6 +339,8 @@ static u8 clk_scu_get_parent(struct clk_hw *hw) return 0; } + clk->parent_index = msg.data.resp.parent; + return msg.data.resp.parent; } @@ -304,6 +349,7 @@ static int clk_scu_set_parent(struct clk_hw *hw, u8 index) struct clk_scu *clk = to_clk_scu(hw); struct imx_sc_msg_set_clock_parent msg; struct imx_sc_rpc_msg *hdr = &msg.hdr; + int ret; hdr->ver = IMX_SC_RPC_VERSION; hdr->svc = IMX_SC_RPC_SVC_PM; @@ -314,7 +360,16 @@ static int clk_scu_set_parent(struct clk_hw *hw, u8 index) msg.clk = clk->clk_type; msg.parent = index; - return imx_scu_call_rpc(ccm_ipc_handle, &msg, true); + ret = imx_scu_call_rpc(ccm_ipc_handle, &msg, true); + if (ret) { + pr_err("%s: failed to set clock parent %d\n", + clk_hw_get_name(hw), ret); + return ret; + } + + clk->parent_index = index; + + return 0; } static int sc_pm_clock_enable(struct imx_sc_ipc *ipc, u16 resource, @@ -386,6 +441,12 @@ static const struct clk_ops clk_scu_cpu_ops = { .unprepare = clk_scu_unprepare, }; +static const struct clk_ops clk_scu_pi_ops = { + .recalc_rate = clk_scu_recalc_rate, + .round_rate = clk_scu_round_rate, + .set_rate = clk_scu_set_rate, +}; + struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, const char * const *parents, int num_parents, u32 rsrc_id, u8 clk_type) @@ -404,8 +465,10 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, init.name = name; init.ops = &clk_scu_ops; - if (rsrc_id == IMX_SC_R_A35) + if (rsrc_id == IMX_SC_R_A35 || rsrc_id == IMX_SC_R_A53 || rsrc_id == IMX_SC_R_A72) init.ops = &clk_scu_cpu_ops; + else if (rsrc_id == IMX_SC_R_PI_0_PLL) + init.ops = &clk_scu_pi_ops; else init.ops = &clk_scu_ops; init.parent_names = parents; @@ -458,15 +521,19 @@ static int imx_clk_scu_probe(struct platform_device *pdev) struct clk_hw *hw; int ret; - pm_runtime_set_suspended(dev); - pm_runtime_set_autosuspend_delay(dev, 50); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_enable(dev); - - ret = pm_runtime_get_sync(dev); - if (ret) { - pm_runtime_disable(dev); - return ret; + if (!((clk->rsrc == IMX_SC_R_A35) || (clk->rsrc == IMX_SC_R_A53) || + (clk->rsrc == IMX_SC_R_A72))) { + pm_runtime_set_suspended(dev); + pm_runtime_set_autosuspend_delay(dev, 50); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(dev); + + ret = pm_runtime_get_sync(dev); + if (ret) { + pm_genpd_remove_device(dev); + pm_runtime_disable(dev); + return ret; + } } hw = __imx_clk_scu(dev, clk->name, clk->parents, clk->num_parents, @@ -479,8 +546,11 @@ static int imx_clk_scu_probe(struct platform_device *pdev) clk->hw = hw; list_add_tail(&clk->node, &imx_scu_clks[clk->rsrc]); - pm_runtime_mark_last_busy(&pdev->dev); - pm_runtime_put_autosuspend(&pdev->dev); + if (!((clk->rsrc == IMX_SC_R_A35) || (clk->rsrc == IMX_SC_R_A53) || + (clk->rsrc == IMX_SC_R_A72))) { + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + } dev_dbg(dev, "register SCU clock rsrc:%d type:%d\n", clk->rsrc, clk->clk_type); @@ -491,10 +561,28 @@ static int imx_clk_scu_probe(struct platform_device *pdev) static int __maybe_unused imx_clk_scu_suspend(struct device *dev) { struct clk_scu *clk = dev_get_drvdata(dev); + u32 rsrc_id = clk->rsrc_id; + + if ((rsrc_id == IMX_SC_R_A35) || (rsrc_id == IMX_SC_R_A53) || + (rsrc_id == IMX_SC_R_A72)) + return 0; + + clk->parent = clk_hw_get_parent(&clk->hw); - clk->rate = clk_hw_get_rate(&clk->hw); + /* DC SS needs to handle bypass clock using non-cached clock rate */ + if (clk->rsrc_id == IMX_SC_R_DC_0_VIDEO0 || + clk->rsrc_id == IMX_SC_R_DC_0_VIDEO1 || + clk->rsrc_id == IMX_SC_R_DC_1_VIDEO0 || + clk->rsrc_id == IMX_SC_R_DC_1_VIDEO1) + clk->rate = clk_scu_recalc_rate(&clk->hw, 0); + else + clk->rate = clk_hw_get_rate(&clk->hw); clk->is_enabled = clk_hw_is_enabled(&clk->hw); + if (clk->parent) + dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent), + clk->parent_index); + if (clk->rate) dev_dbg(dev, "save rate %d\n", clk->rate); @@ -507,15 +595,27 @@ static int __maybe_unused imx_clk_scu_suspend(struct device *dev) static int __maybe_unused imx_clk_scu_resume(struct device *dev) { struct clk_scu *clk = dev_get_drvdata(dev); + u32 rsrc_id = clk->rsrc_id; int ret = 0; + if ((rsrc_id == IMX_SC_R_A35) || (rsrc_id == IMX_SC_R_A53) || + (rsrc_id == IMX_SC_R_A72)) + return 0; + + if (clk->parent) { + ret = clk_scu_set_parent(&clk->hw, clk->parent_index); + dev_dbg(dev, "restore parent %s idx %u %s\n", + clk_hw_get_name(clk->parent), + clk->parent_index, !ret ? "success" : "failed"); + } + if (clk->rate) { ret = clk_scu_set_rate(&clk->hw, clk->rate, 0); dev_dbg(dev, "restore rate %d %s\n", clk->rate, !ret ? "success" : "failed"); } - if (clk->is_enabled) { + if (clk->is_enabled && rsrc_id != IMX_SC_R_PI_0_PLL) { ret = clk_scu_prepare(&clk->hw); dev_dbg(dev, "restore enabled state %s\n", !ret ? "success" : "failed"); @@ -567,6 +667,9 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name, struct platform_device *pdev; int ret; + if (!imx_scu_clk_is_valid(rsrc_id)) + return ERR_PTR(-EINVAL); + pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE); if (!pdev) { pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n", @@ -605,3 +708,176 @@ void imx_clk_scu_unregister(void) } } } + +static unsigned long clk_gpr_div_scu_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + unsigned long rate = 0; + u32 val; + int err; + + err = imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, &val); + + rate = val ? parent_rate / 2 : parent_rate; + + return err ? 0 : rate; +} + +static long clk_gpr_div_scu_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + if (rate < *prate) + rate = *prate / 2; + else + rate = *prate; + + return rate; +} + +static int clk_gpr_div_scu_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + uint32_t val; + int err; + + val = (rate < parent_rate) ? 1 : 0; + err = imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, val); + + return err ? -EINVAL : 0; +} + +static const struct clk_ops clk_gpr_div_scu_ops = { + .recalc_rate = clk_gpr_div_scu_recalc_rate, + .round_rate = clk_gpr_div_scu_round_rate, + .set_rate = clk_gpr_div_scu_set_rate, +}; + +static u8 clk_gpr_mux_scu_get_parent(struct clk_hw *hw) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + u32 val = 0; + + imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, &val); + + return (u8)val; +} + +static int clk_gpr_mux_scu_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + + return imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, index); +} + +static const struct clk_ops clk_gpr_mux_scu_ops = { + .get_parent = clk_gpr_mux_scu_get_parent, + .set_parent = clk_gpr_mux_scu_set_parent, +}; + +static int clk_gpr_gate_scu_prepare(struct clk_hw *hw) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + + return imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, !clk->gate_invert); +} + +static void clk_gpr_gate_scu_unprepare(struct clk_hw *hw) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + int ret; + + ret = imx_sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, clk->gate_invert); + if (ret) + pr_err("%s: clk unprepare failed %d\n", clk_hw_get_name(hw), + ret); +} + +static int clk_gpr_gate_scu_is_prepared(struct clk_hw *hw) +{ + struct clk_gpr_scu *clk = to_clk_gpr_scu(hw); + int ret; + u32 val; + + ret = imx_sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, &val); + if (ret) + return ret; + + return clk->gate_invert ? !val : val; +} + +static const struct clk_ops clk_gpr_gate_scu_ops = { + .prepare = clk_gpr_gate_scu_prepare, + .unprepare = clk_gpr_gate_scu_unprepare, + .is_prepared = clk_gpr_gate_scu_is_prepared, +}; + +struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_name, + int num_parents, u32 rsrc_id, u8 gpr_id, u8 flags, + bool invert) +{ + struct imx_scu_clk_node *clk_node; + struct clk_gpr_scu *clk; + struct clk_hw *hw; + struct clk_init_data init; + int ret; + + if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) + return ERR_PTR(-EINVAL); + + clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL); + if (!clk_node) + return ERR_PTR(-ENOMEM); + + if (!imx_scu_clk_is_valid(rsrc_id)) + return ERR_PTR(-EINVAL); + + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { + kfree(clk_node); + return ERR_PTR(-ENOMEM); + } + + clk->rsrc_id = rsrc_id; + clk->gpr_id = gpr_id; + clk->flags = flags; + clk->gate_invert = invert; + + if (flags & IMX_SCU_GPR_CLK_GATE) + init.ops = &clk_gpr_gate_scu_ops; + + if (flags & IMX_SCU_GPR_CLK_DIV) + init.ops = &clk_gpr_div_scu_ops; + + if (flags & IMX_SCU_GPR_CLK_MUX) + init.ops = &clk_gpr_mux_scu_ops; + + init.flags = 0; + init.name = name; + init.parent_names = parent_name; + init.num_parents = num_parents; + + clk->hw.init = &init; + + hw = &clk->hw; + ret = clk_hw_register(NULL, hw); + if (ret) { + kfree(clk); + kfree(clk_node); + hw = ERR_PTR(ret); + } else { + clk_node->hw = hw; + clk_node->clk_type = gpr_id; + list_add_tail(&clk_node->node, &imx_scu_clks[rsrc_id]); + } + + return hw; +} diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h index e8352164923e..22156e93b85d 100644 --- a/drivers/clk/imx/clk-scu.h +++ b/drivers/clk/imx/clk-scu.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0+ */ /* - * Copyright 2018 NXP + * Copyright 2018-2021 NXP * Dong Aisheng <aisheng.dong@nxp.com> */ @@ -10,10 +10,22 @@ #include <linux/firmware/imx/sci.h> #include <linux/of.h> +#define IMX_SCU_GPR_CLK_GATE BIT(0) +#define IMX_SCU_GPR_CLK_DIV BIT(1) +#define IMX_SCU_GPR_CLK_MUX BIT(2) + +struct imx_clk_scu_rsrc_table { + const u32 *rsrc; + u8 num; +}; + extern struct list_head imx_scu_clks[]; extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops; +extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp; +extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm; -int imx_clk_scu_init(struct device_node *np); +int imx_clk_scu_init(struct device_node *np, + const struct imx_clk_scu_rsrc_table *data); struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec, void *data); struct clk_hw *imx_clk_scu_alloc_dev(const char *name, @@ -31,23 +43,20 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name, void __iomem *reg, u8 bit_idx, bool hw_gate); void imx_clk_lpcg_scu_unregister(struct clk_hw *hw); +struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_name, + int num_parents, u32 rsrc_id, u8 gpr_id, u8 flags, + bool invert); + static inline struct clk_hw *imx_clk_scu(const char *name, u32 rsrc_id, - u8 clk_type, u8 clk_cells) + u8 clk_type) { - if (clk_cells == 2) - return imx_clk_scu_alloc_dev(name, NULL, 0, rsrc_id, clk_type); - else - return __imx_clk_scu(NULL, name, NULL, 0, rsrc_id, clk_type); + return imx_clk_scu_alloc_dev(name, NULL, 0, rsrc_id, clk_type); } static inline struct clk_hw *imx_clk_scu2(const char *name, const char * const *parents, - int num_parents, u32 rsrc_id, u8 clk_type, - u8 clk_cells) + int num_parents, u32 rsrc_id, u8 clk_type) { - if (clk_cells == 2) - return imx_clk_scu_alloc_dev(name, parents, num_parents, rsrc_id, clk_type); - else - return __imx_clk_scu(NULL, name, parents, num_parents, rsrc_id, clk_type); + return imx_clk_scu_alloc_dev(name, parents, num_parents, rsrc_id, clk_type); } static inline struct clk_hw *imx_clk_lpcg_scu_dev(struct device *dev, const char *name, @@ -65,4 +74,25 @@ static inline struct clk_hw *imx_clk_lpcg_scu(const char *name, const char *pare return __imx_clk_lpcg_scu(NULL, name, parent_name, flags, reg, bit_idx, hw_gate); } + +static inline struct clk_hw *imx_clk_gate_gpr_scu(const char *name, const char *parent_name, + u32 rsrc_id, u8 gpr_id, bool invert) +{ + return __imx_clk_gpr_scu(name, &parent_name, 1, rsrc_id, gpr_id, + IMX_SCU_GPR_CLK_GATE, invert); +} + +static inline struct clk_hw *imx_clk_divider_gpr_scu(const char *name, const char *parent_name, + u32 rsrc_id, u8 gpr_id) +{ + return __imx_clk_gpr_scu(name, &parent_name, 1, rsrc_id, gpr_id, + IMX_SCU_GPR_CLK_DIV, 0); +} + +static inline struct clk_hw *imx_clk_mux_gpr_scu(const char *name, const char * const *parent_names, + int num_parents, u32 rsrc_id, u8 gpr_id) +{ + return __imx_clk_gpr_scu(name, parent_names, num_parents, rsrc_id, + gpr_id, IMX_SCU_GPR_CLK_MUX, 0); +} #endif diff --git a/drivers/clk/ingenic/Kconfig b/drivers/clk/ingenic/Kconfig index 580b0cf69ed5..898f1bc478c9 100644 --- a/drivers/clk/ingenic/Kconfig +++ b/drivers/clk/ingenic/Kconfig @@ -25,6 +25,16 @@ config INGENIC_CGU_JZ4725B If building for a JZ4725B SoC, you want to say Y here. +config INGENIC_CGU_JZ4760 + bool "Ingenic JZ4760 CGU driver" + default MACH_JZ4760 + select INGENIC_CGU_COMMON + help + Support the clocks provided by the CGU hardware on Ingenic JZ4760 + and compatible SoCs. + + If building for a JZ4760 SoC, you want to say Y here. + config INGENIC_CGU_JZ4770 bool "Ingenic JZ4770 CGU driver" default MACH_JZ4770 diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile index aaa4bffe03c6..9edfaf4610b9 100644 --- a/drivers/clk/ingenic/Makefile +++ b/drivers/clk/ingenic/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_INGENIC_CGU_COMMON) += cgu.o pm.o obj-$(CONFIG_INGENIC_CGU_JZ4740) += jz4740-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o +obj-$(CONFIG_INGENIC_CGU_JZ4760) += jz4760-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index c8e9cb6c8e39..266c7595d330 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -99,13 +99,14 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) od_enc = ctl >> pll_info->od_shift; od_enc &= GENMASK(pll_info->od_bits - 1, 0); - ctl = readl(cgu->base + pll_info->bypass_reg); + if (pll_info->bypass_bit >= 0) { + ctl = readl(cgu->base + pll_info->bypass_reg); - bypass = !pll_info->no_bypass_bit && - !!(ctl & BIT(pll_info->bypass_bit)); + bypass = !!(ctl & BIT(pll_info->bypass_bit)); - if (bypass) - return parent_rate; + if (bypass) + return parent_rate; + } for (od = 0; od < pll_info->od_max; od++) { if (pll_info->od_encoding[od] == od_enc) @@ -118,28 +119,42 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) n * od); } -static unsigned long -ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, - unsigned long rate, unsigned long parent_rate, - unsigned *pm, unsigned *pn, unsigned *pod) +static void +ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info, + unsigned long rate, unsigned long parent_rate, + unsigned int *pm, unsigned int *pn, unsigned int *pod) { - const struct ingenic_cgu_pll_info *pll_info; - unsigned m, n, od; - - pll_info = &clk_info->pll; - od = 1; + unsigned int m, n, od = 1; /* * The frequency after the input divider must be between 10 and 50 MHz. * The highest divider yields the best resolution. */ n = parent_rate / (10 * MHZ); - n = min_t(unsigned, n, 1 << clk_info->pll.n_bits); - n = max_t(unsigned, n, pll_info->n_offset); + n = min_t(unsigned int, n, 1 << pll_info->n_bits); + n = max_t(unsigned int, n, pll_info->n_offset); m = (rate / MHZ) * od * n / (parent_rate / MHZ); - m = min_t(unsigned, m, 1 << clk_info->pll.m_bits); - m = max_t(unsigned, m, pll_info->m_offset); + m = min_t(unsigned int, m, 1 << pll_info->m_bits); + m = max_t(unsigned int, m, pll_info->m_offset); + + *pm = m; + *pn = n; + *pod = od; +} + +static unsigned long +ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info, + unsigned long rate, unsigned long parent_rate, + unsigned int *pm, unsigned int *pn, unsigned int *pod) +{ + const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll; + unsigned int m, n, od; + + if (pll_info->calc_m_n_od) + (*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od); + else + ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od); if (pm) *pm = m; @@ -225,11 +240,13 @@ static int ingenic_pll_enable(struct clk_hw *hw) u32 ctl; spin_lock_irqsave(&cgu->lock, flags); - ctl = readl(cgu->base + pll_info->bypass_reg); + if (pll_info->bypass_bit >= 0) { + ctl = readl(cgu->base + pll_info->bypass_reg); - ctl &= ~BIT(pll_info->bypass_bit); + ctl &= ~BIT(pll_info->bypass_bit); - writel(ctl, cgu->base + pll_info->bypass_reg); + writel(ctl, cgu->base + pll_info->bypass_reg); + } ctl = readl(cgu->base + pll_info->reg); @@ -369,18 +386,23 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) struct ingenic_cgu *cgu = ingenic_clk->cgu; unsigned long rate = parent_rate; u32 div_reg, div; + u8 parent; if (clk_info->type & CGU_CLK_DIV) { - div_reg = readl(cgu->base + clk_info->div.reg); - div = (div_reg >> clk_info->div.shift) & - GENMASK(clk_info->div.bits - 1, 0); + parent = ingenic_clk_get_parent(hw); - if (clk_info->div.div_table) - div = clk_info->div.div_table[div]; - else - div = (div + 1) * clk_info->div.div; + if (!(clk_info->div.bypass_mask & BIT(parent))) { + div_reg = readl(cgu->base + clk_info->div.reg); + div = (div_reg >> clk_info->div.shift) & + GENMASK(clk_info->div.bits - 1, 0); - rate /= div; + if (clk_info->div.div_table) + div = clk_info->div.div_table[div]; + else + div = (div + 1) * clk_info->div.div; + + rate /= div; + } } else if (clk_info->type & CGU_CLK_FIXDIV) { rate /= clk_info->fixdiv.div; } @@ -410,10 +432,16 @@ ingenic_clk_calc_hw_div(const struct ingenic_cgu_clk_info *clk_info, } static unsigned -ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info, +ingenic_clk_calc_div(struct clk_hw *hw, + const struct ingenic_cgu_clk_info *clk_info, unsigned long parent_rate, unsigned long req_rate) { unsigned int div, hw_div; + u8 parent; + + parent = ingenic_clk_get_parent(hw); + if (clk_info->div.bypass_mask & BIT(parent)) + return 1; /* calculate the divide */ div = DIV_ROUND_UP(parent_rate, req_rate); @@ -448,7 +476,7 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate, unsigned int div = 1; if (clk_info->type & CGU_CLK_DIV) - div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate); + div = ingenic_clk_calc_div(hw, clk_info, *parent_rate, req_rate); else if (clk_info->type & CGU_CLK_FIXDIV) div = clk_info->fixdiv.div; else if (clk_hw_can_set_rate_parent(hw)) @@ -480,7 +508,7 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate, int ret = 0; if (clk_info->type & CGU_CLK_DIV) { - div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate); + div = ingenic_clk_calc_div(hw, clk_info, parent_rate, req_rate); rate = DIV_ROUND_UP(parent_rate, div); if (rate != req_rate) diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index 2c75ef4a36f5..bfc2b9c38a41 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h @@ -39,10 +39,10 @@ * their encoded values in the PLL control register, or -1 for * unsupported values * @bypass_reg: the offset of the bypass control register within the CGU - * @bypass_bit: the index of the bypass bit in the PLL control register + * @bypass_bit: the index of the bypass bit in the PLL control register, or + * -1 if there is no bypass bit * @enable_bit: the index of the enable bit in the PLL control register * @stable_bit: the index of the stable bit in the PLL control register - * @no_bypass_bit: if set, the PLL has no bypass functionality */ struct ingenic_cgu_pll_info { unsigned reg; @@ -52,10 +52,12 @@ struct ingenic_cgu_pll_info { u8 n_shift, n_bits, n_offset; u8 od_shift, od_bits, od_max; unsigned bypass_reg; - u8 bypass_bit; + s8 bypass_bit; u8 enable_bit; u8 stable_bit; - bool no_bypass_bit; + void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info, + unsigned long rate, unsigned long parent_rate, + unsigned int *m, unsigned int *n, unsigned int *od); }; /** @@ -84,6 +86,7 @@ struct ingenic_cgu_mux_info { * isn't one * @busy_bit: the index of the busy bit within reg, or -1 if there isn't one * @stop_bit: the index of the stop bit within reg, or -1 if there isn't one + * @bypass_mask: mask of parent clocks for which the divider does not apply * @div_table: optional table to map the value read from the register to the * actual divider value */ @@ -95,6 +98,7 @@ struct ingenic_cgu_div_info { s8 ce_bit; s8 busy_bit; s8 stop_bit; + u8 bypass_mask; const u8 *div_table; }; diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 8c38e72d14a7..5154b0cf8ad6 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c @@ -80,7 +80,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "pll half", CGU_CLK_DIV, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, + CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0, jz4725b_cgu_pll_half_div_table, }, }, @@ -89,7 +89,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "cclk", CGU_CLK_DIV, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, jz4725b_cgu_cpccr_div_table, }, }, @@ -98,7 +98,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "hclk", CGU_CLK_DIV, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, jz4725b_cgu_cpccr_div_table, }, }, @@ -107,7 +107,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "pclk", CGU_CLK_DIV, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, jz4725b_cgu_cpccr_div_table, }, }, @@ -116,7 +116,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "mclk", CGU_CLK_DIV, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, jz4725b_cgu_cpccr_div_table, }, }, @@ -125,7 +125,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = { "ipu", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4725B_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0, jz4725b_cgu_cpccr_div_table, }, .gate = { CGU_REG_CLKGR, 13 }, diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index c0ac9196a581..cd878f08aca3 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -95,7 +95,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "pll half", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, + CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0, jz4740_cgu_pll_half_div_table, }, }, @@ -104,7 +104,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "cclk", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, jz4740_cgu_cpccr_div_table, }, }, @@ -113,7 +113,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "hclk", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, jz4740_cgu_cpccr_div_table, }, }, @@ -122,7 +122,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "pclk", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, jz4740_cgu_cpccr_div_table, }, }, @@ -131,7 +131,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "mclk", CGU_CLK_DIV, .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, jz4740_cgu_cpccr_div_table, }, }, @@ -140,7 +140,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = { "lcd", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, .div = { - CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, + CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1, 0, jz4740_cgu_cpccr_div_table, }, .gate = { CGU_REG_CLKGR, 10 }, diff --git a/drivers/clk/ingenic/jz4760-cgu.c b/drivers/clk/ingenic/jz4760-cgu.c new file mode 100644 index 000000000000..14483797a4db --- /dev/null +++ b/drivers/clk/ingenic/jz4760-cgu.c @@ -0,0 +1,428 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * JZ4760 SoC CGU driver + * Copyright 2018, Paul Cercueil <paul@crapouillou.net> + */ + +#include <linux/bitops.h> +#include <linux/clk-provider.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/of.h> + +#include <linux/clk.h> + +#include <dt-bindings/clock/jz4760-cgu.h> + +#include "cgu.h" +#include "pm.h" + +#define MHZ (1000 * 1000) + +/* + * CPM registers offset address definition + */ +#define CGU_REG_CPCCR 0x00 +#define CGU_REG_LCR 0x04 +#define CGU_REG_CPPCR0 0x10 +#define CGU_REG_CLKGR0 0x20 +#define CGU_REG_OPCR 0x24 +#define CGU_REG_CLKGR1 0x28 +#define CGU_REG_CPPCR1 0x30 +#define CGU_REG_USBPCR 0x3c +#define CGU_REG_USBCDR 0x50 +#define CGU_REG_I2SCDR 0x60 +#define CGU_REG_LPCDR 0x64 +#define CGU_REG_MSCCDR 0x68 +#define CGU_REG_UHCCDR 0x6c +#define CGU_REG_SSICDR 0x74 +#define CGU_REG_CIMCDR 0x7c +#define CGU_REG_GPSCDR 0x80 +#define CGU_REG_PCMCDR 0x84 +#define CGU_REG_GPUCDR 0x88 + +static const s8 pll_od_encoding[8] = { + 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, +}; + +static const u8 jz4760_cgu_cpccr_div_table[] = { + 1, 2, 3, 4, 6, 8, +}; + +static const u8 jz4760_cgu_pll_half_div_table[] = { + 2, 1, +}; + +static void +jz4760_cgu_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info, + unsigned long rate, unsigned long parent_rate, + unsigned int *pm, unsigned int *pn, unsigned int *pod) +{ + unsigned int m, n, od, m_max = (1 << pll_info->m_bits) - 2; + + /* The frequency after the N divider must be between 1 and 50 MHz. */ + n = parent_rate / (1 * MHZ); + + /* The N divider must be >= 2. */ + n = clamp_val(n, 2, 1 << pll_info->n_bits); + + for (;; n >>= 1) { + od = (unsigned int)-1; + + do { + m = (rate / MHZ) * (1 << ++od) * n / (parent_rate / MHZ); + } while ((m > m_max || m & 1) && (od < 4)); + + if (od < 4 && m >= 4 && m <= m_max) + break; + } + + *pm = m; + *pn = n; + *pod = 1 << od; +} + +static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = { + + /* External clocks */ + + [JZ4760_CLK_EXT] = { "ext", CGU_CLK_EXT }, + [JZ4760_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT }, + + /* PLLs */ + + [JZ4760_CLK_PLL0] = { + "pll0", CGU_CLK_PLL, + .parents = { JZ4760_CLK_EXT }, + .pll = { + .reg = CGU_REG_CPPCR0, + .rate_multiplier = 1, + .m_shift = 23, + .m_bits = 8, + .m_offset = 0, + .n_shift = 18, + .n_bits = 4, + .n_offset = 0, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_reg = CGU_REG_CPPCR0, + .bypass_bit = 9, + .enable_bit = 8, + .stable_bit = 10, + .calc_m_n_od = jz4760_cgu_calc_m_n_od, + }, + }, + + [JZ4760_CLK_PLL1] = { + /* TODO: PLL1 can depend on PLL0 */ + "pll1", CGU_CLK_PLL, + .parents = { JZ4760_CLK_EXT }, + .pll = { + .reg = CGU_REG_CPPCR1, + .rate_multiplier = 1, + .m_shift = 23, + .m_bits = 8, + .m_offset = 0, + .n_shift = 18, + .n_bits = 4, + .n_offset = 0, + .od_shift = 16, + .od_bits = 2, + .od_max = 8, + .od_encoding = pll_od_encoding, + .bypass_bit = -1, + .enable_bit = 7, + .stable_bit = 6, + .calc_m_n_od = jz4760_cgu_calc_m_n_od, + }, + }, + + /* Main clocks */ + + [JZ4760_CLK_CCLK] = { + "cclk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + [JZ4760_CLK_HCLK] = { + "hclk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + [JZ4760_CLK_SCLK] = { + "sclk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + [JZ4760_CLK_H2CLK] = { + "h2clk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + [JZ4760_CLK_MCLK] = { + "mclk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + [JZ4760_CLK_PCLK] = { + "pclk", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0, }, + .div = { + CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, + jz4760_cgu_cpccr_div_table, + }, + }, + + /* Divided clocks */ + + [JZ4760_CLK_PLL0_HALF] = { + "pll0_half", CGU_CLK_DIV, + .parents = { JZ4760_CLK_PLL0 }, + .div = { + CGU_REG_CPCCR, 21, 1, 1, 22, -1, -1, 0, + jz4760_cgu_pll_half_div_table, + }, + }, + + /* Those divided clocks can connect to PLL0 or PLL1 */ + + [JZ4760_CLK_UHC] = { + "uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, }, + .mux = { CGU_REG_UHCCDR, 31, 1 }, + .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 24 }, + }, + [JZ4760_CLK_GPU] = { + "gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, }, + .mux = { CGU_REG_GPUCDR, 31, 1 }, + .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR1, 9 }, + }, + [JZ4760_CLK_LPCLK_DIV] = { + "lpclk_div", CGU_CLK_DIV | CGU_CLK_MUX, + .parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, }, + .mux = { CGU_REG_LPCDR, 29, 1 }, + .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, + }, + [JZ4760_CLK_TVE] = { + "tve", CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_EXT, }, + .mux = { CGU_REG_LPCDR, 31, 1 }, + .gate = { CGU_REG_CLKGR0, 27 }, + }, + [JZ4760_CLK_LPCLK] = { + "lpclk", CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_LPCLK_DIV, JZ4760_CLK_TVE, }, + .mux = { CGU_REG_LPCDR, 30, 1 }, + .gate = { CGU_REG_CLKGR0, 28 }, + }, + [JZ4760_CLK_GPS] = { + "gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1, }, + .mux = { CGU_REG_GPSCDR, 31, 1 }, + .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 22 }, + }, + + /* Those divided clocks can connect to EXT, PLL0 or PLL1 */ + + [JZ4760_CLK_PCM] = { + "pcm", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_EXT, -1, + JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 }, + .mux = { CGU_REG_PCMCDR, 30, 2 }, + .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1, BIT(0) }, + .gate = { CGU_REG_CLKGR1, 8 }, + }, + [JZ4760_CLK_I2S] = { + "i2s", CGU_CLK_DIV | CGU_CLK_MUX, + .parents = { JZ4760_CLK_EXT, -1, + JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 }, + .mux = { CGU_REG_I2SCDR, 30, 2 }, + .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1, BIT(0) }, + }, + [JZ4760_CLK_OTG] = { + "usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, + .parents = { JZ4760_CLK_EXT, -1, + JZ4760_CLK_PLL0_HALF, JZ4760_CLK_PLL1 }, + .mux = { CGU_REG_USBCDR, 30, 2 }, + .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 2 }, + }, + + /* Those divided clocks can connect to EXT or PLL0 */ + [JZ4760_CLK_MMC_MUX] = { + "mmc_mux", CGU_CLK_MUX | CGU_CLK_DIV, + .parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, }, + .mux = { CGU_REG_MSCCDR, 31, 1 }, + .div = { CGU_REG_MSCCDR, 0, 1, 6, -1, -1, -1, BIT(0) }, + }, + [JZ4760_CLK_SSI_MUX] = { + "ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX, + .parents = { JZ4760_CLK_EXT, JZ4760_CLK_PLL0_HALF, }, + .mux = { CGU_REG_SSICDR, 31, 1 }, + .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1, BIT(0) }, + }, + + /* These divided clock can connect to PLL0 only */ + [JZ4760_CLK_CIM] = { + "cim", CGU_CLK_DIV | CGU_CLK_GATE, + .parents = { JZ4760_CLK_PLL0_HALF }, + .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 }, + .gate = { CGU_REG_CLKGR0, 26 }, + }, + + /* Gate-only clocks */ + + [JZ4760_CLK_SSI0] = { + "ssi0", CGU_CLK_GATE, + .parents = { JZ4760_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 4 }, + }, + [JZ4760_CLK_SSI1] = { + "ssi1", CGU_CLK_GATE, + .parents = { JZ4760_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 19 }, + }, + [JZ4760_CLK_SSI2] = { + "ssi2", CGU_CLK_GATE, + .parents = { JZ4760_CLK_SSI_MUX, }, + .gate = { CGU_REG_CLKGR0, 20 }, + }, + [JZ4760_CLK_DMA] = { + "dma", CGU_CLK_GATE, + .parents = { JZ4760_CLK_H2CLK, }, + .gate = { CGU_REG_CLKGR0, 21 }, + }, + [JZ4760_CLK_I2C0] = { + "i2c0", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 5 }, + }, + [JZ4760_CLK_I2C1] = { + "i2c1", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 6 }, + }, + [JZ4760_CLK_UART0] = { + "uart0", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 15 }, + }, + [JZ4760_CLK_UART1] = { + "uart1", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 16 }, + }, + [JZ4760_CLK_UART2] = { + "uart2", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 17 }, + }, + [JZ4760_CLK_UART3] = { + "uart3", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 18 }, + }, + [JZ4760_CLK_IPU] = { + "ipu", CGU_CLK_GATE, + .parents = { JZ4760_CLK_HCLK, }, + .gate = { CGU_REG_CLKGR0, 29 }, + }, + [JZ4760_CLK_ADC] = { + "adc", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 14 }, + }, + [JZ4760_CLK_AIC] = { + "aic", CGU_CLK_GATE, + .parents = { JZ4760_CLK_EXT, }, + .gate = { CGU_REG_CLKGR0, 8 }, + }, + [JZ4760_CLK_VPU] = { + "vpu", CGU_CLK_GATE, + .parents = { JZ4760_CLK_HCLK, }, + .gate = { CGU_REG_LCR, 30, false, 150 }, + }, + [JZ4760_CLK_MMC0] = { + "mmc0", CGU_CLK_GATE, + .parents = { JZ4760_CLK_MMC_MUX, }, + .gate = { CGU_REG_CLKGR0, 3 }, + }, + [JZ4760_CLK_MMC1] = { + "mmc1", CGU_CLK_GATE, + .parents = { JZ4760_CLK_MMC_MUX, }, + .gate = { CGU_REG_CLKGR0, 11 }, + }, + [JZ4760_CLK_MMC2] = { + "mmc2", CGU_CLK_GATE, + .parents = { JZ4760_CLK_MMC_MUX, }, + .gate = { CGU_REG_CLKGR0, 12 }, + }, + [JZ4760_CLK_UHC_PHY] = { + "uhc_phy", CGU_CLK_GATE, + .parents = { JZ4760_CLK_UHC, }, + .gate = { CGU_REG_OPCR, 5 }, + }, + [JZ4760_CLK_OTG_PHY] = { + "usb_phy", CGU_CLK_GATE, + .parents = { JZ4760_CLK_OTG }, + .gate = { CGU_REG_OPCR, 7, true, 50 }, + }, + + /* Custom clocks */ + [JZ4760_CLK_EXT512] = { + "ext/512", CGU_CLK_FIXDIV, + .parents = { JZ4760_CLK_EXT }, + .fixdiv = { 512 }, + }, + [JZ4760_CLK_RTC] = { + "rtc", CGU_CLK_MUX, + .parents = { JZ4760_CLK_EXT512, JZ4760_CLK_OSC32K, }, + .mux = { CGU_REG_OPCR, 2, 1}, + }, +}; + +static void __init jz4760_cgu_init(struct device_node *np) +{ + struct ingenic_cgu *cgu; + int retval; + + cgu = ingenic_cgu_new(jz4760_cgu_clocks, + ARRAY_SIZE(jz4760_cgu_clocks), np); + if (!cgu) { + pr_err("%s: failed to initialise CGU\n", __func__); + return; + } + + retval = ingenic_cgu_register_clocks(cgu); + if (retval) + pr_err("%s: failed to register CGU Clocks\n", __func__); + + ingenic_cgu_register_syscore_ops(cgu); +} + +/* We only probe via devicetree, no need for a platform driver */ +CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-cgu", jz4760_cgu_init); + +/* JZ4760B has some small differences, but we don't implement them. */ +CLK_OF_DECLARE_DRIVER(jz4760b_cgu, "ingenic,jz4760b-cgu", jz4760_cgu_init); diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index 9ea4490ecb7f..2321742b3471 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -139,8 +139,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { .od_bits = 2, .od_max = 8, .od_encoding = pll_od_encoding, - .bypass_reg = CGU_REG_CPPCR1, - .no_bypass_bit = true, + .bypass_bit = -1, .enable_bit = 7, .stable_bit = 6, }, @@ -152,7 +151,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "cclk", CGU_CLK_DIV, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, }, @@ -160,7 +159,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "h0clk", CGU_CLK_DIV, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, }, @@ -168,7 +167,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, .gate = { CGU_REG_CLKGR1, 7 }, @@ -177,7 +176,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "h2clk", CGU_CLK_DIV, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, }, @@ -185,7 +184,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle @@ -194,7 +193,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "pclk", CGU_CLK_DIV, .parents = { JZ4770_CLK_PLL0, }, .div = { - CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, + CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, jz4770_cgu_cpccr_div_table, }, }, diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index 9382dc3aa27e..77acfbeb4830 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -326,6 +326,7 @@ static const struct ingenic_soc_info x1000_soc_info = { static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = { { .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, }, { .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, }, + { .compatible = "ingenic,jz4760-tcu", .data = &jz4770_soc_info, }, { .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, }, { .compatible = "ingenic,x1000-tcu", .data = &x1000_soc_info, }, { /* sentinel */ } @@ -477,5 +478,6 @@ static void __init ingenic_tcu_init(struct device_node *np) CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init); CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init); +CLK_OF_DECLARE_DRIVER(jz4760_cgu, "ingenic,jz4760-tcu", ingenic_tcu_init); CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init); CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-tcu", ingenic_tcu_init); diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c index 5b3d36462174..aae1a4076281 100644 --- a/drivers/clk/keystone/syscon-clk.c +++ b/drivers/clk/keystone/syscon-clk.c @@ -149,11 +149,28 @@ static const struct ti_syscon_gate_clk_data am654_clk_data[] = { { /* Sentinel */ }, }; +static const struct ti_syscon_gate_clk_data am64_clk_data[] = { + TI_SYSCON_CLK_GATE("epwm_tbclk0", 0x0, 0), + TI_SYSCON_CLK_GATE("epwm_tbclk1", 0x0, 1), + TI_SYSCON_CLK_GATE("epwm_tbclk2", 0x0, 2), + TI_SYSCON_CLK_GATE("epwm_tbclk3", 0x0, 3), + TI_SYSCON_CLK_GATE("epwm_tbclk4", 0x0, 4), + TI_SYSCON_CLK_GATE("epwm_tbclk5", 0x0, 5), + TI_SYSCON_CLK_GATE("epwm_tbclk6", 0x0, 6), + TI_SYSCON_CLK_GATE("epwm_tbclk7", 0x0, 7), + TI_SYSCON_CLK_GATE("epwm_tbclk8", 0x0, 8), + { /* Sentinel */ }, +}; + static const struct of_device_id ti_syscon_gate_clk_ids[] = { { .compatible = "ti,am654-ehrpwm-tbclk", .data = &am654_clk_data, }, + { + .compatible = "ti,am64-epwm-tbclk", + .data = &am64_clk_data, + }, { } }; MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids); diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c index 7c8d02164443..bfe36bd41339 100644 --- a/drivers/clk/meson/axg-audio.c +++ b/drivers/clk/meson/axg-audio.c @@ -1665,8 +1665,7 @@ static int devm_clk_get_enable(struct device *dev, char *id) clk = devm_clk_get(dev, id); if (IS_ERR(clk)) { ret = PTR_ERR(clk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "failed to get %s", id); + dev_err_probe(dev, ret, "failed to get %s", id); return ret; } @@ -1811,7 +1810,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev) ret = device_reset(dev); if (ret) { - dev_err(dev, "failed to reset device\n"); + dev_err_probe(dev, ret, "failed to reset device\n"); return ret; } diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c index 49f27fe53213..9e55617bc3b4 100644 --- a/drivers/clk/meson/clk-pll.c +++ b/drivers/clk/meson/clk-pll.c @@ -242,8 +242,8 @@ static int meson_clk_get_pll_settings(unsigned long rate, return best ? 0 : -EINVAL; } -static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int meson_clk_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct clk_regmap *clk = to_clk_regmap(hw); struct meson_clk_pll_data *pll = meson_clk_pll_data(clk); @@ -251,22 +251,26 @@ static long meson_clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long round; int ret; - ret = meson_clk_get_pll_settings(rate, *parent_rate, &m, &n, pll); + ret = meson_clk_get_pll_settings(req->rate, req->best_parent_rate, + &m, &n, pll); if (ret) - return meson_clk_pll_recalc_rate(hw, *parent_rate); + return ret; - round = __pll_params_to_rate(*parent_rate, m, n, 0, pll); + round = __pll_params_to_rate(req->best_parent_rate, m, n, 0, pll); - if (!MESON_PARM_APPLICABLE(&pll->frac) || rate == round) - return round; + if (!MESON_PARM_APPLICABLE(&pll->frac) || req->rate == round) { + req->rate = round; + return 0; + } /* * The rate provided by the setting is not an exact match, let's * try to improve the result using the fractional parameter */ - frac = __pll_params_with_frac(rate, *parent_rate, m, n, pll); + frac = __pll_params_with_frac(req->rate, req->best_parent_rate, m, n, pll); + req->rate = __pll_params_to_rate(req->best_parent_rate, m, n, frac, pll); - return __pll_params_to_rate(*parent_rate, m, n, frac, pll); + return 0; } static int meson_clk_pll_wait_lock(struct clk_hw *hw) @@ -419,7 +423,7 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, */ const struct clk_ops meson_clk_pcie_pll_ops = { .recalc_rate = meson_clk_pll_recalc_rate, - .round_rate = meson_clk_pll_round_rate, + .determine_rate = meson_clk_pll_determine_rate, .is_enabled = meson_clk_pll_is_enabled, .enable = meson_clk_pcie_pll_enable, .disable = meson_clk_pll_disable @@ -429,7 +433,7 @@ EXPORT_SYMBOL_GPL(meson_clk_pcie_pll_ops); const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, .recalc_rate = meson_clk_pll_recalc_rate, - .round_rate = meson_clk_pll_round_rate, + .determine_rate = meson_clk_pll_determine_rate, .set_rate = meson_clk_pll_set_rate, .is_enabled = meson_clk_pll_is_enabled, .enable = meson_clk_pll_enable, diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index b080359b4645..310accf94830 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = { }; static const struct pll_mult_range g12a_gp0_pll_mult_range = { - .min = 55, + .min = 125, .max = 255, }; @@ -4723,6 +4723,12 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = { [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, + [CLKID_NNA_AXI_CLK_SEL] = &sm1_nna_axi_clk_sel.hw, + [CLKID_NNA_AXI_CLK_DIV] = &sm1_nna_axi_clk_div.hw, + [CLKID_NNA_AXI_CLK] = &sm1_nna_axi_clk.hw, + [CLKID_NNA_CORE_CLK_SEL] = &sm1_nna_core_clk_sel.hw, + [CLKID_NNA_CORE_CLK_DIV] = &sm1_nna_core_clk_div.hw, + [CLKID_NNA_CORE_CLK] = &sm1_nna_core_clk.hw, [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw, [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw, [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw, diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index 45646b867cdb..62e00e15495c 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -210,6 +210,13 @@ config MSM_LCC_8960 Say Y if you want to use audio devices such as i2s, pcm, SLIMBus, etc. +config MDM_GCC_9607 + tristate "MDM9607 Global Clock Controller" + help + Support for the global clock controller on mdm9607 devices. + Say Y if you want to use peripheral devices such as UART, SPI, + I2C, USB, SD/eMMC, etc. + config MDM_GCC_9615 tristate "MDM9615 Global Clock Controller" help @@ -483,6 +490,13 @@ config SDX_GCC_55 Say Y if you want to use peripheral devices such as UART, SPI, I2C, USB, SD/UFS, PCIe etc. +config SM_CAMCC_8250 + tristate "SM8250 Camera Clock Controller" + select SM_GCC_8250 + help + Support for the camera clock controller on SM8250 devices. + Say Y if you want to support camera devices and camera functionality. + config SM_DISPCC_8250 tristate "SM8150 and SM8250 Display Clock Controller" depends on SM_GCC_8150 || SM_GCC_8250 @@ -492,6 +506,13 @@ config SM_DISPCC_8250 Say Y if you want to support display devices and functionality such as splash screen. +config SM_GCC_6125 + tristate "SM6125 Global Clock Controller" + help + Support for the global clock controller on SM6125 devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + config SM_GCC_8150 tristate "SM8150 Global Clock Controller" help diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index c8291312e723..c2a1cafb31bc 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o +obj-$(CONFIG_MDM_GCC_9607) += gcc-mdm9607.o obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o @@ -73,7 +74,9 @@ obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o +obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o +obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o diff --git a/drivers/clk/qcom/apcs-sdx55.c b/drivers/clk/qcom/apcs-sdx55.c index d0edabebf9c2..e599f862ec44 100644 --- a/drivers/clk/qcom/apcs-sdx55.c +++ b/drivers/clk/qcom/apcs-sdx55.c @@ -57,7 +57,7 @@ static int qcom_apcs_sdx55_clk_probe(struct platform_device *pdev) regmap = dev_get_regmap(parent, NULL); if (!regmap) { - dev_err_probe(dev, -ENODEV, "Failed to get parent regmap\n"); + dev_err(dev, "Failed to get parent regmap\n"); return -ENODEV; } @@ -80,19 +80,15 @@ static int qcom_apcs_sdx55_clk_probe(struct platform_device *pdev) a7cc->parent_map = apcs_mux_clk_parent_map; a7cc->pclk = devm_clk_get(parent, "pll"); - if (IS_ERR(a7cc->pclk)) { - ret = PTR_ERR(a7cc->pclk); - if (ret != -EPROBE_DEFER) - dev_err_probe(dev, ret, "Failed to get PLL clk\n"); - return ret; - } + if (IS_ERR(a7cc->pclk)) + return dev_err_probe(dev, PTR_ERR(a7cc->pclk), + "Failed to get PLL clk\n"); a7cc->clk_nb.notifier_call = a7cc_notifier_cb; ret = clk_notifier_register(a7cc->pclk, &a7cc->clk_nb); - if (ret) { - dev_err_probe(dev, ret, "Failed to register clock notifier\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "Failed to register clock notifier\n"); ret = devm_clk_register_regmap(dev, &a7cc->clkr); if (ret) { diff --git a/drivers/clk/qcom/camcc-sm8250.c b/drivers/clk/qcom/camcc-sm8250.c new file mode 100644 index 000000000000..439eaafdcc86 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm8250.c @@ -0,0 +1,2456 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/clk-provider.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,camcc-sm8250.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EARLY, + P_CAM_CC_PLL2_OUT_MAIN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_SLEEP_CLK, +}; + +static struct pll_vco lucid_vco[] = { + { 249600000, 2000000000, 0 }, +}; + +static struct pll_vco zonda_vco[] = { + { 595200000UL, 3600000000UL, 0 }, +}; + +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A699c, + .user_ctl_val = 0x00003100, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 8, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x3, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 12, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x1f, + .alpha = 0x4000, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A699c, + .user_ctl_val = 0x00000100, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 8, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x4b, + .alpha = 0x0, + .config_ctl_val = 0x08200920, + .config_ctl_hi_val = 0x05002015, + .config_ctl_hi1_val = 0x00000000, + .user_ctl_val = 0x00000100, + .user_ctl_hi_val = 0x00000000, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .vco_table = zonda_vco, + .num_vco = ARRAY_SIZE(zonda_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_zonda_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll2_out_main[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_main = { + .offset = 0x2000, + .post_div_shift = 8, + .post_div_table = post_div_table_cam_cc_pll2_out_main, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_main), + .width = 2, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll2_out_main", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_zonda_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x24, + .alpha = 0x7555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A699c, + .user_ctl_val = 0x00000100, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 8, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x24, + .alpha = 0x7555, + .config_ctl_val = 0x20485699, + .config_ctl_hi_val = 0x00002261, + .config_ctl_hi1_val = 0x329A699c, + .user_ctl_val = 0x00000100, + .user_ctl_hi_val = 0x00000805, + .user_ctl_hi1_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .vco_table = lucid_vco, + .num_vco = ARRAY_SIZE(lucid_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr = { + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_lucid_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 8, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_lucid_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL2_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll2_out_main.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EARLY, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll2.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .fw_name = "bi_tcxo" }, +}; + +static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_MAIN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_bps_clk_src = { + .cmd_rcgr = 0x7010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_axi_clk_src = { + .cmd_rcgr = 0xc0f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_axi_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0xc0bc, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0xc0d8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0xa068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x6000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x6020, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x6040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x6060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x6080, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .cmd_rcgr = 0x60a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi5phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(50000000, P_CAM_CC_PLL0_OUT_EVEN, 12, 0, 0), + F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x703c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fd_core_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_MAIN, 1.5, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fd_core_clk_src = { + .cmd_rcgr = 0xc098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_icp_clk_src = { + .cmd_rcgr = 0xc074, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fd_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(350000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(576000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(680000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_clk_src = { + .cmd_rcgr = 0xa010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ife_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_regmap_div cam_cc_sbi_div_clk_src = { + .reg = 0x9010, + .shift = 0, + .width = 3, + .clkr.hw.init = &(struct clk_init_data) { + .name = "cam_cc_sbi_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(75000000, P_CAM_CC_PLL0_OUT_EVEN, 8, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = { + .cmd_rcgr = 0xa040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_1_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(350000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(576000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(680000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_1_clk_src = { + .cmd_rcgr = 0xb010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ife_1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = { + .cmd_rcgr = 0xb040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ife_lite_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL2_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0xc000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_ife_lite_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0xc01c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(300000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(525000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(700000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_0_clk_src = { + .cmd_rcgr = 0x8010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ipe_0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0xc048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_bps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_CC_PLL2_OUT_EARLY, 10, 1, 6), + F(68571429, P_CAM_CC_PLL2_OUT_EARLY, 1, 1, 21), + { } +}; + +static struct clk_rcg2 cam_cc_mclk0_clk_src = { + .cmd_rcgr = 0x5000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk1_clk_src = { + .cmd_rcgr = 0x501c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk2_clk_src = { + .cmd_rcgr = 0x5038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk3_clk_src = { + .cmd_rcgr = 0x5054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk4_clk_src = { + .cmd_rcgr = 0x5070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk4_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk5_clk_src = { + .cmd_rcgr = 0x508c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk5_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_mclk6_clk_src = { + .cmd_rcgr = 0x50a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk6_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 cam_cc_sbi_csid_clk_src = { + .cmd_rcgr = 0x901c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = { + F(32768, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sleep_clk_src = { + .cmd_rcgr = 0xc170, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_sleep_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_sleep_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x7058, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0xc154, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch cam_cc_bps_ahb_clk = { + .halt_reg = 0x7070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7070, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_areg_clk = { + .halt_reg = 0x7054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_areg_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_axi_clk = { + .halt_reg = 0x7038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_bps_clk = { + .halt_reg = 0x7028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x7028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_bps_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_bps_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_axi_clk = { + .halt_reg = 0xc114, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc114, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0xc11c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc11c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_xo_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0xc0d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cci_0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0xc0f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cci_1_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0xc150, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0xc150, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cpas_ahb_clk = { + .halt_reg = 0xc0f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0f4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_cpas_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x6018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi0phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x6038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi1phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x6058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi2phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x6078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi3phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x6098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x6098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi4phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi5phytimer_clk = { + .halt_reg = 0x60b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x60b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_csi5phytimer_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x601c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x601c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x603c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x603c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x605c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x605c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x607c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x607c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x609c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x609c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy5_clk = { + .halt_reg = 0x60bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x60bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_csiphy5_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_clk = { + .halt_reg = 0xc0b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fd_core_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_fd_core_uar_clk = { + .halt_reg = 0xc0b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc0b8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_fd_core_uar_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fd_core_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_gdsc_clk = { + .halt_reg = 0xc16c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc16c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_gdsc_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_xo_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_ahb_clk = { + .halt_reg = 0xc094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_clk = { + .halt_reg = 0xc08c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc08c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_icp_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_icp_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_ahb_clk = { + .halt_reg = 0xa088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_areg_clk = { + .halt_reg = 0xa030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_areg_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_axi_clk = { + .halt_reg = 0xa084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_cphy_rx_clk = { + .halt_reg = 0xa080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_csid_clk = { + .halt_reg = 0xa058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_csid_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_csid_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_0_dsp_clk = { + .halt_reg = 0xa03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_0_dsp_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_ahb_clk = { + .halt_reg = 0xb068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_areg_clk = { + .halt_reg = 0xb030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_areg_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_axi_clk = { + .halt_reg = 0xb064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb064, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_clk = { + .halt_reg = 0xb028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_cphy_rx_clk = { + .halt_reg = 0xb060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_csid_clk = { + .halt_reg = 0xb058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_csid_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_csid_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_1_dsp_clk = { + .halt_reg = 0xb03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xb03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_1_dsp_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0xc040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_axi_clk = { + .halt_reg = 0xc044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0xc018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_lite_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0xc03c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc03c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0xc034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_lite_csid_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_ahb_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_areg_clk = { + .halt_reg = 0x803c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x803c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_areg_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_fast_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_axi_clk = { + .halt_reg = 0x8038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_0_clk = { + .halt_reg = 0x8028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_ipe_0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ipe_0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0xc060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_jpeg_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk0_clk = { + .halt_reg = 0x5018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk1_clk = { + .halt_reg = 0x5034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk1_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk2_clk = { + .halt_reg = 0x5050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk2_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk3_clk = { + .halt_reg = 0x506c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x506c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk3_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk4_clk = { + .halt_reg = 0x5088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk4_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk5_clk = { + .halt_reg = 0x50a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk5_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_mclk6_clk = { + .halt_reg = 0x50c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_mclk6_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_ahb_clk = { + .halt_reg = 0x9040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_slow_ahb_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_axi_clk = { + .halt_reg = 0x903c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x903c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_camnoc_axi_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_clk = { + .halt_reg = 0x9014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_sbi_div_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_cphy_rx_clk = { + .halt_reg = 0x9038, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9038, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_cphy_rx_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_csid_clk = { + .halt_reg = 0x9034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_csid_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_sbi_csid_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_ife_0_clk = { + .halt_reg = 0x9044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_ife_0_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_0_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sbi_ife_1_clk = { + .halt_reg = 0x9048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sbi_ife_1_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_ife_1_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_sleep_clk = { + .halt_reg = 0xc188, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xc188, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "cam_cc_sleep_clk", + .parent_hws = (const struct clk_hw*[]){ + &cam_cc_sleep_clk_src.clkr.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc bps_gdsc = { + .gdscr = 0x7004, + .pd = { + .name = "bps_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ipe_0_gdsc = { + .gdscr = 0x8004, + .pd = { + .name = "ipe_0_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc sbi_gdsc = { + .gdscr = 0x9004, + .pd = { + .name = "sbi_gdsc", + }, + .flags = HW_CTRL | POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_0_gdsc = { + .gdscr = 0xa004, + .pd = { + .name = "ife_0_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ife_1_gdsc = { + .gdscr = 0xb004, + .pd = { + .name = "ife_1_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc titan_top_gdsc = { + .gdscr = 0xc144, + .pd = { + .name = "titan_top_gdsc", + }, + .flags = POLL_CFG_GDSCR, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct clk_regmap *cam_cc_sm8250_clocks[] = { + [CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr, + [CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr, + [CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr, + [CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr, + [CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr, + [CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr, + [CAM_CC_CAMNOC_AXI_CLK_SRC] = &cam_cc_camnoc_axi_clk_src.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_FD_CORE_CLK] = &cam_cc_fd_core_clk.clkr, + [CAM_CC_FD_CORE_CLK_SRC] = &cam_cc_fd_core_clk_src.clkr, + [CAM_CC_FD_CORE_UAR_CLK] = &cam_cc_fd_core_uar_clk.clkr, + [CAM_CC_GDSC_CLK] = &cam_cc_gdsc_clk.clkr, + [CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr, + [CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr, + [CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr, + [CAM_CC_IFE_0_AHB_CLK] = &cam_cc_ife_0_ahb_clk.clkr, + [CAM_CC_IFE_0_AREG_CLK] = &cam_cc_ife_0_areg_clk.clkr, + [CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.clkr, + [CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr, + [CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr, + [CAM_CC_IFE_0_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr, + [CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr, + [CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr, + [CAM_CC_IFE_1_AHB_CLK] = &cam_cc_ife_1_ahb_clk.clkr, + [CAM_CC_IFE_1_AREG_CLK] = &cam_cc_ife_1_areg_clk.clkr, + [CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_clk.clkr, + [CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr, + [CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr, + [CAM_CC_IFE_1_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr, + [CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr, + [CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_AXI_CLK] = &cam_cc_ife_lite_axi_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr, + [CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr, + [CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr, + [CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr, + [CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr, + [CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr, + [CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr, + [CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr, + [CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr, + [CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr, + [CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr, + [CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr, + [CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr, + [CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr, + [CAM_CC_MCLK5_CLK] = &cam_cc_mclk5_clk.clkr, + [CAM_CC_MCLK5_CLK_SRC] = &cam_cc_mclk5_clk_src.clkr, + [CAM_CC_MCLK6_CLK] = &cam_cc_mclk6_clk.clkr, + [CAM_CC_MCLK6_CLK_SRC] = &cam_cc_mclk6_clk_src.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_MAIN] = &cam_cc_pll2_out_main.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_SBI_AHB_CLK] = &cam_cc_sbi_ahb_clk.clkr, + [CAM_CC_SBI_AXI_CLK] = &cam_cc_sbi_axi_clk.clkr, + [CAM_CC_SBI_CLK] = &cam_cc_sbi_clk.clkr, + [CAM_CC_SBI_CPHY_RX_CLK] = &cam_cc_sbi_cphy_rx_clk.clkr, + [CAM_CC_SBI_CSID_CLK] = &cam_cc_sbi_csid_clk.clkr, + [CAM_CC_SBI_CSID_CLK_SRC] = &cam_cc_sbi_csid_clk_src.clkr, + [CAM_CC_SBI_DIV_CLK_SRC] = &cam_cc_sbi_div_clk_src.clkr, + [CAM_CC_SBI_IFE_0_CLK] = &cam_cc_sbi_ife_0_clk.clkr, + [CAM_CC_SBI_IFE_1_CLK] = &cam_cc_sbi_ife_1_clk.clkr, + [CAM_CC_SLEEP_CLK] = &cam_cc_sleep_clk.clkr, + [CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_sm8250_gdscs[] = { + [BPS_GDSC] = &bps_gdsc, + [IPE_0_GDSC] = &ipe_0_gdsc, + [SBI_GDSC] = &sbi_gdsc, + [IFE_0_GDSC] = &ife_0_gdsc, + [IFE_1_GDSC] = &ife_1_gdsc, + [TITAN_TOP_GDSC] = &titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_sm8250_resets[] = { + [CAM_CC_BPS_BCR] = { 0x7000 }, + [CAM_CC_ICP_BCR] = { 0xc070 }, + [CAM_CC_IFE_0_BCR] = { 0xa000 }, + [CAM_CC_IFE_1_BCR] = { 0xb000 }, + [CAM_CC_IPE_0_BCR] = { 0x8000 }, + [CAM_CC_SBI_BCR] = { 0x9000 }, +}; + +static const struct regmap_config cam_cc_sm8250_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xe004, + .fast_io = true, +}; + +static const struct qcom_cc_desc cam_cc_sm8250_desc = { + .config = &cam_cc_sm8250_regmap_config, + .clks = cam_cc_sm8250_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sm8250_clocks), + .resets = cam_cc_sm8250_resets, + .num_resets = ARRAY_SIZE(cam_cc_sm8250_resets), + .gdscs = cam_cc_sm8250_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sm8250_gdscs), +}; + +static const struct of_device_id cam_cc_sm8250_match_table[] = { + { .compatible = "qcom,sm8250-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sm8250_match_table); + +static int cam_cc_sm8250_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &cam_cc_sm8250_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + clk_lucid_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config); + clk_lucid_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config); + clk_zonda_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config); + clk_lucid_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config); + clk_lucid_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config); + + return qcom_cc_really_probe(pdev, &cam_cc_sm8250_desc, regmap); +} + +static struct platform_driver cam_cc_sm8250_driver = { + .probe = cam_cc_sm8250_probe, + .driver = { + .name = "cam_cc-sm8250", + .of_match_table = cam_cc_sm8250_match_table, + }, +}; + +static int __init cam_cc_sm8250_init(void) +{ + return platform_driver_register(&cam_cc_sm8250_driver); +} +subsys_initcall(cam_cc_sm8250_init); + +static void __exit cam_cc_sm8250_exit(void) +{ + platform_driver_unregister(&cam_cc_sm8250_driver); +} +module_exit(cam_cc_sm8250_exit); + +MODULE_DESCRIPTION("QTI CAMCC SM8250 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index c6eb99169ddc..eaedcceb766f 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -126,6 +126,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL_U] = 0x1c, [PLL_OFF_STATUS] = 0x2c, }, + [CLK_ALPHA_PLL_TYPE_ZONDA] = { + [PLL_OFF_L_VAL] = 0x04, + [PLL_OFF_ALPHA_VAL] = 0x08, + [PLL_OFF_USER_CTL] = 0x0c, + [PLL_OFF_CONFIG_CTL] = 0x10, + [PLL_OFF_CONFIG_CTL_U] = 0x14, + [PLL_OFF_CONFIG_CTL_U1] = 0x18, + [PLL_OFF_TEST_CTL] = 0x1c, + [PLL_OFF_TEST_CTL_U] = 0x20, + [PLL_OFF_TEST_CTL_U1] = 0x24, + [PLL_OFF_OPMODE] = 0x28, + [PLL_OFF_STATUS] = 0x38, + }, }; EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); @@ -162,6 +175,11 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs); #define LUCID_5LPE_PLL_LATCH_INPUT BIT(14) #define LUCID_5LPE_ENABLE_VOTE_RUN BIT(21) +/* ZONDA PLL specific */ +#define ZONDA_PLL_OUT_MASK 0xf +#define ZONDA_STAY_IN_CFA BIT(16) +#define ZONDA_PLL_FREQ_LOCK_DET BIT(29) + #define pll_alpha_width(p) \ ((PLL_ALPHA_VAL_U(p) - PLL_ALPHA_VAL(p) == 4) ? \ ALPHA_REG_BITWIDTH : ALPHA_REG_16BIT_WIDTH) @@ -208,6 +226,9 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse, #define wait_for_pll_enable_lock(pll) \ wait_for_pll(pll, PLL_LOCK_DET, 0, "enable") +#define wait_for_zonda_pll_freq_lock(pll) \ + wait_for_pll(pll, ZONDA_PLL_FREQ_LOCK_DET, 0, "freq enable") + #define wait_for_pll_disable(pll) \ wait_for_pll(pll, PLL_ACTIVE_FLAG, 1, "disable") @@ -1234,7 +1255,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) return ret; /* Setup PLL for calibration frequency */ - regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); + regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l); /* Bringup the PLL at calibration frequency */ ret = clk_alpha_pll_enable(hw); @@ -1777,3 +1798,156 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops = { .set_rate = clk_lucid_5lpe_pll_postdiv_set_rate, }; EXPORT_SYMBOL(clk_alpha_pll_postdiv_lucid_5lpe_ops); + +void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config) +{ + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l); + clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll), config->user_ctl_hi1_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val); + clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val); + + regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, 0); + + /* Disable PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + + /* Set operation mode to OFF */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY); + + /* Place the PLL in STANDBY mode */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); +} +EXPORT_SYMBOL_GPL(clk_zonda_pll_configure); + +static int clk_zonda_pll_enable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 val; + int ret; + + regmap_read(regmap, PLL_MODE(pll), &val); + + /* If in FSM mode, just vote for it */ + if (val & PLL_VOTE_FSM_ENA) { + ret = clk_enable_regmap(hw); + if (ret) + return ret; + return wait_for_pll_enable_active(pll); + } + + /* Get the PLL out of bypass mode */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_BYPASSNL, PLL_BYPASSNL); + + /* + * H/W requires a 1us delay between disabling the bypass and + * de-asserting the reset. + */ + udelay(1); + + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N); + + /* Set operation mode to RUN */ + regmap_write(regmap, PLL_OPMODE(pll), PLL_RUN); + + regmap_read(regmap, PLL_TEST_CTL(pll), &val); + + /* If cfa mode then poll for freq lock */ + if (val & ZONDA_STAY_IN_CFA) + ret = wait_for_zonda_pll_freq_lock(pll); + else + ret = wait_for_pll_enable_lock(pll); + if (ret) + return ret; + + /* Enable the PLL outputs */ + regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, ZONDA_PLL_OUT_MASK); + + /* Enable the global PLL outputs */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, PLL_OUTCTRL); + + return 0; +} + +static void clk_zonda_pll_disable(struct clk_hw *hw) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + struct regmap *regmap = pll->clkr.regmap; + u32 val; + + regmap_read(regmap, PLL_MODE(pll), &val); + + /* If in FSM mode, just unvote it */ + if (val & PLL_VOTE_FSM_ENA) { + clk_disable_regmap(hw); + return; + } + + /* Disable the global PLL output */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0); + + /* Disable the PLL outputs */ + regmap_update_bits(regmap, PLL_USER_CTL(pll), ZONDA_PLL_OUT_MASK, 0); + + /* Put the PLL in bypass and reset */ + regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N | PLL_BYPASSNL, 0); + + /* Place the PLL mode in OFF state */ + regmap_write(regmap, PLL_OPMODE(pll), 0x0); +} + +static int clk_zonda_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long prate) +{ + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); + unsigned long rrate; + u32 test_ctl_val; + u32 l, alpha_width = pll_alpha_width(pll); + u64 a; + int ret; + + rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); + + ret = alpha_pll_check_rate_margin(hw, rrate, rate); + if (ret < 0) + return ret; + + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); + regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); + + /* Wait before polling for the frequency latch */ + udelay(5); + + /* Read stay in cfa mode */ + regmap_read(pll->clkr.regmap, PLL_TEST_CTL(pll), &test_ctl_val); + + /* If cfa mode then poll for freq lock */ + if (test_ctl_val & ZONDA_STAY_IN_CFA) + ret = wait_for_zonda_pll_freq_lock(pll); + else + ret = wait_for_pll_enable_lock(pll); + if (ret) + return ret; + + /* Wait for PLL output to stabilize */ + udelay(100); + return 0; +} + +const struct clk_ops clk_alpha_pll_zonda_ops = { + .enable = clk_zonda_pll_enable, + .disable = clk_zonda_pll_disable, + .is_enabled = clk_trion_pll_is_enabled, + .recalc_rate = clk_trion_pll_recalc_rate, + .round_rate = clk_alpha_pll_round_rate, + .set_rate = clk_zonda_pll_set_rate, +}; +EXPORT_SYMBOL(clk_alpha_pll_zonda_ops); diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 6943e933be0f..55e4fa47912f 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -16,6 +16,7 @@ enum { CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION, CLK_ALPHA_PLL_TYPE_AGERA, + CLK_ALPHA_PLL_TYPE_ZONDA, CLK_ALPHA_PLL_TYPE_MAX, }; @@ -148,6 +149,9 @@ extern const struct clk_ops clk_alpha_pll_lucid_5lpe_ops; extern const struct clk_ops clk_alpha_pll_fixed_lucid_5lpe_ops; extern const struct clk_ops clk_alpha_pll_postdiv_lucid_5lpe_ops; +extern const struct clk_ops clk_alpha_pll_zonda_ops; +#define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops + void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, const struct alpha_pll_config *config); void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, @@ -159,6 +163,8 @@ void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, #define clk_lucid_pll_configure(pll, regmap, config) \ clk_trion_pll_configure(pll, regmap, config) +void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, + const struct alpha_pll_config *config); #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 05ff3b0d233e..e1b1b426fae4 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -357,6 +357,83 @@ static int clk_rcg2_set_floor_rate_and_parent(struct clk_hw *hw, return __clk_rcg2_set_rate(hw, rate, FLOOR); } +static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 notn_m, n, m, d, not2d, mask; + + if (!rcg->mnd_width) { + /* 50 % duty-cycle for Non-MND RCGs */ + duty->num = 1; + duty->den = 2; + return 0; + } + + regmap_read(rcg->clkr.regmap, RCG_D_OFFSET(rcg), ¬2d); + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m); + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m); + + if (!not2d && !m && !notn_m) { + /* 50 % duty-cycle always */ + duty->num = 1; + duty->den = 2; + return 0; + } + + mask = BIT(rcg->mnd_width) - 1; + + d = ~(not2d) & mask; + d = DIV_ROUND_CLOSEST(d, 2); + + n = (~(notn_m) + m) & mask; + + duty->num = d; + duty->den = n; + + return 0; +} + +static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + u32 notn_m, n, m, d, not2d, mask, duty_per; + int ret; + + /* Duty-cycle cannot be modified for non-MND RCGs */ + if (!rcg->mnd_width) + return -EINVAL; + + mask = BIT(rcg->mnd_width) - 1; + + regmap_read(rcg->clkr.regmap, RCG_N_OFFSET(rcg), ¬n_m); + regmap_read(rcg->clkr.regmap, RCG_M_OFFSET(rcg), &m); + + n = (~(notn_m) + m) & mask; + + duty_per = (duty->num * 100) / duty->den; + + /* Calculate 2d value */ + d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100); + + /* Check bit widths of 2d. If D is too big reduce duty cycle. */ + if (d > mask) + d = mask; + + if ((d / 2) > (n - m)) + d = (n - m) * 2; + else if ((d / 2) < (m / 2)) + d = m; + + not2d = ~d & mask; + + ret = regmap_update_bits(rcg->clkr.regmap, RCG_D_OFFSET(rcg), mask, + not2d); + if (ret) + return ret; + + return update_config(rcg); +} + const struct clk_ops clk_rcg2_ops = { .is_enabled = clk_rcg2_is_enabled, .get_parent = clk_rcg2_get_parent, @@ -365,6 +442,8 @@ const struct clk_ops clk_rcg2_ops = { .determine_rate = clk_rcg2_determine_rate, .set_rate = clk_rcg2_set_rate, .set_rate_and_parent = clk_rcg2_set_rate_and_parent, + .get_duty_cycle = clk_rcg2_get_duty_cycle, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_ops); @@ -376,6 +455,8 @@ const struct clk_ops clk_rcg2_floor_ops = { .determine_rate = clk_rcg2_determine_floor_rate, .set_rate = clk_rcg2_set_floor_rate, .set_rate_and_parent = clk_rcg2_set_floor_rate_and_parent, + .get_duty_cycle = clk_rcg2_get_duty_cycle, + .set_duty_cycle = clk_rcg2_set_duty_cycle, }; EXPORT_SYMBOL_GPL(clk_rcg2_floor_ops); diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index 0e1dfa89489e..800b2fef1887 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -39,7 +39,10 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_name, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ }; \ @@ -54,7 +57,10 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_active, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ } @@ -73,7 +79,10 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_name, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ }; \ @@ -89,7 +98,10 @@ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_active, \ - .parent_names = (const char *[]){ "xo_board" }, \ + .parent_data = &(const struct clk_parent_data){ \ + .fw_name = "xo", \ + .name = "xo_board", \ + }, \ .num_parents = 1, \ }, \ } @@ -406,7 +418,6 @@ static const struct clk_ops clk_smd_rpm_branch_ops = { .unprepare = clk_smd_rpm_unprepare, }; -/* msm8916 */ DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); @@ -452,48 +463,35 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8916 = { .num_clks = ARRAY_SIZE(msm8916_clks), }; -/* msm8936 */ -DEFINE_CLK_SMD_RPM(msm8936, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8936, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM(msm8936, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(msm8936, sysmmnoc_clk, sysmmnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM_QDSS(msm8936, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, bb_clk1, bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, bb_clk2, bb_clk2_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8936, rf_clk2, rf_clk2_a, 5); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, bb_clk1_pin, bb_clk1_a_pin, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, bb_clk2_pin, bb_clk2_a_pin, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, rf_clk1_pin, rf_clk1_a_pin, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8936, rf_clk2_pin, rf_clk2_a_pin, 5); static struct clk_smd_rpm *msm8936_clks[] = { - [RPM_SMD_PCNOC_CLK] = &msm8936_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8936_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8936_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8936_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8936_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8936_bimc_a_clk, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, [RPM_SMD_SYSMMNOC_CLK] = &msm8936_sysmmnoc_clk, [RPM_SMD_SYSMMNOC_A_CLK] = &msm8936_sysmmnoc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8936_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8936_qdss_a_clk, - [RPM_SMD_BB_CLK1] = &msm8936_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8936_bb_clk1_a, - [RPM_SMD_BB_CLK2] = &msm8936_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8936_bb_clk2_a, - [RPM_SMD_RF_CLK1] = &msm8936_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8936_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8936_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8936_rf_clk2_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8936_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8936_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2_PIN] = &msm8936_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8936_bb_clk2_a_pin, - [RPM_SMD_RF_CLK1_PIN] = &msm8936_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8936_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8936_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8936_rf_clk2_a_pin, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, }; static const struct rpm_smd_clk_desc rpm_clk_msm8936 = { @@ -501,15 +499,10 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8936 = { .num_clks = ARRAY_SIZE(msm8936_clks), }; -/* msm8974 */ -DEFINE_CLK_SMD_RPM(msm8974, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8974, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8974, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); DEFINE_CLK_SMD_RPM(msm8974, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 3); -DEFINE_CLK_SMD_RPM(msm8974, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(msm8974, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1); DEFINE_CLK_SMD_RPM(msm8974, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); -DEFINE_CLK_SMD_RPM_QDSS(msm8974, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d0, cxo_d0_a, 1); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_d1, cxo_d1_a, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8974, cxo_a0, cxo_a0_a, 4); @@ -525,22 +518,22 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6); static struct clk_smd_rpm *msm8974_clks[] = { - [RPM_SMD_PNOC_CLK] = &msm8974_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &msm8974_pnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8974_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8974_snoc_a_clk, + [RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, [RPM_SMD_GFX3D_CLK_SRC] = &msm8974_gfx3d_clk_src, [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8974_gfx3d_a_clk_src, - [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8974_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8974_qdss_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, [RPM_SMD_CXO_D0] = &msm8974_cxo_d0, [RPM_SMD_CXO_D0_A] = &msm8974_cxo_d0_a, [RPM_SMD_CXO_D1] = &msm8974_cxo_d1, @@ -574,46 +567,33 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8974 = { .num_clks = ARRAY_SIZE(msm8974_clks), }; - -/* msm8976 */ -DEFINE_CLK_SMD_RPM(msm8976, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8976, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); DEFINE_CLK_SMD_RPM(msm8976, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8976, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(msm8976, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); -DEFINE_CLK_SMD_RPM_QDSS(msm8976, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, bb_clk1, bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, bb_clk2, bb_clk2_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, rf_clk2, rf_clk2_a, 5); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8976, div_clk2, div_clk2_a, 12); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8976, bb_clk1_pin, bb_clk1_a_pin, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8976, bb_clk2_pin, bb_clk2_a_pin, 2); static struct clk_smd_rpm *msm8976_clks[] = { - [RPM_SMD_PCNOC_CLK] = &msm8976_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8976_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8976_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8976_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8976_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8976_bimc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8976_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8976_qdss_a_clk, - [RPM_SMD_BB_CLK1] = &msm8976_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8976_bb_clk1_a, - [RPM_SMD_BB_CLK2] = &msm8976_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8976_bb_clk2_a, - [RPM_SMD_RF_CLK2] = &msm8976_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8976_rf_clk2_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8976_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8976_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2_PIN] = &msm8976_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8976_bb_clk2_a_pin, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8976_mmssnoc_ahb_clk, [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8976_mmssnoc_ahb_a_clk, - [RPM_SMD_DIV_CLK2] = &msm8976_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8976_div_clk2_a, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, }; @@ -623,78 +603,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8976 = { .num_clks = ARRAY_SIZE(msm8976_clks), }; -/* msm8992 */ -DEFINE_CLK_SMD_RPM(msm8992, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8992, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8992, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8992, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8992, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1); -DEFINE_CLK_SMD_RPM(msm8992, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, bb_clk1, bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, bb_clk1_pin, bb_clk1_a_pin, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, bb_clk2, bb_clk2_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, bb_clk2_pin, bb_clk2_a_pin, 2); - -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk1, div_clk1_a, 11); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk2, div_clk2_a, 12); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, div_clk3, div_clk3_a, 13); -DEFINE_CLK_SMD_RPM(msm8992, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, ln_bb_clk, ln_bb_a_clk, 8); -DEFINE_CLK_SMD_RPM(msm8992, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, - QCOM_SMD_RPM_BUS_CLK, 3); -DEFINE_CLK_SMD_RPM_QDSS(msm8992, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, rf_clk2, rf_clk2_a, 5); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, rf_clk1_pin, rf_clk1_a_pin, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8992, rf_clk2_pin, rf_clk2_a_pin, 5); DEFINE_CLK_SMD_RPM(msm8992, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); DEFINE_CLK_SMD_RPM(msm8992, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1); static struct clk_smd_rpm *msm8992_clks[] = { - [RPM_SMD_PNOC_CLK] = &msm8992_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &msm8992_pnoc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &msm8992_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &msm8992_ocmemgx_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8992_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8992_bimc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8992_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8992_cnoc_a_clk, - [RPM_SMD_GFX3D_CLK_SRC] = &msm8992_gfx3d_clk_src, - [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8992_gfx3d_a_clk_src, - [RPM_SMD_SNOC_CLK] = &msm8992_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8992_snoc_a_clk, - [RPM_SMD_BB_CLK1] = &msm8992_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8992_bb_clk1_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8992_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8992_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2] = &msm8992_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8992_bb_clk2_a, - [RPM_SMD_BB_CLK2_PIN] = &msm8992_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8992_bb_clk2_a_pin, - [RPM_SMD_DIV_CLK1] = &msm8992_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8992_div_clk1_a, - [RPM_SMD_DIV_CLK2] = &msm8992_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8992_div_clk2_a, + [RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, + [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, + [RPM_SMD_GFX3D_CLK_SRC] = &msm8974_gfx3d_clk_src, + [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8974_gfx3d_a_clk_src, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, [RPM_SMD_DIV_CLK3] = &msm8992_div_clk3, [RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a, - [RPM_SMD_IPA_CLK] = &msm8992_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8992_ipa_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, [RPM_SMD_LN_BB_CLK] = &msm8992_ln_bb_clk, [RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk, - [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8992_mmssnoc_ahb_clk, - [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8992_mmssnoc_ahb_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8992_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8992_qdss_a_clk, - [RPM_SMD_RF_CLK1] = &msm8992_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8992_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8992_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8992_rf_clk2_a, - [RPM_SMD_RF_CLK1_PIN] = &msm8992_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8992_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8992_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8992_rf_clk2_a_pin, + [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, + [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, [RPM_SMD_CE2_CLK] = &msm8992_ce2_clk, @@ -706,83 +663,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8992 = { .num_clks = ARRAY_SIZE(msm8992_clks), }; -/* msm8994 */ -DEFINE_CLK_SMD_RPM(msm8994, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8994, ocmemgx_clk, ocmemgx_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8994, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8994, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8994, gfx3d_clk_src, gfx3d_a_clk_src, QCOM_SMD_RPM_MEM_CLK, 1); -DEFINE_CLK_SMD_RPM(msm8994, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, bb_clk1, bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, bb_clk1_pin, bb_clk1_a_pin, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, bb_clk2, bb_clk2_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, bb_clk2_pin, bb_clk2_a_pin, 2); - -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk1, div_clk1_a, 11); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk2, div_clk2_a, 12); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, div_clk3, div_clk3_a, 13); -DEFINE_CLK_SMD_RPM(msm8994, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, ln_bb_clk, ln_bb_a_clk, 8); -DEFINE_CLK_SMD_RPM(msm8994, mmssnoc_ahb_clk, mmssnoc_ahb_a_clk, - QCOM_SMD_RPM_BUS_CLK, 3); -DEFINE_CLK_SMD_RPM_QDSS(msm8994, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8994, rf_clk2, rf_clk2_a, 5); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, rf_clk1_pin, rf_clk1_a_pin, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8994, rf_clk2_pin, rf_clk2_a_pin, 5); - -DEFINE_CLK_SMD_RPM(msm8994, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8994, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1); DEFINE_CLK_SMD_RPM(msm8994, ce3_clk, ce3_a_clk, QCOM_SMD_RPM_CE_CLK, 2); static struct clk_smd_rpm *msm8994_clks[] = { - [RPM_SMD_PNOC_CLK] = &msm8994_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &msm8994_pnoc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &msm8994_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &msm8994_ocmemgx_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8994_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8994_bimc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8994_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8994_cnoc_a_clk, - [RPM_SMD_GFX3D_CLK_SRC] = &msm8994_gfx3d_clk_src, - [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8994_gfx3d_a_clk_src, - [RPM_SMD_SNOC_CLK] = &msm8994_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8994_snoc_a_clk, - [RPM_SMD_BB_CLK1] = &msm8994_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8994_bb_clk1_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8994_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8994_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2] = &msm8994_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8994_bb_clk2_a, - [RPM_SMD_BB_CLK2_PIN] = &msm8994_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8994_bb_clk2_a_pin, - [RPM_SMD_DIV_CLK1] = &msm8994_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8994_div_clk1_a, - [RPM_SMD_DIV_CLK2] = &msm8994_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8994_div_clk2_a, - [RPM_SMD_DIV_CLK3] = &msm8994_div_clk3, - [RPM_SMD_DIV_A_CLK3] = &msm8994_div_clk3_a, - [RPM_SMD_IPA_CLK] = &msm8994_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8994_ipa_a_clk, - [RPM_SMD_LN_BB_CLK] = &msm8994_ln_bb_clk, - [RPM_SMD_LN_BB_A_CLK] = &msm8994_ln_bb_a_clk, - [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8994_mmssnoc_ahb_clk, - [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8994_mmssnoc_ahb_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8994_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8994_qdss_a_clk, - [RPM_SMD_RF_CLK1] = &msm8994_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8994_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8994_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8994_rf_clk2_a, - [RPM_SMD_RF_CLK1_PIN] = &msm8994_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8994_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8994_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8994_rf_clk2_a_pin, - [RPM_SMD_CE1_CLK] = &msm8994_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8994_ce1_a_clk, - [RPM_SMD_CE2_CLK] = &msm8994_ce2_clk, - [RPM_SMD_CE2_A_CLK] = &msm8994_ce2_a_clk, + [RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, + [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, + [RPM_SMD_GFX3D_CLK_SRC] = &msm8974_gfx3d_clk_src, + [RPM_SMD_GFX3D_A_CLK_SRC] = &msm8974_gfx3d_a_clk_src, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, + [RPM_SMD_DIV_CLK3] = &msm8992_div_clk3, + [RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_LN_BB_CLK] = &msm8992_ln_bb_clk, + [RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk, + [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, + [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_CE2_CLK] = &msm8992_ce2_clk, + [RPM_SMD_CE2_A_CLK] = &msm8992_ce2_a_clk, [RPM_SMD_CE3_CLK] = &msm8994_ce3_clk, [RPM_SMD_CE3_A_CLK] = &msm8994_ce3_a_clk, }; @@ -792,79 +721,58 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8994 = { .num_clks = ARRAY_SIZE(msm8994_clks), }; -/* msm8996 */ -DEFINE_CLK_SMD_RPM(msm8996, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8996, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM(msm8996, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8996, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(msm8996, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk, QCOM_SMD_RPM_MMAXI_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8996, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8996, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre1_noc_clk, aggre1_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 1, 1000); DEFINE_CLK_SMD_RPM_BRANCH(msm8996, aggre2_noc_clk, aggre2_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 2, 1000); -DEFINE_CLK_SMD_RPM_QDSS(msm8996, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk1, bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, bb_clk2, bb_clk2_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, rf_clk2, rf_clk2_a, 5); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, ln_bb_clk, ln_bb_a_clk, 8); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk1, div_clk1_a, 0xb); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk2, div_clk2_a, 0xc); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8996, div_clk3, div_clk3_a, 0xd); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk1_pin, bb_clk1_a_pin, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5); static struct clk_smd_rpm *msm8996_clks[] = { - [RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk, [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk, - [RPM_SMD_IPA_CLK] = &msm8996_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk, - [RPM_SMD_CE1_CLK] = &msm8996_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, [RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk, [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk, [RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk, [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk, - [RPM_SMD_BB_CLK1] = &msm8996_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a, - [RPM_SMD_BB_CLK2] = &msm8996_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a, - [RPM_SMD_RF_CLK1] = &msm8996_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8996_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a, - [RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk, - [RPM_SMD_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk, - [RPM_SMD_DIV_CLK1] = &msm8996_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a, - [RPM_SMD_DIV_CLK2] = &msm8996_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a, - [RPM_SMD_DIV_CLK3] = &msm8996_div_clk3, - [RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin, - [RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, + [RPM_SMD_LN_BB_CLK] = &msm8992_ln_bb_clk, + [RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, + [RPM_SMD_DIV_CLK3] = &msm8992_div_clk3, + [RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, }; static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { @@ -872,43 +780,29 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { .num_clks = ARRAY_SIZE(msm8996_clks), }; -/* QCS404 */ -DEFINE_CLK_SMD_RPM_QDSS(qcs404, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1); - -DEFINE_CLK_SMD_RPM(qcs404, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(qcs404, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); - -DEFINE_CLK_SMD_RPM(qcs404, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); DEFINE_CLK_SMD_RPM(qcs404, bimc_gpu_clk, bimc_gpu_a_clk, QCOM_SMD_RPM_MEM_CLK, 2); - DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0); -DEFINE_CLK_SMD_RPM(qcs404, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); - -DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, rf_clk1_pin, rf_clk1_a_pin, 4); - -DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, ln_bb_clk, ln_bb_a_clk, 8); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8); static struct clk_smd_rpm *qcs404_clks[] = { - [RPM_SMD_QDSS_CLK] = &qcs404_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &qcs404_qdss_a_clk, - [RPM_SMD_PNOC_CLK] = &qcs404_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &qcs404_pnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &qcs404_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &qcs404_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &qcs404_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &qcs404_bimc_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, [RPM_SMD_BIMC_GPU_CLK] = &qcs404_bimc_gpu_clk, [RPM_SMD_BIMC_GPU_A_CLK] = &qcs404_bimc_gpu_a_clk, [RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk, [RPM_SMD_QPIC_CLK_A] = &qcs404_qpic_a_clk, - [RPM_SMD_CE1_CLK] = &qcs404_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &qcs404_ce1_a_clk, - [RPM_SMD_RF_CLK1] = &qcs404_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &qcs404_rf_clk1_a, - [RPM_SMD_LN_BB_CLK] = &qcs404_ln_bb_clk, - [RPM_SMD_LN_BB_A_CLK] = &qcs404_ln_bb_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_LN_BB_CLK] = &msm8992_ln_bb_clk, + [RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk, }; static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { @@ -916,63 +810,47 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { .num_clks = ARRAY_SIZE(qcs404_clks), }; -/* msm8998 */ -DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, div_clk1, div_clk1_a, 0xb); -DEFINE_CLK_SMD_RPM(msm8998, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk1, ln_bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk2, ln_bb_clk2_a, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin, 3); -DEFINE_CLK_SMD_RPM(msm8998, mmssnoc_axi_rpm_clk, mmssnoc_axi_rpm_a_clk, - QCOM_SMD_RPM_MMAXI_CLK, 0); DEFINE_CLK_SMD_RPM(msm8998, aggre1_noc_clk, aggre1_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 1); DEFINE_CLK_SMD_RPM(msm8998, aggre2_noc_clk, aggre2_noc_a_clk, QCOM_SMD_RPM_AGGR_CLK, 2); -DEFINE_CLK_SMD_RPM_QDSS(msm8998, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); static struct clk_smd_rpm *msm8998_clks[] = { - [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk, - [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8998_cnoc_a_clk, - [RPM_SMD_CE1_CLK] = &msm8998_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8998_ce1_a_clk, - [RPM_SMD_DIV_CLK1] = &msm8998_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8998_div_clk1_a, - [RPM_SMD_IPA_CLK] = &msm8998_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8998_ipa_a_clk, - [RPM_SMD_LN_BB_CLK1] = &msm8998_ln_bb_clk1, - [RPM_SMD_LN_BB_CLK1_A] = &msm8998_ln_bb_clk1_a, - [RPM_SMD_LN_BB_CLK2] = &msm8998_ln_bb_clk2, - [RPM_SMD_LN_BB_CLK2_A] = &msm8998_ln_bb_clk2_a, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_LN_BB_CLK1] = &msm8916_bb_clk1, + [RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a, + [RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a, [RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin, [RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin, - [RPM_SMD_MMAXI_CLK] = &msm8998_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMAXI_A_CLK] = &msm8998_mmssnoc_axi_rpm_a_clk, + [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk, + [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk, [RPM_SMD_AGGR1_NOC_CLK] = &msm8998_aggre1_noc_clk, [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8998_aggre1_noc_a_clk, [RPM_SMD_AGGR2_NOC_CLK] = &msm8998_aggre2_noc_clk, [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8998_aggre2_noc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8998_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8998_qdss_a_clk, - [RPM_SMD_RF_CLK1] = &msm8998_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8998_rf_clk1_a, - [RPM_SMD_RF_CLK2_PIN] = &msm8998_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8998_rf_clk2_a_pin, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, [RPM_SMD_RF_CLK3] = &msm8998_rf_clk3, [RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a, [RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin, @@ -984,72 +862,48 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { .num_clks = ARRAY_SIZE(msm8998_clks), }; -/* sdm660 */ DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0, 19200000); -DEFINE_CLK_SMD_RPM(sdm660, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); -DEFINE_CLK_SMD_RPM(sdm660, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); -DEFINE_CLK_SMD_RPM(sdm660, cnoc_periph_clk, cnoc_periph_a_clk, - QCOM_SMD_RPM_BUS_CLK, 0); -DEFINE_CLK_SMD_RPM(sdm660, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); -DEFINE_CLK_SMD_RPM(sdm660, mmssnoc_axi_clk, mmssnoc_axi_a_clk, - QCOM_SMD_RPM_MMAXI_CLK, 0); -DEFINE_CLK_SMD_RPM(sdm660, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); -DEFINE_CLK_SMD_RPM(sdm660, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); -DEFINE_CLK_SMD_RPM(sdm660, aggre2_noc_clk, aggre2_noc_a_clk, - QCOM_SMD_RPM_AGGR_CLK, 2); -DEFINE_CLK_SMD_RPM_QDSS(sdm660, qdss_clk, qdss_a_clk, - QCOM_SMD_RPM_MISC_CLK, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, rf_clk1, rf_clk1_a, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, div_clk1, div_clk1_a, 11); -DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk1, ln_bb_clk1_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk2, ln_bb_clk2_a, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3); +DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, ln_bb_clk3_pin_a, 3); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, rf_clk1_pin, rf_clk1_a_pin, 4); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk1_pin, - ln_bb_clk1_pin_a, 1); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk2_pin, - ln_bb_clk2_pin_a, 2); -DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, - ln_bb_clk3_pin_a, 3); static struct clk_smd_rpm *sdm660_clks[] = { [RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo, [RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a, - [RPM_SMD_SNOC_CLK] = &sdm660_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &sdm660_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &sdm660_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &sdm660_cnoc_a_clk, - [RPM_SMD_CNOC_PERIPH_CLK] = &sdm660_cnoc_periph_clk, - [RPM_SMD_CNOC_PERIPH_A_CLK] = &sdm660_cnoc_periph_a_clk, - [RPM_SMD_BIMC_CLK] = &sdm660_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &sdm660_bimc_a_clk, - [RPM_SMD_MMSSNOC_AXI_CLK] = &sdm660_mmssnoc_axi_clk, - [RPM_SMD_MMSSNOC_AXI_CLK_A] = &sdm660_mmssnoc_axi_a_clk, - [RPM_SMD_IPA_CLK] = &sdm660_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &sdm660_ipa_a_clk, - [RPM_SMD_CE1_CLK] = &sdm660_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &sdm660_ce1_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &sdm660_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &sdm660_aggre2_noc_a_clk, - [RPM_SMD_QDSS_CLK] = &sdm660_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &sdm660_qdss_a_clk, - [RPM_SMD_RF_CLK1] = &sdm660_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &sdm660_rf_clk1_a, - [RPM_SMD_DIV_CLK1] = &sdm660_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &sdm660_div_clk1_a, - [RPM_SMD_LN_BB_CLK] = &sdm660_ln_bb_clk1, - [RPM_SMD_LN_BB_A_CLK] = &sdm660_ln_bb_clk1_a, - [RPM_SMD_LN_BB_CLK2] = &sdm660_ln_bb_clk2, - [RPM_SMD_LN_BB_CLK2_A] = &sdm660_ln_bb_clk2_a, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, + [RPM_SMD_CNOC_PERIPH_CLK] = &msm8916_pcnoc_clk, + [RPM_SMD_CNOC_PERIPH_A_CLK] = &msm8916_pcnoc_a_clk, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, + [RPM_SMD_MMSSNOC_AXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk, + [RPM_SMD_MMSSNOC_AXI_CLK_A] = &msm8996_mmssnoc_axi_rpm_a_clk, + [RPM_SMD_IPA_CLK] = &msm8976_ipa_clk, + [RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk, + [RPM_SMD_CE1_CLK] = &msm8992_ce1_clk, + [RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk, + [RPM_SMD_AGGR2_NOC_CLK] = &msm8998_aggre2_noc_clk, + [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8998_aggre2_noc_a_clk, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, + [RPM_SMD_LN_BB_CLK] = &msm8916_bb_clk1, + [RPM_SMD_LN_BB_A_CLK] = &msm8916_bb_clk1_a, + [RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2, + [RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a, [RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3, [RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a, - [RPM_SMD_RF_CLK1_PIN] = &sdm660_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &sdm660_rf_clk1_a_pin, - [RPM_SMD_LN_BB_CLK1_PIN] = &sdm660_ln_bb_clk1_pin, - [RPM_SMD_LN_BB_CLK1_A_PIN] = &sdm660_ln_bb_clk1_pin_a, - [RPM_SMD_LN_BB_CLK2_PIN] = &sdm660_ln_bb_clk2_pin, - [RPM_SMD_LN_BB_CLK2_A_PIN] = &sdm660_ln_bb_clk2_pin_a, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, + [RPM_SMD_LN_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, + [RPM_SMD_LN_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, + [RPM_SMD_LN_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, + [RPM_SMD_LN_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, [RPM_SMD_LN_BB_CLK3_PIN] = &sdm660_ln_bb_clk3_pin, [RPM_SMD_LN_BB_CLK3_A_PIN] = &sdm660_ln_bb_clk3_pin_a, }; @@ -1060,6 +914,7 @@ static const struct rpm_smd_clk_desc rpm_clk_sdm660 = { }; static const struct of_device_id rpm_smd_clk_match_table[] = { + { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c index de09cd5c209f..601c7c0ba483 100644 --- a/drivers/clk/qcom/dispcc-sm8250.c +++ b/drivers/clk/qcom/dispcc-sm8250.c @@ -26,6 +26,8 @@ enum { P_DISP_CC_PLL1_OUT_MAIN, P_DP_PHY_PLL_LINK_CLK, P_DP_PHY_PLL_VCO_DIV_CLK, + P_EDP_PHY_PLL_LINK_CLK, + P_EDP_PHY_PLL_VCO_DIV_CLK, P_DSI0_PHY_PLL_OUT_BYTECLK, P_DSI0_PHY_PLL_OUT_DSICLK, P_DSI1_PHY_PLL_OUT_BYTECLK, @@ -134,6 +136,18 @@ static const struct clk_parent_data disp_cc_parent_data_3[] = { { .hw = &disp_cc_pll1.clkr.hw }, }; +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_EDP_PHY_PLL_LINK_CLK, 1 }, + { P_EDP_PHY_PLL_VCO_DIV_CLK, 2}, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "edp_phy_pll_link_clk" }, + { .fw_name = "edp_phy_pll_vco_div_clk" }, +}; + static const struct parent_map disp_cc_parent_map_5[] = { { P_BI_TCXO, 0 }, { P_DISP_CC_PLL0_OUT_MAIN, 1 }, @@ -158,6 +172,18 @@ static const struct clk_parent_data disp_cc_parent_data_6[] = { { .fw_name = "dsi1_phy_pll_out_dsiclk" }, }; +static const struct parent_map disp_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + /* { P_DISP_CC_PLL1_OUT_EVEN, 5 }, */ +}; + +static const struct clk_parent_data disp_cc_parent_data_7[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &disp_cc_pll1.clkr.hw }, + /* { .hw = &disp_cc_pll1_out_even.clkr.hw }, */ +}; + static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { F(19200000, P_BI_TCXO, 1, 0, 0), F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), @@ -261,7 +287,7 @@ static struct clk_rcg2 disp_cc_mdss_dp_link1_clk_src = { .name = "disp_cc_mdss_dp_link1_clk_src", .parent_data = disp_cc_parent_data_0, .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -275,7 +301,7 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { .name = "disp_cc_mdss_dp_link_clk_src", .parent_data = disp_cc_parent_data_0, .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), - .ops = &clk_rcg2_ops, + .ops = &clk_byte2_ops, }, }; @@ -318,6 +344,153 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { }, }; +static struct clk_rcg2 disp_cc_mdss_edp_aux_clk_src = { + .cmd_rcgr = 0x228c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_aux_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_gtc_clk_src = { + .cmd_rcgr = 0x22a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_gtc_clk_src", + .parent_data = disp_cc_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_link_clk_src = { + .cmd_rcgr = 0x2270, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_edp_pixel_clk_src = { + .cmd_rcgr = 0x2258, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .clkr.hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_pixel_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .ops = &clk_dp_ops, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_aux_clk = { + .halt_reg = 0x2078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_aux_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_gtc_clk = { + .halt_reg = 0x207c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x207c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_gtc_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_gtc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_link_clk = { + .halt_reg = 0x2070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2070, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_link_intf_clk = { + .halt_reg = 0x2074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_link_intf_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_edp_pixel_clk = { + .halt_reg = 0x206c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x206c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "disp_cc_mdss_edp_pixel_clk", + .parent_hws = (const struct clk_hw*[]){ + &disp_cc_mdss_edp_pixel_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { .cmd_rcgr = 0x2148, .mnd_width = 0, @@ -987,6 +1160,15 @@ static struct clk_regmap *disp_cc_sm8250_clocks[] = { [DISP_CC_MDSS_DP_PIXEL2_CLK_SRC] = &disp_cc_mdss_dp_pixel2_clk_src.clkr, [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, + [DISP_CC_MDSS_EDP_AUX_CLK] = &disp_cc_mdss_edp_aux_clk.clkr, + [DISP_CC_MDSS_EDP_AUX_CLK_SRC] = &disp_cc_mdss_edp_aux_clk_src.clkr, + [DISP_CC_MDSS_EDP_GTC_CLK] = &disp_cc_mdss_edp_gtc_clk.clkr, + [DISP_CC_MDSS_EDP_GTC_CLK_SRC] = &disp_cc_mdss_edp_gtc_clk_src.clkr, + [DISP_CC_MDSS_EDP_LINK_CLK] = &disp_cc_mdss_edp_link_clk.clkr, + [DISP_CC_MDSS_EDP_LINK_CLK_SRC] = &disp_cc_mdss_edp_link_clk_src.clkr, + [DISP_CC_MDSS_EDP_LINK_INTF_CLK] = &disp_cc_mdss_edp_link_intf_clk.clkr, + [DISP_CC_MDSS_EDP_PIXEL_CLK] = &disp_cc_mdss_edp_pixel_clk.clkr, + [DISP_CC_MDSS_EDP_PIXEL_CLK_SRC] = &disp_cc_mdss_edp_pixel_clk_src.clkr, [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, @@ -1037,6 +1219,7 @@ static const struct qcom_cc_desc disp_cc_sm8250_desc = { }; static const struct of_device_id disp_cc_sm8250_match_table[] = { + { .compatible = "qcom,sc8180x-dispcc" }, { .compatible = "qcom,sm8150-dispcc" }, { .compatible = "qcom,sm8250-dispcc" }, { } @@ -1053,7 +1236,8 @@ static int disp_cc_sm8250_probe(struct platform_device *pdev) /* note: trion == lucid, except for the prepare() op */ BUILD_BUG_ON(CLK_ALPHA_PLL_TYPE_TRION != CLK_ALPHA_PLL_TYPE_LUCID); - if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8150-dispcc")) { + if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8180x-dispcc") || + of_device_is_compatible(pdev->dev.of_node, "qcom,sm8150-dispcc")) { disp_cc_pll0_config.config_ctl_hi_val = 0x00002267; disp_cc_pll0_config.config_ctl_hi1_val = 0x00000024; disp_cc_pll0_config.user_ctl_hi1_val = 0x000000D0; diff --git a/drivers/clk/qcom/gcc-mdm9607.c b/drivers/clk/qcom/gcc-mdm9607.c new file mode 100644 index 000000000000..4c9078e99bb3 --- /dev/null +++ b/drivers/clk/qcom/gcc-mdm9607.c @@ -0,0 +1,1632 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> + */ + +#include <linux/kernel.h> +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/platform_device.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-mdm9607.h> + +#include "common.h" +#include "clk-regmap.h" +#include "clk-alpha-pll.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-branch.h" +#include "reset.h" +#include "gdsc.h" + +enum { + P_XO, + P_BIMC, + P_GPLL0, + P_GPLL1, + P_GPLL2, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0_early = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data) + { + .name = "gpll0_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll0 = { + .offset = 0x21000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) + { + .name = "gpll0", + .parent_hws = (const struct clk_hw *[]){ &gpll0_early.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, +}; + +static struct clk_pll gpll1 = { + .l_reg = 0x20004, + .m_reg = 0x20008, + .n_reg = 0x2000c, + .config_reg = 0x20010, + .mode_reg = 0x20000, + .status_reg = 0x2001c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gpll1", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap gpll1_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gpll1_vote", + .parent_hws = (const struct clk_hw *[]){ &gpll1.clkr.hw }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll1_sleep_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1, 2 }, + { P_SLEEP_CLK, 6 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll1_sleep[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1_vote.hw }, + { .fw_name = "sleep_clk" }, +}; + +static struct clk_alpha_pll gpll2_early = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x45000, + .enable_mask = BIT(3), /* Yeah, apparently it's not 2 */ + .hw.init = &(struct clk_init_data) + { + .name = "gpll2_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll_postdiv gpll2 = { + .offset = 0x25000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr.hw.init = &(struct clk_init_data) + { + .name = "gpll2", + .parent_hws = (const struct clk_hw *[]){ &gpll2_early.clkr.hw }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL2, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll2.clkr.hw }, +}; + +static const struct parent_map gcc_xo_gpll0_gpll1_gpll2_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_GPLL1, 2 }, + { P_GPLL2, 3 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_gpll1_gpll2[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &gpll1_vote.hw }, + { .hw = &gpll2.clkr.hw }, +}; + +static const struct freq_tbl ftbl_apss_ahb_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 apss_ahb_clk_src = { + .cmd_rcgr = 0x46000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_apss_ahb_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_ahb_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_pll bimc_pll = { + .l_reg = 0x23004, + .m_reg = 0x23008, + .n_reg = 0x2300c, + .config_reg = 0x23010, + .mode_reg = 0x23000, + .status_reg = 0x2301c, + .status_bit = 17, + .clkr.hw.init = &(struct clk_init_data){ + .name = "bimc_pll", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_pll_ops, + }, +}; + +static struct clk_regmap bimc_pll_vote = { + .enable_reg = 0x45000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "bimc_pll_vote", + .parent_hws = (const struct clk_hw *[]){ &bimc_pll.clkr.hw }, + .num_parents = 1, + .ops = &clk_pll_vote_ops, + }, +}; + +static const struct parent_map gcc_xo_gpll0_bimc_map[] = { + { P_XO, 0 }, + { P_GPLL0, 1 }, + { P_BIMC, 2 }, +}; + +static const struct clk_parent_data gcc_xo_gpll0_bimc[] = { + { .fw_name = "xo" }, + { .hw = &gpll0.clkr.hw }, + { .hw = &bimc_pll_vote.hw }, +}; + +static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + { } +}; + +static struct clk_rcg2 pcnoc_bfdcd_clk_src = { + .cmd_rcgr = 0x27000, + .freq_tbl = ftbl_pcnoc_bfdcd_clk_src, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pcnoc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_bimc, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .ops = &clk_rcg2_ops, + .flags = CLK_IS_CRITICAL, + }, +}; + +static struct clk_rcg2 system_noc_bfdcd_clk_src = { + .cmd_rcgr = 0x26004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "system_noc_bfdcd_clk_src", + .parent_data = gcc_xo_gpll0_bimc, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_bimc), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_i2c_apps_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { + .cmd_rcgr = 0x200c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = { + F(960000, P_XO, 10, 1, 2), + F(4800000, P_XO, 4, 0, 0), + F(9600000, P_XO, 2, 0, 0), + F(16000000, P_GPLL0, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + { } +}; + +static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { + .cmd_rcgr = 0x2024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup1_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { + .cmd_rcgr = 0x3000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { + .cmd_rcgr = 0x3014, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup2_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = { + .cmd_rcgr = 0x4000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = { + .cmd_rcgr = 0x4024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup3_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = { + .cmd_rcgr = 0x5000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = { + .cmd_rcgr = 0x5024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup4_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = { + .cmd_rcgr = 0x6000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = { + .cmd_rcgr = 0x6024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup5_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = { + .cmd_rcgr = 0x7000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_i2c_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_i2c_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = { + .cmd_rcgr = 0x7024, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_qup1_6_spi_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_qup6_spi_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_blsp1_uart1_6_apps_clk[] = { + F(3686400, P_GPLL0, 1, 72, 15625), + F(7372800, P_GPLL0, 1, 144, 15625), + F(14745600, P_GPLL0, 1, 288, 15625), + F(16000000, P_GPLL0, 10, 1, 5), + F(19200000, P_XO, 1, 0, 0), + F(24000000, P_GPLL0, 1, 3, 100), + F(25000000, P_GPLL0, 16, 1, 2), + F(32000000, P_GPLL0, 1, 1, 25), + F(40000000, P_GPLL0, 1, 1, 20), + F(46400000, P_GPLL0, 1, 29, 500), + F(48000000, P_GPLL0, 1, 3, 50), + F(51200000, P_GPLL0, 1, 8, 125), + F(56000000, P_GPLL0, 1, 7, 100), + F(58982400, P_GPLL0, 1, 1152, 15625), + F(60000000, P_GPLL0, 1, 3, 40), + { } +}; + +static struct clk_rcg2 blsp1_uart1_apps_clk_src = { + .cmd_rcgr = 0x2044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart1_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart2_apps_clk_src = { + .cmd_rcgr = 0x3034, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart2_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart3_apps_clk_src = { + .cmd_rcgr = 0x4044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart3_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart4_apps_clk_src = { + .cmd_rcgr = 0x5044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart4_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart5_apps_clk_src = { + .cmd_rcgr = 0x6044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart5_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 blsp1_uart6_apps_clk_src = { + .cmd_rcgr = 0x6044, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_blsp1_uart1_6_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "blsp1_uart6_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_crypto_clk[] = { + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + { } +}; + +static struct clk_rcg2 crypto_clk_src = { + .cmd_rcgr = 0x16004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_crypto_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "crypto_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_3_clk[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gp1_clk_src = { + .cmd_rcgr = 0x8004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll1_sleep_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp1_clk_src", + .parent_data = gcc_xo_gpll0_gpll1_sleep, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp2_clk_src = { + .cmd_rcgr = 0x09004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll1_sleep_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp2_clk_src", + .parent_data = gcc_xo_gpll0_gpll1_sleep, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gp3_clk_src = { + .cmd_rcgr = 0x0a004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll1_sleep_map, + .freq_tbl = ftbl_gcc_gp1_3_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gp3_clk_src", + .parent_data = gcc_xo_gpll0_gpll1_sleep, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll1_sleep), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk[] = { + F(64000000, P_GPLL0, 12.5, 0, 0), + { } +}; + +static struct clk_rcg2 pdm2_clk_src = { + .cmd_rcgr = 0x44010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_pdm2_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "pdm2_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc_apps_clk[] = { + F(144000, P_XO, 16, 3, 25), + F(400000, P_XO, 12, 1, 4), + F(20000000, P_GPLL0, 10, 1, 4), + F(25000000, P_GPLL0, 16, 1, 2), + F(50000000, P_GPLL0, 16, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(177770000, P_GPLL0, 4.5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + { } +}; + +static struct clk_rcg2 sdcc1_apps_clk_src = { + .cmd_rcgr = 0x42004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc1_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_floor_ops, + }, +}; + +static struct clk_rcg2 sdcc2_apps_clk_src = { + .cmd_rcgr = 0x43004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_sdcc_apps_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "sdcc2_apps_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_apss_tcu_clk[] = { + F(155000000, P_GPLL2, 6, 0, 0), + F(310000000, P_GPLL2, 3, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + { } +}; + +static struct clk_rcg2 apss_tcu_clk_src = { + .cmd_rcgr = 0x1207c, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll1_gpll2_map, + .freq_tbl = ftbl_gcc_apss_tcu_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "apss_tcu_clk_src", + .parent_data = gcc_xo_gpll0_gpll1_gpll2, + .num_parents = 4, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb_hs_system_clk[] = { + F(19200000, P_XO, 1, 0, 0), + F(57140000, P_GPLL0, 14, 0, 0), + F(69565000, P_GPLL0, 11.5, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(177778000, P_GPLL0, 4.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hs_system_clk_src = { + .cmd_rcgr = 0x41010, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_gcc_usb_hs_system_clk, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hs_system_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = 2, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_hsic_clk_src[] = { + F(480000000, P_GPLL2, 1, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hsic_clk_src = { + .cmd_rcgr = 0x3d018, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_gpll2_map, + .freq_tbl = ftbl_usb_hsic_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_clk_src", + .parent_data = gcc_xo_gpll0_gpll2, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_hsic_io_cal_clk_src[] = { + F(9600000, P_XO, 2, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hsic_io_cal_clk_src = { + .cmd_rcgr = 0x3d030, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_usb_hsic_io_cal_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_io_cal_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_usb_hsic_system_clk_src[] = { + F(19200000, P_XO, 1, 0, 0), + F(57140000, P_GPLL0, 14, 0, 0), + F(133330000, P_GPLL0, 6, 0, 0), + F(177778000, P_GPLL0, 4.5, 0, 0), + { } +}; + +static struct clk_rcg2 usb_hsic_system_clk_src = { + .cmd_rcgr = 0x3d000, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_map, + .freq_tbl = ftbl_usb_hsic_system_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "usb_hsic_system_clk_src", + .parent_data = gcc_xo_gpll0, + .num_parents = ARRAY_SIZE(gcc_xo_gpll0), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_blsp1_ahb_clk = { + .halt_reg = 0x1008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_sleep_clk = { + .halt_reg = 0x1004, + .clkr = { + .enable_reg = 0x1004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_sleep_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "sleep_clk", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { + .halt_reg = 0x2008, + .clkr = { + .enable_reg = 0x2008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup1_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { + .halt_reg = 0x2004, + .clkr = { + .enable_reg = 0x2004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup1_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup1_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { + .halt_reg = 0x3010, + .clkr = { + .enable_reg = 0x3010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup2_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { + .halt_reg = 0x300c, + .clkr = { + .enable_reg = 0x300c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup2_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup2_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = { + .halt_reg = 0x4020, + .clkr = { + .enable_reg = 0x4020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup3_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = { + .halt_reg = 0x401c, + .clkr = { + .enable_reg = 0x401c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup3_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup3_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = { + .halt_reg = 0x5020, + .clkr = { + .enable_reg = 0x5020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup4_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = { + .halt_reg = 0x501c, + .clkr = { + .enable_reg = 0x501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup4_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup4_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = { + .halt_reg = 0x6020, + .clkr = { + .enable_reg = 0x6020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup5_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = { + .halt_reg = 0x601c, + .clkr = { + .enable_reg = 0x601c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup5_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup5_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = { + .halt_reg = 0x7020, + .clkr = { + .enable_reg = 0x7020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup6_i2c_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup6_i2c_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = { + .halt_reg = 0x701c, + .clkr = { + .enable_reg = 0x701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_qup6_spi_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_qup6_spi_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart1_apps_clk = { + .halt_reg = 0x203c, + .clkr = { + .enable_reg = 0x203c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart1_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart1_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart2_apps_clk = { + .halt_reg = 0x302c, + .clkr = { + .enable_reg = 0x302c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart2_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart2_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart3_apps_clk = { + .halt_reg = 0x403c, + .clkr = { + .enable_reg = 0x403c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart3_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart3_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart4_apps_clk = { + .halt_reg = 0x503c, + .clkr = { + .enable_reg = 0x503c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart4_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart4_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart5_apps_clk = { + .halt_reg = 0x603c, + .clkr = { + .enable_reg = 0x603c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart5_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart5_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_blsp1_uart6_apps_clk = { + .halt_reg = 0x703c, + .clkr = { + .enable_reg = 0x703c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_blsp1_uart6_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &blsp1_uart6_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x1300c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_ahb_clk = { + .halt_reg = 0x16024, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_axi_clk = { + .halt_reg = 0x16020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_crypto_clk = { + .halt_reg = 0x1601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_crypto_clk", + .parent_hws = (const struct clk_hw *[]){ &crypto_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x08000, + .clkr = { + .enable_reg = 0x08000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw *[]){ &gp1_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x09000, + .clkr = { + .enable_reg = 0x09000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw *[]){ &gp2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x0a000, + .clkr = { + .enable_reg = 0x0a000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw *[]){ &gp3_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_cfg_ahb_clk = { + .halt_reg = 0x49000, + .clkr = { + .enable_reg = 0x49000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_cfg_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x4400c, + .clkr = { + .enable_reg = 0x4400c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw *[]){ &pdm2_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x44004, + .clkr = { + .enable_reg = 0x44004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x13004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x4201c, + .clkr = { + .enable_reg = 0x4201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x42018, + .clkr = { + .enable_reg = 0x42018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &sdcc1_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x4301c, + .clkr = { + .enable_reg = 0x4301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x43018, + .clkr = { + .enable_reg = 0x43018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw *[]){ &sdcc2_apps_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_rcg2 bimc_ddr_clk_src = { + .cmd_rcgr = 0x32004, + .hid_width = 5, + .parent_map = gcc_xo_gpll0_bimc_map, + .clkr.hw.init = &(struct clk_init_data){ + .name = "bimc_ddr_clk_src", + .parent_data = gcc_xo_gpll0_bimc, + .num_parents = 3, + .ops = &clk_rcg2_ops, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_branch gcc_mss_q6_bimc_axi_clk = { + .halt_reg = 0x49004, + .clkr = { + .enable_reg = 0x49004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_q6_bimc_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &bimc_ddr_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_tcu_clk = { + .halt_reg = 0x12018, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_tcu_clk", + .parent_hws = (const struct clk_hw *[]){ &bimc_ddr_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_smmu_cfg_clk = { + .halt_reg = 0x12038, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_smmu_cfg_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qdss_dap_clk = { + .halt_reg = 0x29084, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qdss_dap_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "xo", + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb2a_phy_sleep_clk = { + .halt_reg = 0x4102c, + .clkr = { + .enable_reg = 0x4102c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb2a_phy_sleep_clk", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "sleep_clk", + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_phy_cfg_ahb_clk = { + .halt_reg = 0x41030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x41030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_phy_cfg_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_ahb_clk = { + .halt_reg = 0x41008, + .clkr = { + .enable_reg = 0x41008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb_hs_system_clk = { + .halt_reg = 0x41004, + .clkr = { + .enable_reg = 0x41004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb_hs_system_clk", + .parent_hws = (const struct clk_hw *[]){ &usb_hs_system_clk_src.clkr.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_ahb_clk = { + .halt_reg = 0x4601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_ahb_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apss_axi_clk = { + .halt_reg = 0x4601c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x45004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apss_axi_clk", + .parent_hws = (const struct clk_hw *[]){ &pcnoc_bfdcd_clk_src.clkr.hw }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *gcc_mdm9607_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL1] = &gpll1.clkr, + [GPLL1_VOTE] = &gpll1_vote, + [GPLL2] = &gpll2.clkr, + [GPLL2_EARLY] = &gpll2_early.clkr, + [BIMC_PLL] = &bimc_pll.clkr, + [BIMC_PLL_VOTE] = &bimc_pll_vote, + [BIMC_DDR_CLK_SRC] = &bimc_ddr_clk_src.clkr, + [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr, + [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr, + [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr, + [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr, + [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr, + [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr, + [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [APSS_TCU_CLK_SRC] = &apss_tcu_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_SLEEP_CLK] = &gcc_blsp1_sleep_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, + [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, + [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr, + [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, + [GCC_APSS_AXI_CLK] = &gcc_apss_axi_clk.clkr, + [GCC_USB_HSIC_CLK_SRC] = &usb_hsic_clk_src.clkr, + [GCC_USB_HSIC_IO_CAL_CLK_SRC] = &usb_hsic_io_cal_clk_src.clkr, + [GCC_USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_clk_src.clkr, +}; + +static const struct qcom_reset_map gcc_mdm9607_resets[] = { + [USB_HS_HSIC_BCR] = { 0x3d05c }, + [GCC_MSS_RESTART] = { 0x3e000 }, + [USB_HS_BCR] = { 0x41000 }, + [USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [QUSB2_PHY_BCR] = { 0x4103c }, +}; + +static const struct regmap_config gcc_mdm9607_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x80000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_mdm9607_desc = { + .config = &gcc_mdm9607_regmap_config, + .clks = gcc_mdm9607_clocks, + .num_clks = ARRAY_SIZE(gcc_mdm9607_clocks), + .resets = gcc_mdm9607_resets, + .num_resets = ARRAY_SIZE(gcc_mdm9607_resets), +}; + +static const struct of_device_id gcc_mdm9607_match_table[] = { + { .compatible = "qcom,gcc-mdm9607" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_mdm9607_match_table); + +static int gcc_mdm9607_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + + regmap = qcom_cc_map(pdev, &gcc_mdm9607_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Vote for GPLL0 to turn on. Needed by acpuclock. */ + regmap_update_bits(regmap, 0x45000, BIT(0), BIT(0)); + + return qcom_cc_really_probe(pdev, &gcc_mdm9607_desc, regmap); +} + +static struct platform_driver gcc_mdm9607_driver = { + .probe = gcc_mdm9607_probe, + .driver = { + .name = "gcc-mdm9607", + .of_match_table = gcc_mdm9607_match_table, + }, +}; + +static int __init gcc_mdm9607_init(void) +{ + return platform_driver_register(&gcc_mdm9607_driver); +} +core_initcall(gcc_mdm9607_init); + +static void __exit gcc_mdm9607_exit(void) +{ + platform_driver_unregister(&gcc_mdm9607_driver); +} +module_exit(gcc_mdm9607_exit); + +MODULE_DESCRIPTION("Qualcomm GCC mdm9607 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/qcom/gcc-msm8974.c b/drivers/clk/qcom/gcc-msm8974.c index 740d3c44c04b..bf305fa9e522 100644 --- a/drivers/clk/qcom/gcc-msm8974.c +++ b/drivers/clk/qcom/gcc-msm8974.c @@ -719,6 +719,12 @@ static struct clk_rcg2 blsp2_uart6_apps_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_ce1_clk_msm8226[] = { + F(50000000, P_GPLL0, 12, 0, 0), + F(100000000, P_GPLL0, 6, 0, 0), + { } +}; + static const struct freq_tbl ftbl_gcc_ce1_clk[] = { F(50000000, P_GPLL0, 12, 0, 0), F(75000000, P_GPLL0, 8, 0, 0), @@ -761,6 +767,11 @@ static struct clk_rcg2 ce2_clk_src = { }, }; +static const struct freq_tbl ftbl_gcc_gp_clk_msm8226[] = { + F(19200000, P_XO, 1, 0, 0), + { } +}; + static const struct freq_tbl ftbl_gcc_gp_clk[] = { F(4800000, P_XO, 4, 0, 0), F(6000000, P_GPLL0, 10, 1, 10), @@ -1955,6 +1966,10 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_mss_q6_bimc_axi_clk", + .parent_names = (const char *[]){ + "system_noc_clk_src", + }, + .num_parents = 1, .ops = &clk_branch2_ops, }, }, @@ -1993,6 +2008,20 @@ static struct clk_branch gcc_pdm_ahb_clk = { }, }; +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x0cc8, + .clkr = { + .enable_reg = 0x0cc8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + static struct clk_branch gcc_prng_ahb_clk = { .halt_reg = 0x0d04, .halt_check = BRANCH_HALT_VOTED, @@ -2430,6 +2459,121 @@ static struct gdsc usb_hs_hsic_gdsc = { .pwrsts = PWRSTS_OFF_ON, }; +static struct clk_regmap *gcc_msm8226_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_VOTE] = &gpll0_vote, + [GPLL1] = &gpll1.clkr, + [GPLL1_VOTE] = &gpll1_vote, + [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, + [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, + [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, + [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr, + [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr, + [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr, + [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr, + [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr, + [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr, + [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr, + [CE1_CLK_SRC] = &ce1_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [SDCC3_APPS_CLK_SRC] = &sdcc3_apps_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [USB_HSIC_CLK_SRC] = &usb_hsic_clk_src.clkr, + [USB_HSIC_IO_CAL_CLK_SRC] = &usb_hsic_io_cal_clk_src.clkr, + [USB_HSIC_SYSTEM_CLK_SRC] = &usb_hsic_system_clk_src.clkr, + [GCC_BAM_DMA_AHB_CLK] = &gcc_bam_dma_ahb_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr, + [GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr, + [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr, + [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr, + [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr, + [GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_USB_HSIC_AHB_CLK] = &gcc_usb_hsic_ahb_clk.clkr, + [GCC_USB_HSIC_CLK] = &gcc_usb_hsic_clk.clkr, + [GCC_USB_HSIC_IO_CAL_CLK] = &gcc_usb_hsic_io_cal_clk.clkr, + [GCC_USB_HSIC_SYSTEM_CLK] = &gcc_usb_hsic_system_clk.clkr, +}; + +static const struct qcom_reset_map gcc_msm8226_resets[] = { + [GCC_USB_HS_HSIC_BCR] = { 0x0400 }, + [GCC_USB_HS_BCR] = { 0x0480 }, + [GCC_USB2A_PHY_BCR] = { 0x04a8 }, +}; + +static struct gdsc *gcc_msm8226_gdscs[] = { + [USB_HS_HSIC_GDSC] = &usb_hs_hsic_gdsc, +}; + +static const struct regmap_config gcc_msm8226_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1a80, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_msm8226_desc = { + .config = &gcc_msm8226_regmap_config, + .clks = gcc_msm8226_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8226_clocks), + .resets = gcc_msm8226_resets, + .num_resets = ARRAY_SIZE(gcc_msm8226_resets), + .gdscs = gcc_msm8226_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8226_gdscs), +}; + static struct clk_regmap *gcc_msm8974_clocks[] = { [GPLL0] = &gpll0.clkr, [GPLL0_VOTE] = &gpll0_vote, @@ -2682,13 +2826,22 @@ static const struct qcom_cc_desc gcc_msm8974_desc = { }; static const struct of_device_id gcc_msm8974_match_table[] = { - { .compatible = "qcom,gcc-msm8974" }, - { .compatible = "qcom,gcc-msm8974pro" , .data = (void *)1UL }, - { .compatible = "qcom,gcc-msm8974pro-ac", .data = (void *)1UL }, + { .compatible = "qcom,gcc-msm8226", .data = &gcc_msm8226_desc }, + { .compatible = "qcom,gcc-msm8974", .data = &gcc_msm8974_desc }, + { .compatible = "qcom,gcc-msm8974pro", .data = &gcc_msm8974_desc }, + { .compatible = "qcom,gcc-msm8974pro-ac", .data = &gcc_msm8974_desc }, { } }; MODULE_DEVICE_TABLE(of, gcc_msm8974_match_table); +static void msm8226_clock_override(void) +{ + ce1_clk_src.freq_tbl = ftbl_gcc_ce1_clk_msm8226; + gp1_clk_src.freq_tbl = ftbl_gcc_gp_clk_msm8226; + gp2_clk_src.freq_tbl = ftbl_gcc_gp_clk_msm8226; + gp3_clk_src.freq_tbl = ftbl_gcc_gp_clk_msm8226; +} + static void msm8974_pro_clock_override(void) { sdcc1_apps_clk_src_init.parent_names = gcc_xo_gpll0_gpll4; @@ -2708,16 +2861,18 @@ static int gcc_msm8974_probe(struct platform_device *pdev) { int ret; struct device *dev = &pdev->dev; - bool pro; const struct of_device_id *id; id = of_match_device(gcc_msm8974_match_table, dev); if (!id) return -ENODEV; - pro = !!(id->data); - if (pro) - msm8974_pro_clock_override(); + if (!of_device_is_compatible(dev->of_node, "qcom,gcc-msm8974")) { + if (id->data == &gcc_msm8226_desc) + msm8226_clock_override(); + else + msm8974_pro_clock_override(); + } ret = qcom_cc_register_board_clk(dev, "xo_board", "xo", 19200000); if (ret) diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c index ef734db316df..6cefcdc86990 100644 --- a/drivers/clk/qcom/gcc-sc7280.c +++ b/drivers/clk/qcom/gcc-sc7280.c @@ -716,6 +716,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = { F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(52174000, P_GCC_GPLL0_OUT_MAIN, 1, 2, 23), F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), diff --git a/drivers/clk/qcom/gcc-sm6125.c b/drivers/clk/qcom/gcc-sm6125.c new file mode 100644 index 000000000000..543cfab7561f --- /dev/null +++ b/drivers/clk/qcom/gcc-sm6125.c @@ -0,0 +1,4190 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/clk-provider.h> +#include <linux/regmap.h> +#include <linux/reset-controller.h> + +#include <dt-bindings/clock/qcom,gcc-sm6125.h> + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + P_BI_TCXO, + P_GPLL0_OUT_AUX2, + P_GPLL0_OUT_EARLY, + P_GPLL3_OUT_EARLY, + P_GPLL4_OUT_MAIN, + P_GPLL5_OUT_MAIN, + P_GPLL6_OUT_EARLY, + P_GPLL6_OUT_MAIN, + P_GPLL7_OUT_MAIN, + P_GPLL8_OUT_EARLY, + P_GPLL8_OUT_MAIN, + P_GPLL9_OUT_MAIN, + P_SLEEP_CLK, +}; + +static struct clk_alpha_pll gpll0_out_early = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll0_out_aux2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_aux2", + .parent_hws = (const struct clk_hw*[]){ + &gpll0_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_fixed_factor gpll0_out_main = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll0_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll0_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll3_out_early = { + .offset = 0x3000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gpll3_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll4_out_main = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gpll4_out_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll5_out_main = { + .offset = 0x5000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gpll5_out_main", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_alpha_pll gpll6_out_early = { + .offset = 0x6000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gpll6_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll6_out_main = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll6_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll6_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll7_out_early = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gpll7_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll7_out_main = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll7_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll7_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll8_out_early = { + .offset = 0x8000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gpll8_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll8_out_main = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll8_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll8_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static struct clk_alpha_pll gpll9_out_early = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], + .clkr = { + .enable_reg = 0x79000, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gpll9_out_early", + .parent_data = &(const struct clk_parent_data){ + .fw_name = "bi_tcxo", + }, + .num_parents = 1, + .ops = &clk_alpha_pll_ops, + }, + }, +}; + +static struct clk_fixed_factor gpll9_out_main = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "gpll9_out_main", + .parent_hws = (const struct clk_hw*[]){ + &gpll9_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_fixed_factor_ops, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll0_out_aux2.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL6_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll0_out_aux2.hw }, + { .hw = &gpll6_out_main.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll0_out_aux2.hw }, + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL5_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll5_out_main.clkr.hw }, + { .hw = &gpll4_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL9_OUT_MAIN, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll9_out_main.hw }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll4_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_7[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .fw_name = "sleep_clk" }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL9_OUT_MAIN, 2 }, + { P_GPLL6_OUT_EARLY, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL4_OUT_MAIN, 5 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll9_out_main.hw }, + { .hw = &gpll6_out_early.clkr.hw }, + { .hw = &gpll8_out_main.hw }, + { .hw = &gpll4_out_main.clkr.hw }, + { .hw = &gpll3_out_early.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_MAIN, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_9[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll8_out_main.hw }, +}; + +static const struct parent_map gcc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL9_OUT_MAIN, 2 }, + { P_GPLL6_OUT_EARLY, 3 }, + { P_GPLL8_OUT_MAIN, 4 }, + { P_GPLL3_OUT_EARLY, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_10[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll9_out_main.hw }, + { .hw = &gpll6_out_early.clkr.hw }, + { .hw = &gpll8_out_main.hw }, + { .hw = &gpll3_out_early.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_11[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL8_OUT_EARLY, 4 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_11[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll8_out_early.clkr.hw }, + { .hw = &gpll4_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL6_OUT_EARLY, 3 }, + { P_GPLL8_OUT_EARLY, 4 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll6_out_early.clkr.hw }, + { .hw = &gpll8_out_early.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_13[] = { + { P_BI_TCXO, 0 }, + { P_GPLL0_OUT_EARLY, 1 }, + { P_GPLL0_OUT_AUX2, 2 }, + { P_GPLL7_OUT_MAIN, 3 }, + { P_GPLL4_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_13[] = { + { .fw_name = "bi_tcxo" }, + { .hw = &gpll0_out_early.clkr.hw }, + { .hw = &gpll0_out_aux2.hw }, + { .hw = &gpll7_out_main.hw }, + { .hw = &gpll4_out_main.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_14[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_14[] = { + { .fw_name = "bi_tcxo" }, + { .fw_name = "sleep_clk" }, +}; + +static const struct freq_tbl ftbl_gcc_camss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(40000000, P_GPLL8_OUT_MAIN, 12, 0, 0), + F(80000000, P_GPLL8_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_ahb_clk_src = { + .cmd_rcgr = 0x56088, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_9, + .freq_tbl = ftbl_gcc_camss_ahb_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_ahb_clk_src", + .parent_data = gcc_parent_data_9, + .num_parents = ARRAY_SIZE(gcc_parent_data_9), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cci_clk_src[] = { + F(37500000, P_GPLL0_OUT_EARLY, 16, 0, 0), + F(50000000, P_GPLL0_OUT_EARLY, 12, 0, 0), + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_cci_clk_src = { + .cmd_rcgr = 0x52004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_camss_cci_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cci_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_cpp_clk_src[] = { + F(120000000, P_GPLL8_OUT_MAIN, 4, 0, 0), + F(240000000, P_GPLL8_OUT_MAIN, 2, 0, 0), + F(320000000, P_GPLL8_OUT_MAIN, 1.5, 0, 0), + F(480000000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(576000000, P_GPLL9_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_cpp_clk_src = { + .cmd_rcgr = 0x560c8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_10, + .freq_tbl = ftbl_gcc_camss_cpp_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_clk_src", + .parent_data = gcc_parent_data_10, + .num_parents = ARRAY_SIZE(gcc_parent_data_10), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0_clk_src[] = { + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(311000000, P_GPLL5_OUT_MAIN, 3, 0, 0), + F(403200000, P_GPLL4_OUT_MAIN, 2, 0, 0), + F(466500000, P_GPLL5_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_csi0_clk_src = { + .cmd_rcgr = 0x55030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csi0phytimer_clk_src[] = { + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(268800000, P_GPLL4_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_csi0phytimer_clk_src = { + .cmd_rcgr = 0x53004, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi1_clk_src = { + .cmd_rcgr = 0x5506c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi1phytimer_clk_src = { + .cmd_rcgr = 0x53024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi2_clk_src = { + .cmd_rcgr = 0x550a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi2phytimer_clk_src = { + .cmd_rcgr = 0x53044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_camss_csi0phytimer_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2phytimer_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_csi3_clk_src = { + .cmd_rcgr = 0x550e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_camss_csi0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi3_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_csiphy_clk_src[] = { + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(268800000, P_GPLL4_OUT_MAIN, 3, 0, 0), + F(320000000, P_GPLL8_OUT_EARLY, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_csiphy_clk_src = { + .cmd_rcgr = 0x55000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_11, + .freq_tbl = ftbl_gcc_camss_csiphy_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csiphy_clk_src", + .parent_data = gcc_parent_data_11, + .num_parents = ARRAY_SIZE(gcc_parent_data_11), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_gp0_clk_src[] = { + F(50000000, P_GPLL0_OUT_EARLY, 12, 0, 0), + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_gp0_clk_src = { + .cmd_rcgr = 0x50000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp0_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_gp1_clk_src = { + .cmd_rcgr = 0x5001c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_7, + .freq_tbl = ftbl_gcc_camss_gp0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp1_clk_src", + .parent_data = gcc_parent_data_7, + .num_parents = ARRAY_SIZE(gcc_parent_data_7), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_jpeg_clk_src[] = { + F(66666667, P_GPLL0_OUT_EARLY, 9, 0, 0), + F(133333333, P_GPLL0_OUT_EARLY, 4.5, 0, 0), + F(219428571, P_GPLL6_OUT_EARLY, 3.5, 0, 0), + F(320000000, P_GPLL8_OUT_EARLY, 3, 0, 0), + F(480000000, P_GPLL8_OUT_EARLY, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_jpeg_clk_src = { + .cmd_rcgr = 0x52028, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_12, + .freq_tbl = ftbl_gcc_camss_jpeg_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_GPLL9_OUT_MAIN, 1, 1, 24), + F(64000000, P_GPLL9_OUT_MAIN, 1, 1, 9), + { } +}; + +static struct clk_rcg2 gcc_camss_mclk0_clk_src = { + .cmd_rcgr = 0x51000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk0_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk1_clk_src = { + .cmd_rcgr = 0x5101c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk1_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk2_clk_src = { + .cmd_rcgr = 0x51038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk2_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_mclk3_clk_src = { + .cmd_rcgr = 0x51054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_camss_mclk0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk3_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_camss_vfe0_clk_src[] = { + F(120000000, P_GPLL8_OUT_MAIN, 4, 0, 0), + F(256000000, P_GPLL6_OUT_EARLY, 3, 0, 0), + F(403200000, P_GPLL4_OUT_MAIN, 2, 0, 0), + F(480000000, P_GPLL8_OUT_MAIN, 1, 0, 0), + F(533000000, P_GPLL3_OUT_EARLY, 2, 0, 0), + F(576000000, P_GPLL9_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_camss_vfe0_clk_src = { + .cmd_rcgr = 0x54010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe0_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_camss_vfe1_clk_src = { + .cmd_rcgr = 0x54048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_camss_vfe0_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x4d004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x4e004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x4f004, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(60000000, P_GPLL0_OUT_EARLY, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x20010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = { + F(7372800, P_GPLL0_OUT_AUX2, 1, 384, 15625), + F(14745600, P_GPLL0_OUT_AUX2, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GPLL0_OUT_AUX2, 1, 1536, 15625), + F(32000000, P_GPLL0_OUT_AUX2, 1, 8, 75), + F(48000000, P_GPLL0_OUT_AUX2, 1, 4, 25), + F(64000000, P_GPLL0_OUT_AUX2, 1, 16, 75), + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(80000000, P_GPLL0_OUT_AUX2, 1, 4, 15), + F(96000000, P_GPLL0_OUT_AUX2, 1, 8, 25), + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(102400000, P_GPLL0_OUT_AUX2, 1, 128, 375), + F(112000000, P_GPLL0_OUT_AUX2, 1, 28, 75), + F(117964800, P_GPLL0_OUT_AUX2, 1, 6144, 15625), + F(120000000, P_GPLL0_OUT_AUX2, 2.5, 0, 0), + F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = { + .name = "gcc_qupv3_wrap0_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = { + .cmd_rcgr = 0x1f148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = { + .name = "gcc_qupv3_wrap0_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = { + .cmd_rcgr = 0x1f278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = { + .name = "gcc_qupv3_wrap0_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = { + .cmd_rcgr = 0x1f3a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = { + .name = "gcc_qupv3_wrap0_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = { + .cmd_rcgr = 0x1f4d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = { + .name = "gcc_qupv3_wrap0_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = { + .cmd_rcgr = 0x1f608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = { + .name = "gcc_qupv3_wrap0_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = { + .cmd_rcgr = 0x1f738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x39148, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x39278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { + .cmd_rcgr = 0x393a8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x394d8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x39608, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x39738, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = { + F(144000, P_BI_TCXO, 16, 3, 25), + F(400000, P_BI_TCXO, 12, 1, 4), + F(20000000, P_GPLL0_OUT_AUX2, 5, 1, 3), + F(25000000, P_GPLL0_OUT_AUX2, 6, 1, 2), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0), + F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .cmd_rcgr = 0x38028, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_sdcc1_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = { + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EARLY, 4, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(300000000, P_GPLL0_OUT_EARLY, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .cmd_rcgr = 0x38010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_AUX2, 3, 0, 0), + F(202000000, P_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1e00c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_13, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_13, + .num_parents = ARRAY_SIZE(gcc_parent_data_13), + .ops = &clk_rcg2_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GPLL0_OUT_AUX2, 12, 0, 0), + F(50000000, P_GPLL0_OUT_AUX2, 6, 0, 0), + F(100000000, P_GPLL0_OUT_EARLY, 6, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x45020, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0), + F(75000000, P_GPLL0_OUT_AUX2, 4, 0, 0), + F(150000000, P_GPLL0_OUT_EARLY, 4, 0, 0), + F(300000000, P_GPLL0_OUT_EARLY, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x45048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x4507c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = { + F(37500000, P_GPLL0_OUT_AUX2, 8, 0, 0), + F(75000000, P_GPLL0_OUT_EARLY, 8, 0, 0), + F(150000000, P_GPLL0_OUT_EARLY, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x45060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GPLL0_OUT_AUX2, 4.5, 0, 0), + F(133333333, P_GPLL0_OUT_EARLY, 4.5, 0, 0), + F(200000000, P_GPLL0_OUT_EARLY, 3, 0, 0), + F(240000000, P_GPLL0_OUT_EARLY, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x1a01c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(20000000, P_GPLL0_OUT_AUX2, 15, 0, 0), + F(40000000, P_GPLL0_OUT_AUX2, 7.5, 0, 0), + F(60000000, P_GPLL0_OUT_EARLY, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x1a034, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb3_prim_phy_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x1a060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_14, + .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_14, + .num_parents = ARRAY_SIZE(gcc_parent_data_14), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_vs_ctrl_clk_src = { + .cmd_rcgr = 0x42030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_usb3_prim_phy_aux_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_vs_ctrl_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_vsensor_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(400000000, P_GPLL0_OUT_EARLY, 1.5, 0, 0), + F(600000000, P_GPLL0_OUT_EARLY, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_vsensor_clk_src = { + .cmd_rcgr = 0x42018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_vsensor_clk_src, + .clkr.hw.init = &(struct clk_init_data){ + .name = "gcc_vsensor_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch gcc_ahb2phy_csi_clk = { + .halt_reg = 0x1d004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1d004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ahb2phy_csi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ahb2phy_usb_clk = { + .halt_reg = 0x1d008, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1d008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1d008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ahb2phy_usb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_apc_vs_clk = { + .halt_reg = 0x4204c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4204c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_apc_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_bimc_gpu_axi_clk = { + .halt_reg = 0x71154, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x71154, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_bimc_gpu_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_ahb_clk = { + .halt_reg = 0x17008, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x17008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x17008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_xo_clk = { + .halt_reg = 0x17028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x17028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camera_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_ahb_clk = { + .halt_reg = 0x52020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cci_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cci_clk = { + .halt_reg = 0x5201c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5201c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cci_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_cci_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_csid0_clk = { + .halt_reg = 0x5504c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5504c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cphy_csid0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_csid1_clk = { + .halt_reg = 0x55088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55088, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cphy_csid1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_csid2_clk = { + .halt_reg = 0x550c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550c0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cphy_csid2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cphy_csid3_clk = { + .halt_reg = 0x550fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550fc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cphy_csid3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_ahb_clk = { + .halt_reg = 0x560e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560e8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_axi_clk = { + .halt_reg = 0x560f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560f4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_clk = { + .halt_reg = 0x560e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560e0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_cpp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_cpp_vbif_ahb_clk = { + .halt_reg = 0x560f0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560f0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_cpp_vbif_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0_ahb_clk = { + .halt_reg = 0x55050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0_clk = { + .halt_reg = 0x55048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0phytimer_clk = { + .halt_reg = 0x5301c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5301c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0pix_clk = { + .halt_reg = 0x55060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi0rdi_clk = { + .halt_reg = 0x55058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi0rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1_ahb_clk = { + .halt_reg = 0x5508c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5508c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1_clk = { + .halt_reg = 0x55084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1phytimer_clk = { + .halt_reg = 0x5303c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5303c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1pix_clk = { + .halt_reg = 0x5509c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5509c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi1rdi_clk = { + .halt_reg = 0x55094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55094, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi1rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2_ahb_clk = { + .halt_reg = 0x550c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550c4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2_clk = { + .halt_reg = 0x550bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550bc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2phytimer_clk = { + .halt_reg = 0x5305c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5305c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2pix_clk = { + .halt_reg = 0x550d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550d4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi2rdi_clk = { + .halt_reg = 0x550cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550cc, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi2rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi3_ahb_clk = { + .halt_reg = 0x55100, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55100, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi3_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi3_clk = { + .halt_reg = 0x550f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x550f8, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi3pix_clk = { + .halt_reg = 0x55110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55110, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi3pix_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi3rdi_clk = { + .halt_reg = 0x55108, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55108, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi3rdi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csi3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi_vfe0_clk = { + .halt_reg = 0x54074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54074, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi_vfe0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csi_vfe1_clk = { + .halt_reg = 0x54080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csi_vfe1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csiphy0_clk = { + .halt_reg = 0x55018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csiphy1_clk = { + .halt_reg = 0x5501c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_csiphy2_clk = { + .halt_reg = 0x55020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x55020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_csiphy_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_gp0_clk = { + .halt_reg = 0x50018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_gp0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_gp1_clk = { + .halt_reg = 0x50034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x50034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_gp1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_ispif_ahb_clk = { + .halt_reg = 0x540a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x540a4, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_ispif_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg_ahb_clk = { + .halt_reg = 0x52048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg_axi_clk = { + .halt_reg = 0x5204c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5204c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_jpeg_clk = { + .halt_reg = 0x52040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x52040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_jpeg_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk0_clk = { + .halt_reg = 0x51018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk1_clk = { + .halt_reg = 0x51034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk2_clk = { + .halt_reg = 0x51050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x51050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_mclk3_clk = { + .halt_reg = 0x5106c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5106c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_mclk3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_micro_ahb_clk = { + .halt_reg = 0x560b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560b0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_micro_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_throttle_nrt_axi_clk = { + .halt_reg = 0x560a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_throttle_nrt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_throttle_rt_axi_clk = { + .halt_reg = 0x560a8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_throttle_rt_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_top_ahb_clk = { + .halt_reg = 0x560a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x560a0, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe0_ahb_clk = { + .halt_reg = 0x54034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54034, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe0_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe0_clk = { + .halt_reg = 0x54028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54028, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe0_stream_clk = { + .halt_reg = 0x54030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54030, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe0_stream_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_ahb_clk = { + .halt_reg = 0x5406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5406c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_clk = { + .halt_reg = 0x54060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54060, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe1_stream_clk = { + .halt_reg = 0x54068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54068, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe1_stream_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_vfe1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe_tsctr_clk = { + .halt_reg = 0x5409c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5409c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe_tsctr_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe_vbif_ahb_clk = { + .halt_reg = 0x5408c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x5408c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe_vbif_ahb_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_camss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camss_vfe_vbif_axi_clk = { + .halt_reg = 0x54090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x54090, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_camss_vfe_vbif_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_ahb_clk = { + .halt_reg = 0x2700c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2700c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(3), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_axi_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ce1_clk = { + .halt_reg = 0x27004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ce1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a084, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cpuss_gnoc_clk = { + .halt_reg = 0x2b004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2b004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_cpuss_gnoc_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_ahb_clk = { + .halt_reg = 0x1700c, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x1700c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x1700c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpll0_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x17020, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_throttle_core_clk = { + .halt_reg = 0x17064, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(5), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_xo_clk = { + .halt_reg = 0x1702c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1702c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_disp_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x4d000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4d000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x4e000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4e000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x4f000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4f000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_cfg_ahb_clk = { + .halt_reg = 0x36004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x36004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x36004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_cfg_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpll0_out_early.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]){ + &gpll0_out_aux2.hw, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_memnoc_gfx_clk = { + .halt_reg = 0x3600c, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x3600c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = { + .halt_reg = 0x36018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_snoc_dvm_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_throttle_core_clk = { + .halt_reg = 0x36048, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(31), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_throttle_xo_clk = { + .halt_reg = 0x36044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x36044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_gpu_throttle_xo_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_mss_vs_clk = { + .halt_reg = 0x42048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42048, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_mss_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x2000c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2000c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x20004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x20004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x20004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x20008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_prng_ahb_clk = { + .halt_reg = 0x21004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x21004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_prng_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x17014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x17060, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x17060, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(2), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_ahb_clk = { + .halt_reg = 0x17018, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(1), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_disp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_cfg_ahb_clk = { + .halt_reg = 0x36040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x36040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(4), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_gpu_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x17010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = { + .halt_reg = 0x1f014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(9), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_core_clk = { + .halt_reg = 0x1f00c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(8), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s0_clk = { + .halt_reg = 0x1f144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(10), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s1_clk = { + .halt_reg = 0x1f274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(11), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s2_clk = { + .halt_reg = 0x1f3a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(12), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s3_clk = { + .halt_reg = 0x1f4d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(13), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s4_clk = { + .halt_reg = 0x1f604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(14), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s4_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap0_s5_clk = { + .halt_reg = 0x1f734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(15), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap0_s5_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap0_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x39014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(18), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x3900c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(19), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x39144, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(22), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x39274, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(23), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x393a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(24), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x394d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(25), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x39604, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(26), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x39734, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(27), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = { + .halt_reg = 0x1f004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(6), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = { + .halt_reg = 0x1f008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x1f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(7), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_0_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = { + .halt_reg = 0x39004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(20), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x39008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7900c, + .enable_mask = BIT(21), + .hw.init = &(struct clk_init_data){ + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ahb_clk = { + .halt_reg = 0x38008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x38008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_apps_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x38004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_sdcc1_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc1_ice_core_clk = { + .halt_reg = 0x3800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3800c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc1_ice_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_sdcc1_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x1e008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1e004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_compute_sf_axi_clk = { + .halt_reg = 0x1050c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1050c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_compute_sf_axi_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = { + .halt_reg = 0x2b06c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_cpuss_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_ufs_phy_axi_clk = { + .halt_reg = 0x45098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x45098, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sys_noc_usb3_prim_axi_clk = { + .halt_reg = 0x1a080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a080, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_sys_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_mem_clkref_clk = { + .halt_reg = 0x8c000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8c000, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_mem_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x45014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x45014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x45014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x45010, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x45010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x45010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x45044, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x45044, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x45044, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x45078, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x45078, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x45078, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x4501c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x4501c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x45018, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x45018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x45040, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x45040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x45040, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x1a010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x1a018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a018, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x1a014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_clkref_clk = { + .halt_reg = 0x80278, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80278, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_clkref_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x1a054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1a054, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x1a058, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_usb3_prim_phy_pipe_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vdda_vs_clk = { + .halt_reg = 0x4200c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4200c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vdda_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vddcx_vs_clk = { + .halt_reg = 0x42004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vddcx_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vddmx_vs_clk = { + .halt_reg = 0x42008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42008, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vddmx_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_ahb_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x17004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x17004, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_ahb_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x1701c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1701c, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_throttle_core_clk = { + .halt_reg = 0x17068, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x79004, + .enable_mask = BIT(28), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_throttle_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_xo_clk = { + .halt_reg = 0x17024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x17024, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_video_xo_clk", + .flags = CLK_IS_CRITICAL, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vs_ctrl_ahb_clk = { + .halt_reg = 0x42014, + .halt_check = BRANCH_HALT, + .hwcg_reg = 0x42014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x42014, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vs_ctrl_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_vs_ctrl_clk = { + .halt_reg = 0x42010, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42010, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_vs_ctrl_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vs_ctrl_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_wcss_vs_clk = { + .halt_reg = 0x42050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x42050, + .enable_mask = BIT(0), + .hw.init = &(struct clk_init_data){ + .name = "gcc_wcss_vs_clk", + .parent_hws = (const struct clk_hw*[]){ + &gcc_vsensor_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc usb30_prim_gdsc = { + .gdscr = 0x1a004, + .pd = { + .name = "usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc ufs_phy_gdsc = { + .gdscr = 0x45004, + .pd = { + .name = "ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_vfe0_gdsc = { + .gdscr = 0x54004, + .pd = { + .name = "camss_vfe0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_vfe1_gdsc = { + .gdscr = 0x5403c, + .pd = { + .name = "camss_vfe1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc camss_top_gdsc = { + .gdscr = 0x5607c, + .pd = { + .name = "camss_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc cam_cpp_gdsc = { + .gdscr = 0x560bc, + .pd = { + .name = "cam_cpp_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, +}; + +static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = { + .gdscr = 0x7d060, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc = { + .gdscr = 0x80074, + .pd = { + .name = "hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc = { + .gdscr = 0x80084, + .pd = { + .name = "hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + + +static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = { + .gdscr = 0x80094, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc *gcc_sm6125_gdscs[] = { + [USB30_PRIM_GDSC] = &usb30_prim_gdsc, + [UFS_PHY_GDSC] = &ufs_phy_gdsc, + [CAMSS_VFE0_GDSC] = &camss_vfe0_gdsc, + [CAMSS_VFE1_GDSC] = &camss_vfe1_gdsc, + [CAMSS_TOP_GDSC] = &camss_top_gdsc, + [CAM_CPP_GDSC] = &cam_cpp_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc, + [HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_rt_gdsc, + [HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC] = &hlos1_vote_mm_snoc_mmu_tbu_nrt_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc, +}; + +static struct clk_hw *gcc_sm6125_hws[] = { + [GPLL0_OUT_AUX2] = &gpll0_out_aux2.hw, + [GPLL0_OUT_MAIN] = &gpll0_out_main.hw, + [GPLL6_OUT_MAIN] = &gpll6_out_main.hw, + [GPLL7_OUT_MAIN] = &gpll7_out_main.hw, + [GPLL8_OUT_MAIN] = &gpll8_out_main.hw, + [GPLL9_OUT_MAIN] = &gpll9_out_main.hw, +}; + +static struct clk_regmap *gcc_sm6125_clocks[] = { + [GCC_AHB2PHY_CSI_CLK] = &gcc_ahb2phy_csi_clk.clkr, + [GCC_AHB2PHY_USB_CLK] = &gcc_ahb2phy_usb_clk.clkr, + [GCC_APC_VS_CLK] = &gcc_apc_vs_clk.clkr, + [GCC_BIMC_GPU_AXI_CLK] = &gcc_bimc_gpu_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_AHB_CLK] = &gcc_camera_ahb_clk.clkr, + [GCC_CAMERA_XO_CLK] = &gcc_camera_xo_clk.clkr, + [GCC_CAMSS_AHB_CLK_SRC] = &gcc_camss_ahb_clk_src.clkr, + [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr, + [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr, + [GCC_CAMSS_CCI_CLK_SRC] = &gcc_camss_cci_clk_src.clkr, + [GCC_CAMSS_CPHY_CSID0_CLK] = &gcc_camss_cphy_csid0_clk.clkr, + [GCC_CAMSS_CPHY_CSID1_CLK] = &gcc_camss_cphy_csid1_clk.clkr, + [GCC_CAMSS_CPHY_CSID2_CLK] = &gcc_camss_cphy_csid2_clk.clkr, + [GCC_CAMSS_CPHY_CSID3_CLK] = &gcc_camss_cphy_csid3_clk.clkr, + [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr, + [GCC_CAMSS_CPP_AXI_CLK] = &gcc_camss_cpp_axi_clk.clkr, + [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr, + [GCC_CAMSS_CPP_CLK_SRC] = &gcc_camss_cpp_clk_src.clkr, + [GCC_CAMSS_CPP_VBIF_AHB_CLK] = &gcc_camss_cpp_vbif_ahb_clk.clkr, + [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr, + [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr, + [GCC_CAMSS_CSI0_CLK_SRC] = &gcc_camss_csi0_clk_src.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK_SRC] = &gcc_camss_csi0phytimer_clk_src.clkr, + [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr, + [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr, + [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr, + [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr, + [GCC_CAMSS_CSI1_CLK_SRC] = &gcc_camss_csi1_clk_src.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK_SRC] = &gcc_camss_csi1phytimer_clk_src.clkr, + [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr, + [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr, + [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr, + [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr, + [GCC_CAMSS_CSI2_CLK_SRC] = &gcc_camss_csi2_clk_src.clkr, + [GCC_CAMSS_CSI2PHYTIMER_CLK] = &gcc_camss_csi2phytimer_clk.clkr, + [GCC_CAMSS_CSI2PHYTIMER_CLK_SRC] = &gcc_camss_csi2phytimer_clk_src.clkr, + [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr, + [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr, + [GCC_CAMSS_CSI3_AHB_CLK] = &gcc_camss_csi3_ahb_clk.clkr, + [GCC_CAMSS_CSI3_CLK] = &gcc_camss_csi3_clk.clkr, + [GCC_CAMSS_CSI3_CLK_SRC] = &gcc_camss_csi3_clk_src.clkr, + [GCC_CAMSS_CSI3PIX_CLK] = &gcc_camss_csi3pix_clk.clkr, + [GCC_CAMSS_CSI3RDI_CLK] = &gcc_camss_csi3rdi_clk.clkr, + [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr, + [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr, + [GCC_CAMSS_CSIPHY0_CLK] = &gcc_camss_csiphy0_clk.clkr, + [GCC_CAMSS_CSIPHY1_CLK] = &gcc_camss_csiphy1_clk.clkr, + [GCC_CAMSS_CSIPHY2_CLK] = &gcc_camss_csiphy2_clk.clkr, + [GCC_CAMSS_CSIPHY_CLK_SRC] = &gcc_camss_csiphy_clk_src.clkr, + [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr, + [GCC_CAMSS_GP0_CLK_SRC] = &gcc_camss_gp0_clk_src.clkr, + [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr, + [GCC_CAMSS_GP1_CLK_SRC] = &gcc_camss_gp1_clk_src.clkr, + [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr, + [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr, + [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr, + [GCC_CAMSS_JPEG_CLK] = &gcc_camss_jpeg_clk.clkr, + [GCC_CAMSS_JPEG_CLK_SRC] = &gcc_camss_jpeg_clk_src.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK0_CLK_SRC] = &gcc_camss_mclk0_clk_src.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MCLK1_CLK_SRC] = &gcc_camss_mclk1_clk_src.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MCLK2_CLK_SRC] = &gcc_camss_mclk2_clk_src.clkr, + [GCC_CAMSS_MCLK3_CLK] = &gcc_camss_mclk3_clk.clkr, + [GCC_CAMSS_MCLK3_CLK_SRC] = &gcc_camss_mclk3_clk_src.clkr, + [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr, + [GCC_CAMSS_THROTTLE_NRT_AXI_CLK] = &gcc_camss_throttle_nrt_axi_clk.clkr, + [GCC_CAMSS_THROTTLE_RT_AXI_CLK] = &gcc_camss_throttle_rt_axi_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AHB_CLK] = &gcc_camss_vfe0_ahb_clk.clkr, + [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr, + [GCC_CAMSS_VFE0_CLK_SRC] = &gcc_camss_vfe0_clk_src.clkr, + [GCC_CAMSS_VFE0_STREAM_CLK] = &gcc_camss_vfe0_stream_clk.clkr, + [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr, + [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr, + [GCC_CAMSS_VFE1_CLK_SRC] = &gcc_camss_vfe1_clk_src.clkr, + [GCC_CAMSS_VFE1_STREAM_CLK] = &gcc_camss_vfe1_stream_clk.clkr, + [GCC_CAMSS_VFE_TSCTR_CLK] = &gcc_camss_vfe_tsctr_clk.clkr, + [GCC_CAMSS_VFE_VBIF_AHB_CLK] = &gcc_camss_vfe_vbif_ahb_clk.clkr, + [GCC_CAMSS_VFE_VBIF_AXI_CLK] = &gcc_camss_vfe_vbif_axi_clk.clkr, + [GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr, + [GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr, + [GCC_CE1_CLK] = &gcc_ce1_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, + [GCC_DISP_AHB_CLK] = &gcc_disp_ahb_clk.clkr, + [GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_THROTTLE_CORE_CLK] = &gcc_disp_throttle_core_clk.clkr, + [GCC_DISP_XO_CLK] = &gcc_disp_xo_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr, + [GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr, + [GCC_GPU_THROTTLE_CORE_CLK] = &gcc_gpu_throttle_core_clk.clkr, + [GCC_GPU_THROTTLE_XO_CLK] = &gcc_gpu_throttle_xo_clk.clkr, + [GCC_MSS_VS_CLK] = &gcc_mss_vs_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr, + [GCC_QMIP_GPU_CFG_AHB_CLK] = &gcc_qmip_gpu_cfg_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr, + [GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr, + [GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr, + [GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr, + [GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr, + [GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr, + [GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr, + [GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr, + [GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr, + [GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr, + [GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr, + [GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr, + [GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SYS_NOC_COMPUTE_SF_AXI_CLK] = &gcc_sys_noc_compute_sf_axi_clk.clkr, + [GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr, + [GCC_SYS_NOC_UFS_PHY_AXI_CLK] = &gcc_sys_noc_ufs_phy_axi_clk.clkr, + [GCC_SYS_NOC_USB3_PRIM_AXI_CLK] = &gcc_sys_noc_usb3_prim_axi_clk.clkr, + [GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = + &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = + &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_VDDA_VS_CLK] = &gcc_vdda_vs_clk.clkr, + [GCC_VDDCX_VS_CLK] = &gcc_vddcx_vs_clk.clkr, + [GCC_VDDMX_VS_CLK] = &gcc_vddmx_vs_clk.clkr, + [GCC_VIDEO_AHB_CLK] = &gcc_video_ahb_clk.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_THROTTLE_CORE_CLK] = &gcc_video_throttle_core_clk.clkr, + [GCC_VIDEO_XO_CLK] = &gcc_video_xo_clk.clkr, + [GCC_VS_CTRL_AHB_CLK] = &gcc_vs_ctrl_ahb_clk.clkr, + [GCC_VS_CTRL_CLK] = &gcc_vs_ctrl_clk.clkr, + [GCC_VS_CTRL_CLK_SRC] = &gcc_vs_ctrl_clk_src.clkr, + [GCC_VSENSOR_CLK_SRC] = &gcc_vsensor_clk_src.clkr, + [GCC_WCSS_VS_CLK] = &gcc_wcss_vs_clk.clkr, + [GPLL0_OUT_EARLY] = &gpll0_out_early.clkr, + [GPLL3_OUT_EARLY] = &gpll3_out_early.clkr, + [GPLL4_OUT_MAIN] = &gpll4_out_main.clkr, + [GPLL5_OUT_MAIN] = &gpll5_out_main.clkr, + [GPLL6_OUT_EARLY] = &gpll6_out_early.clkr, + [GPLL7_OUT_EARLY] = &gpll7_out_early.clkr, + [GPLL8_OUT_EARLY] = &gpll8_out_early.clkr, + [GPLL9_OUT_EARLY] = &gpll9_out_early.clkr, + [GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr, +}; + +static const struct qcom_reset_map gcc_sm6125_resets[] = { + [GCC_QUSB2PHY_PRIM_BCR] = { 0x1c000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x1c004 }, + [GCC_UFS_PHY_BCR] = { 0x45000 }, + [GCC_USB30_PRIM_BCR] = { 0x1a000 }, + [GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x1d000 }, + [GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x1b008 }, + [GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x1b000 }, + [GCC_CAMSS_MICRO_BCR] = { 0x560ac }, +}; + +static struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), +}; + +static const struct regmap_config gcc_sm6125_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xc7000, + .fast_io = true, +}; + +static const struct qcom_cc_desc gcc_sm6125_desc = { + .config = &gcc_sm6125_regmap_config, + .clks = gcc_sm6125_clocks, + .num_clks = ARRAY_SIZE(gcc_sm6125_clocks), + .clk_hws = gcc_sm6125_hws, + .num_clk_hws = ARRAY_SIZE(gcc_sm6125_hws), + .resets = gcc_sm6125_resets, + .num_resets = ARRAY_SIZE(gcc_sm6125_resets), + .gdscs = gcc_sm6125_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_sm6125_gdscs), +}; + +static const struct of_device_id gcc_sm6125_match_table[] = { + { .compatible = "qcom,gcc-sm6125" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_sm6125_match_table); + +static int gcc_sm6125_probe(struct platform_device *pdev) +{ + struct regmap *regmap; + int ret; + + regmap = qcom_cc_map(pdev, &gcc_sm6125_desc); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* + * Disable the GPLL0 active input to video block via + * MISC registers. + */ + regmap_update_bits(regmap, 0x80258, 0x1, 0x1); + + /* + * Enable DUAL_EDGE mode for MCLK RCGs + * This is requierd to enable MND divider mode + */ + regmap_update_bits(regmap, 0x51004, 0x3000, 0x2000); + regmap_update_bits(regmap, 0x51020, 0x3000, 0x2000); + regmap_update_bits(regmap, 0x5103c, 0x3000, 0x2000); + regmap_update_bits(regmap, 0x51058, 0x3000, 0x2000); + + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + + return qcom_cc_really_probe(pdev, &gcc_sm6125_desc, regmap); +} + +static struct platform_driver gcc_sm6125_driver = { + .probe = gcc_sm6125_probe, + .driver = { + .name = "gcc-sm6125", + .of_match_table = gcc_sm6125_match_table, + }, +}; + +static int __init gcc_sm6125_init(void) +{ + return platform_driver_register(&gcc_sm6125_driver); +} +subsys_initcall(gcc_sm6125_init); + +static void __exit gcc_sm6125_exit(void) +{ + platform_driver_unregister(&gcc_sm6125_driver); +} +module_exit(gcc_sm6125_exit); + +MODULE_DESCRIPTION("QTI GCC SM6125 Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 607e64a17d72..7b450650bcae 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -32,6 +32,7 @@ config CLK_RENESAS select CLK_R8A77995 if ARCH_R8A77995 select CLK_R8A779A0 if ARCH_R8A779A0 select CLK_R9A06G032 if ARCH_R9A06G032 + select CLK_R9A07G044 if ARCH_R9A07G044 select CLK_SH73A0 if ARCH_SH73A0 if CLK_RENESAS @@ -156,6 +157,10 @@ config CLK_R9A06G032 help This is a driver for R9A06G032 clocks +config CLK_R9A07G044 + bool "RZ/G2L clock support" if COMPILE_TEST + select CLK_RZG2L + config CLK_SH73A0 bool "SH-Mobile AG5 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP @@ -182,6 +187,10 @@ config CLK_RCAR_USB2_CLOCK_SEL help This is a driver for R-Car USB2 clock selector +config CLK_RZG2L + bool "Renesas RZ/G2L family clock support" if COMPILE_TEST + select RESET_CONTROLLER + # Generic config CLK_RENESAS_CPG_MSSR bool "CPG/MSSR clock support" if COMPILE_TEST diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index ef0d2bba92bf..5c6c5c721d98 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o +obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o # Family @@ -36,6 +37,7 @@ obj-$(CONFIG_CLK_RCAR_CPG_LIB) += rcar-cpg-lib.o obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o +obj-$(CONFIG_CLK_RZG2L) += renesas-rzg2l-cpg.o # Generic obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index 8fb68e703a6b..3abd6e5400ad 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -28,8 +28,7 @@ * @hw: handle between common and hardware-specific interfaces * @reg: IO-remapped register * @div: divisor value (1-64) - * @src_shift: Shift to access the register bits to select the parent clock - * @src_width: Number of register bits to select the parent clock (may be 0) + * @src_mask: Bitmask covering the register bits to select the parent clock * @nb: Notifier block to save/restore clock state for system resume * @parents: Array to map from valid parent clocks indices to hardware indices */ @@ -37,8 +36,7 @@ struct div6_clock { struct clk_hw hw; void __iomem *reg; unsigned int div; - u32 src_shift; - u32 src_width; + u32 src_mask; struct notifier_block nb; u8 parents[]; }; @@ -99,15 +97,52 @@ static unsigned int cpg_div6_clock_calc_div(unsigned long rate, rate = 1; div = DIV_ROUND_CLOSEST(parent_rate, rate); - return clamp_t(unsigned int, div, 1, 64); + return clamp(div, 1U, 64U); } -static long cpg_div6_clock_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int cpg_div6_clock_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - unsigned int div = cpg_div6_clock_calc_div(rate, *parent_rate); + unsigned long prate, calc_rate, diff, best_rate, best_prate; + unsigned int num_parents = clk_hw_get_num_parents(hw); + struct clk_hw *parent, *best_parent = NULL; + unsigned int i, min_div, max_div, div; + unsigned long min_diff = ULONG_MAX; + + for (i = 0; i < num_parents; i++) { + parent = clk_hw_get_parent_by_index(hw, i); + if (!parent) + continue; + + prate = clk_hw_get_rate(parent); + if (!prate) + continue; + + min_div = max(DIV_ROUND_UP(prate, req->max_rate), 1UL); + max_div = req->min_rate ? min(prate / req->min_rate, 64UL) : 64; + if (max_div < min_div) + continue; + + div = cpg_div6_clock_calc_div(req->rate, prate); + div = clamp(div, min_div, max_div); + calc_rate = prate / div; + diff = calc_rate > req->rate ? calc_rate - req->rate + : req->rate - calc_rate; + if (diff < min_diff) { + best_rate = calc_rate; + best_parent = parent; + best_prate = prate; + min_diff = diff; + } + } + + if (!best_parent) + return -EINVAL; - return *parent_rate / div; + req->best_parent_rate = best_prate; + req->best_parent_hw = best_parent; + req->rate = best_rate; + return 0; } static int cpg_div6_clock_set_rate(struct clk_hw *hw, unsigned long rate, @@ -133,11 +168,11 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) unsigned int i; u8 hw_index; - if (clock->src_width == 0) + if (clock->src_mask == 0) return 0; - hw_index = (readl(clock->reg) >> clock->src_shift) & - (BIT(clock->src_width) - 1); + hw_index = (readl(clock->reg) & clock->src_mask) >> + __ffs(clock->src_mask); for (i = 0; i < clk_hw_get_num_parents(hw); i++) { if (clock->parents[i] == hw_index) return i; @@ -151,18 +186,13 @@ static u8 cpg_div6_clock_get_parent(struct clk_hw *hw) static int cpg_div6_clock_set_parent(struct clk_hw *hw, u8 index) { struct div6_clock *clock = to_div6_clock(hw); - u8 hw_index; - u32 mask; + u32 src; if (index >= clk_hw_get_num_parents(hw)) return -EINVAL; - mask = ~((BIT(clock->src_width) - 1) << clock->src_shift); - hw_index = clock->parents[index]; - - writel((readl(clock->reg) & mask) | (hw_index << clock->src_shift), - clock->reg); - + src = clock->parents[index] << __ffs(clock->src_mask); + writel((readl(clock->reg) & ~clock->src_mask) | src, clock->reg); return 0; } @@ -173,7 +203,7 @@ static const struct clk_ops cpg_div6_clock_ops = { .get_parent = cpg_div6_clock_get_parent, .set_parent = cpg_div6_clock_set_parent, .recalc_rate = cpg_div6_clock_recalc_rate, - .round_rate = cpg_div6_clock_round_rate, + .determine_rate = cpg_div6_clock_determine_rate, .set_rate = cpg_div6_clock_set_rate, }; @@ -236,17 +266,15 @@ struct clk * __init cpg_div6_register(const char *name, switch (num_parents) { case 1: /* fixed parent clock */ - clock->src_shift = clock->src_width = 0; + clock->src_mask = 0; break; case 4: /* clock with EXSRC bits 6-7 */ - clock->src_shift = 6; - clock->src_width = 2; + clock->src_mask = GENMASK(7, 6); break; case 8: /* VCLK with EXSRC bits 12-14 */ - clock->src_shift = 12; - clock->src_width = 3; + clock->src_mask = GENMASK(14, 12); break; default: pr_err("%s: invalid number of parents for DIV6 clock %s\n", diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index 9cfd00cf4e69..81c0bc1e78af 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), /* Core Clock Outputs */ + DEF_FIXED("za2", R8A77995_CLK_ZA2, CLK_PLL0D3, 2, 1), DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 867c565cb58f..acaf5a93f1d3 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -180,6 +180,10 @@ static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = { DEF_MOD("i2c4", 522, R8A779A0_CLK_S1D4), DEF_MOD("i2c5", 523, R8A779A0_CLK_S1D4), DEF_MOD("i2c6", 524, R8A779A0_CLK_S1D4), + DEF_MOD("ispcs0", 612, R8A779A0_CLK_S1D1), + DEF_MOD("ispcs1", 613, R8A779A0_CLK_S1D1), + DEF_MOD("ispcs2", 614, R8A779A0_CLK_S1D1), + DEF_MOD("ispcs3", 615, R8A779A0_CLK_S1D1), DEF_MOD("msi0", 618, R8A779A0_CLK_MSO), DEF_MOD("msi1", 619, R8A779A0_CLK_MSO), DEF_MOD("msi2", 620, R8A779A0_CLK_MSO), diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 71b11443f6fc..c99942f0e4d4 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -604,20 +604,19 @@ r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, return div; } -static long -r9a06g032_div_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *prate) +static int +r9a06g032_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); - u32 div = DIV_ROUND_UP(*prate, rate); + u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate); pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__, - hw->clk, rate, *prate, div); + hw->clk, req->rate, req->best_parent_rate, div); pr_devel(" min %d (%ld) max %d (%ld)\n", - clk->min, DIV_ROUND_UP(*prate, clk->min), - clk->max, DIV_ROUND_UP(*prate, clk->max)); + clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min), + clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max)); - div = r9a06g032_div_clamp_div(clk, rate, *prate); + div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate); /* * this is a hack. Currently the serial driver asks for a clock rate * that is 16 times the baud rate -- and that is wildly outside the @@ -630,11 +629,13 @@ r9a06g032_div_round_rate(struct clk_hw *hw, if (clk->index == R9A06G032_DIV_UART || clk->index == R9A06G032_DIV_P2_PG) { pr_devel("%s div uart hack!\n", __func__); - return clk_get_rate(hw->clk); + req->rate = clk_get_rate(hw->clk); + return 0; } + req->rate = DIV_ROUND_UP(req->best_parent_rate, div); pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, - *prate, div, DIV_ROUND_UP(*prate, div)); - return DIV_ROUND_UP(*prate, div); + req->best_parent_rate, div, req->rate); + return 0; } static int @@ -663,7 +664,7 @@ r9a06g032_div_set_rate(struct clk_hw *hw, static const struct clk_ops r9a06g032_clk_div_ops = { .recalc_rate = r9a06g032_div_recalc_rate, - .round_rate = r9a06g032_div_round_rate, + .determine_rate = r9a06g032_div_determine_rate, .set_rate = r9a06g032_div_set_rate, }; diff --git a/drivers/clk/renesas/r9a07g044-cpg.c b/drivers/clk/renesas/r9a07g044-cpg.c new file mode 100644 index 000000000000..50b5269586a4 --- /dev/null +++ b/drivers/clk/renesas/r9a07g044-cpg.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G2L CPG driver + * + * Copyright (C) 2021 Renesas Electronics Corp. + */ + +#include <linux/clk-provider.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/kernel.h> + +#include <dt-bindings/clock/r9a07g044-cpg.h> + +#include "renesas-rzg2l-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R9A07G044_OSCCLK, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_OSC_DIV1000, + CLK_PLL1, + CLK_PLL2, + CLK_PLL2_DIV2, + CLK_PLL2_DIV16, + CLK_PLL2_DIV20, + CLK_PLL3, + CLK_PLL3_DIV2, + CLK_PLL3_DIV4, + CLK_PLL3_DIV8, + CLK_PLL4, + CLK_PLL5, + CLK_PLL5_DIV2, + CLK_PLL6, + + /* Module Clocks */ + MOD_CLK_BASE, +}; + +/* Divider tables */ +static const struct clk_div_table dtable_3b[] = { + {0, 1}, + {1, 2}, + {2, 4}, + {3, 8}, + {4, 32}, +}; + +static const struct cpg_core_clk r9a07g044_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_FIXED(".osc", R9A07G044_OSCCLK, CLK_EXTAL, 1, 1), + DEF_FIXED(".osc_div1000", CLK_OSC_DIV1000, CLK_EXTAL, 1, 1000), + DEF_SAMPLL(".pll1", CLK_PLL1, CLK_EXTAL, PLL146_CONF(0)), + DEF_FIXED(".pll2", CLK_PLL2, CLK_EXTAL, 133, 2), + DEF_FIXED(".pll3", CLK_PLL3, CLK_EXTAL, 133, 2), + + DEF_FIXED(".pll2_div2", CLK_PLL2_DIV2, CLK_PLL2, 1, 2), + DEF_FIXED(".pll2_div16", CLK_PLL2_DIV16, CLK_PLL2, 1, 16), + DEF_FIXED(".pll2_div20", CLK_PLL2_DIV20, CLK_PLL2, 1, 20), + + DEF_FIXED(".pll3_div2", CLK_PLL3_DIV2, CLK_PLL3, 1, 2), + DEF_FIXED(".pll3_div4", CLK_PLL3_DIV4, CLK_PLL3, 1, 4), + DEF_FIXED(".pll3_div8", CLK_PLL3_DIV8, CLK_PLL3, 1, 8), + + /* Core output clk */ + DEF_FIXED("I", R9A07G044_CLK_I, CLK_PLL1, 1, 1), + DEF_DIV("P0", R9A07G044_CLK_P0, CLK_PLL2_DIV16, DIVPL2A, + dtable_3b, CLK_DIVIDER_HIWORD_MASK), + DEF_FIXED("TSU", R9A07G044_CLK_TSU, CLK_PLL2_DIV20, 1, 1), + DEF_DIV("P1", R9A07G044_CLK_P1, CLK_PLL3_DIV8, + DIVPL3B, dtable_3b, CLK_DIVIDER_HIWORD_MASK), +}; + +static struct rzg2l_mod_clk r9a07g044_mod_clks[] = { + DEF_MOD("gic", R9A07G044_CLK_GIC600, + R9A07G044_CLK_P1, + 0x514, BIT(0), (BIT(0) | BIT(1))), + DEF_MOD("ia55", R9A07G044_CLK_IA55, + R9A07G044_CLK_P1, + 0x518, (BIT(0) | BIT(1)), BIT(0)), + DEF_MOD("scif0", R9A07G044_CLK_SCIF0, + R9A07G044_CLK_P0, + 0x584, BIT(0), BIT(0)), + DEF_MOD("scif1", R9A07G044_CLK_SCIF1, + R9A07G044_CLK_P0, + 0x584, BIT(1), BIT(1)), + DEF_MOD("scif2", R9A07G044_CLK_SCIF2, + R9A07G044_CLK_P0, + 0x584, BIT(2), BIT(2)), + DEF_MOD("scif3", R9A07G044_CLK_SCIF3, + R9A07G044_CLK_P0, + 0x584, BIT(3), BIT(3)), + DEF_MOD("scif4", R9A07G044_CLK_SCIF4, + R9A07G044_CLK_P0, + 0x584, BIT(4), BIT(4)), + DEF_MOD("sci0", R9A07G044_CLK_SCI0, + R9A07G044_CLK_P0, + 0x588, BIT(0), BIT(0)), +}; + +static const unsigned int r9a07g044_crit_mod_clks[] __initconst = { + MOD_CLK_BASE + R9A07G044_CLK_GIC600, +}; + +const struct rzg2l_cpg_info r9a07g044_cpg_info = { + /* Core Clocks */ + .core_clks = r9a07g044_core_clks, + .num_core_clks = ARRAY_SIZE(r9a07g044_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Critical Module Clocks */ + .crit_mod_clks = r9a07g044_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r9a07g044_crit_mod_clks), + + /* Module Clocks */ + .mod_clks = r9a07g044_mod_clks, + .num_mod_clks = ARRAY_SIZE(r9a07g044_mod_clks), + .num_hw_mod_clks = R9A07G044_CLK_MIPI_DSI_PIN + 1, +}; diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index caa0f9414e45..558191c99b48 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -26,19 +26,135 @@ #include "rcar-cpg-lib.h" #include "rcar-gen3-cpg.h" -#define CPG_PLL0CR 0x00d8 +#define CPG_PLLECR 0x00d0 /* PLL Enable Control Register */ + +#define CPG_PLLECR_PLLST(n) BIT(8 + (n)) /* PLLn Circuit Status */ + +#define CPG_PLL0CR 0x00d8 /* PLLn Control Registers */ #define CPG_PLL2CR 0x002c #define CPG_PLL4CR 0x01f4 +#define CPG_PLLnCR_STC_MASK GENMASK(30, 24) /* PLL Circuit Mult. Ratio */ + #define CPG_RCKCR_CKSEL BIT(15) /* RCLK Clock Source Select */ +/* PLL Clocks */ +struct cpg_pll_clk { + struct clk_hw hw; + void __iomem *pllcr_reg; + void __iomem *pllecr_reg; + unsigned int fixed_mult; + u32 pllecr_pllst_mask; +}; + +#define to_pll_clk(_hw) container_of(_hw, struct cpg_pll_clk, hw) + +static unsigned long cpg_pll_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct cpg_pll_clk *pll_clk = to_pll_clk(hw); + unsigned int mult; + u32 val; + + val = readl(pll_clk->pllcr_reg) & CPG_PLLnCR_STC_MASK; + mult = (val >> __ffs(CPG_PLLnCR_STC_MASK)) + 1; + + return parent_rate * mult * pll_clk->fixed_mult; +} + +static int cpg_pll_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct cpg_pll_clk *pll_clk = to_pll_clk(hw); + unsigned int min_mult, max_mult, mult; + unsigned long prate; + + prate = req->best_parent_rate * pll_clk->fixed_mult; + min_mult = max(div64_ul(req->min_rate, prate), 1ULL); + max_mult = min(div64_ul(req->max_rate, prate), 128ULL); + if (max_mult < min_mult) + return -EINVAL; + + mult = DIV_ROUND_CLOSEST_ULL(req->rate, prate); + mult = clamp(mult, min_mult, max_mult); + + req->rate = prate * mult; + return 0; +} + +static int cpg_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct cpg_pll_clk *pll_clk = to_pll_clk(hw); + unsigned int mult, i; + u32 val; + + mult = DIV_ROUND_CLOSEST_ULL(rate, parent_rate * pll_clk->fixed_mult); + mult = clamp(mult, 1U, 128U); + + val = readl(pll_clk->pllcr_reg); + val &= ~CPG_PLLnCR_STC_MASK; + val |= (mult - 1) << __ffs(CPG_PLLnCR_STC_MASK); + writel(val, pll_clk->pllcr_reg); + + for (i = 1000; i; i--) { + if (readl(pll_clk->pllecr_reg) & pll_clk->pllecr_pllst_mask) + return 0; + + cpu_relax(); + } + + return -ETIMEDOUT; +} + +static const struct clk_ops cpg_pll_clk_ops = { + .recalc_rate = cpg_pll_clk_recalc_rate, + .determine_rate = cpg_pll_clk_determine_rate, + .set_rate = cpg_pll_clk_set_rate, +}; + +static struct clk * __init cpg_pll_clk_register(const char *name, + const char *parent_name, + void __iomem *base, + unsigned int mult, + unsigned int offset, + unsigned int index) + +{ + struct cpg_pll_clk *pll_clk; + struct clk_init_data init = {}; + struct clk *clk; + + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &cpg_pll_clk_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll_clk->hw.init = &init; + pll_clk->pllcr_reg = base + offset; + pll_clk->pllecr_reg = base + CPG_PLLECR; + pll_clk->fixed_mult = mult; /* PLL refclk x (setting + 1) x mult */ + pll_clk->pllecr_pllst_mask = CPG_PLLECR_PLLST(index); + + clk = clk_register(NULL, &pll_clk->hw); + if (IS_ERR(clk)) + kfree(pll_clk); + + return clk; +} + /* * Z Clock & Z2 Clock * * Traits of this clock: * prepare - clk_prepare only ensures that parents are prepared * enable - clk_enable only ensures that parents are enabled - * rate - rate is adjustable. clk->rate = (parent->rate * mult / 32 ) / 2 + * rate - rate is adjustable. + * clk->rate = (parent->rate * mult / 32 ) / fixed_div * parent - fixed parent. No clk_set_parent support */ #define CPG_FRQCRB 0x00000004 @@ -49,8 +165,9 @@ struct cpg_z_clk { struct clk_hw hw; void __iomem *reg; void __iomem *kick_reg; - unsigned long mask; + unsigned long max_rate; /* Maximum rate for normal mode */ unsigned int fixed_div; + u32 mask; }; #define to_z_clk(_hw) container_of(_hw, struct cpg_z_clk, hw) @@ -74,7 +191,18 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw, { struct cpg_z_clk *zclk = to_z_clk(hw); unsigned int min_mult, max_mult, mult; - unsigned long prate; + unsigned long rate, prate; + + rate = min(req->rate, req->max_rate); + if (rate <= zclk->max_rate) { + /* Set parent rate to initial value for normal modes */ + prate = zclk->max_rate; + } else { + /* Set increased parent rate for boost modes */ + prate = rate; + } + req->best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), + prate * zclk->fixed_div); prate = req->best_parent_rate / zclk->fixed_div; min_mult = max(div64_ul(req->min_rate * 32ULL, prate), 1ULL); @@ -82,10 +210,10 @@ static int cpg_z_clk_determine_rate(struct clk_hw *hw, if (max_mult < min_mult) return -EINVAL; - mult = div64_ul(req->rate * 32ULL, prate); + mult = DIV_ROUND_CLOSEST_ULL(rate * 32ULL, prate); mult = clamp(mult, min_mult, max_mult); - req->rate = div_u64((u64)prate * mult, 32); + req->rate = DIV_ROUND_CLOSEST_ULL((u64)prate * mult, 32); return 0; } @@ -103,8 +231,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, if (readl(zclk->kick_reg) & CPG_FRQCRB_KICK) return -EBUSY; - cpg_reg_modify(zclk->reg, zclk->mask, - ((32 - mult) << __ffs(zclk->mask)) & zclk->mask); + cpg_reg_modify(zclk->reg, zclk->mask, (32 - mult) << __ffs(zclk->mask)); /* * Set KICK bit in FRQCRB to update hardware setting and wait for @@ -117,7 +244,7 @@ static int cpg_z_clk_set_rate(struct clk_hw *hw, unsigned long rate, * * Using experimental measurements, it seems that no more than * ~10 iterations are needed, independently of the CPU rate. - * Since this value might be dependent of external xtal rate, pll1 + * Since this value might be dependent on external xtal rate, pll1 * rate or even the other emulation clocks rate, use 1000 as a * "super" safe value. */ @@ -153,7 +280,7 @@ static struct clk * __init cpg_z_clk_register(const char *name, init.name = name; init.ops = &cpg_z_clk_ops; - init.flags = 0; + init.flags = CLK_SET_RATE_PARENT; init.parent_names = &parent_name; init.num_parents = 1; @@ -164,9 +291,13 @@ static struct clk * __init cpg_z_clk_register(const char *name, zclk->fixed_div = div; /* PLLVCO x 1/div x SYS-CPU divider */ clk = clk_register(NULL, &zclk->hw); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { kfree(zclk); + return clk; + } + zclk->max_rate = clk_hw_get_rate(clk_hw_get_parent(&zclk->hw)) / + zclk->fixed_div; return clk; } @@ -314,16 +445,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_PLL0: /* - * PLL0 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. + * PLL0 is implemented as a custom clock, to change the + * multiplier when cpufreq changes between normal and boost + * modes. */ - value = readl(base + CPG_PLL0CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - if (cpg_quirks & PLL_ERRATA) - mult *= 2; - break; + mult = (cpg_quirks & PLL_ERRATA) ? 4 : 2; + return cpg_pll_clk_register(core->name, __clk_get_name(parent), + base, mult, CPG_PLL0CR, 0); case CLK_TYPE_GEN3_PLL1: mult = cpg_pll_config->pll1_mult; @@ -332,16 +460,13 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, case CLK_TYPE_GEN3_PLL2: /* - * PLL2 is a configurable multiplier clock. Register it as a - * fixed factor clock for now as there's no generic multiplier - * clock implementation and we currently have no need to change - * the multiplier value. + * PLL2 is implemented as a custom clock, to change the + * multiplier when cpufreq changes between normal and boost + * modes. */ - value = readl(base + CPG_PLL2CR); - mult = (((value >> 24) & 0x7f) + 1) * 2; - if (cpg_quirks & PLL_ERRATA) - mult *= 2; - break; + mult = (cpg_quirks & PLL_ERRATA) ? 4 : 2; + return cpg_pll_clk_register(core->name, __clk_get_name(parent), + base, mult, CPG_PLL2CR, 2); case CLK_TYPE_GEN3_PLL3: mult = cpg_pll_config->pll3_mult; diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c index 34a85dc95beb..9fb79bd79435 100644 --- a/drivers/clk/renesas/rcar-usb2-clock-sel.c +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c @@ -128,10 +128,8 @@ static int rcar_usb2_clock_sel_resume(struct device *dev) static int rcar_usb2_clock_sel_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev); of_clk_del_provider(dev->of_node); - clk_hw_unregister(&priv->hw); pm_runtime_put(dev); pm_runtime_disable(dev); @@ -164,9 +162,6 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) if (IS_ERR(priv->rsts)) return PTR_ERR(priv->rsts); - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - clk = devm_clk_get(dev, "usb_extal"); if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { priv->extal = !!clk_get_rate(clk); @@ -183,6 +178,8 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) return -ENOENT; } + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); platform_set_drvdata(pdev, priv); dev_set_drvdata(dev, priv); @@ -190,11 +187,20 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) init.ops = &usb2_clock_sel_clock_ops; priv->hw.init = &init; - clk = clk_register(NULL, &priv->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(NULL, &priv->hw); + if (ret) + goto pm_put; + + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); + if (ret) + goto pm_put; + + return 0; - return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); +pm_put: + pm_runtime_put(dev); + pm_runtime_disable(dev); + return ret; } static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = { diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index fc531d35b269..21f762aa2131 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -100,13 +100,9 @@ static const u16 srcr_for_v3u[] = { 0x2C20, 0x2C24, 0x2C28, 0x2C2C, 0x2C30, 0x2C34, 0x2C38, }; -/* Realtime Module Stop Control Register offsets */ -#define RMSTPCR(i) (smstpcr[i] - 0x20) - -/* Modem Module Stop Control Register offsets (r8a73a4) */ -#define MMSTPCR(i) (smstpcr[i] + 0x20) - -/* Software Reset Clearing Register offsets */ +/* + * Software Reset Clearing Register offsets + */ static const u16 srstclr[] = { 0x940, 0x944, 0x948, 0x94C, 0x950, 0x954, 0x958, 0x95C, diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.c b/drivers/clk/renesas/renesas-rzg2l-cpg.c new file mode 100644 index 000000000000..5009b9e48b13 --- /dev/null +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.c @@ -0,0 +1,750 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + * Based on renesas-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2013 Ideas On Board SPRL + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clk/renesas.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/init.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/pm_clock.h> +#include <linux/pm_domain.h> +#include <linux/reset-controller.h> +#include <linux/slab.h> + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +#include "renesas-rzg2l-cpg.h" + +#ifdef DEBUG +#define WARN_DEBUG(x) WARN_ON(x) +#else +#define WARN_DEBUG(x) do { } while (0) +#endif + +#define DIV_RSMASK(v, s, m) ((v >> s) & m) +#define GET_SHIFT(val) ((val >> 12) & 0xff) +#define GET_WIDTH(val) ((val >> 8) & 0xf) + +#define KDIV(val) DIV_RSMASK(val, 16, 0xffff) +#define MDIV(val) DIV_RSMASK(val, 6, 0x3ff) +#define PDIV(val) DIV_RSMASK(val, 0, 0x3f) +#define SDIV(val) DIV_RSMASK(val, 0, 0x7) + +#define CLK_ON_R(reg) (reg) +#define CLK_MON_R(reg) (0x680 - 0x500 + (reg)) +#define CLK_RST_R(reg) (0x800 - 0x500 + (reg)) +#define CLK_MRST_R(reg) (0x980 - 0x500 + (reg)) + +#define GET_REG_OFFSET(val) ((val >> 20) & 0xfff) +#define GET_REG_SAMPLL_CLK1(val) ((val >> 22) & 0xfff) +#define GET_REG_SAMPLL_CLK2(val) ((val >> 12) & 0xfff) + +/** + * struct rzg2l_cpg_priv - Clock Pulse Generator Private Data + * + * @rcdev: Reset controller entity + * @dev: CPG device + * @base: CPG register block base address + * @rmw_lock: protects register accesses + * @clks: Array containing all Core and Module Clocks + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @notifiers: Notifier chain to save/restore clock state for system resume + * @info: Pointer to platform data + */ +struct rzg2l_cpg_priv { + struct reset_controller_dev rcdev; + struct device *dev; + void __iomem *base; + spinlock_t rmw_lock; + + struct clk **clks; + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int last_dt_core_clk; + + struct raw_notifier_head notifiers; + const struct rzg2l_cpg_info *info; +}; + +static void rzg2l_cpg_del_clk_provider(void *data) +{ + of_clk_del_provider(data); +} + +static struct clk * __init +rzg2l_cpg_div_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + const char *parent_name; + struct clk_hw *clk_hw; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + parent_name = __clk_get_name(parent); + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, + core->dtable, + &priv->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, + parent_name, 0, + base + GET_REG_OFFSET(core->conf), + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), + core->flag, &priv->rmw_lock); + + if (IS_ERR(clk_hw)) + return NULL; + + return clk_hw->clk; +} + +struct pll_clk { + struct clk_hw hw; + unsigned int conf; + unsigned int type; + void __iomem *base; + struct rzg2l_cpg_priv *priv; +}; + +#define to_pll(_hw) container_of(_hw, struct pll_clk, hw) + +static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct pll_clk *pll_clk = to_pll(hw); + struct rzg2l_cpg_priv *priv = pll_clk->priv; + unsigned int val1, val2; + unsigned int mult = 1; + unsigned int div = 1; + + if (pll_clk->type != CLK_TYPE_SAM_PLL) + return parent_rate; + + val1 = readl(priv->base + GET_REG_SAMPLL_CLK1(pll_clk->conf)); + val2 = readl(priv->base + GET_REG_SAMPLL_CLK2(pll_clk->conf)); + mult = MDIV(val1) + KDIV(val1) / 65536; + div = PDIV(val1) * (1 << SDIV(val2)); + + return DIV_ROUND_CLOSEST_ULL((u64)parent_rate * mult, div); +} + +static const struct clk_ops rzg2l_cpg_pll_ops = { + .recalc_rate = rzg2l_cpg_pll_clk_recalc_rate, +}; + +static struct clk * __init +rzg2l_cpg_pll_clk_register(const struct cpg_core_clk *core, + struct clk **clks, + void __iomem *base, + struct rzg2l_cpg_priv *priv) +{ + struct device *dev = priv->dev; + const struct clk *parent; + struct clk_init_data init; + const char *parent_name; + struct pll_clk *pll_clk; + struct clk *clk; + + parent = clks[core->parent & 0xffff]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); + if (!pll_clk) { + clk = ERR_PTR(-ENOMEM); + return NULL; + } + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = &rzg2l_cpg_pll_ops; + init.flags = 0; + init.parent_names = &parent_name; + init.num_parents = 1; + + pll_clk->hw.init = &init; + pll_clk->conf = core->conf; + pll_clk->base = base; + pll_clk->priv = priv; + pll_clk->type = core->type; + + clk = clk_register(NULL, &pll_clk->hw); + if (IS_ERR(clk)) + kfree(pll_clk); + + return clk; +} + +static struct clk +*rzg2l_cpg_clk_src_twocell_get(struct of_phandle_args *clkspec, + void *data) +{ + unsigned int clkidx = clkspec->args[1]; + struct rzg2l_cpg_priv *priv = data; + struct device *dev = priv->dev; + const char *type; + struct clk *clk; + + switch (clkspec->args[0]) { + case CPG_CORE: + type = "core"; + if (clkidx > priv->last_dt_core_clk) { + dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[clkidx]; + break; + + case CPG_MOD: + type = "module"; + if (clkidx > priv->num_mod_clks) { + dev_err(dev, "Invalid %s clock index %u\n", type, + clkidx); + return ERR_PTR(-EINVAL); + } + clk = priv->clks[priv->num_core_clks + clkidx]; + break; + + default: + dev_err(dev, "Invalid CPG clock type %u\n", clkspec->args[0]); + return ERR_PTR(-EINVAL); + } + + if (IS_ERR(clk)) + dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + PTR_ERR(clk)); + else + dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", + clkspec->args[0], clkspec->args[1], clk, + clk_get_rate(clk)); + return clk; +} + +static void __init +rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct clk *clk = ERR_PTR(-EOPNOTSUPP), *parent; + struct device *dev = priv->dev; + unsigned int id = core->id, div = core->div; + const char *parent_name; + + WARN_DEBUG(id >= priv->num_core_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!core->name) { + /* Skip NULLified clock */ + return; + } + + switch (core->type) { + case CLK_TYPE_IN: + clk = of_clk_get_by_name(priv->dev->of_node, core->name); + break; + case CLK_TYPE_FF: + WARN_DEBUG(core->parent >= priv->num_core_clks); + parent = priv->clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + parent_name = __clk_get_name(parent); + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, CLK_SET_RATE_PARENT, + core->mult, div); + break; + case CLK_TYPE_SAM_PLL: + clk = rzg2l_cpg_pll_clk_register(core, priv->clks, + priv->base, priv); + break; + case CLK_TYPE_DIV: + clk = rzg2l_cpg_div_clk_register(core, priv->clks, + priv->base, priv); + break; + default: + goto fail; + }; + + if (IS_ERR_OR_NULL(clk)) + goto fail; + + dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "core", + core->name, PTR_ERR(clk)); +} + +/** + * struct mstp_clock - MSTP gating clock + * + * @hw: handle between common and hardware-specific interfaces + * @off: register offset + * @onoff: ON/MON bits + * @reset: reset bits + * @priv: CPG/MSTP private data + */ +struct mstp_clock { + struct clk_hw hw; + u16 off; + u8 onoff; + u8 reset; + struct rzg2l_cpg_priv *priv; +}; + +#define to_mod_clock(_hw) container_of(_hw, struct mstp_clock, hw) + +static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + unsigned int reg = clock->off; + struct device *dev = priv->dev; + unsigned long flags; + unsigned int i; + u32 value; + + if (!clock->off) { + dev_dbg(dev, "%pC does not support ON/OFF\n", hw->clk); + return 0; + } + + dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->rmw_lock, flags); + + if (enable) + value = (clock->onoff << 16) | clock->onoff; + else + value = clock->onoff << 16; + writel(value, priv->base + CLK_ON_R(reg)); + + spin_unlock_irqrestore(&priv->rmw_lock, flags); + + if (!enable) + return 0; + + for (i = 1000; i > 0; --i) { + if (((readl(priv->base + CLK_MON_R(reg))) & clock->onoff)) + break; + cpu_relax(); + } + + if (!i) { + dev_err(dev, "Failed to enable CLK_ON %p\n", + priv->base + CLK_ON_R(reg)); + return -ETIMEDOUT; + } + + return 0; +} + +static int rzg2l_mod_clock_enable(struct clk_hw *hw) +{ + return rzg2l_mod_clock_endisable(hw, true); +} + +static void rzg2l_mod_clock_disable(struct clk_hw *hw) +{ + rzg2l_mod_clock_endisable(hw, false); +} + +static int rzg2l_mod_clock_is_enabled(struct clk_hw *hw) +{ + struct mstp_clock *clock = to_mod_clock(hw); + struct rzg2l_cpg_priv *priv = clock->priv; + u32 value; + + if (!clock->off) { + dev_dbg(priv->dev, "%pC does not support ON/OFF\n", hw->clk); + return 1; + } + + value = readl(priv->base + CLK_MON_R(clock->off)); + + return !(value & clock->onoff); +} + +static const struct clk_ops rzg2l_mod_clock_ops = { + .enable = rzg2l_mod_clock_enable, + .disable = rzg2l_mod_clock_disable, + .is_enabled = rzg2l_mod_clock_is_enabled, +}; + +static void __init +rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod, + const struct rzg2l_cpg_info *info, + struct rzg2l_cpg_priv *priv) +{ + struct mstp_clock *clock = NULL; + struct device *dev = priv->dev; + unsigned int id = mod->id; + struct clk_init_data init; + struct clk *parent, *clk; + const char *parent_name; + unsigned int i; + + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); + + if (!mod->name) { + /* Skip NULLified clock */ + return; + } + + parent = priv->clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; + } + + clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL); + if (!clock) { + clk = ERR_PTR(-ENOMEM); + goto fail; + } + + init.name = mod->name; + init.ops = &rzg2l_mod_clock_ops; + init.flags = CLK_SET_RATE_PARENT; + for (i = 0; i < info->num_crit_mod_clks; i++) + if (id == info->crit_mod_clks[i]) { + dev_dbg(dev, "CPG %s setting CLK_IS_CRITICAL\n", + mod->name); + init.flags |= CLK_IS_CRITICAL; + break; + } + + parent_name = __clk_get_name(parent); + init.parent_names = &parent_name; + init.num_parents = 1; + + clock->off = mod->off; + clock->onoff = mod->onoff; + clock->reset = mod->reset; + clock->priv = priv; + clock->hw.init = &init; + + clk = clk_register(NULL, &clock->hw); + if (IS_ERR(clk)) + goto fail; + + dev_dbg(dev, "Module clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); + priv->clks[id] = clk; + return; + +fail: + dev_err(dev, "Failed to register %s clock %s: %ld\n", "module", + mod->name, PTR_ERR(clk)); + kfree(clock); +} + +#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) + +static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->mod_clks[id].off; + u32 dis = info->mod_clks[id].reset; + u32 we = dis << 16; + + dev_dbg(rcdev->dev, "reset name:%s id:%ld offset:0x%x\n", + info->mod_clks[id].name, id, CLK_RST_R(reg)); + + /* Reset module */ + writel(we, priv->base + CLK_RST_R(reg)); + + /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ + udelay(35); + + /* Release module from reset state */ + writel(we | dis, priv->base + CLK_RST_R(reg)); + + return 0; +} + +static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->mod_clks[id].off; + u32 value = info->mod_clks[id].reset << 16; + + dev_dbg(rcdev->dev, "assert name:%s id:%ld offset:0x%x\n", + info->mod_clks[id].name, id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->mod_clks[id].off; + u32 dis = info->mod_clks[id].reset; + u32 value = (dis << 16) | dis; + + dev_dbg(rcdev->dev, "deassert name:%s id:%ld offset:0x%x\n", + info->mod_clks[id].name, id, CLK_RST_R(reg)); + + writel(value, priv->base + CLK_RST_R(reg)); + return 0; +} + +static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); + const struct rzg2l_cpg_info *info = priv->info; + unsigned int reg = info->mod_clks[id].off; + u32 bitmask = info->mod_clks[id].reset; + + return !(readl(priv->base + CLK_MRST_R(reg)) & bitmask); +} + +static const struct reset_control_ops rzg2l_cpg_reset_ops = { + .reset = rzg2l_cpg_reset, + .assert = rzg2l_cpg_assert, + .deassert = rzg2l_cpg_deassert, + .status = rzg2l_cpg_status, +}; + +static int rzg2l_cpg_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + unsigned int id = reset_spec->args[0]; + + if (id >= rcdev->nr_resets) { + dev_err(rcdev->dev, "Invalid reset index %u\n", id); + return -EINVAL; + } + + return id; +} + +static int rzg2l_cpg_reset_controller_register(struct rzg2l_cpg_priv *priv) +{ + priv->rcdev.ops = &rzg2l_cpg_reset_ops; + priv->rcdev.of_node = priv->dev->of_node; + priv->rcdev.dev = priv->dev; + priv->rcdev.of_reset_n_cells = 1; + priv->rcdev.of_xlate = rzg2l_cpg_reset_xlate; + priv->rcdev.nr_resets = priv->num_mod_clks; + + return devm_reset_controller_register(priv->dev, &priv->rcdev); +} + +static bool rzg2l_cpg_is_pm_clk(const struct of_phandle_args *clkspec) +{ + if (clkspec->args_count != 2) + return false; + + switch (clkspec->args[0]) { + case CPG_MOD: + return true; + + default: + return false; + } +} + +static int rzg2l_cpg_attach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + struct device_node *np = dev->of_node; + struct of_phandle_args clkspec; + struct clk *clk; + int error; + int i = 0; + + while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i, + &clkspec)) { + if (rzg2l_cpg_is_pm_clk(&clkspec)) + goto found; + + of_node_put(clkspec.np); + i++; + } + + return 0; + +found: + clk = of_clk_get_from_provider(&clkspec); + of_node_put(clkspec.np); + + if (IS_ERR(clk)) + return PTR_ERR(clk); + + error = pm_clk_create(dev); + if (error) + goto fail_put; + + error = pm_clk_add_clk(dev, clk); + if (error) + goto fail_destroy; + + return 0; + +fail_destroy: + pm_clk_destroy(dev); +fail_put: + clk_put(clk); + return error; +} + +static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device *dev) +{ + if (!pm_clk_no_clocks(dev)) + pm_clk_destroy(dev); +} + +static int __init rzg2l_cpg_add_clk_domain(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct generic_pm_domain *genpd; + + genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); + if (!genpd) + return -ENOMEM; + + genpd->name = np->name; + genpd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | + GENPD_FLAG_ACTIVE_WAKEUP; + genpd->attach_dev = rzg2l_cpg_attach_dev; + genpd->detach_dev = rzg2l_cpg_detach_dev; + pm_genpd_init(genpd, &pm_domain_always_on_gov, false); + + of_genpd_add_provider_simple(np, genpd); + return 0; +} + +static int __init rzg2l_cpg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct rzg2l_cpg_info *info; + struct rzg2l_cpg_priv *priv; + unsigned int nclks, i; + struct clk **clks; + int error; + + info = of_device_get_match_data(dev); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->info = info; + spin_lock_init(&priv->rmw_lock); + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + nclks = info->num_total_core_clks + info->num_hw_mod_clks; + clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) + return -ENOMEM; + + dev_set_drvdata(dev, priv); + priv->clks = clks; + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->last_dt_core_clk = info->last_dt_core_clk; + + for (i = 0; i < nclks; i++) + clks[i] = ERR_PTR(-ENOENT); + + for (i = 0; i < info->num_core_clks; i++) + rzg2l_cpg_register_core_clk(&info->core_clks[i], info, priv); + + for (i = 0; i < info->num_mod_clks; i++) + rzg2l_cpg_register_mod_clk(&info->mod_clks[i], info, priv); + + error = of_clk_add_provider(np, rzg2l_cpg_clk_src_twocell_get, priv); + if (error) + return error; + + error = devm_add_action_or_reset(dev, rzg2l_cpg_del_clk_provider, np); + if (error) + return error; + + error = rzg2l_cpg_add_clk_domain(dev); + if (error) + return error; + + error = rzg2l_cpg_reset_controller_register(priv); + if (error) + return error; + + return 0; +} + +static const struct of_device_id rzg2l_cpg_match[] = { +#ifdef CONFIG_CLK_R9A07G044 + { + .compatible = "renesas,r9a07g044-cpg", + .data = &r9a07g044_cpg_info, + }, +#endif + { /* sentinel */ } +}; + +static struct platform_driver rzg2l_cpg_driver = { + .driver = { + .name = "rzg2l-cpg", + .of_match_table = rzg2l_cpg_match, + }, +}; + +static int __init rzg2l_cpg_init(void) +{ + return platform_driver_probe(&rzg2l_cpg_driver, rzg2l_cpg_probe); +} + +subsys_initcall(rzg2l_cpg_init); + +MODULE_DESCRIPTION("Renesas RZ/G2L CPG Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/renesas/renesas-rzg2l-cpg.h b/drivers/clk/renesas/renesas-rzg2l-cpg.h new file mode 100644 index 000000000000..3948bdd8afc9 --- /dev/null +++ b/drivers/clk/renesas/renesas-rzg2l-cpg.h @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * RZ/G2L Clock Pulse Generator + * + * Copyright (C) 2021 Renesas Electronics Corp. + * + */ + +#ifndef __RENESAS_RZG2L_CPG_H__ +#define __RENESAS_RZG2L_CPG_H__ + +#define CPG_PL2_DDIV (0x204) +#define CPG_PL3A_DDIV (0x208) + +/* n = 0/1/2 for PLL1/4/6 */ +#define CPG_SAMPLL_CLK1(n) (0x04 + (16 * n)) +#define CPG_SAMPLL_CLK2(n) (0x08 + (16 * n)) + +#define PLL146_CONF(n) (CPG_SAMPLL_CLK1(n) << 22 | CPG_SAMPLL_CLK2(n) << 12) + +#define DDIV_PACK(offset, bitpos, size) \ + (((offset) << 20) | ((bitpos) << 12) | ((size) << 8)) +#define DIVPL2A DDIV_PACK(CPG_PL2_DDIV, 0, 3) +#define DIVPL3B DDIV_PACK(CPG_PL3A_DDIV, 4, 3) + +/** + * Definitions of CPG Core Clocks + * + * These include: + * - Clock outputs exported to DT + * - External input clocks + * - Internal CPG clocks + */ +struct cpg_core_clk { + const char *name; + unsigned int id; + unsigned int parent; + unsigned int div; + unsigned int mult; + unsigned int type; + unsigned int conf; + const struct clk_div_table *dtable; + const char * const *parent_names; + int flag; + int num_parents; +}; + +enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ + CLK_TYPE_FF, /* Fixed Factor Clock */ + CLK_TYPE_SAM_PLL, + + /* Clock with divider */ + CLK_TYPE_DIV, +}; + +#define DEF_TYPE(_name, _id, _type...) \ + { .name = _name, .id = _id, .type = _type } +#define DEF_BASE(_name, _id, _type, _parent...) \ + DEF_TYPE(_name, _id, _type, .parent = _parent) +#define DEF_SAMPLL(_name, _id, _parent, _conf) \ + DEF_TYPE(_name, _id, CLK_TYPE_SAM_PLL, .parent = _parent, .conf = _conf) +#define DEF_INPUT(_name, _id) \ + DEF_TYPE(_name, _id, CLK_TYPE_IN) +#define DEF_FIXED(_name, _id, _parent, _mult, _div) \ + DEF_BASE(_name, _id, CLK_TYPE_FF, _parent, .div = _div, .mult = _mult) +#define DEF_DIV(_name, _id, _parent, _conf, _dtable, _flag) \ + DEF_TYPE(_name, _id, CLK_TYPE_DIV, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = _flag) + +/** + * struct rzg2l_mod_clk - Module Clocks definitions + * + * @name: handle between common and hardware-specific interfaces + * @id: clock index in array containing all Core and Module Clocks + * @parent: id of parent clock + * @off: register offset + * @onoff: ON/MON bits + * @reset: reset bits + */ +struct rzg2l_mod_clk { + const char *name; + unsigned int id; + unsigned int parent; + u16 off; + u8 onoff; + u8 reset; +}; + +#define DEF_MOD(_name, _id, _parent, _off, _onoff, _reset) \ + [_id] = { \ + .name = _name, \ + .id = MOD_CLK_BASE + _id, \ + .parent = (_parent), \ + .off = (_off), \ + .onoff = (_onoff), \ + .reset = (_reset) \ + } + +/** + * struct rzg2l_cpg_info - SoC-specific CPG Description + * + * @core_clks: Array of Core Clock definitions + * @num_core_clks: Number of entries in core_clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT + * @num_total_core_clks: Total number of Core Clocks (exported + internal) + * + * @mod_clks: Array of Module Clock definitions + * @num_mod_clks: Number of entries in mod_clks[] + * @num_hw_mod_clks: Number of Module Clocks supported by the hardware + * + * @crit_mod_clks: Array with Module Clock IDs of critical clocks that + * should not be disabled without a knowledgeable driver + * @num_crit_mod_clks: Number of entries in crit_mod_clks[] + */ +struct rzg2l_cpg_info { + /* Core Clocks */ + const struct cpg_core_clk *core_clks; + unsigned int num_core_clks; + unsigned int last_dt_core_clk; + unsigned int num_total_core_clks; + + /* Module Clocks */ + const struct rzg2l_mod_clk *mod_clks; + unsigned int num_mod_clks; + unsigned int num_hw_mod_clks; + + /* Critical Module Clocks that should not be disabled */ + const unsigned int *crit_mod_clks; + unsigned int num_crit_mod_clks; +}; + +extern const struct rzg2l_cpg_info r9a07g044_cpg_info; + +#endif diff --git a/drivers/clk/rockchip/clk-rk3036.c b/drivers/clk/rockchip/clk-rk3036.c index 91d56ad45817..614845cc5b4a 100644 --- a/drivers/clk/rockchip/clk-rk3036.c +++ b/drivers/clk/rockchip/clk-rk3036.c @@ -259,7 +259,7 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = { RK2928_CLKGATE_CON(1), 13, GFLAGS, &rk3036_uart2_fracmux), - COMPOSITE(0, "aclk_vcodec", mux_pll_src_3plls_p, 0, + COMPOSITE(ACLK_VCODEC, "aclk_vcodec", mux_pll_src_3plls_p, 0, RK2928_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS, RK2928_CLKGATE_CON(3), 11, GFLAGS), FACTOR_GATE(HCLK_VCODEC, "hclk_vcodec", "aclk_vcodec", 0, 1, 4, diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c index 946ea2f45bf3..75ca855e720d 100644 --- a/drivers/clk/rockchip/clk-rk3568.c +++ b/drivers/clk/rockchip/clk-rk3568.c @@ -454,17 +454,17 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = { COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", CLK_IGNORE_UNUSED, RK3568_CLKSEL_CON(80), 0, 5, DFLAGS, RK3568_CLKGATE_CON(35), 10, GFLAGS), + COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED, + RK3568_CLKSEL_CON(82), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 11, GFLAGS), COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", CLK_IGNORE_UNUSED, RK3568_CLKSEL_CON(80), 8, 5, DFLAGS, - RK3568_CLKGATE_CON(35), 11, GFLAGS), + RK3568_CLKGATE_CON(35), 12, GFLAGS), COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", CLK_IGNORE_UNUSED, RK3568_CLKSEL_CON(81), 0, 5, DFLAGS, - RK3568_CLKGATE_CON(35), 12, GFLAGS), + RK3568_CLKGATE_CON(35), 13, GFLAGS), COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", CLK_IGNORE_UNUSED, RK3568_CLKSEL_CON(81), 8, 6, DFLAGS, - RK3568_CLKGATE_CON(35), 13, GFLAGS), - COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", CLK_IGNORE_UNUSED, - RK3568_CLKSEL_CON(82), 0, 5, DFLAGS, RK3568_CLKGATE_CON(35), 14, GFLAGS), COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", CLK_IGNORE_UNUSED, RK3568_CLKSEL_CON(82), 8, 6, DFLAGS, diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h index 571cee7bbfdc..7aa45cc70287 100644 --- a/drivers/clk/rockchip/clk.h +++ b/drivers/clk/rockchip/clk.h @@ -271,17 +271,24 @@ struct rockchip_clk_provider { struct rockchip_pll_rate_table { unsigned long rate; - unsigned int nr; - unsigned int nf; - unsigned int no; - unsigned int nb; - /* for RK3036/RK3399 */ - unsigned int fbdiv; - unsigned int postdiv1; - unsigned int refdiv; - unsigned int postdiv2; - unsigned int dsmpd; - unsigned int frac; + union { + struct { + /* for RK3066 */ + unsigned int nr; + unsigned int nf; + unsigned int no; + unsigned int nb; + }; + struct { + /* for RK3036/RK3399 */ + unsigned int fbdiv; + unsigned int postdiv1; + unsigned int refdiv; + unsigned int postdiv2; + unsigned int dsmpd; + unsigned int frac; + }; + }; }; /** diff --git a/drivers/clk/sifive/sifive-prci.c b/drivers/clk/sifive/sifive-prci.c index 0d79ba31a793..80a288c59e56 100644 --- a/drivers/clk/sifive/sifive-prci.c +++ b/drivers/clk/sifive/sifive-prci.c @@ -564,7 +564,7 @@ static int __prci_register_clocks(struct device *dev, struct __prci_data *pd, } /** - * sifive_prci_init() - initialize prci data and check parent count + * sifive_prci_probe() - initialize prci data and check parent count * @pdev: platform device pointer for the prci * * Return: 0 upon success or a negative error code upon failure. diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index 92a6d740a799..1cb21ea79c64 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -177,6 +177,8 @@ static const struct clk_parent_data emac_mux[] = { .name = "emaca_free_clk", }, { .fw_name = "emacb_free_clk", .name = "emacb_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, }; static const struct clk_parent_data noc_mux[] = { @@ -186,6 +188,41 @@ static const struct clk_parent_data noc_mux[] = { .name = "boot_clk", }, }; +static const struct clk_parent_data sdmmc_mux[] = { + { .fw_name = "sdmmc_free_clk", + .name = "sdmmc_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data s2f_user1_mux[] = { + { .fw_name = "s2f_user1_free_clk", + .name = "s2f_user1_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data psi_mux[] = { + { .fw_name = "psi_ref_free_clk", + .name = "psi_ref_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data gpio_db_mux[] = { + { .fw_name = "gpio_db_free_clk", + .name = "gpio_db_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data emac_ptp_mux[] = { + { .fw_name = "emac_ptp_free_clk", + .name = "emac_ptp_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + /* clocks in AO (always on) controller */ static const struct stratix10_pll_clock agilex_pll_clks[] = { { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, @@ -222,11 +259,9 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), 0, 0x3C, 0, 0, 0}, { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), - 0, 0x40, 0, 0, 1}, - { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, - 0, 4, 0, 0}, - { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), - 0, 0, 0, 0x30, 1}, + 0, 0x40, 0, 0, 0}, + { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, + 0, 4, 0x30, 1}, { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0}, { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), @@ -236,7 +271,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3}, { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, - ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4}, + ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0}, { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, @@ -252,24 +287,24 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { 0, 0, 0, 0, 0, 0, 4}, { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24, 0, 0, 0, 0, 0, 0, 2}, - { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24, - 1, 0x44, 0, 2, 0, 0, 0}, - { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24, - 2, 0x44, 8, 2, 0, 0, 0}, + { AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 1, 0x44, 0, 2, 0x30, 1, 0}, + { AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 2, 0x44, 8, 2, 0x30, 1, 0}, /* * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them * being the SP timers, thus cannot get gated. */ - { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24, - 3, 0x44, 16, 2, 0, 0, 0}, - { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24, - 4, 0x44, 24, 2, 0, 0, 0}, - { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24, - 4, 0x44, 26, 2, 0, 0, 0}, + { AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24, + 3, 0x44, 16, 2, 0x30, 1, 0}, + { AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 4, 0x44, 24, 2, 0x30, 1, 0}, + { AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 4, 0x44, 26, 2, 0x30, 1, 0}, { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, 4, 0x44, 28, 1, 0, 0, 0}, - { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24, - 5, 0, 0, 0, 0, 0, 0}, + { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 5, 0, 0, 0, 0x30, 1, 0}, { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24, 6, 0, 0, 0, 0, 0, 0}, { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, @@ -278,16 +313,16 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { 1, 0, 0, 0, 0x94, 27, 0}, { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0}, - { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C, - 3, 0, 0, 0, 0, 0, 0}, - { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C, - 4, 0x98, 0, 16, 0, 0, 0}, - { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C, - 5, 0, 0, 0, 0, 0, 4}, - { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C, - 6, 0, 0, 0, 0, 0, 0}, - { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C, - 7, 0, 0, 0, 0, 0, 0}, + { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, + 3, 0, 0, 0, 0x88, 2, 0}, + { AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C, + 4, 0x98, 0, 16, 0x88, 3, 0}, + { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C, + 5, 0, 0, 0, 0x88, 4, 4}, + { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, + 6, 0, 0, 0, 0x88, 5, 0}, + { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C, + 7, 0, 0, 0, 0x88, 6, 0}, { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 8, 0, 0, 0, 0, 0, 0}, { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, @@ -366,7 +401,7 @@ static int agilex_clk_register_gate(const struct stratix10_gate_clock *clks, int i; for (i = 0; i < nums; i++) { - hw_clk = s10_register_gate(&clks[i], base); + hw_clk = agilex_register_gate(&clks[i], base); if (IS_ERR(hw_clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index b84f2627551e..32567795765f 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -11,6 +11,13 @@ #define SOCFPGA_CS_PDBG_CLK "cs_pdbg_clk" #define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw.hw) +#define SOCFPGA_EMAC0_CLK "emac0_clk" +#define SOCFPGA_EMAC1_CLK "emac1_clk" +#define SOCFPGA_EMAC2_CLK "emac2_clk" +#define AGILEX_BYPASS_OFFSET 0xC +#define STRATIX10_BYPASS_OFFSET 0x2C +#define BOOTCLK_BYPASS 2 + static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk, unsigned long parent_rate) { @@ -44,14 +51,61 @@ static unsigned long socfpga_dbg_clk_recalc_rate(struct clk_hw *hwclk, static u8 socfpga_gate_get_parent(struct clk_hw *hwclk) { struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); - u32 mask; + u32 mask, second_bypass; + u8 parent = 0; + const char *name = clk_hw_get_name(hwclk); + + if (socfpgaclk->bypass_reg) { + mask = (0x1 << socfpgaclk->bypass_shift); + parent = ((readl(socfpgaclk->bypass_reg) & mask) >> + socfpgaclk->bypass_shift); + } + + if (streq(name, SOCFPGA_EMAC0_CLK) || + streq(name, SOCFPGA_EMAC1_CLK) || + streq(name, SOCFPGA_EMAC2_CLK)) { + second_bypass = readl(socfpgaclk->bypass_reg - + STRATIX10_BYPASS_OFFSET); + /* EMACA bypass to bootclk @0xB0 offset */ + if (second_bypass & 0x1) + if (parent == 0) /* only applicable if parent is maca */ + parent = BOOTCLK_BYPASS; + + if (second_bypass & 0x2) + if (parent == 1) /* only applicable if parent is macb */ + parent = BOOTCLK_BYPASS; + } + return parent; +} + +static u8 socfpga_agilex_gate_get_parent(struct clk_hw *hwclk) +{ + struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk); + u32 mask, second_bypass; u8 parent = 0; + const char *name = clk_hw_get_name(hwclk); if (socfpgaclk->bypass_reg) { mask = (0x1 << socfpgaclk->bypass_shift); parent = ((readl(socfpgaclk->bypass_reg) & mask) >> socfpgaclk->bypass_shift); } + + if (streq(name, SOCFPGA_EMAC0_CLK) || + streq(name, SOCFPGA_EMAC1_CLK) || + streq(name, SOCFPGA_EMAC2_CLK)) { + second_bypass = readl(socfpgaclk->bypass_reg - + AGILEX_BYPASS_OFFSET); + /* EMACA bypass to bootclk @0x88 offset */ + if (second_bypass & 0x1) + if (parent == 0) /* only applicable if parent is maca */ + parent = BOOTCLK_BYPASS; + + if (second_bypass & 0x2) + if (parent == 1) /* only applicable if parent is macb */ + parent = BOOTCLK_BYPASS; + } + return parent; } @@ -60,6 +114,11 @@ static struct clk_ops gateclk_ops = { .get_parent = socfpga_gate_get_parent, }; +static const struct clk_ops agilex_gateclk_ops = { + .recalc_rate = socfpga_gate_clk_recalc_rate, + .get_parent = socfpga_agilex_gate_get_parent, +}; + static const struct clk_ops dbgclk_ops = { .recalc_rate = socfpga_dbg_clk_recalc_rate, .get_parent = socfpga_gate_get_parent, @@ -122,3 +181,61 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _ } return hw_clk; } + +struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase) +{ + struct clk_hw *hw_clk; + struct socfpga_gate_clk *socfpga_clk; + struct clk_init_data init; + const char *parent_name = clks->parent_name; + int ret; + + socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + if (!socfpga_clk) + return NULL; + + socfpga_clk->hw.reg = regbase + clks->gate_reg; + socfpga_clk->hw.bit_idx = clks->gate_idx; + + gateclk_ops.enable = clk_gate_ops.enable; + gateclk_ops.disable = clk_gate_ops.disable; + + socfpga_clk->fixed_div = clks->fixed_div; + + if (clks->div_reg) + socfpga_clk->div_reg = regbase + clks->div_reg; + else + socfpga_clk->div_reg = NULL; + + socfpga_clk->width = clks->div_width; + socfpga_clk->shift = clks->div_offset; + + if (clks->bypass_reg) + socfpga_clk->bypass_reg = regbase + clks->bypass_reg; + else + socfpga_clk->bypass_reg = NULL; + socfpga_clk->bypass_shift = clks->bypass_shift; + + if (streq(clks->name, "cs_pdbg_clk")) + init.ops = &dbgclk_ops; + else + init.ops = &agilex_gateclk_ops; + + init.name = clks->name; + init.flags = clks->flags; + + init.num_parents = clks->num_parents; + init.parent_names = parent_name ? &parent_name : NULL; + if (init.parent_names == NULL) + init.parent_data = clks->parent_data; + socfpga_clk->hw.hw.init = &init; + + hw_clk = &socfpga_clk->hw.hw; + + ret = clk_hw_register(NULL, &socfpga_clk->hw.hw); + if (ret) { + kfree(socfpga_clk); + return ERR_PTR(ret); + } + return hw_clk; +} diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index e5a5fef76df7..cbabde2b476b 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -64,16 +64,21 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk) { struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk); u32 clk_src, mask; - u8 parent; + u8 parent = 0; + /* handle the bypass first */ if (socfpgaclk->bypass_reg) { mask = (0x1 << socfpgaclk->bypass_shift); parent = ((readl(socfpgaclk->bypass_reg) & mask) >> socfpgaclk->bypass_shift); - } else { + if (parent) + return parent; + } + + if (socfpgaclk->hw.reg) { clk_src = readl(socfpgaclk->hw.reg); parent = (clk_src >> CLK_MGR_FREE_SHIFT) & - CLK_MGR_FREE_MASK; + CLK_MGR_FREE_MASK; } return parent; } diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c index dcb573d44034..127cc849c5ee 100644 --- a/drivers/clk/socfpga/clk-pll.c +++ b/drivers/clk/socfpga/clk-pll.c @@ -80,7 +80,6 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node, const char *parent_name[SOCFPGA_MAX_PARENTS]; struct clk_init_data init; struct device_node *clkmgr_np; - int rc; int err; of_property_read_u32(node, "reg", ®); @@ -114,7 +113,7 @@ static __init struct clk_hw *__socfpga_pll_init(struct device_node *node, kfree(pll_clk); return ERR_PTR(err); } - rc = of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); + of_clk_add_provider(node, of_clk_src_simple_get, hw_clk); return hw_clk; } diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index f0bd77138ecb..b532d51faaee 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c @@ -144,6 +144,41 @@ static const struct clk_parent_data mpu_free_mux[] = { .name = "f2s-free-clk", }, }; +static const struct clk_parent_data sdmmc_mux[] = { + { .fw_name = "sdmmc_free_clk", + .name = "sdmmc_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data s2f_user1_mux[] = { + { .fw_name = "s2f_user1_free_clk", + .name = "s2f_user1_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data psi_mux[] = { + { .fw_name = "psi_ref_free_clk", + .name = "psi_ref_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data gpio_db_mux[] = { + { .fw_name = "gpio_db_free_clk", + .name = "gpio_db_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data emac_ptp_mux[] = { + { .fw_name = "emac_ptp_free_clk", + .name = "emac_ptp_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + /* clocks in AO (always on) controller */ static const struct stratix10_pll_clock s10_pll_clks[] = { { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, @@ -167,7 +202,7 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), 0, 0x48, 0, 0, 0}, { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), - 0, 0x4C, 0, 0, 0}, + 0, 0x4C, 0, 0x3C, 1}, { STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0, 0x50, 0, 0, 0}, { STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0, @@ -200,10 +235,8 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { 0, 0xD4, 0, 0, 0}, { STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0, 0xD8, 0, 0, 0}, - { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, - 0, 4, 0, 0}, - { STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), - 0, 0, 0, 0x3C, 1}, + { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, + 0, 4, 0x3C, 1}, { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), 0, 0, 2, 0xB0, 0}, { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), @@ -227,20 +260,20 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { 0, 0, 0, 0, 0, 0, 4}, { STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 2}, - { STRATIX10_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x30, - 1, 0x70, 0, 2, 0, 0, 0}, - { STRATIX10_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x30, - 2, 0x70, 8, 2, 0, 0, 0}, - { STRATIX10_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x30, - 3, 0x70, 16, 2, 0, 0, 0}, - { STRATIX10_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x30, - 4, 0x70, 24, 2, 0, 0, 0}, - { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x30, - 4, 0x70, 26, 2, 0, 0, 0}, + { STRATIX10_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 1, 0x70, 0, 2, 0x3C, 1, 0}, + { STRATIX10_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 2, 0x70, 8, 2, 0x3C, 1, 0}, + { STRATIX10_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x30, + 3, 0x70, 16, 2, 0x3C, 1, 0}, + { STRATIX10_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 4, 0x70, 24, 2, 0x3C, 1, 0}, + { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 4, 0x70, 26, 2, 0x3C, 1, 0}, { STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30, 4, 0x70, 28, 1, 0, 0, 0}, - { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x30, - 5, 0, 0, 0, 0, 0, 0}, + { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 5, 0, 0, 0, 0x3C, 1, 0}, { STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30, 6, 0, 0, 0, 0, 0, 0}, { STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, @@ -249,16 +282,16 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { 1, 0, 0, 0, 0xDC, 27, 0}, { STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, 2, 0, 0, 0, 0xDC, 28, 0}, - { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0xA4, - 3, 0, 0, 0, 0, 0, 0}, - { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0xA4, - 4, 0xE0, 0, 16, 0, 0, 0}, - { STRATIX10_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0xA4, - 5, 0, 0, 0, 0, 0, 4}, - { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0xA4, - 6, 0, 0, 0, 0, 0, 0}, - { STRATIX10_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0xA4, - 7, 0, 0, 0, 0, 0, 0}, + { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0xA4, + 3, 0, 0, 0, 0xB0, 2, 0}, + { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0xA4, + 4, 0xE0, 0, 16, 0xB0, 3, 0}, + { STRATIX10_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0xA4, + 5, 0, 0, 0, 0xB0, 4, 4}, + { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0xA4, + 6, 0, 0, 0, 0xB0, 5, 0}, + { STRATIX10_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0xA4, + 7, 0, 0, 0, 0xB0, 6, 0}, { STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, 8, 0, 0, 0, 0, 0, 0}, { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h index 61eaf3a41fbb..75234e0783e1 100644 --- a/drivers/clk/socfpga/stratix10-clk.h +++ b/drivers/clk/socfpga/stratix10-clk.h @@ -85,4 +85,6 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c void __iomem *reg); struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void __iomem *reg); +struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, + void __iomem *reg); #endif /* __STRATIX10_CLK_H */ diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index 55873d4b7603..7ae4f656191e 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -16,9 +16,16 @@ #include <linux/of.h> #include <linux/of_address.h> +struct clkgen_clk_out { + const char *name; + unsigned long flags; +}; + struct clkgen_data { unsigned long flags; bool mode; + const struct clkgen_clk_out *outputs; + const unsigned int outputs_nb; }; struct flexgen { @@ -295,6 +302,290 @@ static const struct clkgen_data clkgen_video = { .mode = 1, }; +static const struct clkgen_clk_out clkgen_stih407_a0_clk_out[] = { + /* This clk needs to be on so that memory interface is accessible */ + { .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL }, +}; + +static const struct clkgen_data clkgen_stih407_a0 = { + .outputs = clkgen_stih407_a0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih407_a0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih410_a0_clk_out[] = { + /* Those clks need to be on so that memory interface is accessible */ + { .name = "clk-ic-lmi0", .flags = CLK_IS_CRITICAL }, + { .name = "clk-ic-lmi1", .flags = CLK_IS_CRITICAL }, +}; + +static const struct clkgen_data clkgen_stih410_a0 = { + .outputs = clkgen_stih410_a0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih410_a0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih407_c0_clk_out[] = { + { .name = "clk-icn-gpu", }, + { .name = "clk-fdma", }, + { .name = "clk-nand", }, + { .name = "clk-hva", }, + { .name = "clk-proc-stfe", }, + { .name = "clk-proc-tp", }, + { .name = "clk-rx-icn-dmu", }, + { .name = "clk-rx-icn-hva", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL }, + { .name = "clk-mmc-0", }, + { .name = "clk-mmc-1", }, + { .name = "clk-jpegdec", }, + /* This clk needs to be on to keep A9 running */ + { .name = "clk-ext2fa9", .flags = CLK_IS_CRITICAL }, + { .name = "clk-ic-bdisp-0", }, + { .name = "clk-ic-bdisp-1", }, + { .name = "clk-pp-dmu", }, + { .name = "clk-vid-dmu", }, + { .name = "clk-dss-lpc", }, + { .name = "clk-st231-aud-0", }, + { .name = "clk-st231-gp-1", }, + { .name = "clk-st231-dmu", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL }, + { .name = "clk-tx-icn-disp-1", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL }, + { .name = "clk-stfe-frc2", }, + { .name = "clk-eth-phy", }, + { .name = "clk-eth-ref-phyclk", }, + { .name = "clk-flash-promip", }, + { .name = "clk-main-disp", }, + { .name = "clk-aux-disp", }, + { .name = "clk-compo-dvp", }, +}; + +static const struct clkgen_data clkgen_stih407_c0 = { + .outputs = clkgen_stih407_c0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih407_c0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih410_c0_clk_out[] = { + { .name = "clk-icn-gpu", }, + { .name = "clk-fdma", }, + { .name = "clk-nand", }, + { .name = "clk-hva", }, + { .name = "clk-proc-stfe", }, + { .name = "clk-proc-tp", }, + { .name = "clk-rx-icn-dmu", }, + { .name = "clk-rx-icn-hva", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL }, + { .name = "clk-mmc-0", }, + { .name = "clk-mmc-1", }, + { .name = "clk-jpegdec", }, + /* This clk needs to be on to keep A9 running */ + { .name = "clk-ext2fa9", .flags = CLK_IS_CRITICAL }, + { .name = "clk-ic-bdisp-0", }, + { .name = "clk-ic-bdisp-1", }, + { .name = "clk-pp-dmu", }, + { .name = "clk-vid-dmu", }, + { .name = "clk-dss-lpc", }, + { .name = "clk-st231-aud-0", }, + { .name = "clk-st231-gp-1", }, + { .name = "clk-st231-dmu", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL }, + { .name = "clk-tx-icn-disp-1", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL }, + { .name = "clk-stfe-frc2", }, + { .name = "clk-eth-phy", }, + { .name = "clk-eth-ref-phyclk", }, + { .name = "clk-flash-promip", }, + { .name = "clk-main-disp", }, + { .name = "clk-aux-disp", }, + { .name = "clk-compo-dvp", }, + { .name = "clk-tx-icn-hades", }, + { .name = "clk-rx-icn-hades", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-reg-16", .flags = CLK_IS_CRITICAL }, + { .name = "clk-pp-hades", }, + { .name = "clk-clust-hades", }, + { .name = "clk-hwpe-hades", }, + { .name = "clk-fc-hades", }, +}; + +static const struct clkgen_data clkgen_stih410_c0 = { + .outputs = clkgen_stih410_c0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih410_c0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih418_c0_clk_out[] = { + { .name = "clk-icn-gpu", }, + { .name = "clk-fdma", }, + { .name = "clk-nand", }, + { .name = "clk-hva", }, + { .name = "clk-proc-stfe", }, + { .name = "clk-tp", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-rx-icn-dmu", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-rx-icn-hva", .flags = CLK_IS_CRITICAL }, + { .name = "clk-icn-cpu", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-tx-icn-dmu", .flags = CLK_IS_CRITICAL }, + { .name = "clk-mmc-0", }, + { .name = "clk-mmc-1", }, + { .name = "clk-jpegdec", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-reg", .flags = CLK_IS_CRITICAL }, + { .name = "clk-proc-bdisp-0", }, + { .name = "clk-proc-bdisp-1", }, + { .name = "clk-pp-dmu", }, + { .name = "clk-vid-dmu", }, + { .name = "clk-dss-lpc", }, + { .name = "clk-st231-aud-0", }, + { .name = "clk-st231-gp-1", }, + { .name = "clk-st231-dmu", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-lmi", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-tx-icn-1", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-sbc", .flags = CLK_IS_CRITICAL }, + { .name = "clk-stfe-frc2", }, + { .name = "clk-eth-phyref", }, + { .name = "clk-eth-ref-phyclk", }, + { .name = "clk-flash-promip", }, + { .name = "clk-main-disp", }, + { .name = "clk-aux-disp", }, + { .name = "clk-compo-dvp", }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-tx-icn-hades", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-rx-icn-hades", .flags = CLK_IS_CRITICAL }, + /* This clk needs to be on to keep bus interconnect alive */ + { .name = "clk-icn-reg-16", .flags = CLK_IS_CRITICAL }, + { .name = "clk-pp-hevc", }, + { .name = "clk-clust-hevc", }, + { .name = "clk-hwpe-hevc", }, + { .name = "clk-fc-hevc", }, + { .name = "clk-proc-mixer", }, + { .name = "clk-proc-sc", }, + { .name = "clk-avsp-hevc", }, +}; + +static const struct clkgen_data clkgen_stih418_c0 = { + .outputs = clkgen_stih418_c0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih418_c0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih407_d0_clk_out[] = { + { .name = "clk-pcm-0", }, + { .name = "clk-pcm-1", }, + { .name = "clk-pcm-2", }, + { .name = "clk-spdiff", }, +}; + +static const struct clkgen_data clkgen_stih407_d0 = { + .flags = CLK_SET_RATE_PARENT, + .outputs = clkgen_stih407_d0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih407_d0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih410_d0_clk_out[] = { + { .name = "clk-pcm-0", }, + { .name = "clk-pcm-1", }, + { .name = "clk-pcm-2", }, + { .name = "clk-spdiff", }, + { .name = "clk-pcmr10-master", }, + { .name = "clk-usb2-phy", }, +}; + +static const struct clkgen_data clkgen_stih410_d0 = { + .flags = CLK_SET_RATE_PARENT, + .outputs = clkgen_stih410_d0_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih410_d0_clk_out), +}; + +static const struct clkgen_clk_out clkgen_stih407_d2_clk_out[] = { + { .name = "clk-pix-main-disp", }, + { .name = "clk-pix-pip", }, + { .name = "clk-pix-gdp1", }, + { .name = "clk-pix-gdp2", }, + { .name = "clk-pix-gdp3", }, + { .name = "clk-pix-gdp4", }, + { .name = "clk-pix-aux-disp", }, + { .name = "clk-denc", }, + { .name = "clk-pix-hddac", }, + { .name = "clk-hddac", }, + { .name = "clk-sddac", }, + { .name = "clk-pix-dvo", }, + { .name = "clk-dvo", }, + { .name = "clk-pix-hdmi", }, + { .name = "clk-tmds-hdmi", }, + { .name = "clk-ref-hdmiphy", }, +}; + +static const struct clkgen_data clkgen_stih407_d2 = { + .outputs = clkgen_stih407_d2_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih407_d2_clk_out), + .flags = CLK_SET_RATE_PARENT, + .mode = 1, +}; + +static const struct clkgen_clk_out clkgen_stih418_d2_clk_out[] = { + { .name = "clk-pix-main-disp", }, + { .name = "", }, + { .name = "", }, + { .name = "", }, + { .name = "", }, + { .name = "clk-tmds-hdmi-div2", }, + { .name = "clk-pix-aux-disp", }, + { .name = "clk-denc", }, + { .name = "clk-pix-hddac", }, + { .name = "clk-hddac", }, + { .name = "clk-sddac", }, + { .name = "clk-pix-dvo", }, + { .name = "clk-dvo", }, + { .name = "clk-pix-hdmi", }, + { .name = "clk-tmds-hdmi", }, + { .name = "clk-ref-hdmiphy", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "", }, { .name = "", }, { .name = "", }, + { .name = "clk-vp9", }, +}; + +static const struct clkgen_data clkgen_stih418_d2 = { + .outputs = clkgen_stih418_d2_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih418_d2_clk_out), + .flags = CLK_SET_RATE_PARENT, + .mode = 1, +}; + +static const struct clkgen_clk_out clkgen_stih407_d3_clk_out[] = { + { .name = "clk-stfe-frc1", }, + { .name = "clk-tsout-0", }, + { .name = "clk-tsout-1", }, + { .name = "clk-mchi", }, + { .name = "clk-vsens-compo", }, + { .name = "clk-frc1-remote", }, + { .name = "clk-lpc-0", }, + { .name = "clk-lpc-1", }, +}; + +static const struct clkgen_data clkgen_stih407_d3 = { + .outputs = clkgen_stih407_d3_clk_out, + .outputs_nb = ARRAY_SIZE(clkgen_stih407_d3_clk_out), +}; + static const struct of_device_id flexgen_of_match[] = { { .compatible = "st,flexgen-audio", @@ -304,6 +595,46 @@ static const struct of_device_id flexgen_of_match[] = { .compatible = "st,flexgen-video", .data = &clkgen_video, }, + { + .compatible = "st,flexgen-stih407-a0", + .data = &clkgen_stih407_a0, + }, + { + .compatible = "st,flexgen-stih410-a0", + .data = &clkgen_stih410_a0, + }, + { + .compatible = "st,flexgen-stih407-c0", + .data = &clkgen_stih407_c0, + }, + { + .compatible = "st,flexgen-stih410-c0", + .data = &clkgen_stih410_c0, + }, + { + .compatible = "st,flexgen-stih418-c0", + .data = &clkgen_stih418_c0, + }, + { + .compatible = "st,flexgen-stih407-d0", + .data = &clkgen_stih407_d0, + }, + { + .compatible = "st,flexgen-stih410-d0", + .data = &clkgen_stih410_d0, + }, + { + .compatible = "st,flexgen-stih407-d2", + .data = &clkgen_stih407_d2, + }, + { + .compatible = "st,flexgen-stih418-d2", + .data = &clkgen_stih418_d2, + }, + { + .compatible = "st,flexgen-stih407-d3", + .data = &clkgen_stih407_d3, + }, {} }; @@ -320,6 +651,7 @@ static void __init st_of_flexgen_setup(struct device_node *np) unsigned long flex_flags = 0; int ret; bool clk_mode = 0; + const char *clk_name; pnode = of_get_parent(np); if (!pnode) @@ -347,13 +679,17 @@ static void __init st_of_flexgen_setup(struct device_node *np) if (!clk_data) goto err; - ret = of_property_count_strings(np, "clock-output-names"); - if (ret <= 0) { - pr_err("%s: Failed to get number of output clocks (%d)", - __func__, clk_data->clk_num); - goto err; - } - clk_data->clk_num = ret; + /* First try to get output information from the compatible data */ + if (!data || !data->outputs_nb || !data->outputs) { + ret = of_property_count_strings(np, "clock-output-names"); + if (ret <= 0) { + pr_err("%s: Failed to get number of output clocks (%d)", + __func__, clk_data->clk_num); + goto err; + } + clk_data->clk_num = ret; + } else + clk_data->clk_num = data->outputs_nb; clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), GFP_KERNEL); @@ -368,16 +704,19 @@ static void __init st_of_flexgen_setup(struct device_node *np) for (i = 0; i < clk_data->clk_num; i++) { struct clk *clk; - const char *clk_name; - if (of_property_read_string_index(np, "clock-output-names", - i, &clk_name)) { - break; + if (!data || !data->outputs_nb || !data->outputs) { + if (of_property_read_string_index(np, + "clock-output-names", + i, &clk_name)) + break; + flex_flags &= ~CLK_IS_CRITICAL; + of_clk_detect_critical(np, i, &flex_flags); + } else { + clk_name = data->outputs[i].name; + flex_flags = data->flags | data->outputs[i].flags; } - flex_flags &= ~CLK_IS_CRITICAL; - of_clk_detect_critical(np, i, &flex_flags); - /* * If we read an empty clock name then the output is unused */ diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index dd6062e043e0..164285d6be97 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -66,6 +66,16 @@ struct clkgen_quadfs_data { unsigned long *); }; +struct clkgen_clk_out { + const char *name; + unsigned long flags; +}; + +struct clkgen_quadfs_data_clks { + struct clkgen_quadfs_data *data; + const struct clkgen_clk_out *outputs; +}; + static const struct clk_ops st_quadfs_pll_c32_ops; static int clk_fs660c32_dig_get_params(unsigned long input, @@ -115,6 +125,18 @@ static const struct clkgen_quadfs_data st_fs660c32_C = { .get_rate = clk_fs660c32_dig_get_rate, }; +static const struct clkgen_clk_out st_fs660c32_C_clks[] = { + { .name = "clk-s-c0-fs0-ch0", }, + { .name = "clk-s-c0-fs0-ch1", }, + { .name = "clk-s-c0-fs0-ch2", }, + { .name = "clk-s-c0-fs0-ch3", }, +}; + +static const struct clkgen_quadfs_data_clks st_fs660c32_C_data = { + .data = (struct clkgen_quadfs_data *)&st_fs660c32_C, + .outputs = st_fs660c32_C_clks, +}; + static const struct clkgen_quadfs_data st_fs660c32_D = { .nrst_present = true, .nrst = { CLKGEN_FIELD(0x2a0, 0x1, 0), @@ -156,6 +178,46 @@ static const struct clkgen_quadfs_data st_fs660c32_D = { .get_params = clk_fs660c32_dig_get_params, .get_rate = clk_fs660c32_dig_get_rate,}; +static const struct clkgen_quadfs_data_clks st_fs660c32_D_data = { + .data = (struct clkgen_quadfs_data *)&st_fs660c32_D, +}; + +static const struct clkgen_clk_out st_fs660c32_D0_clks[] = { + { .name = "clk-s-d0-fs0-ch0", }, + { .name = "clk-s-d0-fs0-ch1", }, + { .name = "clk-s-d0-fs0-ch2", }, + { .name = "clk-s-d0-fs0-ch3", }, +}; + +static const struct clkgen_quadfs_data_clks st_fs660c32_D0_data = { + .data = (struct clkgen_quadfs_data *)&st_fs660c32_D, + .outputs = st_fs660c32_D0_clks, +}; + +static const struct clkgen_clk_out st_fs660c32_D2_clks[] = { + { .name = "clk-s-d2-fs0-ch0", }, + { .name = "clk-s-d2-fs0-ch1", }, + { .name = "clk-s-d2-fs0-ch2", }, + { .name = "clk-s-d2-fs0-ch3", }, +}; + +static const struct clkgen_quadfs_data_clks st_fs660c32_D2_data = { + .data = (struct clkgen_quadfs_data *)&st_fs660c32_D, + .outputs = st_fs660c32_D2_clks, +}; + +static const struct clkgen_clk_out st_fs660c32_D3_clks[] = { + { .name = "clk-s-d3-fs0-ch0", }, + { .name = "clk-s-d3-fs0-ch1", }, + { .name = "clk-s-d3-fs0-ch2", }, + { .name = "clk-s-d3-fs0-ch3", }, +}; + +static const struct clkgen_quadfs_data_clks st_fs660c32_D3_data = { + .data = (struct clkgen_quadfs_data *)&st_fs660c32_D, + .outputs = st_fs660c32_D3_clks, +}; + /** * DOC: A Frequency Synthesizer that multiples its input clock by a fixed factor * @@ -857,7 +919,7 @@ static struct clk * __init st_clk_register_quadfs_fsynth( static void __init st_of_create_quadfs_fsynths( struct device_node *np, const char *pll_name, - struct clkgen_quadfs_data *quadfs, void __iomem *reg, + struct clkgen_quadfs_data_clks *quadfs, void __iomem *reg, spinlock_t *lock) { struct clk_onecell_data *clk_data; @@ -881,9 +943,15 @@ static void __init st_of_create_quadfs_fsynths( const char *clk_name; unsigned long flags = 0; - if (of_property_read_string_index(np, "clock-output-names", - fschan, &clk_name)) { - break; + if (quadfs->outputs) { + clk_name = quadfs->outputs[fschan].name; + flags = quadfs->outputs[fschan].flags; + } else { + if (of_property_read_string_index(np, + "clock-output-names", + fschan, &clk_name)) + break; + of_clk_detect_critical(np, fschan, &flags); } /* @@ -892,10 +960,8 @@ static void __init st_of_create_quadfs_fsynths( if (*clk_name == '\0') continue; - of_clk_detect_critical(np, fschan, &flags); - clk = st_clk_register_quadfs_fsynth(clk_name, pll_name, - quadfs, reg, fschan, + quadfs->data, reg, fschan, flags, lock); /* @@ -915,7 +981,7 @@ static void __init st_of_create_quadfs_fsynths( } static void __init st_of_quadfs_setup(struct device_node *np, - struct clkgen_quadfs_data *data) + struct clkgen_quadfs_data_clks *datac) { struct clk *clk; const char *pll_name, *clk_parent_name; @@ -940,7 +1006,7 @@ static void __init st_of_quadfs_setup(struct device_node *np, spin_lock_init(lock); - clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, data, + clk = st_clk_register_quadfs_pll(pll_name, clk_parent_name, datac->data, reg, lock); if (IS_ERR(clk)) goto err_exit; @@ -950,7 +1016,7 @@ static void __init st_of_quadfs_setup(struct device_node *np, __clk_get_name(clk_get_parent(clk)), (unsigned int)clk_get_rate(clk)); - st_of_create_quadfs_fsynths(np, pll_name, data, reg, lock); + st_of_create_quadfs_fsynths(np, pll_name, datac, reg, lock); err_exit: kfree(pll_name); /* No longer need local copy of the PLL name */ @@ -958,12 +1024,35 @@ err_exit: static void __init st_of_quadfs660C_setup(struct device_node *np) { - st_of_quadfs_setup(np, (struct clkgen_quadfs_data *) &st_fs660c32_C); + st_of_quadfs_setup(np, + (struct clkgen_quadfs_data_clks *) &st_fs660c32_C_data); } CLK_OF_DECLARE(quadfs660C, "st,quadfs-pll", st_of_quadfs660C_setup); static void __init st_of_quadfs660D_setup(struct device_node *np) { - st_of_quadfs_setup(np, (struct clkgen_quadfs_data *) &st_fs660c32_D); + st_of_quadfs_setup(np, + (struct clkgen_quadfs_data_clks *) &st_fs660c32_D_data); } CLK_OF_DECLARE(quadfs660D, "st,quadfs", st_of_quadfs660D_setup); + +static void __init st_of_quadfs660D0_setup(struct device_node *np) +{ + st_of_quadfs_setup(np, + (struct clkgen_quadfs_data_clks *) &st_fs660c32_D0_data); +} +CLK_OF_DECLARE(quadfs660D0, "st,quadfs-d0", st_of_quadfs660D0_setup); + +static void __init st_of_quadfs660D2_setup(struct device_node *np) +{ + st_of_quadfs_setup(np, + (struct clkgen_quadfs_data_clks *) &st_fs660c32_D2_data); +} +CLK_OF_DECLARE(quadfs660D2, "st,quadfs-d2", st_of_quadfs660D2_setup); + +static void __init st_of_quadfs660D3_setup(struct device_node *np) +{ + st_of_quadfs_setup(np, + (struct clkgen_quadfs_data_clks *) &st_fs660c32_D3_data); +} +CLK_OF_DECLARE(quadfs660D3, "st,quadfs-d3", st_of_quadfs660D3_setup); diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index 119c5b33080c..b36e4d803636 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -57,6 +57,17 @@ struct clkgen_pll_data { const struct clk_ops *ops; }; +struct clkgen_clk_out { + const char *name; + unsigned long flags; +}; + +struct clkgen_pll_data_clks { + struct clkgen_pll_data *data; + const struct clkgen_clk_out *outputs; +}; + + static const struct clk_ops stm_pll3200c32_ops; static const struct clk_ops stm_pll3200c32_a9_ops; static const struct clk_ops stm_pll4600c28_ops; @@ -74,6 +85,28 @@ static const struct clkgen_pll_data st_pll3200c32_cx_0 = { .ops = &stm_pll3200c32_ops, }; +static const struct clkgen_pll_data_clks st_pll3200c32_cx_0_legacy_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_cx_0, +}; + +static const struct clkgen_clk_out st_pll3200c32_ax_0_clks[] = { + { .name = "clk-s-a0-pll-odf-0", }, +}; + +static const struct clkgen_pll_data_clks st_pll3200c32_a0_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_cx_0, + .outputs = st_pll3200c32_ax_0_clks, +}; + +static const struct clkgen_clk_out st_pll3200c32_cx_0_clks[] = { + { .name = "clk-s-c0-pll0-odf-0", }, +}; + +static const struct clkgen_pll_data_clks st_pll3200c32_c0_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_cx_0, + .outputs = st_pll3200c32_cx_0_clks, +}; + static const struct clkgen_pll_data st_pll3200c32_cx_1 = { /* 407 C0 PLL1 */ .pdn_status = CLKGEN_FIELD(0x2c8, 0x1, 8), @@ -87,6 +120,19 @@ static const struct clkgen_pll_data st_pll3200c32_cx_1 = { .ops = &stm_pll3200c32_ops, }; +static const struct clkgen_pll_data_clks st_pll3200c32_cx_1_legacy_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_cx_1, +}; + +static const struct clkgen_clk_out st_pll3200c32_cx_1_clks[] = { + { .name = "clk-s-c0-pll1-odf-0", }, +}; + +static const struct clkgen_pll_data_clks st_pll3200c32_c1_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_cx_1, + .outputs = st_pll3200c32_cx_1_clks, +}; + static const struct clkgen_pll_data st_pll3200c32_407_a9 = { /* 407 A9 */ .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), @@ -104,6 +150,15 @@ static const struct clkgen_pll_data st_pll3200c32_407_a9 = { .ops = &stm_pll3200c32_a9_ops, }; +static const struct clkgen_clk_out st_pll3200c32_407_a9_clks[] = { + { .name = "clockgen-a9-pll-odf", }, +}; + +static const struct clkgen_pll_data_clks st_pll3200c32_407_a9_data = { + .data = (struct clkgen_pll_data *)&st_pll3200c32_407_a9, + .outputs = st_pll3200c32_407_a9_clks, +}; + static struct clkgen_pll_data st_pll4600c28_418_a9 = { /* 418 A9 */ .pdn_status = CLKGEN_FIELD(0x1a8, 0x1, 0), @@ -120,6 +175,15 @@ static struct clkgen_pll_data st_pll4600c28_418_a9 = { .ops = &stm_pll4600c28_ops, }; +static const struct clkgen_clk_out st_pll4600c28_418_a9_clks[] = { + { .name = "clockgen-a9-pll-odf", }, +}; + +static const struct clkgen_pll_data_clks st_pll4600c28_418_a9_data = { + .data = (struct clkgen_pll_data *)&st_pll4600c28_418_a9, + .outputs = st_pll4600c28_418_a9_clks, +}; + /** * DOC: Clock Generated by PLL, rate set and enabled by bootloader * @@ -146,7 +210,6 @@ struct clkgen_pll { u32 ndiv; u32 idf; - u32 odf; u32 cp; }; @@ -685,7 +748,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, static void __init clkgen_c32_pll_setup(struct device_node *np, - struct clkgen_pll_data *data) + struct clkgen_pll_data_clks *datac) { struct clk *clk; const char *parent_name, *pll_name; @@ -705,14 +768,14 @@ static void __init clkgen_c32_pll_setup(struct device_node *np, of_clk_detect_critical(np, 0, &pll_flags); - clk = clkgen_pll_register(parent_name, data, pll_base, pll_flags, - np->name, data->lock); + clk = clkgen_pll_register(parent_name, datac->data, pll_base, pll_flags, + np->name, datac->data->lock); if (IS_ERR(clk)) return; pll_name = __clk_get_name(clk); - num_odfs = data->num_odfs; + num_odfs = datac->data->num_odfs; clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); if (!clk_data) @@ -730,14 +793,21 @@ static void __init clkgen_c32_pll_setup(struct device_node *np, const char *clk_name; unsigned long odf_flags = 0; - if (of_property_read_string_index(np, "clock-output-names", - odf, &clk_name)) - return; + if (datac->outputs) { + clk_name = datac->outputs[odf].name; + odf_flags = datac->outputs[odf].flags; + } else { + if (of_property_read_string_index(np, + "clock-output-names", + odf, &clk_name)) + return; - of_clk_detect_critical(np, odf, &odf_flags); + of_clk_detect_critical(np, odf, &odf_flags); + } - clk = clkgen_odf_register(pll_name, pll_base, data, odf_flags, - odf, &clkgena_c32_odf_lock, clk_name); + clk = clkgen_odf_register(pll_name, pll_base, datac->data, + odf_flags, odf, &clkgena_c32_odf_lock, + clk_name); if (IS_ERR(clk)) goto err; @@ -755,27 +825,48 @@ err: static void __init clkgen_c32_pll0_setup(struct device_node *np) { clkgen_c32_pll_setup(np, - (struct clkgen_pll_data *) &st_pll3200c32_cx_0); + (struct clkgen_pll_data_clks *) &st_pll3200c32_cx_0_legacy_data); } CLK_OF_DECLARE(c32_pll0, "st,clkgen-pll0", clkgen_c32_pll0_setup); +static void __init clkgen_c32_pll0_a0_setup(struct device_node *np) +{ + clkgen_c32_pll_setup(np, + (struct clkgen_pll_data_clks *) &st_pll3200c32_a0_data); +} +CLK_OF_DECLARE(c32_pll0_a0, "st,clkgen-pll0-a0", clkgen_c32_pll0_a0_setup); + +static void __init clkgen_c32_pll0_c0_setup(struct device_node *np) +{ + clkgen_c32_pll_setup(np, + (struct clkgen_pll_data_clks *) &st_pll3200c32_c0_data); +} +CLK_OF_DECLARE(c32_pll0_c0, "st,clkgen-pll0-c0", clkgen_c32_pll0_c0_setup); + static void __init clkgen_c32_pll1_setup(struct device_node *np) { clkgen_c32_pll_setup(np, - (struct clkgen_pll_data *) &st_pll3200c32_cx_1); + (struct clkgen_pll_data_clks *) &st_pll3200c32_cx_1_legacy_data); } CLK_OF_DECLARE(c32_pll1, "st,clkgen-pll1", clkgen_c32_pll1_setup); +static void __init clkgen_c32_pll1_c0_setup(struct device_node *np) +{ + clkgen_c32_pll_setup(np, + (struct clkgen_pll_data_clks *) &st_pll3200c32_c1_data); +} +CLK_OF_DECLARE(c32_pll1_c0, "st,clkgen-pll1-c0", clkgen_c32_pll1_c0_setup); + static void __init clkgen_c32_plla9_setup(struct device_node *np) { clkgen_c32_pll_setup(np, - (struct clkgen_pll_data *) &st_pll3200c32_407_a9); + (struct clkgen_pll_data_clks *) &st_pll3200c32_407_a9_data); } CLK_OF_DECLARE(c32_plla9, "st,stih407-clkgen-plla9", clkgen_c32_plla9_setup); static void __init clkgen_c28_plla9_setup(struct device_node *np) { clkgen_c32_pll_setup(np, - (struct clkgen_pll_data *) &st_pll4600c28_418_a9); + (struct clkgen_pll_data_clks *) &st_pll4600c28_418_a9_data); } CLK_OF_DECLARE(c28_plla9, "st,stih418-clkgen-plla9", clkgen_c28_plla9_setup); diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c index a774942cb153..f49724a22540 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-v3s.c @@ -817,10 +817,10 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node, return; } - /* Force the PLL-Audio-1x divider to 4 */ + /* Force the PLL-Audio-1x divider to 1 */ val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG); val &= ~GENMASK(19, 16); - writel(val | (3 << 16), reg + SUN8I_V3S_PLL_AUDIO_REG); + writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG); sunxi_ccu_probe(node, reg, ccu_desc); } diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index 4b31beefc9fc..2091fc9b0ca9 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -48,36 +48,45 @@ static int clk_periph_is_enabled(struct clk_hw *hw) return state; } -static int clk_periph_enable(struct clk_hw *hw) +static void clk_periph_enable_locked(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); - unsigned long flags = 0; - - spin_lock_irqsave(&periph_ref_lock, flags); - - gate->enable_refcnt[gate->clk_num]++; - if (gate->enable_refcnt[gate->clk_num] > 1) { - spin_unlock_irqrestore(&periph_ref_lock, flags); - return 0; - } write_enb_set(periph_clk_to_bit(gate), gate); udelay(2); - if (!(gate->flags & TEGRA_PERIPH_NO_RESET) && - !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) { - if (read_rst(gate) & periph_clk_to_bit(gate)) { - udelay(5); /* reset propogation delay */ - write_rst_clr(periph_clk_to_bit(gate), gate); - } - } - if (gate->flags & TEGRA_PERIPH_WAR_1005168) { writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE); udelay(1); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); } +} + +static void clk_periph_disable_locked(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + + /* + * If peripheral is in the APB bus then read the APB bus to + * flush the write operation in apb bus. This will avoid the + * peripheral access after disabling clock + */ + if (gate->flags & TEGRA_PERIPH_ON_APB) + tegra_read_chipid(); + + write_enb_clr(periph_clk_to_bit(gate), gate); +} + +static int clk_periph_enable(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + unsigned long flags = 0; + + spin_lock_irqsave(&periph_ref_lock, flags); + + if (!gate->enable_refcnt[gate->clk_num]++) + clk_periph_enable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); @@ -91,21 +100,28 @@ static void clk_periph_disable(struct clk_hw *hw) spin_lock_irqsave(&periph_ref_lock, flags); - gate->enable_refcnt[gate->clk_num]--; - if (gate->enable_refcnt[gate->clk_num] > 0) { - spin_unlock_irqrestore(&periph_ref_lock, flags); - return; - } + WARN_ON(!gate->enable_refcnt[gate->clk_num]); + + if (--gate->enable_refcnt[gate->clk_num] == 0) + clk_periph_disable_locked(hw); + + spin_unlock_irqrestore(&periph_ref_lock, flags); +} + +static void clk_periph_disable_unused(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + unsigned long flags = 0; + + spin_lock_irqsave(&periph_ref_lock, flags); /* - * If peripheral is in the APB bus then read the APB bus to - * flush the write operation in apb bus. This will avoid the - * peripheral access after disabling clock + * Some clocks are duplicated and some of them are marked as critical, + * like fuse and fuse_burn for example, thus the enable_refcnt will + * be non-zero here if the "unused" duplicate is disabled by CCF. */ - if (gate->flags & TEGRA_PERIPH_ON_APB) - tegra_read_chipid(); - - write_enb_clr(periph_clk_to_bit(gate), gate); + if (!gate->enable_refcnt[gate->clk_num]) + clk_periph_disable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); } @@ -114,6 +130,7 @@ const struct clk_ops tegra_clk_periph_gate_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, }; struct clk *tegra_clk_register_periph_gate(const char *name, @@ -148,9 +165,6 @@ struct clk *tegra_clk_register_periph_gate(const char *name, gate->enable_refcnt = enable_refcnt; gate->regs = pregs; - if (read_enb(gate) & periph_clk_to_bit(gate)) - enable_refcnt[clk_num]++; - /* Data in .init is copied by clk_register(), so stack variable OK */ gate->hw.init = &init; diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 67620c7ecd9e..79ca3aa072b7 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -100,6 +100,15 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_periph_disable_unused(struct clk_hw *hw) +{ + struct tegra_clk_periph *periph = to_clk_periph(hw); + const struct clk_ops *gate_ops = periph->gate_ops; + struct clk_hw *gate_hw = &periph->gate.hw; + + gate_ops->disable_unused(gate_hw); +} + static void clk_periph_restore_context(struct clk_hw *hw) { struct tegra_clk_periph *periph = to_clk_periph(hw); @@ -126,6 +135,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, }; @@ -135,6 +145,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, }; diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 0193cebe8c5a..eaa079c177c3 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -558,6 +558,9 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, u32 p_div = 0; int ret; + if (!rate) + return -EINVAL; + switch (parent_rate) { case 12000000: case 26000000: @@ -1131,7 +1134,8 @@ static int clk_pllu_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) @@ -1748,15 +1752,13 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) return -EINVAL; } - if (clk_pll_is_enabled(hw)) - return 0; - input_rate = clk_hw_get_rate(__clk_get_hw(osc)); if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) diff --git a/drivers/clk/tegra/clk-tegra-periph.c b/drivers/clk/tegra/clk-tegra-periph.c index 60cc34f90cb9..292d6269daf1 100644 --- a/drivers/clk/tegra/clk-tegra-periph.c +++ b/drivers/clk/tegra/clk-tegra-periph.c @@ -712,9 +712,9 @@ static struct tegra_periph_init_data periph_clks[] = { MUX8("ndflash", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, TEGRA_PERIPH_ON_APB, tegra_clk_ndflash_8), MUX8("ndspeed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, TEGRA_PERIPH_ON_APB, tegra_clk_ndspeed_8), MUX8("hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, 0, tegra_clk_hdmi), - MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, 0, tegra_clk_extern1), - MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, 0, tegra_clk_extern2), - MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, 0, tegra_clk_extern3), + MUX8("extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, TEGRA_PERIPH_NO_RESET, tegra_clk_extern1), + MUX8("extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, TEGRA_PERIPH_NO_RESET, tegra_clk_extern2), + MUX8("extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, TEGRA_PERIPH_NO_RESET, tegra_clk_extern3), MUX8("soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm), MUX8("soc_therm", mux_clkm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, TEGRA_PERIPH_ON_APB, tegra_clk_soc_therm_8), MUX8("vi_sensor", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 164, TEGRA_PERIPH_NO_RESET, tegra_clk_vi_sensor_8), diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c index a03119c30456..68d7bcd5fc8a 100644 --- a/drivers/clk/tegra/clk-tegra-super-cclk.c +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c @@ -25,6 +25,8 @@ #define SUPER_CDIV_ENB BIT(31) +#define TSENSOR_SLOWDOWN BIT(23) + static struct tegra_clk_super_mux *cclk_super; static bool cclk_on_pllx; @@ -47,10 +49,20 @@ static int cclk_super_set_rate(struct clk_hw *hw, unsigned long rate, static unsigned long cclk_super_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); + u32 val = readl_relaxed(super->reg); + unsigned int div2; + + /* check whether thermal throttling is active */ + if (val & TSENSOR_SLOWDOWN) + div2 = 1; + else + div2 = 0; + if (cclk_super_get_parent(hw) == PLLX_INDEX) - return parent_rate; + return parent_rate >> div2; - return tegra_clk_super_ops.recalc_rate(hw, parent_rate); + return tegra_clk_super_ops.recalc_rate(hw, parent_rate) >> div2; } static int cclk_super_determine_rate(struct clk_hw *hw, diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c index 2ac2679d696d..5e339ad0a97c 100644 --- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c +++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c @@ -537,7 +537,7 @@ static void get_alignment_from_dt(struct device *dev, static int get_alignment_from_regulator(struct device *dev, struct rail_alignment *align) { - struct regulator *reg = devm_regulator_get(dev, "vdd-cpu"); + struct regulator *reg = regulator_get(dev, "vdd-cpu"); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -545,7 +545,7 @@ static int get_alignment_from_regulator(struct device *dev, align->offset_uv = regulator_list_voltage(reg, 0); align->step_uv = regulator_get_linear_step(reg); - devm_regulator_put(reg); + regulator_put(reg); return 0; } diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index bdf6f4a51617..74c1d894cca8 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -249,8 +249,10 @@ static int emc_set_timing(struct tegra_clk_emc *tegra, div = timing->parent_rate / (timing->rate / 2) - 2; err = tegra->prepare_timing_change(emc, timing->rate); - if (err) + if (err) { + clk_disable_unprepare(timing->parent); return err; + } spin_lock_irqsave(tegra->lock, flags); diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 3efc651b42e3..3664593a5ba4 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1021,9 +1021,9 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA20_CLK_PLL_P_OUT3, TEGRA20_CLK_CLK_MAX, 72000000, 1 }, { TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1 }, { TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 0 }, - { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 240000000, 0 }, - { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 240000000, 0 }, - { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 240000000, 0 }, + { TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 0 }, + { TEGRA20_CLK_SCLK, TEGRA20_CLK_PLL_C_OUT1, 120000000, 0 }, + { TEGRA20_CLK_HCLK, TEGRA20_CLK_CLK_MAX, 120000000, 0 }, { TEGRA20_CLK_PCLK, TEGRA20_CLK_CLK_MAX, 60000000, 0 }, { TEGRA20_CLK_CSITE, TEGRA20_CLK_CLK_MAX, 0, 1 }, { TEGRA20_CLK_CCLK, TEGRA20_CLK_CLK_MAX, 0, 1 }, diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 16dbf83d2f62..64121bc66d85 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -930,7 +930,7 @@ static void __init tegra30_super_clk_init(void) /* CCLKG */ clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents, ARRAY_SIZE(cclk_g_parents), - CLK_SET_RATE_PARENT, + CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, clk_base + CCLKG_BURST_POLICY, 0, NULL); clks[TEGRA30_CLK_CCLK_G] = clk; @@ -1006,7 +1006,7 @@ static struct tegra_periph_init_data tegra_periph_clk_list[] = { TEGRA_INIT_DATA_MUX("dam0", mux_pllacp_clkm, CLK_SOURCE_DAM0, 108, 0, TEGRA30_CLK_DAM0), TEGRA_INIT_DATA_MUX("dam1", mux_pllacp_clkm, CLK_SOURCE_DAM1, 109, 0, TEGRA30_CLK_DAM1), TEGRA_INIT_DATA_MUX("dam2", mux_pllacp_clkm, CLK_SOURCE_DAM2, 110, 0, TEGRA30_CLK_DAM2), - TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, TEGRA_PERIPH_MANUAL_RESET, TEGRA30_CLK_GR3D2), + TEGRA_INIT_DATA_INT("3d2", mux_pllmcpa, CLK_SOURCE_3D2, 98, 0, TEGRA30_CLK_GR3D2), TEGRA_INIT_DATA_INT("se", mux_pllpcm_clkm, CLK_SOURCE_SE, 127, 0, TEGRA30_CLK_SE), TEGRA_INIT_DATA_MUX8("hdmi", mux_pllpmdacd2_clkm, CLK_SOURCE_HDMI, 51, 0, TEGRA30_CLK_HDMI), TEGRA_INIT_DATA("pwm", NULL, NULL, pwm_parents, CLK_SOURCE_PWM, 28, 2, 0, 0, 8, 1, 0, 17, TEGRA_PERIPH_ON_APB, TEGRA30_CLK_PWM), @@ -1245,7 +1245,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, - { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 600000000, 0 }, + { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index c3e36b5dcc75..0c3ba0ccce1a 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -553,9 +553,6 @@ struct tegra_clk_periph_regs { * Flags: * TEGRA_PERIPH_NO_RESET - This flag indicates that reset is not allowed * for this module. - * TEGRA_PERIPH_MANUAL_RESET - This flag indicates not to reset module - * after clock enable and driver for the module is responsible for - * doing reset. * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the * bus to flush the write operation in apb bus. This flag indicates * that this peripheral is in apb bus. @@ -577,7 +574,6 @@ struct tegra_clk_periph_gate { #define TEGRA_CLK_PERIPH_GATE_MAGIC 0x17760309 #define TEGRA_PERIPH_NO_RESET BIT(0) -#define TEGRA_PERIPH_MANUAL_RESET BIT(1) #define TEGRA_PERIPH_ON_APB BIT(2) #define TEGRA_PERIPH_WAR_1005168 BIT(3) #define TEGRA_PERIPH_NO_DIV BIT(4) diff --git a/drivers/clk/ti/adpll.c b/drivers/clk/ti/adpll.c index bb2f2836dab2..b341cd990be7 100644 --- a/drivers/clk/ti/adpll.c +++ b/drivers/clk/ti/adpll.c @@ -896,11 +896,8 @@ static int ti_adpll_probe(struct platform_device *pdev) d->pa = res->start; d->iobase = devm_ioremap_resource(dev, res); - if (IS_ERR(d->iobase)) { - dev_err(dev, "could not get IO base: %li\n", - PTR_ERR(d->iobase)); + if (IS_ERR(d->iobase)) return PTR_ERR(d->iobase); - } err = ti_adpll_init_registers(d); if (err) diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index d6f1ac5b53e1..e9f9aee936ae 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -290,7 +290,9 @@ static void __init of_ti_dpll_setup(struct device_node *node, struct clk_init_data *init = NULL; const char **parent_names = NULL; struct dpll_data *dd = NULL; + int ssc_clk_index; u8 dpll_mode = 0; + u32 min_div; dd = kmemdup(ddt, sizeof(*dd), GFP_KERNEL); clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); @@ -345,6 +347,27 @@ static void __init of_ti_dpll_setup(struct device_node *node, if (dd->autoidle_mask) { if (ti_clk_get_reg_addr(node, 3, &dd->autoidle_reg)) goto cleanup; + + ssc_clk_index = 4; + } else { + ssc_clk_index = 3; + } + + if (dd->ssc_deltam_int_mask && dd->ssc_deltam_frac_mask && + dd->ssc_modfreq_mant_mask && dd->ssc_modfreq_exp_mask) { + if (ti_clk_get_reg_addr(node, ssc_clk_index++, + &dd->ssc_deltam_reg)) + goto cleanup; + + if (ti_clk_get_reg_addr(node, ssc_clk_index++, + &dd->ssc_modfreq_reg)) + goto cleanup; + + of_property_read_u32(node, "ti,ssc-modfreq-hz", + &dd->ssc_modfreq); + of_property_read_u32(node, "ti,ssc-deltam", &dd->ssc_deltam); + dd->ssc_downspread = + of_property_read_bool(node, "ti,ssc-downspread"); } if (of_property_read_bool(node, "ti,low-power-stop")) @@ -356,6 +379,10 @@ static void __init of_ti_dpll_setup(struct device_node *node, if (of_property_read_bool(node, "ti,lock")) dpll_mode |= 1 << DPLL_LOCKED; + if (!of_property_read_u32(node, "ti,min-div", &min_div) && + min_div > dd->min_divider) + dd->min_divider = min_div; + if (dpll_mode) dd->modes = dpll_mode; @@ -585,8 +612,14 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node) const struct dpll_data dd = { .idlest_mask = 0x1, .enable_mask = 0x7, + .ssc_enable_mask = 0x1 << 12, + .ssc_downspread_mask = 0x1 << 14, .mult_mask = 0x7ff << 8, .div1_mask = 0x7f, + .ssc_deltam_int_mask = 0x3 << 18, + .ssc_deltam_frac_mask = 0x3ffff, + .ssc_modfreq_mant_mask = 0x7f, + .ssc_modfreq_exp_mask = 0x7 << 8, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, @@ -645,8 +678,14 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node) const struct dpll_data dd = { .idlest_mask = 0x1, .enable_mask = 0x7, + .ssc_enable_mask = 0x1 << 12, + .ssc_downspread_mask = 0x1 << 14, .mult_mask = 0x7ff << 8, .div1_mask = 0x7f, + .ssc_deltam_int_mask = 0x3 << 18, + .ssc_deltam_frac_mask = 0x3ffff, + .ssc_modfreq_mant_mask = 0x7f, + .ssc_modfreq_exp_mask = 0x7 << 8, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 6097b099a5df..e32b3515f9e7 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -292,7 +292,89 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) } /** - * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly + * omap3_noncore_dpll_ssc_program - set spread-spectrum clocking registers + * @clk: struct clk * of DPLL to set + * + * Enable the DPLL spread spectrum clocking if frequency modulation and + * frequency spreading have been set, otherwise disable it. + */ +static void omap3_noncore_dpll_ssc_program(struct clk_hw_omap *clk) +{ + struct dpll_data *dd = clk->dpll_data; + unsigned long ref_rate; + u32 v, ctrl, mod_freq_divider, exponent, mantissa; + u32 deltam_step, deltam_ceil; + + ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg); + + if (dd->ssc_modfreq && dd->ssc_deltam) { + ctrl |= dd->ssc_enable_mask; + + if (dd->ssc_downspread) + ctrl |= dd->ssc_downspread_mask; + else + ctrl &= ~dd->ssc_downspread_mask; + + ref_rate = clk_hw_get_rate(dd->clk_ref); + mod_freq_divider = + (ref_rate / dd->last_rounded_n) / (4 * dd->ssc_modfreq); + if (dd->ssc_modfreq > (ref_rate / 70)) + pr_warn("clock: SSC modulation frequency of DPLL %s greater than %ld\n", + __clk_get_name(clk->hw.clk), ref_rate / 70); + + exponent = 0; + mantissa = mod_freq_divider; + while ((mantissa > 127) && (exponent < 7)) { + exponent++; + mantissa /= 2; + } + if (mantissa > 127) + mantissa = 127; + + v = ti_clk_ll_ops->clk_readl(&dd->ssc_modfreq_reg); + v &= ~(dd->ssc_modfreq_mant_mask | dd->ssc_modfreq_exp_mask); + v |= mantissa << __ffs(dd->ssc_modfreq_mant_mask); + v |= exponent << __ffs(dd->ssc_modfreq_exp_mask); + ti_clk_ll_ops->clk_writel(v, &dd->ssc_modfreq_reg); + + deltam_step = dd->last_rounded_m * dd->ssc_deltam; + deltam_step /= 10; + if (dd->ssc_downspread) + deltam_step /= 2; + + deltam_step <<= __ffs(dd->ssc_deltam_int_mask); + deltam_step /= 100; + deltam_step /= mod_freq_divider; + if (deltam_step > 0xFFFFF) + deltam_step = 0xFFFFF; + + deltam_ceil = (deltam_step & dd->ssc_deltam_int_mask) >> + __ffs(dd->ssc_deltam_int_mask); + if (deltam_step & dd->ssc_deltam_frac_mask) + deltam_ceil++; + + if ((dd->ssc_downspread && + ((dd->last_rounded_m - (2 * deltam_ceil)) < 20 || + dd->last_rounded_m > 2045)) || + ((dd->last_rounded_m - deltam_ceil) < 20 || + (dd->last_rounded_m + deltam_ceil) > 2045)) + pr_warn("clock: SSC multiplier of DPLL %s is out of range\n", + __clk_get_name(clk->hw.clk)); + + v = ti_clk_ll_ops->clk_readl(&dd->ssc_deltam_reg); + v &= ~(dd->ssc_deltam_int_mask | dd->ssc_deltam_frac_mask); + v |= deltam_step << __ffs(dd->ssc_deltam_int_mask | + dd->ssc_deltam_frac_mask); + ti_clk_ll_ops->clk_writel(v, &dd->ssc_deltam_reg); + } else { + ctrl &= ~dd->ssc_enable_mask; + } + + ti_clk_ll_ops->clk_writel(ctrl, &dd->control_reg); +} + +/** + * omap3_noncore_dpll_program - set non-core DPLL M,N values directly * @clk: struct clk * of DPLL to set * @freqsel: FREQSEL value to set * @@ -390,6 +472,9 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) ti_clk_ll_ops->clk_writel(v, &dd->control_reg); } + if (dd->ssc_enable_mask) + omap3_noncore_dpll_ssc_program(clk); + /* We let the clock framework set the other output dividers later */ /* REVISIT: Set ramp-up delay? */ diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig index 91f0ff54237d..481de5657d85 100644 --- a/drivers/clk/versatile/Kconfig +++ b/drivers/clk/versatile/Kconfig @@ -1,8 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menu "Clock driver for ARM Reference designs" - depends on ARCH_INTEGRATOR || ARCH_REALVIEW || \ - ARCH_VERSATILE || ARCH_VEXPRESS || COMPILE_TEST + depends on HAS_IOMEM config ICST bool "Clock driver for ARM Reference designs ICST" diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c index 10c9b889324f..695feaa82da5 100644 --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c @@ -121,7 +121,9 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id, init.name = name; init.ops = &zynqmp_clk_gate_ops; - init.flags = nodes->flag; + + init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag); + init.parent_names = parents; init.num_parents = 1; diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c index 06194149be83..157d4a960bf4 100644 --- a/drivers/clk/zynqmp/clk-mux-zynqmp.c +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -38,7 +38,7 @@ struct zynqmp_clk_mux { * zynqmp_clk_mux_get_parent() - Get parent of clock * @hw: handle between common and hardware-specific interfaces * - * Return: Parent index + * Return: Parent index on success or number of parents in case of error */ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) { @@ -50,9 +50,15 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw) ret = zynqmp_pm_clock_getparent(clk_id, &val); - if (ret) + if (ret) { pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n", __func__, clk_name, ret); + /* + * clk_core_get_parent_by_index() takes num_parents as incorrect + * index which is exactly what I want to return here + */ + return clk_hw_get_num_parents(hw); + } return val; } @@ -90,6 +96,27 @@ static const struct clk_ops zynqmp_clk_mux_ro_ops = { .get_parent = zynqmp_clk_mux_get_parent, }; +static inline unsigned long zynqmp_clk_map_mux_ccf_flags( + const u32 zynqmp_type_flag) +{ + unsigned long ccf_flag = 0; + + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_INDEX_ONE) + ccf_flag |= CLK_MUX_INDEX_ONE; + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_INDEX_BIT) + ccf_flag |= CLK_MUX_INDEX_BIT; + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_HIWORD_MASK) + ccf_flag |= CLK_MUX_HIWORD_MASK; + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_READ_ONLY) + ccf_flag |= CLK_MUX_READ_ONLY; + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_ROUND_CLOSEST) + ccf_flag |= CLK_MUX_ROUND_CLOSEST; + if (zynqmp_type_flag & ZYNQMP_CLK_MUX_BIG_ENDIAN) + ccf_flag |= CLK_MUX_BIG_ENDIAN; + + return ccf_flag; +} + /** * zynqmp_clk_register_mux() - Register a mux table with the clock * framework @@ -120,10 +147,12 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id, init.ops = &zynqmp_clk_mux_ro_ops; else init.ops = &zynqmp_clk_mux_ops; - init.flags = nodes->flag; + + init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag); + init.parent_names = parents; init.num_parents = num_parents; - mux->flags = nodes->type_flag; + mux->flags = zynqmp_clk_map_mux_ccf_flags(nodes->type_flag); mux->hw.init = &init; mux->clk_id = clk_id; diff --git a/drivers/clk/zynqmp/clk-zynqmp.h b/drivers/clk/zynqmp/clk-zynqmp.h index 5beeb41b29fa..84fa80a969a9 100644 --- a/drivers/clk/zynqmp/clk-zynqmp.h +++ b/drivers/clk/zynqmp/clk-zynqmp.h @@ -10,6 +10,37 @@ #include <linux/firmware/xlnx-zynqmp.h> +/* Common Flags */ +/* must be gated across rate change */ +#define ZYNQMP_CLK_SET_RATE_GATE BIT(0) +/* must be gated across re-parent */ +#define ZYNQMP_CLK_SET_PARENT_GATE BIT(1) +/* propagate rate change up one level */ +#define ZYNQMP_CLK_SET_RATE_PARENT BIT(2) +/* do not gate even if unused */ +#define ZYNQMP_CLK_IGNORE_UNUSED BIT(3) +/* don't re-parent on rate change */ +#define ZYNQMP_CLK_SET_RATE_NO_REPARENT BIT(7) +/* do not gate, ever */ +#define ZYNQMP_CLK_IS_CRITICAL BIT(11) + +/* Type Flags for divider clock */ +#define ZYNQMP_CLK_DIVIDER_ONE_BASED BIT(0) +#define ZYNQMP_CLK_DIVIDER_POWER_OF_TWO BIT(1) +#define ZYNQMP_CLK_DIVIDER_ALLOW_ZERO BIT(2) +#define ZYNQMP_CLK_DIVIDER_HIWORD_MASK BIT(3) +#define ZYNQMP_CLK_DIVIDER_ROUND_CLOSEST BIT(4) +#define ZYNQMP_CLK_DIVIDER_READ_ONLY BIT(5) +#define ZYNQMP_CLK_DIVIDER_MAX_AT_ZERO BIT(6) + +/* Type Flags for mux clock */ +#define ZYNQMP_CLK_MUX_INDEX_ONE BIT(0) +#define ZYNQMP_CLK_MUX_INDEX_BIT BIT(1) +#define ZYNQMP_CLK_MUX_HIWORD_MASK BIT(2) +#define ZYNQMP_CLK_MUX_READ_ONLY BIT(3) +#define ZYNQMP_CLK_MUX_ROUND_CLOSEST BIT(4) +#define ZYNQMP_CLK_MUX_BIG_ENDIAN BIT(5) + enum topology_type { TYPE_INVALID, TYPE_MUX, @@ -33,6 +64,8 @@ struct clock_topology { u8 custom_type_flag; }; +unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag); + struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, const char * const *parents, u8 num_parents, diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c index db8d0d7161ce..871184e406e1 100644 --- a/drivers/clk/zynqmp/clkc.c +++ b/drivers/clk/zynqmp/clkc.c @@ -271,6 +271,26 @@ static int zynqmp_pm_clock_get_topology(u32 clock_id, u32 index, return ret; } +unsigned long zynqmp_clk_map_common_ccf_flags(const u32 zynqmp_flag) +{ + unsigned long ccf_flag = 0; + + if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_GATE) + ccf_flag |= CLK_SET_RATE_GATE; + if (zynqmp_flag & ZYNQMP_CLK_SET_PARENT_GATE) + ccf_flag |= CLK_SET_PARENT_GATE; + if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_PARENT) + ccf_flag |= CLK_SET_RATE_PARENT; + if (zynqmp_flag & ZYNQMP_CLK_IGNORE_UNUSED) + ccf_flag |= CLK_IGNORE_UNUSED; + if (zynqmp_flag & ZYNQMP_CLK_SET_RATE_NO_REPARENT) + ccf_flag |= CLK_SET_RATE_NO_REPARENT; + if (zynqmp_flag & ZYNQMP_CLK_IS_CRITICAL) + ccf_flag |= CLK_IS_CRITICAL; + + return ccf_flag; +} + /** * zynqmp_clk_register_fixed_factor() - Register fixed factor with the * clock framework @@ -292,6 +312,7 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, struct zynqmp_pm_query_data qdata = {0}; u32 ret_payload[PAYLOAD_ARG_CNT]; int ret; + unsigned long flag; qdata.qid = PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS; qdata.arg1 = clk_id; @@ -303,9 +324,11 @@ struct clk_hw *zynqmp_clk_register_fixed_factor(const char *name, u32 clk_id, mult = ret_payload[1]; div = ret_payload[2]; + flag = zynqmp_clk_map_common_ccf_flags(nodes->flag); + hw = clk_hw_register_fixed_factor(NULL, name, parents[0], - nodes->flag, mult, + flag, mult, div); return hw; diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index e9bf7958b821..cb49281f9cf9 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -256,6 +256,11 @@ static const struct clk_ops zynqmp_clk_divider_ops = { .set_rate = zynqmp_clk_divider_set_rate, }; +static const struct clk_ops zynqmp_clk_divider_ro_ops = { + .recalc_rate = zynqmp_clk_divider_recalc_rate, + .round_rate = zynqmp_clk_divider_round_rate, +}; + /** * zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware. * @clk_id: Id of clock @@ -284,6 +289,29 @@ static u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type) return ret_payload[1]; } +static inline unsigned long zynqmp_clk_map_divider_ccf_flags( + const u32 zynqmp_type_flag) +{ + unsigned long ccf_flag = 0; + + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ONE_BASED) + ccf_flag |= CLK_DIVIDER_ONE_BASED; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_POWER_OF_TWO) + ccf_flag |= CLK_DIVIDER_POWER_OF_TWO; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ALLOW_ZERO) + ccf_flag |= CLK_DIVIDER_ALLOW_ZERO; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_POWER_OF_TWO) + ccf_flag |= CLK_DIVIDER_HIWORD_MASK; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_ROUND_CLOSEST) + ccf_flag |= CLK_DIVIDER_ROUND_CLOSEST; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_READ_ONLY) + ccf_flag |= CLK_DIVIDER_READ_ONLY; + if (zynqmp_type_flag & ZYNQMP_CLK_DIVIDER_MAX_AT_ZERO) + ccf_flag |= CLK_DIVIDER_MAX_AT_ZERO; + + return ccf_flag; +} + /** * zynqmp_clk_register_divider() - Register a divider clock * @name: Name of this clock @@ -311,16 +339,20 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, return ERR_PTR(-ENOMEM); init.name = name; - init.ops = &zynqmp_clk_divider_ops; - /* CLK_FRAC is not defined in the common clk framework */ - init.flags = nodes->flag & ~CLK_FRAC; + if (nodes->type_flag & CLK_DIVIDER_READ_ONLY) + init.ops = &zynqmp_clk_divider_ro_ops; + else + init.ops = &zynqmp_clk_divider_ops; + + init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag); + init.parent_names = parents; init.num_parents = 1; /* struct clk_divider assignments */ div->is_frac = !!((nodes->flag & CLK_FRAC) | (nodes->custom_type_flag & CUSTOM_FLAG_CLK_FRAC)); - div->flags = nodes->type_flag; + div->flags = zynqmp_clk_map_divider_ccf_flags(nodes->type_flag); div->hw.init = &init; div->clk_id = clk_id; div->div_type = nodes->type; diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index abe6afbf3407..036e4ff64a2f 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -31,8 +31,9 @@ struct zynqmp_pll { #define PS_PLL_VCO_MAX 3000000000UL enum pll_mode { - PLL_MODE_INT, - PLL_MODE_FRAC, + PLL_MODE_INT = 0, + PLL_MODE_FRAC = 1, + PLL_MODE_ERROR = 2, }; #define FRAC_OFFSET 0x8 @@ -54,9 +55,11 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw) int ret; ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload); - if (ret) + if (ret) { pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n", __func__, clk_name, ret); + return PLL_MODE_ERROR; + } return ret_payload[1]; } @@ -126,7 +129,7 @@ static long zynqmp_pll_round_rate(struct clk_hw *hw, unsigned long rate, * @hw: Handle between common and hardware-specific interfaces * @parent_rate: Clock frequency of parent clock * - * Return: Current clock frequency + * Return: Current clock frequency or 0 in case of error */ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -138,14 +141,21 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw, unsigned long rate, frac; u32 ret_payload[PAYLOAD_ARG_CNT]; int ret; + enum pll_mode mode; ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv); - if (ret) + if (ret) { pr_warn_once("%s() get divider failed for %s, ret = %d\n", __func__, clk_name, ret); + return 0ul; + } + + mode = zynqmp_pll_get_mode(hw); + if (mode == PLL_MODE_ERROR) + return 0ul; rate = parent_rate * fbdiv; - if (zynqmp_pll_get_mode(hw) == PLL_MODE_FRAC) { + if (mode == PLL_MODE_FRAC) { zynqmp_pm_get_pll_frac_data(clk_id, ret_payload); data = ret_payload[1]; frac = (parent_rate * data) / FRAC_DIV; @@ -312,7 +322,9 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, init.name = name; init.ops = &zynqmp_pll_ops; - init.flags = nodes->flag; + + init.flags = zynqmp_clk_map_common_ccf_flags(nodes->flag); + init.parent_names = parents; init.num_parents = 1; @@ -331,8 +343,6 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, } clk_hw_set_rate_range(hw, PS_PLL_VCO_MIN, PS_PLL_VCO_MAX); - if (ret < 0) - pr_err("%s:ERROR clk_set_rate_range failed %d\n", name, ret); return hw; } diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 9fa28237715a..eb661b539a3e 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -374,7 +374,7 @@ config ARM_GT_INITIAL_PRESCALER_VAL config ARM_TIMER_SP804 bool "Support for Dual Timer SP804 module" if COMPILE_TEST - depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP + depends on GENERIC_SCHED_CLOCK && HAVE_CLK select CLKSRC_MMIO select TIMER_OF if OF @@ -584,12 +584,12 @@ config H8300_TPU config CLKSRC_IMX_GPT bool "Clocksource using i.MX GPT" if COMPILE_TEST - depends on (ARM || ARM64) && CLKDEV_LOOKUP + depends on (ARM || ARM64) && HAVE_CLK select CLKSRC_MMIO config CLKSRC_IMX_TPM bool "Clocksource using i.MX TPM" if COMPILE_TEST - depends on (ARM || ARM64) && CLKDEV_LOOKUP + depends on (ARM || ARM64) && HAVE_CLK select CLKSRC_MMIO select TIMER_OF help diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 561184fa7eb9..71313961cc54 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -329,7 +329,7 @@ config MMC_SDHCI_S3C config MMC_SDHCI_PXAV3 tristate "Marvell MMP2 SD Host Controller support (PXAV3)" - depends on CLKDEV_LOOKUP + depends on HAVE_CLK depends on MMC_SDHCI_PLTFM depends on ARCH_BERLIN || ARCH_MMP || ARCH_MVEBU || COMPILE_TEST default CPU_MMP2 @@ -342,7 +342,7 @@ config MMC_SDHCI_PXAV3 config MMC_SDHCI_PXAV2 tristate "Marvell PXA9XX SD Host Controller support (PXAV2)" - depends on CLKDEV_LOOKUP + depends on HAVE_CLK depends on MMC_SDHCI_PLTFM depends on ARCH_MMP || COMPILE_TEST default CPU_PXA910 diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 3e7f55e44d84..29fb33c0e26d 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -199,12 +199,6 @@ config RESET_SIMPLE - ZTE's zx2967 family - SiFive FU740 SoCs -config RESET_STM32MP157 - bool "STM32MP157 Reset Driver" if COMPILE_TEST - default MACH_STM32MP157 - help - This enables the RCC reset controller driver for STM32 MPUs. - config RESET_SOCFPGA bool "SoCFPGA Reset Driver" if COMPILE_TEST && (!ARM || !ARCH_INTEL_SOCFPGA) default ARM && ARCH_INTEL_SOCFPGA diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 65a118a91b27..ac3e612ad953 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -26,7 +26,6 @@ obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o obj-$(CONFIG_RESET_SCMI) += reset-scmi.o obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o -obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o diff --git a/drivers/reset/reset-stm32mp1.c b/drivers/reset/reset-stm32mp1.c deleted file mode 100644 index b221a28041fa..000000000000 --- a/drivers/reset/reset-stm32mp1.c +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (C) STMicroelectronics 2018 - All Rights Reserved - * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics. - */ - -#include <linux/device.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/reset-controller.h> - -#define CLR_OFFSET 0x4 - -struct stm32_reset_data { - struct reset_controller_dev rcdev; - void __iomem *membase; -}; - -static inline struct stm32_reset_data * -to_stm32_reset_data(struct reset_controller_dev *rcdev) -{ - return container_of(rcdev, struct stm32_reset_data, rcdev); -} - -static int stm32_reset_update(struct reset_controller_dev *rcdev, - unsigned long id, bool assert) -{ - struct stm32_reset_data *data = to_stm32_reset_data(rcdev); - int reg_width = sizeof(u32); - int bank = id / (reg_width * BITS_PER_BYTE); - int offset = id % (reg_width * BITS_PER_BYTE); - void __iomem *addr; - - addr = data->membase + (bank * reg_width); - if (!assert) - addr += CLR_OFFSET; - - writel(BIT(offset), addr); - - return 0; -} - -static int stm32_reset_assert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - return stm32_reset_update(rcdev, id, true); -} - -static int stm32_reset_deassert(struct reset_controller_dev *rcdev, - unsigned long id) -{ - return stm32_reset_update(rcdev, id, false); -} - -static int stm32_reset_status(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct stm32_reset_data *data = to_stm32_reset_data(rcdev); - int reg_width = sizeof(u32); - int bank = id / (reg_width * BITS_PER_BYTE); - int offset = id % (reg_width * BITS_PER_BYTE); - u32 reg; - - reg = readl(data->membase + (bank * reg_width)); - - return !!(reg & BIT(offset)); -} - -static const struct reset_control_ops stm32_reset_ops = { - .assert = stm32_reset_assert, - .deassert = stm32_reset_deassert, - .status = stm32_reset_status, -}; - -static const struct of_device_id stm32_reset_dt_ids[] = { - { .compatible = "st,stm32mp1-rcc"}, - { /* sentinel */ }, -}; - -static int stm32_reset_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct stm32_reset_data *data; - void __iomem *membase; - struct resource *res; - - data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - membase = devm_ioremap_resource(dev, res); - if (IS_ERR(membase)) - return PTR_ERR(membase); - - data->membase = membase; - data->rcdev.owner = THIS_MODULE; - data->rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE; - data->rcdev.ops = &stm32_reset_ops; - data->rcdev.of_node = dev->of_node; - - return devm_reset_controller_register(dev, &data->rcdev); -} - -static struct platform_driver stm32_reset_driver = { - .probe = stm32_reset_probe, - .driver = { - .name = "stm32mp1-reset", - .of_match_table = stm32_reset_dt_ids, - }, -}; - -builtin_platform_driver(stm32_reset_driver); diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 8e3b78bb2ac2..4a582eae82ef 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -743,11 +743,6 @@ out: return err; } -int __weak tegra210_clk_handle_mbist_war(unsigned int id) -{ - return 0; -} - static int tegra_powergate_power_up(struct tegra_powergate *pg, bool disable_clocks) { diff --git a/drivers/staging/board/Kconfig b/drivers/staging/board/Kconfig index 64c77970eee8..b49216768ef6 100644 --- a/drivers/staging/board/Kconfig +++ b/drivers/staging/board/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 config STAGING_BOARD bool "Staging Board Support" - depends on OF_ADDRESS && OF_IRQ && CLKDEV_LOOKUP + depends on OF_ADDRESS && OF_IRQ && HAVE_CLK help Staging board base is to support continuous upstream in-tree development and integration of platform devices. diff --git a/include/dt-bindings/clock/actions,s500-cmu.h b/include/dt-bindings/clock/actions,s500-cmu.h index a250a52a6192..a237eb26accb 100644 --- a/include/dt-bindings/clock/actions,s500-cmu.h +++ b/include/dt-bindings/clock/actions,s500-cmu.h @@ -74,10 +74,12 @@ #define CLK_RMII_REF 54 #define CLK_GPIO 55 -/* system clock (part 2) */ +/* additional clocks */ #define CLK_APB 56 #define CLK_DMAC 57 +#define CLK_NIC 58 +#define CLK_ETHERNET 59 -#define CLK_NR_CLKS (CLK_DMAC + 1) +#define CLK_NR_CLKS (CLK_ETHERNET + 1) #endif /* __DT_BINDINGS_CLOCK_S500_CMU_H */ diff --git a/include/dt-bindings/clock/hi3559av100-clock.h b/include/dt-bindings/clock/hi3559av100-clock.h new file mode 100644 index 000000000000..5fe7689010a0 --- /dev/null +++ b/include/dt-bindings/clock/hi3559av100-clock.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */ +/* + * Copyright (c) 2019-2020, Huawei Tech. Co., Ltd. + * + * Author: Dongjiu Geng <gengdongjiu@huawei.com> + */ + +#ifndef __DTS_HI3559AV100_CLOCK_H +#define __DTS_HI3559AV100_CLOCK_H + +/* fixed rate */ +#define HI3559AV100_FIXED_1188M 1 +#define HI3559AV100_FIXED_1000M 2 +#define HI3559AV100_FIXED_842M 3 +#define HI3559AV100_FIXED_792M 4 +#define HI3559AV100_FIXED_750M 5 +#define HI3559AV100_FIXED_710M 6 +#define HI3559AV100_FIXED_680M 7 +#define HI3559AV100_FIXED_667M 8 +#define HI3559AV100_FIXED_631M 9 +#define HI3559AV100_FIXED_600M 10 +#define HI3559AV100_FIXED_568M 11 +#define HI3559AV100_FIXED_500M 12 +#define HI3559AV100_FIXED_475M 13 +#define HI3559AV100_FIXED_428M 14 +#define HI3559AV100_FIXED_400M 15 +#define HI3559AV100_FIXED_396M 16 +#define HI3559AV100_FIXED_300M 17 +#define HI3559AV100_FIXED_250M 18 +#define HI3559AV100_FIXED_198M 19 +#define HI3559AV100_FIXED_187p5M 20 +#define HI3559AV100_FIXED_150M 21 +#define HI3559AV100_FIXED_148p5M 22 +#define HI3559AV100_FIXED_125M 23 +#define HI3559AV100_FIXED_107M 24 +#define HI3559AV100_FIXED_100M 25 +#define HI3559AV100_FIXED_99M 26 +#define HI3559AV100_FIXED_74p25M 27 +#define HI3559AV100_FIXED_72M 28 +#define HI3559AV100_FIXED_60M 29 +#define HI3559AV100_FIXED_54M 30 +#define HI3559AV100_FIXED_50M 31 +#define HI3559AV100_FIXED_49p5M 32 +#define HI3559AV100_FIXED_37p125M 33 +#define HI3559AV100_FIXED_36M 34 +#define HI3559AV100_FIXED_32p4M 35 +#define HI3559AV100_FIXED_27M 36 +#define HI3559AV100_FIXED_25M 37 +#define HI3559AV100_FIXED_24M 38 +#define HI3559AV100_FIXED_12M 39 +#define HI3559AV100_FIXED_3M 40 +#define HI3559AV100_FIXED_1p6M 41 +#define HI3559AV100_FIXED_400K 42 +#define HI3559AV100_FIXED_100K 43 +#define HI3559AV100_FIXED_200M 44 +#define HI3559AV100_FIXED_75M 75 + +#define HI3559AV100_I2C0_CLK 50 +#define HI3559AV100_I2C1_CLK 51 +#define HI3559AV100_I2C2_CLK 52 +#define HI3559AV100_I2C3_CLK 53 +#define HI3559AV100_I2C4_CLK 54 +#define HI3559AV100_I2C5_CLK 55 +#define HI3559AV100_I2C6_CLK 56 +#define HI3559AV100_I2C7_CLK 57 +#define HI3559AV100_I2C8_CLK 58 +#define HI3559AV100_I2C9_CLK 59 +#define HI3559AV100_I2C10_CLK 60 +#define HI3559AV100_I2C11_CLK 61 + +#define HI3559AV100_SPI0_CLK 62 +#define HI3559AV100_SPI1_CLK 63 +#define HI3559AV100_SPI2_CLK 64 +#define HI3559AV100_SPI3_CLK 65 +#define HI3559AV100_SPI4_CLK 66 +#define HI3559AV100_SPI5_CLK 67 +#define HI3559AV100_SPI6_CLK 68 + +#define HI3559AV100_EDMAC_CLK 69 +#define HI3559AV100_EDMAC_AXICLK 70 +#define HI3559AV100_EDMAC1_CLK 71 +#define HI3559AV100_EDMAC1_AXICLK 72 +#define HI3559AV100_VDMAC_CLK 73 + +/* mux clocks */ +#define HI3559AV100_FMC_MUX 80 +#define HI3559AV100_SYSAPB_MUX 81 +#define HI3559AV100_UART_MUX 82 +#define HI3559AV100_SYSBUS_MUX 83 +#define HI3559AV100_A73_MUX 84 +#define HI3559AV100_MMC0_MUX 85 +#define HI3559AV100_MMC1_MUX 86 +#define HI3559AV100_MMC2_MUX 87 +#define HI3559AV100_MMC3_MUX 88 + +/* gate clocks */ +#define HI3559AV100_FMC_CLK 90 +#define HI3559AV100_UART0_CLK 91 +#define HI3559AV100_UART1_CLK 92 +#define HI3559AV100_UART2_CLK 93 +#define HI3559AV100_UART3_CLK 94 +#define HI3559AV100_UART4_CLK 95 +#define HI3559AV100_MMC0_CLK 96 +#define HI3559AV100_MMC1_CLK 97 +#define HI3559AV100_MMC2_CLK 98 +#define HI3559AV100_MMC3_CLK 99 + +#define HI3559AV100_ETH_CLK 100 +#define HI3559AV100_ETH_MACIF_CLK 101 +#define HI3559AV100_ETH1_CLK 102 +#define HI3559AV100_ETH1_MACIF_CLK 103 + +/* complex */ +#define HI3559AV100_MAC0_CLK 110 +#define HI3559AV100_MAC1_CLK 111 +#define HI3559AV100_SATA_CLK 112 +#define HI3559AV100_USB_CLK 113 +#define HI3559AV100_USB1_CLK 114 + +/* pll clocks */ +#define HI3559AV100_APLL_CLK 250 +#define HI3559AV100_GPLL_CLK 251 + +#define HI3559AV100_CRG_NR_CLKS 256 + +#define HI3559AV100_SHUB_SOURCE_SOC_24M 0 +#define HI3559AV100_SHUB_SOURCE_SOC_200M 1 +#define HI3559AV100_SHUB_SOURCE_SOC_300M 2 +#define HI3559AV100_SHUB_SOURCE_PLL 3 +#define HI3559AV100_SHUB_SOURCE_CLK 4 + +#define HI3559AV100_SHUB_I2C0_CLK 10 +#define HI3559AV100_SHUB_I2C1_CLK 11 +#define HI3559AV100_SHUB_I2C2_CLK 12 +#define HI3559AV100_SHUB_I2C3_CLK 13 +#define HI3559AV100_SHUB_I2C4_CLK 14 +#define HI3559AV100_SHUB_I2C5_CLK 15 +#define HI3559AV100_SHUB_I2C6_CLK 16 +#define HI3559AV100_SHUB_I2C7_CLK 17 + +#define HI3559AV100_SHUB_SPI_SOURCE_CLK 20 +#define HI3559AV100_SHUB_SPI4_SOURCE_CLK 21 +#define HI3559AV100_SHUB_SPI0_CLK 22 +#define HI3559AV100_SHUB_SPI1_CLK 23 +#define HI3559AV100_SHUB_SPI2_CLK 24 +#define HI3559AV100_SHUB_SPI3_CLK 25 +#define HI3559AV100_SHUB_SPI4_CLK 26 + +#define HI3559AV100_SHUB_UART_CLK_32K 30 +#define HI3559AV100_SHUB_UART_SOURCE_CLK 31 +#define HI3559AV100_SHUB_UART_DIV_CLK 32 +#define HI3559AV100_SHUB_UART0_CLK 33 +#define HI3559AV100_SHUB_UART1_CLK 34 +#define HI3559AV100_SHUB_UART2_CLK 35 +#define HI3559AV100_SHUB_UART3_CLK 36 +#define HI3559AV100_SHUB_UART4_CLK 37 +#define HI3559AV100_SHUB_UART5_CLK 38 +#define HI3559AV100_SHUB_UART6_CLK 39 + +#define HI3559AV100_SHUB_EDMAC_CLK 40 + +#define HI3559AV100_SHUB_NR_CLKS 50 + +#endif /* __DTS_HI3559AV100_CLOCK_H */ + diff --git a/include/dt-bindings/clock/imx8-clock.h b/include/dt-bindings/clock/imx8-clock.h index 82b1fc8d1ee0..2e60ce4d2622 100644 --- a/include/dt-bindings/clock/imx8-clock.h +++ b/include/dt-bindings/clock/imx8-clock.h @@ -7,134 +7,6 @@ #ifndef __DT_BINDINGS_CLOCK_IMX_H #define __DT_BINDINGS_CLOCK_IMX_H -/* SCU Clocks */ - -#define IMX_CLK_DUMMY 0 - -/* CPU */ -#define IMX_A35_CLK 1 - -/* LSIO SS */ -#define IMX_LSIO_MEM_CLK 2 -#define IMX_LSIO_BUS_CLK 3 -#define IMX_LSIO_PWM0_CLK 10 -#define IMX_LSIO_PWM1_CLK 11 -#define IMX_LSIO_PWM2_CLK 12 -#define IMX_LSIO_PWM3_CLK 13 -#define IMX_LSIO_PWM4_CLK 14 -#define IMX_LSIO_PWM5_CLK 15 -#define IMX_LSIO_PWM6_CLK 16 -#define IMX_LSIO_PWM7_CLK 17 -#define IMX_LSIO_GPT0_CLK 18 -#define IMX_LSIO_GPT1_CLK 19 -#define IMX_LSIO_GPT2_CLK 20 -#define IMX_LSIO_GPT3_CLK 21 -#define IMX_LSIO_GPT4_CLK 22 -#define IMX_LSIO_FSPI0_CLK 23 -#define IMX_LSIO_FSPI1_CLK 24 - -/* Connectivity SS */ -#define IMX_CONN_AXI_CLK_ROOT 30 -#define IMX_CONN_AHB_CLK_ROOT 31 -#define IMX_CONN_IPG_CLK_ROOT 32 -#define IMX_CONN_SDHC0_CLK 40 -#define IMX_CONN_SDHC1_CLK 41 -#define IMX_CONN_SDHC2_CLK 42 -#define IMX_CONN_ENET0_ROOT_CLK 43 -#define IMX_CONN_ENET0_BYPASS_CLK 44 -#define IMX_CONN_ENET0_RGMII_CLK 45 -#define IMX_CONN_ENET1_ROOT_CLK 46 -#define IMX_CONN_ENET1_BYPASS_CLK 47 -#define IMX_CONN_ENET1_RGMII_CLK 48 -#define IMX_CONN_GPMI_BCH_IO_CLK 49 -#define IMX_CONN_GPMI_BCH_CLK 50 -#define IMX_CONN_USB2_ACLK 51 -#define IMX_CONN_USB2_BUS_CLK 52 -#define IMX_CONN_USB2_LPM_CLK 53 - -/* HSIO SS */ -#define IMX_HSIO_AXI_CLK 60 -#define IMX_HSIO_PER_CLK 61 - -/* Display controller SS */ -#define IMX_DC_AXI_EXT_CLK 70 -#define IMX_DC_AXI_INT_CLK 71 -#define IMX_DC_CFG_CLK 72 -#define IMX_DC0_PLL0_CLK 80 -#define IMX_DC0_PLL1_CLK 81 -#define IMX_DC0_DISP0_CLK 82 -#define IMX_DC0_DISP1_CLK 83 -#define IMX_DC0_BYPASS0_CLK 84 -#define IMX_DC0_BYPASS1_CLK 85 - -/* MIPI-LVDS SS */ -#define IMX_MIPI_IPG_CLK 90 -#define IMX_MIPI0_PIXEL_CLK 100 -#define IMX_MIPI0_BYPASS_CLK 101 -#define IMX_MIPI0_LVDS_PIXEL_CLK 102 -#define IMX_MIPI0_LVDS_BYPASS_CLK 103 -#define IMX_MIPI0_LVDS_PHY_CLK 104 -#define IMX_MIPI0_I2C0_CLK 105 -#define IMX_MIPI0_I2C1_CLK 106 -#define IMX_MIPI0_PWM0_CLK 107 -#define IMX_MIPI1_PIXEL_CLK 108 -#define IMX_MIPI1_BYPASS_CLK 109 -#define IMX_MIPI1_LVDS_PIXEL_CLK 110 -#define IMX_MIPI1_LVDS_BYPASS_CLK 111 -#define IMX_MIPI1_LVDS_PHY_CLK 112 -#define IMX_MIPI1_I2C0_CLK 113 -#define IMX_MIPI1_I2C1_CLK 114 -#define IMX_MIPI1_PWM0_CLK 115 - -/* IMG SS */ -#define IMX_IMG_AXI_CLK 120 -#define IMX_IMG_IPG_CLK 121 -#define IMX_IMG_PXL_CLK 122 - -/* MIPI-CSI SS */ -#define IMX_CSI0_CORE_CLK 130 -#define IMX_CSI0_ESC_CLK 131 -#define IMX_CSI0_PWM0_CLK 132 -#define IMX_CSI0_I2C0_CLK 133 - -/* PARALLER CSI SS */ -#define IMX_PARALLEL_CSI_DPLL_CLK 140 -#define IMX_PARALLEL_CSI_PIXEL_CLK 141 -#define IMX_PARALLEL_CSI_MCLK_CLK 142 - -/* VPU SS */ -#define IMX_VPU_ENC_CLK 150 -#define IMX_VPU_DEC_CLK 151 - -/* GPU SS */ -#define IMX_GPU0_CORE_CLK 160 -#define IMX_GPU0_SHADER_CLK 161 - -/* ADMA SS */ -#define IMX_ADMA_IPG_CLK_ROOT 165 -#define IMX_ADMA_UART0_CLK 170 -#define IMX_ADMA_UART1_CLK 171 -#define IMX_ADMA_UART2_CLK 172 -#define IMX_ADMA_UART3_CLK 173 -#define IMX_ADMA_SPI0_CLK 174 -#define IMX_ADMA_SPI1_CLK 175 -#define IMX_ADMA_SPI2_CLK 176 -#define IMX_ADMA_SPI3_CLK 177 -#define IMX_ADMA_CAN0_CLK 178 -#define IMX_ADMA_CAN1_CLK 179 -#define IMX_ADMA_CAN2_CLK 180 -#define IMX_ADMA_I2C0_CLK 181 -#define IMX_ADMA_I2C1_CLK 182 -#define IMX_ADMA_I2C2_CLK 183 -#define IMX_ADMA_I2C3_CLK 184 -#define IMX_ADMA_FTM0_CLK 185 -#define IMX_ADMA_FTM1_CLK 186 -#define IMX_ADMA_ADC0_CLK 187 -#define IMX_ADMA_PWM_CLK 188 -#define IMX_ADMA_LCD_CLK 189 - -#define IMX_SCU_CLK_END 190 - /* LPCG clocks */ /* LSIO SS LPCG */ diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h index 82e907ce7bdd..afa74d7ba100 100644 --- a/include/dt-bindings/clock/imx8mq-clock.h +++ b/include/dt-bindings/clock/imx8mq-clock.h @@ -405,25 +405,6 @@ #define IMX8MQ_VIDEO2_PLL1_REF_SEL 266 -#define IMX8MQ_SYS1_PLL_40M_CG 267 -#define IMX8MQ_SYS1_PLL_80M_CG 268 -#define IMX8MQ_SYS1_PLL_100M_CG 269 -#define IMX8MQ_SYS1_PLL_133M_CG 270 -#define IMX8MQ_SYS1_PLL_160M_CG 271 -#define IMX8MQ_SYS1_PLL_200M_CG 272 -#define IMX8MQ_SYS1_PLL_266M_CG 273 -#define IMX8MQ_SYS1_PLL_400M_CG 274 -#define IMX8MQ_SYS1_PLL_800M_CG 275 -#define IMX8MQ_SYS2_PLL_50M_CG 276 -#define IMX8MQ_SYS2_PLL_100M_CG 277 -#define IMX8MQ_SYS2_PLL_125M_CG 278 -#define IMX8MQ_SYS2_PLL_166M_CG 279 -#define IMX8MQ_SYS2_PLL_200M_CG 280 -#define IMX8MQ_SYS2_PLL_250M_CG 281 -#define IMX8MQ_SYS2_PLL_333M_CG 282 -#define IMX8MQ_SYS2_PLL_500M_CG 283 -#define IMX8MQ_SYS2_PLL_1000M_CG 284 - #define IMX8MQ_CLK_GPU_CORE 285 #define IMX8MQ_CLK_GPU_SHADER 286 #define IMX8MQ_CLK_M4_CORE 287 diff --git a/include/dt-bindings/clock/jz4760-cgu.h b/include/dt-bindings/clock/jz4760-cgu.h new file mode 100644 index 000000000000..4bb2e19c4743 --- /dev/null +++ b/include/dt-bindings/clock/jz4760-cgu.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides clock numbers for the ingenic,jz4760-cgu DT binding. + */ + +#ifndef __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ +#define __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ + +#define JZ4760_CLK_EXT 0 +#define JZ4760_CLK_OSC32K 1 +#define JZ4760_CLK_PLL0 2 +#define JZ4760_CLK_PLL0_HALF 3 +#define JZ4760_CLK_PLL1 4 +#define JZ4760_CLK_CCLK 5 +#define JZ4760_CLK_HCLK 6 +#define JZ4760_CLK_SCLK 7 +#define JZ4760_CLK_H2CLK 8 +#define JZ4760_CLK_MCLK 9 +#define JZ4760_CLK_PCLK 10 +#define JZ4760_CLK_MMC_MUX 11 +#define JZ4760_CLK_MMC0 12 +#define JZ4760_CLK_MMC1 13 +#define JZ4760_CLK_MMC2 14 +#define JZ4760_CLK_CIM 15 +#define JZ4760_CLK_UHC 16 +#define JZ4760_CLK_GPU 17 +#define JZ4760_CLK_GPS 18 +#define JZ4760_CLK_SSI_MUX 19 +#define JZ4760_CLK_PCM 20 +#define JZ4760_CLK_I2S 21 +#define JZ4760_CLK_OTG 22 +#define JZ4760_CLK_SSI0 23 +#define JZ4760_CLK_SSI1 24 +#define JZ4760_CLK_SSI2 25 +#define JZ4760_CLK_DMA 26 +#define JZ4760_CLK_I2C0 27 +#define JZ4760_CLK_I2C1 28 +#define JZ4760_CLK_UART0 29 +#define JZ4760_CLK_UART1 30 +#define JZ4760_CLK_UART2 31 +#define JZ4760_CLK_UART3 32 +#define JZ4760_CLK_IPU 33 +#define JZ4760_CLK_ADC 34 +#define JZ4760_CLK_AIC 35 +#define JZ4760_CLK_VPU 36 +#define JZ4760_CLK_UHC_PHY 37 +#define JZ4760_CLK_OTG_PHY 38 +#define JZ4760_CLK_EXT512 39 +#define JZ4760_CLK_RTC 40 +#define JZ4760_CLK_LPCLK_DIV 41 +#define JZ4760_CLK_TVE 42 +#define JZ4760_CLK_LPCLK 43 + +#endif /* __DT_BINDINGS_CLOCK_JZ4760_CGU_H__ */ diff --git a/include/dt-bindings/clock/qcom,camcc-sm8250.h b/include/dt-bindings/clock/qcom,camcc-sm8250.h new file mode 100644 index 000000000000..383ead17608d --- /dev/null +++ b/include/dt-bindings/clock/qcom,camcc-sm8250.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8250_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8250_H + +/* CAM_CC clocks */ +#define CAM_CC_BPS_AHB_CLK 0 +#define CAM_CC_BPS_AREG_CLK 1 +#define CAM_CC_BPS_AXI_CLK 2 +#define CAM_CC_BPS_CLK 3 +#define CAM_CC_BPS_CLK_SRC 4 +#define CAM_CC_CAMNOC_AXI_CLK 5 +#define CAM_CC_CAMNOC_AXI_CLK_SRC 6 +#define CAM_CC_CAMNOC_DCD_XO_CLK 7 +#define CAM_CC_CCI_0_CLK 8 +#define CAM_CC_CCI_0_CLK_SRC 9 +#define CAM_CC_CCI_1_CLK 10 +#define CAM_CC_CCI_1_CLK_SRC 11 +#define CAM_CC_CORE_AHB_CLK 12 +#define CAM_CC_CPAS_AHB_CLK 13 +#define CAM_CC_CPHY_RX_CLK_SRC 14 +#define CAM_CC_CSI0PHYTIMER_CLK 15 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 16 +#define CAM_CC_CSI1PHYTIMER_CLK 17 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 18 +#define CAM_CC_CSI2PHYTIMER_CLK 19 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 20 +#define CAM_CC_CSI3PHYTIMER_CLK 21 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 22 +#define CAM_CC_CSI4PHYTIMER_CLK 23 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 24 +#define CAM_CC_CSI5PHYTIMER_CLK 25 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 26 +#define CAM_CC_CSIPHY0_CLK 27 +#define CAM_CC_CSIPHY1_CLK 28 +#define CAM_CC_CSIPHY2_CLK 29 +#define CAM_CC_CSIPHY3_CLK 30 +#define CAM_CC_CSIPHY4_CLK 31 +#define CAM_CC_CSIPHY5_CLK 32 +#define CAM_CC_FAST_AHB_CLK_SRC 33 +#define CAM_CC_FD_CORE_CLK 34 +#define CAM_CC_FD_CORE_CLK_SRC 35 +#define CAM_CC_FD_CORE_UAR_CLK 36 +#define CAM_CC_GDSC_CLK 37 +#define CAM_CC_ICP_AHB_CLK 38 +#define CAM_CC_ICP_CLK 39 +#define CAM_CC_ICP_CLK_SRC 40 +#define CAM_CC_IFE_0_AHB_CLK 41 +#define CAM_CC_IFE_0_AREG_CLK 42 +#define CAM_CC_IFE_0_AXI_CLK 43 +#define CAM_CC_IFE_0_CLK 44 +#define CAM_CC_IFE_0_CLK_SRC 45 +#define CAM_CC_IFE_0_CPHY_RX_CLK 46 +#define CAM_CC_IFE_0_CSID_CLK 47 +#define CAM_CC_IFE_0_CSID_CLK_SRC 48 +#define CAM_CC_IFE_0_DSP_CLK 49 +#define CAM_CC_IFE_1_AHB_CLK 50 +#define CAM_CC_IFE_1_AREG_CLK 51 +#define CAM_CC_IFE_1_AXI_CLK 52 +#define CAM_CC_IFE_1_CLK 53 +#define CAM_CC_IFE_1_CLK_SRC 54 +#define CAM_CC_IFE_1_CPHY_RX_CLK 55 +#define CAM_CC_IFE_1_CSID_CLK 56 +#define CAM_CC_IFE_1_CSID_CLK_SRC 57 +#define CAM_CC_IFE_1_DSP_CLK 58 +#define CAM_CC_IFE_LITE_AHB_CLK 59 +#define CAM_CC_IFE_LITE_AXI_CLK 60 +#define CAM_CC_IFE_LITE_CLK 61 +#define CAM_CC_IFE_LITE_CLK_SRC 62 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 63 +#define CAM_CC_IFE_LITE_CSID_CLK 64 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 65 +#define CAM_CC_IPE_0_AHB_CLK 66 +#define CAM_CC_IPE_0_AREG_CLK 67 +#define CAM_CC_IPE_0_AXI_CLK 68 +#define CAM_CC_IPE_0_CLK 69 +#define CAM_CC_IPE_0_CLK_SRC 70 +#define CAM_CC_JPEG_CLK 71 +#define CAM_CC_JPEG_CLK_SRC 72 +#define CAM_CC_MCLK0_CLK 73 +#define CAM_CC_MCLK0_CLK_SRC 74 +#define CAM_CC_MCLK1_CLK 75 +#define CAM_CC_MCLK1_CLK_SRC 76 +#define CAM_CC_MCLK2_CLK 77 +#define CAM_CC_MCLK2_CLK_SRC 78 +#define CAM_CC_MCLK3_CLK 79 +#define CAM_CC_MCLK3_CLK_SRC 80 +#define CAM_CC_MCLK4_CLK 81 +#define CAM_CC_MCLK4_CLK_SRC 82 +#define CAM_CC_MCLK5_CLK 83 +#define CAM_CC_MCLK5_CLK_SRC 84 +#define CAM_CC_MCLK6_CLK 85 +#define CAM_CC_MCLK6_CLK_SRC 86 +#define CAM_CC_PLL0 87 +#define CAM_CC_PLL0_OUT_EVEN 88 +#define CAM_CC_PLL0_OUT_ODD 89 +#define CAM_CC_PLL1 90 +#define CAM_CC_PLL1_OUT_EVEN 91 +#define CAM_CC_PLL2 92 +#define CAM_CC_PLL2_OUT_MAIN 93 +#define CAM_CC_PLL3 94 +#define CAM_CC_PLL3_OUT_EVEN 95 +#define CAM_CC_PLL4 96 +#define CAM_CC_PLL4_OUT_EVEN 97 +#define CAM_CC_SBI_AHB_CLK 98 +#define CAM_CC_SBI_AXI_CLK 99 +#define CAM_CC_SBI_CLK 100 +#define CAM_CC_SBI_CPHY_RX_CLK 101 +#define CAM_CC_SBI_CSID_CLK 102 +#define CAM_CC_SBI_CSID_CLK_SRC 103 +#define CAM_CC_SBI_DIV_CLK_SRC 104 +#define CAM_CC_SBI_IFE_0_CLK 105 +#define CAM_CC_SBI_IFE_1_CLK 106 +#define CAM_CC_SLEEP_CLK 107 +#define CAM_CC_SLEEP_CLK_SRC 108 +#define CAM_CC_SLOW_AHB_CLK_SRC 109 +#define CAM_CC_XO_CLK_SRC 110 + +/* CAM_CC resets */ +#define CAM_CC_BPS_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IFE_0_BCR 2 +#define CAM_CC_IFE_1_BCR 3 +#define CAM_CC_IPE_0_BCR 4 +#define CAM_CC_SBI_BCR 5 + +/* CAM_CC GDSCRs */ +#define BPS_GDSC 0 +#define IPE_0_GDSC 1 +#define SBI_GDSC 2 +#define IFE_0_GDSC 3 +#define IFE_1_GDSC 4 +#define TITAN_TOP_GDSC 5 + +#endif diff --git a/include/dt-bindings/clock/qcom,dispcc-sm8250.h b/include/dt-bindings/clock/qcom,dispcc-sm8250.h index fdaca6ad5c85..ce001cbbc27f 100644 --- a/include/dt-bindings/clock/qcom,dispcc-sm8250.h +++ b/include/dt-bindings/clock/qcom,dispcc-sm8250.h @@ -55,6 +55,15 @@ #define DISP_CC_MDSS_VSYNC_CLK_SRC 45 #define DISP_CC_PLL0 46 #define DISP_CC_PLL1 47 +#define DISP_CC_MDSS_EDP_AUX_CLK 48 +#define DISP_CC_MDSS_EDP_AUX_CLK_SRC 49 +#define DISP_CC_MDSS_EDP_GTC_CLK 50 +#define DISP_CC_MDSS_EDP_GTC_CLK_SRC 51 +#define DISP_CC_MDSS_EDP_LINK_CLK 52 +#define DISP_CC_MDSS_EDP_LINK_CLK_SRC 53 +#define DISP_CC_MDSS_EDP_LINK_INTF_CLK 54 +#define DISP_CC_MDSS_EDP_PIXEL_CLK 55 +#define DISP_CC_MDSS_EDP_PIXEL_CLK_SRC 56 /* DISP_CC Reset */ #define DISP_CC_MDSS_CORE_BCR 0 diff --git a/include/dt-bindings/clock/qcom,gcc-mdm9607.h b/include/dt-bindings/clock/qcom,gcc-mdm9607.h new file mode 100644 index 000000000000..357a680a40da --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-mdm9607.h @@ -0,0 +1,104 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> + */ + +#ifndef _DT_BINDINGS_CLK_MSM_GCC_9607_H +#define _DT_BINDINGS_CLK_MSM_GCC_9607_H + +#define GPLL0 0 +#define GPLL0_EARLY 1 +#define GPLL1 2 +#define GPLL1_VOTE 3 +#define GPLL2 4 +#define GPLL2_EARLY 5 +#define PCNOC_BFDCD_CLK_SRC 6 +#define SYSTEM_NOC_BFDCD_CLK_SRC 7 +#define GCC_SMMU_CFG_CLK 8 +#define APSS_AHB_CLK_SRC 9 +#define GCC_QDSS_DAP_CLK 10 +#define BLSP1_QUP1_I2C_APPS_CLK_SRC 11 +#define BLSP1_QUP1_SPI_APPS_CLK_SRC 12 +#define BLSP1_QUP2_I2C_APPS_CLK_SRC 13 +#define BLSP1_QUP2_SPI_APPS_CLK_SRC 14 +#define BLSP1_QUP3_I2C_APPS_CLK_SRC 15 +#define BLSP1_QUP3_SPI_APPS_CLK_SRC 16 +#define BLSP1_QUP4_I2C_APPS_CLK_SRC 17 +#define BLSP1_QUP4_SPI_APPS_CLK_SRC 18 +#define BLSP1_QUP5_I2C_APPS_CLK_SRC 19 +#define BLSP1_QUP5_SPI_APPS_CLK_SRC 20 +#define BLSP1_QUP6_I2C_APPS_CLK_SRC 21 +#define BLSP1_QUP6_SPI_APPS_CLK_SRC 22 +#define BLSP1_UART1_APPS_CLK_SRC 23 +#define BLSP1_UART2_APPS_CLK_SRC 24 +#define CRYPTO_CLK_SRC 25 +#define GP1_CLK_SRC 26 +#define GP2_CLK_SRC 27 +#define GP3_CLK_SRC 28 +#define PDM2_CLK_SRC 29 +#define SDCC1_APPS_CLK_SRC 30 +#define SDCC2_APPS_CLK_SRC 31 +#define APSS_TCU_CLK_SRC 32 +#define USB_HS_SYSTEM_CLK_SRC 33 +#define GCC_BLSP1_AHB_CLK 34 +#define GCC_BLSP1_SLEEP_CLK 35 +#define GCC_BLSP1_QUP1_I2C_APPS_CLK 36 +#define GCC_BLSP1_QUP1_SPI_APPS_CLK 37 +#define GCC_BLSP1_QUP2_I2C_APPS_CLK 38 +#define GCC_BLSP1_QUP2_SPI_APPS_CLK 39 +#define GCC_BLSP1_QUP3_I2C_APPS_CLK 40 +#define GCC_BLSP1_QUP3_SPI_APPS_CLK 41 +#define GCC_BLSP1_QUP4_I2C_APPS_CLK 42 +#define GCC_BLSP1_QUP4_SPI_APPS_CLK 43 +#define GCC_BLSP1_QUP5_I2C_APPS_CLK 44 +#define GCC_BLSP1_QUP5_SPI_APPS_CLK 45 +#define GCC_BLSP1_QUP6_I2C_APPS_CLK 46 +#define GCC_BLSP1_QUP6_SPI_APPS_CLK 47 +#define GCC_BLSP1_UART1_APPS_CLK 48 +#define GCC_BLSP1_UART2_APPS_CLK 49 +#define GCC_BOOT_ROM_AHB_CLK 50 +#define GCC_CRYPTO_AHB_CLK 51 +#define GCC_CRYPTO_AXI_CLK 52 +#define GCC_CRYPTO_CLK 53 +#define GCC_GP1_CLK 54 +#define GCC_GP2_CLK 55 +#define GCC_GP3_CLK 56 +#define GCC_MSS_CFG_AHB_CLK 57 +#define GCC_PDM2_CLK 58 +#define GCC_PDM_AHB_CLK 59 +#define GCC_PRNG_AHB_CLK 60 +#define GCC_SDCC1_AHB_CLK 61 +#define GCC_SDCC1_APPS_CLK 62 +#define GCC_SDCC2_AHB_CLK 63 +#define GCC_SDCC2_APPS_CLK 64 +#define GCC_USB2A_PHY_SLEEP_CLK 65 +#define GCC_USB_HS_AHB_CLK 66 +#define GCC_USB_HS_SYSTEM_CLK 67 +#define GCC_APSS_TCU_CLK 68 +#define GCC_MSS_Q6_BIMC_AXI_CLK 69 +#define BIMC_PLL 70 +#define BIMC_PLL_VOTE 71 +#define BIMC_DDR_CLK_SRC 72 +#define BLSP1_UART3_APPS_CLK_SRC 73 +#define BLSP1_UART4_APPS_CLK_SRC 74 +#define BLSP1_UART5_APPS_CLK_SRC 75 +#define BLSP1_UART6_APPS_CLK_SRC 76 +#define GCC_BLSP1_UART3_APPS_CLK 77 +#define GCC_BLSP1_UART4_APPS_CLK 78 +#define GCC_BLSP1_UART5_APPS_CLK 79 +#define GCC_BLSP1_UART6_APPS_CLK 80 +#define GCC_APSS_AHB_CLK 81 +#define GCC_APSS_AXI_CLK 82 +#define GCC_USB_HS_PHY_CFG_AHB_CLK 83 +#define GCC_USB_HSIC_CLK_SRC 84 +#define GCC_USB_HSIC_IO_CAL_CLK_SRC 85 +#define GCC_USB_HSIC_SYSTEM_CLK_SRC 86 + +/* Resets */ +#define USB2_HS_PHY_ONLY_BCR 0 +#define QUSB2_PHY_BCR 1 +#define GCC_MSS_RESTART 2 +#define USB_HS_HSIC_BCR 3 +#define USB_HS_BCR 4 + +#endif diff --git a/include/dt-bindings/clock/qcom,gcc-sm6125.h b/include/dt-bindings/clock/qcom,gcc-sm6125.h new file mode 100644 index 000000000000..08ea18086824 --- /dev/null +++ b/include/dt-bindings/clock/qcom,gcc-sm6125.h @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SM6125_H +#define _DT_BINDINGS_CLK_QCOM_GCC_SM6125_H + +#define GPLL0_OUT_AUX2 0 +#define GPLL0_OUT_MAIN 1 +#define GPLL6_OUT_MAIN 2 +#define GPLL7_OUT_MAIN 3 +#define GPLL8_OUT_MAIN 4 +#define GPLL9_OUT_MAIN 5 +#define GPLL0_OUT_EARLY 6 +#define GPLL3_OUT_EARLY 7 +#define GPLL4_OUT_MAIN 8 +#define GPLL5_OUT_MAIN 9 +#define GPLL6_OUT_EARLY 10 +#define GPLL7_OUT_EARLY 11 +#define GPLL8_OUT_EARLY 12 +#define GPLL9_OUT_EARLY 13 +#define GCC_AHB2PHY_CSI_CLK 14 +#define GCC_AHB2PHY_USB_CLK 15 +#define GCC_APC_VS_CLK 16 +#define GCC_BOOT_ROM_AHB_CLK 17 +#define GCC_CAMERA_AHB_CLK 18 +#define GCC_CAMERA_XO_CLK 19 +#define GCC_CAMSS_AHB_CLK_SRC 20 +#define GCC_CAMSS_CCI_AHB_CLK 21 +#define GCC_CAMSS_CCI_CLK 22 +#define GCC_CAMSS_CCI_CLK_SRC 23 +#define GCC_CAMSS_CPHY_CSID0_CLK 24 +#define GCC_CAMSS_CPHY_CSID1_CLK 25 +#define GCC_CAMSS_CPHY_CSID2_CLK 26 +#define GCC_CAMSS_CPHY_CSID3_CLK 27 +#define GCC_CAMSS_CPP_AHB_CLK 28 +#define GCC_CAMSS_CPP_AXI_CLK 29 +#define GCC_CAMSS_CPP_CLK 30 +#define GCC_CAMSS_CPP_CLK_SRC 31 +#define GCC_CAMSS_CPP_VBIF_AHB_CLK 32 +#define GCC_CAMSS_CSI0_AHB_CLK 33 +#define GCC_CAMSS_CSI0_CLK 34 +#define GCC_CAMSS_CSI0_CLK_SRC 35 +#define GCC_CAMSS_CSI0PHYTIMER_CLK 36 +#define GCC_CAMSS_CSI0PHYTIMER_CLK_SRC 37 +#define GCC_CAMSS_CSI0PIX_CLK 38 +#define GCC_CAMSS_CSI0RDI_CLK 39 +#define GCC_CAMSS_CSI1_AHB_CLK 40 +#define GCC_CAMSS_CSI1_CLK 41 +#define GCC_CAMSS_CSI1_CLK_SRC 42 +#define GCC_CAMSS_CSI1PHYTIMER_CLK 43 +#define GCC_CAMSS_CSI1PHYTIMER_CLK_SRC 44 +#define GCC_CAMSS_CSI1PIX_CLK 45 +#define GCC_CAMSS_CSI1RDI_CLK 46 +#define GCC_CAMSS_CSI2_AHB_CLK 47 +#define GCC_CAMSS_CSI2_CLK 48 +#define GCC_CAMSS_CSI2_CLK_SRC 49 +#define GCC_CAMSS_CSI2PHYTIMER_CLK 50 +#define GCC_CAMSS_CSI2PHYTIMER_CLK_SRC 51 +#define GCC_CAMSS_CSI2PIX_CLK 52 +#define GCC_CAMSS_CSI2RDI_CLK 53 +#define GCC_CAMSS_CSI3_AHB_CLK 54 +#define GCC_CAMSS_CSI3_CLK 55 +#define GCC_CAMSS_CSI3_CLK_SRC 56 +#define GCC_CAMSS_CSI3PIX_CLK 57 +#define GCC_CAMSS_CSI3RDI_CLK 58 +#define GCC_CAMSS_CSI_VFE0_CLK 59 +#define GCC_CAMSS_CSI_VFE1_CLK 60 +#define GCC_CAMSS_CSIPHY0_CLK 61 +#define GCC_CAMSS_CSIPHY1_CLK 62 +#define GCC_CAMSS_CSIPHY2_CLK 63 +#define GCC_CAMSS_CSIPHY_CLK_SRC 64 +#define GCC_CAMSS_GP0_CLK 65 +#define GCC_CAMSS_GP0_CLK_SRC 66 +#define GCC_CAMSS_GP1_CLK 67 +#define GCC_CAMSS_GP1_CLK_SRC 68 +#define GCC_CAMSS_ISPIF_AHB_CLK 69 +#define GCC_CAMSS_JPEG_AHB_CLK 70 +#define GCC_CAMSS_JPEG_AXI_CLK 71 +#define GCC_CAMSS_JPEG_CLK 72 +#define GCC_CAMSS_JPEG_CLK_SRC 73 +#define GCC_CAMSS_MCLK0_CLK 74 +#define GCC_CAMSS_MCLK0_CLK_SRC 75 +#define GCC_CAMSS_MCLK1_CLK 76 +#define GCC_CAMSS_MCLK1_CLK_SRC 77 +#define GCC_CAMSS_MCLK2_CLK 78 +#define GCC_CAMSS_MCLK2_CLK_SRC 79 +#define GCC_CAMSS_MCLK3_CLK 80 +#define GCC_CAMSS_MCLK3_CLK_SRC 81 +#define GCC_CAMSS_MICRO_AHB_CLK 82 +#define GCC_CAMSS_THROTTLE_NRT_AXI_CLK 83 +#define GCC_CAMSS_THROTTLE_RT_AXI_CLK 84 +#define GCC_CAMSS_TOP_AHB_CLK 85 +#define GCC_CAMSS_VFE0_AHB_CLK 86 +#define GCC_CAMSS_VFE0_CLK 87 +#define GCC_CAMSS_VFE0_CLK_SRC 88 +#define GCC_CAMSS_VFE0_STREAM_CLK 89 +#define GCC_CAMSS_VFE1_AHB_CLK 90 +#define GCC_CAMSS_VFE1_CLK 91 +#define GCC_CAMSS_VFE1_CLK_SRC 92 +#define GCC_CAMSS_VFE1_STREAM_CLK 93 +#define GCC_CAMSS_VFE_TSCTR_CLK 94 +#define GCC_CAMSS_VFE_VBIF_AHB_CLK 95 +#define GCC_CAMSS_VFE_VBIF_AXI_CLK 96 +#define GCC_CE1_AHB_CLK 97 +#define GCC_CE1_AXI_CLK 98 +#define GCC_CE1_CLK 99 +#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 100 +#define GCC_CPUSS_GNOC_CLK 101 +#define GCC_DISP_AHB_CLK 102 +#define GCC_DISP_GPLL0_DIV_CLK_SRC 103 +#define GCC_DISP_HF_AXI_CLK 104 +#define GCC_DISP_THROTTLE_CORE_CLK 105 +#define GCC_DISP_XO_CLK 106 +#define GCC_GP1_CLK 107 +#define GCC_GP1_CLK_SRC 108 +#define GCC_GP2_CLK 109 +#define GCC_GP2_CLK_SRC 110 +#define GCC_GP3_CLK 111 +#define GCC_GP3_CLK_SRC 112 +#define GCC_GPU_CFG_AHB_CLK 113 +#define GCC_GPU_GPLL0_CLK_SRC 114 +#define GCC_GPU_GPLL0_DIV_CLK_SRC 115 +#define GCC_GPU_MEMNOC_GFX_CLK 116 +#define GCC_GPU_SNOC_DVM_GFX_CLK 117 +#define GCC_GPU_THROTTLE_CORE_CLK 118 +#define GCC_GPU_THROTTLE_XO_CLK 119 +#define GCC_MSS_VS_CLK 120 +#define GCC_PDM2_CLK 121 +#define GCC_PDM2_CLK_SRC 122 +#define GCC_PDM_AHB_CLK 123 +#define GCC_PDM_XO4_CLK 124 +#define GCC_PRNG_AHB_CLK 125 +#define GCC_QMIP_CAMERA_NRT_AHB_CLK 126 +#define GCC_QMIP_CAMERA_RT_AHB_CLK 127 +#define GCC_QMIP_DISP_AHB_CLK 128 +#define GCC_QMIP_GPU_CFG_AHB_CLK 129 +#define GCC_QMIP_VIDEO_VCODEC_AHB_CLK 130 +#define GCC_QUPV3_WRAP0_CORE_2X_CLK 131 +#define GCC_QUPV3_WRAP0_CORE_CLK 132 +#define GCC_QUPV3_WRAP0_S0_CLK 133 +#define GCC_QUPV3_WRAP0_S0_CLK_SRC 134 +#define GCC_QUPV3_WRAP0_S1_CLK 135 +#define GCC_QUPV3_WRAP0_S1_CLK_SRC 136 +#define GCC_QUPV3_WRAP0_S2_CLK 137 +#define GCC_QUPV3_WRAP0_S2_CLK_SRC 138 +#define GCC_QUPV3_WRAP0_S3_CLK 139 +#define GCC_QUPV3_WRAP0_S3_CLK_SRC 140 +#define GCC_QUPV3_WRAP0_S4_CLK 141 +#define GCC_QUPV3_WRAP0_S4_CLK_SRC 142 +#define GCC_QUPV3_WRAP0_S5_CLK 143 +#define GCC_QUPV3_WRAP0_S5_CLK_SRC 144 +#define GCC_QUPV3_WRAP1_CORE_2X_CLK 145 +#define GCC_QUPV3_WRAP1_CORE_CLK 146 +#define GCC_QUPV3_WRAP1_S0_CLK 147 +#define GCC_QUPV3_WRAP1_S0_CLK_SRC 148 +#define GCC_QUPV3_WRAP1_S1_CLK 149 +#define GCC_QUPV3_WRAP1_S1_CLK_SRC 150 +#define GCC_QUPV3_WRAP1_S2_CLK 151 +#define GCC_QUPV3_WRAP1_S2_CLK_SRC 152 +#define GCC_QUPV3_WRAP1_S3_CLK 153 +#define GCC_QUPV3_WRAP1_S3_CLK_SRC 154 +#define GCC_QUPV3_WRAP1_S4_CLK 155 +#define GCC_QUPV3_WRAP1_S4_CLK_SRC 156 +#define GCC_QUPV3_WRAP1_S5_CLK 157 +#define GCC_QUPV3_WRAP1_S5_CLK_SRC 158 +#define GCC_QUPV3_WRAP_0_M_AHB_CLK 159 +#define GCC_QUPV3_WRAP_0_S_AHB_CLK 160 +#define GCC_QUPV3_WRAP_1_M_AHB_CLK 161 +#define GCC_QUPV3_WRAP_1_S_AHB_CLK 162 +#define GCC_SDCC1_AHB_CLK 163 +#define GCC_SDCC1_APPS_CLK 164 +#define GCC_SDCC1_APPS_CLK_SRC 165 +#define GCC_SDCC1_ICE_CORE_CLK 166 +#define GCC_SDCC1_ICE_CORE_CLK_SRC 167 +#define GCC_SDCC2_AHB_CLK 168 +#define GCC_SDCC2_APPS_CLK 169 +#define GCC_SDCC2_APPS_CLK_SRC 170 +#define GCC_SYS_NOC_CPUSS_AHB_CLK 171 +#define GCC_SYS_NOC_UFS_PHY_AXI_CLK 172 +#define GCC_SYS_NOC_USB3_PRIM_AXI_CLK 173 +#define GCC_UFS_PHY_AHB_CLK 174 +#define GCC_UFS_PHY_AXI_CLK 175 +#define GCC_UFS_PHY_AXI_CLK_SRC 176 +#define GCC_UFS_PHY_ICE_CORE_CLK 177 +#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 178 +#define GCC_UFS_PHY_PHY_AUX_CLK 179 +#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 180 +#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 181 +#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 182 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK 183 +#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 184 +#define GCC_USB30_PRIM_MASTER_CLK 185 +#define GCC_USB30_PRIM_MASTER_CLK_SRC 186 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK 187 +#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 188 +#define GCC_USB30_PRIM_SLEEP_CLK 189 +#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 190 +#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 191 +#define GCC_USB3_PRIM_PHY_PIPE_CLK 192 +#define GCC_VDDA_VS_CLK 193 +#define GCC_VDDCX_VS_CLK 194 +#define GCC_VDDMX_VS_CLK 195 +#define GCC_VIDEO_AHB_CLK 196 +#define GCC_VIDEO_AXI0_CLK 197 +#define GCC_VIDEO_THROTTLE_CORE_CLK 198 +#define GCC_VIDEO_XO_CLK 199 +#define GCC_VS_CTRL_AHB_CLK 200 +#define GCC_VS_CTRL_CLK 201 +#define GCC_VS_CTRL_CLK_SRC 202 +#define GCC_VSENSOR_CLK_SRC 203 +#define GCC_WCSS_VS_CLK 204 +#define GCC_USB3_PRIM_CLKREF_CLK 205 +#define GCC_SYS_NOC_COMPUTE_SF_AXI_CLK 206 +#define GCC_BIMC_GPU_AXI_CLK 207 +#define GCC_UFS_MEM_CLKREF_CLK 208 + +/* GDSCs */ +#define USB30_PRIM_GDSC 0 +#define UFS_PHY_GDSC 1 +#define CAMSS_VFE0_GDSC 2 +#define CAMSS_VFE1_GDSC 3 +#define CAMSS_TOP_GDSC 4 +#define CAM_CPP_GDSC 5 +#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC 6 +#define HLOS1_VOTE_MM_SNOC_MMU_TBU_RT_GDSC 7 +#define HLOS1_VOTE_MM_SNOC_MMU_TBU_NRT_GDSC 8 +#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC 9 + +#define GCC_QUSB2PHY_PRIM_BCR 0 +#define GCC_QUSB2PHY_SEC_BCR 1 +#define GCC_UFS_PHY_BCR 2 +#define GCC_USB30_PRIM_BCR 3 +#define GCC_USB_PHY_CFG_AHB2PHY_BCR 4 +#define GCC_USB3_PHY_PRIM_SP0_BCR 5 +#define GCC_USB3PHY_PHY_PRIM_SP0_BCR 6 +#define GCC_CAMSS_MICRO_BCR 7 + +#endif diff --git a/include/dt-bindings/clock/r9a07g044-cpg.h b/include/dt-bindings/clock/r9a07g044-cpg.h new file mode 100644 index 000000000000..1d8986563fc5 --- /dev/null +++ b/include/dt-bindings/clock/r9a07g044-cpg.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) + * + * Copyright (C) 2021 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__ +#define __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* R9A07G044 CPG Core Clocks */ +#define R9A07G044_CLK_I 0 +#define R9A07G044_CLK_I2 1 +#define R9A07G044_CLK_G 2 +#define R9A07G044_CLK_S0 3 +#define R9A07G044_CLK_S1 4 +#define R9A07G044_CLK_SPI0 5 +#define R9A07G044_CLK_SPI1 6 +#define R9A07G044_CLK_SD0 7 +#define R9A07G044_CLK_SD1 8 +#define R9A07G044_CLK_M0 9 +#define R9A07G044_CLK_M1 10 +#define R9A07G044_CLK_M2 11 +#define R9A07G044_CLK_M3 12 +#define R9A07G044_CLK_M4 13 +#define R9A07G044_CLK_HP 14 +#define R9A07G044_CLK_TSU 15 +#define R9A07G044_CLK_ZT 16 +#define R9A07G044_CLK_P0 17 +#define R9A07G044_CLK_P1 18 +#define R9A07G044_CLK_P2 19 +#define R9A07G044_CLK_AT 20 +#define R9A07G044_OSCCLK 21 + +/* R9A07G044 Module Clocks */ +#define R9A07G044_CLK_GIC600 0 +#define R9A07G044_CLK_IA55 1 +#define R9A07G044_CLK_SYC 2 +#define R9A07G044_CLK_DMAC 3 +#define R9A07G044_CLK_SYSC 4 +#define R9A07G044_CLK_MTU 5 +#define R9A07G044_CLK_GPT 6 +#define R9A07G044_CLK_ETH0 7 +#define R9A07G044_CLK_ETH1 8 +#define R9A07G044_CLK_I2C0 9 +#define R9A07G044_CLK_I2C1 10 +#define R9A07G044_CLK_I2C2 11 +#define R9A07G044_CLK_I2C3 12 +#define R9A07G044_CLK_SCIF0 13 +#define R9A07G044_CLK_SCIF1 14 +#define R9A07G044_CLK_SCIF2 15 +#define R9A07G044_CLK_SCIF3 16 +#define R9A07G044_CLK_SCIF4 17 +#define R9A07G044_CLK_SCI0 18 +#define R9A07G044_CLK_SCI1 19 +#define R9A07G044_CLK_GPIO 20 +#define R9A07G044_CLK_SDHI0 21 +#define R9A07G044_CLK_SDHI1 22 +#define R9A07G044_CLK_USB0 23 +#define R9A07G044_CLK_USB1 24 +#define R9A07G044_CLK_CANFD 25 +#define R9A07G044_CLK_SSI0 26 +#define R9A07G044_CLK_SSI1 27 +#define R9A07G044_CLK_SSI2 28 +#define R9A07G044_CLK_SSI3 29 +#define R9A07G044_CLK_MHU 30 +#define R9A07G044_CLK_OSTM0 31 +#define R9A07G044_CLK_OSTM1 32 +#define R9A07G044_CLK_OSTM2 33 +#define R9A07G044_CLK_WDT0 34 +#define R9A07G044_CLK_WDT1 35 +#define R9A07G044_CLK_WDT2 36 +#define R9A07G044_CLK_WDT_PON 37 +#define R9A07G044_CLK_GPU 38 +#define R9A07G044_CLK_ISU 39 +#define R9A07G044_CLK_H264 40 +#define R9A07G044_CLK_CRU 41 +#define R9A07G044_CLK_MIPI_DSI 42 +#define R9A07G044_CLK_LCDC 43 +#define R9A07G044_CLK_SRC 44 +#define R9A07G044_CLK_RSPI0 45 +#define R9A07G044_CLK_RSPI1 46 +#define R9A07G044_CLK_RSPI2 47 +#define R9A07G044_CLK_ADC 48 +#define R9A07G044_CLK_TSU_PCLK 49 +#define R9A07G044_CLK_SPI 50 +#define R9A07G044_CLK_MIPI_DSI_V 51 +#define R9A07G044_CLK_MIPI_DSI_PIN 52 + +#endif /* __DT_BINDINGS_CLOCK_R9A07G044_CPG_H__ */ diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h index 4cdaf135829c..e02770b98e6c 100644 --- a/include/dt-bindings/clock/stm32mp1-clks.h +++ b/include/dt-bindings/clock/stm32mp1-clks.h @@ -248,4 +248,31 @@ #define STM32MP1_LAST_CLK 232 +/* SCMI clock identifiers */ +#define CK_SCMI0_HSE 0 +#define CK_SCMI0_HSI 1 +#define CK_SCMI0_CSI 2 +#define CK_SCMI0_LSE 3 +#define CK_SCMI0_LSI 4 +#define CK_SCMI0_PLL2_Q 5 +#define CK_SCMI0_PLL2_R 6 +#define CK_SCMI0_MPU 7 +#define CK_SCMI0_AXI 8 +#define CK_SCMI0_BSEC 9 +#define CK_SCMI0_CRYP1 10 +#define CK_SCMI0_GPIOZ 11 +#define CK_SCMI0_HASH1 12 +#define CK_SCMI0_I2C4 13 +#define CK_SCMI0_I2C6 14 +#define CK_SCMI0_IWDG1 15 +#define CK_SCMI0_RNG1 16 +#define CK_SCMI0_RTC 17 +#define CK_SCMI0_RTCAPB 18 +#define CK_SCMI0_SPI6 19 +#define CK_SCMI0_USART1 20 + +#define CK_SCMI1_PLL3_Q 0 +#define CK_SCMI1_PLL3_R 1 +#define CK_SCMI1_MCU 2 + #endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */ diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h index f0c3aaef67a0..f3a0ed317835 100644 --- a/include/dt-bindings/reset/stm32mp1-resets.h +++ b/include/dt-bindings/reset/stm32mp1-resets.h @@ -7,6 +7,7 @@ #ifndef _DT_BINDINGS_STM32MP1_RESET_H_ #define _DT_BINDINGS_STM32MP1_RESET_H_ +#define MCU_HOLD_BOOT_R 2144 #define LTDC_R 3072 #define DSI_R 3076 #define DDRPERFM_R 3080 @@ -105,4 +106,18 @@ #define GPIOJ_R 19785 #define GPIOK_R 19786 +/* SCMI reset domain identifiers */ +#define RST_SCMI0_SPI6 0 +#define RST_SCMI0_I2C4 1 +#define RST_SCMI0_I2C6 2 +#define RST_SCMI0_USART1 3 +#define RST_SCMI0_STGEN 4 +#define RST_SCMI0_GPIOZ 5 +#define RST_SCMI0_CRYP1 6 +#define RST_SCMI0_HASH1 7 +#define RST_SCMI0_RNG1 8 +#define RST_SCMI0_MDMA 9 +#define RST_SCMI0_MCU 10 +#define RST_SCMI0_MCU_HOLD_BOOT 11 + #endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */ diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index f7ff722a03dd..d128ad1570aa 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h @@ -123,20 +123,6 @@ static inline void tegra_cpu_clock_resume(void) } #endif -extern int tegra210_plle_hw_sequence_start(void); -extern bool tegra210_plle_hw_sequence_is_enabled(void); -extern void tegra210_xusb_pll_hw_control_enable(void); -extern void tegra210_xusb_pll_hw_sequence_start(void); -extern void tegra210_sata_pll_hw_control_enable(void); -extern void tegra210_sata_pll_hw_sequence_start(void); -extern void tegra210_set_sata_pll_seq_sw(bool state); -extern void tegra210_put_utmipll_in_iddq(void); -extern void tegra210_put_utmipll_out_iddq(void); -extern int tegra210_clk_handle_mbist_war(unsigned int id); -extern void tegra210_clk_emc_dll_enable(bool flag); -extern void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value); -extern void tegra210_clk_emc_update_setting(u32 emc_src_value); - struct clk; struct tegra_emc; @@ -144,17 +130,10 @@ typedef long (tegra20_clk_emc_round_cb)(unsigned long rate, unsigned long min_rate, unsigned long max_rate, void *arg); - -void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, - void *cb_arg); -int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same); - typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc, unsigned long rate); typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc, unsigned long rate); -void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb, - tegra124_emc_complete_timing_change_cb *complete_cb); struct tegra210_clk_emc_config { unsigned long rate; @@ -176,8 +155,87 @@ struct tegra210_clk_emc_provider { const struct tegra210_clk_emc_config *config); }; +#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC) +void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, + void *cb_arg); +int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same); +#else +static inline void +tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb, + void *cb_arg) +{ +} + +static inline int +tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same) +{ + return 0; +} +#endif + +#ifdef CONFIG_TEGRA124_CLK_EMC +void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb, + tegra124_emc_complete_timing_change_cb *complete_cb); +#else +static inline void +tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb, + tegra124_emc_complete_timing_change_cb *complete_cb) +{ +} +#endif + +#ifdef CONFIG_ARCH_TEGRA_210_SOC +int tegra210_plle_hw_sequence_start(void); +bool tegra210_plle_hw_sequence_is_enabled(void); +void tegra210_xusb_pll_hw_control_enable(void); +void tegra210_xusb_pll_hw_sequence_start(void); +void tegra210_sata_pll_hw_control_enable(void); +void tegra210_sata_pll_hw_sequence_start(void); +void tegra210_set_sata_pll_seq_sw(bool state); +void tegra210_put_utmipll_in_iddq(void); +void tegra210_put_utmipll_out_iddq(void); +int tegra210_clk_handle_mbist_war(unsigned int id); +void tegra210_clk_emc_dll_enable(bool flag); +void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value); +void tegra210_clk_emc_update_setting(u32 emc_src_value); + int tegra210_clk_emc_attach(struct clk *clk, struct tegra210_clk_emc_provider *provider); void tegra210_clk_emc_detach(struct clk *clk); +#else +static inline int tegra210_plle_hw_sequence_start(void) +{ + return 0; +} + +static inline bool tegra210_plle_hw_sequence_is_enabled(void) +{ + return false; +} + +static inline int tegra210_clk_handle_mbist_war(unsigned int id) +{ + return 0; +} + +static inline int +tegra210_clk_emc_attach(struct clk *clk, + struct tegra210_clk_emc_provider *provider) +{ + return 0; +} + +static inline void tegra210_xusb_pll_hw_control_enable(void) {} +static inline void tegra210_xusb_pll_hw_sequence_start(void) {} +static inline void tegra210_sata_pll_hw_control_enable(void) {} +static inline void tegra210_sata_pll_hw_sequence_start(void) {} +static inline void tegra210_set_sata_pll_seq_sw(bool state) {} +static inline void tegra210_put_utmipll_in_iddq(void) {} +static inline void tegra210_put_utmipll_out_iddq(void) {} +static inline void tegra210_clk_emc_dll_enable(bool flag) {} +static inline void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value) {} +static inline void tegra210_clk_emc_update_setting(u32 emc_src_value) {} +static inline void tegra210_clk_emc_detach(struct clk *clk) {} +#endif #endif /* __LINUX_CLK_TEGRA_H_ */ diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index c62f6fa6763d..3486f20a3753 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -63,6 +63,17 @@ struct clk_omap_reg { * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs + * @ssc_deltam_reg: register containing the DPLL SSC frequency spreading + * @ssc_modfreq_reg: register containing the DPLL SSC modulation frequency + * @ssc_modfreq_mant_mask: mask of the mantissa component in @ssc_modfreq_reg + * @ssc_modfreq_exp_mask: mask of the exponent component in @ssc_modfreq_reg + * @ssc_enable_mask: mask of the DPLL SSC enable bit in @control_reg + * @ssc_downspread_mask: mask of the DPLL SSC low frequency only bit in + * @control_reg + * @ssc_modfreq: the DPLL SSC frequency modulation in kHz + * @ssc_deltam: the DPLL SSC frequency spreading in permille (10th of percent) + * @ssc_downspread: require the only low frequency spread of the DPLL in SSC + * mode * @flags: DPLL type/features (see below) * * Possible values for @flags: @@ -110,6 +121,17 @@ struct dpll_data { u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; + struct clk_omap_reg ssc_deltam_reg; + struct clk_omap_reg ssc_modfreq_reg; + u32 ssc_deltam_int_mask; + u32 ssc_deltam_frac_mask; + u32 ssc_modfreq_mant_mask; + u32 ssc_modfreq_exp_mask; + u32 ssc_enable_mask; + u32 ssc_downspread_mask; + u32 ssc_modfreq; + u32 ssc_deltam; + bool ssc_downspread; u8 flags; }; diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h index fd06b2780a22..8a8423eb8e9a 100644 --- a/include/linux/clkdev.h +++ b/include/linux/clkdev.h @@ -30,11 +30,6 @@ struct clk_lookup { .clk = c, \ } -struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, - const char *dev_fmt, ...) __printf(3, 4); -struct clk_lookup *clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, - const char *dev_fmt, ...) __printf(3, 4); - void clkdev_add(struct clk_lookup *cl); void clkdev_drop(struct clk_lookup *cl); diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig index 0cd1a15f40aa..71a58f7ac13a 100644 --- a/sound/soc/dwc/Kconfig +++ b/sound/soc/dwc/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only config SND_DESIGNWARE_I2S tristate "Synopsys I2S Device Driver" - depends on CLKDEV_LOOKUP + depends on HAVE_CLK select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for I2S driver for diff --git a/sound/soc/rockchip/Kconfig b/sound/soc/rockchip/Kconfig index d610b553ea3b..053097b73e28 100644 --- a/sound/soc/rockchip/Kconfig +++ b/sound/soc/rockchip/Kconfig @@ -9,7 +9,7 @@ config SND_SOC_ROCKCHIP config SND_SOC_ROCKCHIP_I2S tristate "Rockchip I2S Device Driver" - depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + depends on HAVE_CLK && SND_SOC_ROCKCHIP select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for I2S driver for @@ -18,7 +18,7 @@ config SND_SOC_ROCKCHIP_I2S config SND_SOC_ROCKCHIP_PDM tristate "Rockchip PDM Controller Driver" - depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + depends on HAVE_CLK && SND_SOC_ROCKCHIP select SND_SOC_GENERIC_DMAENGINE_PCM select RATIONAL help @@ -28,7 +28,7 @@ config SND_SOC_ROCKCHIP_PDM config SND_SOC_ROCKCHIP_SPDIF tristate "Rockchip SPDIF Device Driver" - depends on CLKDEV_LOOKUP && SND_SOC_ROCKCHIP + depends on HAVE_CLK && SND_SOC_ROCKCHIP select SND_SOC_GENERIC_DMAENGINE_PCM help Say Y or M if you want to add support for SPDIF driver for @@ -36,7 +36,7 @@ config SND_SOC_ROCKCHIP_SPDIF config SND_SOC_ROCKCHIP_MAX98090 tristate "ASoC support for Rockchip boards using a MAX98090 codec" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP + depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK select SND_SOC_ROCKCHIP_I2S select SND_SOC_MAX98090 select SND_SOC_TS3A227E @@ -47,7 +47,7 @@ config SND_SOC_ROCKCHIP_MAX98090 config SND_SOC_ROCKCHIP_RT5645 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP + depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK select SND_SOC_ROCKCHIP_I2S select SND_SOC_RT5645 help @@ -56,7 +56,7 @@ config SND_SOC_ROCKCHIP_RT5645 config SND_SOC_RK3288_HDMI_ANALOG tristate "ASoC support multiple codecs for Rockchip RK3288 boards" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP + depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK select SND_SOC_ROCKCHIP_I2S select SND_SOC_HDMI_CODEC select SND_SOC_ES8328_I2C @@ -68,7 +68,7 @@ config SND_SOC_RK3288_HDMI_ANALOG config SND_SOC_RK3399_GRU_SOUND tristate "ASoC support multiple codecs for Rockchip RK3399 GRU boards" - depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP && SPI + depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && HAVE_CLK && SPI select SND_SOC_ROCKCHIP_I2S select SND_SOC_MAX98357A select SND_SOC_RT5514 |