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

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

Pull clk updates from Stephen Boyd:
"The new and exciting feature this time around is in the clk core.
We've added duty cycle support to the clk API so that clk signal duty
cycle ratios can be adjusted while taking into account things like clk
dividers and clk tree hierarchy. So far only one SoC has implemented
support for this, but I expect there will be more to come in the
future.

Outside of the core, we have the usual pile of clk driver updates and
additions. The Amlogic meson driver got the most lines in the diffstat
this time around because it added support for a whole bunch of
hardware and duty cycle configuration. After that the Rockchip PX30,
Qualcomm SDM845, and Renesas SoC drivers fill in a majority of the
diff. We're left with the collection of non-critical fixes after that.
Overall it looks pretty quiet this time.

Core:
- Clk duty cycle support
- Proper CLK_SET_RATE_GATE support throughout the tree

New Drivers:
- Actions Semi Owl series S700 SoC clk driver
- Qualcomm SDM845 display clock controller
- i.MX6SX ocram_s clk support
- Uniphier NAND, USB3 PHY, and SPI clk support
- Qualcomm RPMh clk driver
- i.MX7D mailbox clk support
- Maxim 9485 Programmable Clock Generator
- expose 32 kHz PLL on PXA SoCs
- imx6sll GPIO clk gate support
- Atmel at91 I2S audio clk support
- SI544/SI514 clk on/off support
- i.MX6UL GPIO clock gates in CCM CCGR
- Renesas Crypto Engine clocks on R-Car H3
- Renesas clk support for the new RZ/N1D SoC
- Allwinner A64 display engine clock support
- support for Rockchip's PX30 SoC
- Amlogic Meson axg PCIe and audio clocks
- Amlogic Meson GEN CLK on gxbb, gxl and axg

Updates:
- remove an unused variable from Exynos4412 ISP driver
- fix a thinko bug in SCMI clk division logic
- add missing of_node_put()s in some i.MX clk drivers
- Tegra SDMMC clk jitter improvements with high speed signaling modes
- SPDX tagging for qcom and cs2000-cp drivers
- stop leaking con ids in __clk_put()
- fix a corner case in fixed factor clk probing where node is in DT
but parent clk is registered much later
- Marvell Armada 3700 clk_pm_cpu_get_parent() had an invalid return
value
- i.MX clk init arrays removed in place of CLK_IS_CRITICAL
- convert to CLK_IS_CRITICAL for i.MX51/53 driver
- fix Tegra BPMP driver oops when xlating a NULL clk
- proper default configuration for vic03 and vde clks on Tegra124
- mark Tegra memory controller clks as critical
- fix array bounds clamp in Tegra's emc determine_rate() op
- Ingenic i2s bit update and allow UDC clk to gate
- fix name of aspeed SDC clk define to have only one 'CLK'
- fix i.MX6QDL video clk parent
- critical clk markings for qcom SDM845
- fix Stratix10 mpu_free_clk and sdmmc_free_clk parents
- mark Rockchip's pclk_rkpwm_pmu as critical clock, due to it
supplying the pwm used to drive the logic supply of the rk3399
core"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (85 commits)
clk: rockchip: Add pclk_rkpwm_pmu to PMU critical clocks in rk3399
clk: cs2000-cp: convert to SPDX identifiers
clk: scmi: Fix the rounding of clock rate
clk: qcom: Add display clock controller driver for SDM845
clk: mvebu: armada-37xx-periph: Remove unused var num_parents
clk: samsung: Remove unused mout_user_aclk400_mcuisp_p4x12 variable
clk: actions: Add S700 SoC clock support
dt-bindings: clock: Add S700 support for Actions Semi Soc's
clk: actions: Add missing REGMAP_MMIO dependency
clk: uniphier: add clock frequency support for SPI
clk: uniphier: add more USB3 PHY clocks
clk: uniphier: add NAND 200MHz clock
clk: tegra: make sdmmc2 and sdmmc4 as sdmmc clocks
clk: tegra: Add sdmmc mux divider clock
clk: tegra: Refactor fractional divider calculation
clk: tegra: Fix includes required by fence_udelay()
clk: imx6sll: fix missing of_node_put()
clk: imx6ul: fix missing of_node_put()
clk: imx: add ocram_s clock for i.mx6sx
clk: mvebu: armada-37xx-periph: Fix wrong return value in get_parent
...

+7980 -582
+11 -9
Documentation/devicetree/bindings/clock/actions,s900-cmu.txt Documentation/devicetree/bindings/clock/actions,owl-cmu.txt
··· 1 - * Actions S900 Clock Management Unit (CMU) 1 + * Actions Semi Owl Clock Management Unit (CMU) 2 2 3 - The Actions S900 clock management unit generates and supplies clock to various 4 - controllers within the SoC. The clock binding described here is applicable to 5 - S900 SoC. 3 + The Actions Semi Owl Clock Management Unit generates and supplies clock 4 + to various controllers within the SoC. The clock binding described here is 5 + applicable to S900 and S700 SoC's. 6 6 7 7 Required Properties: 8 8 9 - - compatible: should be "actions,s900-cmu" 9 + - compatible: should be one of the following, 10 + "actions,s900-cmu" 11 + "actions,s700-cmu" 10 12 - reg: physical base address of the controller and length of memory mapped 11 13 region. 12 14 - clocks: Reference to the parent clocks ("hosc", "losc") ··· 17 15 Each clock is assigned an identifier, and client nodes can use this identifier 18 16 to specify the clock which they consume. 19 17 20 - All available clocks are defined as preprocessor macros in 21 - dt-bindings/clock/actions,s900-cmu.h header and can be used in device 22 - tree sources. 18 + All available clocks are defined as preprocessor macros in corresponding 19 + dt-bindings/clock/actions,s900-cmu.h or actions,s700-cmu.h header and can be 20 + used in device tree sources. 23 21 24 22 External clocks: 25 23 26 24 The hosc clock used as input for the plls is generated outside the SoC. It is 27 25 expected that it is defined using standard clock bindings as "hosc". 28 26 29 - Actions S900 CMU also requires one more clock: 27 + Actions Semi S900 CMU also requires one more clock: 30 28 - "losc" - internal low frequency oscillator 31 29 32 30 Example: Clock Management Unit node:
+56
Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
··· 1 + * Amlogic AXG Audio Clock Controllers 2 + 3 + The Amlogic AXG audio clock controller generates and supplies clock to the 4 + other elements of the audio subsystem, such as fifos, i2s, spdif and pdm 5 + devices. 6 + 7 + Required Properties: 8 + 9 + - compatible : should be "amlogic,axg-audio-clkc" for the A113X and A113D 10 + - reg : physical base address of the clock controller and length of 11 + memory mapped region. 12 + - clocks : a list of phandle + clock-specifier pairs for the clocks listed 13 + in clock-names. 14 + - clock-names : must contain the following: 15 + * "pclk" - Main peripheral bus clock 16 + may contain the following: 17 + * "mst_in[0-7]" - 8 input plls to generate clock signals 18 + * "slv_sclk[0-9]" - 10 slave bit clocks provided by external 19 + components. 20 + * "slv_lrclk[0-9]" - 10 slave sample clocks provided by external 21 + components. 22 + - resets : phandle of the internal reset line 23 + - #clock-cells : should be 1. 24 + 25 + Each clock is assigned an identifier and client nodes can use this identifier 26 + to specify the clock which they consume. All available clocks are defined as 27 + preprocessor macros in the dt-bindings/clock/axg-audio-clkc.h header and can be 28 + used in device tree sources. 29 + 30 + Example: 31 + 32 + clkc_audio: clock-controller@0 { 33 + compatible = "amlogic,axg-audio-clkc"; 34 + reg = <0x0 0x0 0x0 0xb4>; 35 + #clock-cells = <1>; 36 + 37 + clocks = <&clkc CLKID_AUDIO>, 38 + <&clkc CLKID_MPLL0>, 39 + <&clkc CLKID_MPLL1>, 40 + <&clkc CLKID_MPLL2>, 41 + <&clkc CLKID_MPLL3>, 42 + <&clkc CLKID_HIFI_PLL>, 43 + <&clkc CLKID_FCLK_DIV3>, 44 + <&clkc CLKID_FCLK_DIV4>, 45 + <&clkc CLKID_GP0_PLL>; 46 + clock-names = "pclk", 47 + "mst_in0", 48 + "mst_in1", 49 + "mst_in2", 50 + "mst_in3", 51 + "mst_in4", 52 + "mst_in5", 53 + "mst_in6", 54 + "mst_in7"; 55 + resets = <&reset RESET_AUDIO>; 56 + };
+35
Documentation/devicetree/bindings/clock/at91-clock.txt
··· 91 91 at91 audio pll output on AUDIOPLLCLK that feeds the PMC 92 92 and can be used by peripheral clock or generic clock 93 93 94 + "atmel,sama5d2-clk-i2s-mux" (under pmc node): 95 + at91 I2S clock source selection 96 + 94 97 Required properties for SCKC node: 95 98 - reg : defines the IO memory reserved for the SCKC. 96 99 - #size-cells : shall be 0 (reg is used to encode clk id). ··· 501 498 #clock-cells = <0>; 502 499 reg = <38>; 503 500 atmel,clk-output-range = <0 83000000>; 501 + }; 502 + }; 503 + 504 + Required properties for I2S mux clocks: 505 + - #size-cells : shall be 0 (reg is used to encode I2S bus id). 506 + - #address-cells : shall be 1 (reg is used to encode I2S bus id). 507 + - name: device tree node describing a specific mux clock. 508 + * #clock-cells : from common clock binding; shall be set to 0. 509 + * clocks : shall be the mux clock parent phandles; shall be 2 phandles: 510 + peripheral and generated clock; the first phandle shall belong to the 511 + peripheral clock and the second one shall belong to the generated 512 + clock; "clock-indices" property can be user to specify 513 + the correct order. 514 + * reg: I2S bus id of the corresponding mux clock. 515 + e.g. reg = <0>; for i2s0, reg = <1>; for i2s1 516 + 517 + For example: 518 + i2s_clkmux { 519 + compatible = "atmel,sama5d2-clk-i2s-mux"; 520 + #address-cells = <1>; 521 + #size-cells = <0>; 522 + 523 + i2s0muxck: i2s0_muxclk { 524 + clocks = <&i2s0_clk>, <&i2s0_gclk>; 525 + #clock-cells = <0>; 526 + reg = <0>; 527 + }; 528 + 529 + i2s1muxck: i2s1_muxclk { 530 + clocks = <&i2s1_clk>, <&i2s1_gclk>; 531 + #clock-cells = <0>; 532 + reg = <1>; 504 533 }; 505 534 };
+59
Documentation/devicetree/bindings/clock/maxim,max9485.txt
··· 1 + Devicetree bindings for Maxim MAX9485 Programmable Audio Clock Generator 2 + 3 + This device exposes 4 clocks in total: 4 + 5 + - MAX9485_MCLKOUT: A gated, buffered output of the input clock of 27 MHz 6 + - MAX9485_CLKOUT: A PLL that can be configured to 16 different discrete 7 + frequencies 8 + - MAX9485_CLKOUT[1,2]: Two gated outputs for MAX9485_CLKOUT 9 + 10 + MAX9485_CLKOUT[1,2] are children of MAX9485_CLKOUT which upchain all rate set 11 + requests. 12 + 13 + Required properties: 14 + - compatible: "maxim,max9485" 15 + - clocks: Input clock, must provice 27.000 MHz 16 + - clock-names: Must be set to "xclk" 17 + - #clock-cells: From common clock binding; shall be set to 1 18 + 19 + Optional properties: 20 + - reset-gpios: GPIO descriptor connected to the #RESET input pin 21 + - vdd-supply: A regulator node for Vdd 22 + - clock-output-names: Name of output clocks, as defined in common clock 23 + bindings 24 + 25 + If not explicitly set, the output names are "mclkout", "clkout", "clkout1" 26 + and "clkout2". 27 + 28 + Clocks are defined as preprocessor macros in the dt-binding header. 29 + 30 + Example: 31 + 32 + #include <dt-bindings/clock/maxim,max9485.h> 33 + 34 + xo-27mhz: xo-27mhz { 35 + compatible = "fixed-clock"; 36 + #clock-cells = <0>; 37 + clock-frequency = <27000000>; 38 + }; 39 + 40 + &i2c0 { 41 + max9485: audio-clock@63 { 42 + reg = <0x63>; 43 + compatible = "maxim,max9485"; 44 + clock-names = "xclk"; 45 + clocks = <&xo-27mhz>; 46 + reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>; 47 + vdd-supply = <&3v3-reg>; 48 + #clock-cells = <1>; 49 + }; 50 + }; 51 + 52 + // Clock consumer node 53 + 54 + foo@0 { 55 + compatible = "bar,foo"; 56 + /* ... */ 57 + clock-names = "foo-input-clk"; 58 + clocks = <&max9485 MAX9485_CLKOUT1>; 59 + };
+19
Documentation/devicetree/bindings/clock/qcom,dispcc.txt
··· 1 + Qualcomm Technologies, Inc. Display Clock Controller Binding 2 + ------------------------------------------------------------ 3 + 4 + Required properties : 5 + 6 + - compatible : shall contain "qcom,sdm845-dispcc" 7 + - reg : shall contain base register location and length. 8 + - #clock-cells : from common clock binding, shall contain 1. 9 + - #reset-cells : from common reset binding, shall contain 1. 10 + - #power-domain-cells : from generic power domain binding, shall contain 1. 11 + 12 + Example: 13 + dispcc: clock-controller@af00000 { 14 + compatible = "qcom,sdm845-dispcc"; 15 + reg = <0xaf00000 0x100000>; 16 + #clock-cells = <1>; 17 + #reset-cells = <1>; 18 + #power-domain-cells = <1>; 19 + };
+43
Documentation/devicetree/bindings/clock/renesas,r9a06g032-sysctrl.txt
··· 1 + * Renesas R9A06G032 SYSCTRL 2 + 3 + Required Properties: 4 + 5 + - compatible: Must be: 6 + - "renesas,r9a06g032-sysctrl" 7 + - reg: Base address and length of the SYSCTRL IO block. 8 + - #clock-cells: Must be 1 9 + - clocks: References to the parent clocks: 10 + - external 40mhz crystal. 11 + - external (optional) 32.768khz 12 + - external (optional) jtag input 13 + - external (optional) RGMII_REFCLK 14 + - clock-names: Must be: 15 + clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; 16 + 17 + Examples 18 + -------- 19 + 20 + - SYSCTRL node: 21 + 22 + sysctrl: system-controller@4000c000 { 23 + compatible = "renesas,r9a06g032-sysctrl"; 24 + reg = <0x4000c000 0x1000>; 25 + #clock-cells = <1>; 26 + 27 + clocks = <&ext_mclk>, <&ext_rtc_clk>, 28 + <&ext_jtag_clk>, <&ext_rgmii_ref>; 29 + clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; 30 + }; 31 + 32 + - Other nodes can use the clocks provided by SYSCTRL as in: 33 + 34 + #include <dt-bindings/clock/r9a06g032-sysctrl.h> 35 + uart0: serial@40060000 { 36 + compatible = "snps,dw-apb-uart"; 37 + reg = <0x40060000 0x400>; 38 + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; 39 + reg-shift = <2>; 40 + reg-io-width = <4>; 41 + clocks = <&sysctrl R9A06G032_CLK_UART0>; 42 + clock-names = "baudclk"; 43 + };
+65
Documentation/devicetree/bindings/clock/rockchip,px30-cru.txt
··· 1 + * Rockchip PX30 Clock and Reset Unit 2 + 3 + The PX30 clock controller generates and supplies clock to various 4 + controllers within the SoC and also implements a reset controller for SoC 5 + peripherals. 6 + 7 + Required Properties: 8 + 9 + - compatible: PMU for CRU should be "rockchip,px30-pmu-cru" 10 + - compatible: CRU should be "rockchip,px30-cru" 11 + - reg: physical base address of the controller and length of memory mapped 12 + region. 13 + - #clock-cells: should be 1. 14 + - #reset-cells: should be 1. 15 + 16 + Optional Properties: 17 + 18 + - rockchip,grf: phandle to the syscon managing the "general register files" 19 + If missing, pll rates are not changeable, due to the missing pll lock status. 20 + 21 + Each clock is assigned an identifier and client nodes can use this identifier 22 + to specify the clock which they consume. All available clocks are defined as 23 + preprocessor macros in the dt-bindings/clock/px30-cru.h headers and can be 24 + used in device tree sources. Similar macros exist for the reset sources in 25 + these files. 26 + 27 + External clocks: 28 + 29 + There are several clocks that are generated outside the SoC. It is expected 30 + that they are defined using standard clock bindings with following 31 + clock-output-names: 32 + - "xin24m" - crystal input - required, 33 + - "xin32k" - rtc clock - optional, 34 + - "i2sx_clkin" - external I2S clock - optional, 35 + - "gmac_clkin" - external GMAC clock - optional 36 + 37 + Example: Clock controller node: 38 + 39 + pmucru: clock-controller@ff2bc000 { 40 + compatible = "rockchip,px30-pmucru"; 41 + reg = <0x0 0xff2bc000 0x0 0x1000>; 42 + #clock-cells = <1>; 43 + #reset-cells = <1>; 44 + }; 45 + 46 + cru: clock-controller@ff2b0000 { 47 + compatible = "rockchip,px30-cru"; 48 + reg = <0x0 0xff2b0000 0x0 0x1000>; 49 + rockchip,grf = <&grf>; 50 + #clock-cells = <1>; 51 + #reset-cells = <1>; 52 + }; 53 + 54 + Example: UART controller node that consumes the clock generated by the clock 55 + controller: 56 + 57 + uart0: serial@ff030000 { 58 + compatible = "rockchip,px30-uart", "snps,dw-apb-uart"; 59 + reg = <0x0 0xff030000 0x0 0x100>; 60 + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; 61 + clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>; 62 + clock-names = "baudclk", "apb_pclk"; 63 + reg-shift = <2>; 64 + reg-io-width = <4>; 65 + };
+1
Documentation/devicetree/bindings/clock/sun8i-de2.txt
··· 6 6 - "allwinner,sun8i-a83t-de2-clk" 7 7 - "allwinner,sun8i-h3-de2-clk" 8 8 - "allwinner,sun8i-v3s-de2-clk" 9 + - "allwinner,sun50i-a64-de2-clk" 9 10 - "allwinner,sun50i-h5-de2-clk" 10 11 11 12 - reg: Must contain the registers base address and length
+4
arch/arm/mach-at91/Kconfig
··· 27 27 select HAVE_AT91_H32MX 28 28 select HAVE_AT91_GENERATED_CLK 29 29 select HAVE_AT91_AUDIO_PLL 30 + select HAVE_AT91_I2S_MUX_CLK 30 31 select PINCTRL_AT91PIO4 31 32 help 32 33 Select this if ou are using one of Microchip's SAMA5D2 family SoC. ··· 128 127 bool 129 128 130 129 config HAVE_AT91_AUDIO_PLL 130 + bool 131 + 132 + config HAVE_AT91_I2S_MUX_CLK 131 133 bool 132 134 133 135 config SOC_SAM_V4_V5
+6
drivers/clk/Kconfig
··· 45 45 This driver supports Maxim 77620/77686/77802 crystal oscillator 46 46 clock. 47 47 48 + config COMMON_CLK_MAX9485 49 + tristate "Maxim 9485 Programmable Clock Generator" 50 + depends on I2C 51 + help 52 + This driver supports Maxim 9485 Programmable Audio Clock Generator 53 + 48 54 config COMMON_CLK_RK808 49 55 tristate "Clock driver for RK805/RK808/RK818" 50 56 depends on MFD_RK808
+1
drivers/clk/Makefile
··· 31 31 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 32 32 obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o 33 33 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 34 + obj-$(CONFIG_COMMON_CLK_MAX9485) += clk-max9485.o 34 35 obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 35 36 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 36 37 obj-$(CONFIG_ARCH_NPCM7XX) += clk-npcm7xx.o
+7
drivers/clk/actions/Kconfig
··· 1 1 config CLK_ACTIONS 2 2 bool "Clock driver for Actions Semi SoCs" 3 3 depends on ARCH_ACTIONS || COMPILE_TEST 4 + select REGMAP_MMIO 4 5 default ARCH_ACTIONS 5 6 6 7 if CLK_ACTIONS 7 8 8 9 # SoC Drivers 9 10 11 + config CLK_OWL_S700 12 + bool "Support for the Actions Semi OWL S700 clocks" 13 + depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST 14 + default ARM64 && ARCH_ACTIONS 15 + 10 16 config CLK_OWL_S900 11 17 bool "Support for the Actions Semi OWL S900 clocks" 12 18 depends on (ARM64 && ARCH_ACTIONS) || COMPILE_TEST 13 19 default ARM64 && ARCH_ACTIONS 20 + 14 21 endif
+1
drivers/clk/actions/Makefile
··· 9 9 clk-owl-y += owl-pll.o 10 10 11 11 # SoC support 12 + obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o 12 13 obj-$(CONFIG_CLK_OWL_S900) += owl-s900.o
+606
drivers/clk/actions/owl-s700.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * Actions Semi S700 clock driver 4 + * 5 + * Copyright (c) 2014 Actions Semi Inc. 6 + * Author: David Liu <liuwei@actions-semi.com> 7 + * 8 + * Author: Pathiban Nallathambi <pn@denx.de> 9 + * Author: Saravanan Sekar <sravanhome@gmail.com> 10 + */ 11 + 12 + #include <linux/clk-provider.h> 13 + #include <linux/platform_device.h> 14 + 15 + #include "owl-common.h" 16 + #include "owl-composite.h" 17 + #include "owl-divider.h" 18 + #include "owl-factor.h" 19 + #include "owl-fixed-factor.h" 20 + #include "owl-gate.h" 21 + #include "owl-mux.h" 22 + #include "owl-pll.h" 23 + 24 + #include <dt-bindings/clock/actions,s700-cmu.h> 25 + 26 + #define CMU_COREPLL (0x0000) 27 + #define CMU_DEVPLL (0x0004) 28 + #define CMU_DDRPLL (0x0008) 29 + #define CMU_NANDPLL (0x000C) 30 + #define CMU_DISPLAYPLL (0x0010) 31 + #define CMU_AUDIOPLL (0x0014) 32 + #define CMU_TVOUTPLL (0x0018) 33 + #define CMU_BUSCLK (0x001C) 34 + #define CMU_SENSORCLK (0x0020) 35 + #define CMU_LCDCLK (0x0024) 36 + #define CMU_DSIPLLCLK (0x0028) 37 + #define CMU_CSICLK (0x002C) 38 + #define CMU_DECLK (0x0030) 39 + #define CMU_SICLK (0x0034) 40 + #define CMU_BUSCLK1 (0x0038) 41 + #define CMU_HDECLK (0x003C) 42 + #define CMU_VDECLK (0x0040) 43 + #define CMU_VCECLK (0x0044) 44 + #define CMU_NANDCCLK (0x004C) 45 + #define CMU_SD0CLK (0x0050) 46 + #define CMU_SD1CLK (0x0054) 47 + #define CMU_SD2CLK (0x0058) 48 + #define CMU_UART0CLK (0x005C) 49 + #define CMU_UART1CLK (0x0060) 50 + #define CMU_UART2CLK (0x0064) 51 + #define CMU_UART3CLK (0x0068) 52 + #define CMU_UART4CLK (0x006C) 53 + #define CMU_UART5CLK (0x0070) 54 + #define CMU_UART6CLK (0x0074) 55 + #define CMU_PWM0CLK (0x0078) 56 + #define CMU_PWM1CLK (0x007C) 57 + #define CMU_PWM2CLK (0x0080) 58 + #define CMU_PWM3CLK (0x0084) 59 + #define CMU_PWM4CLK (0x0088) 60 + #define CMU_PWM5CLK (0x008C) 61 + #define CMU_GPU3DCLK (0x0090) 62 + #define CMU_CORECTL (0x009C) 63 + #define CMU_DEVCLKEN0 (0x00A0) 64 + #define CMU_DEVCLKEN1 (0x00A4) 65 + #define CMU_DEVRST0 (0x00A8) 66 + #define CMU_DEVRST1 (0x00AC) 67 + #define CMU_USBPLL (0x00B0) 68 + #define CMU_ETHERNETPLL (0x00B4) 69 + #define CMU_CVBSPLL (0x00B8) 70 + #define CMU_SSTSCLK (0x00C0) 71 + 72 + static struct clk_pll_table clk_audio_pll_table[] = { 73 + {0, 45158400}, {1, 49152000}, 74 + {0, 0}, 75 + }; 76 + 77 + static struct clk_pll_table clk_cvbs_pll_table[] = { 78 + {27, 29 * 12000000}, {28, 30 * 12000000}, {29, 31 * 12000000}, 79 + {30, 32 * 12000000}, {31, 33 * 12000000}, {32, 34 * 12000000}, 80 + {33, 35 * 12000000}, {34, 36 * 12000000}, {35, 37 * 12000000}, 81 + {36, 38 * 12000000}, {37, 39 * 12000000}, {38, 40 * 12000000}, 82 + {39, 41 * 12000000}, {40, 42 * 12000000}, {41, 43 * 12000000}, 83 + {42, 44 * 12000000}, {43, 45 * 12000000}, {0, 0}, 84 + }; 85 + 86 + /* pll clocks */ 87 + static OWL_PLL_NO_PARENT(clk_core_pll, "core_pll", CMU_COREPLL, 12000000, 9, 0, 8, 4, 174, NULL, CLK_IGNORE_UNUSED); 88 + static OWL_PLL_NO_PARENT(clk_dev_pll, "dev_pll", CMU_DEVPLL, 6000000, 8, 0, 8, 8, 126, NULL, CLK_IGNORE_UNUSED); 89 + static OWL_PLL_NO_PARENT(clk_ddr_pll, "ddr_pll", CMU_DDRPLL, 6000000, 8, 0, 8, 2, 180, NULL, CLK_IGNORE_UNUSED); 90 + static OWL_PLL_NO_PARENT(clk_nand_pll, "nand_pll", CMU_NANDPLL, 6000000, 8, 0, 8, 2, 86, NULL, CLK_IGNORE_UNUSED); 91 + static OWL_PLL_NO_PARENT(clk_display_pll, "display_pll", CMU_DISPLAYPLL, 6000000, 8, 0, 8, 2, 140, NULL, CLK_IGNORE_UNUSED); 92 + static OWL_PLL_NO_PARENT(clk_cvbs_pll, "cvbs_pll", CMU_CVBSPLL, 0, 8, 0, 8, 27, 43, clk_cvbs_pll_table, CLK_IGNORE_UNUSED); 93 + static OWL_PLL_NO_PARENT(clk_audio_pll, "audio_pll", CMU_AUDIOPLL, 0, 4, 0, 1, 0, 0, clk_audio_pll_table, CLK_IGNORE_UNUSED); 94 + static OWL_PLL_NO_PARENT(clk_ethernet_pll, "ethernet_pll", CMU_ETHERNETPLL, 500000000, 0, 0, 0, 0, 0, NULL, CLK_IGNORE_UNUSED); 95 + 96 + static const char *cpu_clk_mux_p[] = {"losc", "hosc", "core_pll", "noc1_clk_div"}; 97 + static const char *dev_clk_p[] = { "hosc", "dev_pll"}; 98 + static const char *noc_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_pll", "cvbs_pll"}; 99 + 100 + static const char *csi_clk_mux_p[] = { "display_pll", "dev_clk"}; 101 + static const char *de_clk_mux_p[] = { "display_pll", "dev_clk"}; 102 + static const char *hde_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_pll"}; 103 + static const char *nand_clk_mux_p[] = { "nand_pll", "display_pll", "dev_clk", "ddr_pll"}; 104 + static const char *sd_clk_mux_p[] = { "dev_clk", "nand_pll", }; 105 + static const char *uart_clk_mux_p[] = { "hosc", "dev_pll"}; 106 + static const char *pwm_clk_mux_p[] = { "losc", "hosc"}; 107 + static const char *gpu_clk_mux_p[] = { "dev_clk", "display_pll", "nand_pll", "ddr_clk", "cvbs_pll"}; 108 + static const char *lcd_clk_mux_p[] = { "display_pll", "dev_clk" }; 109 + static const char *i2s_clk_mux_p[] = { "audio_pll" }; 110 + static const char *sensor_clk_mux_p[] = { "hosc", "si"}; 111 + 112 + /* mux clocks */ 113 + static OWL_MUX(clk_cpu, "cpu_clk", cpu_clk_mux_p, CMU_BUSCLK, 0, 2, CLK_SET_RATE_PARENT); 114 + static OWL_MUX(clk_dev, "dev_clk", dev_clk_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); 115 + static OWL_MUX(clk_noc0_clk_mux, "noc0_clk_mux", noc_clk_mux_p, CMU_BUSCLK, 4, 3, CLK_SET_RATE_PARENT); 116 + static OWL_MUX(clk_noc1_clk_mux, "noc1_clk_mux", noc_clk_mux_p, CMU_BUSCLK1, 4, 3, CLK_SET_RATE_PARENT); 117 + static OWL_MUX(clk_hp_clk_mux, "hp_clk_mux", noc_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); 118 + 119 + static struct clk_factor_table sd_factor_table[] = { 120 + /* bit0 ~ 4 */ 121 + {0, 1, 1}, {1, 1, 2}, {2, 1, 3}, {3, 1, 4}, 122 + {4, 1, 5}, {5, 1, 6}, {6, 1, 7}, {7, 1, 8}, 123 + {8, 1, 9}, {9, 1, 10}, {10, 1, 11}, {11, 1, 12}, 124 + {12, 1, 13}, {13, 1, 14}, {14, 1, 15}, {15, 1, 16}, 125 + {16, 1, 17}, {17, 1, 18}, {18, 1, 19}, {19, 1, 20}, 126 + {20, 1, 21}, {21, 1, 22}, {22, 1, 23}, {23, 1, 24}, 127 + {24, 1, 25}, {25, 1, 26}, 128 + 129 + /* bit8: /128 */ 130 + {256, 1, 1 * 128}, {257, 1, 2 * 128}, {258, 1, 3 * 128}, {259, 1, 4 * 128}, 131 + {260, 1, 5 * 128}, {261, 1, 6 * 128}, {262, 1, 7 * 128}, {263, 1, 8 * 128}, 132 + {264, 1, 9 * 128}, {265, 1, 10 * 128}, {266, 1, 11 * 128}, {267, 1, 12 * 128}, 133 + {268, 1, 13 * 128}, {269, 1, 14 * 128}, {270, 1, 15 * 128}, {271, 1, 16 * 128}, 134 + {272, 1, 17 * 128}, {273, 1, 18 * 128}, {274, 1, 19 * 128}, {275, 1, 20 * 128}, 135 + {276, 1, 21 * 128}, {277, 1, 22 * 128}, {278, 1, 23 * 128}, {279, 1, 24 * 128}, 136 + {280, 1, 25 * 128}, {281, 1, 26 * 128}, 137 + 138 + {0, 0}, 139 + }; 140 + 141 + static struct clk_factor_table lcd_factor_table[] = { 142 + /* bit0 ~ 3 */ 143 + {0, 1, 1}, {1, 1, 2}, {2, 1, 3}, {3, 1, 4}, 144 + {4, 1, 5}, {5, 1, 6}, {6, 1, 7}, {7, 1, 8}, 145 + {8, 1, 9}, {9, 1, 10}, {10, 1, 11}, {11, 1, 12}, 146 + 147 + /* bit8: /7 */ 148 + {256, 1, 1 * 7}, {257, 1, 2 * 7}, {258, 1, 3 * 7}, {259, 1, 4 * 7}, 149 + {260, 1, 5 * 7}, {261, 1, 6 * 7}, {262, 1, 7 * 7}, {263, 1, 8 * 7}, 150 + {264, 1, 9 * 7}, {265, 1, 10 * 7}, {266, 1, 11 * 7}, {267, 1, 12 * 7}, 151 + {0, 0}, 152 + }; 153 + 154 + static struct clk_div_table hdmia_div_table[] = { 155 + {0, 1}, {1, 2}, {2, 3}, {3, 4}, 156 + {4, 6}, {5, 8}, {6, 12}, {7, 16}, 157 + {8, 24}, 158 + {0, 0}, 159 + }; 160 + 161 + static struct clk_div_table rmii_div_table[] = { 162 + {0, 4}, {1, 10}, 163 + }; 164 + 165 + /* divider clocks */ 166 + static OWL_DIVIDER(clk_noc0, "noc0_clk", "noc0_clk_mux", CMU_BUSCLK, 16, 2, NULL, 0, 0); 167 + static OWL_DIVIDER(clk_noc1, "noc1_clk", "noc1_clk_mux", CMU_BUSCLK1, 16, 2, NULL, 0, 0); 168 + static OWL_DIVIDER(clk_noc1_clk_div, "noc1_clk_div", "noc1_clk", CMU_BUSCLK1, 20, 1, NULL, 0, 0); 169 + static OWL_DIVIDER(clk_hp_clk_div, "hp_clk_div", "hp_clk_mux", CMU_BUSCLK1, 12, 2, NULL, 0, 0); 170 + static OWL_DIVIDER(clk_ahb, "ahb_clk", "hp_clk_div", CMU_BUSCLK1, 2, 2, NULL, 0, 0); 171 + static OWL_DIVIDER(clk_apb, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); 172 + static OWL_DIVIDER(clk_sensor0, "sensor0", "sensor_src", CMU_SENSORCLK, 0, 4, NULL, 0, 0); 173 + static OWL_DIVIDER(clk_sensor1, "sensor1", "sensor_src", CMU_SENSORCLK, 8, 4, NULL, 0, 0); 174 + static OWL_DIVIDER(clk_rmii_ref, "rmii_ref", "ethernet_pll", CMU_ETHERNETPLL, 2, 1, rmii_div_table, 0, 0); 175 + 176 + static struct clk_factor_table de_factor_table[] = { 177 + {0, 1, 1}, {1, 2, 3}, {2, 1, 2}, {3, 2, 5}, 178 + {4, 1, 3}, {5, 1, 4}, {6, 1, 6}, {7, 1, 8}, 179 + {8, 1, 12}, {0, 0, 0}, 180 + }; 181 + 182 + static struct clk_factor_table hde_factor_table[] = { 183 + {0, 1, 1}, {1, 2, 3}, {2, 1, 2}, {3, 2, 5}, 184 + {4, 1, 3}, {5, 1, 4}, {6, 1, 6}, {7, 1, 8}, 185 + {0, 0, 0}, 186 + }; 187 + 188 + /* gate clocks */ 189 + static OWL_GATE(clk_gpio, "gpio", "apb_clk", CMU_DEVCLKEN1, 25, 0, 0); 190 + static OWL_GATE(clk_dmac, "dmac", "hp_clk_div", CMU_DEVCLKEN0, 17, 0, 0); 191 + static OWL_GATE(clk_timer, "timer", "hosc", CMU_DEVCLKEN1, 22, 0, 0); 192 + static OWL_GATE_NO_PARENT(clk_dsi, "dsi_clk", CMU_DEVCLKEN0, 2, 0, 0); 193 + static OWL_GATE_NO_PARENT(clk_tvout, "tvout_clk", CMU_DEVCLKEN0, 3, 0, 0); 194 + static OWL_GATE_NO_PARENT(clk_hdmi_dev, "hdmi_dev", CMU_DEVCLKEN0, 5, 0, 0); 195 + static OWL_GATE_NO_PARENT(clk_usb3_480mpll0, "usb3_480mpll0", CMU_USBPLL, 3, 0, 0); 196 + static OWL_GATE_NO_PARENT(clk_usb3_480mphy0, "usb3_480mphy0", CMU_USBPLL, 2, 0, 0); 197 + static OWL_GATE_NO_PARENT(clk_usb3_5gphy, "usb3_5gphy", CMU_USBPLL, 1, 0, 0); 198 + static OWL_GATE_NO_PARENT(clk_usb3_cce, "usb3_cce", CMU_DEVCLKEN0, 25, 0, 0); 199 + static OWL_GATE(clk_i2c0, "i2c0", "hosc", CMU_DEVCLKEN1, 0, 0, 0); 200 + static OWL_GATE(clk_i2c1, "i2c1", "hosc", CMU_DEVCLKEN1, 1, 0, 0); 201 + static OWL_GATE(clk_i2c2, "i2c2", "hosc", CMU_DEVCLKEN1, 2, 0, 0); 202 + static OWL_GATE(clk_i2c3, "i2c3", "hosc", CMU_DEVCLKEN1, 3, 0, 0); 203 + static OWL_GATE(clk_spi0, "spi0", "ahb_clk", CMU_DEVCLKEN1, 4, 0, 0); 204 + static OWL_GATE(clk_spi1, "spi1", "ahb_clk", CMU_DEVCLKEN1, 5, 0, 0); 205 + static OWL_GATE(clk_spi2, "spi2", "ahb_clk", CMU_DEVCLKEN1, 6, 0, 0); 206 + static OWL_GATE(clk_spi3, "spi3", "ahb_clk", CMU_DEVCLKEN1, 7, 0, 0); 207 + static OWL_GATE_NO_PARENT(clk_usb2h0_pllen, "usbh0_pllen", CMU_USBPLL, 12, 0, 0); 208 + static OWL_GATE_NO_PARENT(clk_usb2h0_phy, "usbh0_phy", CMU_USBPLL, 10, 0, 0); 209 + static OWL_GATE_NO_PARENT(clk_usb2h0_cce, "usbh0_cce", CMU_DEVCLKEN0, 26, 0, 0); 210 + static OWL_GATE_NO_PARENT(clk_usb2h1_pllen, "usbh1_pllen", CMU_USBPLL, 13, 0, 0); 211 + static OWL_GATE_NO_PARENT(clk_usb2h1_phy, "usbh1_phy", CMU_USBPLL, 11, 0, 0); 212 + static OWL_GATE_NO_PARENT(clk_usb2h1_cce, "usbh1_cce", CMU_DEVCLKEN0, 27, 0, 0); 213 + static OWL_GATE_NO_PARENT(clk_irc_switch, "irc_switch", CMU_DEVCLKEN1, 15, 0, 0); 214 + 215 + /* composite clocks */ 216 + 217 + static OWL_COMP_DIV(clk_csi, "csi", csi_clk_mux_p, 218 + OWL_MUX_HW(CMU_CSICLK, 4, 1), 219 + OWL_GATE_HW(CMU_DEVCLKEN0, 13, 0), 220 + OWL_DIVIDER_HW(CMU_CSICLK, 0, 4, 0, NULL), 221 + 0); 222 + 223 + static OWL_COMP_DIV(clk_si, "si", csi_clk_mux_p, 224 + OWL_MUX_HW(CMU_SICLK, 4, 1), 225 + OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), 226 + OWL_DIVIDER_HW(CMU_SICLK, 0, 4, 0, NULL), 227 + 0); 228 + 229 + static OWL_COMP_FACTOR(clk_de, "de", de_clk_mux_p, 230 + OWL_MUX_HW(CMU_DECLK, 12, 1), 231 + OWL_GATE_HW(CMU_DEVCLKEN0, 0, 0), 232 + OWL_FACTOR_HW(CMU_DECLK, 0, 3, 0, de_factor_table), 233 + 0); 234 + 235 + static OWL_COMP_FACTOR(clk_hde, "hde", hde_clk_mux_p, 236 + OWL_MUX_HW(CMU_HDECLK, 4, 2), 237 + OWL_GATE_HW(CMU_DEVCLKEN0, 9, 0), 238 + OWL_FACTOR_HW(CMU_HDECLK, 0, 3, 0, hde_factor_table), 239 + 0); 240 + 241 + static OWL_COMP_FACTOR(clk_vde, "vde", hde_clk_mux_p, 242 + OWL_MUX_HW(CMU_VDECLK, 4, 2), 243 + OWL_GATE_HW(CMU_DEVCLKEN0, 10, 0), 244 + OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), 245 + 0); 246 + 247 + static OWL_COMP_FACTOR(clk_vce, "vce", hde_clk_mux_p, 248 + OWL_MUX_HW(CMU_VCECLK, 4, 2), 249 + OWL_GATE_HW(CMU_DEVCLKEN0, 11, 0), 250 + OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), 251 + 0); 252 + 253 + static OWL_COMP_DIV(clk_nand, "nand", nand_clk_mux_p, 254 + OWL_MUX_HW(CMU_NANDCCLK, 8, 2), 255 + OWL_GATE_HW(CMU_DEVCLKEN0, 21, 0), 256 + OWL_DIVIDER_HW(CMU_NANDCCLK, 0, 3, 0, NULL), 257 + CLK_SET_RATE_PARENT); 258 + 259 + static OWL_COMP_FACTOR(clk_sd0, "sd0", sd_clk_mux_p, 260 + OWL_MUX_HW(CMU_SD0CLK, 9, 1), 261 + OWL_GATE_HW(CMU_DEVCLKEN0, 22, 0), 262 + OWL_FACTOR_HW(CMU_SD0CLK, 0, 9, 0, sd_factor_table), 263 + 0); 264 + 265 + static OWL_COMP_FACTOR(clk_sd1, "sd1", sd_clk_mux_p, 266 + OWL_MUX_HW(CMU_SD1CLK, 9, 1), 267 + OWL_GATE_HW(CMU_DEVCLKEN0, 23, 0), 268 + OWL_FACTOR_HW(CMU_SD1CLK, 0, 9, 0, sd_factor_table), 269 + 0); 270 + 271 + static OWL_COMP_FACTOR(clk_sd2, "sd2", sd_clk_mux_p, 272 + OWL_MUX_HW(CMU_SD2CLK, 9, 1), 273 + OWL_GATE_HW(CMU_DEVCLKEN0, 24, 0), 274 + OWL_FACTOR_HW(CMU_SD2CLK, 0, 9, 0, sd_factor_table), 275 + 0); 276 + 277 + static OWL_COMP_DIV(clk_uart0, "uart0", uart_clk_mux_p, 278 + OWL_MUX_HW(CMU_UART0CLK, 16, 1), 279 + OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), 280 + OWL_DIVIDER_HW(CMU_UART0CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 281 + 0); 282 + 283 + static OWL_COMP_DIV(clk_uart1, "uart1", uart_clk_mux_p, 284 + OWL_MUX_HW(CMU_UART1CLK, 16, 1), 285 + OWL_GATE_HW(CMU_DEVCLKEN1, 9, 0), 286 + OWL_DIVIDER_HW(CMU_UART1CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 287 + 0); 288 + 289 + static OWL_COMP_DIV(clk_uart2, "uart2", uart_clk_mux_p, 290 + OWL_MUX_HW(CMU_UART2CLK, 16, 1), 291 + OWL_GATE_HW(CMU_DEVCLKEN1, 10, 0), 292 + OWL_DIVIDER_HW(CMU_UART2CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 293 + 0); 294 + 295 + static OWL_COMP_DIV(clk_uart3, "uart3", uart_clk_mux_p, 296 + OWL_MUX_HW(CMU_UART3CLK, 16, 1), 297 + OWL_GATE_HW(CMU_DEVCLKEN1, 11, 0), 298 + OWL_DIVIDER_HW(CMU_UART3CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 299 + 0); 300 + 301 + static OWL_COMP_DIV(clk_uart4, "uart4", uart_clk_mux_p, 302 + OWL_MUX_HW(CMU_UART4CLK, 16, 1), 303 + OWL_GATE_HW(CMU_DEVCLKEN1, 12, 0), 304 + OWL_DIVIDER_HW(CMU_UART4CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 305 + 0); 306 + 307 + static OWL_COMP_DIV(clk_uart5, "uart5", uart_clk_mux_p, 308 + OWL_MUX_HW(CMU_UART5CLK, 16, 1), 309 + OWL_GATE_HW(CMU_DEVCLKEN1, 13, 0), 310 + OWL_DIVIDER_HW(CMU_UART5CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 311 + 0); 312 + 313 + static OWL_COMP_DIV(clk_uart6, "uart6", uart_clk_mux_p, 314 + OWL_MUX_HW(CMU_UART6CLK, 16, 1), 315 + OWL_GATE_HW(CMU_DEVCLKEN1, 14, 0), 316 + OWL_DIVIDER_HW(CMU_UART6CLK, 0, 9, CLK_DIVIDER_ROUND_CLOSEST, NULL), 317 + 0); 318 + 319 + static OWL_COMP_DIV(clk_pwm0, "pwm0", pwm_clk_mux_p, 320 + OWL_MUX_HW(CMU_PWM0CLK, 12, 1), 321 + OWL_GATE_HW(CMU_DEVCLKEN1, 16, 0), 322 + OWL_DIVIDER_HW(CMU_PWM0CLK, 0, 10, 0, NULL), 323 + CLK_IGNORE_UNUSED); 324 + 325 + static OWL_COMP_DIV(clk_pwm1, "pwm1", pwm_clk_mux_p, 326 + OWL_MUX_HW(CMU_PWM1CLK, 12, 1), 327 + OWL_GATE_HW(CMU_DEVCLKEN1, 17, 0), 328 + OWL_DIVIDER_HW(CMU_PWM1CLK, 0, 10, 0, NULL), 329 + 0); 330 + 331 + static OWL_COMP_DIV(clk_pwm2, "pwm2", pwm_clk_mux_p, 332 + OWL_MUX_HW(CMU_PWM2CLK, 12, 1), 333 + OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), 334 + OWL_DIVIDER_HW(CMU_PWM2CLK, 0, 10, 0, NULL), 335 + 0); 336 + 337 + static OWL_COMP_DIV(clk_pwm3, "pwm3", pwm_clk_mux_p, 338 + OWL_MUX_HW(CMU_PWM3CLK, 12, 1), 339 + OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), 340 + OWL_DIVIDER_HW(CMU_PWM3CLK, 0, 10, 0, NULL), 341 + 0); 342 + 343 + static OWL_COMP_DIV(clk_pwm4, "pwm4", pwm_clk_mux_p, 344 + OWL_MUX_HW(CMU_PWM4CLK, 12, 1), 345 + OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), 346 + OWL_DIVIDER_HW(CMU_PWM4CLK, 0, 10, 0, NULL), 347 + 0); 348 + 349 + static OWL_COMP_DIV(clk_pwm5, "pwm5", pwm_clk_mux_p, 350 + OWL_MUX_HW(CMU_PWM5CLK, 12, 1), 351 + OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), 352 + OWL_DIVIDER_HW(CMU_PWM5CLK, 0, 10, 0, NULL), 353 + 0); 354 + 355 + static OWL_COMP_FACTOR(clk_gpu3d, "gpu3d", gpu_clk_mux_p, 356 + OWL_MUX_HW(CMU_GPU3DCLK, 4, 3), 357 + OWL_GATE_HW(CMU_DEVCLKEN0, 8, 0), 358 + OWL_FACTOR_HW(CMU_GPU3DCLK, 0, 3, 0, hde_factor_table), 359 + 0); 360 + 361 + static OWL_COMP_FACTOR(clk_lcd, "lcd", lcd_clk_mux_p, 362 + OWL_MUX_HW(CMU_LCDCLK, 12, 2), 363 + OWL_GATE_HW(CMU_DEVCLKEN0, 1, 0), 364 + OWL_FACTOR_HW(CMU_LCDCLK, 0, 9, 0, lcd_factor_table), 365 + 0); 366 + 367 + static OWL_COMP_DIV(clk_hdmi_audio, "hdmia", i2s_clk_mux_p, 368 + OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), /*CMU_AUDIOPLL 24,1 unused*/ 369 + OWL_GATE_HW(CMU_DEVCLKEN1, 28, 0), 370 + OWL_DIVIDER_HW(CMU_AUDIOPLL, 24, 4, 0, hdmia_div_table), 371 + 0); 372 + 373 + static OWL_COMP_DIV(clk_i2srx, "i2srx", i2s_clk_mux_p, 374 + OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), 375 + OWL_GATE_HW(CMU_DEVCLKEN1, 27, 0), 376 + OWL_DIVIDER_HW(CMU_AUDIOPLL, 20, 4, 0, hdmia_div_table), 377 + 0); 378 + 379 + static OWL_COMP_DIV(clk_i2stx, "i2stx", i2s_clk_mux_p, 380 + OWL_MUX_HW(CMU_AUDIOPLL, 24, 1), 381 + OWL_GATE_HW(CMU_DEVCLKEN1, 26, 0), 382 + OWL_DIVIDER_HW(CMU_AUDIOPLL, 16, 4, 0, hdmia_div_table), 383 + 0); 384 + 385 + /* for bluetooth pcm communication */ 386 + static OWL_COMP_FIXED_FACTOR(clk_pcm1, "pcm1", "audio_pll", 387 + OWL_GATE_HW(CMU_DEVCLKEN1, 31, 0), 388 + 1, 2, 0); 389 + 390 + static OWL_COMP_DIV(clk_sensor_src, "sensor_src", sensor_clk_mux_p, 391 + OWL_MUX_HW(CMU_SENSORCLK, 4, 1), 392 + {0}, 393 + OWL_DIVIDER_HW(CMU_SENSORCLK, 5, 2, 0, NULL), 394 + 0); 395 + 396 + static OWL_COMP_FIXED_FACTOR(clk_ethernet, "ethernet", "ethernet_pll", 397 + OWL_GATE_HW(CMU_DEVCLKEN1, 23, 0), 398 + 1, 20, 0); 399 + 400 + static OWL_COMP_DIV_FIXED(clk_thermal_sensor, "thermal_sensor", "hosc", 401 + OWL_GATE_HW(CMU_DEVCLKEN0, 31, 0), 402 + OWL_DIVIDER_HW(CMU_SSTSCLK, 20, 10, 0, NULL), 403 + 0); 404 + 405 + static struct owl_clk_common *s700_clks[] = { 406 + &clk_core_pll.common, 407 + &clk_dev_pll.common, 408 + &clk_ddr_pll.common, 409 + &clk_nand_pll.common, 410 + &clk_display_pll.common, 411 + &clk_cvbs_pll .common, 412 + &clk_audio_pll.common, 413 + &clk_ethernet_pll.common, 414 + &clk_cpu.common, 415 + &clk_dev.common, 416 + &clk_ahb.common, 417 + &clk_apb.common, 418 + &clk_dmac.common, 419 + &clk_noc0_clk_mux.common, 420 + &clk_noc1_clk_mux.common, 421 + &clk_hp_clk_mux.common, 422 + &clk_hp_clk_div.common, 423 + &clk_noc1_clk_div.common, 424 + &clk_noc0.common, 425 + &clk_noc1.common, 426 + &clk_sensor_src.common, 427 + &clk_gpio.common, 428 + &clk_timer.common, 429 + &clk_dsi.common, 430 + &clk_csi.common, 431 + &clk_si.common, 432 + &clk_de.common, 433 + &clk_hde.common, 434 + &clk_vde.common, 435 + &clk_vce.common, 436 + &clk_nand.common, 437 + &clk_sd0.common, 438 + &clk_sd1.common, 439 + &clk_sd2.common, 440 + &clk_uart0.common, 441 + &clk_uart1.common, 442 + &clk_uart2.common, 443 + &clk_uart3.common, 444 + &clk_uart4.common, 445 + &clk_uart5.common, 446 + &clk_uart6.common, 447 + &clk_pwm0.common, 448 + &clk_pwm1.common, 449 + &clk_pwm2.common, 450 + &clk_pwm3.common, 451 + &clk_pwm4.common, 452 + &clk_pwm5.common, 453 + &clk_gpu3d.common, 454 + &clk_i2c0.common, 455 + &clk_i2c1.common, 456 + &clk_i2c2.common, 457 + &clk_i2c3.common, 458 + &clk_spi0.common, 459 + &clk_spi1.common, 460 + &clk_spi2.common, 461 + &clk_spi3.common, 462 + &clk_usb3_480mpll0.common, 463 + &clk_usb3_480mphy0.common, 464 + &clk_usb3_5gphy.common, 465 + &clk_usb3_cce.common, 466 + &clk_lcd.common, 467 + &clk_hdmi_audio.common, 468 + &clk_i2srx.common, 469 + &clk_i2stx.common, 470 + &clk_sensor0.common, 471 + &clk_sensor1.common, 472 + &clk_hdmi_dev.common, 473 + &clk_ethernet.common, 474 + &clk_rmii_ref.common, 475 + &clk_usb2h0_pllen.common, 476 + &clk_usb2h0_phy.common, 477 + &clk_usb2h0_cce.common, 478 + &clk_usb2h1_pllen.common, 479 + &clk_usb2h1_phy.common, 480 + &clk_usb2h1_cce.common, 481 + &clk_tvout.common, 482 + &clk_thermal_sensor.common, 483 + &clk_irc_switch.common, 484 + &clk_pcm1.common, 485 + }; 486 + 487 + static struct clk_hw_onecell_data s700_hw_clks = { 488 + .hws = { 489 + [CLK_CORE_PLL] = &clk_core_pll.common.hw, 490 + [CLK_DEV_PLL] = &clk_dev_pll.common.hw, 491 + [CLK_DDR_PLL] = &clk_ddr_pll.common.hw, 492 + [CLK_NAND_PLL] = &clk_nand_pll.common.hw, 493 + [CLK_DISPLAY_PLL] = &clk_display_pll.common.hw, 494 + [CLK_CVBS_PLL] = &clk_cvbs_pll .common.hw, 495 + [CLK_AUDIO_PLL] = &clk_audio_pll.common.hw, 496 + [CLK_ETHERNET_PLL] = &clk_ethernet_pll.common.hw, 497 + [CLK_CPU] = &clk_cpu.common.hw, 498 + [CLK_DEV] = &clk_dev.common.hw, 499 + [CLK_AHB] = &clk_ahb.common.hw, 500 + [CLK_APB] = &clk_apb.common.hw, 501 + [CLK_DMAC] = &clk_dmac.common.hw, 502 + [CLK_NOC0_CLK_MUX] = &clk_noc0_clk_mux.common.hw, 503 + [CLK_NOC1_CLK_MUX] = &clk_noc1_clk_mux.common.hw, 504 + [CLK_HP_CLK_MUX] = &clk_hp_clk_mux.common.hw, 505 + [CLK_HP_CLK_DIV] = &clk_hp_clk_div.common.hw, 506 + [CLK_NOC1_CLK_DIV] = &clk_noc1_clk_div.common.hw, 507 + [CLK_NOC0] = &clk_noc0.common.hw, 508 + [CLK_NOC1] = &clk_noc1.common.hw, 509 + [CLK_SENOR_SRC] = &clk_sensor_src.common.hw, 510 + [CLK_GPIO] = &clk_gpio.common.hw, 511 + [CLK_TIMER] = &clk_timer.common.hw, 512 + [CLK_DSI] = &clk_dsi.common.hw, 513 + [CLK_CSI] = &clk_csi.common.hw, 514 + [CLK_SI] = &clk_si.common.hw, 515 + [CLK_DE] = &clk_de.common.hw, 516 + [CLK_HDE] = &clk_hde.common.hw, 517 + [CLK_VDE] = &clk_vde.common.hw, 518 + [CLK_VCE] = &clk_vce.common.hw, 519 + [CLK_NAND] = &clk_nand.common.hw, 520 + [CLK_SD0] = &clk_sd0.common.hw, 521 + [CLK_SD1] = &clk_sd1.common.hw, 522 + [CLK_SD2] = &clk_sd2.common.hw, 523 + [CLK_UART0] = &clk_uart0.common.hw, 524 + [CLK_UART1] = &clk_uart1.common.hw, 525 + [CLK_UART2] = &clk_uart2.common.hw, 526 + [CLK_UART3] = &clk_uart3.common.hw, 527 + [CLK_UART4] = &clk_uart4.common.hw, 528 + [CLK_UART5] = &clk_uart5.common.hw, 529 + [CLK_UART6] = &clk_uart6.common.hw, 530 + [CLK_PWM0] = &clk_pwm0.common.hw, 531 + [CLK_PWM1] = &clk_pwm1.common.hw, 532 + [CLK_PWM2] = &clk_pwm2.common.hw, 533 + [CLK_PWM3] = &clk_pwm3.common.hw, 534 + [CLK_PWM4] = &clk_pwm4.common.hw, 535 + [CLK_PWM5] = &clk_pwm5.common.hw, 536 + [CLK_GPU3D] = &clk_gpu3d.common.hw, 537 + [CLK_I2C0] = &clk_i2c0.common.hw, 538 + [CLK_I2C1] = &clk_i2c1.common.hw, 539 + [CLK_I2C2] = &clk_i2c2.common.hw, 540 + [CLK_I2C3] = &clk_i2c3.common.hw, 541 + [CLK_SPI0] = &clk_spi0.common.hw, 542 + [CLK_SPI1] = &clk_spi1.common.hw, 543 + [CLK_SPI2] = &clk_spi2.common.hw, 544 + [CLK_SPI3] = &clk_spi3.common.hw, 545 + [CLK_USB3_480MPLL0] = &clk_usb3_480mpll0.common.hw, 546 + [CLK_USB3_480MPHY0] = &clk_usb3_480mphy0.common.hw, 547 + [CLK_USB3_5GPHY] = &clk_usb3_5gphy.common.hw, 548 + [CLK_USB3_CCE] = &clk_usb3_cce.common.hw, 549 + [CLK_LCD] = &clk_lcd.common.hw, 550 + [CLK_HDMI_AUDIO] = &clk_hdmi_audio.common.hw, 551 + [CLK_I2SRX] = &clk_i2srx.common.hw, 552 + [CLK_I2STX] = &clk_i2stx.common.hw, 553 + [CLK_SENSOR0] = &clk_sensor0.common.hw, 554 + [CLK_SENSOR1] = &clk_sensor1.common.hw, 555 + [CLK_HDMI_DEV] = &clk_hdmi_dev.common.hw, 556 + [CLK_ETHERNET] = &clk_ethernet.common.hw, 557 + [CLK_RMII_REF] = &clk_rmii_ref.common.hw, 558 + [CLK_USB2H0_PLLEN] = &clk_usb2h0_pllen.common.hw, 559 + [CLK_USB2H0_PHY] = &clk_usb2h0_phy.common.hw, 560 + [CLK_USB2H0_CCE] = &clk_usb2h0_cce.common.hw, 561 + [CLK_USB2H1_PLLEN] = &clk_usb2h1_pllen.common.hw, 562 + [CLK_USB2H1_PHY] = &clk_usb2h1_phy.common.hw, 563 + [CLK_USB2H1_CCE] = &clk_usb2h1_cce.common.hw, 564 + [CLK_TVOUT] = &clk_tvout.common.hw, 565 + [CLK_THERMAL_SENSOR] = &clk_thermal_sensor.common.hw, 566 + [CLK_IRC_SWITCH] = &clk_irc_switch.common.hw, 567 + [CLK_PCM1] = &clk_pcm1.common.hw, 568 + }, 569 + .num = CLK_NR_CLKS, 570 + }; 571 + 572 + static const struct owl_clk_desc s700_clk_desc = { 573 + .clks = s700_clks, 574 + .num_clks = ARRAY_SIZE(s700_clks), 575 + 576 + .hw_clks = &s700_hw_clks, 577 + }; 578 + 579 + static int s700_clk_probe(struct platform_device *pdev) 580 + { 581 + const struct owl_clk_desc *desc; 582 + 583 + desc = &s700_clk_desc; 584 + owl_clk_regmap_init(pdev, desc); 585 + 586 + return owl_clk_probe(&pdev->dev, desc->hw_clks); 587 + } 588 + 589 + static const struct of_device_id s700_clk_of_match[] = { 590 + { .compatible = "actions,s700-cmu", }, 591 + { /* sentinel */ } 592 + }; 593 + 594 + static struct platform_driver s700_clk_driver = { 595 + .probe = s700_clk_probe, 596 + .driver = { 597 + .name = "s700-cmu", 598 + .of_match_table = s700_clk_of_match 599 + }, 600 + }; 601 + 602 + static int __init s700_clk_init(void) 603 + { 604 + return platform_driver_register(&s700_clk_driver); 605 + } 606 + core_initcall(s700_clk_init);
+1
drivers/clk/at91/Makefile
··· 13 13 obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o 14 14 obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o 15 15 obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o 16 + obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o
+116
drivers/clk/at91/clk-i2s-mux.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2018 Microchip Technology Inc, 4 + * Codrin Ciubotariu <codrin.ciubotariu@microchip.com> 5 + * 6 + * 7 + */ 8 + 9 + #include <linux/clk-provider.h> 10 + #include <linux/of.h> 11 + #include <linux/mfd/syscon.h> 12 + #include <linux/regmap.h> 13 + #include <linux/slab.h> 14 + 15 + #include <soc/at91/atmel-sfr.h> 16 + 17 + #define I2S_BUS_NR 2 18 + 19 + struct clk_i2s_mux { 20 + struct clk_hw hw; 21 + struct regmap *regmap; 22 + u8 bus_id; 23 + }; 24 + 25 + #define to_clk_i2s_mux(hw) container_of(hw, struct clk_i2s_mux, hw) 26 + 27 + static u8 clk_i2s_mux_get_parent(struct clk_hw *hw) 28 + { 29 + struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); 30 + u32 val; 31 + 32 + regmap_read(mux->regmap, AT91_SFR_I2SCLKSEL, &val); 33 + 34 + return (val & BIT(mux->bus_id)) >> mux->bus_id; 35 + } 36 + 37 + static int clk_i2s_mux_set_parent(struct clk_hw *hw, u8 index) 38 + { 39 + struct clk_i2s_mux *mux = to_clk_i2s_mux(hw); 40 + 41 + return regmap_update_bits(mux->regmap, AT91_SFR_I2SCLKSEL, 42 + BIT(mux->bus_id), index << mux->bus_id); 43 + } 44 + 45 + static const struct clk_ops clk_i2s_mux_ops = { 46 + .get_parent = clk_i2s_mux_get_parent, 47 + .set_parent = clk_i2s_mux_set_parent, 48 + .determine_rate = __clk_mux_determine_rate, 49 + }; 50 + 51 + static struct clk_hw * __init 52 + at91_clk_i2s_mux_register(struct regmap *regmap, const char *name, 53 + const char * const *parent_names, 54 + unsigned int num_parents, u8 bus_id) 55 + { 56 + struct clk_init_data init = {}; 57 + struct clk_i2s_mux *i2s_ck; 58 + int ret; 59 + 60 + i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL); 61 + if (!i2s_ck) 62 + return ERR_PTR(-ENOMEM); 63 + 64 + init.name = name; 65 + init.ops = &clk_i2s_mux_ops; 66 + init.parent_names = parent_names; 67 + init.num_parents = num_parents; 68 + 69 + i2s_ck->hw.init = &init; 70 + i2s_ck->bus_id = bus_id; 71 + i2s_ck->regmap = regmap; 72 + 73 + ret = clk_hw_register(NULL, &i2s_ck->hw); 74 + if (ret) { 75 + kfree(i2s_ck); 76 + return ERR_PTR(ret); 77 + } 78 + 79 + return &i2s_ck->hw; 80 + } 81 + 82 + static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np) 83 + { 84 + struct regmap *regmap_sfr; 85 + u8 bus_id; 86 + const char *parent_names[2]; 87 + struct device_node *i2s_mux_np; 88 + struct clk_hw *hw; 89 + int ret; 90 + 91 + regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr"); 92 + if (IS_ERR(regmap_sfr)) 93 + return; 94 + 95 + for_each_child_of_node(np, i2s_mux_np) { 96 + if (of_property_read_u8(i2s_mux_np, "reg", &bus_id)) 97 + continue; 98 + 99 + if (bus_id > I2S_BUS_NR) 100 + continue; 101 + 102 + ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2); 103 + if (ret != 2) 104 + continue; 105 + 106 + hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name, 107 + parent_names, 2, bus_id); 108 + if (IS_ERR(hw)) 109 + continue; 110 + 111 + of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw); 112 + } 113 + } 114 + 115 + CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux", 116 + of_sama5d2_clk_i2s_mux_setup);
+1 -1
drivers/clk/clk-aspeed.c
··· 109 109 [ASPEED_CLK_GATE_RSACLK] = { 24, -1, "rsaclk-gate", NULL, 0 }, /* RSA */ 110 110 [ASPEED_CLK_GATE_UART3CLK] = { 25, -1, "uart3clk-gate", "uart", 0 }, /* UART3 */ 111 111 [ASPEED_CLK_GATE_UART4CLK] = { 26, -1, "uart4clk-gate", "uart", 0 }, /* UART4 */ 112 - [ASPEED_CLK_GATE_SDCLKCLK] = { 27, 16, "sdclk-gate", NULL, 0 }, /* SDIO/SD */ 112 + [ASPEED_CLK_GATE_SDCLK] = { 27, 16, "sdclk-gate", NULL, 0 }, /* SDIO/SD */ 113 113 [ASPEED_CLK_GATE_LHCCLK] = { 28, -1, "lhclk-gate", "lhclk", 0 }, /* LPC master/LPC+ */ 114 114 }; 115 115
+1 -4
drivers/clk/clk-cs2000-cp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * CS2000 -- CIRRUS LOGIC Fractional-N Clock Synthesizer & Clock Multiplier 3 4 * 4 5 * Copyright (C) 2015 Renesas Electronics Corporation 5 6 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify 8 - * it under the terms of the GNU General Public License version 2 as 9 - * published by the Free Software Foundation. 10 7 */ 11 8 #include <linux/clk-provider.h> 12 9 #include <linux/delay.h>
+8 -1
drivers/clk/clk-fixed-factor.c
··· 177 177 178 178 clk = clk_register_fixed_factor(NULL, clk_name, parent_name, flags, 179 179 mult, div); 180 - if (IS_ERR(clk)) 180 + if (IS_ERR(clk)) { 181 + /* 182 + * If parent clock is not registered, registration would fail. 183 + * Clear OF_POPULATED flag so that clock registration can be 184 + * attempted again from probe function. 185 + */ 186 + of_node_clear_flag(node, OF_POPULATED); 181 187 return clk; 188 + } 182 189 183 190 ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); 184 191 if (ret) {
+387
drivers/clk/clk-max9485.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/module.h> 4 + #include <linux/kernel.h> 5 + #include <linux/clk.h> 6 + #include <linux/clk-provider.h> 7 + #include <linux/err.h> 8 + #include <linux/errno.h> 9 + #include <linux/gpio/consumer.h> 10 + #include <linux/i2c.h> 11 + #include <linux/regulator/consumer.h> 12 + 13 + #include <dt-bindings/clock/maxim,max9485.h> 14 + 15 + #define MAX9485_NUM_CLKS 4 16 + 17 + /* This chip has only one register of 8 bit width. */ 18 + 19 + #define MAX9485_FS_12KHZ (0 << 0) 20 + #define MAX9485_FS_32KHZ (1 << 0) 21 + #define MAX9485_FS_44_1KHZ (2 << 0) 22 + #define MAX9485_FS_48KHZ (3 << 0) 23 + 24 + #define MAX9485_SCALE_256 (0 << 2) 25 + #define MAX9485_SCALE_384 (1 << 2) 26 + #define MAX9485_SCALE_768 (2 << 2) 27 + 28 + #define MAX9485_DOUBLE BIT(4) 29 + #define MAX9485_CLKOUT1_ENABLE BIT(5) 30 + #define MAX9485_CLKOUT2_ENABLE BIT(6) 31 + #define MAX9485_MCLK_ENABLE BIT(7) 32 + #define MAX9485_FREQ_MASK 0x1f 33 + 34 + struct max9485_rate { 35 + unsigned long out; 36 + u8 reg_value; 37 + }; 38 + 39 + /* 40 + * Ordered by frequency. For frequency the hardware can generate with 41 + * multiple settings, the one with lowest jitter is listed first. 42 + */ 43 + static const struct max9485_rate max9485_rates[] = { 44 + { 3072000, MAX9485_FS_12KHZ | MAX9485_SCALE_256 }, 45 + { 4608000, MAX9485_FS_12KHZ | MAX9485_SCALE_384 }, 46 + { 8192000, MAX9485_FS_32KHZ | MAX9485_SCALE_256 }, 47 + { 9126000, MAX9485_FS_12KHZ | MAX9485_SCALE_768 }, 48 + { 11289600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 }, 49 + { 12288000, MAX9485_FS_48KHZ | MAX9485_SCALE_256 }, 50 + { 12288000, MAX9485_FS_32KHZ | MAX9485_SCALE_384 }, 51 + { 16384000, MAX9485_FS_32KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, 52 + { 16934400, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 }, 53 + { 18384000, MAX9485_FS_48KHZ | MAX9485_SCALE_384 }, 54 + { 22579200, MAX9485_FS_44_1KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, 55 + { 24576000, MAX9485_FS_48KHZ | MAX9485_SCALE_256 | MAX9485_DOUBLE }, 56 + { 24576000, MAX9485_FS_32KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, 57 + { 24576000, MAX9485_FS_32KHZ | MAX9485_SCALE_768 }, 58 + { 33868800, MAX9485_FS_44_1KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, 59 + { 33868800, MAX9485_FS_44_1KHZ | MAX9485_SCALE_768 }, 60 + { 36864000, MAX9485_FS_48KHZ | MAX9485_SCALE_384 | MAX9485_DOUBLE }, 61 + { 36864000, MAX9485_FS_48KHZ | MAX9485_SCALE_768 }, 62 + { 49152000, MAX9485_FS_32KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, 63 + { 67737600, MAX9485_FS_44_1KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, 64 + { 73728000, MAX9485_FS_48KHZ | MAX9485_SCALE_768 | MAX9485_DOUBLE }, 65 + { } /* sentinel */ 66 + }; 67 + 68 + struct max9485_driver_data; 69 + 70 + struct max9485_clk_hw { 71 + struct clk_hw hw; 72 + struct clk_init_data init; 73 + u8 enable_bit; 74 + struct max9485_driver_data *drvdata; 75 + }; 76 + 77 + struct max9485_driver_data { 78 + struct clk *xclk; 79 + struct i2c_client *client; 80 + u8 reg_value; 81 + struct regulator *supply; 82 + struct gpio_desc *reset_gpio; 83 + struct max9485_clk_hw hw[MAX9485_NUM_CLKS]; 84 + }; 85 + 86 + static inline struct max9485_clk_hw *to_max9485_clk(struct clk_hw *hw) 87 + { 88 + return container_of(hw, struct max9485_clk_hw, hw); 89 + } 90 + 91 + static int max9485_update_bits(struct max9485_driver_data *drvdata, 92 + u8 mask, u8 value) 93 + { 94 + int ret; 95 + 96 + drvdata->reg_value &= ~mask; 97 + drvdata->reg_value |= value; 98 + 99 + dev_dbg(&drvdata->client->dev, 100 + "updating mask 0x%02x value 0x%02x -> 0x%02x\n", 101 + mask, value, drvdata->reg_value); 102 + 103 + ret = i2c_master_send(drvdata->client, 104 + &drvdata->reg_value, 105 + sizeof(drvdata->reg_value)); 106 + 107 + return ret < 0 ? ret : 0; 108 + } 109 + 110 + static int max9485_clk_prepare(struct clk_hw *hw) 111 + { 112 + struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); 113 + 114 + return max9485_update_bits(clk_hw->drvdata, 115 + clk_hw->enable_bit, 116 + clk_hw->enable_bit); 117 + } 118 + 119 + static void max9485_clk_unprepare(struct clk_hw *hw) 120 + { 121 + struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); 122 + 123 + max9485_update_bits(clk_hw->drvdata, clk_hw->enable_bit, 0); 124 + } 125 + 126 + /* 127 + * CLKOUT - configurable clock output 128 + */ 129 + static int max9485_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 130 + unsigned long parent_rate) 131 + { 132 + struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); 133 + const struct max9485_rate *entry; 134 + 135 + for (entry = max9485_rates; entry->out != 0; entry++) 136 + if (entry->out == rate) 137 + break; 138 + 139 + if (entry->out == 0) 140 + return -EINVAL; 141 + 142 + return max9485_update_bits(clk_hw->drvdata, 143 + MAX9485_FREQ_MASK, 144 + entry->reg_value); 145 + } 146 + 147 + static unsigned long max9485_clkout_recalc_rate(struct clk_hw *hw, 148 + unsigned long parent_rate) 149 + { 150 + struct max9485_clk_hw *clk_hw = to_max9485_clk(hw); 151 + struct max9485_driver_data *drvdata = clk_hw->drvdata; 152 + u8 val = drvdata->reg_value & MAX9485_FREQ_MASK; 153 + const struct max9485_rate *entry; 154 + 155 + for (entry = max9485_rates; entry->out != 0; entry++) 156 + if (val == entry->reg_value) 157 + return entry->out; 158 + 159 + return 0; 160 + } 161 + 162 + static long max9485_clkout_round_rate(struct clk_hw *hw, unsigned long rate, 163 + unsigned long *parent_rate) 164 + { 165 + const struct max9485_rate *curr, *prev = NULL; 166 + 167 + for (curr = max9485_rates; curr->out != 0; curr++) { 168 + /* Exact matches */ 169 + if (curr->out == rate) 170 + return rate; 171 + 172 + /* 173 + * Find the first entry that has a frequency higher than the 174 + * requested one. 175 + */ 176 + if (curr->out > rate) { 177 + unsigned int mid; 178 + 179 + /* 180 + * If this is the first entry, clamp the value to the 181 + * lowest possible frequency. 182 + */ 183 + if (!prev) 184 + return curr->out; 185 + 186 + /* 187 + * Otherwise, determine whether the previous entry or 188 + * current one is closer. 189 + */ 190 + mid = prev->out + ((curr->out - prev->out) / 2); 191 + 192 + return (mid > rate) ? prev->out : curr->out; 193 + } 194 + 195 + prev = curr; 196 + } 197 + 198 + /* If the last entry was still too high, clamp the value */ 199 + return prev->out; 200 + } 201 + 202 + struct max9485_clk { 203 + const char *name; 204 + int parent_index; 205 + const struct clk_ops ops; 206 + u8 enable_bit; 207 + }; 208 + 209 + static const struct max9485_clk max9485_clks[MAX9485_NUM_CLKS] = { 210 + [MAX9485_MCLKOUT] = { 211 + .name = "mclkout", 212 + .parent_index = -1, 213 + .enable_bit = MAX9485_MCLK_ENABLE, 214 + .ops = { 215 + .prepare = max9485_clk_prepare, 216 + .unprepare = max9485_clk_unprepare, 217 + }, 218 + }, 219 + [MAX9485_CLKOUT] = { 220 + .name = "clkout", 221 + .parent_index = -1, 222 + .ops = { 223 + .set_rate = max9485_clkout_set_rate, 224 + .round_rate = max9485_clkout_round_rate, 225 + .recalc_rate = max9485_clkout_recalc_rate, 226 + }, 227 + }, 228 + [MAX9485_CLKOUT1] = { 229 + .name = "clkout1", 230 + .parent_index = MAX9485_CLKOUT, 231 + .enable_bit = MAX9485_CLKOUT1_ENABLE, 232 + .ops = { 233 + .prepare = max9485_clk_prepare, 234 + .unprepare = max9485_clk_unprepare, 235 + }, 236 + }, 237 + [MAX9485_CLKOUT2] = { 238 + .name = "clkout2", 239 + .parent_index = MAX9485_CLKOUT, 240 + .enable_bit = MAX9485_CLKOUT2_ENABLE, 241 + .ops = { 242 + .prepare = max9485_clk_prepare, 243 + .unprepare = max9485_clk_unprepare, 244 + }, 245 + }, 246 + }; 247 + 248 + static struct clk_hw * 249 + max9485_of_clk_get(struct of_phandle_args *clkspec, void *data) 250 + { 251 + struct max9485_driver_data *drvdata = data; 252 + unsigned int idx = clkspec->args[0]; 253 + 254 + return &drvdata->hw[idx].hw; 255 + } 256 + 257 + static int max9485_i2c_probe(struct i2c_client *client, 258 + const struct i2c_device_id *id) 259 + { 260 + struct max9485_driver_data *drvdata; 261 + struct device *dev = &client->dev; 262 + const char *xclk_name; 263 + int i, ret; 264 + 265 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 266 + if (!drvdata) 267 + return -ENOMEM; 268 + 269 + drvdata->xclk = devm_clk_get(dev, "xclk"); 270 + if (IS_ERR(drvdata->xclk)) 271 + return PTR_ERR(drvdata->xclk); 272 + 273 + xclk_name = __clk_get_name(drvdata->xclk); 274 + 275 + drvdata->supply = devm_regulator_get(dev, "vdd"); 276 + if (IS_ERR(drvdata->supply)) 277 + return PTR_ERR(drvdata->supply); 278 + 279 + ret = regulator_enable(drvdata->supply); 280 + if (ret < 0) 281 + return ret; 282 + 283 + drvdata->reset_gpio = 284 + devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); 285 + if (IS_ERR(drvdata->reset_gpio)) 286 + return PTR_ERR(drvdata->reset_gpio); 287 + 288 + i2c_set_clientdata(client, drvdata); 289 + drvdata->client = client; 290 + 291 + ret = i2c_master_recv(drvdata->client, &drvdata->reg_value, 292 + sizeof(drvdata->reg_value)); 293 + if (ret < 0) { 294 + dev_warn(dev, "Unable to read device register: %d\n", ret); 295 + return ret; 296 + } 297 + 298 + for (i = 0; i < MAX9485_NUM_CLKS; i++) { 299 + int parent_index = max9485_clks[i].parent_index; 300 + const char *name; 301 + 302 + if (of_property_read_string_index(dev->of_node, 303 + "clock-output-names", 304 + i, &name) == 0) { 305 + drvdata->hw[i].init.name = name; 306 + } else { 307 + drvdata->hw[i].init.name = max9485_clks[i].name; 308 + } 309 + 310 + drvdata->hw[i].init.ops = &max9485_clks[i].ops; 311 + drvdata->hw[i].init.num_parents = 1; 312 + drvdata->hw[i].init.flags = 0; 313 + 314 + if (parent_index > 0) { 315 + drvdata->hw[i].init.parent_names = 316 + &drvdata->hw[parent_index].init.name; 317 + drvdata->hw[i].init.flags |= CLK_SET_RATE_PARENT; 318 + } else { 319 + drvdata->hw[i].init.parent_names = &xclk_name; 320 + } 321 + 322 + drvdata->hw[i].enable_bit = max9485_clks[i].enable_bit; 323 + drvdata->hw[i].hw.init = &drvdata->hw[i].init; 324 + drvdata->hw[i].drvdata = drvdata; 325 + 326 + ret = devm_clk_hw_register(dev, &drvdata->hw[i].hw); 327 + if (ret < 0) 328 + return ret; 329 + } 330 + 331 + return devm_of_clk_add_hw_provider(dev, max9485_of_clk_get, drvdata); 332 + } 333 + 334 + static int __maybe_unused max9485_suspend(struct device *dev) 335 + { 336 + struct i2c_client *client = to_i2c_client(dev); 337 + struct max9485_driver_data *drvdata = i2c_get_clientdata(client); 338 + 339 + gpiod_set_value_cansleep(drvdata->reset_gpio, 0); 340 + 341 + return 0; 342 + } 343 + 344 + static int __maybe_unused max9485_resume(struct device *dev) 345 + { 346 + struct i2c_client *client = to_i2c_client(dev); 347 + struct max9485_driver_data *drvdata = i2c_get_clientdata(client); 348 + int ret; 349 + 350 + gpiod_set_value_cansleep(drvdata->reset_gpio, 1); 351 + 352 + ret = i2c_master_send(client, &drvdata->reg_value, 353 + sizeof(drvdata->reg_value)); 354 + 355 + return ret < 0 ? ret : 0; 356 + } 357 + 358 + static const struct dev_pm_ops max9485_pm_ops = { 359 + SET_SYSTEM_SLEEP_PM_OPS(max9485_suspend, max9485_resume) 360 + }; 361 + 362 + static const struct of_device_id max9485_dt_ids[] = { 363 + { .compatible = "maxim,max9485", }, 364 + { } 365 + }; 366 + MODULE_DEVICE_TABLE(of, max9485_dt_ids); 367 + 368 + static const struct i2c_device_id max9485_i2c_ids[] = { 369 + { .name = "max9485", }, 370 + { } 371 + }; 372 + MODULE_DEVICE_TABLE(i2c, max9485_i2c_ids); 373 + 374 + static struct i2c_driver max9485_driver = { 375 + .driver = { 376 + .name = "max9485", 377 + .pm = &max9485_pm_ops, 378 + .of_match_table = max9485_dt_ids, 379 + }, 380 + .probe = max9485_i2c_probe, 381 + .id_table = max9485_i2c_ids, 382 + }; 383 + module_i2c_driver(max9485_driver); 384 + 385 + MODULE_AUTHOR("Daniel Mack <daniel@zonque.org>"); 386 + MODULE_DESCRIPTION("MAX9485 Programmable Audio Clock Generator"); 387 + MODULE_LICENSE("GPL v2");
+2 -3
drivers/clk/clk-scmi.c
··· 38 38 static long scmi_clk_round_rate(struct clk_hw *hw, unsigned long rate, 39 39 unsigned long *parent_rate) 40 40 { 41 - int step; 42 41 u64 fmin, fmax, ftmp; 43 42 struct scmi_clk *clk = to_scmi_clk(hw); 44 43 ··· 59 60 60 61 ftmp = rate - fmin; 61 62 ftmp += clk->info->range.step_size - 1; /* to round up */ 62 - step = do_div(ftmp, clk->info->range.step_size); 63 + do_div(ftmp, clk->info->range.step_size); 63 64 64 - return step * clk->info->range.step_size + fmin; 65 + return ftmp * clk->info->range.step_size + fmin; 65 66 } 66 67 67 68 static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+37 -1
drivers/clk/clk-si514.c
··· 74 74 SI514_CONTROL_OE, enable ? SI514_CONTROL_OE : 0); 75 75 } 76 76 77 + static int si514_prepare(struct clk_hw *hw) 78 + { 79 + struct clk_si514 *data = to_clk_si514(hw); 80 + 81 + return si514_enable_output(data, true); 82 + } 83 + 84 + static void si514_unprepare(struct clk_hw *hw) 85 + { 86 + struct clk_si514 *data = to_clk_si514(hw); 87 + 88 + si514_enable_output(data, false); 89 + } 90 + 91 + static int si514_is_prepared(struct clk_hw *hw) 92 + { 93 + struct clk_si514 *data = to_clk_si514(hw); 94 + unsigned int val; 95 + int err; 96 + 97 + err = regmap_read(data->regmap, SI514_REG_CONTROL, &val); 98 + if (err < 0) 99 + return err; 100 + 101 + return !!(val & SI514_CONTROL_OE); 102 + } 103 + 77 104 /* Retrieve clock multiplier and dividers from hardware */ 78 105 static int si514_get_muldiv(struct clk_si514 *data, 79 106 struct clk_si514_muldiv *settings) ··· 262 235 { 263 236 struct clk_si514 *data = to_clk_si514(hw); 264 237 struct clk_si514_muldiv settings; 238 + unsigned int old_oe_state; 265 239 int err; 266 240 267 241 err = si514_calc_muldiv(&settings, rate); 242 + if (err) 243 + return err; 244 + 245 + err = regmap_read(data->regmap, SI514_REG_CONTROL, &old_oe_state); 268 246 if (err) 269 247 return err; 270 248 ··· 287 255 /* Applying a new frequency can take up to 10ms */ 288 256 usleep_range(10000, 12000); 289 257 290 - si514_enable_output(data, true); 258 + if (old_oe_state & SI514_CONTROL_OE) 259 + si514_enable_output(data, true); 291 260 292 261 return err; 293 262 } 294 263 295 264 static const struct clk_ops si514_clk_ops = { 265 + .prepare = si514_prepare, 266 + .unprepare = si514_unprepare, 267 + .is_prepared = si514_is_prepared, 296 268 .recalc_rate = si514_recalc_rate, 297 269 .round_rate = si514_round_rate, 298 270 .set_rate = si514_set_rate,
+37 -1
drivers/clk/clk-si544.c
··· 86 86 SI544_OE_STATE_ODC_OE, enable ? SI544_OE_STATE_ODC_OE : 0); 87 87 } 88 88 89 + static int si544_prepare(struct clk_hw *hw) 90 + { 91 + struct clk_si544 *data = to_clk_si544(hw); 92 + 93 + return si544_enable_output(data, true); 94 + } 95 + 96 + static void si544_unprepare(struct clk_hw *hw) 97 + { 98 + struct clk_si544 *data = to_clk_si544(hw); 99 + 100 + si544_enable_output(data, false); 101 + } 102 + 103 + static int si544_is_prepared(struct clk_hw *hw) 104 + { 105 + struct clk_si544 *data = to_clk_si544(hw); 106 + unsigned int val; 107 + int err; 108 + 109 + err = regmap_read(data->regmap, SI544_REG_OE_STATE, &val); 110 + if (err < 0) 111 + return err; 112 + 113 + return !!(val & SI544_OE_STATE_ODC_OE); 114 + } 115 + 89 116 /* Retrieve clock multiplier and dividers from hardware */ 90 117 static int si544_get_muldiv(struct clk_si544 *data, 91 118 struct clk_si544_muldiv *settings) ··· 300 273 { 301 274 struct clk_si544 *data = to_clk_si544(hw); 302 275 struct clk_si544_muldiv settings; 276 + unsigned int old_oe_state; 303 277 int err; 304 278 305 279 if (!is_valid_frequency(data, rate)) 306 280 return -EINVAL; 307 281 308 282 err = si544_calc_muldiv(&settings, rate); 283 + if (err) 284 + return err; 285 + 286 + err = regmap_read(data->regmap, SI544_REG_OE_STATE, &old_oe_state); 309 287 if (err) 310 288 return err; 311 289 ··· 335 303 /* Applying a new frequency can take up to 10ms */ 336 304 usleep_range(10000, 12000); 337 305 338 - si544_enable_output(data, true); 306 + if (old_oe_state & SI544_OE_STATE_ODC_OE) 307 + si544_enable_output(data, true); 339 308 340 309 return err; 341 310 } 342 311 343 312 static const struct clk_ops si544_clk_ops = { 313 + .prepare = si544_prepare, 314 + .unprepare = si544_unprepare, 315 + .is_prepared = si544_is_prepared, 344 316 .recalc_rate = si544_recalc_rate, 345 317 .round_rate = si544_round_rate, 346 318 .set_rate = si544_set_rate,
+16 -3
drivers/clk/clk.c
··· 691 691 "Unpreparing critical %s\n", core->name)) 692 692 return; 693 693 694 + if (core->flags & CLK_SET_RATE_GATE) 695 + clk_core_rate_unprotect(core); 696 + 694 697 if (--core->prepare_count > 0) 695 698 return; 696 699 ··· 767 764 } 768 765 769 766 core->prepare_count++; 767 + 768 + /* 769 + * CLK_SET_RATE_GATE is a special case of clock protection 770 + * Instead of a consumer claiming exclusive rate control, it is 771 + * actually the provider which prevents any consumer from making any 772 + * operation which could result in a rate change or rate glitch while 773 + * the clock is prepared. 774 + */ 775 + if (core->flags & CLK_SET_RATE_GATE) 776 + clk_core_rate_protect(core); 770 777 771 778 return 0; 772 779 unprepare: ··· 1899 1886 1900 1887 /* fail on a direct rate set of a protected provider */ 1901 1888 if (clk_core_rate_is_protected(core)) 1902 - return -EBUSY; 1903 - 1904 - if ((core->flags & CLK_SET_RATE_GATE) && core->prepare_count) 1905 1889 return -EBUSY; 1906 1890 1907 1891 /* calculate new rates and get the topmost changed clock */ ··· 3132 3122 return clk; 3133 3123 } 3134 3124 3125 + /* keep in sync with __clk_put */ 3135 3126 void __clk_free_clk(struct clk *clk) 3136 3127 { 3137 3128 clk_prepare_lock(); ··· 3512 3501 return 1; 3513 3502 } 3514 3503 3504 + /* keep in sync with __clk_free_clk */ 3515 3505 void __clk_put(struct clk *clk) 3516 3506 { 3517 3507 struct module *owner; ··· 3546 3534 3547 3535 module_put(owner); 3548 3536 3537 + kfree_const(clk->con_id); 3549 3538 kfree(clk); 3550 3539 } 3551 3540
+15 -29
drivers/clk/imx/clk-imx51-imx53.c
··· 16 16 #include <linux/of.h> 17 17 #include <linux/of_address.h> 18 18 #include <linux/of_irq.h> 19 + #include <linux/sizes.h> 19 20 #include <soc/imx/revision.h> 20 21 #include <dt-bindings/clock/imx5-clock.h> 21 22 ··· 176 175 clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, 177 176 per_root_sel, ARRAY_SIZE(per_root_sel)); 178 177 clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); 179 - clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); 180 - clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); 181 - clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); 182 - clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); 183 - clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); 184 - clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); 185 - clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); 178 + clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2_flags("ahb_max", "ahb", MXC_CCM_CCGR0, 28, CLK_IS_CRITICAL); 179 + clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", MXC_CCM_CCGR0, 24, CLK_IS_CRITICAL); 180 + clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", MXC_CCM_CCGR0, 26, CLK_IS_CRITICAL); 181 + clk[IMX5_CLK_TMAX1] = imx_clk_gate2_flags("tmax1", "ahb", MXC_CCM_CCGR1, 0, CLK_IS_CRITICAL); 182 + clk[IMX5_CLK_TMAX2] = imx_clk_gate2_flags("tmax2", "ahb", MXC_CCM_CCGR1, 2, CLK_IS_CRITICAL); 183 + clk[IMX5_CLK_TMAX3] = imx_clk_gate2_flags("tmax3", "ahb", MXC_CCM_CCGR1, 4, CLK_IS_CRITICAL); 184 + clk[IMX5_CLK_SPBA] = imx_clk_gate2_flags("spba", "ipg", MXC_CCM_CCGR5, 0, CLK_IS_CRITICAL); 186 185 clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); 187 186 clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); 188 187 clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); ··· 253 252 clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); 254 253 clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); 255 254 clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); 256 - clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); 257 - clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); 255 + clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2_flags("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14, CLK_IS_CRITICAL); 256 + clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2_flags("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16, CLK_IS_CRITICAL); 258 257 clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); 259 258 clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); 260 259 clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); ··· 268 267 clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); 269 268 clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); 270 269 clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); 271 - clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); 270 + clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2_flags("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24, CLK_IS_CRITICAL); 272 271 273 272 clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); 274 273 clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); ··· 317 316 318 317 /* move usb phy clk to 24MHz */ 319 318 clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); 320 - 321 - clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]); 322 - clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */ 323 - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]); 324 - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */ 325 - clk_prepare_enable(clk[IMX5_CLK_SPBA]); 326 - clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */ 327 - clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */ 328 - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]); 329 - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]); 330 - clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]); 331 - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]); 332 - clk_prepare_enable(clk[IMX5_CLK_TMAX1]); 333 - clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ 334 - clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ 335 319 } 336 320 337 321 static void __init mx50_clocks_init(struct device_node *np) ··· 428 442 clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); 429 443 clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); 430 444 clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); 431 - clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); 432 - clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); 433 - clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); 434 - clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); 445 + clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2_flags("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6, CLK_IS_CRITICAL); 446 + clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2_flags("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8, CLK_IS_CRITICAL); 447 + clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2_flags("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10, CLK_IS_CRITICAL); 448 + clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2_flags("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12, CLK_IS_CRITICAL); 435 449 clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, 436 450 mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); 437 451 clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
+3 -13
drivers/clk/imx/clk-imx6q.c
··· 65 65 static const char *ecspi_sels[] = { "pll3_60m", "osc", }; 66 66 static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", }; 67 67 static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", 68 - "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", 68 + "video_27m", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", 69 69 "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; 70 70 static const char *cko2_sels[] = { 71 71 "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", ··· 95 95 96 96 static struct clk *clk[IMX6QDL_CLK_END]; 97 97 static struct clk_onecell_data clk_data; 98 - 99 - static unsigned int const clks_init_on[] __initconst = { 100 - IMX6QDL_CLK_MMDC_CH0_AXI, 101 - IMX6QDL_CLK_ROM, 102 - IMX6QDL_CLK_ARM, 103 - }; 104 98 105 99 static struct clk_div_table clk_enet_ref_table[] = { 106 100 { .val = 0, .div = 20, }, ··· 411 417 { 412 418 struct device_node *np; 413 419 void __iomem *anatop_base, *base; 414 - int i; 415 420 int ret; 416 421 417 422 clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); ··· 787 794 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "mlb_podf", base + 0x74, 18); 788 795 else 789 796 clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); 790 - clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); 797 + clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL); 791 798 clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); 792 799 clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); 793 800 clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); ··· 801 808 clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); 802 809 clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); 803 810 clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); 804 - clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); 811 + clk[IMX6QDL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); 805 812 clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); 806 813 clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); 807 814 clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); ··· 870 877 * So choose pll2_pfd2_396m as enfc_sel's parent. 871 878 */ 872 879 clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]); 873 - 874 - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 875 - clk_prepare_enable(clk[clks_init_on[i]]); 876 880 877 881 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { 878 882 clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]);
-12
drivers/clk/imx/clk-imx6sl.c
··· 104 104 static void __iomem *ccm_base; 105 105 static void __iomem *anatop_base; 106 106 107 - static const u32 clks_init_on[] __initconst = { 108 - IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT, 109 - }; 110 - 111 107 /* 112 108 * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken 113 109 * during WAIT mode entry process could cause cache memory ··· 191 195 { 192 196 struct device_node *np; 193 197 void __iomem *base; 194 - int i; 195 198 int ret; 196 199 197 200 clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); ··· 420 425 if (ret) 421 426 pr_warn("%s: failed to set AHB clock rate %d!\n", 422 427 __func__, ret); 423 - 424 - /* 425 - * Make sure those always on clocks are enabled to maintain the correct 426 - * usecount and enabling/disabling of parent PLLs. 427 - */ 428 - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 429 - clk_prepare_enable(clks[clks_init_on[i]]); 430 428 431 429 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { 432 430 clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
+7
drivers/clk/imx/clk-imx6sll.c
··· 92 92 93 93 np = of_find_compatible_node(NULL, NULL, "fsl,imx6sll-anatop"); 94 94 base = of_iomap(np, 0); 95 + of_node_put(np); 95 96 WARN_ON(!base); 96 97 97 98 /* Do not bypass PLLs initially */ ··· 254 253 clks[IMX6SLL_CLK_DCP] = imx_clk_gate2("dcp", "ahb", base + 0x68, 10); 255 254 clks[IMX6SLL_CLK_UART2_IPG] = imx_clk_gate2("uart2_ipg", "ipg", base + 0x68, 28); 256 255 clks[IMX6SLL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); 256 + clks[IMX6SLL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); 257 257 258 258 /* CCGR1 */ 259 259 clks[IMX6SLL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); ··· 269 267 clks[IMX6SLL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); 270 268 clks[IMX6SLL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); 271 269 clks[IMX6SLL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serail", "uart_podf", base + 0x6c, 24); 270 + clks[IMX6SLL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); 271 + clks[IMX6SLL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); 272 272 273 273 /* CCGR2 */ 274 + clks[IMX6SLL_CLK_GPIO6] = imx_clk_gate2("gpio6", "ipg", base + 0x70, 0); 274 275 clks[IMX6SLL_CLK_CSI] = imx_clk_gate2("csi", "axi", base + 0x70, 2); 275 276 clks[IMX6SLL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); 276 277 clks[IMX6SLL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); 277 278 clks[IMX6SLL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); 278 279 clks[IMX6SLL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); 280 + clks[IMX6SLL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); 279 281 clks[IMX6SLL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); 280 282 clks[IMX6SLL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); 281 283 ··· 289 283 clks[IMX6SLL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_aclk", "axi", base + 0x74, 4); 290 284 clks[IMX6SLL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_podf", base + 0x74, 4); 291 285 clks[IMX6SLL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); 286 + clks[IMX6SLL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); 292 287 clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); 293 288 clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); 294 289 clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
+15 -26
drivers/clk/imx/clk-imx6sx.c
··· 92 92 static struct clk *clks[IMX6SX_CLK_CLK_END]; 93 93 static struct clk_onecell_data clk_data; 94 94 95 - static int const clks_init_on[] __initconst = { 96 - IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3, 97 - IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3, 98 - IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG, 99 - IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM, 100 - IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_TZASC1, 101 - }; 102 - 103 95 static const struct clk_div_table clk_enet_ref_table[] = { 104 96 { .val = 0, .div = 20, }, 105 97 { .val = 1, .div = 10, }, ··· 134 142 { 135 143 struct device_node *np; 136 144 void __iomem *base; 137 - int i; 138 145 139 146 clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 140 147 ··· 323 332 clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); 324 333 clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); 325 334 clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); 326 - clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); 335 + clks[IMX6SX_CLK_PERCLK] = imx_clk_divider_flags("perclk", "perclk_sel", base + 0x1c, 0, 6, CLK_IS_CRITICAL); 327 336 clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); 328 337 clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); 329 338 clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); ··· 371 380 372 381 /* name parent_name reg shift */ 373 382 /* CCGR0 */ 374 - clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); 375 - clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); 383 + clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); 384 + clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); 376 385 clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); 377 386 clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); 378 387 clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); ··· 385 394 clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); 386 395 clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24); 387 396 clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26); 388 - clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30); 397 + clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2_flags("aips_tz3", "ahb", base + 0x68, 30, CLK_IS_CRITICAL); 389 398 390 399 /* CCGR1 */ 391 400 clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); ··· 398 407 clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); 399 408 clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); 400 409 clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); 401 - clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18); 410 + clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2_flags("wakeup", "ipg", base + 0x6c, 18, CLK_IS_CRITICAL); 402 411 clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20); 403 412 clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); 404 413 clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); 414 + clks[IMX6SX_CLK_OCRAM_S] = imx_clk_gate2("ocram_s", "ahb", base + 0x6c, 28); 405 415 clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30); 406 416 407 417 /* CCGR2 */ ··· 412 420 clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); 413 421 clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); 414 422 clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); 415 - clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16); 416 - clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18); 417 - clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20); 418 - clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22); 423 + clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2_flags("ipmux1", "ahb", base + 0x70, 16, CLK_IS_CRITICAL); 424 + clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2_flags("ipmux2", "ahb", base + 0x70, 18, CLK_IS_CRITICAL); 425 + clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2_flags("ipmux3", "ahb", base + 0x70, 20, CLK_IS_CRITICAL); 426 + clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2_flags("tzasc1", "mmdc_podf", base + 0x70, 22, CLK_IS_CRITICAL); 419 427 clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28); 420 428 clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30); 421 429 ··· 429 437 clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); 430 438 clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); 431 439 clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); 432 - clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20); 433 - clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24); 434 - clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); 440 + clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); 441 + clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); 442 + clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL); 435 443 436 444 /* CCGR4 */ 437 445 clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0); 438 446 clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10); 439 447 clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); 440 - clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14); 448 + clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2_flags("per2_main", "ahb", base + 0x78, 14, CLK_IS_CRITICAL); 441 449 clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); 442 450 clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); 443 451 clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); ··· 448 456 clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); 449 457 450 458 /* CCGR5 */ 451 - clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); 459 + clks[IMX6SX_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); 452 460 clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); 453 461 clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); 454 462 clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); ··· 493 501 clk_data.clks = clks; 494 502 clk_data.clk_num = ARRAY_SIZE(clks); 495 503 of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 496 - 497 - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 498 - clk_prepare_enable(clks[clks_init_on[i]]); 499 504 500 505 if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { 501 506 clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]);
+12 -17
drivers/clk/imx/clk-imx6ul.c
··· 79 79 static struct clk *clks[IMX6UL_CLK_END]; 80 80 static struct clk_onecell_data clk_data; 81 81 82 - static int const clks_init_on[] __initconst = { 83 - IMX6UL_CLK_AIPSTZ1, IMX6UL_CLK_AIPSTZ2, 84 - IMX6UL_CLK_AXI, IMX6UL_CLK_ARM, IMX6UL_CLK_ROM, 85 - IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, 86 - }; 87 - 88 82 static const struct clk_div_table clk_enet_ref_table[] = { 89 83 { .val = 0, .div = 20, }, 90 84 { .val = 1, .div = 10, }, ··· 123 129 { 124 130 struct device_node *np; 125 131 void __iomem *base; 126 - int i; 127 132 128 133 clks[IMX6UL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 129 134 ··· 135 142 136 143 np = of_find_compatible_node(NULL, NULL, "fsl,imx6ul-anatop"); 137 144 base = of_iomap(np, 0); 145 + of_node_put(np); 138 146 WARN_ON(!base); 139 147 140 148 clks[IMX6UL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); ··· 330 336 clks[IMX6UL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); 331 337 332 338 /* CCGR0 */ 333 - clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); 334 - clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); 339 + clks[IMX6UL_CLK_AIPSTZ1] = imx_clk_gate2_flags("aips_tz1", "ahb", base + 0x68, 0, CLK_IS_CRITICAL); 340 + clks[IMX6UL_CLK_AIPSTZ2] = imx_clk_gate2_flags("aips_tz2", "ahb", base + 0x68, 2, CLK_IS_CRITICAL); 335 341 clks[IMX6UL_CLK_APBHDMA] = imx_clk_gate2("apbh_dma", "bch_podf", base + 0x68, 4); 336 342 clks[IMX6UL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); 337 343 clks[IMX6UL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); ··· 354 360 clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28); 355 361 if (clk_on_imx6ull()) 356 362 clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x80, 18); 363 + clks[IMX6UL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30); 357 364 358 365 /* CCGR1 */ 359 366 clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); ··· 371 376 clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22); 372 377 clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24); 373 378 clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24); 379 + clks[IMX6UL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26); 380 + clks[IMX6UL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30); 374 381 375 382 /* CCGR2 */ 376 383 if (clk_on_imx6ull()) { ··· 386 389 clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); 387 390 clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); 388 391 clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14); 392 + clks[IMX6UL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26); 389 393 clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28); 390 394 clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30); 391 395 ··· 403 405 clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6); 404 406 clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6); 405 407 clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10); 408 + clks[IMX6UL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12); 406 409 clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); 407 410 clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); 408 - clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20); 409 - clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24); 410 - clks[IMX6UL_CLK_AXI] = imx_clk_gate("axi", "axi_podf", base + 0x74, 28); 411 + clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); 412 + clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); 413 + clks[IMX6UL_CLK_AXI] = imx_clk_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL); 411 414 412 415 /* CCGR4 */ 413 416 clks[IMX6UL_CLK_PER_BCH] = imx_clk_gate2("per_bch", "bch_podf", base + 0x78, 12); ··· 422 423 clks[IMX6UL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "bch_podf", base + 0x78, 30); 423 424 424 425 /* CCGR5 */ 425 - clks[IMX6UL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); 426 + clks[IMX6UL_CLK_ROM] = imx_clk_gate2_flags("rom", "ahb", base + 0x7c, 0, CLK_IS_CRITICAL); 426 427 clks[IMX6UL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); 427 428 clks[IMX6UL_CLK_KPP] = imx_clk_gate2("kpp", "ipg", base + 0x7c, 8); 428 429 clks[IMX6UL_CLK_WDOG2] = imx_clk_gate2("wdog2", "ipg", base + 0x7c, 10); ··· 495 496 clk_set_rate(clks[IMX6UL_CLK_ENET_REF], 50000000); 496 497 clk_set_rate(clks[IMX6UL_CLK_ENET2_REF], 50000000); 497 498 clk_set_rate(clks[IMX6UL_CLK_CSI], 24000000); 498 - 499 - /* keep all the clks on just for bringup */ 500 - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 501 - clk_prepare_enable(clks[clks_init_on[i]]); 502 499 503 500 if (clk_on_imx6ull()) 504 501 clk_prepare_enable(clks[IMX6UL_CLK_AIPSTZ3]);
+1
drivers/clk/imx/clk-imx7d.c
··· 797 797 clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0); 798 798 clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0); 799 799 clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0); 800 + clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0); 800 801 clks[IMX7D_CAAM_CLK] = imx_clk_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0); 801 802 clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0); 802 803 clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
+2 -2
drivers/clk/ingenic/jz4740-cgu.c
··· 134 134 "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 135 135 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 136 136 .mux = { CGU_REG_CPCCR, 31, 1 }, 137 - .div = { CGU_REG_I2SCDR, 0, 1, 8, -1, -1, -1 }, 137 + .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, 138 138 .gate = { CGU_REG_CLKGR, 6 }, 139 139 }, 140 140 ··· 161 161 }, 162 162 163 163 [JZ4740_CLK_UDC] = { 164 - "udc", CGU_CLK_MUX | CGU_CLK_DIV, 164 + "udc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 165 165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 166 166 .mux = { CGU_REG_CPCCR, 29, 1 }, 167 167 .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 },
+19 -9
drivers/clk/meson/Kconfig
··· 1 1 config COMMON_CLK_AMLOGIC 2 2 bool 3 - depends on OF 4 3 depends on ARCH_MESON || COMPILE_TEST 4 + select COMMON_CLK_REGMAP_MESON 5 + 6 + config COMMON_CLK_AMLOGIC_AUDIO 7 + bool 8 + depends on ARCH_MESON || COMPILE_TEST 9 + select COMMON_CLK_AMLOGIC 5 10 6 11 config COMMON_CLK_MESON_AO 7 12 bool 8 13 depends on OF 9 14 depends on ARCH_MESON || COMPILE_TEST 10 15 select COMMON_CLK_REGMAP_MESON 16 + select RESET_CONTROLLER 11 17 12 18 config COMMON_CLK_REGMAP_MESON 13 19 bool ··· 21 15 22 16 config COMMON_CLK_MESON8B 23 17 bool 24 - depends on COMMON_CLK_AMLOGIC 18 + select COMMON_CLK_AMLOGIC 25 19 select RESET_CONTROLLER 26 - select COMMON_CLK_REGMAP_MESON 27 20 help 28 21 Support for the clock controller on AmLogic S802 (Meson8), 29 22 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you ··· 30 25 31 26 config COMMON_CLK_GXBB 32 27 bool 33 - depends on COMMON_CLK_AMLOGIC 34 - select RESET_CONTROLLER 28 + select COMMON_CLK_AMLOGIC 35 29 select COMMON_CLK_MESON_AO 36 - select COMMON_CLK_REGMAP_MESON 37 30 select MFD_SYSCON 38 31 help 39 32 Support for the clock controller on AmLogic S905 devices, aka gxbb. ··· 39 36 40 37 config COMMON_CLK_AXG 41 38 bool 42 - depends on COMMON_CLK_AMLOGIC 43 - select RESET_CONTROLLER 39 + select COMMON_CLK_AMLOGIC 44 40 select COMMON_CLK_MESON_AO 45 - select COMMON_CLK_REGMAP_MESON 46 41 select MFD_SYSCON 47 42 help 48 43 Support for the clock controller on AmLogic A113D devices, aka axg. 49 44 Say Y if you want peripherals and CPU frequency scaling to work. 45 + 46 + config COMMON_CLK_AXG_AUDIO 47 + tristate "Meson AXG Audio Clock Controller Driver" 48 + depends on COMMON_CLK_AXG 49 + select COMMON_CLK_AMLOGIC_AUDIO 50 + select MFD_SYSCON 51 + help 52 + Support for the audio clock controller on AmLogic A113D devices, 53 + aka axg, Say Y if you want audio subsystem to work.
+3 -1
drivers/clk/meson/Makefile
··· 2 2 # Makefile for Meson specific clk 3 3 # 4 4 5 - obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o 5 + obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o 6 + obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o 6 7 obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o 7 8 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 8 9 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o 9 10 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o 11 + obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o 10 12 obj-$(CONFIG_COMMON_CLK_REGMAP_MESON) += clk-regmap.o
+845
drivers/clk/meson/axg-audio.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #include <linux/clk.h> 8 + #include <linux/clk-provider.h> 9 + #include <linux/init.h> 10 + #include <linux/of_device.h> 11 + #include <linux/module.h> 12 + #include <linux/platform_device.h> 13 + #include <linux/regmap.h> 14 + #include <linux/reset.h> 15 + #include <linux/slab.h> 16 + 17 + #include "clkc-audio.h" 18 + #include "axg-audio.h" 19 + 20 + #define AXG_MST_IN_COUNT 8 21 + #define AXG_SLV_SCLK_COUNT 10 22 + #define AXG_SLV_LRCLK_COUNT 10 23 + 24 + #define AXG_AUD_GATE(_name, _reg, _bit, _pname, _iflags) \ 25 + struct clk_regmap axg_##_name = { \ 26 + .data = &(struct clk_regmap_gate_data){ \ 27 + .offset = (_reg), \ 28 + .bit_idx = (_bit), \ 29 + }, \ 30 + .hw.init = &(struct clk_init_data) { \ 31 + .name = "axg_"#_name, \ 32 + .ops = &clk_regmap_gate_ops, \ 33 + .parent_names = (const char *[]){ _pname }, \ 34 + .num_parents = 1, \ 35 + .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ 36 + }, \ 37 + } 38 + 39 + #define AXG_AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \ 40 + struct clk_regmap axg_##_name = { \ 41 + .data = &(struct clk_regmap_mux_data){ \ 42 + .offset = (_reg), \ 43 + .mask = (_mask), \ 44 + .shift = (_shift), \ 45 + .flags = (_dflags), \ 46 + }, \ 47 + .hw.init = &(struct clk_init_data){ \ 48 + .name = "axg_"#_name, \ 49 + .ops = &clk_regmap_mux_ops, \ 50 + .parent_names = (_pnames), \ 51 + .num_parents = ARRAY_SIZE(_pnames), \ 52 + .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ 53 + }, \ 54 + } 55 + 56 + #define AXG_AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \ 57 + struct clk_regmap axg_##_name = { \ 58 + .data = &(struct clk_regmap_div_data){ \ 59 + .offset = (_reg), \ 60 + .shift = (_shift), \ 61 + .width = (_width), \ 62 + .flags = (_dflags), \ 63 + }, \ 64 + .hw.init = &(struct clk_init_data){ \ 65 + .name = "axg_"#_name, \ 66 + .ops = &clk_regmap_divider_ops, \ 67 + .parent_names = (const char *[]) { _pname }, \ 68 + .num_parents = 1, \ 69 + .flags = (_iflags), \ 70 + }, \ 71 + } 72 + 73 + #define AXG_PCLK_GATE(_name, _bit) \ 74 + AXG_AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "axg_audio_pclk", 0) 75 + 76 + /* Audio peripheral clocks */ 77 + static AXG_PCLK_GATE(ddr_arb, 0); 78 + static AXG_PCLK_GATE(pdm, 1); 79 + static AXG_PCLK_GATE(tdmin_a, 2); 80 + static AXG_PCLK_GATE(tdmin_b, 3); 81 + static AXG_PCLK_GATE(tdmin_c, 4); 82 + static AXG_PCLK_GATE(tdmin_lb, 5); 83 + static AXG_PCLK_GATE(tdmout_a, 6); 84 + static AXG_PCLK_GATE(tdmout_b, 7); 85 + static AXG_PCLK_GATE(tdmout_c, 8); 86 + static AXG_PCLK_GATE(frddr_a, 9); 87 + static AXG_PCLK_GATE(frddr_b, 10); 88 + static AXG_PCLK_GATE(frddr_c, 11); 89 + static AXG_PCLK_GATE(toddr_a, 12); 90 + static AXG_PCLK_GATE(toddr_b, 13); 91 + static AXG_PCLK_GATE(toddr_c, 14); 92 + static AXG_PCLK_GATE(loopback, 15); 93 + static AXG_PCLK_GATE(spdifin, 16); 94 + static AXG_PCLK_GATE(spdifout, 17); 95 + static AXG_PCLK_GATE(resample, 18); 96 + static AXG_PCLK_GATE(power_detect, 19); 97 + 98 + /* Audio Master Clocks */ 99 + static const char * const mst_mux_parent_names[] = { 100 + "axg_mst_in0", "axg_mst_in1", "axg_mst_in2", "axg_mst_in3", 101 + "axg_mst_in4", "axg_mst_in5", "axg_mst_in6", "axg_mst_in7", 102 + }; 103 + 104 + #define AXG_MST_MCLK_MUX(_name, _reg) \ 105 + AXG_AUD_MUX(_name##_sel, _reg, 0x7, 24, CLK_MUX_ROUND_CLOSEST, \ 106 + mst_mux_parent_names, CLK_SET_RATE_PARENT) 107 + 108 + static AXG_MST_MCLK_MUX(mst_a_mclk, AUDIO_MCLK_A_CTRL); 109 + static AXG_MST_MCLK_MUX(mst_b_mclk, AUDIO_MCLK_B_CTRL); 110 + static AXG_MST_MCLK_MUX(mst_c_mclk, AUDIO_MCLK_C_CTRL); 111 + static AXG_MST_MCLK_MUX(mst_d_mclk, AUDIO_MCLK_D_CTRL); 112 + static AXG_MST_MCLK_MUX(mst_e_mclk, AUDIO_MCLK_E_CTRL); 113 + static AXG_MST_MCLK_MUX(mst_f_mclk, AUDIO_MCLK_F_CTRL); 114 + static AXG_MST_MCLK_MUX(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 115 + static AXG_MST_MCLK_MUX(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 116 + static AXG_MST_MCLK_MUX(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 117 + static AXG_MST_MCLK_MUX(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 118 + 119 + #define AXG_MST_MCLK_DIV(_name, _reg) \ 120 + AXG_AUD_DIV(_name##_div, _reg, 0, 16, CLK_DIVIDER_ROUND_CLOSEST, \ 121 + "axg_"#_name"_sel", CLK_SET_RATE_PARENT) \ 122 + 123 + static AXG_MST_MCLK_DIV(mst_a_mclk, AUDIO_MCLK_A_CTRL); 124 + static AXG_MST_MCLK_DIV(mst_b_mclk, AUDIO_MCLK_B_CTRL); 125 + static AXG_MST_MCLK_DIV(mst_c_mclk, AUDIO_MCLK_C_CTRL); 126 + static AXG_MST_MCLK_DIV(mst_d_mclk, AUDIO_MCLK_D_CTRL); 127 + static AXG_MST_MCLK_DIV(mst_e_mclk, AUDIO_MCLK_E_CTRL); 128 + static AXG_MST_MCLK_DIV(mst_f_mclk, AUDIO_MCLK_F_CTRL); 129 + static AXG_MST_MCLK_DIV(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 130 + static AXG_MST_MCLK_DIV(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 131 + static AXG_MST_MCLK_DIV(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 132 + static AXG_MST_MCLK_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 133 + 134 + #define AXG_MST_MCLK_GATE(_name, _reg) \ 135 + AXG_AUD_GATE(_name, _reg, 31, "axg_"#_name"_div", \ 136 + CLK_SET_RATE_PARENT) 137 + 138 + static AXG_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL); 139 + static AXG_MST_MCLK_GATE(mst_b_mclk, AUDIO_MCLK_B_CTRL); 140 + static AXG_MST_MCLK_GATE(mst_c_mclk, AUDIO_MCLK_C_CTRL); 141 + static AXG_MST_MCLK_GATE(mst_d_mclk, AUDIO_MCLK_D_CTRL); 142 + static AXG_MST_MCLK_GATE(mst_e_mclk, AUDIO_MCLK_E_CTRL); 143 + static AXG_MST_MCLK_GATE(mst_f_mclk, AUDIO_MCLK_F_CTRL); 144 + static AXG_MST_MCLK_GATE(spdifout_clk, AUDIO_CLK_SPDIFOUT_CTRL); 145 + static AXG_MST_MCLK_GATE(spdifin_clk, AUDIO_CLK_SPDIFIN_CTRL); 146 + static AXG_MST_MCLK_GATE(pdm_dclk, AUDIO_CLK_PDMIN_CTRL0); 147 + static AXG_MST_MCLK_GATE(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1); 148 + 149 + /* Sample Clocks */ 150 + #define AXG_MST_SCLK_PRE_EN(_name, _reg) \ 151 + AXG_AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \ 152 + "axg_mst_"#_name"_mclk", 0) 153 + 154 + static AXG_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0); 155 + static AXG_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0); 156 + static AXG_MST_SCLK_PRE_EN(c, AUDIO_MST_C_SCLK_CTRL0); 157 + static AXG_MST_SCLK_PRE_EN(d, AUDIO_MST_D_SCLK_CTRL0); 158 + static AXG_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0); 159 + static AXG_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0); 160 + 161 + #define AXG_AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \ 162 + _hi_shift, _hi_width, _pname, _iflags) \ 163 + struct clk_regmap axg_##_name = { \ 164 + .data = &(struct meson_sclk_div_data) { \ 165 + .div = { \ 166 + .reg_off = (_reg), \ 167 + .shift = (_div_shift), \ 168 + .width = (_div_width), \ 169 + }, \ 170 + .hi = { \ 171 + .reg_off = (_reg), \ 172 + .shift = (_hi_shift), \ 173 + .width = (_hi_width), \ 174 + }, \ 175 + }, \ 176 + .hw.init = &(struct clk_init_data) { \ 177 + .name = "axg_"#_name, \ 178 + .ops = &meson_sclk_div_ops, \ 179 + .parent_names = (const char *[]) { _pname }, \ 180 + .num_parents = 1, \ 181 + .flags = (_iflags), \ 182 + }, \ 183 + } 184 + 185 + #define AXG_MST_SCLK_DIV(_name, _reg) \ 186 + AXG_AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \ 187 + "axg_mst_"#_name"_sclk_pre_en", \ 188 + CLK_SET_RATE_PARENT) 189 + 190 + static AXG_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); 191 + static AXG_MST_SCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); 192 + static AXG_MST_SCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); 193 + static AXG_MST_SCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); 194 + static AXG_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); 195 + static AXG_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); 196 + 197 + #define AXG_MST_SCLK_POST_EN(_name, _reg) \ 198 + AXG_AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \ 199 + "axg_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT) 200 + 201 + static AXG_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0); 202 + static AXG_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0); 203 + static AXG_MST_SCLK_POST_EN(c, AUDIO_MST_C_SCLK_CTRL0); 204 + static AXG_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0); 205 + static AXG_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0); 206 + static AXG_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0); 207 + 208 + #define AXG_AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \ 209 + _pname, _iflags) \ 210 + struct clk_regmap axg_##_name = { \ 211 + .data = &(struct meson_clk_triphase_data) { \ 212 + .ph0 = { \ 213 + .reg_off = (_reg), \ 214 + .shift = (_shift0), \ 215 + .width = (_width), \ 216 + }, \ 217 + .ph1 = { \ 218 + .reg_off = (_reg), \ 219 + .shift = (_shift1), \ 220 + .width = (_width), \ 221 + }, \ 222 + .ph2 = { \ 223 + .reg_off = (_reg), \ 224 + .shift = (_shift2), \ 225 + .width = (_width), \ 226 + }, \ 227 + }, \ 228 + .hw.init = &(struct clk_init_data) { \ 229 + .name = "axg_"#_name, \ 230 + .ops = &meson_clk_triphase_ops, \ 231 + .parent_names = (const char *[]) { _pname }, \ 232 + .num_parents = 1, \ 233 + .flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \ 234 + }, \ 235 + } 236 + 237 + #define AXG_MST_SCLK(_name, _reg) \ 238 + AXG_AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \ 239 + "axg_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT) 240 + 241 + static AXG_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1); 242 + static AXG_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1); 243 + static AXG_MST_SCLK(c, AUDIO_MST_C_SCLK_CTRL1); 244 + static AXG_MST_SCLK(d, AUDIO_MST_D_SCLK_CTRL1); 245 + static AXG_MST_SCLK(e, AUDIO_MST_E_SCLK_CTRL1); 246 + static AXG_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1); 247 + 248 + #define AXG_MST_LRCLK_DIV(_name, _reg) \ 249 + AXG_AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \ 250 + "axg_mst_"#_name"_sclk_post_en", 0) \ 251 + 252 + static AXG_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0); 253 + static AXG_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0); 254 + static AXG_MST_LRCLK_DIV(c, AUDIO_MST_C_SCLK_CTRL0); 255 + static AXG_MST_LRCLK_DIV(d, AUDIO_MST_D_SCLK_CTRL0); 256 + static AXG_MST_LRCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0); 257 + static AXG_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0); 258 + 259 + #define AXG_MST_LRCLK(_name, _reg) \ 260 + AXG_AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \ 261 + "axg_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT) 262 + 263 + static AXG_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1); 264 + static AXG_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1); 265 + static AXG_MST_LRCLK(c, AUDIO_MST_C_SCLK_CTRL1); 266 + static AXG_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1); 267 + static AXG_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1); 268 + static AXG_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1); 269 + 270 + static const char * const tdm_sclk_parent_names[] = { 271 + "axg_mst_a_sclk", "axg_mst_b_sclk", "axg_mst_c_sclk", 272 + "axg_mst_d_sclk", "axg_mst_e_sclk", "axg_mst_f_sclk", 273 + "axg_slv_sclk0", "axg_slv_sclk1", "axg_slv_sclk2", 274 + "axg_slv_sclk3", "axg_slv_sclk4", "axg_slv_sclk5", 275 + "axg_slv_sclk6", "axg_slv_sclk7", "axg_slv_sclk8", 276 + "axg_slv_sclk9" 277 + }; 278 + 279 + #define AXG_TDM_SCLK_MUX(_name, _reg) \ 280 + AXG_AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \ 281 + CLK_MUX_ROUND_CLOSEST, \ 282 + tdm_sclk_parent_names, 0) 283 + 284 + static AXG_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL); 285 + static AXG_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL); 286 + static AXG_TDM_SCLK_MUX(in_c, AUDIO_CLK_TDMIN_C_CTRL); 287 + static AXG_TDM_SCLK_MUX(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 288 + static AXG_TDM_SCLK_MUX(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 289 + static AXG_TDM_SCLK_MUX(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 290 + static AXG_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 291 + 292 + #define AXG_TDM_SCLK_PRE_EN(_name, _reg) \ 293 + AXG_AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \ 294 + "axg_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT) 295 + 296 + static AXG_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); 297 + static AXG_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); 298 + static AXG_TDM_SCLK_PRE_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); 299 + static AXG_TDM_SCLK_PRE_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 300 + static AXG_TDM_SCLK_PRE_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 301 + static AXG_TDM_SCLK_PRE_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 302 + static AXG_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 303 + 304 + #define AXG_TDM_SCLK_POST_EN(_name, _reg) \ 305 + AXG_AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \ 306 + "axg_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT) 307 + 308 + static AXG_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL); 309 + static AXG_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL); 310 + static AXG_TDM_SCLK_POST_EN(in_c, AUDIO_CLK_TDMIN_C_CTRL); 311 + static AXG_TDM_SCLK_POST_EN(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 312 + static AXG_TDM_SCLK_POST_EN(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 313 + static AXG_TDM_SCLK_POST_EN(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 314 + static AXG_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 315 + 316 + #define AXG_TDM_SCLK(_name, _reg) \ 317 + struct clk_regmap axg_tdm##_name##_sclk = { \ 318 + .data = &(struct meson_clk_phase_data) { \ 319 + .ph = { \ 320 + .reg_off = (_reg), \ 321 + .shift = 29, \ 322 + .width = 1, \ 323 + }, \ 324 + }, \ 325 + .hw.init = &(struct clk_init_data) { \ 326 + .name = "axg_tdm"#_name"_sclk", \ 327 + .ops = &meson_clk_phase_ops, \ 328 + .parent_names = (const char *[]) \ 329 + { "axg_tdm"#_name"_sclk_post_en" }, \ 330 + .num_parents = 1, \ 331 + .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \ 332 + }, \ 333 + } 334 + 335 + static AXG_TDM_SCLK(in_a, AUDIO_CLK_TDMIN_A_CTRL); 336 + static AXG_TDM_SCLK(in_b, AUDIO_CLK_TDMIN_B_CTRL); 337 + static AXG_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL); 338 + static AXG_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 339 + static AXG_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 340 + static AXG_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 341 + static AXG_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 342 + 343 + static const char * const tdm_lrclk_parent_names[] = { 344 + "axg_mst_a_lrclk", "axg_mst_b_lrclk", "axg_mst_c_lrclk", 345 + "axg_mst_d_lrclk", "axg_mst_e_lrclk", "axg_mst_f_lrclk", 346 + "axg_slv_lrclk0", "axg_slv_lrclk1", "axg_slv_lrclk2", 347 + "axg_slv_lrclk3", "axg_slv_lrclk4", "axg_slv_lrclk5", 348 + "axg_slv_lrclk6", "axg_slv_lrclk7", "axg_slv_lrclk8", 349 + "axg_slv_lrclk9" 350 + }; 351 + 352 + #define AXG_TDM_LRLCK(_name, _reg) \ 353 + AXG_AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \ 354 + CLK_MUX_ROUND_CLOSEST, \ 355 + tdm_lrclk_parent_names, 0) 356 + 357 + static AXG_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL); 358 + static AXG_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL); 359 + static AXG_TDM_LRLCK(in_c, AUDIO_CLK_TDMIN_C_CTRL); 360 + static AXG_TDM_LRLCK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL); 361 + static AXG_TDM_LRLCK(out_a, AUDIO_CLK_TDMOUT_A_CTRL); 362 + static AXG_TDM_LRLCK(out_b, AUDIO_CLK_TDMOUT_B_CTRL); 363 + static AXG_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL); 364 + 365 + /* 366 + * Array of all clocks provided by this provider 367 + * The input clocks of the controller will be populated at runtime 368 + */ 369 + static struct clk_hw_onecell_data axg_audio_hw_onecell_data = { 370 + .hws = { 371 + [AUD_CLKID_DDR_ARB] = &axg_ddr_arb.hw, 372 + [AUD_CLKID_PDM] = &axg_pdm.hw, 373 + [AUD_CLKID_TDMIN_A] = &axg_tdmin_a.hw, 374 + [AUD_CLKID_TDMIN_B] = &axg_tdmin_b.hw, 375 + [AUD_CLKID_TDMIN_C] = &axg_tdmin_c.hw, 376 + [AUD_CLKID_TDMIN_LB] = &axg_tdmin_lb.hw, 377 + [AUD_CLKID_TDMOUT_A] = &axg_tdmout_a.hw, 378 + [AUD_CLKID_TDMOUT_B] = &axg_tdmout_b.hw, 379 + [AUD_CLKID_TDMOUT_C] = &axg_tdmout_c.hw, 380 + [AUD_CLKID_FRDDR_A] = &axg_frddr_a.hw, 381 + [AUD_CLKID_FRDDR_B] = &axg_frddr_b.hw, 382 + [AUD_CLKID_FRDDR_C] = &axg_frddr_c.hw, 383 + [AUD_CLKID_TODDR_A] = &axg_toddr_a.hw, 384 + [AUD_CLKID_TODDR_B] = &axg_toddr_b.hw, 385 + [AUD_CLKID_TODDR_C] = &axg_toddr_c.hw, 386 + [AUD_CLKID_LOOPBACK] = &axg_loopback.hw, 387 + [AUD_CLKID_SPDIFIN] = &axg_spdifin.hw, 388 + [AUD_CLKID_SPDIFOUT] = &axg_spdifout.hw, 389 + [AUD_CLKID_RESAMPLE] = &axg_resample.hw, 390 + [AUD_CLKID_POWER_DETECT] = &axg_power_detect.hw, 391 + [AUD_CLKID_MST_A_MCLK_SEL] = &axg_mst_a_mclk_sel.hw, 392 + [AUD_CLKID_MST_B_MCLK_SEL] = &axg_mst_b_mclk_sel.hw, 393 + [AUD_CLKID_MST_C_MCLK_SEL] = &axg_mst_c_mclk_sel.hw, 394 + [AUD_CLKID_MST_D_MCLK_SEL] = &axg_mst_d_mclk_sel.hw, 395 + [AUD_CLKID_MST_E_MCLK_SEL] = &axg_mst_e_mclk_sel.hw, 396 + [AUD_CLKID_MST_F_MCLK_SEL] = &axg_mst_f_mclk_sel.hw, 397 + [AUD_CLKID_MST_A_MCLK_DIV] = &axg_mst_a_mclk_div.hw, 398 + [AUD_CLKID_MST_B_MCLK_DIV] = &axg_mst_b_mclk_div.hw, 399 + [AUD_CLKID_MST_C_MCLK_DIV] = &axg_mst_c_mclk_div.hw, 400 + [AUD_CLKID_MST_D_MCLK_DIV] = &axg_mst_d_mclk_div.hw, 401 + [AUD_CLKID_MST_E_MCLK_DIV] = &axg_mst_e_mclk_div.hw, 402 + [AUD_CLKID_MST_F_MCLK_DIV] = &axg_mst_f_mclk_div.hw, 403 + [AUD_CLKID_MST_A_MCLK] = &axg_mst_a_mclk.hw, 404 + [AUD_CLKID_MST_B_MCLK] = &axg_mst_b_mclk.hw, 405 + [AUD_CLKID_MST_C_MCLK] = &axg_mst_c_mclk.hw, 406 + [AUD_CLKID_MST_D_MCLK] = &axg_mst_d_mclk.hw, 407 + [AUD_CLKID_MST_E_MCLK] = &axg_mst_e_mclk.hw, 408 + [AUD_CLKID_MST_F_MCLK] = &axg_mst_f_mclk.hw, 409 + [AUD_CLKID_SPDIFOUT_CLK_SEL] = &axg_spdifout_clk_sel.hw, 410 + [AUD_CLKID_SPDIFOUT_CLK_DIV] = &axg_spdifout_clk_div.hw, 411 + [AUD_CLKID_SPDIFOUT_CLK] = &axg_spdifout_clk.hw, 412 + [AUD_CLKID_SPDIFIN_CLK_SEL] = &axg_spdifin_clk_sel.hw, 413 + [AUD_CLKID_SPDIFIN_CLK_DIV] = &axg_spdifin_clk_div.hw, 414 + [AUD_CLKID_SPDIFIN_CLK] = &axg_spdifin_clk.hw, 415 + [AUD_CLKID_PDM_DCLK_SEL] = &axg_pdm_dclk_sel.hw, 416 + [AUD_CLKID_PDM_DCLK_DIV] = &axg_pdm_dclk_div.hw, 417 + [AUD_CLKID_PDM_DCLK] = &axg_pdm_dclk.hw, 418 + [AUD_CLKID_PDM_SYSCLK_SEL] = &axg_pdm_sysclk_sel.hw, 419 + [AUD_CLKID_PDM_SYSCLK_DIV] = &axg_pdm_sysclk_div.hw, 420 + [AUD_CLKID_PDM_SYSCLK] = &axg_pdm_sysclk.hw, 421 + [AUD_CLKID_MST_A_SCLK_PRE_EN] = &axg_mst_a_sclk_pre_en.hw, 422 + [AUD_CLKID_MST_B_SCLK_PRE_EN] = &axg_mst_b_sclk_pre_en.hw, 423 + [AUD_CLKID_MST_C_SCLK_PRE_EN] = &axg_mst_c_sclk_pre_en.hw, 424 + [AUD_CLKID_MST_D_SCLK_PRE_EN] = &axg_mst_d_sclk_pre_en.hw, 425 + [AUD_CLKID_MST_E_SCLK_PRE_EN] = &axg_mst_e_sclk_pre_en.hw, 426 + [AUD_CLKID_MST_F_SCLK_PRE_EN] = &axg_mst_f_sclk_pre_en.hw, 427 + [AUD_CLKID_MST_A_SCLK_DIV] = &axg_mst_a_sclk_div.hw, 428 + [AUD_CLKID_MST_B_SCLK_DIV] = &axg_mst_b_sclk_div.hw, 429 + [AUD_CLKID_MST_C_SCLK_DIV] = &axg_mst_c_sclk_div.hw, 430 + [AUD_CLKID_MST_D_SCLK_DIV] = &axg_mst_d_sclk_div.hw, 431 + [AUD_CLKID_MST_E_SCLK_DIV] = &axg_mst_e_sclk_div.hw, 432 + [AUD_CLKID_MST_F_SCLK_DIV] = &axg_mst_f_sclk_div.hw, 433 + [AUD_CLKID_MST_A_SCLK_POST_EN] = &axg_mst_a_sclk_post_en.hw, 434 + [AUD_CLKID_MST_B_SCLK_POST_EN] = &axg_mst_b_sclk_post_en.hw, 435 + [AUD_CLKID_MST_C_SCLK_POST_EN] = &axg_mst_c_sclk_post_en.hw, 436 + [AUD_CLKID_MST_D_SCLK_POST_EN] = &axg_mst_d_sclk_post_en.hw, 437 + [AUD_CLKID_MST_E_SCLK_POST_EN] = &axg_mst_e_sclk_post_en.hw, 438 + [AUD_CLKID_MST_F_SCLK_POST_EN] = &axg_mst_f_sclk_post_en.hw, 439 + [AUD_CLKID_MST_A_SCLK] = &axg_mst_a_sclk.hw, 440 + [AUD_CLKID_MST_B_SCLK] = &axg_mst_b_sclk.hw, 441 + [AUD_CLKID_MST_C_SCLK] = &axg_mst_c_sclk.hw, 442 + [AUD_CLKID_MST_D_SCLK] = &axg_mst_d_sclk.hw, 443 + [AUD_CLKID_MST_E_SCLK] = &axg_mst_e_sclk.hw, 444 + [AUD_CLKID_MST_F_SCLK] = &axg_mst_f_sclk.hw, 445 + [AUD_CLKID_MST_A_LRCLK_DIV] = &axg_mst_a_lrclk_div.hw, 446 + [AUD_CLKID_MST_B_LRCLK_DIV] = &axg_mst_b_lrclk_div.hw, 447 + [AUD_CLKID_MST_C_LRCLK_DIV] = &axg_mst_c_lrclk_div.hw, 448 + [AUD_CLKID_MST_D_LRCLK_DIV] = &axg_mst_d_lrclk_div.hw, 449 + [AUD_CLKID_MST_E_LRCLK_DIV] = &axg_mst_e_lrclk_div.hw, 450 + [AUD_CLKID_MST_F_LRCLK_DIV] = &axg_mst_f_lrclk_div.hw, 451 + [AUD_CLKID_MST_A_LRCLK] = &axg_mst_a_lrclk.hw, 452 + [AUD_CLKID_MST_B_LRCLK] = &axg_mst_b_lrclk.hw, 453 + [AUD_CLKID_MST_C_LRCLK] = &axg_mst_c_lrclk.hw, 454 + [AUD_CLKID_MST_D_LRCLK] = &axg_mst_d_lrclk.hw, 455 + [AUD_CLKID_MST_E_LRCLK] = &axg_mst_e_lrclk.hw, 456 + [AUD_CLKID_MST_F_LRCLK] = &axg_mst_f_lrclk.hw, 457 + [AUD_CLKID_TDMIN_A_SCLK_SEL] = &axg_tdmin_a_sclk_sel.hw, 458 + [AUD_CLKID_TDMIN_B_SCLK_SEL] = &axg_tdmin_b_sclk_sel.hw, 459 + [AUD_CLKID_TDMIN_C_SCLK_SEL] = &axg_tdmin_c_sclk_sel.hw, 460 + [AUD_CLKID_TDMIN_LB_SCLK_SEL] = &axg_tdmin_lb_sclk_sel.hw, 461 + [AUD_CLKID_TDMOUT_A_SCLK_SEL] = &axg_tdmout_a_sclk_sel.hw, 462 + [AUD_CLKID_TDMOUT_B_SCLK_SEL] = &axg_tdmout_b_sclk_sel.hw, 463 + [AUD_CLKID_TDMOUT_C_SCLK_SEL] = &axg_tdmout_c_sclk_sel.hw, 464 + [AUD_CLKID_TDMIN_A_SCLK_PRE_EN] = &axg_tdmin_a_sclk_pre_en.hw, 465 + [AUD_CLKID_TDMIN_B_SCLK_PRE_EN] = &axg_tdmin_b_sclk_pre_en.hw, 466 + [AUD_CLKID_TDMIN_C_SCLK_PRE_EN] = &axg_tdmin_c_sclk_pre_en.hw, 467 + [AUD_CLKID_TDMIN_LB_SCLK_PRE_EN] = &axg_tdmin_lb_sclk_pre_en.hw, 468 + [AUD_CLKID_TDMOUT_A_SCLK_PRE_EN] = &axg_tdmout_a_sclk_pre_en.hw, 469 + [AUD_CLKID_TDMOUT_B_SCLK_PRE_EN] = &axg_tdmout_b_sclk_pre_en.hw, 470 + [AUD_CLKID_TDMOUT_C_SCLK_PRE_EN] = &axg_tdmout_c_sclk_pre_en.hw, 471 + [AUD_CLKID_TDMIN_A_SCLK_POST_EN] = &axg_tdmin_a_sclk_post_en.hw, 472 + [AUD_CLKID_TDMIN_B_SCLK_POST_EN] = &axg_tdmin_b_sclk_post_en.hw, 473 + [AUD_CLKID_TDMIN_C_SCLK_POST_EN] = &axg_tdmin_c_sclk_post_en.hw, 474 + [AUD_CLKID_TDMIN_LB_SCLK_POST_EN] = &axg_tdmin_lb_sclk_post_en.hw, 475 + [AUD_CLKID_TDMOUT_A_SCLK_POST_EN] = &axg_tdmout_a_sclk_post_en.hw, 476 + [AUD_CLKID_TDMOUT_B_SCLK_POST_EN] = &axg_tdmout_b_sclk_post_en.hw, 477 + [AUD_CLKID_TDMOUT_C_SCLK_POST_EN] = &axg_tdmout_c_sclk_post_en.hw, 478 + [AUD_CLKID_TDMIN_A_SCLK] = &axg_tdmin_a_sclk.hw, 479 + [AUD_CLKID_TDMIN_B_SCLK] = &axg_tdmin_b_sclk.hw, 480 + [AUD_CLKID_TDMIN_C_SCLK] = &axg_tdmin_c_sclk.hw, 481 + [AUD_CLKID_TDMIN_LB_SCLK] = &axg_tdmin_lb_sclk.hw, 482 + [AUD_CLKID_TDMOUT_A_SCLK] = &axg_tdmout_a_sclk.hw, 483 + [AUD_CLKID_TDMOUT_B_SCLK] = &axg_tdmout_b_sclk.hw, 484 + [AUD_CLKID_TDMOUT_C_SCLK] = &axg_tdmout_c_sclk.hw, 485 + [AUD_CLKID_TDMIN_A_LRCLK] = &axg_tdmin_a_lrclk.hw, 486 + [AUD_CLKID_TDMIN_B_LRCLK] = &axg_tdmin_b_lrclk.hw, 487 + [AUD_CLKID_TDMIN_C_LRCLK] = &axg_tdmin_c_lrclk.hw, 488 + [AUD_CLKID_TDMIN_LB_LRCLK] = &axg_tdmin_lb_lrclk.hw, 489 + [AUD_CLKID_TDMOUT_A_LRCLK] = &axg_tdmout_a_lrclk.hw, 490 + [AUD_CLKID_TDMOUT_B_LRCLK] = &axg_tdmout_b_lrclk.hw, 491 + [AUD_CLKID_TDMOUT_C_LRCLK] = &axg_tdmout_c_lrclk.hw, 492 + [NR_CLKS] = NULL, 493 + }, 494 + .num = NR_CLKS, 495 + }; 496 + 497 + /* Convenience table to populate regmap in .probe() */ 498 + static struct clk_regmap *const axg_audio_clk_regmaps[] = { 499 + &axg_ddr_arb, 500 + &axg_pdm, 501 + &axg_tdmin_a, 502 + &axg_tdmin_b, 503 + &axg_tdmin_c, 504 + &axg_tdmin_lb, 505 + &axg_tdmout_a, 506 + &axg_tdmout_b, 507 + &axg_tdmout_c, 508 + &axg_frddr_a, 509 + &axg_frddr_b, 510 + &axg_frddr_c, 511 + &axg_toddr_a, 512 + &axg_toddr_b, 513 + &axg_toddr_c, 514 + &axg_loopback, 515 + &axg_spdifin, 516 + &axg_spdifout, 517 + &axg_resample, 518 + &axg_power_detect, 519 + &axg_mst_a_mclk_sel, 520 + &axg_mst_b_mclk_sel, 521 + &axg_mst_c_mclk_sel, 522 + &axg_mst_d_mclk_sel, 523 + &axg_mst_e_mclk_sel, 524 + &axg_mst_f_mclk_sel, 525 + &axg_mst_a_mclk_div, 526 + &axg_mst_b_mclk_div, 527 + &axg_mst_c_mclk_div, 528 + &axg_mst_d_mclk_div, 529 + &axg_mst_e_mclk_div, 530 + &axg_mst_f_mclk_div, 531 + &axg_mst_a_mclk, 532 + &axg_mst_b_mclk, 533 + &axg_mst_c_mclk, 534 + &axg_mst_d_mclk, 535 + &axg_mst_e_mclk, 536 + &axg_mst_f_mclk, 537 + &axg_spdifout_clk_sel, 538 + &axg_spdifout_clk_div, 539 + &axg_spdifout_clk, 540 + &axg_spdifin_clk_sel, 541 + &axg_spdifin_clk_div, 542 + &axg_spdifin_clk, 543 + &axg_pdm_dclk_sel, 544 + &axg_pdm_dclk_div, 545 + &axg_pdm_dclk, 546 + &axg_pdm_sysclk_sel, 547 + &axg_pdm_sysclk_div, 548 + &axg_pdm_sysclk, 549 + &axg_mst_a_sclk_pre_en, 550 + &axg_mst_b_sclk_pre_en, 551 + &axg_mst_c_sclk_pre_en, 552 + &axg_mst_d_sclk_pre_en, 553 + &axg_mst_e_sclk_pre_en, 554 + &axg_mst_f_sclk_pre_en, 555 + &axg_mst_a_sclk_div, 556 + &axg_mst_b_sclk_div, 557 + &axg_mst_c_sclk_div, 558 + &axg_mst_d_sclk_div, 559 + &axg_mst_e_sclk_div, 560 + &axg_mst_f_sclk_div, 561 + &axg_mst_a_sclk_post_en, 562 + &axg_mst_b_sclk_post_en, 563 + &axg_mst_c_sclk_post_en, 564 + &axg_mst_d_sclk_post_en, 565 + &axg_mst_e_sclk_post_en, 566 + &axg_mst_f_sclk_post_en, 567 + &axg_mst_a_sclk, 568 + &axg_mst_b_sclk, 569 + &axg_mst_c_sclk, 570 + &axg_mst_d_sclk, 571 + &axg_mst_e_sclk, 572 + &axg_mst_f_sclk, 573 + &axg_mst_a_lrclk_div, 574 + &axg_mst_b_lrclk_div, 575 + &axg_mst_c_lrclk_div, 576 + &axg_mst_d_lrclk_div, 577 + &axg_mst_e_lrclk_div, 578 + &axg_mst_f_lrclk_div, 579 + &axg_mst_a_lrclk, 580 + &axg_mst_b_lrclk, 581 + &axg_mst_c_lrclk, 582 + &axg_mst_d_lrclk, 583 + &axg_mst_e_lrclk, 584 + &axg_mst_f_lrclk, 585 + &axg_tdmin_a_sclk_sel, 586 + &axg_tdmin_b_sclk_sel, 587 + &axg_tdmin_c_sclk_sel, 588 + &axg_tdmin_lb_sclk_sel, 589 + &axg_tdmout_a_sclk_sel, 590 + &axg_tdmout_b_sclk_sel, 591 + &axg_tdmout_c_sclk_sel, 592 + &axg_tdmin_a_sclk_pre_en, 593 + &axg_tdmin_b_sclk_pre_en, 594 + &axg_tdmin_c_sclk_pre_en, 595 + &axg_tdmin_lb_sclk_pre_en, 596 + &axg_tdmout_a_sclk_pre_en, 597 + &axg_tdmout_b_sclk_pre_en, 598 + &axg_tdmout_c_sclk_pre_en, 599 + &axg_tdmin_a_sclk_post_en, 600 + &axg_tdmin_b_sclk_post_en, 601 + &axg_tdmin_c_sclk_post_en, 602 + &axg_tdmin_lb_sclk_post_en, 603 + &axg_tdmout_a_sclk_post_en, 604 + &axg_tdmout_b_sclk_post_en, 605 + &axg_tdmout_c_sclk_post_en, 606 + &axg_tdmin_a_sclk, 607 + &axg_tdmin_b_sclk, 608 + &axg_tdmin_c_sclk, 609 + &axg_tdmin_lb_sclk, 610 + &axg_tdmout_a_sclk, 611 + &axg_tdmout_b_sclk, 612 + &axg_tdmout_c_sclk, 613 + &axg_tdmin_a_lrclk, 614 + &axg_tdmin_b_lrclk, 615 + &axg_tdmin_c_lrclk, 616 + &axg_tdmin_lb_lrclk, 617 + &axg_tdmout_a_lrclk, 618 + &axg_tdmout_b_lrclk, 619 + &axg_tdmout_c_lrclk, 620 + }; 621 + 622 + static struct clk *devm_clk_get_enable(struct device *dev, char *id) 623 + { 624 + struct clk *clk; 625 + int ret; 626 + 627 + clk = devm_clk_get(dev, id); 628 + if (IS_ERR(clk)) { 629 + if (PTR_ERR(clk) != -EPROBE_DEFER) 630 + dev_err(dev, "failed to get %s", id); 631 + return clk; 632 + } 633 + 634 + ret = clk_prepare_enable(clk); 635 + if (ret) { 636 + dev_err(dev, "failed to enable %s", id); 637 + return ERR_PTR(ret); 638 + } 639 + 640 + ret = devm_add_action_or_reset(dev, 641 + (void(*)(void *))clk_disable_unprepare, 642 + clk); 643 + if (ret) { 644 + dev_err(dev, "failed to add reset action on %s", id); 645 + return ERR_PTR(ret); 646 + } 647 + 648 + return clk; 649 + } 650 + 651 + static const struct clk_ops axg_clk_no_ops = {}; 652 + 653 + static struct clk_hw *axg_clk_hw_register_bypass(struct device *dev, 654 + const char *name, 655 + const char *parent_name) 656 + { 657 + struct clk_hw *hw; 658 + struct clk_init_data init; 659 + char *clk_name; 660 + int ret; 661 + 662 + hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 663 + if (!hw) 664 + return ERR_PTR(-ENOMEM); 665 + 666 + clk_name = kasprintf(GFP_KERNEL, "axg_%s", name); 667 + if (!clk_name) 668 + return ERR_PTR(-ENOMEM); 669 + 670 + init.name = clk_name; 671 + init.ops = &axg_clk_no_ops; 672 + init.flags = 0; 673 + init.parent_names = parent_name ? &parent_name : NULL; 674 + init.num_parents = parent_name ? 1 : 0; 675 + hw->init = &init; 676 + 677 + ret = devm_clk_hw_register(dev, hw); 678 + kfree(clk_name); 679 + 680 + return ret ? ERR_PTR(ret) : hw; 681 + } 682 + 683 + static int axg_register_clk_hw_input(struct device *dev, 684 + const char *name, 685 + unsigned int clkid) 686 + { 687 + struct clk *parent_clk = devm_clk_get(dev, name); 688 + struct clk_hw *hw = NULL; 689 + 690 + if (IS_ERR(parent_clk)) { 691 + int err = PTR_ERR(parent_clk); 692 + 693 + /* It is ok if an input clock is missing */ 694 + if (err == -ENOENT) { 695 + dev_dbg(dev, "%s not provided", name); 696 + } else { 697 + if (err != -EPROBE_DEFER) 698 + dev_err(dev, "failed to get %s clock", name); 699 + return err; 700 + } 701 + } else { 702 + hw = axg_clk_hw_register_bypass(dev, name, 703 + __clk_get_name(parent_clk)); 704 + } 705 + 706 + if (IS_ERR(hw)) { 707 + dev_err(dev, "failed to register %s clock", name); 708 + return PTR_ERR(hw); 709 + } 710 + 711 + axg_audio_hw_onecell_data.hws[clkid] = hw; 712 + return 0; 713 + } 714 + 715 + static int axg_register_clk_hw_inputs(struct device *dev, 716 + const char *basename, 717 + unsigned int count, 718 + unsigned int clkid) 719 + { 720 + char *name; 721 + int i, ret; 722 + 723 + for (i = 0; i < count; i++) { 724 + name = kasprintf(GFP_KERNEL, "%s%d", basename, i); 725 + if (!name) 726 + return -ENOMEM; 727 + 728 + ret = axg_register_clk_hw_input(dev, name, clkid + i); 729 + kfree(name); 730 + if (ret) 731 + return ret; 732 + } 733 + 734 + return 0; 735 + } 736 + 737 + static const struct regmap_config axg_audio_regmap_cfg = { 738 + .reg_bits = 32, 739 + .val_bits = 32, 740 + .reg_stride = 4, 741 + .max_register = AUDIO_CLK_PDMIN_CTRL1, 742 + }; 743 + 744 + static int axg_audio_clkc_probe(struct platform_device *pdev) 745 + { 746 + struct device *dev = &pdev->dev; 747 + struct regmap *map; 748 + struct resource *res; 749 + void __iomem *regs; 750 + struct clk *clk; 751 + struct clk_hw *hw; 752 + int ret, i; 753 + 754 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 755 + regs = devm_ioremap_resource(dev, res); 756 + if (IS_ERR(regs)) 757 + return PTR_ERR(regs); 758 + 759 + map = devm_regmap_init_mmio(dev, regs, &axg_audio_regmap_cfg); 760 + if (IS_ERR(map)) { 761 + dev_err(dev, "failed to init regmap: %ld\n", PTR_ERR(map)); 762 + return PTR_ERR(map); 763 + } 764 + 765 + /* Get the mandatory peripheral clock */ 766 + clk = devm_clk_get_enable(dev, "pclk"); 767 + if (IS_ERR(clk)) 768 + return PTR_ERR(clk); 769 + 770 + ret = device_reset(dev); 771 + if (ret) { 772 + dev_err(dev, "failed to reset device\n"); 773 + return ret; 774 + } 775 + 776 + /* Register the peripheral input clock */ 777 + hw = axg_clk_hw_register_bypass(dev, "audio_pclk", 778 + __clk_get_name(clk)); 779 + if (IS_ERR(hw)) 780 + return PTR_ERR(hw); 781 + 782 + axg_audio_hw_onecell_data.hws[AUD_CLKID_PCLK] = hw; 783 + 784 + /* Register optional input master clocks */ 785 + ret = axg_register_clk_hw_inputs(dev, "mst_in", 786 + AXG_MST_IN_COUNT, 787 + AUD_CLKID_MST0); 788 + if (ret) 789 + return ret; 790 + 791 + /* Register optional input slave sclks */ 792 + ret = axg_register_clk_hw_inputs(dev, "slv_sclk", 793 + AXG_SLV_SCLK_COUNT, 794 + AUD_CLKID_SLV_SCLK0); 795 + if (ret) 796 + return ret; 797 + 798 + /* Register optional input slave lrclks */ 799 + ret = axg_register_clk_hw_inputs(dev, "slv_lrclk", 800 + AXG_SLV_LRCLK_COUNT, 801 + AUD_CLKID_SLV_LRCLK0); 802 + if (ret) 803 + return ret; 804 + 805 + /* Populate regmap for the regmap backed clocks */ 806 + for (i = 0; i < ARRAY_SIZE(axg_audio_clk_regmaps); i++) 807 + axg_audio_clk_regmaps[i]->map = map; 808 + 809 + /* Take care to skip the registered input clocks */ 810 + for (i = AUD_CLKID_DDR_ARB; i < axg_audio_hw_onecell_data.num; i++) { 811 + hw = axg_audio_hw_onecell_data.hws[i]; 812 + /* array might be sparse */ 813 + if (!hw) 814 + continue; 815 + 816 + ret = devm_clk_hw_register(dev, hw); 817 + if (ret) { 818 + dev_err(dev, "failed to register clock %s\n", 819 + hw->init->name); 820 + return ret; 821 + } 822 + } 823 + 824 + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, 825 + &axg_audio_hw_onecell_data); 826 + } 827 + 828 + static const struct of_device_id clkc_match_table[] = { 829 + { .compatible = "amlogic,axg-audio-clkc" }, 830 + {} 831 + }; 832 + MODULE_DEVICE_TABLE(of, clkc_match_table); 833 + 834 + static struct platform_driver axg_audio_driver = { 835 + .probe = axg_audio_clkc_probe, 836 + .driver = { 837 + .name = "axg-audio-clkc", 838 + .of_match_table = clkc_match_table, 839 + }, 840 + }; 841 + module_platform_driver(axg_audio_driver); 842 + 843 + MODULE_DESCRIPTION("Amlogic A113x Audio Clock driver"); 844 + MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 845 + MODULE_LICENSE("GPL v2");
+127
drivers/clk/meson/axg-audio.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef __AXG_AUDIO_CLKC_H 8 + #define __AXG_AUDIO_CLKC_H 9 + 10 + /* 11 + * Audio Clock register offsets 12 + * 13 + * Register offsets from the datasheet must be multiplied by 4 before 14 + * to get the right offset 15 + */ 16 + #define AUDIO_CLK_GATE_EN 0x000 17 + #define AUDIO_MCLK_A_CTRL 0x004 18 + #define AUDIO_MCLK_B_CTRL 0x008 19 + #define AUDIO_MCLK_C_CTRL 0x00C 20 + #define AUDIO_MCLK_D_CTRL 0x010 21 + #define AUDIO_MCLK_E_CTRL 0x014 22 + #define AUDIO_MCLK_F_CTRL 0x018 23 + #define AUDIO_MST_A_SCLK_CTRL0 0x040 24 + #define AUDIO_MST_A_SCLK_CTRL1 0x044 25 + #define AUDIO_MST_B_SCLK_CTRL0 0x048 26 + #define AUDIO_MST_B_SCLK_CTRL1 0x04C 27 + #define AUDIO_MST_C_SCLK_CTRL0 0x050 28 + #define AUDIO_MST_C_SCLK_CTRL1 0x054 29 + #define AUDIO_MST_D_SCLK_CTRL0 0x058 30 + #define AUDIO_MST_D_SCLK_CTRL1 0x05C 31 + #define AUDIO_MST_E_SCLK_CTRL0 0x060 32 + #define AUDIO_MST_E_SCLK_CTRL1 0x064 33 + #define AUDIO_MST_F_SCLK_CTRL0 0x068 34 + #define AUDIO_MST_F_SCLK_CTRL1 0x06C 35 + #define AUDIO_CLK_TDMIN_A_CTRL 0x080 36 + #define AUDIO_CLK_TDMIN_B_CTRL 0x084 37 + #define AUDIO_CLK_TDMIN_C_CTRL 0x088 38 + #define AUDIO_CLK_TDMIN_LB_CTRL 0x08C 39 + #define AUDIO_CLK_TDMOUT_A_CTRL 0x090 40 + #define AUDIO_CLK_TDMOUT_B_CTRL 0x094 41 + #define AUDIO_CLK_TDMOUT_C_CTRL 0x098 42 + #define AUDIO_CLK_SPDIFIN_CTRL 0x09C 43 + #define AUDIO_CLK_SPDIFOUT_CTRL 0x0A0 44 + #define AUDIO_CLK_RESAMPLE_CTRL 0x0A4 45 + #define AUDIO_CLK_LOCKER_CTRL 0x0A8 46 + #define AUDIO_CLK_PDMIN_CTRL0 0x0AC 47 + #define AUDIO_CLK_PDMIN_CTRL1 0x0B0 48 + 49 + /* 50 + * CLKID index values 51 + * These indices are entirely contrived and do not map onto the hardware. 52 + */ 53 + 54 + #define AUD_CLKID_PCLK 0 55 + #define AUD_CLKID_MST0 1 56 + #define AUD_CLKID_MST1 2 57 + #define AUD_CLKID_MST2 3 58 + #define AUD_CLKID_MST3 4 59 + #define AUD_CLKID_MST4 5 60 + #define AUD_CLKID_MST5 6 61 + #define AUD_CLKID_MST6 7 62 + #define AUD_CLKID_MST7 8 63 + #define AUD_CLKID_MST_A_MCLK_SEL 59 64 + #define AUD_CLKID_MST_B_MCLK_SEL 60 65 + #define AUD_CLKID_MST_C_MCLK_SEL 61 66 + #define AUD_CLKID_MST_D_MCLK_SEL 62 67 + #define AUD_CLKID_MST_E_MCLK_SEL 63 68 + #define AUD_CLKID_MST_F_MCLK_SEL 64 69 + #define AUD_CLKID_MST_A_MCLK_DIV 65 70 + #define AUD_CLKID_MST_B_MCLK_DIV 66 71 + #define AUD_CLKID_MST_C_MCLK_DIV 67 72 + #define AUD_CLKID_MST_D_MCLK_DIV 68 73 + #define AUD_CLKID_MST_E_MCLK_DIV 69 74 + #define AUD_CLKID_MST_F_MCLK_DIV 70 75 + #define AUD_CLKID_SPDIFOUT_CLK_SEL 71 76 + #define AUD_CLKID_SPDIFOUT_CLK_DIV 72 77 + #define AUD_CLKID_SPDIFIN_CLK_SEL 73 78 + #define AUD_CLKID_SPDIFIN_CLK_DIV 74 79 + #define AUD_CLKID_PDM_DCLK_SEL 75 80 + #define AUD_CLKID_PDM_DCLK_DIV 76 81 + #define AUD_CLKID_PDM_SYSCLK_SEL 77 82 + #define AUD_CLKID_PDM_SYSCLK_DIV 78 83 + #define AUD_CLKID_MST_A_SCLK_PRE_EN 92 84 + #define AUD_CLKID_MST_B_SCLK_PRE_EN 93 85 + #define AUD_CLKID_MST_C_SCLK_PRE_EN 94 86 + #define AUD_CLKID_MST_D_SCLK_PRE_EN 95 87 + #define AUD_CLKID_MST_E_SCLK_PRE_EN 96 88 + #define AUD_CLKID_MST_F_SCLK_PRE_EN 97 89 + #define AUD_CLKID_MST_A_SCLK_DIV 98 90 + #define AUD_CLKID_MST_B_SCLK_DIV 99 91 + #define AUD_CLKID_MST_C_SCLK_DIV 100 92 + #define AUD_CLKID_MST_D_SCLK_DIV 101 93 + #define AUD_CLKID_MST_E_SCLK_DIV 102 94 + #define AUD_CLKID_MST_F_SCLK_DIV 103 95 + #define AUD_CLKID_MST_A_SCLK_POST_EN 104 96 + #define AUD_CLKID_MST_B_SCLK_POST_EN 105 97 + #define AUD_CLKID_MST_C_SCLK_POST_EN 106 98 + #define AUD_CLKID_MST_D_SCLK_POST_EN 107 99 + #define AUD_CLKID_MST_E_SCLK_POST_EN 108 100 + #define AUD_CLKID_MST_F_SCLK_POST_EN 109 101 + #define AUD_CLKID_MST_A_LRCLK_DIV 110 102 + #define AUD_CLKID_MST_B_LRCLK_DIV 111 103 + #define AUD_CLKID_MST_C_LRCLK_DIV 112 104 + #define AUD_CLKID_MST_D_LRCLK_DIV 113 105 + #define AUD_CLKID_MST_E_LRCLK_DIV 114 106 + #define AUD_CLKID_MST_F_LRCLK_DIV 115 107 + #define AUD_CLKID_TDMIN_A_SCLK_PRE_EN 137 108 + #define AUD_CLKID_TDMIN_B_SCLK_PRE_EN 138 109 + #define AUD_CLKID_TDMIN_C_SCLK_PRE_EN 139 110 + #define AUD_CLKID_TDMIN_LB_SCLK_PRE_EN 140 111 + #define AUD_CLKID_TDMOUT_A_SCLK_PRE_EN 141 112 + #define AUD_CLKID_TDMOUT_B_SCLK_PRE_EN 142 113 + #define AUD_CLKID_TDMOUT_C_SCLK_PRE_EN 143 114 + #define AUD_CLKID_TDMIN_A_SCLK_POST_EN 144 115 + #define AUD_CLKID_TDMIN_B_SCLK_POST_EN 145 116 + #define AUD_CLKID_TDMIN_C_SCLK_POST_EN 146 117 + #define AUD_CLKID_TDMIN_LB_SCLK_POST_EN 147 118 + #define AUD_CLKID_TDMOUT_A_SCLK_POST_EN 148 119 + #define AUD_CLKID_TDMOUT_B_SCLK_POST_EN 149 120 + #define AUD_CLKID_TDMOUT_C_SCLK_POST_EN 150 121 + 122 + /* include the CLKIDs which are part of the DT bindings */ 123 + #include <dt-bindings/clock/axg-audio-clkc.h> 124 + 125 + #define NR_CLKS 151 126 + 127 + #endif /*__AXG_AUDIO_CLKC_H */
+209 -35
drivers/clk/meson/axg.c
··· 12 12 #include <linux/clk.h> 13 13 #include <linux/clk-provider.h> 14 14 #include <linux/init.h> 15 - #include <linux/of_address.h> 16 15 #include <linux/of_device.h> 17 16 #include <linux/mfd/syscon.h> 18 17 #include <linux/platform_device.h> ··· 625 626 }, 626 627 }; 627 628 629 + static const struct pll_rate_table axg_pcie_pll_rate_table[] = { 630 + { 631 + .rate = 100000000, 632 + .m = 200, 633 + .n = 3, 634 + .od = 1, 635 + .od2 = 3, 636 + }, 637 + { /* sentinel */ }, 638 + }; 639 + 640 + static const struct reg_sequence axg_pcie_init_regs[] = { 641 + { .reg = HHI_PCIE_PLL_CNTL, .def = 0x400106c8 }, 642 + { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x0084a2aa }, 643 + { .reg = HHI_PCIE_PLL_CNTL2, .def = 0xb75020be }, 644 + { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x0a47488e }, 645 + { .reg = HHI_PCIE_PLL_CNTL4, .def = 0xc000004d }, 646 + { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x00078000 }, 647 + { .reg = HHI_PCIE_PLL_CNTL6, .def = 0x002323c6 }, 648 + }; 649 + 650 + static struct clk_regmap axg_pcie_pll = { 651 + .data = &(struct meson_clk_pll_data){ 652 + .m = { 653 + .reg_off = HHI_PCIE_PLL_CNTL, 654 + .shift = 0, 655 + .width = 9, 656 + }, 657 + .n = { 658 + .reg_off = HHI_PCIE_PLL_CNTL, 659 + .shift = 9, 660 + .width = 5, 661 + }, 662 + .od = { 663 + .reg_off = HHI_PCIE_PLL_CNTL, 664 + .shift = 16, 665 + .width = 2, 666 + }, 667 + .od2 = { 668 + .reg_off = HHI_PCIE_PLL_CNTL6, 669 + .shift = 6, 670 + .width = 2, 671 + }, 672 + .frac = { 673 + .reg_off = HHI_PCIE_PLL_CNTL1, 674 + .shift = 0, 675 + .width = 12, 676 + }, 677 + .l = { 678 + .reg_off = HHI_PCIE_PLL_CNTL, 679 + .shift = 31, 680 + .width = 1, 681 + }, 682 + .rst = { 683 + .reg_off = HHI_PCIE_PLL_CNTL, 684 + .shift = 29, 685 + .width = 1, 686 + }, 687 + .table = axg_pcie_pll_rate_table, 688 + .init_regs = axg_pcie_init_regs, 689 + .init_count = ARRAY_SIZE(axg_pcie_init_regs), 690 + }, 691 + .hw.init = &(struct clk_init_data){ 692 + .name = "pcie_pll", 693 + .ops = &meson_clk_pll_ops, 694 + .parent_names = (const char *[]){ "xtal" }, 695 + .num_parents = 1, 696 + }, 697 + }; 698 + 699 + static struct clk_regmap axg_pcie_mux = { 700 + .data = &(struct clk_regmap_mux_data){ 701 + .offset = HHI_PCIE_PLL_CNTL6, 702 + .mask = 0x1, 703 + .shift = 2, 704 + }, 705 + .hw.init = &(struct clk_init_data){ 706 + .name = "pcie_mux", 707 + .ops = &clk_regmap_mux_ops, 708 + .parent_names = (const char *[]){ "mpll3", "pcie_pll" }, 709 + .num_parents = 2, 710 + .flags = CLK_SET_RATE_PARENT, 711 + }, 712 + }; 713 + 714 + static struct clk_regmap axg_pcie_ref = { 715 + .data = &(struct clk_regmap_mux_data){ 716 + .offset = HHI_PCIE_PLL_CNTL6, 717 + .mask = 0x1, 718 + .shift = 1, 719 + /* skip the parent 0, reserved for debug */ 720 + .table = (u32[]){ 1 }, 721 + }, 722 + .hw.init = &(struct clk_init_data){ 723 + .name = "pcie_ref", 724 + .ops = &clk_regmap_mux_ops, 725 + .parent_names = (const char *[]){ "pcie_mux" }, 726 + .num_parents = 1, 727 + .flags = CLK_SET_RATE_PARENT, 728 + }, 729 + }; 730 + 731 + static struct clk_regmap axg_pcie_cml_en0 = { 732 + .data = &(struct clk_regmap_gate_data){ 733 + .offset = HHI_PCIE_PLL_CNTL6, 734 + .bit_idx = 4, 735 + }, 736 + .hw.init = &(struct clk_init_data) { 737 + .name = "pcie_cml_en0", 738 + .ops = &clk_regmap_gate_ops, 739 + .parent_names = (const char *[]){ "pcie_ref" }, 740 + .num_parents = 1, 741 + .flags = CLK_SET_RATE_PARENT, 742 + 743 + }, 744 + }; 745 + 746 + static struct clk_regmap axg_pcie_cml_en1 = { 747 + .data = &(struct clk_regmap_gate_data){ 748 + .offset = HHI_PCIE_PLL_CNTL6, 749 + .bit_idx = 3, 750 + }, 751 + .hw.init = &(struct clk_init_data) { 752 + .name = "pcie_cml_en1", 753 + .ops = &clk_regmap_gate_ops, 754 + .parent_names = (const char *[]){ "pcie_ref" }, 755 + .num_parents = 1, 756 + .flags = CLK_SET_RATE_PARENT, 757 + }, 758 + }; 759 + 628 760 static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; 629 761 static const char * const clk81_parent_names[] = { 630 762 "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4", ··· 909 779 }, 910 780 }; 911 781 782 + static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 783 + 9, 10, 11, 13, 14, }; 784 + static const char * const gen_clk_parent_names[] = { 785 + "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3", 786 + "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 787 + }; 788 + 789 + static struct clk_regmap axg_gen_clk_sel = { 790 + .data = &(struct clk_regmap_mux_data){ 791 + .offset = HHI_GEN_CLK_CNTL, 792 + .mask = 0xf, 793 + .shift = 12, 794 + .table = mux_table_gen_clk, 795 + }, 796 + .hw.init = &(struct clk_init_data){ 797 + .name = "gen_clk_sel", 798 + .ops = &clk_regmap_mux_ops, 799 + /* 800 + * bits 15:12 selects from 14 possible parents: 801 + * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], 802 + * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4, 803 + * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll 804 + */ 805 + .parent_names = gen_clk_parent_names, 806 + .num_parents = ARRAY_SIZE(gen_clk_parent_names), 807 + }, 808 + }; 809 + 810 + static struct clk_regmap axg_gen_clk_div = { 811 + .data = &(struct clk_regmap_div_data){ 812 + .offset = HHI_GEN_CLK_CNTL, 813 + .shift = 0, 814 + .width = 11, 815 + }, 816 + .hw.init = &(struct clk_init_data){ 817 + .name = "gen_clk_div", 818 + .ops = &clk_regmap_divider_ops, 819 + .parent_names = (const char *[]){ "gen_clk_sel" }, 820 + .num_parents = 1, 821 + .flags = CLK_SET_RATE_PARENT, 822 + }, 823 + }; 824 + 825 + static struct clk_regmap axg_gen_clk = { 826 + .data = &(struct clk_regmap_gate_data){ 827 + .offset = HHI_GEN_CLK_CNTL, 828 + .bit_idx = 7, 829 + }, 830 + .hw.init = &(struct clk_init_data){ 831 + .name = "gen_clk", 832 + .ops = &clk_regmap_gate_ops, 833 + .parent_names = (const char *[]){ "gen_clk_div" }, 834 + .num_parents = 1, 835 + .flags = CLK_SET_RATE_PARENT, 836 + }, 837 + }; 838 + 912 839 /* Everything Else (EE) domain gates */ 913 840 static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); 914 841 static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); ··· 1008 821 static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); 1009 822 static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); 1010 823 static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); 824 + static MESON_GATE(axg_mipi_enable, HHI_MIPI_CNTL0, 29); 1011 825 1012 826 /* Always On (AO) domain gates */ 1013 827 ··· 1098 910 [CLKID_FCLK_DIV4_DIV] = &axg_fclk_div4_div.hw, 1099 911 [CLKID_FCLK_DIV5_DIV] = &axg_fclk_div5_div.hw, 1100 912 [CLKID_FCLK_DIV7_DIV] = &axg_fclk_div7_div.hw, 913 + [CLKID_PCIE_PLL] = &axg_pcie_pll.hw, 914 + [CLKID_PCIE_MUX] = &axg_pcie_mux.hw, 915 + [CLKID_PCIE_REF] = &axg_pcie_ref.hw, 916 + [CLKID_PCIE_CML_EN0] = &axg_pcie_cml_en0.hw, 917 + [CLKID_PCIE_CML_EN1] = &axg_pcie_cml_en1.hw, 918 + [CLKID_MIPI_ENABLE] = &axg_mipi_enable.hw, 919 + [CLKID_GEN_CLK_SEL] = &axg_gen_clk_sel.hw, 920 + [CLKID_GEN_CLK_DIV] = &axg_gen_clk_div.hw, 921 + [CLKID_GEN_CLK] = &axg_gen_clk.hw, 1101 922 [NR_CLKS] = NULL, 1102 923 }, 1103 924 .num = NR_CLKS, ··· 1185 988 &axg_fclk_div4, 1186 989 &axg_fclk_div5, 1187 990 &axg_fclk_div7, 991 + &axg_pcie_pll, 992 + &axg_pcie_mux, 993 + &axg_pcie_ref, 994 + &axg_pcie_cml_en0, 995 + &axg_pcie_cml_en1, 996 + &axg_mipi_enable, 997 + &axg_gen_clk_sel, 998 + &axg_gen_clk_div, 999 + &axg_gen_clk, 1188 1000 }; 1189 1001 1190 1002 static const struct of_device_id clkc_match_table[] = { ··· 1201 995 {} 1202 996 }; 1203 997 1204 - static const struct regmap_config clkc_regmap_config = { 1205 - .reg_bits = 32, 1206 - .val_bits = 32, 1207 - .reg_stride = 4, 1208 - }; 1209 - 1210 998 static int axg_clkc_probe(struct platform_device *pdev) 1211 999 { 1212 1000 struct device *dev = &pdev->dev; 1213 - struct resource *res; 1214 - void __iomem *clk_base = NULL; 1215 1001 struct regmap *map; 1216 1002 int ret, i; 1217 1003 1218 1004 /* Get the hhi system controller node if available */ 1219 1005 map = syscon_node_to_regmap(of_get_parent(dev->of_node)); 1220 1006 if (IS_ERR(map)) { 1221 - dev_err(dev, 1222 - "failed to get HHI regmap - Trying obsolete regs\n"); 1223 - 1224 - /* 1225 - * FIXME: HHI registers should be accessed through 1226 - * the appropriate system controller. This is required because 1227 - * there is more than just clocks in this register space 1228 - * 1229 - * This fallback method is only provided temporarily until 1230 - * all the platform DTs are properly using the syscon node 1231 - */ 1232 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1233 - if (!res) 1234 - return -EINVAL; 1235 - 1236 - 1237 - clk_base = devm_ioremap(dev, res->start, resource_size(res)); 1238 - if (!clk_base) { 1239 - dev_err(dev, "Unable to map clk base\n"); 1240 - return -ENXIO; 1241 - } 1242 - 1243 - map = devm_regmap_init_mmio(dev, clk_base, 1244 - &clkc_regmap_config); 1245 - if (IS_ERR(map)) 1246 - return PTR_ERR(map); 1007 + dev_err(dev, "failed to get HHI regmap\n"); 1008 + return PTR_ERR(map); 1247 1009 } 1248 1010 1249 1011 /* Populate regmap for the regmap backed clocks */
+7 -1
drivers/clk/meson/axg.h
··· 16 16 * Register offsets from the data sheet must be multiplied by 4 before 17 17 * adding them to the base address to get the right value. 18 18 */ 19 + #define HHI_MIPI_CNTL0 0x00 19 20 #define HHI_GP0_PLL_CNTL 0x40 20 21 #define HHI_GP0_PLL_CNTL2 0x44 21 22 #define HHI_GP0_PLL_CNTL3 0x48 ··· 128 127 #define CLKID_FCLK_DIV4_DIV 73 129 128 #define CLKID_FCLK_DIV5_DIV 74 130 129 #define CLKID_FCLK_DIV7_DIV 75 130 + #define CLKID_PCIE_PLL 76 131 + #define CLKID_PCIE_MUX 77 132 + #define CLKID_PCIE_REF 78 133 + #define CLKID_GEN_CLK_SEL 82 134 + #define CLKID_GEN_CLK_DIV 83 131 135 132 - #define NR_CLKS 76 136 + #define NR_CLKS 85 133 137 134 138 /* include the CLKIDs that have been made part of the DT binding */ 135 139 #include <dt-bindings/clock/axg-clkc.h>
-110
drivers/clk/meson/clk-audio-divider.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Copyright (c) 2017 AmLogic, Inc. 4 - * Author: Jerome Brunet <jbrunet@baylibre.com> 5 - */ 6 - 7 - /* 8 - * i2s master clock divider: The algorithm of the generic clk-divider used with 9 - * a very precise clock parent such as the mpll tends to select a low divider 10 - * factor. This gives poor results with this particular divider, especially with 11 - * high frequencies (> 100 MHz) 12 - * 13 - * This driver try to select the maximum possible divider with the rate the 14 - * upstream clock can provide. 15 - */ 16 - 17 - #include <linux/clk-provider.h> 18 - #include "clkc.h" 19 - 20 - static inline struct meson_clk_audio_div_data * 21 - meson_clk_audio_div_data(struct clk_regmap *clk) 22 - { 23 - return (struct meson_clk_audio_div_data *)clk->data; 24 - } 25 - 26 - static int _div_round(unsigned long parent_rate, unsigned long rate, 27 - unsigned long flags) 28 - { 29 - if (flags & CLK_DIVIDER_ROUND_CLOSEST) 30 - return DIV_ROUND_CLOSEST_ULL((u64)parent_rate, rate); 31 - 32 - return DIV_ROUND_UP_ULL((u64)parent_rate, rate); 33 - } 34 - 35 - static int _get_val(unsigned long parent_rate, unsigned long rate) 36 - { 37 - return DIV_ROUND_UP_ULL((u64)parent_rate, rate) - 1; 38 - } 39 - 40 - static int _valid_divider(unsigned int width, int divider) 41 - { 42 - int max_divider = 1 << width; 43 - 44 - return clamp(divider, 1, max_divider); 45 - } 46 - 47 - static unsigned long audio_divider_recalc_rate(struct clk_hw *hw, 48 - unsigned long parent_rate) 49 - { 50 - struct clk_regmap *clk = to_clk_regmap(hw); 51 - struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); 52 - unsigned long divider; 53 - 54 - divider = meson_parm_read(clk->map, &adiv->div) + 1; 55 - 56 - return DIV_ROUND_UP_ULL((u64)parent_rate, divider); 57 - } 58 - 59 - static long audio_divider_round_rate(struct clk_hw *hw, 60 - unsigned long rate, 61 - unsigned long *parent_rate) 62 - { 63 - struct clk_regmap *clk = to_clk_regmap(hw); 64 - struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); 65 - unsigned long max_prate; 66 - int divider; 67 - 68 - if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 69 - divider = _div_round(*parent_rate, rate, adiv->flags); 70 - divider = _valid_divider(adiv->div.width, divider); 71 - return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); 72 - } 73 - 74 - /* Get the maximum parent rate */ 75 - max_prate = clk_hw_round_rate(clk_hw_get_parent(hw), ULONG_MAX); 76 - 77 - /* Get the corresponding rounded down divider */ 78 - divider = max_prate / rate; 79 - divider = _valid_divider(adiv->div.width, divider); 80 - 81 - /* Get actual rate of the parent */ 82 - *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 83 - divider * rate); 84 - 85 - return DIV_ROUND_UP_ULL((u64)*parent_rate, divider); 86 - } 87 - 88 - static int audio_divider_set_rate(struct clk_hw *hw, 89 - unsigned long rate, 90 - unsigned long parent_rate) 91 - { 92 - struct clk_regmap *clk = to_clk_regmap(hw); 93 - struct meson_clk_audio_div_data *adiv = meson_clk_audio_div_data(clk); 94 - int val = _get_val(parent_rate, rate); 95 - 96 - meson_parm_write(clk->map, &adiv->div, val); 97 - 98 - return 0; 99 - } 100 - 101 - const struct clk_ops meson_clk_audio_divider_ro_ops = { 102 - .recalc_rate = audio_divider_recalc_rate, 103 - .round_rate = audio_divider_round_rate, 104 - }; 105 - 106 - const struct clk_ops meson_clk_audio_divider_ops = { 107 - .recalc_rate = audio_divider_recalc_rate, 108 - .round_rate = audio_divider_round_rate, 109 - .set_rate = audio_divider_set_rate, 110 - };
+63
drivers/clk/meson/clk-phase.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include "clkc.h" 9 + 10 + #define phase_step(_width) (360 / (1 << (_width))) 11 + 12 + static inline struct meson_clk_phase_data * 13 + meson_clk_phase_data(struct clk_regmap *clk) 14 + { 15 + return (struct meson_clk_phase_data *)clk->data; 16 + } 17 + 18 + int meson_clk_degrees_from_val(unsigned int val, unsigned int width) 19 + { 20 + return phase_step(width) * val; 21 + } 22 + EXPORT_SYMBOL_GPL(meson_clk_degrees_from_val); 23 + 24 + unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width) 25 + { 26 + unsigned int val = DIV_ROUND_CLOSEST(degrees, phase_step(width)); 27 + 28 + /* 29 + * This last calculation is here for cases when degrees is rounded 30 + * to 360, in which case val == (1 << width). 31 + */ 32 + return val % (1 << width); 33 + } 34 + EXPORT_SYMBOL_GPL(meson_clk_degrees_to_val); 35 + 36 + static int meson_clk_phase_get_phase(struct clk_hw *hw) 37 + { 38 + struct clk_regmap *clk = to_clk_regmap(hw); 39 + struct meson_clk_phase_data *phase = meson_clk_phase_data(clk); 40 + unsigned int val; 41 + 42 + val = meson_parm_read(clk->map, &phase->ph); 43 + 44 + return meson_clk_degrees_from_val(val, phase->ph.width); 45 + } 46 + 47 + static int meson_clk_phase_set_phase(struct clk_hw *hw, int degrees) 48 + { 49 + struct clk_regmap *clk = to_clk_regmap(hw); 50 + struct meson_clk_phase_data *phase = meson_clk_phase_data(clk); 51 + unsigned int val; 52 + 53 + val = meson_clk_degrees_to_val(degrees, phase->ph.width); 54 + meson_parm_write(clk->map, &phase->ph, val); 55 + 56 + return 0; 57 + } 58 + 59 + const struct clk_ops meson_clk_phase_ops = { 60 + .get_phase = meson_clk_phase_get_phase, 61 + .set_phase = meson_clk_phase_set_phase, 62 + }; 63 + EXPORT_SYMBOL_GPL(meson_clk_phase_ops);
+68
drivers/clk/meson/clk-triphase.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include "clkc-audio.h" 9 + 10 + /* 11 + * This is a special clock for the audio controller. 12 + * The phase of mst_sclk clock output can be controlled independently 13 + * for the outside world (ph0), the tdmout (ph1) and tdmin (ph2). 14 + * Controlling these 3 phases as just one makes things simpler and 15 + * give the same clock view to all the element on the i2s bus. 16 + * If necessary, we can still control the phase in the tdm block 17 + * which makes these independent control redundant. 18 + */ 19 + static inline struct meson_clk_triphase_data * 20 + meson_clk_triphase_data(struct clk_regmap *clk) 21 + { 22 + return (struct meson_clk_triphase_data *)clk->data; 23 + } 24 + 25 + static void meson_clk_triphase_sync(struct clk_hw *hw) 26 + { 27 + struct clk_regmap *clk = to_clk_regmap(hw); 28 + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); 29 + unsigned int val; 30 + 31 + /* Get phase 0 and sync it to phase 1 and 2 */ 32 + val = meson_parm_read(clk->map, &tph->ph0); 33 + meson_parm_write(clk->map, &tph->ph1, val); 34 + meson_parm_write(clk->map, &tph->ph2, val); 35 + } 36 + 37 + static int meson_clk_triphase_get_phase(struct clk_hw *hw) 38 + { 39 + struct clk_regmap *clk = to_clk_regmap(hw); 40 + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); 41 + unsigned int val; 42 + 43 + /* Phase are in sync, reading phase 0 is enough */ 44 + val = meson_parm_read(clk->map, &tph->ph0); 45 + 46 + return meson_clk_degrees_from_val(val, tph->ph0.width); 47 + } 48 + 49 + static int meson_clk_triphase_set_phase(struct clk_hw *hw, int degrees) 50 + { 51 + struct clk_regmap *clk = to_clk_regmap(hw); 52 + struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk); 53 + unsigned int val; 54 + 55 + val = meson_clk_degrees_to_val(degrees, tph->ph0.width); 56 + meson_parm_write(clk->map, &tph->ph0, val); 57 + meson_parm_write(clk->map, &tph->ph1, val); 58 + meson_parm_write(clk->map, &tph->ph2, val); 59 + 60 + return 0; 61 + } 62 + 63 + const struct clk_ops meson_clk_triphase_ops = { 64 + .init = meson_clk_triphase_sync, 65 + .get_phase = meson_clk_triphase_get_phase, 66 + .set_phase = meson_clk_triphase_set_phase, 67 + }; 68 + EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
+28
drivers/clk/meson/clkc-audio.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef __MESON_CLKC_AUDIO_H 8 + #define __MESON_CLKC_AUDIO_H 9 + 10 + #include "clkc.h" 11 + 12 + struct meson_clk_triphase_data { 13 + struct parm ph0; 14 + struct parm ph1; 15 + struct parm ph2; 16 + }; 17 + 18 + struct meson_sclk_div_data { 19 + struct parm div; 20 + struct parm hi; 21 + unsigned int cached_div; 22 + struct clk_duty cached_duty; 23 + }; 24 + 25 + extern const struct clk_ops meson_clk_triphase_ops; 26 + extern const struct clk_ops meson_sclk_div_ops; 27 + 28 + #endif /* __MESON_CLKC_AUDIO_H */
+6 -5
drivers/clk/meson/clkc.h
··· 91 91 92 92 #define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) 93 93 94 - struct meson_clk_audio_div_data { 95 - struct parm div; 96 - u8 flags; 94 + struct meson_clk_phase_data { 95 + struct parm ph; 97 96 }; 97 + 98 + int meson_clk_degrees_from_val(unsigned int val, unsigned int width); 99 + unsigned int meson_clk_degrees_to_val(int degrees, unsigned int width); 98 100 99 101 #define MESON_GATE(_name, _reg, _bit) \ 100 102 struct clk_regmap _name = { \ ··· 119 117 extern const struct clk_ops meson_clk_cpu_ops; 120 118 extern const struct clk_ops meson_clk_mpll_ro_ops; 121 119 extern const struct clk_ops meson_clk_mpll_ops; 122 - extern const struct clk_ops meson_clk_audio_divider_ro_ops; 123 - extern const struct clk_ops meson_clk_audio_divider_ops; 120 + extern const struct clk_ops meson_clk_phase_ops; 124 121 125 122 #endif /* __CLKC_H */
+75 -43
drivers/clk/meson/gxbb.c
··· 7 7 #include <linux/clk.h> 8 8 #include <linux/clk-provider.h> 9 9 #include <linux/init.h> 10 - #include <linux/of_address.h> 11 10 #include <linux/of_device.h> 12 11 #include <linux/mfd/syscon.h> 13 12 #include <linux/platform_device.h> ··· 970 971 .mask = 0x3, 971 972 .shift = 9, 972 973 .table = (u32[]){ 1, 2, 3 }, 974 + .flags = CLK_MUX_ROUND_CLOSEST, 973 975 }, 974 976 .hw.init = &(struct clk_init_data){ 975 977 .name = "cts_amclk_sel", 976 978 .ops = &clk_regmap_mux_ops, 977 979 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 978 980 .num_parents = 3, 979 - .flags = CLK_SET_RATE_PARENT, 980 981 }, 981 982 }; 982 983 983 984 static struct clk_regmap gxbb_cts_amclk_div = { 984 - .data = &(struct meson_clk_audio_div_data){ 985 - .div = { 986 - .reg_off = HHI_AUD_CLK_CNTL, 987 - .shift = 0, 988 - .width = 8, 989 - }, 985 + .data = &(struct clk_regmap_div_data) { 986 + .offset = HHI_AUD_CLK_CNTL, 987 + .shift = 0, 988 + .width = 8, 990 989 .flags = CLK_DIVIDER_ROUND_CLOSEST, 991 990 }, 992 991 .hw.init = &(struct clk_init_data){ 993 992 .name = "cts_amclk_div", 994 - .ops = &meson_clk_audio_divider_ops, 993 + .ops = &clk_regmap_divider_ops, 995 994 .parent_names = (const char *[]){ "cts_amclk_sel" }, 996 995 .num_parents = 1, 997 996 .flags = CLK_SET_RATE_PARENT, ··· 1016 1019 .mask = 0x3, 1017 1020 .shift = 25, 1018 1021 .table = (u32[]){ 1, 2, 3 }, 1022 + .flags = CLK_MUX_ROUND_CLOSEST, 1019 1023 }, 1020 1024 .hw.init = &(struct clk_init_data) { 1021 1025 .name = "cts_mclk_i958_sel", 1022 1026 .ops = &clk_regmap_mux_ops, 1023 1027 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, 1024 1028 .num_parents = 3, 1025 - .flags = CLK_SET_RATE_PARENT, 1026 1029 }, 1027 1030 }; 1028 1031 ··· 1624 1627 }, 1625 1628 }; 1626 1629 1630 + static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8, 1631 + 9, 10, 11, 13, 14, }; 1632 + static const char * const gen_clk_parent_names[] = { 1633 + "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2", 1634 + "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll", 1635 + }; 1636 + 1637 + static struct clk_regmap gxbb_gen_clk_sel = { 1638 + .data = &(struct clk_regmap_mux_data){ 1639 + .offset = HHI_GEN_CLK_CNTL, 1640 + .mask = 0xf, 1641 + .shift = 12, 1642 + .table = mux_table_gen_clk, 1643 + }, 1644 + .hw.init = &(struct clk_init_data){ 1645 + .name = "gen_clk_sel", 1646 + .ops = &clk_regmap_mux_ops, 1647 + /* 1648 + * bits 15:12 selects from 14 possible parents: 1649 + * xtal, [rtc_oscin_i], [sys_cpu_div16], [ddr_dpll_pt], 1650 + * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4, 1651 + * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll 1652 + */ 1653 + .parent_names = gen_clk_parent_names, 1654 + .num_parents = ARRAY_SIZE(gen_clk_parent_names), 1655 + }, 1656 + }; 1657 + 1658 + static struct clk_regmap gxbb_gen_clk_div = { 1659 + .data = &(struct clk_regmap_div_data){ 1660 + .offset = HHI_GEN_CLK_CNTL, 1661 + .shift = 0, 1662 + .width = 11, 1663 + }, 1664 + .hw.init = &(struct clk_init_data){ 1665 + .name = "gen_clk_div", 1666 + .ops = &clk_regmap_divider_ops, 1667 + .parent_names = (const char *[]){ "gen_clk_sel" }, 1668 + .num_parents = 1, 1669 + .flags = CLK_SET_RATE_PARENT, 1670 + }, 1671 + }; 1672 + 1673 + static struct clk_regmap gxbb_gen_clk = { 1674 + .data = &(struct clk_regmap_gate_data){ 1675 + .offset = HHI_GEN_CLK_CNTL, 1676 + .bit_idx = 7, 1677 + }, 1678 + .hw.init = &(struct clk_init_data){ 1679 + .name = "gen_clk", 1680 + .ops = &clk_regmap_gate_ops, 1681 + .parent_names = (const char *[]){ "gen_clk_div" }, 1682 + .num_parents = 1, 1683 + .flags = CLK_SET_RATE_PARENT, 1684 + }, 1685 + }; 1686 + 1627 1687 /* Everything Else (EE) domain gates */ 1628 1688 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0); 1629 1689 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1); ··· 1930 1876 [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, 1931 1877 [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, 1932 1878 [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, 1879 + [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, 1880 + [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, 1881 + [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, 1933 1882 [NR_CLKS] = NULL, 1934 1883 }, 1935 1884 .num = NR_CLKS, ··· 2095 2038 [CLKID_VDEC_HEVC_SEL] = &gxbb_vdec_hevc_sel.hw, 2096 2039 [CLKID_VDEC_HEVC_DIV] = &gxbb_vdec_hevc_div.hw, 2097 2040 [CLKID_VDEC_HEVC] = &gxbb_vdec_hevc.hw, 2041 + [CLKID_GEN_CLK_SEL] = &gxbb_gen_clk_sel.hw, 2042 + [CLKID_GEN_CLK_DIV] = &gxbb_gen_clk_div.hw, 2043 + [CLKID_GEN_CLK] = &gxbb_gen_clk.hw, 2098 2044 [NR_CLKS] = NULL, 2099 2045 }, 2100 2046 .num = NR_CLKS, ··· 2262 2202 &gxbb_vdec_hevc_sel, 2263 2203 &gxbb_vdec_hevc_div, 2264 2204 &gxbb_vdec_hevc, 2205 + &gxbb_gen_clk_sel, 2206 + &gxbb_gen_clk_div, 2207 + &gxbb_gen_clk, 2265 2208 }; 2266 2209 2267 2210 struct clkc_data { ··· 2291 2228 {}, 2292 2229 }; 2293 2230 2294 - static const struct regmap_config clkc_regmap_config = { 2295 - .reg_bits = 32, 2296 - .val_bits = 32, 2297 - .reg_stride = 4, 2298 - }; 2299 - 2300 2231 static int gxbb_clkc_probe(struct platform_device *pdev) 2301 2232 { 2302 2233 const struct clkc_data *clkc_data; 2303 - struct resource *res; 2304 - void __iomem *clk_base; 2305 2234 struct regmap *map; 2306 2235 int ret, i; 2307 2236 struct device *dev = &pdev->dev; ··· 2305 2250 /* Get the hhi system controller node if available */ 2306 2251 map = syscon_node_to_regmap(of_get_parent(dev->of_node)); 2307 2252 if (IS_ERR(map)) { 2308 - dev_err(dev, 2309 - "failed to get HHI regmap - Trying obsolete regs\n"); 2310 - 2311 - /* 2312 - * FIXME: HHI registers should be accessed through 2313 - * the appropriate system controller. This is required because 2314 - * there is more than just clocks in this register space 2315 - * 2316 - * This fallback method is only provided temporarily until 2317 - * all the platform DTs are properly using the syscon node 2318 - */ 2319 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2320 - if (!res) 2321 - return -EINVAL; 2322 - 2323 - clk_base = devm_ioremap(dev, res->start, resource_size(res)); 2324 - if (!clk_base) { 2325 - dev_err(dev, "Unable to map clk base\n"); 2326 - return -ENXIO; 2327 - } 2328 - 2329 - map = devm_regmap_init_mmio(dev, clk_base, 2330 - &clkc_regmap_config); 2331 - if (IS_ERR(map)) 2332 - return PTR_ERR(map); 2253 + dev_err(dev, "failed to get HHI regmap\n"); 2254 + return PTR_ERR(map); 2333 2255 } 2334 2256 2335 2257 /* Populate regmap for the common regmap backed clocks */
+3 -2
drivers/clk/meson/gxbb.h
··· 66 66 #define HHI_USB_CLK_CNTL 0x220 /* 0x88 offset in data sheet */ 67 67 #define HHI_32K_CLK_CNTL 0x224 /* 0x89 offset in data sheet */ 68 68 #define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */ 69 - #define HHI_GEN_CLK_CNTL 0x228 /* 0x8a offset in data sheet */ 70 69 71 70 #define HHI_PCM_CLK_CNTL 0x258 /* 0x96 offset in data sheet */ 72 71 #define HHI_NAND_CLK_CNTL 0x25C /* 0x97 offset in data sheet */ ··· 157 158 #define CLKID_VDEC_1_DIV 152 158 159 #define CLKID_VDEC_HEVC_SEL 154 159 160 #define CLKID_VDEC_HEVC_DIV 155 161 + #define CLKID_GEN_CLK_SEL 157 162 + #define CLKID_GEN_CLK_DIV 158 160 163 161 - #define NR_CLKS 157 164 + #define NR_CLKS 160 162 165 163 166 /* include the CLKIDs that have been made part of the DT binding */ 164 167 #include <dt-bindings/clock/gxbb-clkc.h>
+243
drivers/clk/meson/sclk-div.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 + /* 3 + * Copyright (c) 2018 BayLibre, SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + * 6 + * Sample clock generator divider: 7 + * This HW divider gates with value 0 but is otherwise a zero based divider: 8 + * 9 + * val >= 1 10 + * divider = val + 1 11 + * 12 + * The duty cycle may also be set for the LR clock variant. The duty cycle 13 + * ratio is: 14 + * 15 + * hi = [0 - val] 16 + * duty_cycle = (1 + hi) / (1 + val) 17 + */ 18 + 19 + #include "clkc-audio.h" 20 + 21 + static inline struct meson_sclk_div_data * 22 + meson_sclk_div_data(struct clk_regmap *clk) 23 + { 24 + return (struct meson_sclk_div_data *)clk->data; 25 + } 26 + 27 + static int sclk_div_maxval(struct meson_sclk_div_data *sclk) 28 + { 29 + return (1 << sclk->div.width) - 1; 30 + } 31 + 32 + static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk) 33 + { 34 + return sclk_div_maxval(sclk) + 1; 35 + } 36 + 37 + static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate, 38 + unsigned long prate, int maxdiv) 39 + { 40 + int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate); 41 + 42 + return clamp(div, 2, maxdiv); 43 + } 44 + 45 + static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate, 46 + unsigned long *prate, 47 + struct meson_sclk_div_data *sclk) 48 + { 49 + struct clk_hw *parent = clk_hw_get_parent(hw); 50 + int bestdiv = 0, i; 51 + unsigned long maxdiv, now, parent_now; 52 + unsigned long best = 0, best_parent = 0; 53 + 54 + if (!rate) 55 + rate = 1; 56 + 57 + maxdiv = sclk_div_maxdiv(sclk); 58 + 59 + if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) 60 + return sclk_div_getdiv(hw, rate, *prate, maxdiv); 61 + 62 + /* 63 + * The maximum divider we can use without overflowing 64 + * unsigned long in rate * i below 65 + */ 66 + maxdiv = min(ULONG_MAX / rate, maxdiv); 67 + 68 + for (i = 2; i <= maxdiv; i++) { 69 + /* 70 + * It's the most ideal case if the requested rate can be 71 + * divided from parent clock without needing to change 72 + * parent rate, so return the divider immediately. 73 + */ 74 + if (rate * i == *prate) 75 + return i; 76 + 77 + parent_now = clk_hw_round_rate(parent, rate * i); 78 + now = DIV_ROUND_UP_ULL((u64)parent_now, i); 79 + 80 + if (abs(rate - now) < abs(rate - best)) { 81 + bestdiv = i; 82 + best = now; 83 + best_parent = parent_now; 84 + } 85 + } 86 + 87 + if (!bestdiv) 88 + bestdiv = sclk_div_maxdiv(sclk); 89 + else 90 + *prate = best_parent; 91 + 92 + return bestdiv; 93 + } 94 + 95 + static long sclk_div_round_rate(struct clk_hw *hw, unsigned long rate, 96 + unsigned long *prate) 97 + { 98 + struct clk_regmap *clk = to_clk_regmap(hw); 99 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 100 + int div; 101 + 102 + div = sclk_div_bestdiv(hw, rate, prate, sclk); 103 + 104 + return DIV_ROUND_UP_ULL((u64)*prate, div); 105 + } 106 + 107 + static void sclk_apply_ratio(struct clk_regmap *clk, 108 + struct meson_sclk_div_data *sclk) 109 + { 110 + unsigned int hi = DIV_ROUND_CLOSEST(sclk->cached_div * 111 + sclk->cached_duty.num, 112 + sclk->cached_duty.den); 113 + 114 + if (hi) 115 + hi -= 1; 116 + 117 + meson_parm_write(clk->map, &sclk->hi, hi); 118 + } 119 + 120 + static int sclk_div_set_duty_cycle(struct clk_hw *hw, 121 + struct clk_duty *duty) 122 + { 123 + struct clk_regmap *clk = to_clk_regmap(hw); 124 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 125 + 126 + if (MESON_PARM_APPLICABLE(&sclk->hi)) { 127 + memcpy(&sclk->cached_duty, duty, sizeof(*duty)); 128 + sclk_apply_ratio(clk, sclk); 129 + } 130 + 131 + return 0; 132 + } 133 + 134 + static int sclk_div_get_duty_cycle(struct clk_hw *hw, 135 + struct clk_duty *duty) 136 + { 137 + struct clk_regmap *clk = to_clk_regmap(hw); 138 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 139 + int hi; 140 + 141 + if (!MESON_PARM_APPLICABLE(&sclk->hi)) { 142 + duty->num = 1; 143 + duty->den = 2; 144 + return 0; 145 + } 146 + 147 + hi = meson_parm_read(clk->map, &sclk->hi); 148 + duty->num = hi + 1; 149 + duty->den = sclk->cached_div; 150 + return 0; 151 + } 152 + 153 + static void sclk_apply_divider(struct clk_regmap *clk, 154 + struct meson_sclk_div_data *sclk) 155 + { 156 + if (MESON_PARM_APPLICABLE(&sclk->hi)) 157 + sclk_apply_ratio(clk, sclk); 158 + 159 + meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1); 160 + } 161 + 162 + static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate, 163 + unsigned long prate) 164 + { 165 + struct clk_regmap *clk = to_clk_regmap(hw); 166 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 167 + unsigned long maxdiv = sclk_div_maxdiv(sclk); 168 + 169 + sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv); 170 + 171 + if (clk_hw_is_enabled(hw)) 172 + sclk_apply_divider(clk, sclk); 173 + 174 + return 0; 175 + } 176 + 177 + static unsigned long sclk_div_recalc_rate(struct clk_hw *hw, 178 + unsigned long prate) 179 + { 180 + struct clk_regmap *clk = to_clk_regmap(hw); 181 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 182 + 183 + return DIV_ROUND_UP_ULL((u64)prate, sclk->cached_div); 184 + } 185 + 186 + static int sclk_div_enable(struct clk_hw *hw) 187 + { 188 + struct clk_regmap *clk = to_clk_regmap(hw); 189 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 190 + 191 + sclk_apply_divider(clk, sclk); 192 + 193 + return 0; 194 + } 195 + 196 + static void sclk_div_disable(struct clk_hw *hw) 197 + { 198 + struct clk_regmap *clk = to_clk_regmap(hw); 199 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 200 + 201 + meson_parm_write(clk->map, &sclk->div, 0); 202 + } 203 + 204 + static int sclk_div_is_enabled(struct clk_hw *hw) 205 + { 206 + struct clk_regmap *clk = to_clk_regmap(hw); 207 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 208 + 209 + if (meson_parm_read(clk->map, &sclk->div)) 210 + return 1; 211 + 212 + return 0; 213 + } 214 + 215 + static void sclk_div_init(struct clk_hw *hw) 216 + { 217 + struct clk_regmap *clk = to_clk_regmap(hw); 218 + struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk); 219 + unsigned int val; 220 + 221 + val = meson_parm_read(clk->map, &sclk->div); 222 + 223 + /* if the divider is initially disabled, assume max */ 224 + if (!val) 225 + sclk->cached_div = sclk_div_maxdiv(sclk); 226 + else 227 + sclk->cached_div = val + 1; 228 + 229 + sclk_div_get_duty_cycle(hw, &sclk->cached_duty); 230 + } 231 + 232 + const struct clk_ops meson_sclk_div_ops = { 233 + .recalc_rate = sclk_div_recalc_rate, 234 + .round_rate = sclk_div_round_rate, 235 + .set_rate = sclk_div_set_rate, 236 + .enable = sclk_div_enable, 237 + .disable = sclk_div_disable, 238 + .is_enabled = sclk_div_is_enabled, 239 + .get_duty_cycle = sclk_div_get_duty_cycle, 240 + .set_duty_cycle = sclk_div_set_duty_cycle, 241 + .init = sclk_div_init, 242 + }; 243 + EXPORT_SYMBOL_GPL(meson_sclk_div_ops);
+1 -8
drivers/clk/mvebu/armada-37xx-periph.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 1 2 /* 2 3 * Marvell Armada 37xx SoC Peripheral clocks 3 4 * 4 5 * Copyright (C) 2016 Marvell 5 6 * 6 7 * Gregory CLEMENT <gregory.clement@free-electrons.com> 7 - * 8 - * This file is licensed under the terms of the GNU General Public 9 - * License version 2 or later. This program is licensed "as is" 10 - * without any warranty of any kind, whether express or implied. 11 8 * 12 9 * Most of the peripheral clocks can be modelled like this: 13 10 * _____ _______ _______ ··· 416 419 static u8 clk_pm_cpu_get_parent(struct clk_hw *hw) 417 420 { 418 421 struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw); 419 - int num_parents = clk_hw_get_num_parents(hw); 420 422 u32 val; 421 423 422 424 if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) { ··· 424 428 val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux; 425 429 val &= pm_cpu->mask_mux; 426 430 } 427 - 428 - if (val >= num_parents) 429 - return -EINVAL; 430 431 431 432 return val; 432 433 }
+4 -2
drivers/clk/pxa/clk-pxa25x.c
··· 292 292 { 293 293 clk_register_fixed_rate(NULL, "osc_3_6864mhz", NULL, 294 294 CLK_GET_RATE_NOCACHE, 3686400); 295 - clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 296 - CLK_GET_RATE_NOCACHE, 32768); 295 + clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, 296 + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 297 + CLK_GET_RATE_NOCACHE, 298 + 32768)); 297 299 clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); 298 300 clk_register_fixed_factor(NULL, "ppll_95_85mhz", "osc_3_6864mhz", 299 301 0, 26, 1);
+4 -3
drivers/clk/pxa/clk-pxa27x.c
··· 314 314 clk_register_fixed_rate(NULL, "osc_13mhz", NULL, 315 315 CLK_GET_RATE_NOCACHE, 316 316 13 * MHz); 317 - clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 318 - CLK_GET_RATE_NOCACHE, 319 - 32768 * KHz); 317 + clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, 318 + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 319 + CLK_GET_RATE_NOCACHE, 320 + 32768 * KHz)); 320 321 clk_register_fixed_rate(NULL, "clk_dummy", NULL, 0, 0); 321 322 clk_register_fixed_factor(NULL, "ppll_312mhz", "osc_13mhz", 0, 24, 1); 322 323 }
+4 -3
drivers/clk/pxa/clk-pxa3xx.c
··· 286 286 clk_register_fixed_rate(NULL, "osc_13mhz", NULL, 287 287 CLK_GET_RATE_NOCACHE, 288 288 13 * MHz); 289 - clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 290 - CLK_GET_RATE_NOCACHE, 291 - 32768); 289 + clkdev_pxa_register(CLK_OSC32k768, "osc_32_768khz", NULL, 290 + clk_register_fixed_rate(NULL, "osc_32_768khz", NULL, 291 + CLK_GET_RATE_NOCACHE, 292 + 32768)); 292 293 clk_register_fixed_rate(NULL, "ring_osc_120mhz", NULL, 293 294 CLK_GET_RATE_NOCACHE, 294 295 120 * MHz);
+19
drivers/clk/qcom/Kconfig
··· 59 59 Say Y if you want to support the clocks exposed by the RPM on 60 60 platforms such as apq8016, apq8084, msm8974 etc. 61 61 62 + config QCOM_CLK_RPMH 63 + tristate "RPMh Clock Driver" 64 + depends on COMMON_CLK_QCOM && QCOM_RPMH 65 + help 66 + RPMh manages shared resources on some Qualcomm Technologies, Inc. 67 + SoCs. It accepts requests from other hardware subsystems via RSC. 68 + Say Y if you want to support the clocks exposed by RPMh on 69 + platforms such as SDM845. 70 + 62 71 config APQ_GCC_8084 63 72 tristate "APQ8084 Global Clock Controller" 64 73 select QCOM_GDSC ··· 253 244 Support for the video clock controller on SDM845 devices. 254 245 Say Y if you want to support video devices and functionality such as 255 246 video encode and decode. 247 + 248 + config SDM_DISPCC_845 249 + tristate "SDM845 Display Clock Controller" 250 + select SDM_GCC_845 251 + depends on COMMON_CLK_QCOM 252 + help 253 + Support for the display clock controller on Qualcomm Technologies, Inc 254 + SDM845 devices. 255 + Say Y if you want to support display devices and functionality such as 256 + splash screen. 256 257 257 258 config SPMI_PMIC_CLKDIV 258 259 tristate "SPMI PMIC clkdiv Support"
+2
drivers/clk/qcom/Makefile
··· 37 37 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o 38 38 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o 39 39 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o 40 + obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o 40 41 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o 42 + obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o 41 43 obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o 42 44 obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o 43 45 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
+1 -9
drivers/clk/qcom/clk-alpha-pll.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 4 */ 13 5 14 6 #include <linux/kernel.h>
+2 -12
drivers/clk/qcom/clk-alpha-pll.h
··· 1 - /* 2 - * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - */ 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved. */ 13 3 14 4 #ifndef __QCOM_CLK_ALPHA_PLL_H__ 15 5 #define __QCOM_CLK_ALPHA_PLL_H__
+1 -9
drivers/clk/qcom/clk-branch.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 4 */ 13 5 14 6 #include <linux/kernel.h>
+2 -12
drivers/clk/qcom/clk-branch.h
··· 1 - /* 2 - * Copyright (c) 2013, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - */ 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2013, The Linux Foundation. All rights reserved. */ 13 3 14 4 #ifndef __QCOM_CLK_BRANCH_H__ 15 5 #define __QCOM_CLK_BRANCH_H__
+2
drivers/clk/qcom/clk-rcg.h
··· 7 7 #include <linux/clk-provider.h> 8 8 #include "clk-regmap.h" 9 9 10 + #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 11 + 10 12 struct freq_tbl { 11 13 unsigned long freq; 12 14 u8 src;
+1 -9
drivers/clk/qcom/clk-regmap.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 4 */ 13 5 14 6 #include <linux/device.h>
+2 -12
drivers/clk/qcom/clk-regmap.h
··· 1 - /* 2 - * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - */ 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ 13 3 14 4 #ifndef __QCOM_CLK_REGMAP_H__ 15 5 #define __QCOM_CLK_REGMAP_H__
+329
drivers/clk/qcom/clk-rpmh.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/err.h> 8 + #include <linux/kernel.h> 9 + #include <linux/module.h> 10 + #include <linux/of.h> 11 + #include <linux/of_device.h> 12 + #include <linux/platform_device.h> 13 + #include <soc/qcom/cmd-db.h> 14 + #include <soc/qcom/rpmh.h> 15 + 16 + #include <dt-bindings/clock/qcom,rpmh.h> 17 + 18 + #define CLK_RPMH_ARC_EN_OFFSET 0 19 + #define CLK_RPMH_VRM_EN_OFFSET 4 20 + 21 + /** 22 + * struct clk_rpmh - individual rpmh clock data structure 23 + * @hw: handle between common and hardware-specific interfaces 24 + * @res_name: resource name for the rpmh clock 25 + * @div: clock divider to compute the clock rate 26 + * @res_addr: base address of the rpmh resource within the RPMh 27 + * @res_on_val: rpmh clock enable value 28 + * @state: rpmh clock requested state 29 + * @aggr_state: rpmh clock aggregated state 30 + * @last_sent_aggr_state: rpmh clock last aggr state sent to RPMh 31 + * @valid_state_mask: mask to determine the state of the rpmh clock 32 + * @dev: device to which it is attached 33 + * @peer: pointer to the clock rpmh sibling 34 + */ 35 + struct clk_rpmh { 36 + struct clk_hw hw; 37 + const char *res_name; 38 + u8 div; 39 + u32 res_addr; 40 + u32 res_on_val; 41 + u32 state; 42 + u32 aggr_state; 43 + u32 last_sent_aggr_state; 44 + u32 valid_state_mask; 45 + struct device *dev; 46 + struct clk_rpmh *peer; 47 + }; 48 + 49 + struct clk_rpmh_desc { 50 + struct clk_hw **clks; 51 + size_t num_clks; 52 + }; 53 + 54 + static DEFINE_MUTEX(rpmh_clk_lock); 55 + 56 + #define __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ 57 + _res_en_offset, _res_on, _div) \ 58 + static struct clk_rpmh _platform##_##_name_active; \ 59 + static struct clk_rpmh _platform##_##_name = { \ 60 + .res_name = _res_name, \ 61 + .res_addr = _res_en_offset, \ 62 + .res_on_val = _res_on, \ 63 + .div = _div, \ 64 + .peer = &_platform##_##_name_active, \ 65 + .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \ 66 + BIT(RPMH_ACTIVE_ONLY_STATE) | \ 67 + BIT(RPMH_SLEEP_STATE)), \ 68 + .hw.init = &(struct clk_init_data){ \ 69 + .ops = &clk_rpmh_ops, \ 70 + .name = #_name, \ 71 + .parent_names = (const char *[]){ "xo_board" }, \ 72 + .num_parents = 1, \ 73 + }, \ 74 + }; \ 75 + static struct clk_rpmh _platform##_##_name_active = { \ 76 + .res_name = _res_name, \ 77 + .res_addr = _res_en_offset, \ 78 + .res_on_val = _res_on, \ 79 + .div = _div, \ 80 + .peer = &_platform##_##_name, \ 81 + .valid_state_mask = (BIT(RPMH_WAKE_ONLY_STATE) | \ 82 + BIT(RPMH_ACTIVE_ONLY_STATE)), \ 83 + .hw.init = &(struct clk_init_data){ \ 84 + .ops = &clk_rpmh_ops, \ 85 + .name = #_name_active, \ 86 + .parent_names = (const char *[]){ "xo_board" }, \ 87 + .num_parents = 1, \ 88 + }, \ 89 + } 90 + 91 + #define DEFINE_CLK_RPMH_ARC(_platform, _name, _name_active, _res_name, \ 92 + _res_on, _div) \ 93 + __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ 94 + CLK_RPMH_ARC_EN_OFFSET, _res_on, _div) 95 + 96 + #define DEFINE_CLK_RPMH_VRM(_platform, _name, _name_active, _res_name, \ 97 + _div) \ 98 + __DEFINE_CLK_RPMH(_platform, _name, _name_active, _res_name, \ 99 + CLK_RPMH_VRM_EN_OFFSET, 1, _div) 100 + 101 + static inline struct clk_rpmh *to_clk_rpmh(struct clk_hw *_hw) 102 + { 103 + return container_of(_hw, struct clk_rpmh, hw); 104 + } 105 + 106 + static inline bool has_state_changed(struct clk_rpmh *c, u32 state) 107 + { 108 + return (c->last_sent_aggr_state & BIT(state)) 109 + != (c->aggr_state & BIT(state)); 110 + } 111 + 112 + static int clk_rpmh_send_aggregate_command(struct clk_rpmh *c) 113 + { 114 + struct tcs_cmd cmd = { 0 }; 115 + u32 cmd_state, on_val; 116 + enum rpmh_state state = RPMH_SLEEP_STATE; 117 + int ret; 118 + 119 + cmd.addr = c->res_addr; 120 + cmd_state = c->aggr_state; 121 + on_val = c->res_on_val; 122 + 123 + for (; state <= RPMH_ACTIVE_ONLY_STATE; state++) { 124 + if (has_state_changed(c, state)) { 125 + if (cmd_state & BIT(state)) 126 + cmd.data = on_val; 127 + 128 + ret = rpmh_write_async(c->dev, state, &cmd, 1); 129 + if (ret) { 130 + dev_err(c->dev, "set %s state of %s failed: (%d)\n", 131 + !state ? "sleep" : 132 + state == RPMH_WAKE_ONLY_STATE ? 133 + "wake" : "active", c->res_name, ret); 134 + return ret; 135 + } 136 + } 137 + } 138 + 139 + c->last_sent_aggr_state = c->aggr_state; 140 + c->peer->last_sent_aggr_state = c->last_sent_aggr_state; 141 + 142 + return 0; 143 + } 144 + 145 + /* 146 + * Update state and aggregate state values based on enable value. 147 + */ 148 + static int clk_rpmh_aggregate_state_send_command(struct clk_rpmh *c, 149 + bool enable) 150 + { 151 + int ret; 152 + 153 + /* Nothing required to be done if already off or on */ 154 + if (enable == c->state) 155 + return 0; 156 + 157 + c->state = enable ? c->valid_state_mask : 0; 158 + c->aggr_state = c->state | c->peer->state; 159 + c->peer->aggr_state = c->aggr_state; 160 + 161 + ret = clk_rpmh_send_aggregate_command(c); 162 + if (!ret) 163 + return 0; 164 + 165 + if (ret && enable) 166 + c->state = 0; 167 + else if (ret) 168 + c->state = c->valid_state_mask; 169 + 170 + WARN(1, "clk: %s failed to %s\n", c->res_name, 171 + enable ? "enable" : "disable"); 172 + return ret; 173 + } 174 + 175 + static int clk_rpmh_prepare(struct clk_hw *hw) 176 + { 177 + struct clk_rpmh *c = to_clk_rpmh(hw); 178 + int ret = 0; 179 + 180 + mutex_lock(&rpmh_clk_lock); 181 + ret = clk_rpmh_aggregate_state_send_command(c, true); 182 + mutex_unlock(&rpmh_clk_lock); 183 + 184 + return ret; 185 + }; 186 + 187 + static void clk_rpmh_unprepare(struct clk_hw *hw) 188 + { 189 + struct clk_rpmh *c = to_clk_rpmh(hw); 190 + 191 + mutex_lock(&rpmh_clk_lock); 192 + clk_rpmh_aggregate_state_send_command(c, false); 193 + mutex_unlock(&rpmh_clk_lock); 194 + }; 195 + 196 + static unsigned long clk_rpmh_recalc_rate(struct clk_hw *hw, 197 + unsigned long prate) 198 + { 199 + struct clk_rpmh *r = to_clk_rpmh(hw); 200 + 201 + /* 202 + * RPMh clocks have a fixed rate. Return static rate. 203 + */ 204 + return prate / r->div; 205 + } 206 + 207 + static const struct clk_ops clk_rpmh_ops = { 208 + .prepare = clk_rpmh_prepare, 209 + .unprepare = clk_rpmh_unprepare, 210 + .recalc_rate = clk_rpmh_recalc_rate, 211 + }; 212 + 213 + /* Resource name must match resource id present in cmd-db. */ 214 + DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2); 215 + DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2); 216 + DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2); 217 + DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1); 218 + DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1); 219 + DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1); 220 + 221 + static struct clk_hw *sdm845_rpmh_clocks[] = { 222 + [RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw, 223 + [RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw, 224 + [RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw, 225 + [RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw, 226 + [RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw, 227 + [RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw, 228 + [RPMH_RF_CLK1] = &sdm845_rf_clk1.hw, 229 + [RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw, 230 + [RPMH_RF_CLK2] = &sdm845_rf_clk2.hw, 231 + [RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw, 232 + [RPMH_RF_CLK3] = &sdm845_rf_clk3.hw, 233 + [RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw, 234 + }; 235 + 236 + static const struct clk_rpmh_desc clk_rpmh_sdm845 = { 237 + .clks = sdm845_rpmh_clocks, 238 + .num_clks = ARRAY_SIZE(sdm845_rpmh_clocks), 239 + }; 240 + 241 + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, 242 + void *data) 243 + { 244 + struct clk_rpmh_desc *rpmh = data; 245 + unsigned int idx = clkspec->args[0]; 246 + 247 + if (idx >= rpmh->num_clks) { 248 + pr_err("%s: invalid index %u\n", __func__, idx); 249 + return ERR_PTR(-EINVAL); 250 + } 251 + 252 + return rpmh->clks[idx]; 253 + } 254 + 255 + static int clk_rpmh_probe(struct platform_device *pdev) 256 + { 257 + struct clk_hw **hw_clks; 258 + struct clk_rpmh *rpmh_clk; 259 + const struct clk_rpmh_desc *desc; 260 + int ret, i; 261 + 262 + desc = of_device_get_match_data(&pdev->dev); 263 + if (!desc) 264 + return -ENODEV; 265 + 266 + hw_clks = desc->clks; 267 + 268 + for (i = 0; i < desc->num_clks; i++) { 269 + u32 res_addr; 270 + 271 + rpmh_clk = to_clk_rpmh(hw_clks[i]); 272 + res_addr = cmd_db_read_addr(rpmh_clk->res_name); 273 + if (!res_addr) { 274 + dev_err(&pdev->dev, "missing RPMh resource address for %s\n", 275 + rpmh_clk->res_name); 276 + return -ENODEV; 277 + } 278 + rpmh_clk->res_addr += res_addr; 279 + rpmh_clk->dev = &pdev->dev; 280 + 281 + ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]); 282 + if (ret) { 283 + dev_err(&pdev->dev, "failed to register %s\n", 284 + hw_clks[i]->init->name); 285 + return ret; 286 + } 287 + } 288 + 289 + /* typecast to silence compiler warning */ 290 + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_rpmh_hw_get, 291 + (void *)desc); 292 + if (ret) { 293 + dev_err(&pdev->dev, "Failed to add clock provider\n"); 294 + return ret; 295 + } 296 + 297 + dev_dbg(&pdev->dev, "Registered RPMh clocks\n"); 298 + 299 + return 0; 300 + } 301 + 302 + static const struct of_device_id clk_rpmh_match_table[] = { 303 + { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845}, 304 + { } 305 + }; 306 + MODULE_DEVICE_TABLE(of, clk_rpmh_match_table); 307 + 308 + static struct platform_driver clk_rpmh_driver = { 309 + .probe = clk_rpmh_probe, 310 + .driver = { 311 + .name = "clk-rpmh", 312 + .of_match_table = clk_rpmh_match_table, 313 + }, 314 + }; 315 + 316 + static int __init clk_rpmh_init(void) 317 + { 318 + return platform_driver_register(&clk_rpmh_driver); 319 + } 320 + subsys_initcall(clk_rpmh_init); 321 + 322 + static void __exit clk_rpmh_exit(void) 323 + { 324 + platform_driver_unregister(&clk_rpmh_driver); 325 + } 326 + module_exit(clk_rpmh_exit); 327 + 328 + MODULE_DESCRIPTION("QCOM RPMh Clock Driver"); 329 + MODULE_LICENSE("GPL v2");
+1 -9
drivers/clk/qcom/common.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 1 2 /* 2 3 * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 4 */ 13 5 14 6 #include <linux/export.h>
+3 -12
drivers/clk/qcom/common.h
··· 1 - /* 2 - * Copyright (c) 2014, The Linux Foundation. All rights reserved. 3 - * 4 - * This software is licensed under the terms of the GNU General Public 5 - * License version 2, as published by the Free Software Foundation, and 6 - * may be copied, distributed, and modified under those terms. 7 - * 8 - * This program is distributed in the hope that it will be useful, 9 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 - * GNU General Public License for more details. 12 - */ 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */ 3 + 13 4 #ifndef __QCOM_CLK_COMMON_H__ 14 5 #define __QCOM_CLK_COMMON_H__ 15 6
+685
drivers/clk/qcom/dispcc-sdm845.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/module.h> 8 + #include <linux/platform_device.h> 9 + #include <linux/regmap.h> 10 + #include <linux/reset-controller.h> 11 + 12 + #include <dt-bindings/clock/qcom,dispcc-sdm845.h> 13 + 14 + #include "clk-alpha-pll.h" 15 + #include "clk-branch.h" 16 + #include "clk-rcg.h" 17 + #include "clk-regmap-divider.h" 18 + #include "common.h" 19 + #include "gdsc.h" 20 + #include "reset.h" 21 + 22 + enum { 23 + P_BI_TCXO, 24 + P_CORE_BI_PLL_TEST_SE, 25 + P_DISP_CC_PLL0_OUT_MAIN, 26 + P_DSI0_PHY_PLL_OUT_BYTECLK, 27 + P_DSI0_PHY_PLL_OUT_DSICLK, 28 + P_DSI1_PHY_PLL_OUT_BYTECLK, 29 + P_DSI1_PHY_PLL_OUT_DSICLK, 30 + P_GPLL0_OUT_MAIN, 31 + P_GPLL0_OUT_MAIN_DIV, 32 + }; 33 + 34 + static const struct parent_map disp_cc_parent_map_0[] = { 35 + { P_BI_TCXO, 0 }, 36 + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 37 + { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, 38 + { P_CORE_BI_PLL_TEST_SE, 7 }, 39 + }; 40 + 41 + static const char * const disp_cc_parent_names_0[] = { 42 + "bi_tcxo", 43 + "dsi0_phy_pll_out_byteclk", 44 + "dsi1_phy_pll_out_byteclk", 45 + "core_bi_pll_test_se", 46 + }; 47 + 48 + static const struct parent_map disp_cc_parent_map_2[] = { 49 + { P_BI_TCXO, 0 }, 50 + { P_CORE_BI_PLL_TEST_SE, 7 }, 51 + }; 52 + 53 + static const char * const disp_cc_parent_names_2[] = { 54 + "bi_tcxo", 55 + "core_bi_pll_test_se", 56 + }; 57 + 58 + static const struct parent_map disp_cc_parent_map_3[] = { 59 + { P_BI_TCXO, 0 }, 60 + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 61 + { P_GPLL0_OUT_MAIN, 4 }, 62 + { P_GPLL0_OUT_MAIN_DIV, 5 }, 63 + { P_CORE_BI_PLL_TEST_SE, 7 }, 64 + }; 65 + 66 + static const char * const disp_cc_parent_names_3[] = { 67 + "bi_tcxo", 68 + "disp_cc_pll0", 69 + "gcc_disp_gpll0_clk_src", 70 + "gcc_disp_gpll0_div_clk_src", 71 + "core_bi_pll_test_se", 72 + }; 73 + 74 + static const struct parent_map disp_cc_parent_map_4[] = { 75 + { P_BI_TCXO, 0 }, 76 + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 77 + { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, 78 + { P_CORE_BI_PLL_TEST_SE, 7 }, 79 + }; 80 + 81 + static const char * const disp_cc_parent_names_4[] = { 82 + "bi_tcxo", 83 + "dsi0_phy_pll_out_dsiclk", 84 + "dsi1_phy_pll_out_dsiclk", 85 + "core_bi_pll_test_se", 86 + }; 87 + 88 + static struct clk_alpha_pll disp_cc_pll0 = { 89 + .offset = 0x0, 90 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 91 + .clkr = { 92 + .hw.init = &(struct clk_init_data){ 93 + .name = "disp_cc_pll0", 94 + .parent_names = (const char *[]){ "bi_tcxo" }, 95 + .num_parents = 1, 96 + .ops = &clk_alpha_pll_fabia_ops, 97 + }, 98 + }, 99 + }; 100 + 101 + /* Return the HW recalc rate for idle use case */ 102 + static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 103 + .cmd_rcgr = 0x20d0, 104 + .mnd_width = 0, 105 + .hid_width = 5, 106 + .parent_map = disp_cc_parent_map_0, 107 + .clkr.hw.init = &(struct clk_init_data){ 108 + .name = "disp_cc_mdss_byte0_clk_src", 109 + .parent_names = disp_cc_parent_names_0, 110 + .num_parents = 4, 111 + .flags = CLK_SET_RATE_PARENT, 112 + .ops = &clk_byte2_ops, 113 + }, 114 + }; 115 + 116 + /* Return the HW recalc rate for idle use case */ 117 + static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { 118 + .cmd_rcgr = 0x20ec, 119 + .mnd_width = 0, 120 + .hid_width = 5, 121 + .parent_map = disp_cc_parent_map_0, 122 + .clkr.hw.init = &(struct clk_init_data){ 123 + .name = "disp_cc_mdss_byte1_clk_src", 124 + .parent_names = disp_cc_parent_names_0, 125 + .num_parents = 4, 126 + .flags = CLK_SET_RATE_PARENT, 127 + .ops = &clk_byte2_ops, 128 + }, 129 + }; 130 + 131 + static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { 132 + F(19200000, P_BI_TCXO, 1, 0, 0), 133 + { } 134 + }; 135 + 136 + static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 137 + .cmd_rcgr = 0x2108, 138 + .mnd_width = 0, 139 + .hid_width = 5, 140 + .parent_map = disp_cc_parent_map_0, 141 + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 142 + .clkr.hw.init = &(struct clk_init_data){ 143 + .name = "disp_cc_mdss_esc0_clk_src", 144 + .parent_names = disp_cc_parent_names_0, 145 + .num_parents = 4, 146 + .ops = &clk_rcg2_ops, 147 + }, 148 + }; 149 + 150 + static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { 151 + .cmd_rcgr = 0x2120, 152 + .mnd_width = 0, 153 + .hid_width = 5, 154 + .parent_map = disp_cc_parent_map_0, 155 + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 156 + .clkr.hw.init = &(struct clk_init_data){ 157 + .name = "disp_cc_mdss_esc1_clk_src", 158 + .parent_names = disp_cc_parent_names_0, 159 + .num_parents = 4, 160 + .ops = &clk_rcg2_ops, 161 + }, 162 + }; 163 + 164 + static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 165 + F(19200000, P_BI_TCXO, 1, 0, 0), 166 + F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), 167 + F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), 168 + F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), 169 + F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 170 + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 171 + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 172 + F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 173 + F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 174 + { } 175 + }; 176 + 177 + static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 178 + .cmd_rcgr = 0x2088, 179 + .mnd_width = 0, 180 + .hid_width = 5, 181 + .parent_map = disp_cc_parent_map_3, 182 + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 183 + .clkr.hw.init = &(struct clk_init_data){ 184 + .name = "disp_cc_mdss_mdp_clk_src", 185 + .parent_names = disp_cc_parent_names_3, 186 + .num_parents = 5, 187 + .ops = &clk_rcg2_shared_ops, 188 + }, 189 + }; 190 + 191 + /* Return the HW recalc rate for idle use case */ 192 + static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 193 + .cmd_rcgr = 0x2058, 194 + .mnd_width = 8, 195 + .hid_width = 5, 196 + .parent_map = disp_cc_parent_map_4, 197 + .clkr.hw.init = &(struct clk_init_data){ 198 + .name = "disp_cc_mdss_pclk0_clk_src", 199 + .parent_names = disp_cc_parent_names_4, 200 + .num_parents = 4, 201 + .flags = CLK_SET_RATE_PARENT, 202 + .ops = &clk_pixel_ops, 203 + }, 204 + }; 205 + 206 + /* Return the HW recalc rate for idle use case */ 207 + static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { 208 + .cmd_rcgr = 0x2070, 209 + .mnd_width = 8, 210 + .hid_width = 5, 211 + .parent_map = disp_cc_parent_map_4, 212 + .clkr.hw.init = &(struct clk_init_data){ 213 + .name = "disp_cc_mdss_pclk1_clk_src", 214 + .parent_names = disp_cc_parent_names_4, 215 + .num_parents = 4, 216 + .flags = CLK_SET_RATE_PARENT, 217 + .ops = &clk_pixel_ops, 218 + }, 219 + }; 220 + 221 + static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 222 + F(19200000, P_BI_TCXO, 1, 0, 0), 223 + F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 224 + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 225 + F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 226 + F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 227 + { } 228 + }; 229 + 230 + static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 231 + .cmd_rcgr = 0x20a0, 232 + .mnd_width = 0, 233 + .hid_width = 5, 234 + .parent_map = disp_cc_parent_map_3, 235 + .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 236 + .clkr.hw.init = &(struct clk_init_data){ 237 + .name = "disp_cc_mdss_rot_clk_src", 238 + .parent_names = disp_cc_parent_names_3, 239 + .num_parents = 5, 240 + .ops = &clk_rcg2_shared_ops, 241 + }, 242 + }; 243 + 244 + static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 245 + .cmd_rcgr = 0x20b8, 246 + .mnd_width = 0, 247 + .hid_width = 5, 248 + .parent_map = disp_cc_parent_map_2, 249 + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 250 + .clkr.hw.init = &(struct clk_init_data){ 251 + .name = "disp_cc_mdss_vsync_clk_src", 252 + .parent_names = disp_cc_parent_names_2, 253 + .num_parents = 2, 254 + .ops = &clk_rcg2_ops, 255 + }, 256 + }; 257 + 258 + static struct clk_branch disp_cc_mdss_ahb_clk = { 259 + .halt_reg = 0x4004, 260 + .halt_check = BRANCH_HALT, 261 + .clkr = { 262 + .enable_reg = 0x4004, 263 + .enable_mask = BIT(0), 264 + .hw.init = &(struct clk_init_data){ 265 + .name = "disp_cc_mdss_ahb_clk", 266 + .ops = &clk_branch2_ops, 267 + }, 268 + }, 269 + }; 270 + 271 + static struct clk_branch disp_cc_mdss_axi_clk = { 272 + .halt_reg = 0x4008, 273 + .halt_check = BRANCH_HALT, 274 + .clkr = { 275 + .enable_reg = 0x4008, 276 + .enable_mask = BIT(0), 277 + .hw.init = &(struct clk_init_data){ 278 + .name = "disp_cc_mdss_axi_clk", 279 + .ops = &clk_branch2_ops, 280 + }, 281 + }, 282 + }; 283 + 284 + /* Return the HW recalc rate for idle use case */ 285 + static struct clk_branch disp_cc_mdss_byte0_clk = { 286 + .halt_reg = 0x2028, 287 + .halt_check = BRANCH_HALT, 288 + .clkr = { 289 + .enable_reg = 0x2028, 290 + .enable_mask = BIT(0), 291 + .hw.init = &(struct clk_init_data){ 292 + .name = "disp_cc_mdss_byte0_clk", 293 + .parent_names = (const char *[]){ 294 + "disp_cc_mdss_byte0_clk_src", 295 + }, 296 + .num_parents = 1, 297 + .flags = CLK_SET_RATE_PARENT, 298 + .ops = &clk_branch2_ops, 299 + }, 300 + }, 301 + }; 302 + 303 + /* Return the HW recalc rate for idle use case */ 304 + static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 305 + .reg = 0x20e8, 306 + .shift = 0, 307 + .width = 2, 308 + .clkr = { 309 + .hw.init = &(struct clk_init_data){ 310 + .name = "disp_cc_mdss_byte0_div_clk_src", 311 + .parent_names = (const char *[]){ 312 + "disp_cc_mdss_byte0_clk_src", 313 + }, 314 + .num_parents = 1, 315 + .ops = &clk_regmap_div_ops, 316 + }, 317 + }, 318 + }; 319 + 320 + /* Return the HW recalc rate for idle use case */ 321 + static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 322 + .halt_reg = 0x202c, 323 + .halt_check = BRANCH_HALT, 324 + .clkr = { 325 + .enable_reg = 0x202c, 326 + .enable_mask = BIT(0), 327 + .hw.init = &(struct clk_init_data){ 328 + .name = "disp_cc_mdss_byte0_intf_clk", 329 + .parent_names = (const char *[]){ 330 + "disp_cc_mdss_byte0_div_clk_src", 331 + }, 332 + .num_parents = 1, 333 + .flags = CLK_SET_RATE_PARENT, 334 + .ops = &clk_branch2_ops, 335 + }, 336 + }, 337 + }; 338 + 339 + /* Return the HW recalc rate for idle use case */ 340 + static struct clk_branch disp_cc_mdss_byte1_clk = { 341 + .halt_reg = 0x2030, 342 + .halt_check = BRANCH_HALT, 343 + .clkr = { 344 + .enable_reg = 0x2030, 345 + .enable_mask = BIT(0), 346 + .hw.init = &(struct clk_init_data){ 347 + .name = "disp_cc_mdss_byte1_clk", 348 + .parent_names = (const char *[]){ 349 + "disp_cc_mdss_byte1_clk_src", 350 + }, 351 + .num_parents = 1, 352 + .flags = CLK_SET_RATE_PARENT, 353 + .ops = &clk_branch2_ops, 354 + }, 355 + }, 356 + }; 357 + 358 + /* Return the HW recalc rate for idle use case */ 359 + static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { 360 + .reg = 0x2104, 361 + .shift = 0, 362 + .width = 2, 363 + .clkr = { 364 + .hw.init = &(struct clk_init_data){ 365 + .name = "disp_cc_mdss_byte1_div_clk_src", 366 + .parent_names = (const char *[]){ 367 + "disp_cc_mdss_byte1_clk_src", 368 + }, 369 + .num_parents = 1, 370 + .ops = &clk_regmap_div_ops, 371 + }, 372 + }, 373 + }; 374 + 375 + /* Return the HW recalc rate for idle use case */ 376 + static struct clk_branch disp_cc_mdss_byte1_intf_clk = { 377 + .halt_reg = 0x2034, 378 + .halt_check = BRANCH_HALT, 379 + .clkr = { 380 + .enable_reg = 0x2034, 381 + .enable_mask = BIT(0), 382 + .hw.init = &(struct clk_init_data){ 383 + .name = "disp_cc_mdss_byte1_intf_clk", 384 + .parent_names = (const char *[]){ 385 + "disp_cc_mdss_byte1_div_clk_src", 386 + }, 387 + .num_parents = 1, 388 + .flags = CLK_SET_RATE_PARENT, 389 + .ops = &clk_branch2_ops, 390 + }, 391 + }, 392 + }; 393 + 394 + static struct clk_branch disp_cc_mdss_esc0_clk = { 395 + .halt_reg = 0x2038, 396 + .halt_check = BRANCH_HALT, 397 + .clkr = { 398 + .enable_reg = 0x2038, 399 + .enable_mask = BIT(0), 400 + .hw.init = &(struct clk_init_data){ 401 + .name = "disp_cc_mdss_esc0_clk", 402 + .parent_names = (const char *[]){ 403 + "disp_cc_mdss_esc0_clk_src", 404 + }, 405 + .num_parents = 1, 406 + .flags = CLK_SET_RATE_PARENT, 407 + .ops = &clk_branch2_ops, 408 + }, 409 + }, 410 + }; 411 + 412 + static struct clk_branch disp_cc_mdss_esc1_clk = { 413 + .halt_reg = 0x203c, 414 + .halt_check = BRANCH_HALT, 415 + .clkr = { 416 + .enable_reg = 0x203c, 417 + .enable_mask = BIT(0), 418 + .hw.init = &(struct clk_init_data){ 419 + .name = "disp_cc_mdss_esc1_clk", 420 + .parent_names = (const char *[]){ 421 + "disp_cc_mdss_esc1_clk_src", 422 + }, 423 + .num_parents = 1, 424 + .flags = CLK_SET_RATE_PARENT, 425 + .ops = &clk_branch2_ops, 426 + }, 427 + }, 428 + }; 429 + 430 + static struct clk_branch disp_cc_mdss_mdp_clk = { 431 + .halt_reg = 0x200c, 432 + .halt_check = BRANCH_HALT, 433 + .clkr = { 434 + .enable_reg = 0x200c, 435 + .enable_mask = BIT(0), 436 + .hw.init = &(struct clk_init_data){ 437 + .name = "disp_cc_mdss_mdp_clk", 438 + .parent_names = (const char *[]){ 439 + "disp_cc_mdss_mdp_clk_src", 440 + }, 441 + .num_parents = 1, 442 + .flags = CLK_SET_RATE_PARENT, 443 + .ops = &clk_branch2_ops, 444 + }, 445 + }, 446 + }; 447 + 448 + static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 449 + .halt_reg = 0x201c, 450 + .halt_check = BRANCH_HALT, 451 + .clkr = { 452 + .enable_reg = 0x201c, 453 + .enable_mask = BIT(0), 454 + .hw.init = &(struct clk_init_data){ 455 + .name = "disp_cc_mdss_mdp_lut_clk", 456 + .parent_names = (const char *[]){ 457 + "disp_cc_mdss_mdp_clk_src", 458 + }, 459 + .num_parents = 1, 460 + .ops = &clk_branch2_ops, 461 + }, 462 + }, 463 + }; 464 + 465 + /* Return the HW recalc rate for idle use case */ 466 + static struct clk_branch disp_cc_mdss_pclk0_clk = { 467 + .halt_reg = 0x2004, 468 + .halt_check = BRANCH_HALT, 469 + .clkr = { 470 + .enable_reg = 0x2004, 471 + .enable_mask = BIT(0), 472 + .hw.init = &(struct clk_init_data){ 473 + .name = "disp_cc_mdss_pclk0_clk", 474 + .parent_names = (const char *[]){ 475 + "disp_cc_mdss_pclk0_clk_src", 476 + }, 477 + .num_parents = 1, 478 + .flags = CLK_SET_RATE_PARENT, 479 + .ops = &clk_branch2_ops, 480 + }, 481 + }, 482 + }; 483 + 484 + /* Return the HW recalc rate for idle use case */ 485 + static struct clk_branch disp_cc_mdss_pclk1_clk = { 486 + .halt_reg = 0x2008, 487 + .halt_check = BRANCH_HALT, 488 + .clkr = { 489 + .enable_reg = 0x2008, 490 + .enable_mask = BIT(0), 491 + .hw.init = &(struct clk_init_data){ 492 + .name = "disp_cc_mdss_pclk1_clk", 493 + .parent_names = (const char *[]){ 494 + "disp_cc_mdss_pclk1_clk_src", 495 + }, 496 + .num_parents = 1, 497 + .flags = CLK_SET_RATE_PARENT, 498 + .ops = &clk_branch2_ops, 499 + }, 500 + }, 501 + }; 502 + 503 + static struct clk_branch disp_cc_mdss_rot_clk = { 504 + .halt_reg = 0x2014, 505 + .halt_check = BRANCH_HALT, 506 + .clkr = { 507 + .enable_reg = 0x2014, 508 + .enable_mask = BIT(0), 509 + .hw.init = &(struct clk_init_data){ 510 + .name = "disp_cc_mdss_rot_clk", 511 + .parent_names = (const char *[]){ 512 + "disp_cc_mdss_rot_clk_src", 513 + }, 514 + .num_parents = 1, 515 + .flags = CLK_SET_RATE_PARENT, 516 + .ops = &clk_branch2_ops, 517 + }, 518 + }, 519 + }; 520 + 521 + static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 522 + .halt_reg = 0x5004, 523 + .halt_check = BRANCH_HALT, 524 + .clkr = { 525 + .enable_reg = 0x5004, 526 + .enable_mask = BIT(0), 527 + .hw.init = &(struct clk_init_data){ 528 + .name = "disp_cc_mdss_rscc_ahb_clk", 529 + .ops = &clk_branch2_ops, 530 + }, 531 + }, 532 + }; 533 + 534 + static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 535 + .halt_reg = 0x5008, 536 + .halt_check = BRANCH_HALT, 537 + .clkr = { 538 + .enable_reg = 0x5008, 539 + .enable_mask = BIT(0), 540 + .hw.init = &(struct clk_init_data){ 541 + .name = "disp_cc_mdss_rscc_vsync_clk", 542 + .parent_names = (const char *[]){ 543 + "disp_cc_mdss_vsync_clk_src", 544 + }, 545 + .num_parents = 1, 546 + .flags = CLK_SET_RATE_PARENT, 547 + .ops = &clk_branch2_ops, 548 + }, 549 + }, 550 + }; 551 + 552 + static struct clk_branch disp_cc_mdss_vsync_clk = { 553 + .halt_reg = 0x2024, 554 + .halt_check = BRANCH_HALT, 555 + .clkr = { 556 + .enable_reg = 0x2024, 557 + .enable_mask = BIT(0), 558 + .hw.init = &(struct clk_init_data){ 559 + .name = "disp_cc_mdss_vsync_clk", 560 + .parent_names = (const char *[]){ 561 + "disp_cc_mdss_vsync_clk_src", 562 + }, 563 + .num_parents = 1, 564 + .flags = CLK_SET_RATE_PARENT, 565 + .ops = &clk_branch2_ops, 566 + }, 567 + }, 568 + }; 569 + 570 + static struct gdsc mdss_gdsc = { 571 + .gdscr = 0x3000, 572 + .pd = { 573 + .name = "mdss_gdsc", 574 + }, 575 + .pwrsts = PWRSTS_OFF_ON, 576 + .flags = HW_CTRL | POLL_CFG_GDSCR, 577 + }; 578 + 579 + static struct clk_regmap *disp_cc_sdm845_clocks[] = { 580 + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 581 + [DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr, 582 + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 583 + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 584 + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 585 + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = 586 + &disp_cc_mdss_byte0_div_clk_src.clkr, 587 + [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, 588 + [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, 589 + [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, 590 + [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = 591 + &disp_cc_mdss_byte1_div_clk_src.clkr, 592 + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 593 + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 594 + [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, 595 + [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, 596 + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 597 + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 598 + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 599 + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 600 + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 601 + [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, 602 + [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, 603 + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 604 + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 605 + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 606 + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 607 + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 608 + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 609 + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 610 + }; 611 + 612 + static const struct qcom_reset_map disp_cc_sdm845_resets[] = { 613 + [DISP_CC_MDSS_RSCC_BCR] = { 0x5000 }, 614 + }; 615 + 616 + static struct gdsc *disp_cc_sdm845_gdscs[] = { 617 + [MDSS_GDSC] = &mdss_gdsc, 618 + }; 619 + 620 + static const struct regmap_config disp_cc_sdm845_regmap_config = { 621 + .reg_bits = 32, 622 + .reg_stride = 4, 623 + .val_bits = 32, 624 + .max_register = 0x10000, 625 + .fast_io = true, 626 + }; 627 + 628 + static const struct qcom_cc_desc disp_cc_sdm845_desc = { 629 + .config = &disp_cc_sdm845_regmap_config, 630 + .clks = disp_cc_sdm845_clocks, 631 + .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks), 632 + .resets = disp_cc_sdm845_resets, 633 + .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets), 634 + .gdscs = disp_cc_sdm845_gdscs, 635 + .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs), 636 + }; 637 + 638 + static const struct of_device_id disp_cc_sdm845_match_table[] = { 639 + { .compatible = "qcom,sdm845-dispcc" }, 640 + { } 641 + }; 642 + MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table); 643 + 644 + static int disp_cc_sdm845_probe(struct platform_device *pdev) 645 + { 646 + struct regmap *regmap; 647 + struct alpha_pll_config disp_cc_pll0_config = {}; 648 + 649 + regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc); 650 + if (IS_ERR(regmap)) 651 + return PTR_ERR(regmap); 652 + 653 + disp_cc_pll0_config.l = 0x2c; 654 + disp_cc_pll0_config.alpha = 0xcaaa; 655 + 656 + clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 657 + 658 + /* Enable hardware clock gating for DSI and MDP clocks */ 659 + regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); 660 + 661 + return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); 662 + } 663 + 664 + static struct platform_driver disp_cc_sdm845_driver = { 665 + .probe = disp_cc_sdm845_probe, 666 + .driver = { 667 + .name = "disp_cc-sdm845", 668 + .of_match_table = disp_cc_sdm845_match_table, 669 + }, 670 + }; 671 + 672 + static int __init disp_cc_sdm845_init(void) 673 + { 674 + return platform_driver_register(&disp_cc_sdm845_driver); 675 + } 676 + subsys_initcall(disp_cc_sdm845_init); 677 + 678 + static void __exit disp_cc_sdm845_exit(void) 679 + { 680 + platform_driver_unregister(&disp_cc_sdm845_driver); 681 + } 682 + module_exit(disp_cc_sdm845_exit); 683 + 684 + MODULE_LICENSE("GPL v2"); 685 + MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver");
-2
drivers/clk/qcom/gcc-apq8084.c
··· 106 106 "sleep_clk_src", 107 107 }; 108 108 109 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 110 - 111 109 static struct clk_pll gpll0 = { 112 110 .l_reg = 0x0004, 113 111 .m_reg = 0x0008,
-2
drivers/clk/qcom/gcc-ipq4019.c
··· 179 179 "ddrpllapss", 180 180 }; 181 181 182 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 183 - 184 182 static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { 185 183 F(48000000, P_XO, 1, 0, 0), 186 184 F(200000000, P_FEPLL200, 1, 0, 0),
-3
drivers/clk/qcom/gcc-ipq806x.c
··· 1220 1220 .parent_names = gcc_pxo_pll8, 1221 1221 .num_parents = 2, 1222 1222 .ops = &clk_rcg_ops, 1223 - .flags = CLK_SET_RATE_GATE, 1224 1223 }, 1225 1224 } 1226 1225 }; ··· 1268 1269 .parent_names = gcc_pxo_pll8, 1269 1270 .num_parents = 2, 1270 1271 .ops = &clk_rcg_ops, 1271 - .flags = CLK_SET_RATE_GATE, 1272 1272 }, 1273 1273 } 1274 1274 }; ··· 1351 1353 .parent_names = gcc_pxo_pll8, 1352 1354 .num_parents = 2, 1353 1355 .ops = &clk_rcg_ops, 1354 - .flags = CLK_SET_RATE_GATE, 1355 1356 }, 1356 1357 } 1357 1358 };
-2
drivers/clk/qcom/gcc-ipq8074.c
··· 32 32 #include "clk-regmap-mux.h" 33 33 #include "reset.h" 34 34 35 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 36 - 37 35 enum { 38 36 P_XO, 39 37 P_GPLL0,
-2
drivers/clk/qcom/gcc-mdm9615.c
··· 947 947 .parent_names = gcc_cxo_pll8, 948 948 .num_parents = 2, 949 949 .ops = &clk_rcg_ops, 950 - .flags = CLK_SET_RATE_GATE, 951 950 }, 952 951 } 953 952 }; ··· 995 996 .parent_names = gcc_cxo_pll8, 996 997 .num_parents = 2, 997 998 .ops = &clk_rcg_ops, 998 - .flags = CLK_SET_RATE_GATE, 999 999 }, 1000 1000 } 1001 1001 };
-5
drivers/clk/qcom/gcc-msm8660.c
··· 1558 1558 .parent_names = gcc_pxo_pll8, 1559 1559 .num_parents = 2, 1560 1560 .ops = &clk_rcg_ops, 1561 - .flags = CLK_SET_RATE_GATE, 1562 1561 }, 1563 1562 } 1564 1563 }; ··· 1606 1607 .parent_names = gcc_pxo_pll8, 1607 1608 .num_parents = 2, 1608 1609 .ops = &clk_rcg_ops, 1609 - .flags = CLK_SET_RATE_GATE, 1610 1610 }, 1611 1611 } 1612 1612 }; ··· 1654 1656 .parent_names = gcc_pxo_pll8, 1655 1657 .num_parents = 2, 1656 1658 .ops = &clk_rcg_ops, 1657 - .flags = CLK_SET_RATE_GATE, 1658 1659 }, 1659 1660 } 1660 1661 }; ··· 1702 1705 .parent_names = gcc_pxo_pll8, 1703 1706 .num_parents = 2, 1704 1707 .ops = &clk_rcg_ops, 1705 - .flags = CLK_SET_RATE_GATE, 1706 1708 }, 1707 1709 } 1708 1710 }; ··· 1750 1754 .parent_names = gcc_pxo_pll8, 1751 1755 .num_parents = 2, 1752 1756 .ops = &clk_rcg_ops, 1753 - .flags = CLK_SET_RATE_GATE, 1754 1757 }, 1755 1758 } 1756 1759 };
-2
drivers/clk/qcom/gcc-msm8916.c
··· 264 264 "sleep_clk", 265 265 }; 266 266 267 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 268 - 269 267 static struct clk_pll gpll0 = { 270 268 .l_reg = 0x21004, 271 269 .m_reg = 0x21008,
-5
drivers/clk/qcom/gcc-msm8960.c
··· 1628 1628 .parent_names = gcc_pxo_pll8, 1629 1629 .num_parents = 2, 1630 1630 .ops = &clk_rcg_ops, 1631 - .flags = CLK_SET_RATE_GATE, 1632 1631 }, 1633 1632 } 1634 1633 }; ··· 1676 1677 .parent_names = gcc_pxo_pll8, 1677 1678 .num_parents = 2, 1678 1679 .ops = &clk_rcg_ops, 1679 - .flags = CLK_SET_RATE_GATE, 1680 1680 }, 1681 1681 } 1682 1682 }; ··· 1724 1726 .parent_names = gcc_pxo_pll8, 1725 1727 .num_parents = 2, 1726 1728 .ops = &clk_rcg_ops, 1727 - .flags = CLK_SET_RATE_GATE, 1728 1729 }, 1729 1730 } 1730 1731 }; ··· 1772 1775 .parent_names = gcc_pxo_pll8, 1773 1776 .num_parents = 2, 1774 1777 .ops = &clk_rcg_ops, 1775 - .flags = CLK_SET_RATE_GATE, 1776 1778 }, 1777 1779 } 1778 1780 }; ··· 1820 1824 .parent_names = gcc_pxo_pll8, 1821 1825 .num_parents = 2, 1822 1826 .ops = &clk_rcg_ops, 1823 - .flags = CLK_SET_RATE_GATE, 1824 1827 }, 1825 1828 } 1826 1829 };
-2
drivers/clk/qcom/gcc-msm8974.c
··· 62 62 "gpll4_vote", 63 63 }; 64 64 65 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 66 - 67 65 static struct clk_pll gpll0 = { 68 66 .l_reg = 0x0004, 69 67 .m_reg = 0x0008,
-2
drivers/clk/qcom/gcc-msm8994.c
··· 57 57 "gpll4", 58 58 }; 59 59 60 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 61 - 62 60 static struct clk_fixed_factor xo = { 63 61 .mult = 1, 64 62 .div = 1,
-2
drivers/clk/qcom/gcc-msm8996.c
··· 32 32 #include "reset.h" 33 33 #include "gdsc.h" 34 34 35 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 36 - 37 35 enum { 38 36 P_XO, 39 37 P_GPLL0,
-2
drivers/clk/qcom/gcc-msm8998.c
··· 25 25 #include "reset.h" 26 26 #include "gdsc.h" 27 27 28 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 29 - 30 28 enum { 31 29 P_AUD_REF_CLK, 32 30 P_CORE_BI_PLL_TEST_SE,
+39 -6
drivers/clk/qcom/gcc-sdm845.c
··· 25 25 #include "gdsc.h" 26 26 #include "reset.h" 27 27 28 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 29 - 30 28 enum { 31 29 P_BI_TCXO, 32 30 P_AUD_REF_CLK, ··· 1101 1103 .enable_mask = BIT(0), 1102 1104 .hw.init = &(struct clk_init_data){ 1103 1105 .name = "gcc_camera_ahb_clk", 1106 + .flags = CLK_IS_CRITICAL, 1104 1107 .ops = &clk_branch2_ops, 1105 1108 }, 1106 1109 }, ··· 1128 1129 .enable_mask = BIT(0), 1129 1130 .hw.init = &(struct clk_init_data){ 1130 1131 .name = "gcc_camera_xo_clk", 1132 + .flags = CLK_IS_CRITICAL, 1131 1133 .ops = &clk_branch2_ops, 1132 1134 }, 1133 1135 }, ··· 1270 1270 .enable_mask = BIT(0), 1271 1271 .hw.init = &(struct clk_init_data){ 1272 1272 .name = "gcc_disp_ahb_clk", 1273 + .flags = CLK_IS_CRITICAL, 1273 1274 .ops = &clk_branch2_ops, 1274 1275 }, 1275 1276 }, ··· 1329 1328 .enable_mask = BIT(0), 1330 1329 .hw.init = &(struct clk_init_data){ 1331 1330 .name = "gcc_disp_xo_clk", 1331 + .flags = CLK_IS_CRITICAL, 1332 1332 .ops = &clk_branch2_ops, 1333 1333 }, 1334 1334 }, ··· 1399 1397 .enable_mask = BIT(0), 1400 1398 .hw.init = &(struct clk_init_data){ 1401 1399 .name = "gcc_gpu_cfg_ahb_clk", 1400 + .flags = CLK_IS_CRITICAL, 1402 1401 .ops = &clk_branch2_ops, 1403 1402 }, 1404 1403 }, ··· 2988 2985 .enable_mask = BIT(0), 2989 2986 .hw.init = &(struct clk_init_data){ 2990 2987 .name = "gcc_video_ahb_clk", 2988 + .flags = CLK_IS_CRITICAL, 2991 2989 .ops = &clk_branch2_ops, 2992 2990 }, 2993 2991 }, ··· 3015 3011 .enable_mask = BIT(0), 3016 3012 .hw.init = &(struct clk_init_data){ 3017 3013 .name = "gcc_video_xo_clk", 3014 + .flags = CLK_IS_CRITICAL, 3018 3015 .ops = &clk_branch2_ops, 3019 3016 }, 3020 3017 }, ··· 3049 3044 }, 3050 3045 .num_parents = 1, 3051 3046 .flags = CLK_SET_RATE_PARENT, 3047 + .ops = &clk_branch2_ops, 3048 + }, 3049 + }, 3050 + }; 3051 + 3052 + static struct clk_branch gcc_cpuss_dvm_bus_clk = { 3053 + .halt_reg = 0x48190, 3054 + .halt_check = BRANCH_HALT, 3055 + .clkr = { 3056 + .enable_reg = 0x48190, 3057 + .enable_mask = BIT(0), 3058 + .hw.init = &(struct clk_init_data){ 3059 + .name = "gcc_cpuss_dvm_bus_clk", 3060 + .flags = CLK_IS_CRITICAL, 3061 + .ops = &clk_branch2_ops, 3062 + }, 3063 + }, 3064 + }; 3065 + 3066 + static struct clk_branch gcc_cpuss_gnoc_clk = { 3067 + .halt_reg = 0x48004, 3068 + .halt_check = BRANCH_HALT_VOTED, 3069 + .hwcg_reg = 0x48004, 3070 + .hwcg_bit = 1, 3071 + .clkr = { 3072 + .enable_reg = 0x52004, 3073 + .enable_mask = BIT(22), 3074 + .hw.init = &(struct clk_init_data){ 3075 + .name = "gcc_cpuss_gnoc_clk", 3076 + .flags = CLK_IS_CRITICAL, 3052 3077 .ops = &clk_branch2_ops, 3053 3078 }, 3054 3079 }, ··· 3379 3344 [GPLL0] = &gpll0.clkr, 3380 3345 [GPLL0_OUT_EVEN] = &gpll0_out_even.clkr, 3381 3346 [GPLL4] = &gpll4.clkr, 3347 + [GCC_CPUSS_DVM_BUS_CLK] = &gcc_cpuss_dvm_bus_clk.clkr, 3348 + [GCC_CPUSS_GNOC_CLK] = &gcc_cpuss_gnoc_clk.clkr, 3382 3349 }; 3383 3350 3384 3351 static const struct qcom_reset_map gcc_sdm845_resets[] = { ··· 3469 3432 /* Disable the GPLL0 active input to MMSS and GPU via MISC registers */ 3470 3433 regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); 3471 3434 regmap_update_bits(regmap, 0x71028, 0x3, 0x3); 3472 - 3473 - /* Enable CPUSS clocks */ 3474 - regmap_update_bits(regmap, 0x48190, BIT(0), 0x1); 3475 - regmap_update_bits(regmap, 0x52004, BIT(22), 0x1); 3476 3435 3477 3436 return qcom_cc_really_probe(pdev, &gcc_sdm845_desc, regmap); 3478 3437 }
-2
drivers/clk/qcom/mmcc-apq8084.c
··· 219 219 "sleep_clk_src", 220 220 }; 221 221 222 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 223 - 224 222 static struct clk_pll mmpll0 = { 225 223 .l_reg = 0x0004, 226 224 .m_reg = 0x0008,
-2
drivers/clk/qcom/mmcc-msm8974.c
··· 184 184 "dsi1pllbyte", 185 185 }; 186 186 187 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 188 - 189 187 static struct clk_pll mmpll0 = { 190 188 .l_reg = 0x0004, 191 189 .m_reg = 0x0008,
-2
drivers/clk/qcom/mmcc-msm8996.c
··· 34 34 #include "reset.h" 35 35 #include "gdsc.h" 36 36 37 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 38 - 39 37 enum { 40 38 P_XO, 41 39 P_MMPLL0,
-2
drivers/clk/qcom/videocc-sdm845.c
··· 18 18 #include "clk-pll.h" 19 19 #include "gdsc.h" 20 20 21 - #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 22 - 23 21 enum { 24 22 P_BI_TCXO, 25 23 P_CORE_BI_PLL_TEST_SE,
+6
drivers/clk/renesas/Kconfig
··· 21 21 select CLK_R8A77980 if ARCH_R8A77980 22 22 select CLK_R8A77990 if ARCH_R8A77990 23 23 select CLK_R8A77995 if ARCH_R8A77995 24 + select CLK_R9A06G032 if ARCH_R9A06G032 24 25 select CLK_SH73A0 if ARCH_SH73A0 25 26 26 27 if CLK_RENESAS ··· 125 124 config CLK_R8A77995 126 125 bool "R-Car D3 clock support" if COMPILE_TEST 127 126 select CLK_RCAR_GEN3_CPG 127 + 128 + config CLK_R9A06G032 129 + bool "Renesas R9A06G032 clock driver" 130 + help 131 + This is a driver for R9A06G032 clocks 128 132 129 133 config CLK_SH73A0 130 134 bool "SH-Mobile AG5 clock support" if COMPILE_TEST
+1
drivers/clk/renesas/Makefile
··· 20 20 obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o 21 21 obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o 22 22 obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o 23 + obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o 23 24 obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o 24 25 25 26 # Family
+2
drivers/clk/renesas/r8a7795-cpg-mssr.c
··· 103 103 DEF_GEN3_SD("sd3", R8A7795_CLK_SD3, CLK_SDSRC, 0x26c), 104 104 105 105 DEF_FIXED("cl", R8A7795_CLK_CL, CLK_PLL1_DIV2, 48, 1), 106 + DEF_FIXED("cr", R8A7795_CLK_CR, CLK_PLL1_DIV4, 2, 1), 106 107 DEF_FIXED("cp", R8A7795_CLK_CP, CLK_EXTAL, 2, 1), 107 108 108 109 DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), ··· 133 132 DEF_MOD("sys-dmac2", 217, R8A7795_CLK_S0D3), 134 133 DEF_MOD("sys-dmac1", 218, R8A7795_CLK_S0D3), 135 134 DEF_MOD("sys-dmac0", 219, R8A7795_CLK_S0D3), 135 + DEF_MOD("sceg-pub", 229, R8A7795_CLK_CR), 136 136 DEF_MOD("cmt3", 300, R8A7795_CLK_R), 137 137 DEF_MOD("cmt2", 301, R8A7795_CLK_R), 138 138 DEF_MOD("cmt1", 302, R8A7795_CLK_R),
+893
drivers/clk/renesas/r9a06g032-clocks.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * R9A09G032 clock driver 4 + * 5 + * Copyright (C) 2018 Renesas Electronics Europe Limited 6 + * 7 + * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com> 8 + */ 9 + 10 + #include <linux/clk.h> 11 + #include <linux/clk-provider.h> 12 + #include <linux/delay.h> 13 + #include <linux/init.h> 14 + #include <linux/kernel.h> 15 + #include <linux/math64.h> 16 + #include <linux/of.h> 17 + #include <linux/of_address.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/slab.h> 20 + #include <linux/spinlock.h> 21 + #include <dt-bindings/clock/r9a06g032-sysctrl.h> 22 + 23 + struct r9a06g032_gate { 24 + u16 gate, reset, ready, midle, 25 + scon, mirack, mistat; 26 + }; 27 + 28 + /* This is used to describe a clock for instantiation */ 29 + struct r9a06g032_clkdesc { 30 + const char *name; 31 + uint32_t type: 3; 32 + uint32_t index: 8; 33 + uint32_t source : 8; /* source index + 1 (0 == none) */ 34 + /* these are used to populate the bitsel struct */ 35 + union { 36 + struct r9a06g032_gate gate; 37 + /* for dividers */ 38 + struct { 39 + unsigned int div_min : 10, div_max : 10, reg: 10; 40 + u16 div_table[4]; 41 + }; 42 + /* For fixed-factor ones */ 43 + struct { 44 + u16 div, mul; 45 + }; 46 + unsigned int factor; 47 + unsigned int frequency; 48 + /* for dual gate */ 49 + struct { 50 + uint16_t group : 1, index: 3; 51 + u16 sel, g1, r1, g2, r2; 52 + } dual; 53 + }; 54 + } __packed; 55 + 56 + #define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) \ 57 + { .gate = _clk, .reset = _rst, \ 58 + .ready = _rdy, .midle = _midle, \ 59 + .scon = _scon, .mirack = _mirack, .mistat = _mistat } 60 + #define D_GATE(_idx, _n, _src, ...) \ 61 + { .type = K_GATE, .index = R9A06G032_##_idx, \ 62 + .source = 1 + R9A06G032_##_src, .name = _n, \ 63 + .gate = I_GATE(__VA_ARGS__), } 64 + #define D_ROOT(_idx, _n, _mul, _div) \ 65 + { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \ 66 + .div = _div, .mul = _mul } 67 + #define D_FFC(_idx, _n, _src, _div) \ 68 + { .type = K_FFC, .index = R9A06G032_##_idx, \ 69 + .source = 1 + R9A06G032_##_src, .name = _n, \ 70 + .div = _div, .mul = 1} 71 + #define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) \ 72 + { .type = K_DIV, .index = R9A06G032_##_idx, \ 73 + .source = 1 + R9A06G032_##_src, .name = _n, \ 74 + .reg = _reg, .div_min = _min, .div_max = _max, \ 75 + .div_table = { __VA_ARGS__ } } 76 + #define D_UGATE(_idx, _n, _src, _g, _gi, _g1, _r1, _g2, _r2) \ 77 + { .type = K_DUALGATE, .index = R9A06G032_##_idx, \ 78 + .source = 1 + R9A06G032_##_src, .name = _n, \ 79 + .dual = { .group = _g, .index = _gi, \ 80 + .g1 = _g1, .r1 = _r1, .g2 = _g2, .r2 = _r2 }, } 81 + 82 + enum { K_GATE = 0, K_FFC, K_DIV, K_BITSEL, K_DUALGATE }; 83 + 84 + /* Internal clock IDs */ 85 + #define R9A06G032_CLKOUT 0 86 + #define R9A06G032_CLKOUT_D10 2 87 + #define R9A06G032_CLKOUT_D16 3 88 + #define R9A06G032_CLKOUT_D160 4 89 + #define R9A06G032_CLKOUT_D1OR2 5 90 + #define R9A06G032_CLKOUT_D20 6 91 + #define R9A06G032_CLKOUT_D40 7 92 + #define R9A06G032_CLKOUT_D5 8 93 + #define R9A06G032_CLKOUT_D8 9 94 + #define R9A06G032_DIV_ADC 10 95 + #define R9A06G032_DIV_I2C 11 96 + #define R9A06G032_DIV_NAND 12 97 + #define R9A06G032_DIV_P1_PG 13 98 + #define R9A06G032_DIV_P2_PG 14 99 + #define R9A06G032_DIV_P3_PG 15 100 + #define R9A06G032_DIV_P4_PG 16 101 + #define R9A06G032_DIV_P5_PG 17 102 + #define R9A06G032_DIV_P6_PG 18 103 + #define R9A06G032_DIV_QSPI0 19 104 + #define R9A06G032_DIV_QSPI1 20 105 + #define R9A06G032_DIV_REF_SYNC 21 106 + #define R9A06G032_DIV_SDIO0 22 107 + #define R9A06G032_DIV_SDIO1 23 108 + #define R9A06G032_DIV_SWITCH 24 109 + #define R9A06G032_DIV_UART 25 110 + #define R9A06G032_DIV_MOTOR 64 111 + #define R9A06G032_CLK_DDRPHY_PLLCLK_D4 78 112 + #define R9A06G032_CLK_ECAT100_D4 79 113 + #define R9A06G032_CLK_HSR100_D2 80 114 + #define R9A06G032_CLK_REF_SYNC_D4 81 115 + #define R9A06G032_CLK_REF_SYNC_D8 82 116 + #define R9A06G032_CLK_SERCOS100_D2 83 117 + #define R9A06G032_DIV_CA7 84 118 + 119 + #define R9A06G032_UART_GROUP_012 154 120 + #define R9A06G032_UART_GROUP_34567 155 121 + 122 + #define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1) 123 + 124 + static const struct r9a06g032_clkdesc r9a06g032_clocks[] __initconst = { 125 + D_ROOT(CLKOUT, "clkout", 25, 1), 126 + D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10), 127 + D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10), 128 + D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16), 129 + D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160), 130 + D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2), 131 + D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20), 132 + D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40), 133 + D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5), 134 + D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8), 135 + D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250), 136 + D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16), 137 + D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32), 138 + D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200), 139 + D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128), 140 + D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128), 141 + D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128), 142 + D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40), 143 + D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64), 144 + D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7), 145 + D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7), 146 + D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16), 147 + D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128), 148 + D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128), 149 + D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40), 150 + D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128), 151 + D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, 0x749, 0x74a, 0x74b, 0, 0xae3, 0, 0), 152 + D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, 0x74c, 0x74d, 0x74e, 0, 0xae4, 0, 0), 153 + D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, 0x74f, 0x750, 0x751, 0, 0xae5, 0, 0), 154 + D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, 0x752, 0x753, 0x754, 0, 0xae6, 0, 0), 155 + D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, 0x755, 0x756, 0x757, 0, 0xae7, 0, 0), 156 + D_GATE(CLK_ADC, "clk_adc", DIV_ADC, 0x1ea, 0x1eb, 0, 0, 0, 0, 0), 157 + D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, 0x405, 0, 0, 0, 0, 0, 0), 158 + D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, 0x483, 0, 0, 0, 0, 0, 0), 159 + D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, 0x1e6, 0x1e7, 0, 0, 0, 0, 0), 160 + D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, 0x1e8, 0x1e9, 0, 0, 0, 0, 0), 161 + D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, 0x342, 0, 0, 0, 0, 0, 0), 162 + D_GATE(CLK_NAND, "clk_nand", DIV_NAND, 0x284, 0x285, 0, 0, 0, 0, 0), 163 + D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, 0x774, 0x775, 0, 0, 0, 0, 0), 164 + D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, 0x862, 0x863, 0, 0, 0, 0, 0), 165 + D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, 0x864, 0x865, 0, 0, 0, 0, 0), 166 + D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, 0x866, 0x867, 0, 0, 0, 0, 0), 167 + D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, 0x824, 0x825, 0, 0, 0, 0, 0), 168 + D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, 0x826, 0x827, 0, 0, 0, 0, 0), 169 + D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, 0x8a0, 0x8a1, 0x8a2, 0, 0xb60, 0, 0), 170 + D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), 171 + D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), 172 + D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), 173 + D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), 174 + D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), 175 + D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), 176 + D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, 0x341, 0, 0, 0, 0, 0, 0), 177 + D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, 0x64, 0, 0, 0, 0, 0, 0), 178 + D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, 0x644, 0, 0, 0, 0, 0, 0), 179 + D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, 0x425, 0, 0, 0, 0, 0, 0), 180 + D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, 0x860, 0x861, 0, 0, 0, 0, 0), 181 + D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, 0x7e0, 0x7e1, 0, 0, 0, 0, 0), 182 + D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, 0x7e2, 0x7e3, 0, 0, 0, 0, 0), 183 + D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, 0x7e4, 0x7e5, 0, 0, 0, 0, 0), 184 + D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, 0x7e6, 0x7e7, 0, 0, 0, 0, 0), 185 + D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, 0x820, 0x821, 0, 0, 0, 0, 0), 186 + D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0), 187 + D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0), 188 + D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8), 189 + D_GATE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441), 190 + D_GATE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0), 191 + D_GATE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461), 192 + D_GATE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0), 193 + D_GATE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0), 194 + D_GATE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0), 195 + D_GATE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0), 196 + D_GATE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0), 197 + D_GATE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103), 198 + D_GATE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101), 199 + D_GATE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0), 200 + D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05), 201 + D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0), 202 + D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4), 203 + D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4), 204 + D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2), 205 + D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4), 206 + D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8), 207 + D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2), 208 + D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4), 209 + D_GATE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0), 210 + D_GATE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0), 211 + D_GATE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0), 212 + D_GATE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0), 213 + D_GATE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0), 214 + D_GATE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0), 215 + D_GATE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0), 216 + D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640), 217 + D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1), 218 + D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0), 219 + D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, 0x403, 0x404, 0, 0, 0, 0, 0), 220 + D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0), 221 + D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0), 222 + D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0), 223 + D_GATE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0), 224 + D_GATE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0), 225 + D_GATE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0), 226 + D_GATE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141), 227 + D_GATE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1), 228 + D_GATE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2), 229 + D_GATE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5), 230 + D_GATE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2), 231 + D_GATE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2), 232 + D_GATE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0), 233 + D_GATE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0), 234 + D_GATE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0), 235 + D_GATE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1), 236 + D_GATE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0), 237 + D_GATE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0), 238 + D_GATE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0), 239 + D_GATE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0), 240 + D_GATE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182), 241 + D_GATE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2), 242 + D_GATE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25), 243 + D_GATE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0), 244 + D_GATE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0), 245 + D_GATE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0), 246 + D_GATE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0), 247 + D_GATE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302), 248 + D_GATE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2), 249 + D_GATE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0), 250 + D_GATE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0), 251 + D_GATE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82), 252 + D_GATE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662), 253 + D_GATE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0), 254 + D_GATE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0), 255 + D_GATE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0), 256 + D_GATE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0), 257 + D_GATE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0), 258 + D_GATE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0), 259 + D_GATE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0), 260 + D_GATE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0), 261 + D_GATE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0), 262 + D_GATE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0), 263 + D_GATE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0), 264 + D_GATE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0), 265 + D_GATE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0), 266 + D_GATE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0), 267 + D_GATE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0), 268 + D_GATE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0), 269 + D_GATE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0), 270 + /* 271 + * These are not hardware clocks, but are needed to handle the special 272 + * case where we have a 'selector bit' that doesn't just change the 273 + * parent for a clock, but also the gate it's suposed to use. 274 + */ 275 + { 276 + .index = R9A06G032_UART_GROUP_012, 277 + .name = "uart_group_012", 278 + .type = K_BITSEL, 279 + .source = 1 + R9A06G032_DIV_UART, 280 + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ 281 + .dual.sel = ((0xec / 4) << 5) | 24, 282 + .dual.group = 0, 283 + }, 284 + { 285 + .index = R9A06G032_UART_GROUP_34567, 286 + .name = "uart_group_34567", 287 + .type = K_BITSEL, 288 + .source = 1 + R9A06G032_DIV_P2_PG, 289 + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ 290 + .dual.sel = ((0x34 / 4) << 5) | 30, 291 + .dual.group = 1, 292 + }, 293 + D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5), 294 + D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0, 1, 0x1b6, 0x1b7, 0x1b8, 0x1b9), 295 + D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0, 2, 0x1ba, 0x1bb, 0x1bc, 0x1bd), 296 + D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1, 0, 0x760, 0x761, 0x762, 0x763), 297 + D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1, 1, 0x764, 0x765, 0x766, 0x767), 298 + D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1, 2, 0x768, 0x769, 0x76a, 0x76b), 299 + D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1, 3, 0x76c, 0x76d, 0x76e, 0x76f), 300 + D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1, 4, 0x770, 0x771, 0x772, 0x773), 301 + }; 302 + 303 + struct r9a06g032_priv { 304 + struct clk_onecell_data data; 305 + spinlock_t lock; /* protects concurent access to gates */ 306 + void __iomem *reg; 307 + }; 308 + 309 + /* register/bit pairs are encoded as an uint16_t */ 310 + static void 311 + clk_rdesc_set(struct r9a06g032_priv *clocks, 312 + u16 one, unsigned int on) 313 + { 314 + u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); 315 + u32 val = readl(reg); 316 + 317 + val = (val & ~(1U << (one & 0x1f))) | ((!!on) << (one & 0x1f)); 318 + writel(val, reg); 319 + } 320 + 321 + static int 322 + clk_rdesc_get(struct r9a06g032_priv *clocks, 323 + uint16_t one) 324 + { 325 + u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); 326 + u32 val = readl(reg); 327 + 328 + return !!(val & (1U << (one & 0x1f))); 329 + } 330 + 331 + /* 332 + * This implements the R9A09G032 clock gate 'driver'. We cannot use the system's 333 + * clock gate framework as the gates on the R9A09G032 have a special enabling 334 + * sequence, therefore we use this little proxy. 335 + */ 336 + struct r9a06g032_clk_gate { 337 + struct clk_hw hw; 338 + struct r9a06g032_priv *clocks; 339 + u16 index; 340 + 341 + struct r9a06g032_gate gate; 342 + }; 343 + 344 + #define to_r9a06g032_gate(_hw) container_of(_hw, struct r9a06g032_clk_gate, hw) 345 + 346 + static void 347 + r9a06g032_clk_gate_set(struct r9a06g032_priv *clocks, 348 + struct r9a06g032_gate *g, int on) 349 + { 350 + unsigned long flags; 351 + 352 + WARN_ON(!g->gate); 353 + 354 + spin_lock_irqsave(&clocks->lock, flags); 355 + clk_rdesc_set(clocks, g->gate, on); 356 + /* De-assert reset */ 357 + if (g->reset) 358 + clk_rdesc_set(clocks, g->reset, 1); 359 + spin_unlock_irqrestore(&clocks->lock, flags); 360 + 361 + /* Hardware manual recommends 5us delay after enabling clock & reset */ 362 + udelay(5); 363 + 364 + /* If the peripheral is memory mapped (i.e. an AXI slave), there is an 365 + * associated SLVRDY bit in the System Controller that needs to be set 366 + * so that the FlexWAY bus fabric passes on the read/write requests. 367 + */ 368 + if (g->ready || g->midle) { 369 + spin_lock_irqsave(&clocks->lock, flags); 370 + if (g->ready) 371 + clk_rdesc_set(clocks, g->ready, on); 372 + /* Clear 'Master Idle Request' bit */ 373 + if (g->midle) 374 + clk_rdesc_set(clocks, g->midle, !on); 375 + spin_unlock_irqrestore(&clocks->lock, flags); 376 + } 377 + /* Note: We don't wait for FlexWAY Socket Connection signal */ 378 + } 379 + 380 + static int r9a06g032_clk_gate_enable(struct clk_hw *hw) 381 + { 382 + struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); 383 + 384 + r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); 385 + return 0; 386 + } 387 + 388 + static void r9a06g032_clk_gate_disable(struct clk_hw *hw) 389 + { 390 + struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); 391 + 392 + r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); 393 + } 394 + 395 + static int r9a06g032_clk_gate_is_enabled(struct clk_hw *hw) 396 + { 397 + struct r9a06g032_clk_gate *g = to_r9a06g032_gate(hw); 398 + 399 + /* if clock is in reset, the gate might be on, and still not 'be' on */ 400 + if (g->gate.reset && !clk_rdesc_get(g->clocks, g->gate.reset)) 401 + return 0; 402 + 403 + return clk_rdesc_get(g->clocks, g->gate.gate); 404 + } 405 + 406 + static const struct clk_ops r9a06g032_clk_gate_ops = { 407 + .enable = r9a06g032_clk_gate_enable, 408 + .disable = r9a06g032_clk_gate_disable, 409 + .is_enabled = r9a06g032_clk_gate_is_enabled, 410 + }; 411 + 412 + static struct clk * 413 + r9a06g032_register_gate(struct r9a06g032_priv *clocks, 414 + const char *parent_name, 415 + const struct r9a06g032_clkdesc *desc) 416 + { 417 + struct clk *clk; 418 + struct r9a06g032_clk_gate *g; 419 + struct clk_init_data init; 420 + 421 + g = kzalloc(sizeof(*g), GFP_KERNEL); 422 + if (!g) 423 + return NULL; 424 + 425 + init.name = desc->name; 426 + init.ops = &r9a06g032_clk_gate_ops; 427 + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 428 + init.parent_names = parent_name ? &parent_name : NULL; 429 + init.num_parents = parent_name ? 1 : 0; 430 + 431 + g->clocks = clocks; 432 + g->index = desc->index; 433 + g->gate = desc->gate; 434 + g->hw.init = &init; 435 + 436 + /* 437 + * important here, some clocks are already in use by the CM3, we 438 + * have to assume they are not Linux's to play with and try to disable 439 + * at the end of the boot! 440 + */ 441 + if (r9a06g032_clk_gate_is_enabled(&g->hw)) { 442 + init.flags |= CLK_IS_CRITICAL; 443 + pr_debug("%s was enabled, making read-only\n", desc->name); 444 + } 445 + 446 + clk = clk_register(NULL, &g->hw); 447 + if (IS_ERR(clk)) { 448 + kfree(g); 449 + return NULL; 450 + } 451 + return clk; 452 + } 453 + 454 + struct r9a06g032_clk_div { 455 + struct clk_hw hw; 456 + struct r9a06g032_priv *clocks; 457 + u16 index; 458 + u16 reg; 459 + u16 min, max; 460 + u8 table_size; 461 + u16 table[8]; /* we know there are no more than 8 */ 462 + }; 463 + 464 + #define to_r9a06g032_div(_hw) \ 465 + container_of(_hw, struct r9a06g032_clk_div, hw) 466 + 467 + static unsigned long 468 + r9a06g032_div_recalc_rate(struct clk_hw *hw, 469 + unsigned long parent_rate) 470 + { 471 + struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); 472 + u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); 473 + u32 div = readl(reg); 474 + 475 + if (div < clk->min) 476 + div = clk->min; 477 + else if (div > clk->max) 478 + div = clk->max; 479 + return DIV_ROUND_UP(parent_rate, div); 480 + } 481 + 482 + /* 483 + * Attempts to find a value that is in range of min,max, 484 + * and if a table of set dividers was specified for this 485 + * register, try to find the fixed divider that is the closest 486 + * to the target frequency 487 + */ 488 + static long 489 + r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, 490 + unsigned long rate, unsigned long prate) 491 + { 492 + /* + 1 to cope with rates that have the remainder dropped */ 493 + u32 div = DIV_ROUND_UP(prate, rate + 1); 494 + int i; 495 + 496 + if (div <= clk->min) 497 + return clk->min; 498 + if (div >= clk->max) 499 + return clk->max; 500 + 501 + for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { 502 + if (div >= clk->table[i] && div <= clk->table[i + 1]) { 503 + unsigned long m = rate - 504 + DIV_ROUND_UP(prate, clk->table[i]); 505 + unsigned long p = 506 + DIV_ROUND_UP(prate, clk->table[i + 1]) - 507 + rate; 508 + /* 509 + * select the divider that generates 510 + * the value closest to the ideal frequency 511 + */ 512 + div = p >= m ? clk->table[i] : clk->table[i + 1]; 513 + return div; 514 + } 515 + } 516 + return div; 517 + } 518 + 519 + static long 520 + r9a06g032_div_round_rate(struct clk_hw *hw, 521 + unsigned long rate, unsigned long *prate) 522 + { 523 + struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); 524 + u32 div = DIV_ROUND_UP(*prate, rate); 525 + 526 + pr_devel("%s %pC %ld (prate %ld) (wanted div %u)\n", __func__, 527 + hw->clk, rate, *prate, div); 528 + pr_devel(" min %d (%ld) max %d (%ld)\n", 529 + clk->min, DIV_ROUND_UP(*prate, clk->min), 530 + clk->max, DIV_ROUND_UP(*prate, clk->max)); 531 + 532 + div = r9a06g032_div_clamp_div(clk, rate, *prate); 533 + /* 534 + * this is a hack. Currently the serial driver asks for a clock rate 535 + * that is 16 times the baud rate -- and that is wildly outside the 536 + * range of the UART divider, somehow there is no provision for that 537 + * case of 'let the divider as is if outside range'. 538 + * The serial driver *shouldn't* play with these clocks anyway, there's 539 + * several uarts attached to this divider, and changing this impacts 540 + * everyone. 541 + */ 542 + if (clk->index == R9A06G032_DIV_UART) { 543 + pr_devel("%s div uart hack!\n", __func__); 544 + return clk_get_rate(hw->clk); 545 + } 546 + pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, 547 + *prate, div, DIV_ROUND_UP(*prate, div)); 548 + return DIV_ROUND_UP(*prate, div); 549 + } 550 + 551 + static int 552 + r9a06g032_div_set_rate(struct clk_hw *hw, 553 + unsigned long rate, unsigned long parent_rate) 554 + { 555 + struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); 556 + /* + 1 to cope with rates that have the remainder dropped */ 557 + u32 div = DIV_ROUND_UP(parent_rate, rate + 1); 558 + u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); 559 + 560 + pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, 561 + rate, parent_rate, div); 562 + 563 + /* 564 + * Need to write the bit 31 with the divider value to 565 + * latch it. Technically we should wait until it has been 566 + * cleared too. 567 + * TODO: Find whether this callback is sleepable, in case 568 + * the hardware /does/ require some sort of spinloop here. 569 + */ 570 + writel(div | BIT(31), reg); 571 + 572 + return 0; 573 + } 574 + 575 + static const struct clk_ops r9a06g032_clk_div_ops = { 576 + .recalc_rate = r9a06g032_div_recalc_rate, 577 + .round_rate = r9a06g032_div_round_rate, 578 + .set_rate = r9a06g032_div_set_rate, 579 + }; 580 + 581 + static struct clk * 582 + r9a06g032_register_div(struct r9a06g032_priv *clocks, 583 + const char *parent_name, 584 + const struct r9a06g032_clkdesc *desc) 585 + { 586 + struct r9a06g032_clk_div *div; 587 + struct clk *clk; 588 + struct clk_init_data init; 589 + unsigned int i; 590 + 591 + div = kzalloc(sizeof(*div), GFP_KERNEL); 592 + if (!div) 593 + return NULL; 594 + 595 + init.name = desc->name; 596 + init.ops = &r9a06g032_clk_div_ops; 597 + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 598 + init.parent_names = parent_name ? &parent_name : NULL; 599 + init.num_parents = parent_name ? 1 : 0; 600 + 601 + div->clocks = clocks; 602 + div->index = desc->index; 603 + div->reg = desc->reg; 604 + div->hw.init = &init; 605 + div->min = desc->div_min; 606 + div->max = desc->div_max; 607 + /* populate (optional) divider table fixed values */ 608 + for (i = 0; i < ARRAY_SIZE(div->table) && 609 + i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) { 610 + div->table[div->table_size++] = desc->div_table[i]; 611 + } 612 + 613 + clk = clk_register(NULL, &div->hw); 614 + if (IS_ERR(clk)) { 615 + kfree(div); 616 + return NULL; 617 + } 618 + return clk; 619 + } 620 + 621 + /* 622 + * This clock provider handles the case of the R9A06G032 where you have 623 + * peripherals that have two potential clock source and two gates, one for 624 + * each of the clock source - the used clock source (for all sub clocks) 625 + * is selected by a single bit. 626 + * That single bit affects all sub-clocks, and therefore needs to change the 627 + * active gate (and turn the others off) and force a recalculation of the rates. 628 + * 629 + * This implements two clock providers, one 'bitselect' that 630 + * handles the switch between both parents, and another 'dualgate' 631 + * that knows which gate to poke at, depending on the parent's bit position. 632 + */ 633 + struct r9a06g032_clk_bitsel { 634 + struct clk_hw hw; 635 + struct r9a06g032_priv *clocks; 636 + u16 index; 637 + u16 selector; /* selector register + bit */ 638 + }; 639 + 640 + #define to_clk_bitselect(_hw) \ 641 + container_of(_hw, struct r9a06g032_clk_bitsel, hw) 642 + 643 + static u8 r9a06g032_clk_mux_get_parent(struct clk_hw *hw) 644 + { 645 + struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw); 646 + 647 + return clk_rdesc_get(set->clocks, set->selector); 648 + } 649 + 650 + static int r9a06g032_clk_mux_set_parent(struct clk_hw *hw, u8 index) 651 + { 652 + struct r9a06g032_clk_bitsel *set = to_clk_bitselect(hw); 653 + 654 + /* a single bit in the register selects one of two parent clocks */ 655 + clk_rdesc_set(set->clocks, set->selector, !!index); 656 + 657 + return 0; 658 + } 659 + 660 + static const struct clk_ops clk_bitselect_ops = { 661 + .get_parent = r9a06g032_clk_mux_get_parent, 662 + .set_parent = r9a06g032_clk_mux_set_parent, 663 + }; 664 + 665 + static struct clk * 666 + r9a06g032_register_bitsel(struct r9a06g032_priv *clocks, 667 + const char *parent_name, 668 + const struct r9a06g032_clkdesc *desc) 669 + { 670 + struct clk *clk; 671 + struct r9a06g032_clk_bitsel *g; 672 + struct clk_init_data init; 673 + const char *names[2]; 674 + 675 + /* allocate the gate */ 676 + g = kzalloc(sizeof(*g), GFP_KERNEL); 677 + if (!g) 678 + return NULL; 679 + 680 + names[0] = parent_name; 681 + names[1] = "clk_pll_usb"; 682 + 683 + init.name = desc->name; 684 + init.ops = &clk_bitselect_ops; 685 + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 686 + init.parent_names = names; 687 + init.num_parents = 2; 688 + 689 + g->clocks = clocks; 690 + g->index = desc->index; 691 + g->selector = desc->dual.sel; 692 + g->hw.init = &init; 693 + 694 + clk = clk_register(NULL, &g->hw); 695 + if (IS_ERR(clk)) { 696 + kfree(g); 697 + return NULL; 698 + } 699 + return clk; 700 + } 701 + 702 + struct r9a06g032_clk_dualgate { 703 + struct clk_hw hw; 704 + struct r9a06g032_priv *clocks; 705 + u16 index; 706 + u16 selector; /* selector register + bit */ 707 + struct r9a06g032_gate gate[2]; 708 + }; 709 + 710 + #define to_clk_dualgate(_hw) \ 711 + container_of(_hw, struct r9a06g032_clk_dualgate, hw) 712 + 713 + static int 714 + r9a06g032_clk_dualgate_setenable(struct r9a06g032_clk_dualgate *g, int enable) 715 + { 716 + u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); 717 + 718 + /* we always turn off the 'other' gate, regardless */ 719 + r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); 720 + r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); 721 + 722 + return 0; 723 + } 724 + 725 + static int r9a06g032_clk_dualgate_enable(struct clk_hw *hw) 726 + { 727 + struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw); 728 + 729 + r9a06g032_clk_dualgate_setenable(gate, 1); 730 + 731 + return 0; 732 + } 733 + 734 + static void r9a06g032_clk_dualgate_disable(struct clk_hw *hw) 735 + { 736 + struct r9a06g032_clk_dualgate *gate = to_clk_dualgate(hw); 737 + 738 + r9a06g032_clk_dualgate_setenable(gate, 0); 739 + } 740 + 741 + static int r9a06g032_clk_dualgate_is_enabled(struct clk_hw *hw) 742 + { 743 + struct r9a06g032_clk_dualgate *g = to_clk_dualgate(hw); 744 + u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); 745 + 746 + return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); 747 + } 748 + 749 + static const struct clk_ops r9a06g032_clk_dualgate_ops = { 750 + .enable = r9a06g032_clk_dualgate_enable, 751 + .disable = r9a06g032_clk_dualgate_disable, 752 + .is_enabled = r9a06g032_clk_dualgate_is_enabled, 753 + }; 754 + 755 + static struct clk * 756 + r9a06g032_register_dualgate(struct r9a06g032_priv *clocks, 757 + const char *parent_name, 758 + const struct r9a06g032_clkdesc *desc, 759 + uint16_t sel) 760 + { 761 + struct r9a06g032_clk_dualgate *g; 762 + struct clk *clk; 763 + struct clk_init_data init; 764 + 765 + /* allocate the gate */ 766 + g = kzalloc(sizeof(*g), GFP_KERNEL); 767 + if (!g) 768 + return NULL; 769 + g->clocks = clocks; 770 + g->index = desc->index; 771 + g->selector = sel; 772 + g->gate[0].gate = desc->dual.g1; 773 + g->gate[0].reset = desc->dual.r1; 774 + g->gate[1].gate = desc->dual.g2; 775 + g->gate[1].reset = desc->dual.r2; 776 + 777 + init.name = desc->name; 778 + init.ops = &r9a06g032_clk_dualgate_ops; 779 + init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT; 780 + init.parent_names = &parent_name; 781 + init.num_parents = 1; 782 + g->hw.init = &init; 783 + /* 784 + * important here, some clocks are already in use by the CM3, we 785 + * have to assume they are not Linux's to play with and try to disable 786 + * at the end of the boot! 787 + */ 788 + if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { 789 + init.flags |= CLK_IS_CRITICAL; 790 + pr_debug("%s was enabled, making read-only\n", desc->name); 791 + } 792 + 793 + clk = clk_register(NULL, &g->hw); 794 + if (IS_ERR(clk)) { 795 + kfree(g); 796 + return NULL; 797 + } 798 + return clk; 799 + } 800 + 801 + static void r9a06g032_clocks_del_clk_provider(void *data) 802 + { 803 + of_clk_del_provider(data); 804 + } 805 + 806 + static int __init r9a06g032_clocks_probe(struct platform_device *pdev) 807 + { 808 + struct device *dev = &pdev->dev; 809 + struct device_node *np = dev->of_node; 810 + struct r9a06g032_priv *clocks; 811 + struct clk **clks; 812 + struct clk *mclk; 813 + unsigned int i; 814 + u16 uart_group_sel[2]; 815 + int error; 816 + 817 + clocks = devm_kzalloc(dev, sizeof(*clocks), GFP_KERNEL); 818 + clks = devm_kcalloc(dev, R9A06G032_CLOCK_COUNT, sizeof(struct clk *), 819 + GFP_KERNEL); 820 + if (!clocks || !clks) 821 + return -ENOMEM; 822 + 823 + spin_lock_init(&clocks->lock); 824 + 825 + clocks->data.clks = clks; 826 + clocks->data.clk_num = R9A06G032_CLOCK_COUNT; 827 + 828 + mclk = devm_clk_get(dev, "mclk"); 829 + if (IS_ERR(mclk)) 830 + return PTR_ERR(mclk); 831 + 832 + clocks->reg = of_iomap(np, 0); 833 + if (WARN_ON(!clocks->reg)) 834 + return -ENOMEM; 835 + for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { 836 + const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; 837 + const char *parent_name = d->source ? 838 + __clk_get_name(clocks->data.clks[d->source - 1]) : 839 + __clk_get_name(mclk); 840 + struct clk *clk = NULL; 841 + 842 + switch (d->type) { 843 + case K_FFC: 844 + clk = clk_register_fixed_factor(NULL, d->name, 845 + parent_name, 0, 846 + d->mul, d->div); 847 + break; 848 + case K_GATE: 849 + clk = r9a06g032_register_gate(clocks, parent_name, d); 850 + break; 851 + case K_DIV: 852 + clk = r9a06g032_register_div(clocks, parent_name, d); 853 + break; 854 + case K_BITSEL: 855 + /* keep that selector register around */ 856 + uart_group_sel[d->dual.group] = d->dual.sel; 857 + clk = r9a06g032_register_bitsel(clocks, parent_name, d); 858 + break; 859 + case K_DUALGATE: 860 + clk = r9a06g032_register_dualgate(clocks, parent_name, 861 + d, 862 + uart_group_sel[d->dual.group]); 863 + break; 864 + } 865 + clocks->data.clks[d->index] = clk; 866 + } 867 + error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); 868 + if (error) 869 + return error; 870 + 871 + return devm_add_action_or_reset(dev, 872 + r9a06g032_clocks_del_clk_provider, np); 873 + } 874 + 875 + static const struct of_device_id r9a06g032_match[] = { 876 + { .compatible = "renesas,r9a06g032-sysctrl" }, 877 + { } 878 + }; 879 + 880 + static struct platform_driver r9a06g032_clock_driver = { 881 + .driver = { 882 + .name = "renesas,r9a06g032-sysctrl", 883 + .of_match_table = r9a06g032_match, 884 + }, 885 + }; 886 + 887 + static int __init r9a06g032_clocks_init(void) 888 + { 889 + return platform_driver_probe(&r9a06g032_clock_driver, 890 + r9a06g032_clocks_probe); 891 + } 892 + 893 + subsys_initcall(r9a06g032_clocks_init);
+2
drivers/clk/rockchip/Makefile
··· 6 6 obj-y += clk.o 7 7 obj-y += clk-pll.o 8 8 obj-y += clk-cpu.o 9 + obj-y += clk-half-divider.o 9 10 obj-y += clk-inverter.o 10 11 obj-y += clk-mmc-phase.o 11 12 obj-y += clk-muxgrf.o 12 13 obj-y += clk-ddr.o 13 14 obj-$(CONFIG_RESET_CONTROLLER) += softrst.o 14 15 16 + obj-y += clk-px30.o 15 17 obj-y += clk-rv1108.o 16 18 obj-y += clk-rk3036.o 17 19 obj-y += clk-rk3128.o
+227
drivers/clk/rockchip/clk-half-divider.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 4 + */ 5 + 6 + #include <linux/slab.h> 7 + #include <linux/clk-provider.h> 8 + #include "clk.h" 9 + 10 + #define div_mask(width) ((1 << (width)) - 1) 11 + 12 + static bool _is_best_half_div(unsigned long rate, unsigned long now, 13 + unsigned long best, unsigned long flags) 14 + { 15 + if (flags & CLK_DIVIDER_ROUND_CLOSEST) 16 + return abs(rate - now) < abs(rate - best); 17 + 18 + return now <= rate && now > best; 19 + } 20 + 21 + static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw, 22 + unsigned long parent_rate) 23 + { 24 + struct clk_divider *divider = to_clk_divider(hw); 25 + unsigned int val; 26 + 27 + val = clk_readl(divider->reg) >> divider->shift; 28 + val &= div_mask(divider->width); 29 + val = val * 2 + 3; 30 + 31 + return DIV_ROUND_UP_ULL(((u64)parent_rate * 2), val); 32 + } 33 + 34 + static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate, 35 + unsigned long *best_parent_rate, u8 width, 36 + unsigned long flags) 37 + { 38 + unsigned int i, bestdiv = 0; 39 + unsigned long parent_rate, best = 0, now, maxdiv; 40 + unsigned long parent_rate_saved = *best_parent_rate; 41 + 42 + if (!rate) 43 + rate = 1; 44 + 45 + maxdiv = div_mask(width); 46 + 47 + if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { 48 + parent_rate = *best_parent_rate; 49 + bestdiv = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), rate); 50 + if (bestdiv < 3) 51 + bestdiv = 0; 52 + else 53 + bestdiv = (bestdiv - 3) / 2; 54 + bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; 55 + return bestdiv; 56 + } 57 + 58 + /* 59 + * The maximum divider we can use without overflowing 60 + * unsigned long in rate * i below 61 + */ 62 + maxdiv = min(ULONG_MAX / rate, maxdiv); 63 + 64 + for (i = 0; i <= maxdiv; i++) { 65 + if (((u64)rate * (i * 2 + 3)) == ((u64)parent_rate_saved * 2)) { 66 + /* 67 + * It's the most ideal case if the requested rate can be 68 + * divided from parent clock without needing to change 69 + * parent rate, so return the divider immediately. 70 + */ 71 + *best_parent_rate = parent_rate_saved; 72 + return i; 73 + } 74 + parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 75 + ((u64)rate * (i * 2 + 3)) / 2); 76 + now = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), 77 + (i * 2 + 3)); 78 + 79 + if (_is_best_half_div(rate, now, best, flags)) { 80 + bestdiv = i; 81 + best = now; 82 + *best_parent_rate = parent_rate; 83 + } 84 + } 85 + 86 + if (!bestdiv) { 87 + bestdiv = div_mask(width); 88 + *best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1); 89 + } 90 + 91 + return bestdiv; 92 + } 93 + 94 + static long clk_half_divider_round_rate(struct clk_hw *hw, unsigned long rate, 95 + unsigned long *prate) 96 + { 97 + struct clk_divider *divider = to_clk_divider(hw); 98 + int div; 99 + 100 + div = clk_half_divider_bestdiv(hw, rate, prate, 101 + divider->width, 102 + divider->flags); 103 + 104 + return DIV_ROUND_UP_ULL(((u64)*prate * 2), div * 2 + 3); 105 + } 106 + 107 + static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate, 108 + unsigned long parent_rate) 109 + { 110 + struct clk_divider *divider = to_clk_divider(hw); 111 + unsigned int value; 112 + unsigned long flags = 0; 113 + u32 val; 114 + 115 + value = DIV_ROUND_UP_ULL(((u64)parent_rate * 2), rate); 116 + value = (value - 3) / 2; 117 + value = min_t(unsigned int, value, div_mask(divider->width)); 118 + 119 + if (divider->lock) 120 + spin_lock_irqsave(divider->lock, flags); 121 + else 122 + __acquire(divider->lock); 123 + 124 + if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { 125 + val = div_mask(divider->width) << (divider->shift + 16); 126 + } else { 127 + val = clk_readl(divider->reg); 128 + val &= ~(div_mask(divider->width) << divider->shift); 129 + } 130 + val |= value << divider->shift; 131 + clk_writel(val, divider->reg); 132 + 133 + if (divider->lock) 134 + spin_unlock_irqrestore(divider->lock, flags); 135 + else 136 + __release(divider->lock); 137 + 138 + return 0; 139 + } 140 + 141 + const struct clk_ops clk_half_divider_ops = { 142 + .recalc_rate = clk_half_divider_recalc_rate, 143 + .round_rate = clk_half_divider_round_rate, 144 + .set_rate = clk_half_divider_set_rate, 145 + }; 146 + EXPORT_SYMBOL_GPL(clk_half_divider_ops); 147 + 148 + /** 149 + * Register a clock branch. 150 + * Most clock branches have a form like 151 + * 152 + * src1 --|--\ 153 + * |M |--[GATE]-[DIV]- 154 + * src2 --|--/ 155 + * 156 + * sometimes without one of those components. 157 + */ 158 + struct clk *rockchip_clk_register_halfdiv(const char *name, 159 + const char *const *parent_names, 160 + u8 num_parents, void __iomem *base, 161 + int muxdiv_offset, u8 mux_shift, 162 + u8 mux_width, u8 mux_flags, 163 + u8 div_shift, u8 div_width, 164 + u8 div_flags, int gate_offset, 165 + u8 gate_shift, u8 gate_flags, 166 + unsigned long flags, 167 + spinlock_t *lock) 168 + { 169 + struct clk *clk; 170 + struct clk_mux *mux = NULL; 171 + struct clk_gate *gate = NULL; 172 + struct clk_divider *div = NULL; 173 + const struct clk_ops *mux_ops = NULL, *div_ops = NULL, 174 + *gate_ops = NULL; 175 + 176 + if (num_parents > 1) { 177 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 178 + if (!mux) 179 + return ERR_PTR(-ENOMEM); 180 + 181 + mux->reg = base + muxdiv_offset; 182 + mux->shift = mux_shift; 183 + mux->mask = BIT(mux_width) - 1; 184 + mux->flags = mux_flags; 185 + mux->lock = lock; 186 + mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops 187 + : &clk_mux_ops; 188 + } 189 + 190 + if (gate_offset >= 0) { 191 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 192 + if (!gate) 193 + goto err_gate; 194 + 195 + gate->flags = gate_flags; 196 + gate->reg = base + gate_offset; 197 + gate->bit_idx = gate_shift; 198 + gate->lock = lock; 199 + gate_ops = &clk_gate_ops; 200 + } 201 + 202 + if (div_width > 0) { 203 + div = kzalloc(sizeof(*div), GFP_KERNEL); 204 + if (!div) 205 + goto err_div; 206 + 207 + div->flags = div_flags; 208 + div->reg = base + muxdiv_offset; 209 + div->shift = div_shift; 210 + div->width = div_width; 211 + div->lock = lock; 212 + div_ops = &clk_half_divider_ops; 213 + } 214 + 215 + clk = clk_register_composite(NULL, name, parent_names, num_parents, 216 + mux ? &mux->hw : NULL, mux_ops, 217 + div ? &div->hw : NULL, div_ops, 218 + gate ? &gate->hw : NULL, gate_ops, 219 + flags); 220 + 221 + return clk; 222 + err_div: 223 + kfree(gate); 224 + err_gate: 225 + kfree(mux); 226 + return ERR_PTR(-ENOMEM); 227 + }
+1039
drivers/clk/rockchip/clk-px30.c
··· 1 + /* 2 + * Copyright (c) 2018 Rockchip Electronics Co. Ltd. 3 + * Author: Elaine Zhang<zhangqing@rock-chips.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/clk-provider.h> 17 + #include <linux/of.h> 18 + #include <linux/of_address.h> 19 + #include <linux/syscore_ops.h> 20 + #include <dt-bindings/clock/px30-cru.h> 21 + #include "clk.h" 22 + 23 + #define PX30_GRF_SOC_STATUS0 0x480 24 + 25 + enum px30_plls { 26 + apll, dpll, cpll, npll, apll_b_h, apll_b_l, 27 + }; 28 + 29 + enum px30_pmu_plls { 30 + gpll, 31 + }; 32 + 33 + static struct rockchip_pll_rate_table px30_pll_rates[] = { 34 + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 35 + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 36 + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), 37 + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), 38 + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), 39 + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), 40 + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), 41 + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), 42 + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), 43 + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), 44 + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), 45 + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), 46 + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), 47 + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), 48 + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), 49 + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), 50 + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), 51 + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 52 + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), 53 + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), 54 + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), 55 + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 56 + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), 57 + RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0), 58 + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), 59 + RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0), 60 + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), 61 + RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0), 62 + RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0), 63 + RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0), 64 + RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0), 65 + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), 66 + RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), 67 + RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0), 68 + RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0), 69 + RK3036_PLL_RATE(624000000, 1, 52, 2, 1, 1, 0), 70 + RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), 71 + RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), 72 + RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0), 73 + RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), 74 + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), 75 + RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0), 76 + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), 77 + RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0), 78 + { /* sentinel */ }, 79 + }; 80 + 81 + #define PX30_DIV_ACLKM_MASK 0x7 82 + #define PX30_DIV_ACLKM_SHIFT 12 83 + #define PX30_DIV_PCLK_DBG_MASK 0xf 84 + #define PX30_DIV_PCLK_DBG_SHIFT 8 85 + 86 + #define PX30_CLKSEL0(_aclk_core, _pclk_dbg) \ 87 + { \ 88 + .reg = PX30_CLKSEL_CON(0), \ 89 + .val = HIWORD_UPDATE(_aclk_core, PX30_DIV_ACLKM_MASK, \ 90 + PX30_DIV_ACLKM_SHIFT) | \ 91 + HIWORD_UPDATE(_pclk_dbg, PX30_DIV_PCLK_DBG_MASK, \ 92 + PX30_DIV_PCLK_DBG_SHIFT), \ 93 + } 94 + 95 + #define PX30_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ 96 + { \ 97 + .prate = _prate, \ 98 + .divs = { \ 99 + PX30_CLKSEL0(_aclk_core, _pclk_dbg), \ 100 + }, \ 101 + } 102 + 103 + static struct rockchip_cpuclk_rate_table px30_cpuclk_rates[] __initdata = { 104 + PX30_CPUCLK_RATE(1608000000, 1, 7), 105 + PX30_CPUCLK_RATE(1584000000, 1, 7), 106 + PX30_CPUCLK_RATE(1560000000, 1, 7), 107 + PX30_CPUCLK_RATE(1536000000, 1, 7), 108 + PX30_CPUCLK_RATE(1512000000, 1, 7), 109 + PX30_CPUCLK_RATE(1488000000, 1, 5), 110 + PX30_CPUCLK_RATE(1464000000, 1, 5), 111 + PX30_CPUCLK_RATE(1440000000, 1, 5), 112 + PX30_CPUCLK_RATE(1416000000, 1, 5), 113 + PX30_CPUCLK_RATE(1392000000, 1, 5), 114 + PX30_CPUCLK_RATE(1368000000, 1, 5), 115 + PX30_CPUCLK_RATE(1344000000, 1, 5), 116 + PX30_CPUCLK_RATE(1320000000, 1, 5), 117 + PX30_CPUCLK_RATE(1296000000, 1, 5), 118 + PX30_CPUCLK_RATE(1272000000, 1, 5), 119 + PX30_CPUCLK_RATE(1248000000, 1, 5), 120 + PX30_CPUCLK_RATE(1224000000, 1, 5), 121 + PX30_CPUCLK_RATE(1200000000, 1, 5), 122 + PX30_CPUCLK_RATE(1104000000, 1, 5), 123 + PX30_CPUCLK_RATE(1008000000, 1, 5), 124 + PX30_CPUCLK_RATE(912000000, 1, 5), 125 + PX30_CPUCLK_RATE(816000000, 1, 3), 126 + PX30_CPUCLK_RATE(696000000, 1, 3), 127 + PX30_CPUCLK_RATE(600000000, 1, 3), 128 + PX30_CPUCLK_RATE(408000000, 1, 1), 129 + PX30_CPUCLK_RATE(312000000, 1, 1), 130 + PX30_CPUCLK_RATE(216000000, 1, 1), 131 + PX30_CPUCLK_RATE(96000000, 1, 1), 132 + }; 133 + 134 + static const struct rockchip_cpuclk_reg_data px30_cpuclk_data = { 135 + .core_reg = PX30_CLKSEL_CON(0), 136 + .div_core_shift = 0, 137 + .div_core_mask = 0xf, 138 + .mux_core_alt = 1, 139 + .mux_core_main = 0, 140 + .mux_core_shift = 7, 141 + .mux_core_mask = 0x1, 142 + }; 143 + 144 + PNAME(mux_pll_p) = { "xin24m"}; 145 + PNAME(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc32k_pmu" }; 146 + PNAME(mux_armclk_p) = { "apll_core", "gpll_core" }; 147 + PNAME(mux_ddrphy_p) = { "dpll_ddr", "gpll_ddr" }; 148 + PNAME(mux_ddrstdby_p) = { "clk_ddrphy1x", "clk_stdby_2wrap" }; 149 + PNAME(mux_4plls_p) = { "gpll", "dummy_cpll", "usb480m", "npll" }; 150 + PNAME(mux_cpll_npll_p) = { "cpll", "npll" }; 151 + PNAME(mux_npll_cpll_p) = { "npll", "cpll" }; 152 + PNAME(mux_gpll_cpll_p) = { "gpll", "dummy_cpll" }; 153 + PNAME(mux_gpll_npll_p) = { "gpll", "npll" }; 154 + PNAME(mux_gpll_xin24m_p) = { "gpll", "xin24m"}; 155 + PNAME(mux_gpll_cpll_npll_p) = { "gpll", "dummy_cpll", "npll" }; 156 + PNAME(mux_gpll_cpll_npll_xin24m_p) = { "gpll", "dummy_cpll", "npll", "xin24m" }; 157 + PNAME(mux_gpll_xin24m_npll_p) = { "gpll", "xin24m", "npll"}; 158 + PNAME(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" }; 159 + PNAME(mux_i2s0_tx_p) = { "clk_i2s0_tx_src", "clk_i2s0_tx_frac", "mclk_i2s0_tx_in", "xin12m"}; 160 + PNAME(mux_i2s0_rx_p) = { "clk_i2s0_rx_src", "clk_i2s0_rx_frac", "mclk_i2s0_rx_in", "xin12m"}; 161 + PNAME(mux_i2s1_p) = { "clk_i2s1_src", "clk_i2s1_frac", "i2s1_clkin", "xin12m"}; 162 + PNAME(mux_i2s2_p) = { "clk_i2s2_src", "clk_i2s2_frac", "i2s2_clkin", "xin12m"}; 163 + PNAME(mux_i2s0_tx_out_p) = { "clk_i2s0_tx", "xin12m", "clk_i2s0_rx"}; 164 + PNAME(mux_i2s0_rx_out_p) = { "clk_i2s0_rx", "xin12m", "clk_i2s0_tx"}; 165 + PNAME(mux_i2s1_out_p) = { "clk_i2s1", "xin12m"}; 166 + PNAME(mux_i2s2_out_p) = { "clk_i2s2", "xin12m"}; 167 + PNAME(mux_i2s0_tx_rx_p) = { "clk_i2s0_tx_mux", "clk_i2s0_rx_mux"}; 168 + PNAME(mux_i2s0_rx_tx_p) = { "clk_i2s0_rx_mux", "clk_i2s0_tx_mux"}; 169 + PNAME(mux_uart_src_p) = { "gpll", "xin24m", "usb480m", "npll" }; 170 + PNAME(mux_uart1_p) = { "clk_uart1_src", "clk_uart1_np5", "clk_uart1_frac" }; 171 + PNAME(mux_uart2_p) = { "clk_uart2_src", "clk_uart2_np5", "clk_uart2_frac" }; 172 + PNAME(mux_uart3_p) = { "clk_uart3_src", "clk_uart3_np5", "clk_uart3_frac" }; 173 + PNAME(mux_uart4_p) = { "clk_uart4_src", "clk_uart4_np5", "clk_uart4_frac" }; 174 + PNAME(mux_uart5_p) = { "clk_uart5_src", "clk_uart5_np5", "clk_uart5_frac" }; 175 + PNAME(mux_cif_out_p) = { "xin24m", "dummy_cpll", "npll", "usb480m" }; 176 + PNAME(mux_dclk_vopb_p) = { "dclk_vopb_src", "dclk_vopb_frac", "xin24m" }; 177 + PNAME(mux_dclk_vopl_p) = { "dclk_vopl_src", "dclk_vopl_frac", "xin24m" }; 178 + PNAME(mux_gmac_p) = { "clk_gmac_src", "gmac_clkin" }; 179 + PNAME(mux_gmac_rmii_sel_p) = { "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx_div2" }; 180 + PNAME(mux_rtc32k_pmu_p) = { "xin32k", "pmu_pvtm_32k", "clk_rtc32k_frac", }; 181 + PNAME(mux_wifi_pmu_p) = { "xin24m", "clk_wifi_pmu_src" }; 182 + PNAME(mux_uart0_pmu_p) = { "clk_uart0_pmu_src", "clk_uart0_np5", "clk_uart0_frac" }; 183 + PNAME(mux_usbphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; 184 + PNAME(mux_mipidsiphy_ref_p) = { "xin24m", "clk_ref24m_pmu" }; 185 + PNAME(mux_gpu_p) = { "clk_gpu_div", "clk_gpu_np5" }; 186 + 187 + static struct rockchip_pll_clock px30_pll_clks[] __initdata = { 188 + [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, 189 + 0, PX30_PLL_CON(0), 190 + PX30_MODE_CON, 0, 0, 0, px30_pll_rates), 191 + [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, 192 + 0, PX30_PLL_CON(8), 193 + PX30_MODE_CON, 4, 1, 0, NULL), 194 + [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, 195 + 0, PX30_PLL_CON(16), 196 + PX30_MODE_CON, 2, 2, 0, px30_pll_rates), 197 + [npll] = PLL(pll_rk3328, PLL_NPLL, "npll", mux_pll_p, 198 + 0, PX30_PLL_CON(24), 199 + PX30_MODE_CON, 6, 4, 0, px30_pll_rates), 200 + }; 201 + 202 + static struct rockchip_pll_clock px30_pmu_pll_clks[] __initdata = { 203 + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, 0, PX30_PMU_PLL_CON(0), 204 + PX30_PMU_MODE, 0, 3, 0, px30_pll_rates), 205 + }; 206 + 207 + #define MFLAGS CLK_MUX_HIWORD_MASK 208 + #define DFLAGS CLK_DIVIDER_HIWORD_MASK 209 + #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) 210 + 211 + static struct rockchip_clk_branch px30_pdm_fracmux __initdata = 212 + MUX(0, "clk_pdm_mux", mux_pdm_p, CLK_SET_RATE_PARENT, 213 + PX30_CLKSEL_CON(26), 15, 1, MFLAGS); 214 + 215 + static struct rockchip_clk_branch px30_i2s0_tx_fracmux __initdata = 216 + MUX(0, "clk_i2s0_tx_mux", mux_i2s0_tx_p, CLK_SET_RATE_PARENT, 217 + PX30_CLKSEL_CON(28), 10, 2, MFLAGS); 218 + 219 + static struct rockchip_clk_branch px30_i2s0_rx_fracmux __initdata = 220 + MUX(0, "clk_i2s0_rx_mux", mux_i2s0_rx_p, CLK_SET_RATE_PARENT, 221 + PX30_CLKSEL_CON(58), 10, 2, MFLAGS); 222 + 223 + static struct rockchip_clk_branch px30_i2s1_fracmux __initdata = 224 + MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT, 225 + PX30_CLKSEL_CON(30), 10, 2, MFLAGS); 226 + 227 + static struct rockchip_clk_branch px30_i2s2_fracmux __initdata = 228 + MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT, 229 + PX30_CLKSEL_CON(32), 10, 2, MFLAGS); 230 + 231 + static struct rockchip_clk_branch px30_uart1_fracmux __initdata = 232 + MUX(0, "clk_uart1_mux", mux_uart1_p, CLK_SET_RATE_PARENT, 233 + PX30_CLKSEL_CON(35), 14, 2, MFLAGS); 234 + 235 + static struct rockchip_clk_branch px30_uart2_fracmux __initdata = 236 + MUX(0, "clk_uart2_mux", mux_uart2_p, CLK_SET_RATE_PARENT, 237 + PX30_CLKSEL_CON(38), 14, 2, MFLAGS); 238 + 239 + static struct rockchip_clk_branch px30_uart3_fracmux __initdata = 240 + MUX(0, "clk_uart3_mux", mux_uart3_p, CLK_SET_RATE_PARENT, 241 + PX30_CLKSEL_CON(41), 14, 2, MFLAGS); 242 + 243 + static struct rockchip_clk_branch px30_uart4_fracmux __initdata = 244 + MUX(0, "clk_uart4_mux", mux_uart4_p, CLK_SET_RATE_PARENT, 245 + PX30_CLKSEL_CON(44), 14, 2, MFLAGS); 246 + 247 + static struct rockchip_clk_branch px30_uart5_fracmux __initdata = 248 + MUX(0, "clk_uart5_mux", mux_uart5_p, CLK_SET_RATE_PARENT, 249 + PX30_CLKSEL_CON(47), 14, 2, MFLAGS); 250 + 251 + static struct rockchip_clk_branch px30_dclk_vopb_fracmux __initdata = 252 + MUX(0, "dclk_vopb_mux", mux_dclk_vopb_p, CLK_SET_RATE_PARENT, 253 + PX30_CLKSEL_CON(5), 14, 2, MFLAGS); 254 + 255 + static struct rockchip_clk_branch px30_dclk_vopl_fracmux __initdata = 256 + MUX(0, "dclk_vopl_mux", mux_dclk_vopl_p, CLK_SET_RATE_PARENT, 257 + PX30_CLKSEL_CON(8), 14, 2, MFLAGS); 258 + 259 + static struct rockchip_clk_branch px30_rtc32k_pmu_fracmux __initdata = 260 + MUX(SCLK_RTC32K_PMU, "clk_rtc32k_pmu", mux_rtc32k_pmu_p, CLK_SET_RATE_PARENT, 261 + PX30_PMU_CLKSEL_CON(0), 14, 2, MFLAGS); 262 + 263 + static struct rockchip_clk_branch px30_uart0_pmu_fracmux __initdata = 264 + MUX(0, "clk_uart0_pmu_mux", mux_uart0_pmu_p, CLK_SET_RATE_PARENT, 265 + PX30_PMU_CLKSEL_CON(4), 14, 2, MFLAGS); 266 + 267 + static struct rockchip_clk_branch px30_clk_branches[] __initdata = { 268 + /* 269 + * Clock-Architecture Diagram 1 270 + */ 271 + 272 + MUX(USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT, 273 + PX30_MODE_CON, 8, 2, MFLAGS), 274 + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), 275 + 276 + /* 277 + * Clock-Architecture Diagram 3 278 + */ 279 + 280 + /* PD_CORE */ 281 + GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED, 282 + PX30_CLKGATE_CON(0), 0, GFLAGS), 283 + GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED, 284 + PX30_CLKGATE_CON(0), 0, GFLAGS), 285 + COMPOSITE_NOMUX(0, "pclk_dbg", "armclk", CLK_IGNORE_UNUSED, 286 + PX30_CLKSEL_CON(0), 8, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, 287 + PX30_CLKGATE_CON(0), 2, GFLAGS), 288 + COMPOSITE_NOMUX(0, "aclk_core", "armclk", CLK_IGNORE_UNUSED, 289 + PX30_CLKSEL_CON(0), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, 290 + PX30_CLKGATE_CON(0), 1, GFLAGS), 291 + GATE(0, "aclk_core_niu", "aclk_core", CLK_IGNORE_UNUSED, 292 + PX30_CLKGATE_CON(0), 4, GFLAGS), 293 + GATE(0, "aclk_core_prf", "aclk_core", CLK_IGNORE_UNUSED, 294 + PX30_CLKGATE_CON(17), 5, GFLAGS), 295 + GATE(0, "pclk_dbg_niu", "pclk_dbg", CLK_IGNORE_UNUSED, 296 + PX30_CLKGATE_CON(0), 5, GFLAGS), 297 + GATE(0, "pclk_core_dbg", "pclk_dbg", CLK_IGNORE_UNUSED, 298 + PX30_CLKGATE_CON(0), 6, GFLAGS), 299 + GATE(0, "pclk_core_grf", "pclk_dbg", CLK_IGNORE_UNUSED, 300 + PX30_CLKGATE_CON(17), 6, GFLAGS), 301 + 302 + GATE(0, "clk_jtag", "jtag_clkin", CLK_IGNORE_UNUSED, 303 + PX30_CLKGATE_CON(0), 3, GFLAGS), 304 + GATE(SCLK_PVTM, "clk_pvtm", "xin24m", 0, 305 + PX30_CLKGATE_CON(17), 4, GFLAGS), 306 + 307 + /* PD_GPU */ 308 + COMPOSITE_NODIV(0, "clk_gpu_src", mux_4plls_p, 0, 309 + PX30_CLKSEL_CON(1), 6, 2, MFLAGS, 310 + PX30_CLKGATE_CON(0), 8, GFLAGS), 311 + COMPOSITE_NOMUX(0, "clk_gpu_div", "clk_gpu_src", 0, 312 + PX30_CLKSEL_CON(1), 0, 4, DFLAGS, 313 + PX30_CLKGATE_CON(0), 12, GFLAGS), 314 + COMPOSITE_NOMUX_HALFDIV(0, "clk_gpu_np5", "clk_gpu_src", 0, 315 + PX30_CLKSEL_CON(1), 8, 4, DFLAGS, 316 + PX30_CLKGATE_CON(0), 9, GFLAGS), 317 + COMPOSITE_NODIV(SCLK_GPU, "clk_gpu", mux_gpu_p, CLK_SET_RATE_PARENT, 318 + PX30_CLKSEL_CON(1), 15, 1, MFLAGS, 319 + PX30_CLKGATE_CON(0), 10, GFLAGS), 320 + COMPOSITE_NOMUX(0, "aclk_gpu", "clk_gpu", CLK_IGNORE_UNUSED, 321 + PX30_CLKSEL_CON(1), 13, 2, DFLAGS, 322 + PX30_CLKGATE_CON(17), 10, GFLAGS), 323 + GATE(0, "aclk_gpu_niu", "aclk_gpu", CLK_IGNORE_UNUSED, 324 + PX30_CLKGATE_CON(0), 11, GFLAGS), 325 + GATE(0, "aclk_gpu_prf", "aclk_gpu", CLK_IGNORE_UNUSED, 326 + PX30_CLKGATE_CON(17), 8, GFLAGS), 327 + GATE(0, "pclk_gpu_grf", "aclk_gpu", CLK_IGNORE_UNUSED, 328 + PX30_CLKGATE_CON(17), 9, GFLAGS), 329 + 330 + /* 331 + * Clock-Architecture Diagram 4 332 + */ 333 + 334 + /* PD_DDR */ 335 + GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED, 336 + PX30_CLKGATE_CON(0), 7, GFLAGS), 337 + GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, 338 + PX30_CLKGATE_CON(0), 13, GFLAGS), 339 + COMPOSITE_NOGATE(SCLK_DDRCLK, "sclk_ddrc", mux_ddrphy_p, CLK_IGNORE_UNUSED, 340 + PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 341 + COMPOSITE_NOGATE(0, "clk_ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED, 342 + PX30_CLKSEL_CON(2), 7, 1, MFLAGS, 0, 3, DFLAGS), 343 + FACTOR_GATE(0, "clk_ddrphy1x", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, 344 + PX30_CLKGATE_CON(0), 14, GFLAGS), 345 + FACTOR_GATE(0, "clk_stdby_2wrap", "clk_ddrphy4x", CLK_IGNORE_UNUSED, 1, 4, 346 + PX30_CLKGATE_CON(1), 0, GFLAGS), 347 + COMPOSITE_NODIV(0, "clk_ddrstdby", mux_ddrstdby_p, CLK_IGNORE_UNUSED, 348 + PX30_CLKSEL_CON(2), 4, 1, MFLAGS, 349 + PX30_CLKGATE_CON(1), 13, GFLAGS), 350 + GATE(0, "aclk_split", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 351 + PX30_CLKGATE_CON(1), 15, GFLAGS), 352 + GATE(0, "clk_msch", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 353 + PX30_CLKGATE_CON(1), 8, GFLAGS), 354 + GATE(0, "aclk_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 355 + PX30_CLKGATE_CON(1), 5, GFLAGS), 356 + GATE(0, "clk_core_ddrc", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 357 + PX30_CLKGATE_CON(1), 6, GFLAGS), 358 + GATE(0, "aclk_cmd_buff", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 359 + PX30_CLKGATE_CON(1), 6, GFLAGS), 360 + GATE(0, "clk_ddrmon", "clk_ddrphy1x", CLK_IGNORE_UNUSED, 361 + PX30_CLKGATE_CON(1), 11, GFLAGS), 362 + 363 + GATE(0, "clk_ddrmon_timer", "xin24m", CLK_IGNORE_UNUSED, 364 + PX30_CLKGATE_CON(0), 15, GFLAGS), 365 + 366 + COMPOSITE_NOMUX(PCLK_DDR, "pclk_ddr", "gpll", CLK_IGNORE_UNUSED, 367 + PX30_CLKSEL_CON(2), 8, 5, DFLAGS, 368 + PX30_CLKGATE_CON(1), 1, GFLAGS), 369 + GATE(0, "pclk_ddrmon", "pclk_ddr", CLK_IGNORE_UNUSED, 370 + PX30_CLKGATE_CON(1), 10, GFLAGS), 371 + GATE(0, "pclk_ddrc", "pclk_ddr", CLK_IGNORE_UNUSED, 372 + PX30_CLKGATE_CON(1), 7, GFLAGS), 373 + GATE(0, "pclk_msch", "pclk_ddr", CLK_IGNORE_UNUSED, 374 + PX30_CLKGATE_CON(1), 9, GFLAGS), 375 + GATE(0, "pclk_stdby", "pclk_ddr", CLK_IGNORE_UNUSED, 376 + PX30_CLKGATE_CON(1), 12, GFLAGS), 377 + GATE(0, "pclk_ddr_grf", "pclk_ddr", CLK_IGNORE_UNUSED, 378 + PX30_CLKGATE_CON(1), 14, GFLAGS), 379 + GATE(0, "pclk_cmdbuff", "pclk_ddr", CLK_IGNORE_UNUSED, 380 + PX30_CLKGATE_CON(1), 3, GFLAGS), 381 + 382 + /* 383 + * Clock-Architecture Diagram 5 384 + */ 385 + 386 + /* PD_VI */ 387 + COMPOSITE(ACLK_VI_PRE, "aclk_vi_pre", mux_gpll_cpll_npll_p, 0, 388 + PX30_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, 389 + PX30_CLKGATE_CON(4), 8, GFLAGS), 390 + COMPOSITE_NOMUX(HCLK_VI_PRE, "hclk_vi_pre", "aclk_vi_pre", 0, 391 + PX30_CLKSEL_CON(11), 8, 4, DFLAGS, 392 + PX30_CLKGATE_CON(4), 12, GFLAGS), 393 + COMPOSITE(SCLK_ISP, "clk_isp", mux_gpll_cpll_npll_p, 0, 394 + PX30_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS, 395 + PX30_CLKGATE_CON(4), 9, GFLAGS), 396 + COMPOSITE(SCLK_CIF_OUT, "clk_cif_out", mux_cif_out_p, 0, 397 + PX30_CLKSEL_CON(13), 6, 2, MFLAGS, 0, 6, DFLAGS, 398 + PX30_CLKGATE_CON(4), 11, GFLAGS), 399 + GATE(PCLK_ISP, "pclkin_isp", "ext_pclkin", 0, 400 + PX30_CLKGATE_CON(4), 13, GFLAGS), 401 + GATE(PCLK_CIF, "pclkin_cif", "ext_pclkin", 0, 402 + PX30_CLKGATE_CON(4), 14, GFLAGS), 403 + 404 + /* 405 + * Clock-Architecture Diagram 6 406 + */ 407 + 408 + /* PD_VO */ 409 + COMPOSITE(ACLK_VO_PRE, "aclk_vo_pre", mux_gpll_cpll_npll_p, 0, 410 + PX30_CLKSEL_CON(3), 6, 2, MFLAGS, 0, 5, DFLAGS, 411 + PX30_CLKGATE_CON(2), 0, GFLAGS), 412 + COMPOSITE_NOMUX(HCLK_VO_PRE, "hclk_vo_pre", "aclk_vo_pre", 0, 413 + PX30_CLKSEL_CON(3), 8, 4, DFLAGS, 414 + PX30_CLKGATE_CON(2), 12, GFLAGS), 415 + COMPOSITE_NOMUX(PCLK_VO_PRE, "pclk_vo_pre", "aclk_vo_pre", 0, 416 + PX30_CLKSEL_CON(3), 12, 4, DFLAGS, 417 + PX30_CLKGATE_CON(2), 13, GFLAGS), 418 + COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_gpll_cpll_npll_p, 0, 419 + PX30_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS, 420 + PX30_CLKGATE_CON(2), 1, GFLAGS), 421 + 422 + COMPOSITE(SCLK_VOPB_PWM, "clk_vopb_pwm", mux_gpll_xin24m_p, 0, 423 + PX30_CLKSEL_CON(7), 7, 1, MFLAGS, 0, 7, DFLAGS, 424 + PX30_CLKGATE_CON(2), 5, GFLAGS), 425 + COMPOSITE(0, "dclk_vopb_src", mux_cpll_npll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, 426 + PX30_CLKSEL_CON(5), 11, 1, MFLAGS, 0, 8, DFLAGS, 427 + PX30_CLKGATE_CON(2), 2, GFLAGS), 428 + COMPOSITE_FRACMUX(0, "dclk_vopb_frac", "dclk_vopb_src", CLK_SET_RATE_PARENT, 429 + PX30_CLKSEL_CON(6), 0, 430 + PX30_CLKGATE_CON(2), 3, GFLAGS, 431 + &px30_dclk_vopb_fracmux), 432 + GATE(DCLK_VOPB, "dclk_vopb", "dclk_vopb_mux", CLK_SET_RATE_PARENT, 433 + PX30_CLKGATE_CON(2), 4, GFLAGS), 434 + COMPOSITE(0, "dclk_vopl_src", mux_npll_cpll_p, 0, 435 + PX30_CLKSEL_CON(8), 11, 1, MFLAGS, 0, 8, DFLAGS, 436 + PX30_CLKGATE_CON(2), 6, GFLAGS), 437 + COMPOSITE_FRACMUX(0, "dclk_vopl_frac", "dclk_vopl_src", CLK_SET_RATE_PARENT, 438 + PX30_CLKSEL_CON(9), 0, 439 + PX30_CLKGATE_CON(2), 7, GFLAGS, 440 + &px30_dclk_vopl_fracmux), 441 + GATE(DCLK_VOPL, "dclk_vopl", "dclk_vopl_mux", CLK_SET_RATE_PARENT, 442 + PX30_CLKGATE_CON(2), 8, GFLAGS), 443 + 444 + /* PD_VPU */ 445 + COMPOSITE(0, "aclk_vpu_pre", mux_gpll_cpll_npll_p, 0, 446 + PX30_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS, 447 + PX30_CLKGATE_CON(4), 0, GFLAGS), 448 + COMPOSITE_NOMUX(0, "hclk_vpu_pre", "aclk_vpu_pre", 0, 449 + PX30_CLKSEL_CON(10), 8, 4, DFLAGS, 450 + PX30_CLKGATE_CON(4), 2, GFLAGS), 451 + COMPOSITE(SCLK_CORE_VPU, "sclk_core_vpu", mux_gpll_cpll_npll_p, 0, 452 + PX30_CLKSEL_CON(13), 14, 2, MFLAGS, 8, 5, DFLAGS, 453 + PX30_CLKGATE_CON(4), 1, GFLAGS), 454 + 455 + /* 456 + * Clock-Architecture Diagram 7 457 + */ 458 + 459 + COMPOSITE_NODIV(ACLK_PERI_SRC, "aclk_peri_src", mux_gpll_cpll_p, 0, 460 + PX30_CLKSEL_CON(14), 15, 1, MFLAGS, 461 + PX30_CLKGATE_CON(5), 7, GFLAGS), 462 + COMPOSITE_NOMUX(ACLK_PERI_PRE, "aclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED, 463 + PX30_CLKSEL_CON(14), 0, 5, DFLAGS, 464 + PX30_CLKGATE_CON(5), 8, GFLAGS), 465 + DIV(HCLK_PERI_PRE, "hclk_peri_pre", "aclk_peri_src", CLK_IGNORE_UNUSED, 466 + PX30_CLKSEL_CON(14), 8, 5, DFLAGS), 467 + 468 + /* PD_MMC_NAND */ 469 + GATE(HCLK_MMC_NAND, "hclk_mmc_nand", "hclk_peri_pre", 0, 470 + PX30_CLKGATE_CON(6), 0, GFLAGS), 471 + COMPOSITE(SCLK_NANDC, "clk_nandc", mux_gpll_cpll_npll_p, 0, 472 + PX30_CLKSEL_CON(15), 6, 2, MFLAGS, 0, 5, DFLAGS, 473 + PX30_CLKGATE_CON(5), 13, GFLAGS), 474 + 475 + COMPOSITE(SCLK_SDIO, "clk_sdio", mux_gpll_cpll_npll_xin24m_p, 0, 476 + PX30_CLKSEL_CON(18), 14, 2, MFLAGS, 0, 8, DFLAGS, 477 + PX30_CLKGATE_CON(6), 3, GFLAGS), 478 + 479 + COMPOSITE(SCLK_EMMC, "clk_emmc", mux_gpll_cpll_npll_xin24m_p, 0, 480 + PX30_CLKSEL_CON(20), 14, 2, MFLAGS, 0, 8, DFLAGS, 481 + PX30_CLKGATE_CON(6), 6, GFLAGS), 482 + 483 + COMPOSITE(SCLK_SFC, "clk_sfc", mux_gpll_cpll_p, 0, 484 + PX30_CLKSEL_CON(22), 7, 1, MFLAGS, 0, 7, DFLAGS, 485 + PX30_CLKGATE_CON(6), 7, GFLAGS), 486 + 487 + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", 488 + PX30_SDMMC_CON0, 1), 489 + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", 490 + PX30_SDMMC_CON1, 1), 491 + 492 + MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", 493 + PX30_SDIO_CON0, 1), 494 + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", 495 + PX30_SDIO_CON1, 1), 496 + 497 + MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", 498 + PX30_EMMC_CON0, 1), 499 + MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", 500 + PX30_EMMC_CON1, 1), 501 + 502 + /* PD_SDCARD */ 503 + GATE(0, "hclk_sdmmc_pre", "hclk_peri_pre", 0, 504 + PX30_CLKGATE_CON(6), 12, GFLAGS), 505 + COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_gpll_cpll_npll_xin24m_p, 0, 506 + PX30_CLKSEL_CON(16), 14, 2, MFLAGS, 0, 8, DFLAGS, 507 + PX30_CLKGATE_CON(6), 15, GFLAGS), 508 + 509 + /* PD_USB */ 510 + GATE(HCLK_USB, "hclk_usb", "hclk_peri_pre", 0, 511 + PX30_CLKGATE_CON(7), 2, GFLAGS), 512 + GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k_pmu", 0, 513 + PX30_CLKGATE_CON(7), 3, GFLAGS), 514 + 515 + /* PD_GMAC */ 516 + COMPOSITE(SCLK_GMAC_SRC, "clk_gmac_src", mux_gpll_cpll_npll_p, 0, 517 + PX30_CLKSEL_CON(22), 14, 2, MFLAGS, 8, 5, DFLAGS, 518 + PX30_CLKGATE_CON(7), 11, GFLAGS), 519 + MUX(SCLK_GMAC, "clk_gmac", mux_gmac_p, CLK_SET_RATE_PARENT, 520 + PX30_CLKSEL_CON(23), 6, 1, MFLAGS), 521 + GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_gmac", 0, 522 + PX30_CLKGATE_CON(7), 15, GFLAGS), 523 + GATE(SCLK_GMAC_RX_TX, "clk_gmac_rx_tx", "clk_gmac", 0, 524 + PX30_CLKGATE_CON(7), 13, GFLAGS), 525 + FACTOR(0, "clk_gmac_rx_tx_div2", "clk_gmac_rx_tx", 0, 1, 2), 526 + FACTOR(0, "clk_gmac_rx_tx_div20", "clk_gmac_rx_tx", 0, 1, 20), 527 + MUX(SCLK_GMAC_RMII, "clk_gmac_rmii_sel", mux_gmac_rmii_sel_p, CLK_SET_RATE_PARENT, 528 + PX30_CLKSEL_CON(23), 7, 1, MFLAGS), 529 + 530 + GATE(0, "aclk_gmac_pre", "aclk_peri_pre", 0, 531 + PX30_CLKGATE_CON(7), 10, GFLAGS), 532 + COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0, 533 + PX30_CLKSEL_CON(23), 0, 4, DFLAGS, 534 + PX30_CLKGATE_CON(7), 12, GFLAGS), 535 + 536 + COMPOSITE(SCLK_MAC_OUT, "clk_mac_out", mux_gpll_cpll_npll_p, 0, 537 + PX30_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS, 538 + PX30_CLKGATE_CON(8), 5, GFLAGS), 539 + 540 + /* 541 + * Clock-Architecture Diagram 8 542 + */ 543 + 544 + /* PD_BUS */ 545 + COMPOSITE_NODIV(ACLK_BUS_SRC, "aclk_bus_src", mux_gpll_cpll_p, CLK_IGNORE_UNUSED, 546 + PX30_CLKSEL_CON(23), 15, 1, MFLAGS, 547 + PX30_CLKGATE_CON(8), 6, GFLAGS), 548 + COMPOSITE_NOMUX(HCLK_BUS_PRE, "hclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED, 549 + PX30_CLKSEL_CON(24), 0, 5, DFLAGS, 550 + PX30_CLKGATE_CON(8), 8, GFLAGS), 551 + COMPOSITE_NOMUX(ACLK_BUS_PRE, "aclk_bus_pre", "aclk_bus_src", CLK_IGNORE_UNUSED, 552 + PX30_CLKSEL_CON(23), 8, 5, DFLAGS, 553 + PX30_CLKGATE_CON(8), 7, GFLAGS), 554 + COMPOSITE_NOMUX(PCLK_BUS_PRE, "pclk_bus_pre", "aclk_bus_pre", CLK_IGNORE_UNUSED, 555 + PX30_CLKSEL_CON(24), 8, 2, DFLAGS, 556 + PX30_CLKGATE_CON(8), 9, GFLAGS), 557 + GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, 558 + PX30_CLKGATE_CON(8), 10, GFLAGS), 559 + 560 + COMPOSITE(0, "clk_pdm_src", mux_gpll_xin24m_npll_p, 0, 561 + PX30_CLKSEL_CON(26), 8, 2, MFLAGS, 0, 7, DFLAGS, 562 + PX30_CLKGATE_CON(9), 9, GFLAGS), 563 + COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", CLK_SET_RATE_PARENT, 564 + PX30_CLKSEL_CON(27), 0, 565 + PX30_CLKGATE_CON(9), 10, GFLAGS, 566 + &px30_pdm_fracmux), 567 + GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", CLK_SET_RATE_PARENT, 568 + PX30_CLKGATE_CON(9), 11, GFLAGS), 569 + 570 + COMPOSITE(0, "clk_i2s0_tx_src", mux_gpll_npll_p, 0, 571 + PX30_CLKSEL_CON(28), 8, 1, MFLAGS, 0, 7, DFLAGS, 572 + PX30_CLKGATE_CON(9), 12, GFLAGS), 573 + COMPOSITE_FRACMUX(0, "clk_i2s0_tx_frac", "clk_i2s0_tx_src", CLK_SET_RATE_PARENT, 574 + PX30_CLKSEL_CON(29), 0, 575 + PX30_CLKGATE_CON(9), 13, GFLAGS, 576 + &px30_i2s0_tx_fracmux), 577 + COMPOSITE_NODIV(SCLK_I2S0_TX, "clk_i2s0_tx", mux_i2s0_tx_rx_p, CLK_SET_RATE_PARENT, 578 + PX30_CLKSEL_CON(28), 12, 1, MFLAGS, 579 + PX30_CLKGATE_CON(9), 14, GFLAGS), 580 + COMPOSITE_NODIV(0, "clk_i2s0_tx_out_pre", mux_i2s0_tx_out_p, 0, 581 + PX30_CLKSEL_CON(28), 14, 2, MFLAGS, 582 + PX30_CLKGATE_CON(9), 15, GFLAGS), 583 + GATE(SCLK_I2S0_TX_OUT, "clk_i2s0_tx_out", "clk_i2s0_tx_out_pre", CLK_SET_RATE_PARENT, 584 + PX30_CLKGATE_CON(10), 8, CLK_GATE_HIWORD_MASK), 585 + 586 + COMPOSITE(0, "clk_i2s0_rx_src", mux_gpll_npll_p, 0, 587 + PX30_CLKSEL_CON(58), 8, 1, MFLAGS, 0, 7, DFLAGS, 588 + PX30_CLKGATE_CON(17), 0, GFLAGS), 589 + COMPOSITE_FRACMUX(0, "clk_i2s0_rx_frac", "clk_i2s0_rx_src", CLK_SET_RATE_PARENT, 590 + PX30_CLKSEL_CON(59), 0, 591 + PX30_CLKGATE_CON(17), 1, GFLAGS, 592 + &px30_i2s0_rx_fracmux), 593 + COMPOSITE_NODIV(SCLK_I2S0_RX, "clk_i2s0_rx", mux_i2s0_rx_tx_p, CLK_SET_RATE_PARENT, 594 + PX30_CLKSEL_CON(58), 12, 1, MFLAGS, 595 + PX30_CLKGATE_CON(17), 2, GFLAGS), 596 + COMPOSITE_NODIV(0, "clk_i2s0_rx_out_pre", mux_i2s0_rx_out_p, 0, 597 + PX30_CLKSEL_CON(58), 14, 2, MFLAGS, 598 + PX30_CLKGATE_CON(17), 3, GFLAGS), 599 + GATE(SCLK_I2S0_RX_OUT, "clk_i2s0_rx_out", "clk_i2s0_rx_out_pre", CLK_SET_RATE_PARENT, 600 + PX30_CLKGATE_CON(10), 11, CLK_GATE_HIWORD_MASK), 601 + 602 + COMPOSITE(0, "clk_i2s1_src", mux_gpll_npll_p, 0, 603 + PX30_CLKSEL_CON(30), 8, 1, MFLAGS, 0, 7, DFLAGS, 604 + PX30_CLKGATE_CON(10), 0, GFLAGS), 605 + COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_src", CLK_SET_RATE_PARENT, 606 + PX30_CLKSEL_CON(31), 0, 607 + PX30_CLKGATE_CON(10), 1, GFLAGS, 608 + &px30_i2s1_fracmux), 609 + GATE(SCLK_I2S1, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT, 610 + PX30_CLKGATE_CON(10), 2, GFLAGS), 611 + COMPOSITE_NODIV(0, "clk_i2s1_out_pre", mux_i2s1_out_p, 0, 612 + PX30_CLKSEL_CON(30), 15, 1, MFLAGS, 613 + PX30_CLKGATE_CON(10), 3, GFLAGS), 614 + GATE(SCLK_I2S1_OUT, "clk_i2s1_out", "clk_i2s1_out_pre", CLK_SET_RATE_PARENT, 615 + PX30_CLKGATE_CON(10), 9, CLK_GATE_HIWORD_MASK), 616 + 617 + COMPOSITE(0, "clk_i2s2_src", mux_gpll_npll_p, 0, 618 + PX30_CLKSEL_CON(32), 8, 1, MFLAGS, 0, 7, DFLAGS, 619 + PX30_CLKGATE_CON(10), 4, GFLAGS), 620 + COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_src", CLK_SET_RATE_PARENT, 621 + PX30_CLKSEL_CON(33), 0, 622 + PX30_CLKGATE_CON(10), 5, GFLAGS, 623 + &px30_i2s2_fracmux), 624 + GATE(SCLK_I2S2, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT, 625 + PX30_CLKGATE_CON(10), 6, GFLAGS), 626 + COMPOSITE_NODIV(0, "clk_i2s2_out_pre", mux_i2s2_out_p, 0, 627 + PX30_CLKSEL_CON(32), 15, 1, MFLAGS, 628 + PX30_CLKGATE_CON(10), 7, GFLAGS), 629 + GATE(SCLK_I2S2_OUT, "clk_i2s2_out", "clk_i2s2_out_pre", CLK_SET_RATE_PARENT, 630 + PX30_CLKGATE_CON(10), 10, CLK_GATE_HIWORD_MASK), 631 + 632 + COMPOSITE(SCLK_UART1_SRC, "clk_uart1_src", mux_uart_src_p, CLK_SET_RATE_NO_REPARENT, 633 + PX30_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 5, DFLAGS, 634 + PX30_CLKGATE_CON(10), 12, GFLAGS), 635 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart1_np5", "clk_uart1_src", 0, 636 + PX30_CLKSEL_CON(35), 0, 5, DFLAGS, 637 + PX30_CLKGATE_CON(10), 13, GFLAGS), 638 + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, 639 + PX30_CLKSEL_CON(36), 0, 640 + PX30_CLKGATE_CON(10), 14, GFLAGS, 641 + &px30_uart1_fracmux), 642 + GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", CLK_SET_RATE_PARENT, 643 + PX30_CLKGATE_CON(10), 15, GFLAGS), 644 + 645 + COMPOSITE(SCLK_UART2_SRC, "clk_uart2_src", mux_uart_src_p, 0, 646 + PX30_CLKSEL_CON(37), 14, 2, MFLAGS, 0, 5, DFLAGS, 647 + PX30_CLKGATE_CON(11), 0, GFLAGS), 648 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart2_np5", "clk_uart2_src", 0, 649 + PX30_CLKSEL_CON(38), 0, 5, DFLAGS, 650 + PX30_CLKGATE_CON(11), 1, GFLAGS), 651 + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, 652 + PX30_CLKSEL_CON(39), 0, 653 + PX30_CLKGATE_CON(11), 2, GFLAGS, 654 + &px30_uart2_fracmux), 655 + GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", CLK_SET_RATE_PARENT, 656 + PX30_CLKGATE_CON(11), 3, GFLAGS), 657 + 658 + COMPOSITE(0, "clk_uart3_src", mux_uart_src_p, 0, 659 + PX30_CLKSEL_CON(40), 14, 2, MFLAGS, 0, 5, DFLAGS, 660 + PX30_CLKGATE_CON(11), 4, GFLAGS), 661 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart3_np5", "clk_uart3_src", 0, 662 + PX30_CLKSEL_CON(41), 0, 5, DFLAGS, 663 + PX30_CLKGATE_CON(11), 5, GFLAGS), 664 + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, 665 + PX30_CLKSEL_CON(42), 0, 666 + PX30_CLKGATE_CON(11), 6, GFLAGS, 667 + &px30_uart3_fracmux), 668 + GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", CLK_SET_RATE_PARENT, 669 + PX30_CLKGATE_CON(11), 7, GFLAGS), 670 + 671 + COMPOSITE(0, "clk_uart4_src", mux_uart_src_p, 0, 672 + PX30_CLKSEL_CON(43), 14, 2, MFLAGS, 0, 5, DFLAGS, 673 + PX30_CLKGATE_CON(11), 8, GFLAGS), 674 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart4_np5", "clk_uart4_src", 0, 675 + PX30_CLKSEL_CON(44), 0, 5, DFLAGS, 676 + PX30_CLKGATE_CON(11), 9, GFLAGS), 677 + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, 678 + PX30_CLKSEL_CON(45), 0, 679 + PX30_CLKGATE_CON(11), 10, GFLAGS, 680 + &px30_uart4_fracmux), 681 + GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", CLK_SET_RATE_PARENT, 682 + PX30_CLKGATE_CON(11), 11, GFLAGS), 683 + 684 + COMPOSITE(0, "clk_uart5_src", mux_uart_src_p, 0, 685 + PX30_CLKSEL_CON(46), 14, 2, MFLAGS, 0, 5, DFLAGS, 686 + PX30_CLKGATE_CON(11), 12, GFLAGS), 687 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart5_np5", "clk_uart5_src", 0, 688 + PX30_CLKSEL_CON(47), 0, 5, DFLAGS, 689 + PX30_CLKGATE_CON(11), 13, GFLAGS), 690 + COMPOSITE_FRACMUX(0, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, 691 + PX30_CLKSEL_CON(48), 0, 692 + PX30_CLKGATE_CON(11), 14, GFLAGS, 693 + &px30_uart5_fracmux), 694 + GATE(SCLK_UART5, "clk_uart5", "clk_uart5_mux", CLK_SET_RATE_PARENT, 695 + PX30_CLKGATE_CON(11), 15, GFLAGS), 696 + 697 + COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_gpll_xin24m_p, 0, 698 + PX30_CLKSEL_CON(49), 7, 1, MFLAGS, 0, 7, DFLAGS, 699 + PX30_CLKGATE_CON(12), 0, GFLAGS), 700 + COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_gpll_xin24m_p, 0, 701 + PX30_CLKSEL_CON(49), 15, 1, MFLAGS, 8, 7, DFLAGS, 702 + PX30_CLKGATE_CON(12), 1, GFLAGS), 703 + COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_gpll_xin24m_p, 0, 704 + PX30_CLKSEL_CON(50), 7, 1, MFLAGS, 0, 7, DFLAGS, 705 + PX30_CLKGATE_CON(12), 2, GFLAGS), 706 + COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_gpll_xin24m_p, 0, 707 + PX30_CLKSEL_CON(50), 15, 1, MFLAGS, 8, 7, DFLAGS, 708 + PX30_CLKGATE_CON(12), 3, GFLAGS), 709 + COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_gpll_xin24m_p, 0, 710 + PX30_CLKSEL_CON(52), 7, 1, MFLAGS, 0, 7, DFLAGS, 711 + PX30_CLKGATE_CON(12), 5, GFLAGS), 712 + COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_gpll_xin24m_p, 0, 713 + PX30_CLKSEL_CON(52), 15, 1, MFLAGS, 8, 7, DFLAGS, 714 + PX30_CLKGATE_CON(12), 6, GFLAGS), 715 + COMPOSITE(SCLK_SPI0, "clk_spi0", mux_gpll_xin24m_p, 0, 716 + PX30_CLKSEL_CON(53), 7, 1, MFLAGS, 0, 7, DFLAGS, 717 + PX30_CLKGATE_CON(12), 7, GFLAGS), 718 + COMPOSITE(SCLK_SPI1, "clk_spi1", mux_gpll_xin24m_p, 0, 719 + PX30_CLKSEL_CON(53), 15, 1, MFLAGS, 8, 7, DFLAGS, 720 + PX30_CLKGATE_CON(12), 8, GFLAGS), 721 + 722 + GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, 723 + PX30_CLKGATE_CON(13), 0, GFLAGS), 724 + GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, 725 + PX30_CLKGATE_CON(13), 1, GFLAGS), 726 + GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, 727 + PX30_CLKGATE_CON(13), 2, GFLAGS), 728 + GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, 729 + PX30_CLKGATE_CON(13), 3, GFLAGS), 730 + GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, 731 + PX30_CLKGATE_CON(13), 4, GFLAGS), 732 + GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, 733 + PX30_CLKGATE_CON(13), 5, GFLAGS), 734 + 735 + COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 0, 736 + PX30_CLKSEL_CON(54), 0, 11, DFLAGS, 737 + PX30_CLKGATE_CON(12), 9, GFLAGS), 738 + COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0, 739 + PX30_CLKSEL_CON(55), 0, 11, DFLAGS, 740 + PX30_CLKGATE_CON(12), 10, GFLAGS), 741 + COMPOSITE_NOMUX(SCLK_OTP, "clk_otp", "xin24m", 0, 742 + PX30_CLKSEL_CON(56), 0, 3, DFLAGS, 743 + PX30_CLKGATE_CON(12), 11, GFLAGS), 744 + COMPOSITE_NOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 0, 745 + PX30_CLKSEL_CON(56), 4, 2, DFLAGS, 746 + PX30_CLKGATE_CON(13), 6, GFLAGS), 747 + 748 + GATE(0, "clk_cpu_boost", "xin24m", CLK_IGNORE_UNUSED, 749 + PX30_CLKGATE_CON(12), 12, GFLAGS), 750 + 751 + /* PD_CRYPTO */ 752 + GATE(0, "aclk_crypto_pre", "aclk_bus_pre", 0, 753 + PX30_CLKGATE_CON(8), 12, GFLAGS), 754 + GATE(0, "hclk_crypto_pre", "hclk_bus_pre", 0, 755 + PX30_CLKGATE_CON(8), 13, GFLAGS), 756 + COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_gpll_cpll_npll_p, 0, 757 + PX30_CLKSEL_CON(25), 6, 2, MFLAGS, 0, 5, DFLAGS, 758 + PX30_CLKGATE_CON(8), 14, GFLAGS), 759 + COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_gpll_cpll_npll_p, 0, 760 + PX30_CLKSEL_CON(25), 14, 2, MFLAGS, 8, 5, DFLAGS, 761 + PX30_CLKGATE_CON(8), 15, GFLAGS), 762 + 763 + /* 764 + * Clock-Architecture Diagram 9 765 + */ 766 + 767 + /* PD_BUS_TOP */ 768 + GATE(0, "pclk_top_niu", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 0, GFLAGS), 769 + GATE(0, "pclk_top_cru", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 1, GFLAGS), 770 + GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 2, GFLAGS), 771 + GATE(0, "pclk_ddrphy", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 3, GFLAGS), 772 + GATE(PCLK_MIPIDSIPHY, "pclk_mipidsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 4, GFLAGS), 773 + GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top_pre", 0, PX30_CLKGATE_CON(16), 5, GFLAGS), 774 + GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 6, GFLAGS), 775 + GATE(0, "pclk_cpu_hoost", "pclk_top_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(16), 7, GFLAGS), 776 + 777 + /* PD_VI */ 778 + GATE(0, "aclk_vi_niu", "aclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 15, GFLAGS), 779 + GATE(ACLK_CIF, "aclk_cif", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 1, GFLAGS), 780 + GATE(ACLK_ISP, "aclk_isp", "aclk_vi_pre", 0, PX30_CLKGATE_CON(5), 3, GFLAGS), 781 + GATE(0, "hclk_vi_niu", "hclk_vi_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 0, GFLAGS), 782 + GATE(HCLK_CIF, "hclk_cif", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 2, GFLAGS), 783 + GATE(HCLK_ISP, "hclk_isp", "hclk_vi_pre", 0, PX30_CLKGATE_CON(5), 4, GFLAGS), 784 + 785 + /* PD_VO */ 786 + GATE(0, "aclk_vo_niu", "aclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 0, GFLAGS), 787 + GATE(ACLK_VOPB, "aclk_vopb", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 3, GFLAGS), 788 + GATE(ACLK_RGA, "aclk_rga", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 7, GFLAGS), 789 + GATE(ACLK_VOPL, "aclk_vopl", "aclk_vo_pre", 0, PX30_CLKGATE_CON(3), 5, GFLAGS), 790 + 791 + GATE(0, "hclk_vo_niu", "hclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 1, GFLAGS), 792 + GATE(HCLK_VOPB, "hclk_vopb", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 4, GFLAGS), 793 + GATE(HCLK_RGA, "hclk_rga", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 8, GFLAGS), 794 + GATE(HCLK_VOPL, "hclk_vopl", "hclk_vo_pre", 0, PX30_CLKGATE_CON(3), 6, GFLAGS), 795 + 796 + GATE(0, "pclk_vo_niu", "pclk_vo_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(3), 2, GFLAGS), 797 + GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vo_pre", 0, PX30_CLKGATE_CON(3), 9, GFLAGS), 798 + 799 + /* PD_BUS */ 800 + GATE(0, "aclk_bus_niu", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 8, GFLAGS), 801 + GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 11, GFLAGS), 802 + GATE(ACLK_GIC, "aclk_gic", "aclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 12, GFLAGS), 803 + GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_pre", 0, PX30_CLKGATE_CON(13), 15, GFLAGS), 804 + 805 + GATE(0, "hclk_bus_niu", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 9, GFLAGS), 806 + GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 14, GFLAGS), 807 + GATE(HCLK_PDM, "hclk_pdm", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 1, GFLAGS), 808 + GATE(HCLK_I2S0, "hclk_i2s0", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 2, GFLAGS), 809 + GATE(HCLK_I2S1, "hclk_i2s1", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 3, GFLAGS), 810 + GATE(HCLK_I2S2, "hclk_i2s2", "hclk_bus_pre", 0, PX30_CLKGATE_CON(14), 4, GFLAGS), 811 + 812 + GATE(0, "pclk_bus_niu", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(13), 10, GFLAGS), 813 + GATE(PCLK_DCF, "pclk_dcf", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 0, GFLAGS), 814 + GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 5, GFLAGS), 815 + GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 6, GFLAGS), 816 + GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 7, GFLAGS), 817 + GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 8, GFLAGS), 818 + GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 9, GFLAGS), 819 + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 10, GFLAGS), 820 + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 11, GFLAGS), 821 + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 12, GFLAGS), 822 + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 13, GFLAGS), 823 + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 14, GFLAGS), 824 + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(14), 15, GFLAGS), 825 + GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 0, GFLAGS), 826 + GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 1, GFLAGS), 827 + GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 2, GFLAGS), 828 + GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 3, GFLAGS), 829 + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 4, GFLAGS), 830 + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 5, GFLAGS), 831 + GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 6, GFLAGS), 832 + GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 7, GFLAGS), 833 + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 8, GFLAGS), 834 + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 9, GFLAGS), 835 + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0, PX30_CLKGATE_CON(15), 10, GFLAGS), 836 + GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 11, GFLAGS), 837 + GATE(0, "pclk_sgrf", "pclk_bus_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(15), 12, GFLAGS), 838 + 839 + /* PD_VPU */ 840 + GATE(0, "hclk_vpu_niu", "hclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 7, GFLAGS), 841 + GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 6, GFLAGS), 842 + GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(4), 5, GFLAGS), 843 + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, PX30_CLKGATE_CON(4), 4, GFLAGS), 844 + 845 + /* PD_CRYPTO */ 846 + GATE(0, "hclk_crypto_niu", "hclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 3, GFLAGS), 847 + GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 5, GFLAGS), 848 + GATE(0, "aclk_crypto_niu", "aclk_crypto_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(9), 2, GFLAGS), 849 + GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_crypto_pre", 0, PX30_CLKGATE_CON(9), 4, GFLAGS), 850 + 851 + /* PD_SDCARD */ 852 + GATE(0, "hclk_sdmmc_niu", "hclk_sdmmc_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 0, GFLAGS), 853 + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sdmmc_pre", 0, PX30_CLKGATE_CON(7), 1, GFLAGS), 854 + 855 + /* PD_PERI */ 856 + GATE(0, "aclk_peri_niu", "aclk_peri_pre", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(5), 9, GFLAGS), 857 + 858 + /* PD_MMC_NAND */ 859 + GATE(HCLK_NANDC, "hclk_nandc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(5), 15, GFLAGS), 860 + GATE(0, "hclk_mmc_nand_niu", "hclk_mmc_nand", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(6), 8, GFLAGS), 861 + GATE(HCLK_SDIO, "hclk_sdio", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 9, GFLAGS), 862 + GATE(HCLK_EMMC, "hclk_emmc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 10, GFLAGS), 863 + GATE(HCLK_SFC, "hclk_sfc", "hclk_mmc_nand", 0, PX30_CLKGATE_CON(6), 11, GFLAGS), 864 + 865 + /* PD_USB */ 866 + GATE(0, "hclk_usb_niu", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 4, GFLAGS), 867 + GATE(HCLK_OTG, "hclk_otg", "hclk_usb", 0, PX30_CLKGATE_CON(7), 5, GFLAGS), 868 + GATE(HCLK_HOST, "hclk_host", "hclk_usb", 0, PX30_CLKGATE_CON(7), 6, GFLAGS), 869 + GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_usb", CLK_IGNORE_UNUSED, PX30_CLKGATE_CON(7), 8, GFLAGS), 870 + 871 + /* PD_GMAC */ 872 + GATE(0, "aclk_gmac_niu", "aclk_gmac_pre", CLK_IGNORE_UNUSED, 873 + PX30_CLKGATE_CON(8), 0, GFLAGS), 874 + GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0, 875 + PX30_CLKGATE_CON(8), 2, GFLAGS), 876 + GATE(0, "pclk_gmac_niu", "pclk_gmac_pre", CLK_IGNORE_UNUSED, 877 + PX30_CLKGATE_CON(8), 1, GFLAGS), 878 + GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0, 879 + PX30_CLKGATE_CON(8), 3, GFLAGS), 880 + }; 881 + 882 + static struct rockchip_clk_branch px30_clk_pmu_branches[] __initdata = { 883 + /* 884 + * Clock-Architecture Diagram 2 885 + */ 886 + 887 + COMPOSITE_FRACMUX(0, "clk_rtc32k_frac", "xin24m", CLK_IGNORE_UNUSED, 888 + PX30_PMU_CLKSEL_CON(1), 0, 889 + PX30_PMU_CLKGATE_CON(0), 13, GFLAGS, 890 + &px30_rtc32k_pmu_fracmux), 891 + 892 + COMPOSITE_NOMUX(XIN24M_DIV, "xin24m_div", "xin24m", CLK_IGNORE_UNUSED, 893 + PX30_PMU_CLKSEL_CON(0), 8, 5, DFLAGS, 894 + PX30_PMU_CLKGATE_CON(0), 12, GFLAGS), 895 + 896 + COMPOSITE_NOMUX(0, "clk_wifi_pmu_src", "gpll", 0, 897 + PX30_PMU_CLKSEL_CON(2), 8, 6, DFLAGS, 898 + PX30_PMU_CLKGATE_CON(0), 14, GFLAGS), 899 + COMPOSITE_NODIV(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT, 900 + PX30_PMU_CLKSEL_CON(2), 15, 1, MFLAGS, 901 + PX30_PMU_CLKGATE_CON(0), 15, GFLAGS), 902 + 903 + COMPOSITE(0, "clk_uart0_pmu_src", mux_uart_src_p, 0, 904 + PX30_PMU_CLKSEL_CON(3), 14, 2, MFLAGS, 0, 5, DFLAGS, 905 + PX30_PMU_CLKGATE_CON(1), 0, GFLAGS), 906 + COMPOSITE_NOMUX_HALFDIV(0, "clk_uart0_np5", "clk_uart0_pmu_src", 0, 907 + PX30_PMU_CLKSEL_CON(4), 0, 5, DFLAGS, 908 + PX30_PMU_CLKGATE_CON(1), 1, GFLAGS), 909 + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_pmu_src", CLK_SET_RATE_PARENT, 910 + PX30_PMU_CLKSEL_CON(5), 0, 911 + PX30_PMU_CLKGATE_CON(1), 2, GFLAGS, 912 + &px30_uart0_pmu_fracmux), 913 + GATE(SCLK_UART0_PMU, "clk_uart0_pmu", "clk_uart0_pmu_mux", CLK_SET_RATE_PARENT, 914 + PX30_PMU_CLKGATE_CON(1), 3, GFLAGS), 915 + 916 + GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0, 917 + PX30_PMU_CLKGATE_CON(1), 4, GFLAGS), 918 + 919 + COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "gpll", 0, 920 + PX30_PMU_CLKSEL_CON(0), 0, 5, DFLAGS, 921 + PX30_PMU_CLKGATE_CON(0), 0, GFLAGS), 922 + 923 + COMPOSITE_NOMUX(SCLK_REF24M_PMU, "clk_ref24m_pmu", "gpll", 0, 924 + PX30_PMU_CLKSEL_CON(2), 0, 6, DFLAGS, 925 + PX30_PMU_CLKGATE_CON(1), 8, GFLAGS), 926 + COMPOSITE_NODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, CLK_SET_RATE_PARENT, 927 + PX30_PMU_CLKSEL_CON(2), 6, 1, MFLAGS, 928 + PX30_PMU_CLKGATE_CON(1), 9, GFLAGS), 929 + COMPOSITE_NODIV(SCLK_MIPIDSIPHY_REF, "clk_mipidsiphy_ref", mux_mipidsiphy_ref_p, CLK_SET_RATE_PARENT, 930 + PX30_PMU_CLKSEL_CON(2), 7, 1, MFLAGS, 931 + PX30_PMU_CLKGATE_CON(1), 10, GFLAGS), 932 + 933 + /* 934 + * Clock-Architecture Diagram 9 935 + */ 936 + 937 + /* PD_PMU */ 938 + GATE(0, "pclk_pmu_niu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 1, GFLAGS), 939 + GATE(0, "pclk_pmu_sgrf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 2, GFLAGS), 940 + GATE(0, "pclk_pmu_grf", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 3, GFLAGS), 941 + GATE(0, "pclk_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 4, GFLAGS), 942 + GATE(0, "pclk_pmu_mem", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 5, GFLAGS), 943 + GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 6, GFLAGS), 944 + GATE(PCLK_UART0_PMU, "pclk_uart0_pmu", "pclk_pmu_pre", 0, PX30_PMU_CLKGATE_CON(0), 7, GFLAGS), 945 + GATE(0, "pclk_cru_pmu", "pclk_pmu_pre", CLK_IGNORE_UNUSED, PX30_PMU_CLKGATE_CON(0), 8, GFLAGS), 946 + }; 947 + 948 + static const char *const px30_pmucru_critical_clocks[] __initconst = { 949 + "aclk_bus_pre", 950 + "pclk_bus_pre", 951 + "hclk_bus_pre", 952 + "aclk_peri_pre", 953 + "hclk_peri_pre", 954 + "aclk_gpu_niu", 955 + "pclk_top_pre", 956 + "pclk_pmu_pre", 957 + "hclk_usb_niu", 958 + "pll_npll", 959 + "usb480m", 960 + "clk_uart2", 961 + "pclk_uart2", 962 + }; 963 + 964 + static void __init px30_clk_init(struct device_node *np) 965 + { 966 + struct rockchip_clk_provider *ctx; 967 + void __iomem *reg_base; 968 + struct clk *clk; 969 + 970 + reg_base = of_iomap(np, 0); 971 + if (!reg_base) { 972 + pr_err("%s: could not map cru region\n", __func__); 973 + return; 974 + } 975 + 976 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 977 + if (IS_ERR(ctx)) { 978 + pr_err("%s: rockchip clk init failed\n", __func__); 979 + iounmap(reg_base); 980 + return; 981 + } 982 + 983 + /* aclk_dmac is controlled by sgrf_soc_con1[11]. */ 984 + clk = clk_register_fixed_factor(NULL, "aclk_dmac", "aclk_bus_pre", 0, 1, 1); 985 + if (IS_ERR(clk)) 986 + pr_warn("%s: could not register clock aclk_dmac: %ld\n", 987 + __func__, PTR_ERR(clk)); 988 + else 989 + rockchip_clk_add_lookup(ctx, clk, ACLK_DMAC); 990 + 991 + rockchip_clk_register_plls(ctx, px30_pll_clks, 992 + ARRAY_SIZE(px30_pll_clks), 993 + PX30_GRF_SOC_STATUS0); 994 + rockchip_clk_register_branches(ctx, px30_clk_branches, 995 + ARRAY_SIZE(px30_clk_branches)); 996 + 997 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 998 + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 999 + &px30_cpuclk_data, px30_cpuclk_rates, 1000 + ARRAY_SIZE(px30_cpuclk_rates)); 1001 + 1002 + rockchip_register_softrst(np, 12, reg_base + PX30_SOFTRST_CON(0), 1003 + ROCKCHIP_SOFTRST_HIWORD_MASK); 1004 + 1005 + rockchip_register_restart_notifier(ctx, PX30_GLB_SRST_FST, NULL); 1006 + 1007 + rockchip_clk_of_add_provider(np, ctx); 1008 + } 1009 + CLK_OF_DECLARE(px30_cru, "rockchip,px30-cru", px30_clk_init); 1010 + 1011 + static void __init px30_pmu_clk_init(struct device_node *np) 1012 + { 1013 + struct rockchip_clk_provider *ctx; 1014 + void __iomem *reg_base; 1015 + 1016 + reg_base = of_iomap(np, 0); 1017 + if (!reg_base) { 1018 + pr_err("%s: could not map cru pmu region\n", __func__); 1019 + return; 1020 + } 1021 + 1022 + ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS); 1023 + if (IS_ERR(ctx)) { 1024 + pr_err("%s: rockchip pmu clk init failed\n", __func__); 1025 + return; 1026 + } 1027 + 1028 + rockchip_clk_register_plls(ctx, px30_pmu_pll_clks, 1029 + ARRAY_SIZE(px30_pmu_pll_clks), PX30_GRF_SOC_STATUS0); 1030 + 1031 + rockchip_clk_register_branches(ctx, px30_clk_pmu_branches, 1032 + ARRAY_SIZE(px30_clk_pmu_branches)); 1033 + 1034 + rockchip_clk_protect_critical(px30_pmucru_critical_clocks, 1035 + ARRAY_SIZE(px30_pmucru_critical_clocks)); 1036 + 1037 + rockchip_clk_of_add_provider(np, ctx); 1038 + } 1039 + CLK_OF_DECLARE(px30_cru_pmu, "rockchip,px30-pmucru", px30_pmu_clk_init);
+2 -1
drivers/clk/rockchip/clk-rk3399.c
··· 631 631 MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, 632 632 RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), 633 633 COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, 634 - RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, 634 + RK3399_CLKSEL_CON(31), 2, 1, MFLAGS, 635 635 RK3399_CLKGATE_CON(8), 12, GFLAGS), 636 636 637 637 /* uart */ ··· 1523 1523 "pclk_pmu_src", 1524 1524 "fclk_cm0s_src_pmu", 1525 1525 "clk_timer_src_pmu", 1526 + "pclk_rkpwm_pmu", 1526 1527 }; 1527 1528 1528 1529 static void __init rk3399_clk_init(struct device_node *np)
+10
drivers/clk/rockchip/clk.c
··· 492 492 list->gate_flags, flags, list->child, 493 493 &ctx->lock); 494 494 break; 495 + case branch_half_divider: 496 + clk = rockchip_clk_register_halfdiv(list->name, 497 + list->parent_names, list->num_parents, 498 + ctx->reg_base, list->muxdiv_offset, 499 + list->mux_shift, list->mux_width, 500 + list->mux_flags, list->div_shift, 501 + list->div_width, list->div_flags, 502 + list->gate_offset, list->gate_shift, 503 + list->gate_flags, flags, &ctx->lock); 504 + break; 495 505 case branch_gate: 496 506 flags |= CLK_SET_RATE_PARENT; 497 507
+125 -1
drivers/clk/rockchip/clk.h
··· 34 34 #define HIWORD_UPDATE(val, mask, shift) \ 35 35 ((val) << (shift) | (mask) << ((shift) + 16)) 36 36 37 - /* register positions shared by RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */ 37 + /* register positions shared by PX30, RV1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */ 38 + #define BOOST_PLL_H_CON(x) ((x) * 0x4) 39 + #define BOOST_CLK_CON 0x0008 40 + #define BOOST_BOOST_CON 0x000c 41 + #define BOOST_SWITCH_CNT 0x0010 42 + #define BOOST_HIGH_PERF_CNT0 0x0014 43 + #define BOOST_HIGH_PERF_CNT1 0x0018 44 + #define BOOST_STATIS_THRESHOLD 0x001c 45 + #define BOOST_SHORT_SWITCH_CNT 0x0020 46 + #define BOOST_SWITCH_THRESHOLD 0x0024 47 + #define BOOST_FSM_STATUS 0x0028 48 + #define BOOST_PLL_L_CON(x) ((x) * 0x4 + 0x2c) 49 + #define BOOST_RECOVERY_MASK 0x1 50 + #define BOOST_RECOVERY_SHIFT 1 51 + #define BOOST_SW_CTRL_MASK 0x1 52 + #define BOOST_SW_CTRL_SHIFT 2 53 + #define BOOST_LOW_FREQ_EN_MASK 0x1 54 + #define BOOST_LOW_FREQ_EN_SHIFT 3 55 + #define BOOST_BUSY_STATE BIT(8) 56 + 57 + #define PX30_PLL_CON(x) ((x) * 0x4) 58 + #define PX30_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 59 + #define PX30_CLKGATE_CON(x) ((x) * 0x4 + 0x200) 60 + #define PX30_GLB_SRST_FST 0xb8 61 + #define PX30_GLB_SRST_SND 0xbc 62 + #define PX30_SOFTRST_CON(x) ((x) * 0x4 + 0x300) 63 + #define PX30_MODE_CON 0xa0 64 + #define PX30_MISC_CON 0xa4 65 + #define PX30_SDMMC_CON0 0x380 66 + #define PX30_SDMMC_CON1 0x384 67 + #define PX30_SDIO_CON0 0x388 68 + #define PX30_SDIO_CON1 0x38c 69 + #define PX30_EMMC_CON0 0x390 70 + #define PX30_EMMC_CON1 0x394 71 + 72 + #define PX30_PMU_PLL_CON(x) ((x) * 0x4) 73 + #define PX30_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x40) 74 + #define PX30_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x80) 75 + #define PX30_PMU_MODE 0x0020 76 + 38 77 #define RV1108_PLL_CON(x) ((x) * 0x4) 39 78 #define RV1108_CLKSEL_CON(x) ((x) * 0x4 + 0x60) 40 79 #define RV1108_CLKGATE_CON(x) ((x) * 0x4 + 0x120) ··· 393 354 branch_inverter, 394 355 branch_factor, 395 356 branch_ddrclk, 357 + branch_half_divider, 396 358 }; 397 359 398 360 struct rockchip_clk_branch { ··· 724 684 .gate_flags = gf, \ 725 685 } 726 686 687 + #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 688 + df, go, gs, gf) \ 689 + { \ 690 + .id = _id, \ 691 + .branch_type = branch_half_divider, \ 692 + .name = cname, \ 693 + .parent_names = pnames, \ 694 + .num_parents = ARRAY_SIZE(pnames), \ 695 + .flags = f, \ 696 + .muxdiv_offset = mo, \ 697 + .mux_shift = ms, \ 698 + .mux_width = mw, \ 699 + .mux_flags = mf, \ 700 + .div_shift = ds, \ 701 + .div_width = dw, \ 702 + .div_flags = df, \ 703 + .gate_offset = go, \ 704 + .gate_shift = gs, \ 705 + .gate_flags = gf, \ 706 + } 707 + 708 + #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 709 + ds, dw, df) \ 710 + { \ 711 + .id = _id, \ 712 + .branch_type = branch_half_divider, \ 713 + .name = cname, \ 714 + .parent_names = pnames, \ 715 + .num_parents = ARRAY_SIZE(pnames), \ 716 + .flags = f, \ 717 + .muxdiv_offset = mo, \ 718 + .mux_shift = ms, \ 719 + .mux_width = mw, \ 720 + .mux_flags = mf, \ 721 + .div_shift = ds, \ 722 + .div_width = dw, \ 723 + .div_flags = df, \ 724 + .gate_offset = -1, \ 725 + } 726 + 727 + #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, \ 728 + go, gs, gf) \ 729 + { \ 730 + .id = _id, \ 731 + .branch_type = branch_half_divider, \ 732 + .name = cname, \ 733 + .parent_names = (const char *[]){ pname }, \ 734 + .num_parents = 1, \ 735 + .flags = f, \ 736 + .muxdiv_offset = mo, \ 737 + .div_shift = ds, \ 738 + .div_width = dw, \ 739 + .div_flags = df, \ 740 + .gate_offset = go, \ 741 + .gate_shift = gs, \ 742 + .gate_flags = gf, \ 743 + } 744 + 745 + #define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ 746 + { \ 747 + .id = _id, \ 748 + .branch_type = branch_half_divider, \ 749 + .name = cname, \ 750 + .parent_names = (const char *[]){ pname }, \ 751 + .num_parents = 1, \ 752 + .flags = f, \ 753 + .muxdiv_offset = o, \ 754 + .div_shift = s, \ 755 + .div_width = w, \ 756 + .div_flags = df, \ 757 + .gate_offset = -1, \ 758 + } 759 + 727 760 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 728 761 void __iomem *base, unsigned long nr_clks); 729 762 void rockchip_clk_of_add_provider(struct device_node *np, ··· 820 707 unsigned int reg, void (*cb)(void)); 821 708 822 709 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 710 + 711 + struct clk *rockchip_clk_register_halfdiv(const char *name, 712 + const char *const *parent_names, 713 + u8 num_parents, void __iomem *base, 714 + int muxdiv_offset, u8 mux_shift, 715 + u8 mux_width, u8 mux_flags, 716 + u8 div_shift, u8 div_width, 717 + u8 div_flags, int gate_offset, 718 + u8 gate_shift, u8 gate_flags, 719 + unsigned long flags, 720 + spinlock_t *lock); 823 721 824 722 #ifdef CONFIG_RESET_CONTROLLER 825 723 void rockchip_register_softrst(struct device_node *np,
-2
drivers/clk/samsung/clk-exynos4412-isp.c
··· 37 37 E4X12_GATE_ISP1, 38 38 }; 39 39 40 - PNAME(mout_user_aclk400_mcuisp_p4x12) = { "fin_pll", "div_aclk400_mcuisp", }; 41 - 42 40 static struct samsung_div_clock exynos4x12_isp_div_clks[] = { 43 41 DIV(CLK_ISP_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), 44 42 DIV(CLK_ISP_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
+7 -2
drivers/clk/socfpga/clk-s10.c
··· 28 28 static const char * const emacb_free_mux[] = {"peri_emacb_clk", "boot_clk"}; 29 29 static const char * const emac_ptp_free_mux[] = {"peri_emac_ptp_clk", "boot_clk"}; 30 30 static const char * const gpio_db_free_mux[] = {"peri_gpio_db_clk", "boot_clk"}; 31 - static const char * const sdmmc_free_mux[] = {"peri_sdmmc_clk", "boot_clk"}; 31 + static const char * const sdmmc_free_mux[] = {"main_sdmmc_clk", "boot_clk"}; 32 32 static const char * const s2f_usr1_free_mux[] = {"peri_s2f_usr1_clk", "boot_clk"}; 33 33 static const char * const psi_ref_free_mux[] = {"peri_psi_ref_clk", "boot_clk"}; 34 34 static const char * const mpu_mux[] = { "mpu_free_clk", "boot_clk",}; ··· 36 36 static const char * const s2f_usr0_mux[] = {"f2s_free_clk", "boot_clk"}; 37 37 static const char * const emac_mux[] = {"emaca_free_clk", "emacb_free_clk"}; 38 38 static const char * const noc_mux[] = {"noc_free_clk", "boot_clk"}; 39 + 40 + static const char * const mpu_free_mux[] = {"main_mpu_base_clk", 41 + "peri_mpu_base_clk", 42 + "osc1", "cb_intosc_hs_div2_clk", 43 + "f2s_free_clk"}; 39 44 40 45 /* clocks in AO (always on) controller */ 41 46 static const struct stratix10_pll_clock s10_pll_clks[] = { ··· 62 57 }; 63 58 64 59 static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { 65 - { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, cntr_mux, ARRAY_SIZE(cntr_mux), 60 + { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), 66 61 0, 0x48, 0, 0, 0}, 67 62 { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), 68 63 0, 0x4C, 0, 0, 0},
+4 -7
drivers/clk/sunxi-ng/ccu-sun8i-de2.c
··· 289 289 .data = &sun8i_v3s_de2_clk_desc, 290 290 }, 291 291 { 292 + .compatible = "allwinner,sun50i-a64-de2-clk", 293 + .data = &sun50i_a64_de2_clk_desc, 294 + }, 295 + { 292 296 .compatible = "allwinner,sun50i-h5-de2-clk", 293 297 .data = &sun50i_a64_de2_clk_desc, 294 298 }, 295 - /* 296 - * The Allwinner A64 SoC needs some bit to be poke in syscon to make 297 - * DE2 really working. 298 - * So there's currently no A64 compatible here. 299 - * H5 shares the same reset line with A64, so here H5 is using the 300 - * clock description of A64. 301 - */ 302 299 { } 303 300 }; 304 301
+32 -26
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
··· 66 66 CLK_SET_RATE_UNGATE); 67 67 68 68 /* TODO: The result of N/M is required to be in [8, 25] range. */ 69 - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", 70 - "osc24M", 0x0010, 71 - 8, 7, /* N */ 72 - 0, 4, /* M */ 73 - BIT(24), /* frac enable */ 74 - BIT(25), /* frac select */ 75 - 270000000, /* frac rate 0 */ 76 - 297000000, /* frac rate 1 */ 77 - BIT(31), /* gate */ 78 - BIT(28), /* lock */ 79 - CLK_SET_RATE_UNGATE); 69 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video0_clk, "pll-video0", 70 + "osc24M", 0x0010, 71 + 192000000, /* Minimum rate */ 72 + 8, 7, /* N */ 73 + 0, 4, /* M */ 74 + BIT(24), /* frac enable */ 75 + BIT(25), /* frac select */ 76 + 270000000, /* frac rate 0 */ 77 + 297000000, /* frac rate 1 */ 78 + BIT(31), /* gate */ 79 + BIT(28), /* lock */ 80 + CLK_SET_RATE_UNGATE); 80 81 81 82 /* TODO: The result of N/M is required to be in [8, 25] range. */ 82 83 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", ··· 153 152 }; 154 153 155 154 /* TODO: The result of N/M is required to be in [8, 25] range. */ 156 - static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", 157 - "osc24M", 0x030, 158 - 8, 7, /* N */ 159 - 0, 4, /* M */ 160 - BIT(24), /* frac enable */ 161 - BIT(25), /* frac select */ 162 - 270000000, /* frac rate 0 */ 163 - 297000000, /* frac rate 1 */ 164 - BIT(31), /* gate */ 165 - BIT(28), /* lock */ 166 - CLK_SET_RATE_UNGATE); 155 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN(pll_video1_clk, "pll-video1", 156 + "osc24M", 0x030, 157 + 192000000, /* Minimum rate */ 158 + 8, 7, /* N */ 159 + 0, 4, /* M */ 160 + BIT(24), /* frac enable */ 161 + BIT(25), /* frac select */ 162 + 270000000, /* frac rate 0 */ 163 + 297000000, /* frac rate 1 */ 164 + BIT(31), /* gate */ 165 + BIT(28), /* lock */ 166 + CLK_SET_RATE_UNGATE); 167 167 168 168 static struct ccu_nkm pll_sata_clk = { 169 169 .enable = BIT(31), ··· 656 654 657 655 static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; 658 656 static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 659 - 0x104, 0, 4, 24, 3, BIT(31), 0); 657 + 0x104, 0, 4, 24, 3, BIT(31), 658 + CLK_SET_RATE_PARENT); 660 659 static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents, 661 660 0x108, 0, 4, 24, 3, BIT(31), 0); 662 661 ··· 669 666 static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, 670 667 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT); 671 668 static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents, 672 - 0x118, 0, 4, 24, 3, BIT(31), 0); 669 + 0x118, 0, 4, 24, 3, BIT(31), 670 + CLK_SET_RATE_PARENT); 673 671 static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents, 674 - 0x11c, 0, 4, 24, 3, BIT(31), 0); 672 + 0x11c, 0, 4, 24, 3, BIT(31), 673 + CLK_SET_RATE_PARENT); 675 674 676 675 static const char * const deinterlace_parents[] = { "pll-periph0", 677 676 "pll-periph1" }; ··· 703 698 704 699 static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; 705 700 static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, 706 - 0x150, 0, 4, 24, 2, BIT(31), 0); 701 + 0x150, 0, 4, 24, 2, BIT(31), 702 + CLK_SET_RATE_PARENT); 707 703 708 704 static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 709 705 0x154, BIT(31), 0);
+6 -2
drivers/clk/sunxi-ng/ccu-sun8i-r40.h
··· 25 25 #define CLK_PLL_AUDIO_2X 4 26 26 #define CLK_PLL_AUDIO_4X 5 27 27 #define CLK_PLL_AUDIO_8X 6 28 - #define CLK_PLL_VIDEO0 7 28 + 29 + /* PLL_VIDEO0 is exported */ 30 + 29 31 #define CLK_PLL_VIDEO0_2X 8 30 32 #define CLK_PLL_VE 9 31 33 #define CLK_PLL_DDR0 10 ··· 36 34 #define CLK_PLL_PERIPH0_2X 13 37 35 #define CLK_PLL_PERIPH1 14 38 36 #define CLK_PLL_PERIPH1_2X 15 39 - #define CLK_PLL_VIDEO1 16 37 + 38 + /* PLL_VIDEO1 is exported */ 39 + 40 40 #define CLK_PLL_VIDEO1_2X 17 41 41 #define CLK_PLL_SATA 18 42 42 #define CLK_PLL_SATA_OUT 19
+2
drivers/clk/tegra/Makefile
··· 8 8 obj-y += clk-periph-gate.o 9 9 obj-y += clk-pll.o 10 10 obj-y += clk-pll-out.o 11 + obj-y += clk-sdmmc-mux.o 11 12 obj-y += clk-super.o 12 13 obj-y += clk-tegra-audio.o 13 14 obj-y += clk-tegra-periph.o ··· 25 24 obj-y += cvb.o 26 25 obj-$(CONFIG_ARCH_TEGRA_210_SOC) += clk-tegra210.o 27 26 obj-$(CONFIG_CLK_TEGRA_BPMP) += clk-bpmp.o 27 + obj-y += clk-utils.o
+9 -3
drivers/clk/tegra/clk-bpmp.c
··· 586 586 unsigned int id = clkspec->args[0], i; 587 587 struct tegra_bpmp *bpmp = data; 588 588 589 - for (i = 0; i < bpmp->num_clocks; i++) 590 - if (bpmp->clocks[i]->id == id) 591 - return &bpmp->clocks[i]->hw; 589 + for (i = 0; i < bpmp->num_clocks; i++) { 590 + struct tegra_bpmp_clk *clk = bpmp->clocks[i]; 591 + 592 + if (!clk) 593 + continue; 594 + 595 + if (clk->id == id) 596 + return &clk->hw; 597 + } 592 598 593 599 return NULL; 594 600 }
+9 -28
drivers/clk/tegra/clk-divider.c
··· 32 32 static int get_div(struct tegra_clk_frac_div *divider, unsigned long rate, 33 33 unsigned long parent_rate) 34 34 { 35 - u64 divider_ux1 = parent_rate; 36 - u8 flags = divider->flags; 37 - int mul; 35 + int div; 38 36 39 - if (!rate) 37 + div = div_frac_get(rate, parent_rate, divider->width, 38 + divider->frac_width, divider->flags); 39 + 40 + if (div < 0) 40 41 return 0; 41 42 42 - mul = get_mul(divider); 43 - 44 - if (!(flags & TEGRA_DIVIDER_INT)) 45 - divider_ux1 *= mul; 46 - 47 - if (flags & TEGRA_DIVIDER_ROUND_UP) 48 - divider_ux1 += rate - 1; 49 - 50 - do_div(divider_ux1, rate); 51 - 52 - if (flags & TEGRA_DIVIDER_INT) 53 - divider_ux1 *= mul; 54 - 55 - divider_ux1 -= mul; 56 - 57 - if ((s64)divider_ux1 < 0) 58 - return 0; 59 - 60 - if (divider_ux1 > get_max_div(divider)) 61 - return get_max_div(divider); 62 - 63 - return divider_ux1; 43 + return div; 64 44 } 65 45 66 46 static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw, ··· 174 194 struct clk *tegra_clk_register_mc(const char *name, const char *parent_name, 175 195 void __iomem *reg, spinlock_t *lock) 176 196 { 177 - return clk_register_divider_table(NULL, name, parent_name, 0, reg, 178 - 16, 1, 0, mc_div_table, lock); 197 + return clk_register_divider_table(NULL, name, parent_name, 198 + CLK_IS_CRITICAL, reg, 16, 1, 0, 199 + mc_div_table, lock); 179 200 }
+1 -1
drivers/clk/tegra/clk-emc.c
··· 132 132 timing = tegra->timings + i; 133 133 134 134 if (timing->rate > req->max_rate) { 135 - i = min(i, 1); 135 + i = max(i, 1); 136 136 req->rate = tegra->timings[i - 1].rate; 137 137 return 0; 138 138 }
-2
drivers/clk/tegra/clk-id.h
··· 227 227 tegra_clk_sdmmc1_9, 228 228 tegra_clk_sdmmc2, 229 229 tegra_clk_sdmmc2_8, 230 - tegra_clk_sdmmc2_9, 231 230 tegra_clk_sdmmc3, 232 231 tegra_clk_sdmmc3_8, 233 232 tegra_clk_sdmmc3_9, 234 233 tegra_clk_sdmmc4, 235 234 tegra_clk_sdmmc4_8, 236 - tegra_clk_sdmmc4_9, 237 235 tegra_clk_se, 238 236 tegra_clk_soc_therm, 239 237 tegra_clk_soc_therm_8,
+251
drivers/clk/tegra/clk-sdmmc-mux.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018 NVIDIA CORPORATION. All rights reserved. 4 + * 5 + * based on clk-mux.c 6 + * 7 + * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 8 + * Copyright (C) 2011 Richard Zhao, Linaro <richard.zhao@linaro.org> 9 + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> 10 + * 11 + */ 12 + 13 + #include <linux/clk-provider.h> 14 + #include <linux/err.h> 15 + #include <linux/types.h> 16 + 17 + #include "clk.h" 18 + 19 + #define DIV_MASK GENMASK(7, 0) 20 + #define MUX_SHIFT 29 21 + #define MUX_MASK GENMASK(MUX_SHIFT + 2, MUX_SHIFT) 22 + #define SDMMC_MUL 2 23 + 24 + #define get_max_div(d) DIV_MASK 25 + #define get_div_field(val) ((val) & DIV_MASK) 26 + #define get_mux_field(val) (((val) & MUX_MASK) >> MUX_SHIFT) 27 + 28 + static const char * const mux_sdmmc_parents[] = { 29 + "pll_p", "pll_c4_out2", "pll_c4_out0", "pll_c4_out1", "clk_m" 30 + }; 31 + 32 + static const u8 mux_lj_idx[] = { 33 + [0] = 0, [1] = 1, [2] = 2, [3] = 5, [4] = 6 34 + }; 35 + 36 + static const u8 mux_non_lj_idx[] = { 37 + [0] = 0, [1] = 3, [2] = 7, [3] = 4, [4] = 6 38 + }; 39 + 40 + static u8 clk_sdmmc_mux_get_parent(struct clk_hw *hw) 41 + { 42 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 43 + int num_parents, i; 44 + u32 src, val; 45 + const u8 *mux_idx; 46 + 47 + num_parents = clk_hw_get_num_parents(hw); 48 + 49 + val = readl_relaxed(sdmmc_mux->reg); 50 + src = get_mux_field(val); 51 + if (get_div_field(val)) 52 + mux_idx = mux_non_lj_idx; 53 + else 54 + mux_idx = mux_lj_idx; 55 + 56 + for (i = 0; i < num_parents; i++) { 57 + if (mux_idx[i] == src) 58 + return i; 59 + } 60 + 61 + WARN(1, "Unknown parent selector %d\n", src); 62 + 63 + return 0; 64 + } 65 + 66 + static int clk_sdmmc_mux_set_parent(struct clk_hw *hw, u8 index) 67 + { 68 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 69 + u32 val; 70 + 71 + 72 + val = readl_relaxed(sdmmc_mux->reg); 73 + if (get_div_field(val)) 74 + index = mux_non_lj_idx[index]; 75 + else 76 + index = mux_lj_idx[index]; 77 + 78 + val &= ~MUX_MASK; 79 + val |= index << MUX_SHIFT; 80 + 81 + writel(val, sdmmc_mux->reg); 82 + 83 + return 0; 84 + } 85 + 86 + static unsigned long clk_sdmmc_mux_recalc_rate(struct clk_hw *hw, 87 + unsigned long parent_rate) 88 + { 89 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 90 + u32 val; 91 + int div; 92 + u64 rate = parent_rate; 93 + 94 + val = readl_relaxed(sdmmc_mux->reg); 95 + div = get_div_field(val); 96 + 97 + div += SDMMC_MUL; 98 + 99 + rate *= SDMMC_MUL; 100 + rate += div - 1; 101 + do_div(rate, div); 102 + 103 + return rate; 104 + } 105 + 106 + static int clk_sdmmc_mux_determine_rate(struct clk_hw *hw, 107 + struct clk_rate_request *req) 108 + { 109 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 110 + int div; 111 + unsigned long output_rate = req->best_parent_rate; 112 + 113 + req->rate = max(req->rate, req->min_rate); 114 + req->rate = min(req->rate, req->max_rate); 115 + 116 + if (!req->rate) 117 + return output_rate; 118 + 119 + div = div_frac_get(req->rate, output_rate, 8, 1, sdmmc_mux->div_flags); 120 + if (div < 0) 121 + div = 0; 122 + 123 + if (sdmmc_mux->div_flags & TEGRA_DIVIDER_ROUND_UP) 124 + req->rate = DIV_ROUND_UP(output_rate * SDMMC_MUL, 125 + div + SDMMC_MUL); 126 + else 127 + req->rate = output_rate * SDMMC_MUL / (div + SDMMC_MUL); 128 + 129 + return 0; 130 + } 131 + 132 + static int clk_sdmmc_mux_set_rate(struct clk_hw *hw, unsigned long rate, 133 + unsigned long parent_rate) 134 + { 135 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 136 + int div; 137 + unsigned long flags = 0; 138 + u32 val; 139 + u8 src; 140 + 141 + div = div_frac_get(rate, parent_rate, 8, 1, sdmmc_mux->div_flags); 142 + if (div < 0) 143 + return div; 144 + 145 + if (sdmmc_mux->lock) 146 + spin_lock_irqsave(sdmmc_mux->lock, flags); 147 + 148 + src = clk_sdmmc_mux_get_parent(hw); 149 + if (div) 150 + src = mux_non_lj_idx[src]; 151 + else 152 + src = mux_lj_idx[src]; 153 + 154 + val = src << MUX_SHIFT; 155 + val |= div; 156 + writel(val, sdmmc_mux->reg); 157 + fence_udelay(2, sdmmc_mux->reg); 158 + 159 + if (sdmmc_mux->lock) 160 + spin_unlock_irqrestore(sdmmc_mux->lock, flags); 161 + 162 + return 0; 163 + } 164 + 165 + static int clk_sdmmc_mux_is_enabled(struct clk_hw *hw) 166 + { 167 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 168 + const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; 169 + struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; 170 + 171 + __clk_hw_set_clk(gate_hw, hw); 172 + 173 + return gate_ops->is_enabled(gate_hw); 174 + } 175 + 176 + static int clk_sdmmc_mux_enable(struct clk_hw *hw) 177 + { 178 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 179 + const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; 180 + struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; 181 + 182 + __clk_hw_set_clk(gate_hw, hw); 183 + 184 + return gate_ops->enable(gate_hw); 185 + } 186 + 187 + static void clk_sdmmc_mux_disable(struct clk_hw *hw) 188 + { 189 + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); 190 + const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; 191 + struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; 192 + 193 + gate_ops->disable(gate_hw); 194 + } 195 + 196 + static const struct clk_ops tegra_clk_sdmmc_mux_ops = { 197 + .get_parent = clk_sdmmc_mux_get_parent, 198 + .set_parent = clk_sdmmc_mux_set_parent, 199 + .determine_rate = clk_sdmmc_mux_determine_rate, 200 + .recalc_rate = clk_sdmmc_mux_recalc_rate, 201 + .set_rate = clk_sdmmc_mux_set_rate, 202 + .is_enabled = clk_sdmmc_mux_is_enabled, 203 + .enable = clk_sdmmc_mux_enable, 204 + .disable = clk_sdmmc_mux_disable, 205 + }; 206 + 207 + struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, 208 + void __iomem *clk_base, u32 offset, u32 clk_num, u8 div_flags, 209 + unsigned long flags, void *lock) 210 + { 211 + struct clk *clk; 212 + struct clk_init_data init; 213 + const struct tegra_clk_periph_regs *bank; 214 + struct tegra_sdmmc_mux *sdmmc_mux; 215 + 216 + init.ops = &tegra_clk_sdmmc_mux_ops; 217 + init.name = name; 218 + init.flags = flags; 219 + init.parent_names = mux_sdmmc_parents; 220 + init.num_parents = ARRAY_SIZE(mux_sdmmc_parents); 221 + 222 + bank = get_reg_bank(clk_num); 223 + if (!bank) 224 + return ERR_PTR(-EINVAL); 225 + 226 + sdmmc_mux = kzalloc(sizeof(*sdmmc_mux), GFP_KERNEL); 227 + if (!sdmmc_mux) 228 + return ERR_PTR(-ENOMEM); 229 + 230 + /* Data in .init is copied by clk_register(), so stack variable OK */ 231 + sdmmc_mux->hw.init = &init; 232 + sdmmc_mux->reg = clk_base + offset; 233 + sdmmc_mux->lock = lock; 234 + sdmmc_mux->gate.clk_base = clk_base; 235 + sdmmc_mux->gate.regs = bank; 236 + sdmmc_mux->gate.enable_refcnt = periph_clk_enb_refcnt; 237 + sdmmc_mux->gate.clk_num = clk_num; 238 + sdmmc_mux->gate.flags = TEGRA_PERIPH_ON_APB; 239 + sdmmc_mux->div_flags = div_flags; 240 + sdmmc_mux->gate_ops = &tegra_clk_periph_gate_ops; 241 + 242 + clk = clk_register(NULL, &sdmmc_mux->hw); 243 + if (IS_ERR(clk)) { 244 + kfree(sdmmc_mux); 245 + return clk; 246 + } 247 + 248 + sdmmc_mux->gate.hw.clk = clk; 249 + 250 + return clk; 251 + }
-11
drivers/clk/tegra/clk-tegra-periph.c
··· 451 451 [0] = 0, [1] = 3, [2] = 4, [3] = 6, [4] = 7, 452 452 }; 453 453 454 - static const char *mux_pllp_clkm_pllc4_out2_out1_out0_lj[] = { 455 - "pll_p", 456 - "pll_c4_out2", "pll_c4_out0", /* LJ input */ 457 - "pll_c4_out2", "pll_c4_out1", 458 - "pll_c4_out1", /* LJ input */ 459 - "clk_m", "pll_c4_out0" 460 - }; 461 - #define mux_pllp_clkm_pllc4_out2_out1_out0_lj_idx NULL 462 - 463 454 static const char *mux_pllp_pllc2_c_c3_clkm[] = { 464 455 "pll_p", "pll_c2", "pll_c", "pll_c3", "clk_m" 465 456 }; ··· 677 686 MUX("sdmmc3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3), 678 687 MUX("sdmmc4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4), 679 688 MUX8("sdmmc1", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC1, 14, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc1_9), 680 - MUX8("sdmmc2", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC2, 9, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc2_9), 681 689 MUX8("sdmmc3", mux_pllp_pllc4_out2_pllc4_out1_clkm_pllc4_out0, CLK_SOURCE_SDMMC3, 69, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc3_9), 682 - MUX8("sdmmc4", mux_pllp_clkm_pllc4_out2_out1_out0_lj, CLK_SOURCE_SDMMC4, 15, TEGRA_PERIPH_ON_APB, tegra_clk_sdmmc4_9), 683 690 MUX("la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, TEGRA_PERIPH_ON_APB, tegra_clk_la), 684 691 MUX("trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, TEGRA_PERIPH_ON_APB, tegra_clk_trace), 685 692 MUX("owr", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, TEGRA_PERIPH_ON_APB, tegra_clk_owr),
+2 -1
drivers/clk/tegra/clk-tegra124.c
··· 1267 1267 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1268 1268 { TEGRA124_CLK_I2S3, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1269 1269 { TEGRA124_CLK_I2S4, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, 1270 - { TEGRA124_CLK_VDE, TEGRA124_CLK_CLK_MAX, 600000000, 0 }, 1270 + { TEGRA124_CLK_VDE, TEGRA124_CLK_PLL_C3, 600000000, 0 }, 1271 1271 { TEGRA124_CLK_HOST1X, TEGRA124_CLK_PLL_P, 136000000, 1 }, 1272 1272 { TEGRA124_CLK_DSIALP, TEGRA124_CLK_PLL_P, 68000000, 0 }, 1273 1273 { TEGRA124_CLK_DSIBLP, TEGRA124_CLK_PLL_P, 68000000, 0 }, ··· 1290 1290 { TEGRA124_CLK_MSELECT, TEGRA124_CLK_CLK_MAX, 0, 1 }, 1291 1291 { TEGRA124_CLK_CSITE, TEGRA124_CLK_CLK_MAX, 0, 1 }, 1292 1292 { TEGRA124_CLK_TSENSOR, TEGRA124_CLK_CLK_M, 400000, 0 }, 1293 + { TEGRA124_CLK_VIC03, TEGRA124_CLK_PLL_C3, 0, 0 }, 1293 1294 /* must be the last entry */ 1294 1295 { TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0 }, 1295 1296 };
+12 -2
drivers/clk/tegra/clk-tegra210.c
··· 44 44 #define CLK_SOURCE_EMC 0x19c 45 45 #define CLK_SOURCE_SOR1 0x410 46 46 #define CLK_SOURCE_LA 0x1f8 47 + #define CLK_SOURCE_SDMMC2 0x154 48 + #define CLK_SOURCE_SDMMC4 0x164 47 49 48 50 #define PLLC_BASE 0x80 49 51 #define PLLC_OUT 0x84 ··· 2288 2286 [tegra_clk_rtc] = { .dt_id = TEGRA210_CLK_RTC, .present = true }, 2289 2287 [tegra_clk_timer] = { .dt_id = TEGRA210_CLK_TIMER, .present = true }, 2290 2288 [tegra_clk_uarta_8] = { .dt_id = TEGRA210_CLK_UARTA, .present = true }, 2291 - [tegra_clk_sdmmc2_9] = { .dt_id = TEGRA210_CLK_SDMMC2, .present = true }, 2292 2289 [tegra_clk_i2s1] = { .dt_id = TEGRA210_CLK_I2S1, .present = true }, 2293 2290 [tegra_clk_i2c1] = { .dt_id = TEGRA210_CLK_I2C1, .present = true }, 2294 2291 [tegra_clk_sdmmc1_9] = { .dt_id = TEGRA210_CLK_SDMMC1, .present = true }, 2295 - [tegra_clk_sdmmc4_9] = { .dt_id = TEGRA210_CLK_SDMMC4, .present = true }, 2296 2292 [tegra_clk_pwm] = { .dt_id = TEGRA210_CLK_PWM, .present = true }, 2297 2293 [tegra_clk_i2s2] = { .dt_id = TEGRA210_CLK_I2S2, .present = true }, 2298 2294 [tegra_clk_usbd] = { .dt_id = TEGRA210_CLK_USBD, .present = true }, ··· 3029 3029 ARRAY_SIZE(aclk_parents), 0, clk_base + 0x6e0, 3030 3030 0, NULL); 3031 3031 clks[TEGRA210_CLK_ACLK] = clk; 3032 + 3033 + clk = tegra_clk_register_sdmmc_mux_div("sdmmc2", clk_base, 3034 + CLK_SOURCE_SDMMC2, 9, 3035 + TEGRA_DIVIDER_ROUND_UP, 0, NULL); 3036 + clks[TEGRA210_CLK_SDMMC2] = clk; 3037 + 3038 + clk = tegra_clk_register_sdmmc_mux_div("sdmmc4", clk_base, 3039 + CLK_SOURCE_SDMMC4, 15, 3040 + TEGRA_DIVIDER_ROUND_UP, 0, NULL); 3041 + clks[TEGRA210_CLK_SDMMC4] = clk; 3032 3042 3033 3043 for (i = 0; i < ARRAY_SIZE(tegra210_periph); i++) { 3034 3044 struct tegra_periph_init_data *init = &tegra210_periph[i];
+43
drivers/clk/tegra/clk-utils.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. 4 + */ 5 + 6 + #include <asm/div64.h> 7 + 8 + #include "clk.h" 9 + 10 + #define div_mask(w) ((1 << (w)) - 1) 11 + 12 + int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, 13 + u8 frac_width, u8 flags) 14 + { 15 + u64 divider_ux1 = parent_rate; 16 + int mul; 17 + 18 + if (!rate) 19 + return 0; 20 + 21 + mul = 1 << frac_width; 22 + 23 + if (!(flags & TEGRA_DIVIDER_INT)) 24 + divider_ux1 *= mul; 25 + 26 + if (flags & TEGRA_DIVIDER_ROUND_UP) 27 + divider_ux1 += rate - 1; 28 + 29 + do_div(divider_ux1, rate); 30 + 31 + if (flags & TEGRA_DIVIDER_INT) 32 + divider_ux1 *= mul; 33 + 34 + if (divider_ux1 < mul) 35 + return 0; 36 + 37 + divider_ux1 -= mul; 38 + 39 + if (divider_ux1 > div_mask(width)) 40 + return div_mask(width); 41 + 42 + return divider_ux1; 43 + }
+30
drivers/clk/tegra/clk.h
··· 19 19 20 20 #include <linux/clk-provider.h> 21 21 #include <linux/clkdev.h> 22 + #include <linux/delay.h> 22 23 23 24 /** 24 25 * struct tegra_clk_sync_source - external clock source from codec ··· 706 705 const char * const *parent_names, u8 num_parents, 707 706 unsigned long flags, void __iomem *reg, u8 clk_super_flags, 708 707 spinlock_t *lock); 708 + 709 + /** 710 + * struct tegra_sdmmc_mux - switch divider with Low Jitter inputs for SDMMC 711 + * 712 + * @hw: handle between common and hardware-specific interfaces 713 + * @reg: register controlling mux and divider 714 + * @flags: hardware-specific flags 715 + * @lock: optional register lock 716 + * @gate: gate clock 717 + * @gate_ops: gate clock ops 718 + */ 719 + struct tegra_sdmmc_mux { 720 + struct clk_hw hw; 721 + void __iomem *reg; 722 + spinlock_t *lock; 723 + const struct clk_ops *gate_ops; 724 + struct tegra_clk_periph_gate gate; 725 + u8 div_flags; 726 + }; 727 + 728 + #define to_clk_sdmmc_mux(_hw) container_of(_hw, struct tegra_sdmmc_mux, hw) 729 + 730 + struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, 731 + void __iomem *clk_base, u32 offset, u32 clk_num, u8 div_flags, 732 + unsigned long flags, void *lock); 733 + 709 734 /** 710 735 * struct clk_init_table - clock initialization table 711 736 * @clk_id: clock id as mentioned in device tree bindings ··· 838 811 int tegra_pll_wait_for_lock(struct tegra_clk_pll *pll); 839 812 u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate); 840 813 int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div); 814 + int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width, 815 + u8 frac_width, u8 flags); 816 + 841 817 842 818 /* Combined read fence with delay */ 843 819 #define fence_udelay(delay, reg) \
+9
drivers/clk/uniphier/clk-uniphier-peri.c
··· 27 27 #define UNIPHIER_PERI_CLK_FI2C(idx, ch) \ 28 28 UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch)) 29 29 30 + #define UNIPHIER_PERI_CLK_SCSSI(idx) \ 31 + UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17) 32 + 33 + #define UNIPHIER_PERI_CLK_MCSSI(idx) \ 34 + UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14) 35 + 30 36 const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = { 31 37 UNIPHIER_PERI_CLK_UART(0, 0), 32 38 UNIPHIER_PERI_CLK_UART(1, 1), ··· 44 38 UNIPHIER_PERI_CLK_I2C(6, 2), 45 39 UNIPHIER_PERI_CLK_I2C(7, 3), 46 40 UNIPHIER_PERI_CLK_I2C(8, 4), 41 + UNIPHIER_PERI_CLK_SCSSI(11), 47 42 { /* sentinel */ } 48 43 }; 49 44 ··· 60 53 UNIPHIER_PERI_CLK_FI2C(8, 4), 61 54 UNIPHIER_PERI_CLK_FI2C(9, 5), 62 55 UNIPHIER_PERI_CLK_FI2C(10, 6), 56 + UNIPHIER_PERI_CLK_SCSSI(11), 57 + UNIPHIER_PERI_CLK_MCSSI(12), 63 58 { /* sentinel */ } 64 59 };
+42 -16
drivers/clk/uniphier/clk-uniphier-sys.c
··· 29 29 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 10), \ 30 30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) 31 31 32 - /* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ 33 32 #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ 34 - UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ 35 - UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) 33 + UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 32), \ 34 + UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x2104, 2) 36 35 37 36 #define UNIPHIER_PRO5_SYS_CLK_NAND(idx) \ 38 - UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 12), \ 39 - UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) 37 + UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 48), \ 38 + UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x2104, 2) 40 39 41 40 #define UNIPHIER_LD11_SYS_CLK_NAND(idx) \ 42 - UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 10), \ 43 - UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x210c, 0) 41 + UNIPHIER_CLK_FACTOR("nand-50m", -1, "spll", 1, 40), \ 42 + UNIPHIER_CLK_GATE("nand", (idx), "nand-50m", 0x210c, 0) 43 + 44 + #define UNIPHIER_SYS_CLK_NAND_4X(idx) \ 45 + UNIPHIER_CLK_FACTOR("nand-4x", (idx), "nand", 4, 1) 44 46 45 47 #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ 46 48 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) ··· 95 93 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 96 94 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 97 95 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 96 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 32), 98 97 UNIPHIER_LD4_SYS_CLK_NAND(2), 98 + UNIPHIER_SYS_CLK_NAND_4X(3), 99 99 UNIPHIER_LD4_SYS_CLK_SD, 100 100 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 101 101 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ ··· 112 108 UNIPHIER_CLK_FACTOR("gpll", -1, "ref", 10, 1), /* 250 MHz */ 113 109 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), 114 110 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), 111 + UNIPHIER_CLK_FACTOR("spi", 1, "spll", 1, 32), 115 112 UNIPHIER_LD4_SYS_CLK_NAND(2), 113 + UNIPHIER_SYS_CLK_NAND_4X(3), 116 114 UNIPHIER_LD4_SYS_CLK_SD, 117 115 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 118 116 UNIPHIER_PRO4_SYS_CLK_ETHER(6), ··· 124 118 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ 125 119 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 126 120 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), 121 + UNIPHIER_CLK_FACTOR("usb30-hsphy0", 16, "upll", 1, 12), 122 + UNIPHIER_CLK_FACTOR("usb30-ssphy0", 17, "ref", 1, 1), 123 + UNIPHIER_CLK_FACTOR("usb31-ssphy0", 20, "ref", 1, 1), 127 124 UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 18), 128 125 UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x2104, 19), 129 126 UNIPHIER_PRO4_SYS_CLK_AIO(40), ··· 139 130 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 140 131 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), 141 132 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 133 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 32), 142 134 UNIPHIER_LD4_SYS_CLK_NAND(2), 135 + UNIPHIER_SYS_CLK_NAND_4X(3), 143 136 UNIPHIER_LD4_SYS_CLK_SD, 144 137 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 145 138 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ ··· 154 143 UNIPHIER_CLK_FACTOR("dapll2", -1, "dapll1", 144, 125), /* 2949.12 MHz */ 155 144 UNIPHIER_CLK_FACTOR("uart", 0, "dapll2", 1, 40), 156 145 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 146 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 48), 157 147 UNIPHIER_PRO5_SYS_CLK_NAND(2), 148 + UNIPHIER_SYS_CLK_NAND_4X(3), 158 149 UNIPHIER_PRO5_SYS_CLK_SD, 159 150 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */ 160 151 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ ··· 171 158 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1), /* 2400 MHz */ 172 159 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27), 173 160 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 161 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 48), 174 162 UNIPHIER_PRO5_SYS_CLK_NAND(2), 163 + UNIPHIER_SYS_CLK_NAND_4X(3), 175 164 UNIPHIER_PRO5_SYS_CLK_SD, 176 165 UNIPHIER_PRO4_SYS_CLK_ETHER(6), 177 166 UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */ ··· 181 166 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 182 167 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), 183 168 /* The document mentions 0x2104 bit 18, but not functional */ 184 - UNIPHIER_CLK_GATE("usb30-phy", 16, NULL, 0x2104, 19), 185 - UNIPHIER_CLK_GATE("usb31-phy", 20, NULL, 0x2104, 20), 169 + UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x2104, 19), 170 + UNIPHIER_CLK_FACTOR("usb30-ssphy0", 17, "ref", 1, 1), 171 + UNIPHIER_CLK_FACTOR("usb30-ssphy1", 18, "ref", 1, 1), 172 + UNIPHIER_CLK_GATE("usb31-hsphy0", 20, NULL, 0x2104, 20), 173 + UNIPHIER_CLK_FACTOR("usb31-ssphy0", 21, "ref", 1, 1), 186 174 UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x2104, 22), 187 175 UNIPHIER_PRO5_SYS_CLK_AIO(40), 188 176 { /* sentinel */ } ··· 198 180 UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1), /* 2000 MHz */ 199 181 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 200 182 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 183 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), 201 184 UNIPHIER_LD11_SYS_CLK_NAND(2), 185 + UNIPHIER_SYS_CLK_NAND_4X(3), 202 186 UNIPHIER_LD11_SYS_CLK_EMMC(4), 203 187 /* Index 5 reserved for eMMC PHY */ 204 188 UNIPHIER_LD11_SYS_CLK_ETHER(6), ··· 233 213 UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5), /* 2520 MHz */ 234 214 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 235 215 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 216 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), 236 217 UNIPHIER_LD11_SYS_CLK_NAND(2), 218 + UNIPHIER_SYS_CLK_NAND_4X(3), 237 219 UNIPHIER_LD11_SYS_CLK_EMMC(4), 238 220 /* Index 5 reserved for eMMC PHY */ 239 221 UNIPHIER_LD20_SYS_CLK_SD, ··· 248 226 * We do not use bit 15 here. 249 227 */ 250 228 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), 251 - UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), 252 - UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), 229 + UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x210c, 12), 230 + UNIPHIER_CLK_GATE("usb30-hsphy1", 17, NULL, 0x210c, 13), 231 + UNIPHIER_CLK_FACTOR("usb30-ssphy0", 18, "ref", 1, 1), 232 + UNIPHIER_CLK_FACTOR("usb30-ssphy1", 19, "ref", 1, 1), 253 233 UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 4), 254 234 UNIPHIER_LD11_SYS_CLK_AIO(40), 255 235 UNIPHIER_LD11_SYS_CLK_EVEA(41), ··· 278 254 UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */ 279 255 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 280 256 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 257 + UNIPHIER_CLK_FACTOR("spi", -1, "spll", 1, 40), 281 258 UNIPHIER_LD20_SYS_CLK_SD, 282 259 UNIPHIER_LD11_SYS_CLK_NAND(2), 260 + UNIPHIER_SYS_CLK_NAND_4X(3), 283 261 UNIPHIER_LD11_SYS_CLK_EMMC(4), 284 262 UNIPHIER_CLK_GATE("ether0", 6, NULL, 0x210c, 9), 285 263 UNIPHIER_CLK_GATE("ether1", 7, NULL, 0x210c, 10), 286 264 UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x210c, 4), /* =GIO0 */ 287 265 UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x210c, 5), /* =GIO1 */ 288 266 UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x210c, 6), /* =GIO1-1 */ 289 - UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 16), 290 - UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 18), 291 - UNIPHIER_CLK_GATE("usb30-phy2", 18, NULL, 0x210c, 20), 292 - UNIPHIER_CLK_GATE("usb31-phy0", 20, NULL, 0x210c, 17), 293 - UNIPHIER_CLK_GATE("usb31-phy1", 21, NULL, 0x210c, 19), 267 + UNIPHIER_CLK_GATE("usb30-hsphy0", 16, NULL, 0x210c, 16), 268 + UNIPHIER_CLK_GATE("usb30-ssphy0", 17, NULL, 0x210c, 18), 269 + UNIPHIER_CLK_GATE("usb30-ssphy1", 18, NULL, 0x210c, 20), 270 + UNIPHIER_CLK_GATE("usb31-hsphy0", 20, NULL, 0x210c, 17), 271 + UNIPHIER_CLK_GATE("usb31-ssphy0", 21, NULL, 0x210c, 19), 294 272 UNIPHIER_CLK_GATE("pcie", 24, NULL, 0x210c, 3), 295 273 UNIPHIER_CLK_GATE("sata0", 28, NULL, 0x210c, 7), 296 274 UNIPHIER_CLK_GATE("sata1", 29, NULL, 0x210c, 8),
+118
include/dt-bindings/clock/actions,s700-cmu.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 2 + * 3 + * Device Tree binding constants for Actions Semi S700 Clock Management Unit 4 + * 5 + * Copyright (c) 2014 Actions Semi Inc. 6 + * Author: David Liu <liuwei@actions-semi.com> 7 + * 8 + * Author: Pathiban Nallathambi <pn@denx.de> 9 + * Author: Saravanan Sekar <sravanhome@gmail.com> 10 + */ 11 + 12 + #ifndef __DT_BINDINGS_CLOCK_S700_H 13 + #define __DT_BINDINGS_CLOCK_S700_H 14 + 15 + #define CLK_NONE 0 16 + 17 + /* pll clocks */ 18 + #define CLK_CORE_PLL 1 19 + #define CLK_DEV_PLL 2 20 + #define CLK_DDR_PLL 3 21 + #define CLK_NAND_PLL 4 22 + #define CLK_DISPLAY_PLL 5 23 + #define CLK_TVOUT_PLL 6 24 + #define CLK_CVBS_PLL 7 25 + #define CLK_AUDIO_PLL 8 26 + #define CLK_ETHERNET_PLL 9 27 + 28 + /* system clock */ 29 + #define CLK_CPU 10 30 + #define CLK_DEV 11 31 + #define CLK_AHB 12 32 + #define CLK_APB 13 33 + #define CLK_DMAC 14 34 + #define CLK_NOC0_CLK_MUX 15 35 + #define CLK_NOC1_CLK_MUX 16 36 + #define CLK_HP_CLK_MUX 17 37 + #define CLK_HP_CLK_DIV 18 38 + #define CLK_NOC1_CLK_DIV 19 39 + #define CLK_NOC0 20 40 + #define CLK_NOC1 21 41 + #define CLK_SENOR_SRC 22 42 + 43 + /* peripheral device clock */ 44 + #define CLK_GPIO 23 45 + #define CLK_TIMER 24 46 + #define CLK_DSI 25 47 + #define CLK_CSI 26 48 + #define CLK_SI 27 49 + #define CLK_DE 28 50 + #define CLK_HDE 29 51 + #define CLK_VDE 30 52 + #define CLK_VCE 31 53 + #define CLK_NAND 32 54 + #define CLK_SD0 33 55 + #define CLK_SD1 34 56 + #define CLK_SD2 35 57 + 58 + #define CLK_UART0 36 59 + #define CLK_UART1 37 60 + #define CLK_UART2 38 61 + #define CLK_UART3 39 62 + #define CLK_UART4 40 63 + #define CLK_UART5 41 64 + #define CLK_UART6 42 65 + 66 + #define CLK_PWM0 43 67 + #define CLK_PWM1 44 68 + #define CLK_PWM2 45 69 + #define CLK_PWM3 46 70 + #define CLK_PWM4 47 71 + #define CLK_PWM5 48 72 + #define CLK_GPU3D 49 73 + 74 + #define CLK_I2C0 50 75 + #define CLK_I2C1 51 76 + #define CLK_I2C2 52 77 + #define CLK_I2C3 53 78 + 79 + #define CLK_SPI0 54 80 + #define CLK_SPI1 55 81 + #define CLK_SPI2 56 82 + #define CLK_SPI3 57 83 + 84 + #define CLK_USB3_480MPLL0 58 85 + #define CLK_USB3_480MPHY0 59 86 + #define CLK_USB3_5GPHY 60 87 + #define CLK_USB3_CCE 61 88 + #define CLK_USB3_MAC 62 89 + 90 + #define CLK_LCD 63 91 + #define CLK_HDMI_AUDIO 64 92 + #define CLK_I2SRX 65 93 + #define CLK_I2STX 66 94 + 95 + #define CLK_SENSOR0 67 96 + #define CLK_SENSOR1 68 97 + 98 + #define CLK_HDMI_DEV 69 99 + 100 + #define CLK_ETHERNET 70 101 + #define CLK_RMII_REF 71 102 + 103 + #define CLK_USB2H0_PLLEN 72 104 + #define CLK_USB2H0_PHY 73 105 + #define CLK_USB2H0_CCE 74 106 + #define CLK_USB2H1_PLLEN 75 107 + #define CLK_USB2H1_PHY 76 108 + #define CLK_USB2H1_CCE 77 109 + 110 + #define CLK_TVOUT 78 111 + 112 + #define CLK_THERMAL_SENSOR 79 113 + 114 + #define CLK_IRC_SWITCH 80 115 + #define CLK_PCM1 81 116 + #define CLK_NR_CLKS (CLK_PCM1 + 1) 117 + 118 + #endif /* __DT_BINDINGS_CLOCK_S700_H */
+1 -1
include/dt-bindings/clock/aspeed-clock.h
··· 25 25 #define ASPEED_CLK_GATE_RSACLK 19 26 26 #define ASPEED_CLK_GATE_UART3CLK 20 27 27 #define ASPEED_CLK_GATE_UART4CLK 21 28 - #define ASPEED_CLK_GATE_SDCLKCLK 22 28 + #define ASPEED_CLK_GATE_SDCLK 22 29 29 #define ASPEED_CLK_GATE_LHCCLK 23 30 30 #define ASPEED_CLK_HPLL 24 31 31 #define ASPEED_CLK_AHB 25
+94
include/dt-bindings/clock/axg-audio-clkc.h
··· 1 + /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ 2 + /* 3 + * Copyright (c) 2018 Baylibre SAS. 4 + * Author: Jerome Brunet <jbrunet@baylibre.com> 5 + */ 6 + 7 + #ifndef __AXG_AUDIO_CLKC_BINDINGS_H 8 + #define __AXG_AUDIO_CLKC_BINDINGS_H 9 + 10 + #define AUD_CLKID_SLV_SCLK0 9 11 + #define AUD_CLKID_SLV_SCLK1 10 12 + #define AUD_CLKID_SLV_SCLK2 11 13 + #define AUD_CLKID_SLV_SCLK3 12 14 + #define AUD_CLKID_SLV_SCLK4 13 15 + #define AUD_CLKID_SLV_SCLK5 14 16 + #define AUD_CLKID_SLV_SCLK6 15 17 + #define AUD_CLKID_SLV_SCLK7 16 18 + #define AUD_CLKID_SLV_SCLK8 17 19 + #define AUD_CLKID_SLV_SCLK9 18 20 + #define AUD_CLKID_SLV_LRCLK0 19 21 + #define AUD_CLKID_SLV_LRCLK1 20 22 + #define AUD_CLKID_SLV_LRCLK2 21 23 + #define AUD_CLKID_SLV_LRCLK3 22 24 + #define AUD_CLKID_SLV_LRCLK4 23 25 + #define AUD_CLKID_SLV_LRCLK5 24 26 + #define AUD_CLKID_SLV_LRCLK6 25 27 + #define AUD_CLKID_SLV_LRCLK7 26 28 + #define AUD_CLKID_SLV_LRCLK8 27 29 + #define AUD_CLKID_SLV_LRCLK9 28 30 + #define AUD_CLKID_DDR_ARB 29 31 + #define AUD_CLKID_PDM 30 32 + #define AUD_CLKID_TDMIN_A 31 33 + #define AUD_CLKID_TDMIN_B 32 34 + #define AUD_CLKID_TDMIN_C 33 35 + #define AUD_CLKID_TDMIN_LB 34 36 + #define AUD_CLKID_TDMOUT_A 35 37 + #define AUD_CLKID_TDMOUT_B 36 38 + #define AUD_CLKID_TDMOUT_C 37 39 + #define AUD_CLKID_FRDDR_A 38 40 + #define AUD_CLKID_FRDDR_B 39 41 + #define AUD_CLKID_FRDDR_C 40 42 + #define AUD_CLKID_TODDR_A 41 43 + #define AUD_CLKID_TODDR_B 42 44 + #define AUD_CLKID_TODDR_C 43 45 + #define AUD_CLKID_LOOPBACK 44 46 + #define AUD_CLKID_SPDIFIN 45 47 + #define AUD_CLKID_SPDIFOUT 46 48 + #define AUD_CLKID_RESAMPLE 47 49 + #define AUD_CLKID_POWER_DETECT 48 50 + #define AUD_CLKID_MST_A_MCLK 49 51 + #define AUD_CLKID_MST_B_MCLK 50 52 + #define AUD_CLKID_MST_C_MCLK 51 53 + #define AUD_CLKID_MST_D_MCLK 52 54 + #define AUD_CLKID_MST_E_MCLK 53 55 + #define AUD_CLKID_MST_F_MCLK 54 56 + #define AUD_CLKID_SPDIFOUT_CLK 55 57 + #define AUD_CLKID_SPDIFIN_CLK 56 58 + #define AUD_CLKID_PDM_DCLK 57 59 + #define AUD_CLKID_PDM_SYSCLK 58 60 + #define AUD_CLKID_MST_A_SCLK 79 61 + #define AUD_CLKID_MST_B_SCLK 80 62 + #define AUD_CLKID_MST_C_SCLK 81 63 + #define AUD_CLKID_MST_D_SCLK 82 64 + #define AUD_CLKID_MST_E_SCLK 83 65 + #define AUD_CLKID_MST_F_SCLK 84 66 + #define AUD_CLKID_MST_A_LRCLK 86 67 + #define AUD_CLKID_MST_B_LRCLK 87 68 + #define AUD_CLKID_MST_C_LRCLK 88 69 + #define AUD_CLKID_MST_D_LRCLK 89 70 + #define AUD_CLKID_MST_E_LRCLK 90 71 + #define AUD_CLKID_MST_F_LRCLK 91 72 + #define AUD_CLKID_TDMIN_A_SCLK_SEL 116 73 + #define AUD_CLKID_TDMIN_B_SCLK_SEL 117 74 + #define AUD_CLKID_TDMIN_C_SCLK_SEL 118 75 + #define AUD_CLKID_TDMIN_LB_SCLK_SEL 119 76 + #define AUD_CLKID_TDMOUT_A_SCLK_SEL 120 77 + #define AUD_CLKID_TDMOUT_B_SCLK_SEL 121 78 + #define AUD_CLKID_TDMOUT_C_SCLK_SEL 122 79 + #define AUD_CLKID_TDMIN_A_SCLK 123 80 + #define AUD_CLKID_TDMIN_B_SCLK 124 81 + #define AUD_CLKID_TDMIN_C_SCLK 125 82 + #define AUD_CLKID_TDMIN_LB_SCLK 126 83 + #define AUD_CLKID_TDMOUT_A_SCLK 127 84 + #define AUD_CLKID_TDMOUT_B_SCLK 128 85 + #define AUD_CLKID_TDMOUT_C_SCLK 129 86 + #define AUD_CLKID_TDMIN_A_LRCLK 130 87 + #define AUD_CLKID_TDMIN_B_LRCLK 131 88 + #define AUD_CLKID_TDMIN_C_LRCLK 132 89 + #define AUD_CLKID_TDMIN_LB_LRCLK 133 90 + #define AUD_CLKID_TDMOUT_A_LRCLK 134 91 + #define AUD_CLKID_TDMOUT_B_LRCLK 135 92 + #define AUD_CLKID_TDMOUT_C_LRCLK 136 93 + 94 + #endif /* __AXG_AUDIO_CLKC_BINDINGS_H */
+4
include/dt-bindings/clock/axg-clkc.h
··· 68 68 #define CLKID_SD_EMMC_B_CLK0 59 69 69 #define CLKID_SD_EMMC_C_CLK0 60 70 70 #define CLKID_HIFI_PLL 69 71 + #define CLKID_PCIE_CML_EN0 79 72 + #define CLKID_PCIE_CML_EN1 80 73 + #define CLKID_MIPI_ENABLE 81 74 + #define CLKID_GEN_CLK 84 71 75 72 76 #endif /* __AXG_CLKC_H */
+1
include/dt-bindings/clock/gxbb-clkc.h
··· 127 127 #define CLKID_VAPB 140 128 128 #define CLKID_VDEC_1 153 129 129 #define CLKID_VDEC_HEVC 156 130 + #define CLKID_GEN_CLK 159 130 131 131 132 #endif /* __GXBB_CLKC_H */
+8 -1
include/dt-bindings/clock/imx6sll-clock.h
··· 197 197 #define IMX6SLL_CLK_EXTERN_AUDIO_PODF 171 198 198 #define IMX6SLL_CLK_EXTERN_AUDIO 172 199 199 200 - #define IMX6SLL_CLK_END 173 200 + #define IMX6SLL_CLK_GPIO1 173 201 + #define IMX6SLL_CLK_GPIO2 174 202 + #define IMX6SLL_CLK_GPIO3 175 203 + #define IMX6SLL_CLK_GPIO4 176 204 + #define IMX6SLL_CLK_GPIO5 177 205 + #define IMX6SLL_CLK_GPIO6 178 206 + 207 + #define IMX6SLL_CLK_END 179 201 208 202 209 #endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */
+7 -1
include/dt-bindings/clock/imx6ul-clock.h
··· 254 254 #define IMX6UL_CLK_CKO2_PODF 241 255 255 #define IMX6UL_CLK_CKO2 242 256 256 #define IMX6UL_CLK_CKO 243 257 - #define IMX6UL_CLK_END 244 257 + #define IMX6UL_CLK_GPIO1 244 258 + #define IMX6UL_CLK_GPIO2 245 259 + #define IMX6UL_CLK_GPIO3 246 260 + #define IMX6UL_CLK_GPIO4 247 261 + #define IMX6UL_CLK_GPIO5 248 262 + 263 + #define IMX6UL_CLK_END 249 258 264 259 265 #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
+18
include/dt-bindings/clock/maxim,max9485.h
··· 1 + /* 2 + * Copyright (C) 2018 Daniel Mack 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + * 8 + */ 9 + 10 + #ifndef __DT_BINDINGS_MAX9485_CLK_H 11 + #define __DT_BINDINGS_MAX9485_CLK_H 12 + 13 + #define MAX9485_MCLKOUT 0 14 + #define MAX9485_CLKOUT 1 15 + #define MAX9485_CLKOUT1 2 16 + #define MAX9485_CLKOUT2 3 17 + 18 + #endif /* __DT_BINDINGS_MAX9485_CLK_H */
+389
include/dt-bindings/clock/px30-cru.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef _DT_BINDINGS_CLK_ROCKCHIP_PX30_H 4 + #define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H 5 + 6 + /* core clocks */ 7 + #define PLL_APLL 1 8 + #define PLL_DPLL 2 9 + #define PLL_CPLL 3 10 + #define PLL_NPLL 4 11 + #define APLL_BOOST_H 5 12 + #define APLL_BOOST_L 6 13 + #define ARMCLK 7 14 + 15 + /* sclk gates (special clocks) */ 16 + #define USB480M 14 17 + #define SCLK_PDM 15 18 + #define SCLK_I2S0_TX 16 19 + #define SCLK_I2S0_TX_OUT 17 20 + #define SCLK_I2S0_RX 18 21 + #define SCLK_I2S0_RX_OUT 19 22 + #define SCLK_I2S1 20 23 + #define SCLK_I2S1_OUT 21 24 + #define SCLK_I2S2 22 25 + #define SCLK_I2S2_OUT 23 26 + #define SCLK_UART1 24 27 + #define SCLK_UART2 25 28 + #define SCLK_UART3 26 29 + #define SCLK_UART4 27 30 + #define SCLK_UART5 28 31 + #define SCLK_I2C0 29 32 + #define SCLK_I2C1 30 33 + #define SCLK_I2C2 31 34 + #define SCLK_I2C3 32 35 + #define SCLK_I2C4 33 36 + #define SCLK_PWM0 34 37 + #define SCLK_PWM1 35 38 + #define SCLK_SPI0 36 39 + #define SCLK_SPI1 37 40 + #define SCLK_TIMER0 38 41 + #define SCLK_TIMER1 39 42 + #define SCLK_TIMER2 40 43 + #define SCLK_TIMER3 41 44 + #define SCLK_TIMER4 42 45 + #define SCLK_TIMER5 43 46 + #define SCLK_TSADC 44 47 + #define SCLK_SARADC 45 48 + #define SCLK_OTP 46 49 + #define SCLK_OTP_USR 47 50 + #define SCLK_CRYPTO 48 51 + #define SCLK_CRYPTO_APK 49 52 + #define SCLK_DDRC 50 53 + #define SCLK_ISP 51 54 + #define SCLK_CIF_OUT 52 55 + #define SCLK_RGA_CORE 53 56 + #define SCLK_VOPB_PWM 54 57 + #define SCLK_NANDC 55 58 + #define SCLK_SDIO 56 59 + #define SCLK_EMMC 57 60 + #define SCLK_SFC 58 61 + #define SCLK_SDMMC 59 62 + #define SCLK_OTG_ADP 60 63 + #define SCLK_GMAC_SRC 61 64 + #define SCLK_GMAC 62 65 + #define SCLK_GMAC_RX_TX 63 66 + #define SCLK_MAC_REF 64 67 + #define SCLK_MAC_REFOUT 65 68 + #define SCLK_MAC_OUT 66 69 + #define SCLK_SDMMC_DRV 67 70 + #define SCLK_SDMMC_SAMPLE 68 71 + #define SCLK_SDIO_DRV 69 72 + #define SCLK_SDIO_SAMPLE 70 73 + #define SCLK_EMMC_DRV 71 74 + #define SCLK_EMMC_SAMPLE 72 75 + #define SCLK_GPU 73 76 + #define SCLK_PVTM 74 77 + #define SCLK_CORE_VPU 75 78 + #define SCLK_GMAC_RMII 76 79 + #define SCLK_UART2_SRC 77 80 + #define SCLK_NANDC_DIV 78 81 + #define SCLK_NANDC_DIV50 79 82 + #define SCLK_SDIO_DIV 80 83 + #define SCLK_SDIO_DIV50 81 84 + #define SCLK_EMMC_DIV 82 85 + #define SCLK_EMMC_DIV50 83 86 + #define SCLK_DDRCLK 84 87 + #define SCLK_UART1_SRC 85 88 + 89 + /* dclk gates */ 90 + #define DCLK_VOPB 150 91 + #define DCLK_VOPL 151 92 + 93 + /* aclk gates */ 94 + #define ACLK_GPU 170 95 + #define ACLK_BUS_PRE 171 96 + #define ACLK_CRYPTO 172 97 + #define ACLK_VI_PRE 173 98 + #define ACLK_VO_PRE 174 99 + #define ACLK_VPU 175 100 + #define ACLK_PERI_PRE 176 101 + #define ACLK_GMAC 178 102 + #define ACLK_CIF 179 103 + #define ACLK_ISP 180 104 + #define ACLK_VOPB 181 105 + #define ACLK_VOPL 182 106 + #define ACLK_RGA 183 107 + #define ACLK_GIC 184 108 + #define ACLK_DCF 186 109 + #define ACLK_DMAC 187 110 + #define ACLK_BUS_SRC 188 111 + #define ACLK_PERI_SRC 189 112 + 113 + /* hclk gates */ 114 + #define HCLK_BUS_PRE 240 115 + #define HCLK_CRYPTO 241 116 + #define HCLK_VI_PRE 242 117 + #define HCLK_VO_PRE 243 118 + #define HCLK_VPU 244 119 + #define HCLK_PERI_PRE 245 120 + #define HCLK_MMC_NAND 246 121 + #define HCLK_SDMMC 247 122 + #define HCLK_USB 248 123 + #define HCLK_CIF 249 124 + #define HCLK_ISP 250 125 + #define HCLK_VOPB 251 126 + #define HCLK_VOPL 252 127 + #define HCLK_RGA 253 128 + #define HCLK_NANDC 254 129 + #define HCLK_SDIO 255 130 + #define HCLK_EMMC 256 131 + #define HCLK_SFC 257 132 + #define HCLK_OTG 258 133 + #define HCLK_HOST 259 134 + #define HCLK_HOST_ARB 260 135 + #define HCLK_PDM 261 136 + #define HCLK_I2S0 262 137 + #define HCLK_I2S1 263 138 + #define HCLK_I2S2 264 139 + 140 + /* pclk gates */ 141 + #define PCLK_BUS_PRE 320 142 + #define PCLK_DDR 321 143 + #define PCLK_VO_PRE 322 144 + #define PCLK_GMAC 323 145 + #define PCLK_MIPI_DSI 324 146 + #define PCLK_MIPIDSIPHY 325 147 + #define PCLK_MIPICSIPHY 326 148 + #define PCLK_USB_GRF 327 149 + #define PCLK_DCF 328 150 + #define PCLK_UART1 329 151 + #define PCLK_UART2 330 152 + #define PCLK_UART3 331 153 + #define PCLK_UART4 332 154 + #define PCLK_UART5 333 155 + #define PCLK_I2C0 334 156 + #define PCLK_I2C1 335 157 + #define PCLK_I2C2 336 158 + #define PCLK_I2C3 337 159 + #define PCLK_I2C4 338 160 + #define PCLK_PWM0 339 161 + #define PCLK_PWM1 340 162 + #define PCLK_SPI0 341 163 + #define PCLK_SPI1 342 164 + #define PCLK_SARADC 343 165 + #define PCLK_TSADC 344 166 + #define PCLK_TIMER 345 167 + #define PCLK_OTP_NS 346 168 + #define PCLK_WDT_NS 347 169 + #define PCLK_GPIO1 348 170 + #define PCLK_GPIO2 349 171 + #define PCLK_GPIO3 350 172 + #define PCLK_ISP 351 173 + #define PCLK_CIF 352 174 + #define PCLK_OTP_PHY 353 175 + 176 + #define CLK_NR_CLKS (PCLK_OTP_PHY + 1) 177 + 178 + /* pmu-clocks indices */ 179 + 180 + #define PLL_GPLL 1 181 + 182 + #define SCLK_RTC32K_PMU 4 183 + #define SCLK_WIFI_PMU 5 184 + #define SCLK_UART0_PMU 6 185 + #define SCLK_PVTM_PMU 7 186 + #define PCLK_PMU_PRE 8 187 + #define SCLK_REF24M_PMU 9 188 + #define SCLK_USBPHY_REF 10 189 + #define SCLK_MIPIDSIPHY_REF 11 190 + 191 + #define XIN24M_DIV 12 192 + 193 + #define PCLK_GPIO0_PMU 20 194 + #define PCLK_UART0_PMU 21 195 + 196 + #define CLKPMU_NR_CLKS (PCLK_UART0_PMU + 1) 197 + 198 + /* soft-reset indices */ 199 + #define SRST_CORE0_PO 0 200 + #define SRST_CORE1_PO 1 201 + #define SRST_CORE2_PO 2 202 + #define SRST_CORE3_PO 3 203 + #define SRST_CORE0 4 204 + #define SRST_CORE1 5 205 + #define SRST_CORE2 6 206 + #define SRST_CORE3 7 207 + #define SRST_CORE0_DBG 8 208 + #define SRST_CORE1_DBG 9 209 + #define SRST_CORE2_DBG 10 210 + #define SRST_CORE3_DBG 11 211 + #define SRST_TOPDBG 12 212 + #define SRST_CORE_NOC 13 213 + #define SRST_STRC_A 14 214 + #define SRST_L2C 15 215 + 216 + #define SRST_DAP 16 217 + #define SRST_CORE_PVTM 17 218 + #define SRST_GPU 18 219 + #define SRST_GPU_NIU 19 220 + #define SRST_UPCTL2 20 221 + #define SRST_UPCTL2_A 21 222 + #define SRST_UPCTL2_P 22 223 + #define SRST_MSCH 23 224 + #define SRST_MSCH_P 24 225 + #define SRST_DDRMON_P 25 226 + #define SRST_DDRSTDBY_P 26 227 + #define SRST_DDRSTDBY 27 228 + #define SRST_DDRGRF_p 28 229 + #define SRST_AXI_SPLIT_A 29 230 + #define SRST_AXI_CMD_A 30 231 + #define SRST_AXI_CMD_P 31 232 + 233 + #define SRST_DDRPHY 32 234 + #define SRST_DDRPHYDIV 33 235 + #define SRST_DDRPHY_P 34 236 + #define SRST_VPU_A 36 237 + #define SRST_VPU_NIU_A 37 238 + #define SRST_VPU_H 38 239 + #define SRST_VPU_NIU_H 39 240 + #define SRST_VI_NIU_A 40 241 + #define SRST_VI_NIU_H 41 242 + #define SRST_ISP_H 42 243 + #define SRST_ISP 43 244 + #define SRST_CIF_A 44 245 + #define SRST_CIF_H 45 246 + #define SRST_CIF_PCLKIN 46 247 + #define SRST_MIPICSIPHY_P 47 248 + 249 + #define SRST_VO_NIU_A 48 250 + #define SRST_VO_NIU_H 49 251 + #define SRST_VO_NIU_P 50 252 + #define SRST_VOPB_A 51 253 + #define SRST_VOPB_H 52 254 + #define SRST_VOPB 53 255 + #define SRST_PWM_VOPB 54 256 + #define SRST_VOPL_A 55 257 + #define SRST_VOPL_H 56 258 + #define SRST_VOPL 57 259 + #define SRST_RGA_A 58 260 + #define SRST_RGA_H 59 261 + #define SRST_RGA 60 262 + #define SRST_MIPIDSI_HOST_P 61 263 + #define SRST_MIPIDSIPHY_P 62 264 + #define SRST_VPU_CORE 63 265 + 266 + #define SRST_PERI_NIU_A 64 267 + #define SRST_USB_NIU_H 65 268 + #define SRST_USB2OTG_H 66 269 + #define SRST_USB2OTG 67 270 + #define SRST_USB2OTG_ADP 68 271 + #define SRST_USB2HOST_H 69 272 + #define SRST_USB2HOST_ARB_H 70 273 + #define SRST_USB2HOST_AUX_H 71 274 + #define SRST_USB2HOST_EHCI 72 275 + #define SRST_USB2HOST 73 276 + #define SRST_USBPHYPOR 74 277 + #define SRST_USBPHY_OTG_PORT 75 278 + #define SRST_USBPHY_HOST_PORT 76 279 + #define SRST_USBPHY_GRF 77 280 + #define SRST_CPU_BOOST_P 78 281 + #define SRST_CPU_BOOST 79 282 + 283 + #define SRST_MMC_NAND_NIU_H 80 284 + #define SRST_SDIO_H 81 285 + #define SRST_EMMC_H 82 286 + #define SRST_SFC_H 83 287 + #define SRST_SFC 84 288 + #define SRST_SDCARD_NIU_H 85 289 + #define SRST_SDMMC_H 86 290 + #define SRST_NANDC_H 89 291 + #define SRST_NANDC 90 292 + #define SRST_GMAC_NIU_A 92 293 + #define SRST_GMAC_NIU_P 93 294 + #define SRST_GMAC_A 94 295 + 296 + #define SRST_PMU_NIU_P 96 297 + #define SRST_PMU_SGRF_P 97 298 + #define SRST_PMU_GRF_P 98 299 + #define SRST_PMU 99 300 + #define SRST_PMU_MEM_P 100 301 + #define SRST_PMU_GPIO0_P 101 302 + #define SRST_PMU_UART0_P 102 303 + #define SRST_PMU_CRU_P 103 304 + #define SRST_PMU_PVTM 104 305 + #define SRST_PMU_UART 105 306 + #define SRST_PMU_NIU_H 106 307 + #define SRST_PMU_DDR_FAIL_SAVE 107 308 + #define SRST_PMU_CORE_PERF_A 108 309 + #define SRST_PMU_CORE_GRF_P 109 310 + #define SRST_PMU_GPU_PERF_A 110 311 + #define SRST_PMU_GPU_GRF_P 111 312 + 313 + #define SRST_CRYPTO_NIU_A 112 314 + #define SRST_CRYPTO_NIU_H 113 315 + #define SRST_CRYPTO_A 114 316 + #define SRST_CRYPTO_H 115 317 + #define SRST_CRYPTO 116 318 + #define SRST_CRYPTO_APK 117 319 + #define SRST_BUS_NIU_H 120 320 + #define SRST_USB_NIU_P 121 321 + #define SRST_BUS_TOP_NIU_P 122 322 + #define SRST_INTMEM_A 123 323 + #define SRST_GIC_A 124 324 + #define SRST_ROM_H 126 325 + #define SRST_DCF_A 127 326 + 327 + #define SRST_DCF_P 128 328 + #define SRST_PDM_H 129 329 + #define SRST_PDM 130 330 + #define SRST_I2S0_H 131 331 + #define SRST_I2S0_TX 132 332 + #define SRST_I2S1_H 133 333 + #define SRST_I2S1 134 334 + #define SRST_I2S2_H 135 335 + #define SRST_I2S2 136 336 + #define SRST_UART1_P 137 337 + #define SRST_UART1 138 338 + #define SRST_UART2_P 139 339 + #define SRST_UART2 140 340 + #define SRST_UART3_P 141 341 + #define SRST_UART3 142 342 + #define SRST_UART4_P 143 343 + 344 + #define SRST_UART4 144 345 + #define SRST_UART5_P 145 346 + #define SRST_UART5 146 347 + #define SRST_I2C0_P 147 348 + #define SRST_I2C0 148 349 + #define SRST_I2C1_P 149 350 + #define SRST_I2C1 150 351 + #define SRST_I2C2_P 151 352 + #define SRST_I2C2 152 353 + #define SRST_I2C3_P 153 354 + #define SRST_I2C3 154 355 + #define SRST_PWM0_P 157 356 + #define SRST_PWM0 158 357 + #define SRST_PWM1_P 159 358 + 359 + #define SRST_PWM1 160 360 + #define SRST_SPI0_P 161 361 + #define SRST_SPI0 162 362 + #define SRST_SPI1_P 163 363 + #define SRST_SPI1 164 364 + #define SRST_SARADC_P 165 365 + #define SRST_SARADC 166 366 + #define SRST_TSADC_P 167 367 + #define SRST_TSADC 168 368 + #define SRST_TIMER_P 169 369 + #define SRST_TIMER0 170 370 + #define SRST_TIMER1 171 371 + #define SRST_TIMER2 172 372 + #define SRST_TIMER3 173 373 + #define SRST_TIMER4 174 374 + #define SRST_TIMER5 175 375 + 376 + #define SRST_OTP_NS_P 176 377 + #define SRST_OTP_NS_SBPI 177 378 + #define SRST_OTP_NS_USR 178 379 + #define SRST_OTP_PHY_P 179 380 + #define SRST_OTP_PHY 180 381 + #define SRST_WDT_NS_P 181 382 + #define SRST_GPIO1_P 182 383 + #define SRST_GPIO2_P 183 384 + #define SRST_GPIO3_P 184 385 + #define SRST_SGRF_P 185 386 + #define SRST_GRF_P 186 387 + #define SRST_I2S0_RX 191 388 + 389 + #endif
+2 -1
include/dt-bindings/clock/pxa-clock.h
··· 72 72 #define CLK_USIM 58 73 73 #define CLK_USIM1 59 74 74 #define CLK_USMI0 60 75 - #define CLK_MAX 61 75 + #define CLK_OSC32k768 61 76 + #define CLK_MAX 62 76 77 77 78 #endif
+45
include/dt-bindings/clock/qcom,dispcc-sdm845.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 + */ 5 + 6 + #ifndef _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H 7 + #define _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H 8 + 9 + /* DISP_CC clock registers */ 10 + #define DISP_CC_MDSS_AHB_CLK 0 11 + #define DISP_CC_MDSS_AXI_CLK 1 12 + #define DISP_CC_MDSS_BYTE0_CLK 2 13 + #define DISP_CC_MDSS_BYTE0_CLK_SRC 3 14 + #define DISP_CC_MDSS_BYTE0_INTF_CLK 4 15 + #define DISP_CC_MDSS_BYTE1_CLK 5 16 + #define DISP_CC_MDSS_BYTE1_CLK_SRC 6 17 + #define DISP_CC_MDSS_BYTE1_INTF_CLK 7 18 + #define DISP_CC_MDSS_ESC0_CLK 8 19 + #define DISP_CC_MDSS_ESC0_CLK_SRC 9 20 + #define DISP_CC_MDSS_ESC1_CLK 10 21 + #define DISP_CC_MDSS_ESC1_CLK_SRC 11 22 + #define DISP_CC_MDSS_MDP_CLK 12 23 + #define DISP_CC_MDSS_MDP_CLK_SRC 13 24 + #define DISP_CC_MDSS_MDP_LUT_CLK 14 25 + #define DISP_CC_MDSS_PCLK0_CLK 15 26 + #define DISP_CC_MDSS_PCLK0_CLK_SRC 16 27 + #define DISP_CC_MDSS_PCLK1_CLK 17 28 + #define DISP_CC_MDSS_PCLK1_CLK_SRC 18 29 + #define DISP_CC_MDSS_ROT_CLK 19 30 + #define DISP_CC_MDSS_ROT_CLK_SRC 20 31 + #define DISP_CC_MDSS_RSCC_AHB_CLK 21 32 + #define DISP_CC_MDSS_RSCC_VSYNC_CLK 22 33 + #define DISP_CC_MDSS_VSYNC_CLK 23 34 + #define DISP_CC_MDSS_VSYNC_CLK_SRC 24 35 + #define DISP_CC_PLL0 25 36 + #define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 26 37 + #define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 27 38 + 39 + /* DISP_CC Reset */ 40 + #define DISP_CC_MDSS_RSCC_BCR 0 41 + 42 + /* DISP_CC GDSCR */ 43 + #define MDSS_GDSC 0 44 + 45 + #endif
+2
include/dt-bindings/clock/qcom,gcc-sdm845.h
··· 192 192 #define GCC_VS_CTRL_CLK_SRC 182 193 193 #define GCC_VSENSOR_CLK_SRC 183 194 194 #define GPLL4 184 195 + #define GCC_CPUSS_DVM_BUS_CLK 185 196 + #define GCC_CPUSS_GNOC_CLK 186 195 197 196 198 /* GCC Resets */ 197 199 #define GCC_MMSS_BCR 0
+148
include/dt-bindings/clock/r9a06g032-sysctrl.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * R9A06G032 sysctrl IDs 4 + * 5 + * Copyright (C) 2018 Renesas Electronics Europe Limited 6 + * 7 + * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com> 8 + */ 9 + 10 + #ifndef __DT_BINDINGS_R9A06G032_SYSCTRL_H__ 11 + #define __DT_BINDINGS_R9A06G032_SYSCTRL_H__ 12 + 13 + #define R9A06G032_CLK_PLL_USB 1 14 + #define R9A06G032_CLK_48 1 /* AKA CLK_PLL_USB */ 15 + #define R9A06G032_MSEBIS_CLK 3 /* AKA CLKOUT_D16 */ 16 + #define R9A06G032_MSEBIM_CLK 3 /* AKA CLKOUT_D16 */ 17 + #define R9A06G032_CLK_DDRPHY_PLLCLK 5 /* AKA CLKOUT_D1OR2 */ 18 + #define R9A06G032_CLK50 6 /* AKA CLKOUT_D20 */ 19 + #define R9A06G032_CLK25 7 /* AKA CLKOUT_D40 */ 20 + #define R9A06G032_CLK125 9 /* AKA CLKOUT_D8 */ 21 + #define R9A06G032_CLK_P5_PG1 17 /* AKA DIV_P5_PG */ 22 + #define R9A06G032_CLK_REF_SYNC 21 /* AKA DIV_REF_SYNC */ 23 + #define R9A06G032_CLK_25_PG4 26 24 + #define R9A06G032_CLK_25_PG5 27 25 + #define R9A06G032_CLK_25_PG6 28 26 + #define R9A06G032_CLK_25_PG7 29 27 + #define R9A06G032_CLK_25_PG8 30 28 + #define R9A06G032_CLK_ADC 31 29 + #define R9A06G032_CLK_ECAT100 32 30 + #define R9A06G032_CLK_HSR100 33 31 + #define R9A06G032_CLK_I2C0 34 32 + #define R9A06G032_CLK_I2C1 35 33 + #define R9A06G032_CLK_MII_REF 36 34 + #define R9A06G032_CLK_NAND 37 35 + #define R9A06G032_CLK_NOUSBP2_PG6 38 36 + #define R9A06G032_CLK_P1_PG2 39 37 + #define R9A06G032_CLK_P1_PG3 40 38 + #define R9A06G032_CLK_P1_PG4 41 39 + #define R9A06G032_CLK_P4_PG3 42 40 + #define R9A06G032_CLK_P4_PG4 43 41 + #define R9A06G032_CLK_P6_PG1 44 42 + #define R9A06G032_CLK_P6_PG2 45 43 + #define R9A06G032_CLK_P6_PG3 46 44 + #define R9A06G032_CLK_P6_PG4 47 45 + #define R9A06G032_CLK_PCI_USB 48 46 + #define R9A06G032_CLK_QSPI0 49 47 + #define R9A06G032_CLK_QSPI1 50 48 + #define R9A06G032_CLK_RGMII_REF 51 49 + #define R9A06G032_CLK_RMII_REF 52 50 + #define R9A06G032_CLK_SDIO0 53 51 + #define R9A06G032_CLK_SDIO1 54 52 + #define R9A06G032_CLK_SERCOS100 55 53 + #define R9A06G032_CLK_SLCD 56 54 + #define R9A06G032_CLK_SPI0 57 55 + #define R9A06G032_CLK_SPI1 58 56 + #define R9A06G032_CLK_SPI2 59 57 + #define R9A06G032_CLK_SPI3 60 58 + #define R9A06G032_CLK_SPI4 61 59 + #define R9A06G032_CLK_SPI5 62 60 + #define R9A06G032_CLK_SWITCH 63 61 + #define R9A06G032_HCLK_ECAT125 65 62 + #define R9A06G032_HCLK_PINCONFIG 66 63 + #define R9A06G032_HCLK_SERCOS 67 64 + #define R9A06G032_HCLK_SGPIO2 68 65 + #define R9A06G032_HCLK_SGPIO3 69 66 + #define R9A06G032_HCLK_SGPIO4 70 67 + #define R9A06G032_HCLK_TIMER0 71 68 + #define R9A06G032_HCLK_TIMER1 72 69 + #define R9A06G032_HCLK_USBF 73 70 + #define R9A06G032_HCLK_USBH 74 71 + #define R9A06G032_HCLK_USBPM 75 72 + #define R9A06G032_CLK_48_PG_F 76 73 + #define R9A06G032_CLK_48_PG4 77 74 + #define R9A06G032_CLK_DDRPHY_PCLK 81 /* AKA CLK_REF_SYNC_D4 */ 75 + #define R9A06G032_CLK_FW 81 /* AKA CLK_REF_SYNC_D4 */ 76 + #define R9A06G032_CLK_CRYPTO 81 /* AKA CLK_REF_SYNC_D4 */ 77 + #define R9A06G032_CLK_A7MP 84 /* AKA DIV_CA7 */ 78 + #define R9A06G032_HCLK_CAN0 85 79 + #define R9A06G032_HCLK_CAN1 86 80 + #define R9A06G032_HCLK_DELTASIGMA 87 81 + #define R9A06G032_HCLK_PWMPTO 88 82 + #define R9A06G032_HCLK_RSV 89 83 + #define R9A06G032_HCLK_SGPIO0 90 84 + #define R9A06G032_HCLK_SGPIO1 91 85 + #define R9A06G032_RTOS_MDC 92 86 + #define R9A06G032_CLK_CM3 93 87 + #define R9A06G032_CLK_DDRC 94 88 + #define R9A06G032_CLK_ECAT25 95 89 + #define R9A06G032_CLK_HSR50 96 90 + #define R9A06G032_CLK_HW_RTOS 97 91 + #define R9A06G032_CLK_SERCOS50 98 92 + #define R9A06G032_HCLK_ADC 99 93 + #define R9A06G032_HCLK_CM3 100 94 + #define R9A06G032_HCLK_CRYPTO_EIP150 101 95 + #define R9A06G032_HCLK_CRYPTO_EIP93 102 96 + #define R9A06G032_HCLK_DDRC 103 97 + #define R9A06G032_HCLK_DMA0 104 98 + #define R9A06G032_HCLK_DMA1 105 99 + #define R9A06G032_HCLK_GMAC0 106 100 + #define R9A06G032_HCLK_GMAC1 107 101 + #define R9A06G032_HCLK_GPIO0 108 102 + #define R9A06G032_HCLK_GPIO1 109 103 + #define R9A06G032_HCLK_GPIO2 110 104 + #define R9A06G032_HCLK_HSR 111 105 + #define R9A06G032_HCLK_I2C0 112 106 + #define R9A06G032_HCLK_I2C1 113 107 + #define R9A06G032_HCLK_LCD 114 108 + #define R9A06G032_HCLK_MSEBI_M 115 109 + #define R9A06G032_HCLK_MSEBI_S 116 110 + #define R9A06G032_HCLK_NAND 117 111 + #define R9A06G032_HCLK_PG_I 118 112 + #define R9A06G032_HCLK_PG19 119 113 + #define R9A06G032_HCLK_PG20 120 114 + #define R9A06G032_HCLK_PG3 121 115 + #define R9A06G032_HCLK_PG4 122 116 + #define R9A06G032_HCLK_QSPI0 123 117 + #define R9A06G032_HCLK_QSPI1 124 118 + #define R9A06G032_HCLK_ROM 125 119 + #define R9A06G032_HCLK_RTC 126 120 + #define R9A06G032_HCLK_SDIO0 127 121 + #define R9A06G032_HCLK_SDIO1 128 122 + #define R9A06G032_HCLK_SEMAP 129 123 + #define R9A06G032_HCLK_SPI0 130 124 + #define R9A06G032_HCLK_SPI1 131 125 + #define R9A06G032_HCLK_SPI2 132 126 + #define R9A06G032_HCLK_SPI3 133 127 + #define R9A06G032_HCLK_SPI4 134 128 + #define R9A06G032_HCLK_SPI5 135 129 + #define R9A06G032_HCLK_SWITCH 136 130 + #define R9A06G032_HCLK_SWITCH_RG 137 131 + #define R9A06G032_HCLK_UART0 138 132 + #define R9A06G032_HCLK_UART1 139 133 + #define R9A06G032_HCLK_UART2 140 134 + #define R9A06G032_HCLK_UART3 141 135 + #define R9A06G032_HCLK_UART4 142 136 + #define R9A06G032_HCLK_UART5 143 137 + #define R9A06G032_HCLK_UART6 144 138 + #define R9A06G032_HCLK_UART7 145 139 + #define R9A06G032_CLK_UART0 146 140 + #define R9A06G032_CLK_UART1 147 141 + #define R9A06G032_CLK_UART2 148 142 + #define R9A06G032_CLK_UART3 149 143 + #define R9A06G032_CLK_UART4 150 144 + #define R9A06G032_CLK_UART5 151 145 + #define R9A06G032_CLK_UART6 152 146 + #define R9A06G032_CLK_UART7 153 147 + 148 + #endif /* __DT_BINDINGS_R9A06G032_SYSCTRL_H__ */
+4
include/dt-bindings/clock/sun8i-r40-ccu.h
··· 43 43 #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ 44 44 #define _DT_BINDINGS_CLK_SUN8I_R40_H_ 45 45 46 + #define CLK_PLL_VIDEO0 7 47 + 48 + #define CLK_PLL_VIDEO1 16 49 + 46 50 #define CLK_CPU 24 47 51 48 52 #define CLK_BUS_MIPI_DSI 29