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

Pull clk updates from Stephen Boyd:
"The diff is dominated by the Allwinner A10/A20 SoCs getting converted
to the sunxi-ng framework. Otherwise, the heavy hitters are various
drivers for SoCs like AT91, Amlogic, Renesas, and Rockchip. There are
some other new clk drivers in here too but overall this is just a
bunch of clk drivers for various different pieces of hardware and a
collection of non-critical fixes for clk drivers.

New Drivers:
- Allwinner R40 SoCs
- Renesas R-Car Gen3 USB 2.0 clock selector PHY
- Atmel AT91 audio PLL
- Uniphier PXs3 SoCs
- ARC HSDK Board PLLs
- AXS10X Board PLLs
- STMicroelectronics STM32H743 SoCs

Removed Drivers:
- Non-compiling mb86s7x support

Updates:
- Allwinner A10/A20 SoCs converted to sunxi-ng framework
- Allwinner H3 CPU clk fixes
- Renesas R-Car D3 SoC
- Renesas V2H and M3-W modules
- Samsung Exynos5420/5422/5800 audio fixes
- Rockchip fractional clk approximation fixes
- Rockchip rk3126 SoC support within the rk3128 driver
- Amlogic gxbb CEC32 and sd_emmc clks
- Amlogic meson8b reset controller support
- IDT VersaClock 5P49V5925/5P49V6901 support
- Qualcomm MSM8996 SMMU clks
- Various 'const' applications for struct clk_ops
- si5351 PLL reset bugfix
- Uniphier audio on LD11/LD20 and ethernet support on LD11/LD20/Pro4/PXs2
- Assorted Tegra clk driver fixes"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (120 commits)
clk: si5351: fix PLL reset
ASoC: atmel-classd: remove aclk clock
ASoC: atmel-classd: remove aclk clock from DT binding
clk: at91: clk-generated: make gclk determine audio_pll rate
clk: at91: clk-generated: create function to find best_diff
clk: at91: add audio pll clock drivers
dt-bindings: clk: at91: add audio plls to the compatible list
clk: at91: clk-generated: remove useless divisor loop
clk: mb86s7x: Drop non-building driver
clk: ti: check for null return in strrchr to avoid null dereferencing
clk: Don't write error code into divider register
clk: uniphier: add video input subsystem clock
clk: uniphier: add audio system clock
clk: stm32h7: Add stm32h743 clock driver
clk: gate: expose clk_gate_ops::is_enabled
clk: nxp: clk-lpc32xx: rename clk_gate_is_enabled()
clk: uniphier: add PXs3 clock data
clk: hi6220: change watchdog clock source
clk: Kconfig: Name RK805 in Kconfig for COMMON_CLK_RK808
clk: cs2000: Add cs2000_set_saved_rate
...

+9356 -1103
+16 -6
Documentation/devicetree/bindings/clock/amlogic,gxbb-aoclkc.txt
··· 5 5 6 6 Required Properties: 7 7 8 - - compatible: should be "amlogic,gxbb-aoclkc" 9 - - reg: physical base address of the clock controller and length of memory 10 - mapped region. 8 + - compatible: value should be different for each SoC family as : 9 + - GXBB (S905) : "amlogic,meson-gxbb-aoclkc" 10 + - GXL (S905X, S905D) : "amlogic,meson-gxl-aoclkc" 11 + - GXM (S912) : "amlogic,meson-gxm-aoclkc" 12 + followed by the common "amlogic,meson-gx-aoclkc" 11 13 12 14 - #clock-cells: should be 1. 13 15 ··· 25 23 preprocessor macros in the dt-bindings/reset/gxbb-aoclkc.h header and can be 26 24 used in device tree sources. 27 25 26 + Parent node should have the following properties : 27 + - compatible: "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd" 28 + - reg: base address and size of the AO system control register space. 29 + 28 30 Example: AO Clock controller node: 29 31 30 - clkc_AO: clock-controller@040 { 31 - compatible = "amlogic,gxbb-aoclkc"; 32 - reg = <0x0 0x040 0x0 0x4>; 32 + ao_sysctrl: sys-ctrl@0 { 33 + compatible = "amlogic,meson-gx-ao-sysctrl", "syscon", "simple-mfd"; 34 + reg = <0x0 0x0 0x0 0x100>; 35 + 36 + clkc_AO: clock-controller { 37 + compatible = "amlogic,meson-gxbb-aoclkc", "amlogic,meson-gx-aoclkc"; 33 38 #clock-cells = <1>; 34 39 #reset-cells = <1>; 35 40 }; 41 + }; 36 42 37 43 Example: UART controller node that consumes the clock and reset generated 38 44 by the clock controller:
+10
Documentation/devicetree/bindings/clock/at91-clock.txt
··· 81 81 "atmel,sama5d2-clk-generated": 82 82 at91 generated clock 83 83 84 + "atmel,sama5d2-clk-audio-pll-frac": 85 + at91 audio fractional pll 86 + 87 + "atmel,sama5d2-clk-audio-pll-pad": 88 + at91 audio pll CLK_AUDIO output pin 89 + 90 + "atmel,sama5d2-clk-audio-pll-pmc" 91 + at91 audio pll output on AUDIOPLLCLK that feeds the PMC 92 + and can be used by peripheral clock or generic clock 93 + 84 94 Required properties for SCKC node: 85 95 - reg : defines the IO memory reserved for the SCKC. 86 96 - #size-cells : shall be 0 (reg is used to encode clk id).
+23 -7
Documentation/devicetree/bindings/clock/idt,versaclock5.txt
··· 1 - Binding for IDT VersaClock5 programmable i2c clock generator. 1 + Binding for IDT VersaClock 5,6 programmable i2c clock generators. 2 2 3 - The IDT VersaClock5 are programmable i2c clock generators providing 4 - from 3 to 12 output clocks. 3 + The IDT VersaClock 5 and VersaClock 6 are programmable i2c clock 4 + generators providing from 3 to 12 output clocks. 5 5 6 6 ==I2C device node== 7 7 8 8 Required properties: 9 - - compatible: shall be one of "idt,5p49v5923" , "idt,5p49v5933" , 10 - "idt,5p49v5935". 9 + - compatible: shall be one of 10 + "idt,5p49v5923" 11 + "idt,5p49v5925" 12 + "idt,5p49v5933" 13 + "idt,5p49v5935" 14 + "idt,5p49v6901" 11 15 - reg: i2c device address, shall be 0x68 or 0x6a. 12 16 - #clock-cells: from common clock binding; shall be set to 1. 13 17 - clocks: from common clock binding; list of parent clock handles, 14 - - 5p49v5923: (required) either or both of XTAL or CLKIN 18 + - 5p49v5923 and 19 + 5p49v5925 and 20 + 5p49v6901: (required) either or both of XTAL or CLKIN 15 21 reference clock. 16 22 - 5p49v5933 and 17 23 - 5p49v5935: (optional) property not present (internal 18 24 Xtal used) or CLKIN reference 19 25 clock. 20 26 - clock-names: from common clock binding; clock input names, can be 21 - - 5p49v5923: (required) either or both of "xin", "clkin". 27 + - 5p49v5923 and 28 + 5p49v5925 and 29 + 5p49v6901: (required) either or both of "xin", "clkin". 22 30 - 5p49v5933 and 23 31 - 5p49v5935: (optional) property not present or "clkin". 24 32 ··· 45 37 1 -- OUT1 46 38 2 -- OUT4 47 39 40 + 5P49V5925 and 48 41 5P49V5935: 42 + 0 -- OUT0_SEL_I2CB 43 + 1 -- OUT1 44 + 2 -- OUT2 45 + 3 -- OUT3 46 + 4 -- OUT4 47 + 48 + 5P49V6901: 49 49 0 -- OUT0_SEL_I2CB 50 50 1 -- OUT1 51 51 2 -- OUT2
+2 -1
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
··· 22 22 - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2) 23 23 - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3) 24 24 - "renesas,r8a7796-cpg-mssr" for the r8a7796 SoC (R-Car M3-W) 25 + - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3) 25 26 26 27 - reg: Base address and length of the memory resource used by the CPG/MSSR 27 28 block ··· 31 30 clock-names 32 31 - clock-names: List of external parent clock names. Valid names are: 33 32 - "extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7792, r8a7793, r8a7794, 34 - r8a7795, r8a7796) 33 + r8a7795, r8a7796, r8a77995) 35 34 - "extalr" (r8a7795, r8a7796) 36 35 - "usb_extal" (r8a7743, r8a7745, r8a7790, r8a7791, r8a7793, r8a7794) 37 36
+55
Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
··· 1 + * Renesas R-Car USB 2.0 clock selector 2 + 3 + This file provides information on what the device node for the R-Car USB 2.0 4 + clock selector. 5 + 6 + If you connect an external clock to the USB_EXTAL pin only, you should set 7 + the clock rate to "usb_extal" node only. 8 + If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module 9 + is not needed because this is default setting. (Of course, you can set the 10 + clock rates to both "usb_extal" and "usb_xtal" nodes. 11 + 12 + Case 1: An external clock connects to R-Car SoC 13 + +----------+ +--- R-Car ---------------------+ 14 + |External |---|USB_EXTAL ---> all usb channels| 15 + |clock | |USB_XTAL | 16 + +----------+ +-------------------------------+ 17 + In this case, we need this driver with "usb_extal" clock. 18 + 19 + Case 2: An oscillator connects to R-Car SoC 20 + +----------+ +--- R-Car ---------------------+ 21 + |Oscillator|---|USB_EXTAL -+-> all usb channels| 22 + | |---|USB_XTAL --+ | 23 + +----------+ +-------------------------------+ 24 + In this case, we don't need this selector. 25 + 26 + Required properties: 27 + - compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of 28 + an R8A7795 SoC. 29 + "renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of 30 + an R8A7796 SoC. 31 + "renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3 32 + compatible device. 33 + 34 + When compatible with the generic version, nodes must list the 35 + SoC-specific version corresponding to the platform first 36 + followed by the generic version. 37 + 38 + - reg: offset and length of the USB 2.0 clock selector register block. 39 + - clocks: A list of phandles and specifier pairs. 40 + - clock-names: Name of the clocks. 41 + - The functional clock must be "ehci_ohci" 42 + - The USB_EXTAL clock pin must be "usb_extal" 43 + - The USB_XTAL clock pin must be "usb_xtal" 44 + - #clock-cells: Must be 0 45 + 46 + Example (R-Car H3): 47 + 48 + usb2_clksel: clock-controller@e6590630 { 49 + compatible = "renesas,r8a77950-rcar-usb2-clock-sel", 50 + "renesas,rcar-gen3-usb2-clock-sel"; 51 + reg = <0 0xe6590630 0 0x02>; 52 + clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>; 53 + clock-names = "ehci_ohci", "usb_extal", "usb_xtal"; 54 + #clock-cells = <0>; 55 + };
+5 -3
Documentation/devicetree/bindings/clock/rockchip,rk3128-cru.txt
··· 1 - * Rockchip RK3128 Clock and Reset Unit 1 + * Rockchip RK3126/RK3128 Clock and Reset Unit 2 2 3 - The RK3128 clock controller generates and supplies clock to various 3 + The RK3126/RK3128 clock controller generates and supplies clock to various 4 4 controllers within the SoC and also implements a reset controller for SoC 5 5 peripherals. 6 6 7 7 Required Properties: 8 8 9 - - compatible: should be "rockchip,rk3128-cru" 9 + - compatible: should be "rockchip,rk3126-cru" or "rockchip,rk3128-cru" 10 + "rockchip,rk3126-cru" - controller compatible with RK3126 SoC. 11 + "rockchip,rk3128-cru" - controller compatible with RK3128 SoC. 10 12 - reg: physical base address of the controller and length of memory mapped 11 13 region. 12 14 - #clock-cells: should be 1.
+28
Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt
··· 1 + Binding for the HSDK Generic PLL clock 2 + 3 + This binding uses the common clock binding[1]. 4 + 5 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 + 7 + Required properties: 8 + - compatible: should be "snps,hsdk-<name>-pll-clock" 9 + "snps,hsdk-core-pll-clock" 10 + "snps,hsdk-gp-pll-clock" 11 + "snps,hsdk-hdmi-pll-clock" 12 + - reg : should contain base register location and length. 13 + - clocks: shall be the input parent clock phandle for the PLL. 14 + - #clock-cells: from common clock binding; Should always be set to 0. 15 + 16 + Example: 17 + input_clk: input-clk { 18 + clock-frequency = <33333333>; 19 + compatible = "fixed-clock"; 20 + #clock-cells = <0>; 21 + }; 22 + 23 + cpu_clk: cpu-clk@0 { 24 + compatible = "snps,hsdk-core-pll-clock"; 25 + reg = <0x00 0x10>; 26 + #clock-cells = <0>; 27 + clocks = <&input_clk>; 28 + };
+28
Documentation/devicetree/bindings/clock/snps,pll-clock.txt
··· 1 + Binding for the AXS10X Generic PLL clock 2 + 3 + This binding uses the common clock binding[1]. 4 + 5 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 6 + 7 + Required properties: 8 + - compatible: should be "snps,axs10x-<name>-pll-clock" 9 + "snps,axs10x-arc-pll-clock" 10 + "snps,axs10x-pgu-pll-clock" 11 + - reg: should always contain 2 pairs address - length: first for PLL config 12 + registers and second for corresponding LOCK CGU register. 13 + - clocks: shall be the input parent clock phandle for the PLL. 14 + - #clock-cells: from common clock binding; Should always be set to 0. 15 + 16 + Example: 17 + input-clk: input-clk { 18 + clock-frequency = <33333333>; 19 + compatible = "fixed-clock"; 20 + #clock-cells = <0>; 21 + }; 22 + 23 + core-clk: core-clk@80 { 24 + compatible = "snps,axs10x-arc-pll-clock"; 25 + reg = <0x80 0x10>, <0x100 0x10>; 26 + #clock-cells = <0>; 27 + clocks = <&input-clk>; 28 + };
+71
Documentation/devicetree/bindings/clock/st,stm32h7-rcc.txt
··· 1 + STMicroelectronics STM32H7 Reset and Clock Controller 2 + ===================================================== 3 + 4 + The RCC IP is both a reset and a clock controller. 5 + 6 + Please refer to clock-bindings.txt for common clock controller binding usage. 7 + Please also refer to reset.txt for common reset controller binding usage. 8 + 9 + Required properties: 10 + - compatible: Should be: 11 + "st,stm32h743-rcc" 12 + 13 + - reg: should be register base and length as documented in the 14 + datasheet 15 + 16 + - #reset-cells: 1, see below 17 + 18 + - #clock-cells : from common clock binding; shall be set to 1 19 + 20 + - clocks: External oscillator clock phandle 21 + - high speed external clock signal (HSE) 22 + - low speed external clock signal (LSE) 23 + - external I2S clock (I2S_CKIN) 24 + 25 + Optional properties: 26 + - st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain 27 + write protection (RTC clock). 28 + 29 + Example: 30 + 31 + rcc: reset-clock-controller@58024400 { 32 + compatible = "st,stm32h743-rcc", "st,stm32-rcc"; 33 + reg = <0x58024400 0x400>; 34 + #reset-cells = <1>; 35 + #clock-cells = <2>; 36 + clocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>; 37 + 38 + st,syscfg = <&pwrcfg>; 39 + }; 40 + 41 + The peripheral clock consumer should specify the desired clock by 42 + having the clock ID in its "clocks" phandle cell. 43 + 44 + Example: 45 + 46 + timer5: timer@40000c00 { 47 + compatible = "st,stm32-timer"; 48 + reg = <0x40000c00 0x400>; 49 + interrupts = <50>; 50 + clocks = <&rcc TIM5_CK>; 51 + }; 52 + 53 + Specifying softreset control of devices 54 + ======================================= 55 + 56 + Device nodes should specify the reset channel required in their "resets" 57 + property, containing a phandle to the reset device node and an index specifying 58 + which channel to use. 59 + The index is the bit number within the RCC registers bank, starting from RCC 60 + base address. 61 + It is calculated as: index = register_offset / 4 * 32 + bit_offset. 62 + Where bit_offset is the bit offset within the register. 63 + 64 + For example, for CRC reset: 65 + crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107 66 + 67 + Example: 68 + 69 + timer2 { 70 + resets = <&rcc STM32H7_APB1L_RESET(TIM2)>; 71 + };
+6
Documentation/devicetree/bindings/clock/sunxi-ccu.txt
··· 3 3 4 4 Required properties : 5 5 - compatible: must contain one of the following compatibles: 6 + - "allwinner,sun4i-a10-ccu" 7 + - "allwinner,sun5i-a10s-ccu" 8 + - "allwinner,sun5i-a13-ccu" 6 9 - "allwinner,sun6i-a31-ccu" 10 + - "allwinner,sun7i-a20-ccu" 7 11 - "allwinner,sun8i-a23-ccu" 8 12 - "allwinner,sun8i-a33-ccu" 9 13 - "allwinner,sun8i-a83t-ccu" 10 14 - "allwinner,sun8i-a83t-r-ccu" 11 15 - "allwinner,sun8i-h3-ccu" 12 16 - "allwinner,sun8i-h3-r-ccu" 17 + + - "allwinner,sun8i-r40-ccu" 13 18 - "allwinner,sun8i-v3s-ccu" 14 19 - "allwinner,sun9i-a80-ccu" 15 20 - "allwinner,sun50i-a64-ccu" 16 21 - "allwinner,sun50i-a64-r-ccu" 17 22 - "allwinner,sun50i-h5-ccu" 23 + - "nextthing,gr8-ccu" 18 24 19 25 - reg: Must contain the registers base address and length 20 26 - clocks: phandle to the oscillators feeding the CCU. Two are needed:
+3 -5
Documentation/devicetree/bindings/clock/uniphier-clock.txt
··· 6 6 7 7 Required properties: 8 8 - compatible: should be one of the following: 9 - "socionext,uniphier-sld3-clock" - for sLD3 SoC. 10 9 "socionext,uniphier-ld4-clock" - for LD4 SoC. 11 10 "socionext,uniphier-pro4-clock" - for Pro4 SoC. 12 11 "socionext,uniphier-sld8-clock" - for sLD8 SoC. ··· 13 14 "socionext,uniphier-pxs2-clock" - for PXs2/LD6b SoC. 14 15 "socionext,uniphier-ld11-clock" - for LD11 SoC. 15 16 "socionext,uniphier-ld20-clock" - for LD20 SoC. 17 + "socionext,uniphier-pxs3-clock" - for PXs3 SoC 16 18 - #clock-cells: should be 1. 17 19 18 20 Example: ··· 48 48 49 49 Required properties: 50 50 - compatible: should be one of the following: 51 - "socionext,uniphier-sld3-mio-clock" - for sLD3 SoC. 52 51 "socionext,uniphier-ld4-mio-clock" - for LD4 SoC. 53 52 "socionext,uniphier-pro4-mio-clock" - for Pro4 SoC. 54 53 "socionext,uniphier-sld8-mio-clock" - for sLD8 SoC. ··· 55 56 "socionext,uniphier-pxs2-sd-clock" - for PXs2/LD6b SoC. 56 57 "socionext,uniphier-ld11-mio-clock" - for LD11 SoC. 57 58 "socionext,uniphier-ld20-sd-clock" - for LD20 SoC. 59 + "socionext,uniphier-pxs3-sd-clock" - for PXs3 SoC 58 60 - #clock-cells: should be 1. 59 61 60 62 Example: ··· 82 82 8: USB2 ch0 host 83 83 9: USB2 ch1 host 84 84 10: USB2 ch2 host 85 - 11: USB2 ch3 host 86 85 12: USB2 ch0 PHY 87 86 13: USB2 ch1 PHY 88 87 14: USB2 ch2 PHY 89 - 15: USB2 ch3 PHY 90 88 91 89 92 90 Peripheral clock ··· 92 94 93 95 Required properties: 94 96 - compatible: should be one of the following: 95 - "socionext,uniphier-sld3-peri-clock" - for sLD3 SoC. 96 97 "socionext,uniphier-ld4-peri-clock" - for LD4 SoC. 97 98 "socionext,uniphier-pro4-peri-clock" - for Pro4 SoC. 98 99 "socionext,uniphier-sld8-peri-clock" - for sLD8 SoC. ··· 99 102 "socionext,uniphier-pxs2-peri-clock" - for PXs2/LD6b SoC. 100 103 "socionext,uniphier-ld11-peri-clock" - for LD11 SoC. 101 104 "socionext,uniphier-ld20-peri-clock" - for LD20 SoC. 105 + "socionext,uniphier-pxs3-peri-clock" - for PXs3 SoC 102 106 - #clock-cells: should be 1. 103 107 104 108 Example:
+3 -6
Documentation/devicetree/bindings/sound/atmel-classd.txt
··· 13 13 Must be "tx". 14 14 - clock-names 15 15 Tuple listing input clock names. 16 - Required elements: "pclk", "gclk" and "aclk". 16 + Required elements: "pclk" and "gclk". 17 17 - clocks 18 18 Please refer to clock-bindings.txt. 19 19 - assigned-clocks 20 20 Should be <&classd_gclk>. 21 - - assigned-clock-parents 22 - Should be <&audio_pll_pmc>. 23 21 24 22 Optional properties: 25 23 - pinctrl-names, pinctrl-0 ··· 43 45 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) 44 46 | AT91_XDMAC_DT_PERID(47))>; 45 47 dma-names = "tx"; 46 - clocks = <&classd_clk>, <&classd_gclk>, <&audio_pll_pmc>; 47 - clock-names = "pclk", "gclk", "aclk"; 48 + clocks = <&classd_clk>, <&classd_gclk>; 49 + clock-names = "pclk", "gclk"; 48 50 assigned-clocks = <&classd_gclk>; 49 - assigned-clock-parents = <&audio_pll_pmc>; 50 51 51 52 pinctrl-names = "default"; 52 53 pinctrl-0 = <&pinctrl_classd_default>;
+12
MAINTAINERS
··· 12842 12842 F: drivers/tty/serial/arc_uart.c 12843 12843 T: git git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc.git 12844 12844 12845 + SYNOPSYS ARC HSDK SDP pll clock driver 12846 + M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> 12847 + S: Supported 12848 + F: drivers/clk/clk-hsdk-pll.c 12849 + F: Documentation/devicetree/bindings/clock/snps,hsdk-pll-clock.txt 12850 + 12851 + SYNOPSYS ARC SDP clock driver 12852 + M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> 12853 + S: Supported 12854 + F: drivers/clk/axs10x/* 12855 + F: Documentation/devicetree/bindings/clock/snps,pll-clock.txt 12856 + 12845 12857 SYNOPSYS ARC SDP platform support 12846 12858 M: Alexey Brodkin <abrodkin@synopsys.com> 12847 12859 S: Supported
+4
arch/arm/mach-at91/Kconfig
··· 26 26 select HAVE_AT91_USB_CLK 27 27 select HAVE_AT91_H32MX 28 28 select HAVE_AT91_GENERATED_CLK 29 + select HAVE_AT91_AUDIO_PLL 29 30 select PINCTRL_AT91PIO4 30 31 help 31 32 Select this if ou are using one of Atmel's SAMA5D2 family SoC. ··· 124 123 bool 125 124 126 125 config HAVE_AT91_GENERATED_CLK 126 + bool 127 + 128 + config HAVE_AT91_AUDIO_PLL 127 129 bool 128 130 129 131 config SOC_SAM_V4_V5
+12 -5
drivers/clk/Kconfig
··· 31 31 32 32 source "drivers/clk/versatile/Kconfig" 33 33 34 + config CLK_HSDK 35 + bool "PLL Driver for HSDK platform" 36 + depends on OF || COMPILE_TEST 37 + ---help--- 38 + This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs 39 + control. 40 + 34 41 config COMMON_CLK_MAX77686 35 42 tristate "Clock driver for Maxim 77620/77686/77802 MFD" 36 43 depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST ··· 46 39 clock. 47 40 48 41 config COMMON_CLK_RK808 49 - tristate "Clock driver for RK808/RK818" 42 + tristate "Clock driver for RK805/RK808/RK818" 50 43 depends on MFD_RK808 51 44 ---help--- 52 - This driver supports RK808 and RK818 crystal oscillator clock. These 45 + This driver supports RK805, RK808 and RK818 crystal oscillator clock. These 53 46 multi-function devices have two fixed-rate oscillators, 54 47 clocked at 32KHz each. Clkout1 is always on, Clkout2 can off 55 48 by control register. ··· 217 210 Support for the OXNAS SoC Family clocks. 218 211 219 212 config COMMON_CLK_VC5 220 - tristate "Clock driver for IDT VersaClock5 devices" 213 + tristate "Clock driver for IDT VersaClock 5,6 devices" 221 214 depends on I2C 222 215 depends on OF 223 216 select REGMAP_I2C 224 217 help 225 218 ---help--- 226 - This driver supports the IDT VersaClock5 programmable clock 227 - generator. 219 + This driver supports the IDT VersaClock 5 and VersaClock 6 220 + programmable clock generators. 228 221 229 222 source "drivers/clk/bcm/Kconfig" 230 223 source "drivers/clk/hisilicon/Kconfig"
+2 -1
drivers/clk/Makefile
··· 27 27 obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o 28 28 obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o 29 29 obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o 30 + obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o 30 31 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 31 - obj-$(CONFIG_ARCH_MB86S7X) += clk-mb86s7x.o 32 32 obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 33 33 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 34 34 obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o ··· 44 44 obj-$(CONFIG_COMMON_CLK_SI514) += clk-si514.o 45 45 obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o 46 46 obj-$(CONFIG_ARCH_STM32) += clk-stm32f4.o 47 + obj-$(CONFIG_ARCH_STM32) += clk-stm32h7.o 47 48 obj-$(CONFIG_ARCH_TANGO) += clk-tango4.o 48 49 obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 49 50 obj-$(CONFIG_ARCH_U300) += clk-u300.o
+1
drivers/clk/at91/Makefile
··· 6 6 obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o 7 7 obj-y += clk-system.o clk-peripheral.o clk-programmable.o 8 8 9 + obj-$(CONFIG_HAVE_AT91_AUDIO_PLL) += clk-audio-pll.o 9 10 obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o 10 11 obj-$(CONFIG_HAVE_AT91_USB_CLK) += clk-usb.o 11 12 obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
+536
drivers/clk/at91/clk-audio-pll.c
··· 1 + /* 2 + * Copyright (C) 2016 Atmel Corporation, 3 + * Songjun Wu <songjun.wu@atmel.com>, 4 + * Nicolas Ferre <nicolas.ferre@atmel.com> 5 + * Copyright (C) 2017 Free Electrons, 6 + * Quentin Schulz <quentin.schulz@free-electrons.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + * 13 + * The Sama5d2 SoC has two audio PLLs (PMC and PAD) that shares the same parent 14 + * (FRAC). FRAC can output between 620 and 700MHz and only multiply the rate of 15 + * its own parent. PMC and PAD can then divide the FRAC rate to best match the 16 + * asked rate. 17 + * 18 + * Traits of FRAC clock: 19 + * enable - clk_enable writes nd, fracr parameters and enables PLL 20 + * rate - rate is adjustable. 21 + * clk->rate = parent->rate * ((nd + 1) + (fracr / 2^22)) 22 + * parent - fixed parent. No clk_set_parent support 23 + * 24 + * Traits of PMC clock: 25 + * enable - clk_enable writes qdpmc, and enables PMC output 26 + * rate - rate is adjustable. 27 + * clk->rate = parent->rate / (qdpmc + 1) 28 + * parent - fixed parent. No clk_set_parent support 29 + * 30 + * Traits of PAD clock: 31 + * enable - clk_enable writes divisors and enables PAD output 32 + * rate - rate is adjustable. 33 + * clk->rate = parent->rate / (qdaudio * div)) 34 + * parent - fixed parent. No clk_set_parent support 35 + * 36 + */ 37 + 38 + #include <linux/clk.h> 39 + #include <linux/clk-provider.h> 40 + #include <linux/clk/at91_pmc.h> 41 + #include <linux/of.h> 42 + #include <linux/mfd/syscon.h> 43 + #include <linux/regmap.h> 44 + #include <linux/slab.h> 45 + 46 + #define AUDIO_PLL_DIV_FRAC BIT(22) 47 + #define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \ 48 + AT91_PMC_AUDIO_PLL_ND_OFFSET) 49 + 50 + #define AUDIO_PLL_QDPAD(qd, div) ((AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(qd) & \ 51 + AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK) | \ 52 + (AT91_PMC_AUDIO_PLL_QDPAD_DIV(div) & \ 53 + AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK)) 54 + 55 + #define AUDIO_PLL_QDPMC_MAX (AT91_PMC_AUDIO_PLL_QDPMC_MASK >> \ 56 + AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) 57 + 58 + #define AUDIO_PLL_FOUT_MIN 620000000UL 59 + #define AUDIO_PLL_FOUT_MAX 700000000UL 60 + 61 + struct clk_audio_frac { 62 + struct clk_hw hw; 63 + struct regmap *regmap; 64 + u32 fracr; 65 + u8 nd; 66 + }; 67 + 68 + struct clk_audio_pad { 69 + struct clk_hw hw; 70 + struct regmap *regmap; 71 + u8 qdaudio; 72 + u8 div; 73 + }; 74 + 75 + struct clk_audio_pmc { 76 + struct clk_hw hw; 77 + struct regmap *regmap; 78 + u8 qdpmc; 79 + }; 80 + 81 + #define to_clk_audio_frac(hw) container_of(hw, struct clk_audio_frac, hw) 82 + #define to_clk_audio_pad(hw) container_of(hw, struct clk_audio_pad, hw) 83 + #define to_clk_audio_pmc(hw) container_of(hw, struct clk_audio_pmc, hw) 84 + 85 + static int clk_audio_pll_frac_enable(struct clk_hw *hw) 86 + { 87 + struct clk_audio_frac *frac = to_clk_audio_frac(hw); 88 + 89 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, 90 + AT91_PMC_AUDIO_PLL_RESETN, 0); 91 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, 92 + AT91_PMC_AUDIO_PLL_RESETN, 93 + AT91_PMC_AUDIO_PLL_RESETN); 94 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL1, 95 + AT91_PMC_AUDIO_PLL_FRACR_MASK, frac->fracr); 96 + 97 + /* 98 + * reset and enable have to be done in 2 separated writes 99 + * for AT91_PMC_AUDIO_PLL0 100 + */ 101 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, 102 + AT91_PMC_AUDIO_PLL_PLLEN | 103 + AT91_PMC_AUDIO_PLL_ND_MASK, 104 + AT91_PMC_AUDIO_PLL_PLLEN | 105 + AT91_PMC_AUDIO_PLL_ND(frac->nd)); 106 + 107 + return 0; 108 + } 109 + 110 + static int clk_audio_pll_pad_enable(struct clk_hw *hw) 111 + { 112 + struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); 113 + 114 + regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL1, 115 + AT91_PMC_AUDIO_PLL_QDPAD_MASK, 116 + AUDIO_PLL_QDPAD(apad_ck->qdaudio, apad_ck->div)); 117 + regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0, 118 + AT91_PMC_AUDIO_PLL_PADEN, AT91_PMC_AUDIO_PLL_PADEN); 119 + 120 + return 0; 121 + } 122 + 123 + static int clk_audio_pll_pmc_enable(struct clk_hw *hw) 124 + { 125 + struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); 126 + 127 + regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0, 128 + AT91_PMC_AUDIO_PLL_PMCEN | 129 + AT91_PMC_AUDIO_PLL_QDPMC_MASK, 130 + AT91_PMC_AUDIO_PLL_PMCEN | 131 + AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc)); 132 + return 0; 133 + } 134 + 135 + static void clk_audio_pll_frac_disable(struct clk_hw *hw) 136 + { 137 + struct clk_audio_frac *frac = to_clk_audio_frac(hw); 138 + 139 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, 140 + AT91_PMC_AUDIO_PLL_PLLEN, 0); 141 + /* do it in 2 separated writes */ 142 + regmap_update_bits(frac->regmap, AT91_PMC_AUDIO_PLL0, 143 + AT91_PMC_AUDIO_PLL_RESETN, 0); 144 + } 145 + 146 + static void clk_audio_pll_pad_disable(struct clk_hw *hw) 147 + { 148 + struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); 149 + 150 + regmap_update_bits(apad_ck->regmap, AT91_PMC_AUDIO_PLL0, 151 + AT91_PMC_AUDIO_PLL_PADEN, 0); 152 + } 153 + 154 + static void clk_audio_pll_pmc_disable(struct clk_hw *hw) 155 + { 156 + struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); 157 + 158 + regmap_update_bits(apmc_ck->regmap, AT91_PMC_AUDIO_PLL0, 159 + AT91_PMC_AUDIO_PLL_PMCEN, 0); 160 + } 161 + 162 + static unsigned long clk_audio_pll_fout(unsigned long parent_rate, 163 + unsigned long nd, unsigned long fracr) 164 + { 165 + unsigned long long fr = (unsigned long long)parent_rate * fracr; 166 + 167 + pr_debug("A PLL: %s, fr = %llu\n", __func__, fr); 168 + 169 + fr = DIV_ROUND_CLOSEST_ULL(fr, AUDIO_PLL_DIV_FRAC); 170 + 171 + pr_debug("A PLL: %s, fr = %llu\n", __func__, fr); 172 + 173 + return parent_rate * (nd + 1) + fr; 174 + } 175 + 176 + static unsigned long clk_audio_pll_frac_recalc_rate(struct clk_hw *hw, 177 + unsigned long parent_rate) 178 + { 179 + struct clk_audio_frac *frac = to_clk_audio_frac(hw); 180 + unsigned long fout; 181 + 182 + fout = clk_audio_pll_fout(parent_rate, frac->nd, frac->fracr); 183 + 184 + pr_debug("A PLL: %s, fout = %lu (nd = %u, fracr = %lu)\n", __func__, 185 + fout, frac->nd, (unsigned long)frac->fracr); 186 + 187 + return fout; 188 + } 189 + 190 + static unsigned long clk_audio_pll_pad_recalc_rate(struct clk_hw *hw, 191 + unsigned long parent_rate) 192 + { 193 + struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); 194 + unsigned long apad_rate = 0; 195 + 196 + if (apad_ck->qdaudio && apad_ck->div) 197 + apad_rate = parent_rate / (apad_ck->qdaudio * apad_ck->div); 198 + 199 + pr_debug("A PLL/PAD: %s, apad_rate = %lu (div = %u, qdaudio = %u)\n", 200 + __func__, apad_rate, apad_ck->div, apad_ck->qdaudio); 201 + 202 + return apad_rate; 203 + } 204 + 205 + static unsigned long clk_audio_pll_pmc_recalc_rate(struct clk_hw *hw, 206 + unsigned long parent_rate) 207 + { 208 + struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); 209 + unsigned long apmc_rate = 0; 210 + 211 + apmc_rate = parent_rate / (apmc_ck->qdpmc + 1); 212 + 213 + pr_debug("A PLL/PMC: %s, apmc_rate = %lu (qdpmc = %u)\n", __func__, 214 + apmc_rate, apmc_ck->qdpmc); 215 + 216 + return apmc_rate; 217 + } 218 + 219 + static int clk_audio_pll_frac_compute_frac(unsigned long rate, 220 + unsigned long parent_rate, 221 + unsigned long *nd, 222 + unsigned long *fracr) 223 + { 224 + unsigned long long tmp, rem; 225 + 226 + if (!rate) 227 + return -EINVAL; 228 + 229 + tmp = rate; 230 + rem = do_div(tmp, parent_rate); 231 + if (!tmp || tmp >= AUDIO_PLL_ND_MAX) 232 + return -EINVAL; 233 + 234 + *nd = tmp - 1; 235 + 236 + tmp = rem * AUDIO_PLL_DIV_FRAC; 237 + tmp = DIV_ROUND_CLOSEST_ULL(tmp, parent_rate); 238 + if (tmp > AT91_PMC_AUDIO_PLL_FRACR_MASK) 239 + return -EINVAL; 240 + 241 + /* we can cast here as we verified the bounds just above */ 242 + *fracr = (unsigned long)tmp; 243 + 244 + return 0; 245 + } 246 + 247 + static int clk_audio_pll_frac_determine_rate(struct clk_hw *hw, 248 + struct clk_rate_request *req) 249 + { 250 + unsigned long fracr, nd; 251 + int ret; 252 + 253 + pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, 254 + req->rate, req->best_parent_rate); 255 + 256 + req->rate = clamp(req->rate, AUDIO_PLL_FOUT_MIN, AUDIO_PLL_FOUT_MAX); 257 + 258 + req->min_rate = max(req->min_rate, AUDIO_PLL_FOUT_MIN); 259 + req->max_rate = min(req->max_rate, AUDIO_PLL_FOUT_MAX); 260 + 261 + ret = clk_audio_pll_frac_compute_frac(req->rate, req->best_parent_rate, 262 + &nd, &fracr); 263 + if (ret) 264 + return ret; 265 + 266 + req->rate = clk_audio_pll_fout(req->best_parent_rate, nd, fracr); 267 + 268 + req->best_parent_hw = clk_hw_get_parent(hw); 269 + 270 + pr_debug("A PLL: %s, best_rate = %lu (nd = %lu, fracr = %lu)\n", 271 + __func__, req->rate, nd, fracr); 272 + 273 + return 0; 274 + } 275 + 276 + static long clk_audio_pll_pad_round_rate(struct clk_hw *hw, unsigned long rate, 277 + unsigned long *parent_rate) 278 + { 279 + struct clk_hw *pclk = clk_hw_get_parent(hw); 280 + long best_rate = -EINVAL; 281 + unsigned long best_parent_rate; 282 + unsigned long tmp_qd; 283 + u32 div; 284 + long tmp_rate; 285 + int tmp_diff; 286 + int best_diff = -1; 287 + 288 + pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__, 289 + rate, *parent_rate); 290 + 291 + /* 292 + * Rate divisor is actually made of two different divisors, multiplied 293 + * between themselves before dividing the rate. 294 + * tmp_qd goes from 1 to 31 and div is either 2 or 3. 295 + * In order to avoid testing twice the rate divisor (e.g. divisor 12 can 296 + * be found with (tmp_qd, div) = (2, 6) or (3, 4)), we remove any loop 297 + * for a rate divisor when div is 2 and tmp_qd is a multiple of 3. 298 + * We cannot inverse it (condition div is 3 and tmp_qd is even) or we 299 + * would miss some rate divisor that aren't reachable with div being 2 300 + * (e.g. rate divisor 90 is made with div = 3 and tmp_qd = 30, thus 301 + * tmp_qd is even so we skip it because we think div 2 could make this 302 + * rate divisor which isn't possible since tmp_qd has to be <= 31). 303 + */ 304 + for (tmp_qd = 1; tmp_qd < AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX; tmp_qd++) 305 + for (div = 2; div <= 3; div++) { 306 + if (div == 2 && tmp_qd % 3 == 0) 307 + continue; 308 + 309 + best_parent_rate = clk_hw_round_rate(pclk, 310 + rate * tmp_qd * div); 311 + tmp_rate = best_parent_rate / (div * tmp_qd); 312 + tmp_diff = abs(rate - tmp_rate); 313 + 314 + if (best_diff < 0 || best_diff > tmp_diff) { 315 + *parent_rate = best_parent_rate; 316 + best_rate = tmp_rate; 317 + best_diff = tmp_diff; 318 + } 319 + } 320 + 321 + pr_debug("A PLL/PAD: %s, best_rate = %ld, best_parent_rate = %lu\n", 322 + __func__, best_rate, best_parent_rate); 323 + 324 + return best_rate; 325 + } 326 + 327 + static long clk_audio_pll_pmc_round_rate(struct clk_hw *hw, unsigned long rate, 328 + unsigned long *parent_rate) 329 + { 330 + struct clk_hw *pclk = clk_hw_get_parent(hw); 331 + long best_rate = -EINVAL; 332 + unsigned long best_parent_rate = 0; 333 + u32 tmp_qd = 0, div; 334 + long tmp_rate; 335 + int tmp_diff; 336 + int best_diff = -1; 337 + 338 + pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, 339 + rate, *parent_rate); 340 + 341 + for (div = 1; div <= AUDIO_PLL_QDPMC_MAX; div++) { 342 + best_parent_rate = clk_round_rate(pclk->clk, rate * div); 343 + tmp_rate = best_parent_rate / div; 344 + tmp_diff = abs(rate - tmp_rate); 345 + 346 + if (best_diff < 0 || best_diff > tmp_diff) { 347 + *parent_rate = best_parent_rate; 348 + best_rate = tmp_rate; 349 + best_diff = tmp_diff; 350 + tmp_qd = div; 351 + } 352 + } 353 + 354 + pr_debug("A PLL/PMC: %s, best_rate = %ld, best_parent_rate = %lu (qd = %d)\n", 355 + __func__, best_rate, *parent_rate, tmp_qd - 1); 356 + 357 + return best_rate; 358 + } 359 + 360 + static int clk_audio_pll_frac_set_rate(struct clk_hw *hw, unsigned long rate, 361 + unsigned long parent_rate) 362 + { 363 + struct clk_audio_frac *frac = to_clk_audio_frac(hw); 364 + unsigned long fracr, nd; 365 + int ret; 366 + 367 + pr_debug("A PLL: %s, rate = %lu (parent_rate = %lu)\n", __func__, rate, 368 + parent_rate); 369 + 370 + if (rate < AUDIO_PLL_FOUT_MIN || rate > AUDIO_PLL_FOUT_MAX) 371 + return -EINVAL; 372 + 373 + ret = clk_audio_pll_frac_compute_frac(rate, parent_rate, &nd, &fracr); 374 + if (ret) 375 + return ret; 376 + 377 + frac->nd = nd; 378 + frac->fracr = fracr; 379 + 380 + return 0; 381 + } 382 + 383 + static int clk_audio_pll_pad_set_rate(struct clk_hw *hw, unsigned long rate, 384 + unsigned long parent_rate) 385 + { 386 + struct clk_audio_pad *apad_ck = to_clk_audio_pad(hw); 387 + u8 tmp_div; 388 + 389 + pr_debug("A PLL/PAD: %s, rate = %lu (parent_rate = %lu)\n", __func__, 390 + rate, parent_rate); 391 + 392 + if (!rate) 393 + return -EINVAL; 394 + 395 + tmp_div = parent_rate / rate; 396 + if (tmp_div % 3 == 0) { 397 + apad_ck->qdaudio = tmp_div / 3; 398 + apad_ck->div = 3; 399 + } else { 400 + apad_ck->qdaudio = tmp_div / 2; 401 + apad_ck->div = 2; 402 + } 403 + 404 + return 0; 405 + } 406 + 407 + static int clk_audio_pll_pmc_set_rate(struct clk_hw *hw, unsigned long rate, 408 + unsigned long parent_rate) 409 + { 410 + struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw); 411 + 412 + if (!rate) 413 + return -EINVAL; 414 + 415 + pr_debug("A PLL/PMC: %s, rate = %lu (parent_rate = %lu)\n", __func__, 416 + rate, parent_rate); 417 + 418 + apmc_ck->qdpmc = parent_rate / rate - 1; 419 + 420 + return 0; 421 + } 422 + 423 + static const struct clk_ops audio_pll_frac_ops = { 424 + .enable = clk_audio_pll_frac_enable, 425 + .disable = clk_audio_pll_frac_disable, 426 + .recalc_rate = clk_audio_pll_frac_recalc_rate, 427 + .determine_rate = clk_audio_pll_frac_determine_rate, 428 + .set_rate = clk_audio_pll_frac_set_rate, 429 + }; 430 + 431 + static const struct clk_ops audio_pll_pad_ops = { 432 + .enable = clk_audio_pll_pad_enable, 433 + .disable = clk_audio_pll_pad_disable, 434 + .recalc_rate = clk_audio_pll_pad_recalc_rate, 435 + .round_rate = clk_audio_pll_pad_round_rate, 436 + .set_rate = clk_audio_pll_pad_set_rate, 437 + }; 438 + 439 + static const struct clk_ops audio_pll_pmc_ops = { 440 + .enable = clk_audio_pll_pmc_enable, 441 + .disable = clk_audio_pll_pmc_disable, 442 + .recalc_rate = clk_audio_pll_pmc_recalc_rate, 443 + .round_rate = clk_audio_pll_pmc_round_rate, 444 + .set_rate = clk_audio_pll_pmc_set_rate, 445 + }; 446 + 447 + static int of_sama5d2_clk_audio_pll_setup(struct device_node *np, 448 + struct clk_init_data *init, 449 + struct clk_hw *hw, 450 + struct regmap **clk_audio_regmap) 451 + { 452 + struct regmap *regmap; 453 + const char *parent_names[1]; 454 + int ret; 455 + 456 + regmap = syscon_node_to_regmap(of_get_parent(np)); 457 + if (IS_ERR(regmap)) 458 + return PTR_ERR(regmap); 459 + 460 + init->name = np->name; 461 + of_clk_parent_fill(np, parent_names, 1); 462 + init->parent_names = parent_names; 463 + init->num_parents = 1; 464 + 465 + hw->init = init; 466 + *clk_audio_regmap = regmap; 467 + 468 + ret = clk_hw_register(NULL, hw); 469 + if (ret) 470 + return ret; 471 + 472 + return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw); 473 + } 474 + 475 + static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) 476 + { 477 + struct clk_audio_frac *frac_ck; 478 + struct clk_init_data init = {}; 479 + 480 + frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL); 481 + if (!frac_ck) 482 + return; 483 + 484 + init.ops = &audio_pll_frac_ops; 485 + init.flags = CLK_SET_RATE_GATE; 486 + 487 + if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw, 488 + &frac_ck->regmap)) 489 + kfree(frac_ck); 490 + } 491 + 492 + static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np) 493 + { 494 + struct clk_audio_pad *apad_ck; 495 + struct clk_init_data init = {}; 496 + 497 + apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL); 498 + if (!apad_ck) 499 + return; 500 + 501 + init.ops = &audio_pll_pad_ops; 502 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 503 + CLK_SET_RATE_PARENT; 504 + 505 + if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw, 506 + &apad_ck->regmap)) 507 + kfree(apad_ck); 508 + } 509 + 510 + static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np) 511 + { 512 + struct clk_audio_pad *apmc_ck; 513 + struct clk_init_data init = {}; 514 + 515 + apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL); 516 + if (!apmc_ck) 517 + return; 518 + 519 + init.ops = &audio_pll_pmc_ops; 520 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 521 + CLK_SET_RATE_PARENT; 522 + 523 + if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw, 524 + &apmc_ck->regmap)) 525 + kfree(apmc_ck); 526 + } 527 + 528 + CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup, 529 + "atmel,sama5d2-clk-audio-pll-frac", 530 + of_sama5d2_clk_audio_pll_frac_setup); 531 + CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup, 532 + "atmel,sama5d2-clk-audio-pll-pad", 533 + of_sama5d2_clk_audio_pll_pad_setup); 534 + CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup, 535 + "atmel,sama5d2-clk-audio-pll-pmc", 536 + of_sama5d2_clk_audio_pll_pmc_setup);
+83 -20
drivers/clk/at91/clk-generated.c
··· 26 26 #define GENERATED_SOURCE_MAX 6 27 27 #define GENERATED_MAX_DIV 255 28 28 29 + #define GCK_ID_SSC0 43 30 + #define GCK_ID_SSC1 44 31 + #define GCK_ID_I2S0 54 32 + #define GCK_ID_I2S1 55 33 + #define GCK_ID_CLASSD 59 34 + #define GCK_INDEX_DT_AUDIO_PLL 5 35 + 29 36 struct clk_generated { 30 37 struct clk_hw hw; 31 38 struct regmap *regmap; ··· 41 34 u32 id; 42 35 u32 gckdiv; 43 36 u8 parent_id; 37 + bool audio_pll_allowed; 44 38 }; 45 39 46 40 #define to_clk_generated(hw) \ ··· 107 99 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); 108 100 } 109 101 102 + static void clk_generated_best_diff(struct clk_rate_request *req, 103 + struct clk_hw *parent, 104 + unsigned long parent_rate, u32 div, 105 + int *best_diff, long *best_rate) 106 + { 107 + unsigned long tmp_rate; 108 + int tmp_diff; 109 + 110 + if (!div) 111 + tmp_rate = parent_rate; 112 + else 113 + tmp_rate = parent_rate / div; 114 + tmp_diff = abs(req->rate - tmp_rate); 115 + 116 + if (*best_diff < 0 || *best_diff > tmp_diff) { 117 + *best_rate = tmp_rate; 118 + *best_diff = tmp_diff; 119 + req->best_parent_rate = parent_rate; 120 + req->best_parent_hw = parent; 121 + } 122 + } 123 + 110 124 static int clk_generated_determine_rate(struct clk_hw *hw, 111 125 struct clk_rate_request *req) 112 126 { 113 127 struct clk_generated *gck = to_clk_generated(hw); 114 128 struct clk_hw *parent = NULL; 129 + struct clk_rate_request req_parent = *req; 115 130 long best_rate = -EINVAL; 116 - unsigned long tmp_rate, min_rate; 131 + unsigned long min_rate, parent_rate; 117 132 int best_diff = -1; 118 - int tmp_diff; 119 133 int i; 134 + u32 div; 120 135 121 - for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 122 - u32 div; 123 - unsigned long parent_rate; 124 - 136 + for (i = 0; i < clk_hw_get_num_parents(hw) - 1; i++) { 125 137 parent = clk_hw_get_parent_by_index(hw, i); 126 138 if (!parent) 127 139 continue; ··· 152 124 (gck->range.max && min_rate > gck->range.max)) 153 125 continue; 154 126 155 - for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 156 - tmp_rate = DIV_ROUND_CLOSEST(parent_rate, div); 157 - tmp_diff = abs(req->rate - tmp_rate); 127 + div = DIV_ROUND_CLOSEST(parent_rate, req->rate); 158 128 159 - if (best_diff < 0 || best_diff > tmp_diff) { 160 - best_rate = tmp_rate; 161 - best_diff = tmp_diff; 162 - req->best_parent_rate = parent_rate; 163 - req->best_parent_hw = parent; 164 - } 165 - 166 - if (!best_diff || tmp_rate < req->rate) 167 - break; 168 - } 129 + clk_generated_best_diff(req, parent, parent_rate, div, 130 + &best_diff, &best_rate); 169 131 170 132 if (!best_diff) 171 133 break; 172 134 } 173 135 136 + /* 137 + * The audio_pll rate can be modified, unlike the five others clocks 138 + * that should never be altered. 139 + * The audio_pll can technically be used by multiple consumers. However, 140 + * with the rate locking, the first consumer to enable to clock will be 141 + * the one definitely setting the rate of the clock. 142 + * Since audio IPs are most likely to request the same rate, we enforce 143 + * that the only clks able to modify gck rate are those of audio IPs. 144 + */ 145 + 146 + if (!gck->audio_pll_allowed) 147 + goto end; 148 + 149 + parent = clk_hw_get_parent_by_index(hw, GCK_INDEX_DT_AUDIO_PLL); 150 + if (!parent) 151 + goto end; 152 + 153 + for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { 154 + req_parent.rate = req->rate * div; 155 + __clk_determine_rate(parent, &req_parent); 156 + clk_generated_best_diff(req, parent, req_parent.rate, div, 157 + &best_diff, &best_rate); 158 + 159 + if (!best_diff) 160 + break; 161 + } 162 + 163 + end: 174 164 pr_debug("GCLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 175 165 __func__, best_rate, 176 166 __clk_get_name((req->best_parent_hw)->clk), ··· 298 252 init.ops = &generated_ops; 299 253 init.parent_names = parent_names; 300 254 init.num_parents = num_parents; 301 - init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 255 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | 256 + CLK_SET_RATE_PARENT; 302 257 303 258 gck->id = id; 304 259 gck->hw.init = &init; ··· 331 284 struct device_node *gcknp; 332 285 struct clk_range range = CLK_RANGE(0, 0); 333 286 struct regmap *regmap; 287 + struct clk_generated *gck; 334 288 335 289 num_parents = of_clk_get_parent_count(np); 336 290 if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX) ··· 363 315 hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, 364 316 parent_names, num_parents, 365 317 id, &range); 318 + 319 + gck = to_clk_generated(hw); 320 + 321 + if (of_device_is_compatible(np, 322 + "atmel,sama5d2-clk-generated")) { 323 + if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 || 324 + gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 || 325 + gck->id == GCK_ID_CLASSD) 326 + gck->audio_pll_allowed = true; 327 + else 328 + gck->audio_pll_allowed = false; 329 + } else { 330 + gck->audio_pll_allowed = false; 331 + } 332 + 366 333 if (IS_ERR(hw)) 367 334 continue; 368 335
+1
drivers/clk/axs10x/Makefile
··· 1 1 obj-y += i2s_pll_clock.o 2 + obj-y += pll_clock.o
+346
drivers/clk/axs10x/pll_clock.c
··· 1 + /* 2 + * Synopsys AXS10X SDP Generic PLL clock driver 3 + * 4 + * Copyright (C) 2017 Synopsys 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + #include <linux/platform_device.h> 12 + #include <linux/module.h> 13 + #include <linux/clk-provider.h> 14 + #include <linux/delay.h> 15 + #include <linux/err.h> 16 + #include <linux/device.h> 17 + #include <linux/of_address.h> 18 + #include <linux/of_device.h> 19 + #include <linux/slab.h> 20 + #include <linux/of.h> 21 + 22 + /* PLL registers addresses */ 23 + #define PLL_REG_IDIV 0x0 24 + #define PLL_REG_FBDIV 0x4 25 + #define PLL_REG_ODIV 0x8 26 + 27 + /* 28 + * Bit fields of the PLL IDIV/FBDIV/ODIV registers: 29 + * ________________________________________________________________________ 30 + * |31 15| 14 | 13 | 12 |11 6|5 0| 31 + * |-------RESRVED------|-NOUPDATE-|-BYPASS-|-EDGE-|--HIGHTIME--|--LOWTIME--| 32 + * |____________________|__________|________|______|____________|___________| 33 + * 34 + * Following macros determine the way of access to these registers 35 + * They should be set up only using the macros. 36 + * reg should be an u32 variable. 37 + */ 38 + 39 + #define PLL_REG_GET_LOW(reg) \ 40 + (((reg) & (0x3F << 0)) >> 0) 41 + #define PLL_REG_GET_HIGH(reg) \ 42 + (((reg) & (0x3F << 6)) >> 6) 43 + #define PLL_REG_GET_EDGE(reg) \ 44 + (((reg) & (BIT(12))) ? 1 : 0) 45 + #define PLL_REG_GET_BYPASS(reg) \ 46 + (((reg) & (BIT(13))) ? 1 : 0) 47 + #define PLL_REG_GET_NOUPD(reg) \ 48 + (((reg) & (BIT(14))) ? 1 : 0) 49 + #define PLL_REG_GET_PAD(reg) \ 50 + (((reg) & (0x1FFFF << 15)) >> 15) 51 + 52 + #define PLL_REG_SET_LOW(reg, value) \ 53 + { reg |= (((value) & 0x3F) << 0); } 54 + #define PLL_REG_SET_HIGH(reg, value) \ 55 + { reg |= (((value) & 0x3F) << 6); } 56 + #define PLL_REG_SET_EDGE(reg, value) \ 57 + { reg |= (((value) & 0x01) << 12); } 58 + #define PLL_REG_SET_BYPASS(reg, value) \ 59 + { reg |= (((value) & 0x01) << 13); } 60 + #define PLL_REG_SET_NOUPD(reg, value) \ 61 + { reg |= (((value) & 0x01) << 14); } 62 + #define PLL_REG_SET_PAD(reg, value) \ 63 + { reg |= (((value) & 0x1FFFF) << 15); } 64 + 65 + #define PLL_LOCK BIT(0) 66 + #define PLL_ERROR BIT(1) 67 + #define PLL_MAX_LOCK_TIME 100 /* 100 us */ 68 + 69 + struct axs10x_pll_cfg { 70 + u32 rate; 71 + u32 idiv; 72 + u32 fbdiv; 73 + u32 odiv; 74 + }; 75 + 76 + static const struct axs10x_pll_cfg arc_pll_cfg[] = { 77 + { 33333333, 1, 1, 1 }, 78 + { 50000000, 1, 30, 20 }, 79 + { 75000000, 2, 45, 10 }, 80 + { 90000000, 2, 54, 10 }, 81 + { 100000000, 1, 30, 10 }, 82 + { 125000000, 2, 45, 6 }, 83 + {} 84 + }; 85 + 86 + static const struct axs10x_pll_cfg pgu_pll_cfg[] = { 87 + { 25200000, 1, 84, 90 }, 88 + { 50000000, 1, 100, 54 }, 89 + { 74250000, 1, 44, 16 }, 90 + {} 91 + }; 92 + 93 + struct axs10x_pll_clk { 94 + struct clk_hw hw; 95 + void __iomem *base; 96 + void __iomem *lock; 97 + const struct axs10x_pll_cfg *pll_cfg; 98 + struct device *dev; 99 + }; 100 + 101 + static inline void axs10x_pll_write(struct axs10x_pll_clk *clk, u32 reg, 102 + u32 val) 103 + { 104 + iowrite32(val, clk->base + reg); 105 + } 106 + 107 + static inline u32 axs10x_pll_read(struct axs10x_pll_clk *clk, u32 reg) 108 + { 109 + return ioread32(clk->base + reg); 110 + } 111 + 112 + static inline struct axs10x_pll_clk *to_axs10x_pll_clk(struct clk_hw *hw) 113 + { 114 + return container_of(hw, struct axs10x_pll_clk, hw); 115 + } 116 + 117 + static inline u32 axs10x_div_get_value(u32 reg) 118 + { 119 + if (PLL_REG_GET_BYPASS(reg)) 120 + return 1; 121 + 122 + return PLL_REG_GET_HIGH(reg) + PLL_REG_GET_LOW(reg); 123 + } 124 + 125 + static inline u32 axs10x_encode_div(unsigned int id, int upd) 126 + { 127 + u32 div = 0; 128 + 129 + PLL_REG_SET_LOW(div, (id % 2 == 0) ? id >> 1 : (id >> 1) + 1); 130 + PLL_REG_SET_HIGH(div, id >> 1); 131 + PLL_REG_SET_EDGE(div, id % 2); 132 + PLL_REG_SET_BYPASS(div, id == 1 ? 1 : 0); 133 + PLL_REG_SET_NOUPD(div, upd == 0 ? 1 : 0); 134 + 135 + return div; 136 + } 137 + 138 + static unsigned long axs10x_pll_recalc_rate(struct clk_hw *hw, 139 + unsigned long parent_rate) 140 + { 141 + u64 rate; 142 + u32 idiv, fbdiv, odiv; 143 + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); 144 + 145 + idiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_IDIV)); 146 + fbdiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_FBDIV)); 147 + odiv = axs10x_div_get_value(axs10x_pll_read(clk, PLL_REG_ODIV)); 148 + 149 + rate = (u64)parent_rate * fbdiv; 150 + do_div(rate, idiv * odiv); 151 + 152 + return rate; 153 + } 154 + 155 + static long axs10x_pll_round_rate(struct clk_hw *hw, unsigned long rate, 156 + unsigned long *prate) 157 + { 158 + int i; 159 + long best_rate; 160 + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); 161 + const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; 162 + 163 + if (pll_cfg[0].rate == 0) 164 + return -EINVAL; 165 + 166 + best_rate = pll_cfg[0].rate; 167 + 168 + for (i = 1; pll_cfg[i].rate != 0; i++) { 169 + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) 170 + best_rate = pll_cfg[i].rate; 171 + } 172 + 173 + return best_rate; 174 + } 175 + 176 + static int axs10x_pll_set_rate(struct clk_hw *hw, unsigned long rate, 177 + unsigned long parent_rate) 178 + { 179 + int i; 180 + struct axs10x_pll_clk *clk = to_axs10x_pll_clk(hw); 181 + const struct axs10x_pll_cfg *pll_cfg = clk->pll_cfg; 182 + 183 + for (i = 0; pll_cfg[i].rate != 0; i++) { 184 + if (pll_cfg[i].rate == rate) { 185 + axs10x_pll_write(clk, PLL_REG_IDIV, 186 + axs10x_encode_div(pll_cfg[i].idiv, 0)); 187 + axs10x_pll_write(clk, PLL_REG_FBDIV, 188 + axs10x_encode_div(pll_cfg[i].fbdiv, 0)); 189 + axs10x_pll_write(clk, PLL_REG_ODIV, 190 + axs10x_encode_div(pll_cfg[i].odiv, 1)); 191 + 192 + /* 193 + * Wait until CGU relocks and check error status. 194 + * If after timeout CGU is unlocked yet return error 195 + */ 196 + udelay(PLL_MAX_LOCK_TIME); 197 + if (!(ioread32(clk->lock) & PLL_LOCK)) 198 + return -ETIMEDOUT; 199 + 200 + if (ioread32(clk->lock) & PLL_ERROR) 201 + return -EINVAL; 202 + 203 + return 0; 204 + } 205 + } 206 + 207 + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, 208 + parent_rate); 209 + return -EINVAL; 210 + } 211 + 212 + static const struct clk_ops axs10x_pll_ops = { 213 + .recalc_rate = axs10x_pll_recalc_rate, 214 + .round_rate = axs10x_pll_round_rate, 215 + .set_rate = axs10x_pll_set_rate, 216 + }; 217 + 218 + static int axs10x_pll_clk_probe(struct platform_device *pdev) 219 + { 220 + struct device *dev = &pdev->dev; 221 + const char *parent_name; 222 + struct axs10x_pll_clk *pll_clk; 223 + struct resource *mem; 224 + struct clk_init_data init = { }; 225 + int ret; 226 + 227 + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); 228 + if (!pll_clk) 229 + return -ENOMEM; 230 + 231 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 232 + pll_clk->base = devm_ioremap_resource(dev, mem); 233 + if (IS_ERR(pll_clk->base)) 234 + return PTR_ERR(pll_clk->base); 235 + 236 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); 237 + pll_clk->lock = devm_ioremap_resource(dev, mem); 238 + if (IS_ERR(pll_clk->lock)) 239 + return PTR_ERR(pll_clk->lock); 240 + 241 + init.name = dev->of_node->name; 242 + init.ops = &axs10x_pll_ops; 243 + parent_name = of_clk_get_parent_name(dev->of_node, 0); 244 + init.parent_names = &parent_name; 245 + init.num_parents = 1; 246 + pll_clk->hw.init = &init; 247 + pll_clk->dev = dev; 248 + pll_clk->pll_cfg = of_device_get_match_data(dev); 249 + 250 + if (!pll_clk->pll_cfg) { 251 + dev_err(dev, "No OF match data provided\n"); 252 + return -EINVAL; 253 + } 254 + 255 + ret = devm_clk_hw_register(dev, &pll_clk->hw); 256 + if (ret) { 257 + dev_err(dev, "failed to register %s clock\n", init.name); 258 + return ret; 259 + } 260 + 261 + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, 262 + &pll_clk->hw); 263 + } 264 + 265 + static int axs10x_pll_clk_remove(struct platform_device *pdev) 266 + { 267 + of_clk_del_provider(pdev->dev.of_node); 268 + return 0; 269 + } 270 + 271 + static void __init of_axs10x_pll_clk_setup(struct device_node *node) 272 + { 273 + const char *parent_name; 274 + struct axs10x_pll_clk *pll_clk; 275 + struct clk_init_data init = { }; 276 + int ret; 277 + 278 + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); 279 + if (!pll_clk) 280 + return; 281 + 282 + pll_clk->base = of_iomap(node, 0); 283 + if (!pll_clk->base) { 284 + pr_err("failed to map pll div registers\n"); 285 + goto err_free_pll_clk; 286 + } 287 + 288 + pll_clk->lock = of_iomap(node, 1); 289 + if (!pll_clk->lock) { 290 + pr_err("failed to map pll lock register\n"); 291 + goto err_unmap_base; 292 + } 293 + 294 + init.name = node->name; 295 + init.ops = &axs10x_pll_ops; 296 + parent_name = of_clk_get_parent_name(node, 0); 297 + init.parent_names = &parent_name; 298 + init.num_parents = parent_name ? 1 : 0; 299 + pll_clk->hw.init = &init; 300 + pll_clk->pll_cfg = arc_pll_cfg; 301 + 302 + ret = clk_hw_register(NULL, &pll_clk->hw); 303 + if (ret) { 304 + pr_err("failed to register %s clock\n", node->name); 305 + goto err_unmap_lock; 306 + } 307 + 308 + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); 309 + if (ret) { 310 + pr_err("failed to add hw provider for %s clock\n", node->name); 311 + goto err_unregister_clk; 312 + } 313 + 314 + return; 315 + 316 + err_unregister_clk: 317 + clk_hw_unregister(&pll_clk->hw); 318 + err_unmap_lock: 319 + iounmap(pll_clk->lock); 320 + err_unmap_base: 321 + iounmap(pll_clk->base); 322 + err_free_pll_clk: 323 + kfree(pll_clk); 324 + } 325 + CLK_OF_DECLARE(axs10x_pll_clock, "snps,axs10x-arc-pll-clock", 326 + of_axs10x_pll_clk_setup); 327 + 328 + static const struct of_device_id axs10x_pll_clk_id[] = { 329 + { .compatible = "snps,axs10x-pgu-pll-clock", .data = &pgu_pll_cfg}, 330 + { } 331 + }; 332 + MODULE_DEVICE_TABLE(of, axs10x_pll_clk_id); 333 + 334 + static struct platform_driver axs10x_pll_clk_driver = { 335 + .driver = { 336 + .name = "axs10x-pll-clock", 337 + .of_match_table = axs10x_pll_clk_id, 338 + }, 339 + .probe = axs10x_pll_clk_probe, 340 + .remove = axs10x_pll_clk_remove, 341 + }; 342 + builtin_platform_driver(axs10x_pll_clk_driver); 343 + 344 + MODULE_AUTHOR("Vlad Zakharov <vzakhar@synopsys.com>"); 345 + MODULE_DESCRIPTION("Synopsys AXS10X SDP Generic PLL Clock Driver"); 346 + MODULE_LICENSE("GPL v2");
+1 -2
drivers/clk/berlin/bg2.c
··· 679 679 if (!IS_ERR(hws[n])) 680 680 continue; 681 681 682 - pr_err("%s: Unable to register leaf clock %d\n", 683 - np->full_name, n); 682 + pr_err("%pOF: Unable to register leaf clock %d\n", np, n); 684 683 goto bg2_fail; 685 684 } 686 685
+3 -4
drivers/clk/berlin/bg2q.c
··· 304 304 305 305 gbase = of_iomap(parent_np, 0); 306 306 if (!gbase) { 307 - pr_err("%s: Unable to map global base\n", np->full_name); 307 + pr_err("%pOF: Unable to map global base\n", np); 308 308 return; 309 309 } 310 310 311 311 /* BG2Q CPU PLL is not part of global registers */ 312 312 cpupll_base = of_iomap(parent_np, 1); 313 313 if (!cpupll_base) { 314 - pr_err("%s: Unable to map cpupll base\n", np->full_name); 314 + pr_err("%pOF: Unable to map cpupll base\n", np); 315 315 iounmap(gbase); 316 316 return; 317 317 } ··· 376 376 if (!IS_ERR(hws[n])) 377 377 continue; 378 378 379 - pr_err("%s: Unable to register leaf clock %d\n", 380 - np->full_name, n); 379 + pr_err("%pOF: Unable to register leaf clock %d\n", np, n); 381 380 goto bg2q_fail; 382 381 } 383 382
+2 -2
drivers/clk/clk-asm9260.c
··· 338 338 if (!IS_ERR(hws[n])) 339 339 continue; 340 340 341 - pr_err("%s: Unable to register leaf clock %d\n", 342 - np->full_name, n); 341 + pr_err("%pOF: Unable to register leaf clock %d\n", 342 + np, n); 343 343 goto fail; 344 344 } 345 345
+8 -8
drivers/clk/clk-conf.c
··· 23 23 num_parents = of_count_phandle_with_args(node, "assigned-clock-parents", 24 24 "#clock-cells"); 25 25 if (num_parents == -EINVAL) 26 - pr_err("clk: invalid value of clock-parents property at %s\n", 27 - node->full_name); 26 + pr_err("clk: invalid value of clock-parents property at %pOF\n", 27 + node); 28 28 29 29 for (index = 0; index < num_parents; index++) { 30 30 rc = of_parse_phandle_with_args(node, "assigned-clock-parents", ··· 41 41 pclk = of_clk_get_from_provider(&clkspec); 42 42 if (IS_ERR(pclk)) { 43 43 if (PTR_ERR(pclk) != -EPROBE_DEFER) 44 - pr_warn("clk: couldn't get parent clock %d for %s\n", 45 - index, node->full_name); 44 + pr_warn("clk: couldn't get parent clock %d for %pOF\n", 45 + index, node); 46 46 return PTR_ERR(pclk); 47 47 } 48 48 ··· 57 57 clk = of_clk_get_from_provider(&clkspec); 58 58 if (IS_ERR(clk)) { 59 59 if (PTR_ERR(clk) != -EPROBE_DEFER) 60 - pr_warn("clk: couldn't get assigned clock %d for %s\n", 61 - index, node->full_name); 60 + pr_warn("clk: couldn't get assigned clock %d for %pOF\n", 61 + index, node); 62 62 rc = PTR_ERR(clk); 63 63 goto err; 64 64 } ··· 102 102 clk = of_clk_get_from_provider(&clkspec); 103 103 if (IS_ERR(clk)) { 104 104 if (PTR_ERR(clk) != -EPROBE_DEFER) 105 - pr_warn("clk: couldn't get clock %d for %s\n", 106 - index, node->full_name); 105 + pr_warn("clk: couldn't get clock %d for %pOF\n", 106 + index, node); 107 107 return PTR_ERR(clk); 108 108 } 109 109
+10 -4
drivers/clk/clk-cs2000-cp.c
··· 343 343 return __cs2000_set_rate(priv, ch, rate, parent_rate); 344 344 } 345 345 346 + static int cs2000_set_saved_rate(struct cs2000_priv *priv) 347 + { 348 + int ch = 0; /* it uses ch0 only at this point */ 349 + 350 + return __cs2000_set_rate(priv, ch, 351 + priv->saved_rate, 352 + priv->saved_parent_rate); 353 + } 354 + 346 355 static int cs2000_enable(struct clk_hw *hw) 347 356 { 348 357 struct cs2000_priv *priv = hw_to_priv(hw); ··· 544 535 static int cs2000_resume(struct device *dev) 545 536 { 546 537 struct cs2000_priv *priv = dev_get_drvdata(dev); 547 - int ch = 0; /* it uses ch0 only at this point */ 548 538 549 - return __cs2000_set_rate(priv, ch, 550 - priv->saved_rate, 551 - priv->saved_parent_rate); 539 + return cs2000_set_saved_rate(priv); 552 540 } 553 541 554 542 static const struct dev_pm_ops cs2000_pm_ops = {
+4 -2
drivers/clk/clk-divider.c
··· 385 385 unsigned long parent_rate) 386 386 { 387 387 struct clk_divider *divider = to_clk_divider(hw); 388 - unsigned int value; 388 + int value; 389 389 unsigned long flags = 0; 390 390 u32 val; 391 391 392 392 value = divider_get_val(rate, parent_rate, divider->table, 393 393 divider->width, divider->flags); 394 + if (value < 0) 395 + return value; 394 396 395 397 if (divider->lock) 396 398 spin_lock_irqsave(divider->lock, flags); ··· 405 403 val = clk_readl(divider->reg); 406 404 val &= ~(div_mask(divider->width) << divider->shift); 407 405 } 408 - val |= value << divider->shift; 406 + val |= (u32)value << divider->shift; 409 407 clk_writel(val, divider->reg); 410 408 411 409 if (divider->lock)
+20 -8
drivers/clk/clk-fractional-divider.c
··· 49 49 return ret; 50 50 } 51 51 52 - static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, 53 - unsigned long *parent_rate) 52 + static void clk_fd_general_approximation(struct clk_hw *hw, unsigned long rate, 53 + unsigned long *parent_rate, 54 + unsigned long *m, unsigned long *n) 54 55 { 55 56 struct clk_fractional_divider *fd = to_clk_fd(hw); 56 57 unsigned long scale; 57 - unsigned long m, n; 58 - u64 ret; 59 - 60 - if (!rate || rate >= *parent_rate) 61 - return *parent_rate; 62 58 63 59 /* 64 60 * Get rate closer to *parent_rate to guarantee there is no overflow ··· 67 71 68 72 rational_best_approximation(rate, *parent_rate, 69 73 GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), 70 - &m, &n); 74 + m, n); 75 + } 76 + 77 + static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate, 78 + unsigned long *parent_rate) 79 + { 80 + struct clk_fractional_divider *fd = to_clk_fd(hw); 81 + unsigned long m, n; 82 + u64 ret; 83 + 84 + if (!rate || rate >= *parent_rate) 85 + return *parent_rate; 86 + 87 + if (fd->approximation) 88 + fd->approximation(hw, rate, parent_rate, &m, &n); 89 + else 90 + clk_fd_general_approximation(hw, rate, parent_rate, &m, &n); 71 91 72 92 ret = (u64)*parent_rate * m; 73 93 do_div(ret, n);
+2 -1
drivers/clk/clk-gate.c
··· 86 86 clk_gate_endisable(hw, 0); 87 87 } 88 88 89 - static int clk_gate_is_enabled(struct clk_hw *hw) 89 + int clk_gate_is_enabled(struct clk_hw *hw) 90 90 { 91 91 u32 reg; 92 92 struct clk_gate *gate = to_clk_gate(hw); ··· 101 101 102 102 return reg ? 1 : 0; 103 103 } 104 + EXPORT_SYMBOL_GPL(clk_gate_is_enabled); 104 105 105 106 const struct clk_ops clk_gate_ops = { 106 107 .enable = clk_gate_enable,
-7
drivers/clk/clk-gemini.c
··· 37 37 38 38 #define GEMINI_GLOBAL_MISC_CONTROL 0x30 39 39 #define PCI_CLK_66MHZ BIT(18) 40 - #define PCI_CLK_OE BIT(17) 41 40 42 41 #define GEMINI_GLOBAL_CLOCK_CONTROL 0x34 43 42 #define PCI_CLKRUN_EN BIT(16) ··· 158 159 159 160 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, 160 161 0, PCI_CLKRUN_EN); 161 - regmap_update_bits(pciclk->map, 162 - GEMINI_GLOBAL_MISC_CONTROL, 163 - 0, PCI_CLK_OE); 164 162 return 0; 165 163 } 166 164 ··· 165 169 { 166 170 struct clk_gemini_pci *pciclk = to_pciclk(hw); 167 171 168 - regmap_update_bits(pciclk->map, 169 - GEMINI_GLOBAL_MISC_CONTROL, 170 - PCI_CLK_OE, 0); 171 172 regmap_update_bits(pciclk->map, GEMINI_GLOBAL_CLOCK_CONTROL, 172 173 PCI_CLKRUN_EN, 0); 173 174 }
+431
drivers/clk/clk-hsdk-pll.c
··· 1 + /* 2 + * Synopsys HSDK SDP Generic PLL clock driver 3 + * 4 + * Copyright (C) 2017 Synopsys 5 + * 6 + * This file is licensed under the terms of the GNU General Public 7 + * License version 2. This program is licensed "as is" without any 8 + * warranty of any kind, whether express or implied. 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/delay.h> 13 + #include <linux/device.h> 14 + #include <linux/err.h> 15 + #include <linux/of.h> 16 + #include <linux/of_address.h> 17 + #include <linux/of_device.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/slab.h> 20 + 21 + #define CGU_PLL_CTRL 0x000 /* ARC PLL control register */ 22 + #define CGU_PLL_STATUS 0x004 /* ARC PLL status register */ 23 + #define CGU_PLL_FMEAS 0x008 /* ARC PLL frequency measurement register */ 24 + #define CGU_PLL_MON 0x00C /* ARC PLL monitor register */ 25 + 26 + #define CGU_PLL_CTRL_ODIV_SHIFT 2 27 + #define CGU_PLL_CTRL_IDIV_SHIFT 4 28 + #define CGU_PLL_CTRL_FBDIV_SHIFT 9 29 + #define CGU_PLL_CTRL_BAND_SHIFT 20 30 + 31 + #define CGU_PLL_CTRL_ODIV_MASK GENMASK(3, CGU_PLL_CTRL_ODIV_SHIFT) 32 + #define CGU_PLL_CTRL_IDIV_MASK GENMASK(8, CGU_PLL_CTRL_IDIV_SHIFT) 33 + #define CGU_PLL_CTRL_FBDIV_MASK GENMASK(15, CGU_PLL_CTRL_FBDIV_SHIFT) 34 + 35 + #define CGU_PLL_CTRL_PD BIT(0) 36 + #define CGU_PLL_CTRL_BYPASS BIT(1) 37 + 38 + #define CGU_PLL_STATUS_LOCK BIT(0) 39 + #define CGU_PLL_STATUS_ERR BIT(1) 40 + 41 + #define HSDK_PLL_MAX_LOCK_TIME 100 /* 100 us */ 42 + 43 + #define CGU_PLL_SOURCE_MAX 1 44 + 45 + #define CORE_IF_CLK_THRESHOLD_HZ 500000000 46 + #define CREG_CORE_IF_CLK_DIV_1 0x0 47 + #define CREG_CORE_IF_CLK_DIV_2 0x1 48 + 49 + struct hsdk_pll_cfg { 50 + u32 rate; 51 + u32 idiv; 52 + u32 fbdiv; 53 + u32 odiv; 54 + u32 band; 55 + }; 56 + 57 + static const struct hsdk_pll_cfg asdt_pll_cfg[] = { 58 + { 100000000, 0, 11, 3, 0 }, 59 + { 133000000, 0, 15, 3, 0 }, 60 + { 200000000, 1, 47, 3, 0 }, 61 + { 233000000, 1, 27, 2, 0 }, 62 + { 300000000, 1, 35, 2, 0 }, 63 + { 333000000, 1, 39, 2, 0 }, 64 + { 400000000, 1, 47, 2, 0 }, 65 + { 500000000, 0, 14, 1, 0 }, 66 + { 600000000, 0, 17, 1, 0 }, 67 + { 700000000, 0, 20, 1, 0 }, 68 + { 800000000, 0, 23, 1, 0 }, 69 + { 900000000, 1, 26, 0, 0 }, 70 + { 1000000000, 1, 29, 0, 0 }, 71 + { 1100000000, 1, 32, 0, 0 }, 72 + { 1200000000, 1, 35, 0, 0 }, 73 + { 1300000000, 1, 38, 0, 0 }, 74 + { 1400000000, 1, 41, 0, 0 }, 75 + { 1500000000, 1, 44, 0, 0 }, 76 + { 1600000000, 1, 47, 0, 0 }, 77 + {} 78 + }; 79 + 80 + static const struct hsdk_pll_cfg hdmi_pll_cfg[] = { 81 + { 297000000, 0, 21, 2, 0 }, 82 + { 540000000, 0, 19, 1, 0 }, 83 + { 594000000, 0, 21, 1, 0 }, 84 + {} 85 + }; 86 + 87 + struct hsdk_pll_clk { 88 + struct clk_hw hw; 89 + void __iomem *regs; 90 + void __iomem *spec_regs; 91 + const struct hsdk_pll_devdata *pll_devdata; 92 + struct device *dev; 93 + }; 94 + 95 + struct hsdk_pll_devdata { 96 + const struct hsdk_pll_cfg *pll_cfg; 97 + int (*update_rate)(struct hsdk_pll_clk *clk, unsigned long rate, 98 + const struct hsdk_pll_cfg *cfg); 99 + }; 100 + 101 + static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *, unsigned long, 102 + const struct hsdk_pll_cfg *); 103 + static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *, unsigned long, 104 + const struct hsdk_pll_cfg *); 105 + 106 + static const struct hsdk_pll_devdata core_pll_devdata = { 107 + .pll_cfg = asdt_pll_cfg, 108 + .update_rate = hsdk_pll_core_update_rate, 109 + }; 110 + 111 + static const struct hsdk_pll_devdata sdt_pll_devdata = { 112 + .pll_cfg = asdt_pll_cfg, 113 + .update_rate = hsdk_pll_comm_update_rate, 114 + }; 115 + 116 + static const struct hsdk_pll_devdata hdmi_pll_devdata = { 117 + .pll_cfg = hdmi_pll_cfg, 118 + .update_rate = hsdk_pll_comm_update_rate, 119 + }; 120 + 121 + static inline void hsdk_pll_write(struct hsdk_pll_clk *clk, u32 reg, u32 val) 122 + { 123 + iowrite32(val, clk->regs + reg); 124 + } 125 + 126 + static inline u32 hsdk_pll_read(struct hsdk_pll_clk *clk, u32 reg) 127 + { 128 + return ioread32(clk->regs + reg); 129 + } 130 + 131 + static inline void hsdk_pll_set_cfg(struct hsdk_pll_clk *clk, 132 + const struct hsdk_pll_cfg *cfg) 133 + { 134 + u32 val = 0; 135 + 136 + /* Powerdown and Bypass bits should be cleared */ 137 + val |= cfg->idiv << CGU_PLL_CTRL_IDIV_SHIFT; 138 + val |= cfg->fbdiv << CGU_PLL_CTRL_FBDIV_SHIFT; 139 + val |= cfg->odiv << CGU_PLL_CTRL_ODIV_SHIFT; 140 + val |= cfg->band << CGU_PLL_CTRL_BAND_SHIFT; 141 + 142 + dev_dbg(clk->dev, "write configurarion: %#x\n", val); 143 + 144 + hsdk_pll_write(clk, CGU_PLL_CTRL, val); 145 + } 146 + 147 + static inline bool hsdk_pll_is_locked(struct hsdk_pll_clk *clk) 148 + { 149 + return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_LOCK); 150 + } 151 + 152 + static inline bool hsdk_pll_is_err(struct hsdk_pll_clk *clk) 153 + { 154 + return !!(hsdk_pll_read(clk, CGU_PLL_STATUS) & CGU_PLL_STATUS_ERR); 155 + } 156 + 157 + static inline struct hsdk_pll_clk *to_hsdk_pll_clk(struct clk_hw *hw) 158 + { 159 + return container_of(hw, struct hsdk_pll_clk, hw); 160 + } 161 + 162 + static unsigned long hsdk_pll_recalc_rate(struct clk_hw *hw, 163 + unsigned long parent_rate) 164 + { 165 + u32 val; 166 + u64 rate; 167 + u32 idiv, fbdiv, odiv; 168 + struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); 169 + 170 + val = hsdk_pll_read(clk, CGU_PLL_CTRL); 171 + 172 + dev_dbg(clk->dev, "current configurarion: %#x\n", val); 173 + 174 + /* Check if PLL is disabled */ 175 + if (val & CGU_PLL_CTRL_PD) 176 + return 0; 177 + 178 + /* Check if PLL is bypassed */ 179 + if (val & CGU_PLL_CTRL_BYPASS) 180 + return parent_rate; 181 + 182 + /* input divider = reg.idiv + 1 */ 183 + idiv = 1 + ((val & CGU_PLL_CTRL_IDIV_MASK) >> CGU_PLL_CTRL_IDIV_SHIFT); 184 + /* fb divider = 2*(reg.fbdiv + 1) */ 185 + fbdiv = 2 * (1 + ((val & CGU_PLL_CTRL_FBDIV_MASK) >> CGU_PLL_CTRL_FBDIV_SHIFT)); 186 + /* output divider = 2^(reg.odiv) */ 187 + odiv = 1 << ((val & CGU_PLL_CTRL_ODIV_MASK) >> CGU_PLL_CTRL_ODIV_SHIFT); 188 + 189 + rate = (u64)parent_rate * fbdiv; 190 + do_div(rate, idiv * odiv); 191 + 192 + return rate; 193 + } 194 + 195 + static long hsdk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 196 + unsigned long *prate) 197 + { 198 + int i; 199 + unsigned long best_rate; 200 + struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); 201 + const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg; 202 + 203 + if (pll_cfg[0].rate == 0) 204 + return -EINVAL; 205 + 206 + best_rate = pll_cfg[0].rate; 207 + 208 + for (i = 1; pll_cfg[i].rate != 0; i++) { 209 + if (abs(rate - pll_cfg[i].rate) < abs(rate - best_rate)) 210 + best_rate = pll_cfg[i].rate; 211 + } 212 + 213 + dev_dbg(clk->dev, "chosen best rate: %lu\n", best_rate); 214 + 215 + return best_rate; 216 + } 217 + 218 + static int hsdk_pll_comm_update_rate(struct hsdk_pll_clk *clk, 219 + unsigned long rate, 220 + const struct hsdk_pll_cfg *cfg) 221 + { 222 + hsdk_pll_set_cfg(clk, cfg); 223 + 224 + /* 225 + * Wait until CGU relocks and check error status. 226 + * If after timeout CGU is unlocked yet return error. 227 + */ 228 + udelay(HSDK_PLL_MAX_LOCK_TIME); 229 + if (!hsdk_pll_is_locked(clk)) 230 + return -ETIMEDOUT; 231 + 232 + if (hsdk_pll_is_err(clk)) 233 + return -EINVAL; 234 + 235 + return 0; 236 + } 237 + 238 + static int hsdk_pll_core_update_rate(struct hsdk_pll_clk *clk, 239 + unsigned long rate, 240 + const struct hsdk_pll_cfg *cfg) 241 + { 242 + /* 243 + * When core clock exceeds 500MHz, the divider for the interface 244 + * clock must be programmed to div-by-2. 245 + */ 246 + if (rate > CORE_IF_CLK_THRESHOLD_HZ) 247 + iowrite32(CREG_CORE_IF_CLK_DIV_2, clk->spec_regs); 248 + 249 + hsdk_pll_set_cfg(clk, cfg); 250 + 251 + /* 252 + * Wait until CGU relocks and check error status. 253 + * If after timeout CGU is unlocked yet return error. 254 + */ 255 + udelay(HSDK_PLL_MAX_LOCK_TIME); 256 + if (!hsdk_pll_is_locked(clk)) 257 + return -ETIMEDOUT; 258 + 259 + if (hsdk_pll_is_err(clk)) 260 + return -EINVAL; 261 + 262 + /* 263 + * Program divider to div-by-1 if we succesfuly set core clock below 264 + * 500MHz threshold. 265 + */ 266 + if (rate <= CORE_IF_CLK_THRESHOLD_HZ) 267 + iowrite32(CREG_CORE_IF_CLK_DIV_1, clk->spec_regs); 268 + 269 + return 0; 270 + } 271 + 272 + static int hsdk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 273 + unsigned long parent_rate) 274 + { 275 + int i; 276 + struct hsdk_pll_clk *clk = to_hsdk_pll_clk(hw); 277 + const struct hsdk_pll_cfg *pll_cfg = clk->pll_devdata->pll_cfg; 278 + 279 + for (i = 0; pll_cfg[i].rate != 0; i++) { 280 + if (pll_cfg[i].rate == rate) { 281 + return clk->pll_devdata->update_rate(clk, rate, 282 + &pll_cfg[i]); 283 + } 284 + } 285 + 286 + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, 287 + parent_rate); 288 + 289 + return -EINVAL; 290 + } 291 + 292 + static const struct clk_ops hsdk_pll_ops = { 293 + .recalc_rate = hsdk_pll_recalc_rate, 294 + .round_rate = hsdk_pll_round_rate, 295 + .set_rate = hsdk_pll_set_rate, 296 + }; 297 + 298 + static int hsdk_pll_clk_probe(struct platform_device *pdev) 299 + { 300 + int ret; 301 + struct resource *mem; 302 + const char *parent_name; 303 + unsigned int num_parents; 304 + struct hsdk_pll_clk *pll_clk; 305 + struct clk_init_data init = { }; 306 + struct device *dev = &pdev->dev; 307 + 308 + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); 309 + if (!pll_clk) 310 + return -ENOMEM; 311 + 312 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 313 + pll_clk->regs = devm_ioremap_resource(dev, mem); 314 + if (IS_ERR(pll_clk->regs)) 315 + return PTR_ERR(pll_clk->regs); 316 + 317 + init.name = dev->of_node->name; 318 + init.ops = &hsdk_pll_ops; 319 + parent_name = of_clk_get_parent_name(dev->of_node, 0); 320 + init.parent_names = &parent_name; 321 + num_parents = of_clk_get_parent_count(dev->of_node); 322 + if (num_parents == 0 || num_parents > CGU_PLL_SOURCE_MAX) { 323 + dev_err(dev, "wrong clock parents number: %u\n", num_parents); 324 + return -EINVAL; 325 + } 326 + init.num_parents = num_parents; 327 + 328 + pll_clk->hw.init = &init; 329 + pll_clk->dev = dev; 330 + pll_clk->pll_devdata = of_device_get_match_data(dev); 331 + 332 + if (!pll_clk->pll_devdata) { 333 + dev_err(dev, "No OF match data provided\n"); 334 + return -EINVAL; 335 + } 336 + 337 + ret = devm_clk_hw_register(dev, &pll_clk->hw); 338 + if (ret) { 339 + dev_err(dev, "failed to register %s clock\n", init.name); 340 + return ret; 341 + } 342 + 343 + return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, 344 + &pll_clk->hw); 345 + } 346 + 347 + static int hsdk_pll_clk_remove(struct platform_device *pdev) 348 + { 349 + of_clk_del_provider(pdev->dev.of_node); 350 + return 0; 351 + } 352 + 353 + static void __init of_hsdk_pll_clk_setup(struct device_node *node) 354 + { 355 + int ret; 356 + const char *parent_name; 357 + unsigned int num_parents; 358 + struct hsdk_pll_clk *pll_clk; 359 + struct clk_init_data init = { }; 360 + 361 + pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); 362 + if (!pll_clk) 363 + return; 364 + 365 + pll_clk->regs = of_iomap(node, 0); 366 + if (!pll_clk->regs) { 367 + pr_err("failed to map pll registers\n"); 368 + goto err_free_pll_clk; 369 + } 370 + 371 + pll_clk->spec_regs = of_iomap(node, 1); 372 + if (!pll_clk->spec_regs) { 373 + pr_err("failed to map pll registers\n"); 374 + goto err_unmap_comm_regs; 375 + } 376 + 377 + init.name = node->name; 378 + init.ops = &hsdk_pll_ops; 379 + parent_name = of_clk_get_parent_name(node, 0); 380 + init.parent_names = &parent_name; 381 + num_parents = of_clk_get_parent_count(node); 382 + if (num_parents > CGU_PLL_SOURCE_MAX) { 383 + pr_err("too much clock parents: %u\n", num_parents); 384 + goto err_unmap_spec_regs; 385 + } 386 + init.num_parents = num_parents; 387 + 388 + pll_clk->hw.init = &init; 389 + pll_clk->pll_devdata = &core_pll_devdata; 390 + 391 + ret = clk_hw_register(NULL, &pll_clk->hw); 392 + if (ret) { 393 + pr_err("failed to register %s clock\n", node->name); 394 + goto err_unmap_spec_regs; 395 + } 396 + 397 + ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, &pll_clk->hw); 398 + if (ret) { 399 + pr_err("failed to add hw provider for %s clock\n", node->name); 400 + goto err_unmap_spec_regs; 401 + } 402 + 403 + return; 404 + 405 + err_unmap_spec_regs: 406 + iounmap(pll_clk->spec_regs); 407 + err_unmap_comm_regs: 408 + iounmap(pll_clk->regs); 409 + err_free_pll_clk: 410 + kfree(pll_clk); 411 + } 412 + 413 + /* Core PLL needed early for ARC cpus timers */ 414 + CLK_OF_DECLARE(hsdk_pll_clock, "snps,hsdk-core-pll-clock", 415 + of_hsdk_pll_clk_setup); 416 + 417 + static const struct of_device_id hsdk_pll_clk_id[] = { 418 + { .compatible = "snps,hsdk-gp-pll-clock", .data = &sdt_pll_devdata}, 419 + { .compatible = "snps,hsdk-hdmi-pll-clock", .data = &hdmi_pll_devdata}, 420 + { } 421 + }; 422 + 423 + static struct platform_driver hsdk_pll_clk_driver = { 424 + .driver = { 425 + .name = "hsdk-gp-pll-clock", 426 + .of_match_table = hsdk_pll_clk_id, 427 + }, 428 + .probe = hsdk_pll_clk_probe, 429 + .remove = hsdk_pll_clk_remove, 430 + }; 431 + builtin_platform_driver(hsdk_pll_clk_driver);
-390
drivers/clk/clk-mb86s7x.c
··· 1 - /* 2 - * Copyright (C) 2013-2015 FUJITSU SEMICONDUCTOR LIMITED 3 - * Copyright (C) 2015 Linaro Ltd. 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, version 2 of the License. 8 - * 9 - * This program is distributed in the hope that it will be useful, 10 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 - * GNU General Public License for more details. 13 - */ 14 - 15 - #include <linux/clkdev.h> 16 - #include <linux/err.h> 17 - #include <linux/io.h> 18 - #include <linux/of.h> 19 - #include <linux/cpu.h> 20 - #include <linux/clk-provider.h> 21 - #include <linux/spinlock.h> 22 - #include <linux/module.h> 23 - #include <linux/topology.h> 24 - #include <linux/mailbox_client.h> 25 - #include <linux/platform_device.h> 26 - 27 - #include <soc/mb86s7x/scb_mhu.h> 28 - 29 - #define to_crg_clk(p) container_of(p, struct crg_clk, hw) 30 - #define to_clc_clk(p) container_of(p, struct cl_clk, hw) 31 - 32 - struct mb86s7x_peri_clk { 33 - u32 payload_size; 34 - u32 cntrlr; 35 - u32 domain; 36 - u32 port; 37 - u32 en; 38 - u64 frequency; 39 - } __packed __aligned(4); 40 - 41 - struct hack_rate { 42 - unsigned clk_id; 43 - unsigned long rate; 44 - int gated; 45 - }; 46 - 47 - struct crg_clk { 48 - struct clk_hw hw; 49 - u8 cntrlr, domain, port; 50 - }; 51 - 52 - static int crg_gate_control(struct clk_hw *hw, int en) 53 - { 54 - struct crg_clk *crgclk = to_crg_clk(hw); 55 - struct mb86s7x_peri_clk cmd; 56 - int ret; 57 - 58 - cmd.payload_size = sizeof(cmd); 59 - cmd.cntrlr = crgclk->cntrlr; 60 - cmd.domain = crgclk->domain; 61 - cmd.port = crgclk->port; 62 - cmd.en = en; 63 - 64 - /* Port is UngatedCLK */ 65 - if (cmd.port == 8) 66 - return en ? 0 : -EINVAL; 67 - 68 - pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u En-%u}\n", 69 - __func__, __LINE__, cmd.cntrlr, 70 - cmd.domain, cmd.port, cmd.en); 71 - 72 - ret = mb86s7x_send_packet(CMD_PERI_CLOCK_GATE_SET_REQ, 73 - &cmd, sizeof(cmd)); 74 - if (ret < 0) { 75 - pr_err("%s:%d failed!\n", __func__, __LINE__); 76 - return ret; 77 - } 78 - 79 - pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u En-%u}\n", 80 - __func__, __LINE__, cmd.cntrlr, 81 - cmd.domain, cmd.port, cmd.en); 82 - 83 - /* If the request was rejected */ 84 - if (cmd.en != en) 85 - ret = -EINVAL; 86 - else 87 - ret = 0; 88 - 89 - return ret; 90 - } 91 - 92 - static int crg_port_prepare(struct clk_hw *hw) 93 - { 94 - return crg_gate_control(hw, 1); 95 - } 96 - 97 - static void crg_port_unprepare(struct clk_hw *hw) 98 - { 99 - crg_gate_control(hw, 0); 100 - } 101 - 102 - static int 103 - crg_rate_control(struct clk_hw *hw, int set, unsigned long *rate) 104 - { 105 - struct crg_clk *crgclk = to_crg_clk(hw); 106 - struct mb86s7x_peri_clk cmd; 107 - int code, ret; 108 - 109 - cmd.payload_size = sizeof(cmd); 110 - cmd.cntrlr = crgclk->cntrlr; 111 - cmd.domain = crgclk->domain; 112 - cmd.port = crgclk->port; 113 - cmd.frequency = *rate; 114 - 115 - if (set) { 116 - code = CMD_PERI_CLOCK_RATE_SET_REQ; 117 - pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n", 118 - __func__, __LINE__, cmd.cntrlr, 119 - cmd.domain, cmd.port, cmd.frequency); 120 - } else { 121 - code = CMD_PERI_CLOCK_RATE_GET_REQ; 122 - pr_debug("%s:%d CMD Cntrlr-%u Dom-%u Port-%u Rate-GET}\n", 123 - __func__, __LINE__, cmd.cntrlr, 124 - cmd.domain, cmd.port); 125 - } 126 - 127 - ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd)); 128 - if (ret < 0) { 129 - pr_err("%s:%d failed!\n", __func__, __LINE__); 130 - return ret; 131 - } 132 - 133 - if (set) 134 - pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-SET %lluHz}\n", 135 - __func__, __LINE__, cmd.cntrlr, 136 - cmd.domain, cmd.port, cmd.frequency); 137 - else 138 - pr_debug("%s:%d REP Cntrlr-%u Dom-%u Port-%u Rate-GOT %lluHz}\n", 139 - __func__, __LINE__, cmd.cntrlr, 140 - cmd.domain, cmd.port, cmd.frequency); 141 - 142 - *rate = cmd.frequency; 143 - return 0; 144 - } 145 - 146 - static unsigned long 147 - crg_port_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 148 - { 149 - unsigned long rate; 150 - 151 - crg_rate_control(hw, 0, &rate); 152 - 153 - return rate; 154 - } 155 - 156 - static long 157 - crg_port_round_rate(struct clk_hw *hw, 158 - unsigned long rate, unsigned long *pr) 159 - { 160 - return rate; 161 - } 162 - 163 - static int 164 - crg_port_set_rate(struct clk_hw *hw, 165 - unsigned long rate, unsigned long parent_rate) 166 - { 167 - return crg_rate_control(hw, 1, &rate); 168 - } 169 - 170 - const struct clk_ops crg_port_ops = { 171 - .prepare = crg_port_prepare, 172 - .unprepare = crg_port_unprepare, 173 - .recalc_rate = crg_port_recalc_rate, 174 - .round_rate = crg_port_round_rate, 175 - .set_rate = crg_port_set_rate, 176 - }; 177 - 178 - struct mb86s70_crg11 { 179 - struct mutex lock; /* protects CLK populating and searching */ 180 - }; 181 - 182 - static struct clk *crg11_get(struct of_phandle_args *clkspec, void *data) 183 - { 184 - struct mb86s70_crg11 *crg11 = data; 185 - struct clk_init_data init; 186 - u32 cntrlr, domain, port; 187 - struct crg_clk *crgclk; 188 - struct clk *clk; 189 - char clkp[20]; 190 - 191 - if (clkspec->args_count != 3) 192 - return ERR_PTR(-EINVAL); 193 - 194 - cntrlr = clkspec->args[0]; 195 - domain = clkspec->args[1]; 196 - port = clkspec->args[2]; 197 - 198 - if (port > 7) 199 - snprintf(clkp, 20, "UngatedCLK%d_%X", cntrlr, domain); 200 - else 201 - snprintf(clkp, 20, "CLK%d_%X_%d", cntrlr, domain, port); 202 - 203 - mutex_lock(&crg11->lock); 204 - 205 - clk = __clk_lookup(clkp); 206 - if (clk) { 207 - mutex_unlock(&crg11->lock); 208 - return clk; 209 - } 210 - 211 - crgclk = kzalloc(sizeof(*crgclk), GFP_KERNEL); 212 - if (!crgclk) { 213 - mutex_unlock(&crg11->lock); 214 - return ERR_PTR(-ENOMEM); 215 - } 216 - 217 - init.name = clkp; 218 - init.num_parents = 0; 219 - init.ops = &crg_port_ops; 220 - init.flags = 0; 221 - crgclk->hw.init = &init; 222 - crgclk->cntrlr = cntrlr; 223 - crgclk->domain = domain; 224 - crgclk->port = port; 225 - clk = clk_register(NULL, &crgclk->hw); 226 - if (IS_ERR(clk)) 227 - pr_err("%s:%d Error!\n", __func__, __LINE__); 228 - else 229 - pr_debug("Registered %s\n", clkp); 230 - 231 - clk_register_clkdev(clk, clkp, NULL); 232 - mutex_unlock(&crg11->lock); 233 - return clk; 234 - } 235 - 236 - static void __init crg_port_init(struct device_node *node) 237 - { 238 - struct mb86s70_crg11 *crg11; 239 - 240 - crg11 = kzalloc(sizeof(*crg11), GFP_KERNEL); 241 - if (!crg11) 242 - return; 243 - 244 - mutex_init(&crg11->lock); 245 - 246 - of_clk_add_provider(node, crg11_get, crg11); 247 - } 248 - CLK_OF_DECLARE(crg11_gate, "fujitsu,mb86s70-crg11", crg_port_init); 249 - 250 - struct cl_clk { 251 - struct clk_hw hw; 252 - int cluster; 253 - }; 254 - 255 - struct mb86s7x_cpu_freq { 256 - u32 payload_size; 257 - u32 cluster_class; 258 - u32 cluster_id; 259 - u32 cpu_id; 260 - u64 frequency; 261 - }; 262 - 263 - static void mhu_cluster_rate(struct clk_hw *hw, unsigned long *rate, int get) 264 - { 265 - struct cl_clk *clc = to_clc_clk(hw); 266 - struct mb86s7x_cpu_freq cmd; 267 - int code, ret; 268 - 269 - cmd.payload_size = sizeof(cmd); 270 - cmd.cluster_class = 0; 271 - cmd.cluster_id = clc->cluster; 272 - cmd.cpu_id = 0; 273 - cmd.frequency = *rate; 274 - 275 - if (get) 276 - code = CMD_CPU_CLOCK_RATE_GET_REQ; 277 - else 278 - code = CMD_CPU_CLOCK_RATE_SET_REQ; 279 - 280 - pr_debug("%s:%d CMD Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n", 281 - __func__, __LINE__, cmd.cluster_class, 282 - cmd.cluster_id, cmd.cpu_id, cmd.frequency); 283 - 284 - ret = mb86s7x_send_packet(code, &cmd, sizeof(cmd)); 285 - if (ret < 0) { 286 - pr_err("%s:%d failed!\n", __func__, __LINE__); 287 - return; 288 - } 289 - 290 - pr_debug("%s:%d REP Cl_Class-%u CL_ID-%u CPU_ID-%u Freq-%llu}\n", 291 - __func__, __LINE__, cmd.cluster_class, 292 - cmd.cluster_id, cmd.cpu_id, cmd.frequency); 293 - 294 - *rate = cmd.frequency; 295 - } 296 - 297 - static unsigned long 298 - clc_recalc_rate(struct clk_hw *hw, unsigned long unused) 299 - { 300 - unsigned long rate; 301 - 302 - mhu_cluster_rate(hw, &rate, 1); 303 - return rate; 304 - } 305 - 306 - static long 307 - clc_round_rate(struct clk_hw *hw, unsigned long rate, 308 - unsigned long *unused) 309 - { 310 - return rate; 311 - } 312 - 313 - static int 314 - clc_set_rate(struct clk_hw *hw, unsigned long rate, 315 - unsigned long unused) 316 - { 317 - unsigned long res = rate; 318 - 319 - mhu_cluster_rate(hw, &res, 0); 320 - 321 - return (res == rate) ? 0 : -EINVAL; 322 - } 323 - 324 - static struct clk_ops clk_clc_ops = { 325 - .recalc_rate = clc_recalc_rate, 326 - .round_rate = clc_round_rate, 327 - .set_rate = clc_set_rate, 328 - }; 329 - 330 - static struct clk_hw *mb86s7x_clclk_register(struct device *cpu_dev) 331 - { 332 - struct clk_init_data init; 333 - struct cl_clk *clc; 334 - int ret; 335 - 336 - clc = kzalloc(sizeof(*clc), GFP_KERNEL); 337 - if (!clc) 338 - return ERR_PTR(-ENOMEM); 339 - 340 - clc->hw.init = &init; 341 - clc->cluster = topology_physical_package_id(cpu_dev->id); 342 - 343 - init.name = dev_name(cpu_dev); 344 - init.ops = &clk_clc_ops; 345 - init.flags = CLK_GET_RATE_NOCACHE; 346 - init.num_parents = 0; 347 - 348 - ret = devm_clk_hw_register(cpu_dev, &clc->hw); 349 - if (ret) 350 - return ERR_PTR(ret); 351 - return &clc->hw; 352 - } 353 - 354 - static int mb86s7x_clclk_of_init(void) 355 - { 356 - int cpu, ret = -ENODEV; 357 - struct device_node *np; 358 - struct clk_hw *hw; 359 - 360 - np = of_find_compatible_node(NULL, NULL, "fujitsu,mb86s70-scb-1.0"); 361 - if (!np || !of_device_is_available(np)) 362 - goto exit; 363 - 364 - for_each_possible_cpu(cpu) { 365 - struct device *cpu_dev = get_cpu_device(cpu); 366 - 367 - if (!cpu_dev) { 368 - pr_err("failed to get cpu%d device\n", cpu); 369 - continue; 370 - } 371 - 372 - hw = mb86s7x_clclk_register(cpu_dev); 373 - if (IS_ERR(hw)) { 374 - pr_err("failed to register cpu%d clock\n", cpu); 375 - continue; 376 - } 377 - if (clk_hw_register_clkdev(hw, NULL, dev_name(cpu_dev))) { 378 - pr_err("failed to register cpu%d clock lookup\n", cpu); 379 - continue; 380 - } 381 - pr_debug("registered clk for %s\n", dev_name(cpu_dev)); 382 - } 383 - ret = 0; 384 - 385 - platform_device_register_simple("arm-bL-cpufreq-dt", -1, NULL, 0); 386 - exit: 387 - of_node_put(np); 388 - return ret; 389 - } 390 - module_init(mb86s7x_clclk_of_init);
+8 -8
drivers/clk/clk-moxart.c
··· 18 18 19 19 static void __init moxart_of_pll_clk_init(struct device_node *node) 20 20 { 21 - static void __iomem *base; 21 + void __iomem *base; 22 22 struct clk_hw *hw; 23 23 struct clk *ref_clk; 24 24 unsigned int mul; ··· 30 30 31 31 base = of_iomap(node, 0); 32 32 if (!base) { 33 - pr_err("%s: of_iomap failed\n", node->full_name); 33 + pr_err("%pOF: of_iomap failed\n", node); 34 34 return; 35 35 } 36 36 ··· 39 39 40 40 ref_clk = of_clk_get(node, 0); 41 41 if (IS_ERR(ref_clk)) { 42 - pr_err("%s: of_clk_get failed\n", node->full_name); 42 + pr_err("%pOF: of_clk_get failed\n", node); 43 43 return; 44 44 } 45 45 46 46 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, mul, 1); 47 47 if (IS_ERR(hw)) { 48 - pr_err("%s: failed to register clock\n", node->full_name); 48 + pr_err("%pOF: failed to register clock\n", node); 49 49 return; 50 50 } 51 51 ··· 57 57 58 58 static void __init moxart_of_apb_clk_init(struct device_node *node) 59 59 { 60 - static void __iomem *base; 60 + void __iomem *base; 61 61 struct clk_hw *hw; 62 62 struct clk *pll_clk; 63 63 unsigned int div, val; ··· 70 70 71 71 base = of_iomap(node, 0); 72 72 if (!base) { 73 - pr_err("%s: of_iomap failed\n", node->full_name); 73 + pr_err("%pOF: of_iomap failed\n", node); 74 74 return; 75 75 } 76 76 ··· 83 83 84 84 pll_clk = of_clk_get(node, 0); 85 85 if (IS_ERR(pll_clk)) { 86 - pr_err("%s: of_clk_get failed\n", node->full_name); 86 + pr_err("%pOF: of_clk_get failed\n", node); 87 87 return; 88 88 } 89 89 90 90 hw = clk_hw_register_fixed_factor(NULL, name, parent_name, 0, 1, div); 91 91 if (IS_ERR(hw)) { 92 - pr_err("%s: failed to register clock\n", node->full_name); 92 + pr_err("%pOF: failed to register clock\n", node); 93 93 return; 94 94 } 95 95
+22 -4
drivers/clk/clk-qoriq.c
··· 12 12 13 13 #include <linux/clk.h> 14 14 #include <linux/clk-provider.h> 15 + #include <linux/clkdev.h> 15 16 #include <linux/fsl/guts.h> 16 17 #include <linux/io.h> 17 18 #include <linux/kernel.h> ··· 536 535 }, 537 536 .pll_mask = 0x07, 538 537 .flags = CG_PLL_8BIT, 538 + }, 539 + { 540 + .compat = "fsl,ls1088a-clockgen", 541 + .cmux_groups = { 542 + &clockgen2_cmux_cga12 543 + }, 544 + .cmux_to_group = { 545 + 0, 0, -1 546 + }, 547 + .pll_mask = 0x07, 548 + .flags = CG_VER3 | CG_LITTLE_ENDIAN, 539 549 }, 540 550 { 541 551 .compat = "fsl,ls1012a-clockgen", ··· 1125 1113 1126 1114 for (i = 0; i < ARRAY_SIZE(pll->div); i++) { 1127 1115 struct clk *clk; 1116 + int ret; 1128 1117 1129 1118 snprintf(pll->div[i].name, sizeof(pll->div[i].name), 1130 1119 "cg-pll%d-div%d", idx, i + 1); ··· 1139 1126 } 1140 1127 1141 1128 pll->div[i].clk = clk; 1129 + ret = clk_register_clkdev(clk, pll->div[i].name, NULL); 1130 + if (ret != 0) 1131 + pr_err("%s: %s: register to lookup table failed %ld\n", 1132 + __func__, pll->div[i].name, PTR_ERR(clk)); 1133 + 1142 1134 } 1143 1135 } 1144 1136 ··· 1366 1348 } 1367 1349 1368 1350 if (i == ARRAY_SIZE(chipinfo)) { 1369 - pr_err("%s: unknown clockgen node %s\n", __func__, 1370 - np->full_name); 1351 + pr_err("%s: unknown clockgen node %pOF\n", __func__, np); 1371 1352 goto err; 1372 1353 } 1373 1354 clockgen.info = chipinfo[i]; ··· 1379 1362 if (guts) { 1380 1363 clockgen.guts = of_iomap(guts, 0); 1381 1364 if (!clockgen.guts) { 1382 - pr_err("%s: Couldn't map %s regs\n", __func__, 1383 - guts->full_name); 1365 + pr_err("%s: Couldn't map %pOF regs\n", __func__, 1366 + guts); 1384 1367 } 1385 1368 } 1386 1369 ··· 1415 1398 CLK_OF_DECLARE(qoriq_clockgen_ls1021a, "fsl,ls1021a-clockgen", clockgen_init); 1416 1399 CLK_OF_DECLARE(qoriq_clockgen_ls1043a, "fsl,ls1043a-clockgen", clockgen_init); 1417 1400 CLK_OF_DECLARE(qoriq_clockgen_ls1046a, "fsl,ls1046a-clockgen", clockgen_init); 1401 + CLK_OF_DECLARE(qoriq_clockgen_ls1088a, "fsl,ls1088a-clockgen", clockgen_init); 1418 1402 CLK_OF_DECLARE(qoriq_clockgen_ls2080a, "fsl,ls2080a-clockgen", clockgen_init); 1419 1403 1420 1404 /* Legacy nodes */
+5 -7
drivers/clk/clk-si5351.c
··· 519 519 SI5351_CLK_INTEGER_MODE, 520 520 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0); 521 521 522 + /* Do a pll soft reset on the affected pll */ 523 + si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, 524 + hwdata->num == 0 ? SI5351_PLL_RESET_A : 525 + SI5351_PLL_RESET_B); 526 + 522 527 dev_dbg(&hwdata->drvdata->client->dev, 523 528 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n", 524 529 __func__, clk_hw_get_name(hw), ··· 1095 1090 /* powerup clkout */ 1096 1091 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num, 1097 1092 SI5351_CLK_POWERDOWN, 0); 1098 - 1099 - /* 1100 - * Do a pll soft reset on both plls, needed in some cases to get 1101 - * all outputs running. 1102 - */ 1103 - si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET, 1104 - SI5351_PLL_RESET_A | SI5351_PLL_RESET_B); 1105 1093 1106 1094 dev_dbg(&hwdata->drvdata->client->dev, 1107 1095 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
+2 -2
drivers/clk/clk-stm32f4.c
··· 1541 1541 base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock); 1542 1542 1543 1543 if (IS_ERR(clks[idx])) { 1544 - pr_err("%s: Unable to register leaf clock %s\n", 1545 - np->full_name, gd->name); 1544 + pr_err("%pOF: Unable to register leaf clock %s\n", 1545 + np, gd->name); 1546 1546 goto fail; 1547 1547 } 1548 1548 }
+1410
drivers/clk/clk-stm32h7.c
··· 1 + /* 2 + * Copyright (C) Gabriel Fernandez 2017 3 + * Author: Gabriel Fernandez <gabriel.fernandez@st.com> 4 + * 5 + * License terms: GPL V2.0. 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms and conditions of the GNU General Public License, 9 + * version 2, as published by the Free Software Foundation. 10 + * 11 + * This program is distributed in the hope it will be useful, but WITHOUT 12 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14 + * more details. 15 + * 16 + * You should have received a copy of the GNU General Public License along with 17 + * this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/clk.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/err.h> 23 + #include <linux/io.h> 24 + #include <linux/mfd/syscon.h> 25 + #include <linux/of.h> 26 + #include <linux/of_address.h> 27 + #include <linux/slab.h> 28 + #include <linux/spinlock.h> 29 + #include <linux/regmap.h> 30 + 31 + #include <dt-bindings/clock/stm32h7-clks.h> 32 + 33 + /* Reset Clock Control Registers */ 34 + #define RCC_CR 0x00 35 + #define RCC_CFGR 0x10 36 + #define RCC_D1CFGR 0x18 37 + #define RCC_D2CFGR 0x1C 38 + #define RCC_D3CFGR 0x20 39 + #define RCC_PLLCKSELR 0x28 40 + #define RCC_PLLCFGR 0x2C 41 + #define RCC_PLL1DIVR 0x30 42 + #define RCC_PLL1FRACR 0x34 43 + #define RCC_PLL2DIVR 0x38 44 + #define RCC_PLL2FRACR 0x3C 45 + #define RCC_PLL3DIVR 0x40 46 + #define RCC_PLL3FRACR 0x44 47 + #define RCC_D1CCIPR 0x4C 48 + #define RCC_D2CCIP1R 0x50 49 + #define RCC_D2CCIP2R 0x54 50 + #define RCC_D3CCIPR 0x58 51 + #define RCC_BDCR 0x70 52 + #define RCC_CSR 0x74 53 + #define RCC_AHB3ENR 0xD4 54 + #define RCC_AHB1ENR 0xD8 55 + #define RCC_AHB2ENR 0xDC 56 + #define RCC_AHB4ENR 0xE0 57 + #define RCC_APB3ENR 0xE4 58 + #define RCC_APB1LENR 0xE8 59 + #define RCC_APB1HENR 0xEC 60 + #define RCC_APB2ENR 0xF0 61 + #define RCC_APB4ENR 0xF4 62 + 63 + static DEFINE_SPINLOCK(stm32rcc_lock); 64 + 65 + static void __iomem *base; 66 + static struct clk_hw **hws; 67 + 68 + /* System clock parent */ 69 + static const char * const sys_src[] = { 70 + "hsi_ck", "csi_ck", "hse_ck", "pll1_p" }; 71 + 72 + static const char * const tracein_src[] = { 73 + "hsi_ck", "csi_ck", "hse_ck", "pll1_r" }; 74 + 75 + static const char * const per_src[] = { 76 + "hsi_ker", "csi_ker", "hse_ck", "disabled" }; 77 + 78 + static const char * const pll_src[] = { 79 + "hsi_ck", "csi_ck", "hse_ck", "no clock" }; 80 + 81 + static const char * const sdmmc_src[] = { "pll1_q", "pll2_r" }; 82 + 83 + static const char * const dsi_src[] = { "ck_dsi_phy", "pll2_q" }; 84 + 85 + static const char * const qspi_src[] = { 86 + "hclk", "pll1_q", "pll2_r", "per_ck" }; 87 + 88 + static const char * const fmc_src[] = { 89 + "hclk", "pll1_q", "pll2_r", "per_ck" }; 90 + 91 + /* Kernel clock parent */ 92 + static const char * const swp_src[] = { "pclk1", "hsi_ker" }; 93 + 94 + static const char * const fdcan_src[] = { "hse_ck", "pll1_q", "pll2_q" }; 95 + 96 + static const char * const dfsdm1_src[] = { "pclk2", "sys_ck" }; 97 + 98 + static const char * const spdifrx_src[] = { 99 + "pll1_q", "pll2_r", "pll3_r", "hsi_ker" }; 100 + 101 + static const char *spi_src1[5] = { 102 + "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" }; 103 + 104 + static const char * const spi_src2[] = { 105 + "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" }; 106 + 107 + static const char * const spi_src3[] = { 108 + "pclk4", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "hse_ck" }; 109 + 110 + static const char * const lptim_src1[] = { 111 + "pclk1", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" }; 112 + 113 + static const char * const lptim_src2[] = { 114 + "pclk4", "pll2_p", "pll3_r", "lse_ck", "lsi_ck", "per_ck" }; 115 + 116 + static const char * const cec_src[] = {"lse_ck", "lsi_ck", "csi_ker_div122" }; 117 + 118 + static const char * const usbotg_src[] = {"pll1_q", "pll3_q", "rc48_ck" }; 119 + 120 + /* i2c 1,2,3 src */ 121 + static const char * const i2c_src1[] = { 122 + "pclk1", "pll3_r", "hsi_ker", "csi_ker" }; 123 + 124 + static const char * const i2c_src2[] = { 125 + "pclk4", "pll3_r", "hsi_ker", "csi_ker" }; 126 + 127 + static const char * const rng_src[] = { 128 + "rc48_ck", "pll1_q", "lse_ck", "lsi_ck" }; 129 + 130 + /* usart 1,6 src */ 131 + static const char * const usart_src1[] = { 132 + "pclk2", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" }; 133 + 134 + /* usart 2,3,4,5,7,8 src */ 135 + static const char * const usart_src2[] = { 136 + "pclk1", "pll2_q", "pll3_q", "hsi_ker", "csi_ker", "lse_ck" }; 137 + 138 + static const char *sai_src[5] = { 139 + "pll1_q", "pll2_p", "pll3_p", NULL, "per_ck" }; 140 + 141 + static const char * const adc_src[] = { "pll2_p", "pll3_r", "per_ck" }; 142 + 143 + /* lptim 2,3,4,5 src */ 144 + static const char * const lpuart1_src[] = { 145 + "pclk3", "pll2_q", "pll3_q", "csi_ker", "lse_ck" }; 146 + 147 + static const char * const hrtim_src[] = { "tim2_ker", "d1cpre" }; 148 + 149 + /* RTC clock parent */ 150 + static const char * const rtc_src[] = { "off", "lse_ck", "lsi_ck", "hse_1M" }; 151 + 152 + /* Micro-controller output clock parent */ 153 + static const char * const mco_src1[] = { 154 + "hsi_ck", "lse_ck", "hse_ck", "pll1_q", "rc48_ck" }; 155 + 156 + static const char * const mco_src2[] = { 157 + "sys_ck", "pll2_p", "hse_ck", "pll1_p", "csi_ck", "lsi_ck" }; 158 + 159 + /* LCD clock */ 160 + static const char * const ltdc_src[] = {"pll3_r"}; 161 + 162 + /* Gate clock with ready bit and backup domain management */ 163 + struct stm32_ready_gate { 164 + struct clk_gate gate; 165 + u8 bit_rdy; 166 + }; 167 + 168 + #define to_ready_gate_clk(_rgate) container_of(_rgate, struct stm32_ready_gate,\ 169 + gate) 170 + 171 + #define RGATE_TIMEOUT 10000 172 + 173 + static int ready_gate_clk_enable(struct clk_hw *hw) 174 + { 175 + struct clk_gate *gate = to_clk_gate(hw); 176 + struct stm32_ready_gate *rgate = to_ready_gate_clk(gate); 177 + int bit_status; 178 + unsigned int timeout = RGATE_TIMEOUT; 179 + 180 + if (clk_gate_ops.is_enabled(hw)) 181 + return 0; 182 + 183 + clk_gate_ops.enable(hw); 184 + 185 + /* We can't use readl_poll_timeout() because we can blocked if 186 + * someone enables this clock before clocksource changes. 187 + * Only jiffies counter is available. Jiffies are incremented by 188 + * interruptions and enable op does not allow to be interrupted. 189 + */ 190 + do { 191 + bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy)); 192 + 193 + if (bit_status) 194 + udelay(100); 195 + 196 + } while (bit_status && --timeout); 197 + 198 + return bit_status; 199 + } 200 + 201 + static void ready_gate_clk_disable(struct clk_hw *hw) 202 + { 203 + struct clk_gate *gate = to_clk_gate(hw); 204 + struct stm32_ready_gate *rgate = to_ready_gate_clk(gate); 205 + int bit_status; 206 + unsigned int timeout = RGATE_TIMEOUT; 207 + 208 + if (!clk_gate_ops.is_enabled(hw)) 209 + return; 210 + 211 + clk_gate_ops.disable(hw); 212 + 213 + do { 214 + bit_status = !!(readl(gate->reg) & BIT(rgate->bit_rdy)); 215 + 216 + if (bit_status) 217 + udelay(100); 218 + 219 + } while (bit_status && --timeout); 220 + } 221 + 222 + static const struct clk_ops ready_gate_clk_ops = { 223 + .enable = ready_gate_clk_enable, 224 + .disable = ready_gate_clk_disable, 225 + .is_enabled = clk_gate_is_enabled, 226 + }; 227 + 228 + static struct clk_hw *clk_register_ready_gate(struct device *dev, 229 + const char *name, const char *parent_name, 230 + void __iomem *reg, u8 bit_idx, u8 bit_rdy, 231 + unsigned long flags, spinlock_t *lock) 232 + { 233 + struct stm32_ready_gate *rgate; 234 + struct clk_init_data init = { NULL }; 235 + struct clk_hw *hw; 236 + int ret; 237 + 238 + rgate = kzalloc(sizeof(*rgate), GFP_KERNEL); 239 + if (!rgate) 240 + return ERR_PTR(-ENOMEM); 241 + 242 + init.name = name; 243 + init.ops = &ready_gate_clk_ops; 244 + init.flags = flags; 245 + init.parent_names = &parent_name; 246 + init.num_parents = 1; 247 + 248 + rgate->bit_rdy = bit_rdy; 249 + rgate->gate.lock = lock; 250 + rgate->gate.reg = reg; 251 + rgate->gate.bit_idx = bit_idx; 252 + rgate->gate.hw.init = &init; 253 + 254 + hw = &rgate->gate.hw; 255 + ret = clk_hw_register(dev, hw); 256 + if (ret) { 257 + kfree(rgate); 258 + hw = ERR_PTR(ret); 259 + } 260 + 261 + return hw; 262 + } 263 + 264 + struct gate_cfg { 265 + u32 offset; 266 + u8 bit_idx; 267 + }; 268 + 269 + struct muxdiv_cfg { 270 + u32 offset; 271 + u8 shift; 272 + u8 width; 273 + }; 274 + 275 + struct composite_clk_cfg { 276 + struct gate_cfg *gate; 277 + struct muxdiv_cfg *mux; 278 + struct muxdiv_cfg *div; 279 + const char *name; 280 + const char * const *parent_name; 281 + int num_parents; 282 + u32 flags; 283 + }; 284 + 285 + struct composite_clk_gcfg_t { 286 + u8 flags; 287 + const struct clk_ops *ops; 288 + }; 289 + 290 + /* 291 + * General config definition of a composite clock (only clock diviser for rate) 292 + */ 293 + struct composite_clk_gcfg { 294 + struct composite_clk_gcfg_t *mux; 295 + struct composite_clk_gcfg_t *div; 296 + struct composite_clk_gcfg_t *gate; 297 + }; 298 + 299 + #define M_CFG_MUX(_mux_ops, _mux_flags)\ 300 + .mux = &(struct composite_clk_gcfg_t) { _mux_flags, _mux_ops} 301 + 302 + #define M_CFG_DIV(_rate_ops, _rate_flags)\ 303 + .div = &(struct composite_clk_gcfg_t) {_rate_flags, _rate_ops} 304 + 305 + #define M_CFG_GATE(_gate_ops, _gate_flags)\ 306 + .gate = &(struct composite_clk_gcfg_t) { _gate_flags, _gate_ops} 307 + 308 + static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width, 309 + u32 flags, spinlock_t *lock) 310 + { 311 + struct clk_mux *mux; 312 + 313 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 314 + if (!mux) 315 + return ERR_PTR(-ENOMEM); 316 + 317 + mux->reg = reg; 318 + mux->shift = shift; 319 + mux->mask = (1 << width) - 1; 320 + mux->flags = flags; 321 + mux->lock = lock; 322 + 323 + return mux; 324 + } 325 + 326 + static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width, 327 + u32 flags, spinlock_t *lock) 328 + { 329 + struct clk_divider *div; 330 + 331 + div = kzalloc(sizeof(*div), GFP_KERNEL); 332 + 333 + if (!div) 334 + return ERR_PTR(-ENOMEM); 335 + 336 + div->reg = reg; 337 + div->shift = shift; 338 + div->width = width; 339 + div->flags = flags; 340 + div->lock = lock; 341 + 342 + return div; 343 + } 344 + 345 + static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags, 346 + spinlock_t *lock) 347 + { 348 + struct clk_gate *gate; 349 + 350 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 351 + if (!gate) 352 + return ERR_PTR(-ENOMEM); 353 + 354 + gate->reg = reg; 355 + gate->bit_idx = bit_idx; 356 + gate->flags = flags; 357 + gate->lock = lock; 358 + 359 + return gate; 360 + } 361 + 362 + struct composite_cfg { 363 + struct clk_hw *mux_hw; 364 + struct clk_hw *div_hw; 365 + struct clk_hw *gate_hw; 366 + 367 + const struct clk_ops *mux_ops; 368 + const struct clk_ops *div_ops; 369 + const struct clk_ops *gate_ops; 370 + }; 371 + 372 + static void get_cfg_composite_div(const struct composite_clk_gcfg *gcfg, 373 + const struct composite_clk_cfg *cfg, 374 + struct composite_cfg *composite, spinlock_t *lock) 375 + { 376 + struct clk_mux *mux = NULL; 377 + struct clk_divider *div = NULL; 378 + struct clk_gate *gate = NULL; 379 + const struct clk_ops *mux_ops, *div_ops, *gate_ops; 380 + struct clk_hw *mux_hw; 381 + struct clk_hw *div_hw; 382 + struct clk_hw *gate_hw; 383 + 384 + mux_ops = div_ops = gate_ops = NULL; 385 + mux_hw = div_hw = gate_hw = NULL; 386 + 387 + if (gcfg->mux && gcfg->mux) { 388 + mux = _get_cmux(base + cfg->mux->offset, 389 + cfg->mux->shift, 390 + cfg->mux->width, 391 + gcfg->mux->flags, lock); 392 + 393 + if (!IS_ERR(mux)) { 394 + mux_hw = &mux->hw; 395 + mux_ops = gcfg->mux->ops ? 396 + gcfg->mux->ops : &clk_mux_ops; 397 + } 398 + } 399 + 400 + if (gcfg->div && cfg->div) { 401 + div = _get_cdiv(base + cfg->div->offset, 402 + cfg->div->shift, 403 + cfg->div->width, 404 + gcfg->div->flags, lock); 405 + 406 + if (!IS_ERR(div)) { 407 + div_hw = &div->hw; 408 + div_ops = gcfg->div->ops ? 409 + gcfg->div->ops : &clk_divider_ops; 410 + } 411 + } 412 + 413 + if (gcfg->gate && gcfg->gate) { 414 + gate = _get_cgate(base + cfg->gate->offset, 415 + cfg->gate->bit_idx, 416 + gcfg->gate->flags, lock); 417 + 418 + if (!IS_ERR(gate)) { 419 + gate_hw = &gate->hw; 420 + gate_ops = gcfg->gate->ops ? 421 + gcfg->gate->ops : &clk_gate_ops; 422 + } 423 + } 424 + 425 + composite->mux_hw = mux_hw; 426 + composite->mux_ops = mux_ops; 427 + 428 + composite->div_hw = div_hw; 429 + composite->div_ops = div_ops; 430 + 431 + composite->gate_hw = gate_hw; 432 + composite->gate_ops = gate_ops; 433 + } 434 + 435 + /* Kernel Timer */ 436 + struct timer_ker { 437 + u8 dppre_shift; 438 + struct clk_hw hw; 439 + spinlock_t *lock; 440 + }; 441 + 442 + #define to_timer_ker(_hw) container_of(_hw, struct timer_ker, hw) 443 + 444 + static unsigned long timer_ker_recalc_rate(struct clk_hw *hw, 445 + unsigned long parent_rate) 446 + { 447 + struct timer_ker *clk_elem = to_timer_ker(hw); 448 + u32 timpre; 449 + u32 dppre_shift = clk_elem->dppre_shift; 450 + u32 prescaler; 451 + u32 mul; 452 + 453 + timpre = (readl(base + RCC_CFGR) >> 15) & 0x01; 454 + 455 + prescaler = (readl(base + RCC_D2CFGR) >> dppre_shift) & 0x03; 456 + 457 + mul = 2; 458 + 459 + if (prescaler < 4) 460 + mul = 1; 461 + 462 + else if (timpre && prescaler > 4) 463 + mul = 4; 464 + 465 + return parent_rate * mul; 466 + } 467 + 468 + static const struct clk_ops timer_ker_ops = { 469 + .recalc_rate = timer_ker_recalc_rate, 470 + }; 471 + 472 + static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev, 473 + const char *name, const char *parent_name, 474 + unsigned long flags, 475 + u8 dppre_shift, 476 + spinlock_t *lock) 477 + { 478 + struct timer_ker *element; 479 + struct clk_init_data init; 480 + struct clk_hw *hw; 481 + int err; 482 + 483 + element = kzalloc(sizeof(*element), GFP_KERNEL); 484 + if (!element) 485 + return ERR_PTR(-ENOMEM); 486 + 487 + init.name = name; 488 + init.ops = &timer_ker_ops; 489 + init.flags = flags; 490 + init.parent_names = &parent_name; 491 + init.num_parents = 1; 492 + 493 + element->hw.init = &init; 494 + element->lock = lock; 495 + element->dppre_shift = dppre_shift; 496 + 497 + hw = &element->hw; 498 + err = clk_hw_register(dev, hw); 499 + 500 + if (err) { 501 + kfree(element); 502 + return ERR_PTR(err); 503 + } 504 + 505 + return hw; 506 + } 507 + 508 + static const struct clk_div_table d1cpre_div_table[] = { 509 + { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1}, 510 + { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1}, 511 + { 8, 2 }, { 9, 4 }, { 10, 8 }, { 11, 16 }, 512 + { 12, 64 }, { 13, 128 }, { 14, 256 }, 513 + { 15, 512 }, 514 + { 0 }, 515 + }; 516 + 517 + static const struct clk_div_table ppre_div_table[] = { 518 + { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1}, 519 + { 4, 2 }, { 5, 4 }, { 6, 8 }, { 7, 16 }, 520 + { 0 }, 521 + }; 522 + 523 + static void register_core_and_bus_clocks(void) 524 + { 525 + /* CORE AND BUS */ 526 + hws[SYS_D1CPRE] = clk_hw_register_divider_table(NULL, "d1cpre", 527 + "sys_ck", CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 8, 4, 0, 528 + d1cpre_div_table, &stm32rcc_lock); 529 + 530 + hws[HCLK] = clk_hw_register_divider_table(NULL, "hclk", "d1cpre", 531 + CLK_IGNORE_UNUSED, base + RCC_D1CFGR, 0, 4, 0, 532 + d1cpre_div_table, &stm32rcc_lock); 533 + 534 + /* D1 DOMAIN */ 535 + /* * CPU Systick */ 536 + hws[CPU_SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick", 537 + "d1cpre", 0, 1, 8); 538 + 539 + /* * APB3 peripheral */ 540 + hws[PCLK3] = clk_hw_register_divider_table(NULL, "pclk3", "hclk", 0, 541 + base + RCC_D1CFGR, 4, 3, 0, 542 + ppre_div_table, &stm32rcc_lock); 543 + 544 + /* D2 DOMAIN */ 545 + /* * APB1 peripheral */ 546 + hws[PCLK1] = clk_hw_register_divider_table(NULL, "pclk1", "hclk", 0, 547 + base + RCC_D2CFGR, 4, 3, 0, 548 + ppre_div_table, &stm32rcc_lock); 549 + 550 + /* Timers prescaler clocks */ 551 + clk_register_stm32_timer_ker(NULL, "tim1_ker", "pclk1", 0, 552 + 4, &stm32rcc_lock); 553 + 554 + /* * APB2 peripheral */ 555 + hws[PCLK2] = clk_hw_register_divider_table(NULL, "pclk2", "hclk", 0, 556 + base + RCC_D2CFGR, 8, 3, 0, ppre_div_table, 557 + &stm32rcc_lock); 558 + 559 + clk_register_stm32_timer_ker(NULL, "tim2_ker", "pclk2", 0, 8, 560 + &stm32rcc_lock); 561 + 562 + /* D3 DOMAIN */ 563 + /* * APB4 peripheral */ 564 + hws[PCLK4] = clk_hw_register_divider_table(NULL, "pclk4", "hclk", 0, 565 + base + RCC_D3CFGR, 4, 3, 0, 566 + ppre_div_table, &stm32rcc_lock); 567 + } 568 + 569 + /* MUX clock configuration */ 570 + struct stm32_mux_clk { 571 + const char *name; 572 + const char * const *parents; 573 + u8 num_parents; 574 + u32 offset; 575 + u8 shift; 576 + u8 width; 577 + u32 flags; 578 + }; 579 + 580 + #define M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, _flags)\ 581 + {\ 582 + .name = _name,\ 583 + .parents = _parents,\ 584 + .num_parents = ARRAY_SIZE(_parents),\ 585 + .offset = _mux_offset,\ 586 + .shift = _mux_shift,\ 587 + .width = _mux_width,\ 588 + .flags = _flags,\ 589 + } 590 + 591 + #define M_MCLOC(_name, _parents, _mux_offset, _mux_shift, _mux_width)\ 592 + M_MCLOCF(_name, _parents, _mux_offset, _mux_shift, _mux_width, 0)\ 593 + 594 + static const struct stm32_mux_clk stm32_mclk[] __initconst = { 595 + M_MCLOC("per_ck", per_src, RCC_D1CCIPR, 28, 3), 596 + M_MCLOC("pllsrc", pll_src, RCC_PLLCKSELR, 0, 3), 597 + M_MCLOC("sys_ck", sys_src, RCC_CFGR, 0, 3), 598 + M_MCLOC("tracein_ck", tracein_src, RCC_CFGR, 0, 3), 599 + }; 600 + 601 + /* Oscillary clock configuration */ 602 + struct stm32_osc_clk { 603 + const char *name; 604 + const char *parent; 605 + u32 gate_offset; 606 + u8 bit_idx; 607 + u8 bit_rdy; 608 + u32 flags; 609 + }; 610 + 611 + #define OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, _flags)\ 612 + {\ 613 + .name = _name,\ 614 + .parent = _parent,\ 615 + .gate_offset = _gate_offset,\ 616 + .bit_idx = _bit_idx,\ 617 + .bit_rdy = _bit_rdy,\ 618 + .flags = _flags,\ 619 + } 620 + 621 + #define OSC_CLK(_name, _parent, _gate_offset, _bit_idx, _bit_rdy)\ 622 + OSC_CLKF(_name, _parent, _gate_offset, _bit_idx, _bit_rdy, 0) 623 + 624 + static const struct stm32_osc_clk stm32_oclk[] __initconst = { 625 + OSC_CLKF("hsi_ck", "hsidiv", RCC_CR, 0, 2, CLK_IGNORE_UNUSED), 626 + OSC_CLKF("hsi_ker", "hsidiv", RCC_CR, 1, 2, CLK_IGNORE_UNUSED), 627 + OSC_CLKF("csi_ck", "clk-csi", RCC_CR, 7, 8, CLK_IGNORE_UNUSED), 628 + OSC_CLKF("csi_ker", "clk-csi", RCC_CR, 9, 8, CLK_IGNORE_UNUSED), 629 + OSC_CLKF("rc48_ck", "clk-rc48", RCC_CR, 12, 13, CLK_IGNORE_UNUSED), 630 + OSC_CLKF("lsi_ck", "clk-lsi", RCC_CSR, 0, 1, CLK_IGNORE_UNUSED), 631 + }; 632 + 633 + /* PLL configuration */ 634 + struct st32h7_pll_cfg { 635 + u8 bit_idx; 636 + u32 offset_divr; 637 + u8 bit_frac_en; 638 + u32 offset_frac; 639 + u8 divm; 640 + }; 641 + 642 + struct stm32_pll_data { 643 + const char *name; 644 + const char *parent_name; 645 + unsigned long flags; 646 + const struct st32h7_pll_cfg *cfg; 647 + }; 648 + 649 + static const struct st32h7_pll_cfg stm32h7_pll1 = { 650 + .bit_idx = 24, 651 + .offset_divr = RCC_PLL1DIVR, 652 + .bit_frac_en = 0, 653 + .offset_frac = RCC_PLL1FRACR, 654 + .divm = 4, 655 + }; 656 + 657 + static const struct st32h7_pll_cfg stm32h7_pll2 = { 658 + .bit_idx = 26, 659 + .offset_divr = RCC_PLL2DIVR, 660 + .bit_frac_en = 4, 661 + .offset_frac = RCC_PLL2FRACR, 662 + .divm = 12, 663 + }; 664 + 665 + static const struct st32h7_pll_cfg stm32h7_pll3 = { 666 + .bit_idx = 28, 667 + .offset_divr = RCC_PLL3DIVR, 668 + .bit_frac_en = 8, 669 + .offset_frac = RCC_PLL3FRACR, 670 + .divm = 20, 671 + }; 672 + 673 + static const struct stm32_pll_data stm32_pll[] = { 674 + { "vco1", "pllsrc", CLK_IGNORE_UNUSED, &stm32h7_pll1 }, 675 + { "vco2", "pllsrc", 0, &stm32h7_pll2 }, 676 + { "vco3", "pllsrc", 0, &stm32h7_pll3 }, 677 + }; 678 + 679 + struct stm32_fractional_divider { 680 + void __iomem *mreg; 681 + u8 mshift; 682 + u8 mwidth; 683 + u32 mmask; 684 + 685 + void __iomem *nreg; 686 + u8 nshift; 687 + u8 nwidth; 688 + 689 + void __iomem *freg_status; 690 + u8 freg_bit; 691 + void __iomem *freg_value; 692 + u8 fshift; 693 + u8 fwidth; 694 + 695 + u8 flags; 696 + struct clk_hw hw; 697 + spinlock_t *lock; 698 + }; 699 + 700 + struct stm32_pll_obj { 701 + spinlock_t *lock; 702 + struct stm32_fractional_divider div; 703 + struct stm32_ready_gate rgate; 704 + struct clk_hw hw; 705 + }; 706 + 707 + #define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw) 708 + 709 + static int pll_is_enabled(struct clk_hw *hw) 710 + { 711 + struct stm32_pll_obj *clk_elem = to_pll(hw); 712 + struct clk_hw *_hw = &clk_elem->rgate.gate.hw; 713 + 714 + __clk_hw_set_clk(_hw, hw); 715 + 716 + return ready_gate_clk_ops.is_enabled(_hw); 717 + } 718 + 719 + static int pll_enable(struct clk_hw *hw) 720 + { 721 + struct stm32_pll_obj *clk_elem = to_pll(hw); 722 + struct clk_hw *_hw = &clk_elem->rgate.gate.hw; 723 + 724 + __clk_hw_set_clk(_hw, hw); 725 + 726 + return ready_gate_clk_ops.enable(_hw); 727 + } 728 + 729 + static void pll_disable(struct clk_hw *hw) 730 + { 731 + struct stm32_pll_obj *clk_elem = to_pll(hw); 732 + struct clk_hw *_hw = &clk_elem->rgate.gate.hw; 733 + 734 + __clk_hw_set_clk(_hw, hw); 735 + 736 + ready_gate_clk_ops.disable(_hw); 737 + } 738 + 739 + static int pll_frac_is_enabled(struct clk_hw *hw) 740 + { 741 + struct stm32_pll_obj *clk_elem = to_pll(hw); 742 + struct stm32_fractional_divider *fd = &clk_elem->div; 743 + 744 + return (readl(fd->freg_status) >> fd->freg_bit) & 0x01; 745 + } 746 + 747 + static unsigned long pll_read_frac(struct clk_hw *hw) 748 + { 749 + struct stm32_pll_obj *clk_elem = to_pll(hw); 750 + struct stm32_fractional_divider *fd = &clk_elem->div; 751 + 752 + return (readl(fd->freg_value) >> fd->fshift) & 753 + GENMASK(fd->fwidth - 1, 0); 754 + } 755 + 756 + static unsigned long pll_fd_recalc_rate(struct clk_hw *hw, 757 + unsigned long parent_rate) 758 + { 759 + struct stm32_pll_obj *clk_elem = to_pll(hw); 760 + struct stm32_fractional_divider *fd = &clk_elem->div; 761 + unsigned long m, n; 762 + u32 val, mask; 763 + u64 rate, rate1 = 0; 764 + 765 + val = readl(fd->mreg); 766 + mask = GENMASK(fd->mwidth - 1, 0) << fd->mshift; 767 + m = (val & mask) >> fd->mshift; 768 + 769 + val = readl(fd->nreg); 770 + mask = GENMASK(fd->nwidth - 1, 0) << fd->nshift; 771 + n = ((val & mask) >> fd->nshift) + 1; 772 + 773 + if (!n || !m) 774 + return parent_rate; 775 + 776 + rate = (u64)parent_rate * n; 777 + do_div(rate, m); 778 + 779 + if (pll_frac_is_enabled(hw)) { 780 + val = pll_read_frac(hw); 781 + rate1 = (u64)parent_rate * (u64)val; 782 + do_div(rate1, (m * 8191)); 783 + } 784 + 785 + return rate + rate1; 786 + } 787 + 788 + static const struct clk_ops pll_ops = { 789 + .enable = pll_enable, 790 + .disable = pll_disable, 791 + .is_enabled = pll_is_enabled, 792 + .recalc_rate = pll_fd_recalc_rate, 793 + }; 794 + 795 + static struct clk_hw *clk_register_stm32_pll(struct device *dev, 796 + const char *name, 797 + const char *parent, 798 + unsigned long flags, 799 + const struct st32h7_pll_cfg *cfg, 800 + spinlock_t *lock) 801 + { 802 + struct stm32_pll_obj *pll; 803 + struct clk_init_data init = { NULL }; 804 + struct clk_hw *hw; 805 + int ret; 806 + struct stm32_fractional_divider *div = NULL; 807 + struct stm32_ready_gate *rgate; 808 + 809 + pll = kzalloc(sizeof(*pll), GFP_KERNEL); 810 + if (!pll) 811 + return ERR_PTR(-ENOMEM); 812 + 813 + init.name = name; 814 + init.ops = &pll_ops; 815 + init.flags = flags; 816 + init.parent_names = &parent; 817 + init.num_parents = 1; 818 + pll->hw.init = &init; 819 + 820 + hw = &pll->hw; 821 + rgate = &pll->rgate; 822 + 823 + rgate->bit_rdy = cfg->bit_idx + 1; 824 + rgate->gate.lock = lock; 825 + rgate->gate.reg = base + RCC_CR; 826 + rgate->gate.bit_idx = cfg->bit_idx; 827 + 828 + div = &pll->div; 829 + div->flags = 0; 830 + div->mreg = base + RCC_PLLCKSELR; 831 + div->mshift = cfg->divm; 832 + div->mwidth = 6; 833 + div->nreg = base + cfg->offset_divr; 834 + div->nshift = 0; 835 + div->nwidth = 9; 836 + 837 + div->freg_status = base + RCC_PLLCFGR; 838 + div->freg_bit = cfg->bit_frac_en; 839 + div->freg_value = base + cfg->offset_frac; 840 + div->fshift = 3; 841 + div->fwidth = 13; 842 + 843 + div->lock = lock; 844 + 845 + ret = clk_hw_register(dev, hw); 846 + if (ret) { 847 + kfree(pll); 848 + hw = ERR_PTR(ret); 849 + } 850 + 851 + return hw; 852 + } 853 + 854 + /* ODF CLOCKS */ 855 + static unsigned long odf_divider_recalc_rate(struct clk_hw *hw, 856 + unsigned long parent_rate) 857 + { 858 + return clk_divider_ops.recalc_rate(hw, parent_rate); 859 + } 860 + 861 + static long odf_divider_round_rate(struct clk_hw *hw, unsigned long rate, 862 + unsigned long *prate) 863 + { 864 + return clk_divider_ops.round_rate(hw, rate, prate); 865 + } 866 + 867 + static int odf_divider_set_rate(struct clk_hw *hw, unsigned long rate, 868 + unsigned long parent_rate) 869 + { 870 + struct clk_hw *hwp; 871 + int pll_status; 872 + int ret; 873 + 874 + hwp = clk_hw_get_parent(hw); 875 + 876 + pll_status = pll_is_enabled(hwp); 877 + 878 + if (pll_status) 879 + pll_disable(hwp); 880 + 881 + ret = clk_divider_ops.set_rate(hw, rate, parent_rate); 882 + 883 + if (pll_status) 884 + pll_enable(hwp); 885 + 886 + return ret; 887 + } 888 + 889 + static const struct clk_ops odf_divider_ops = { 890 + .recalc_rate = odf_divider_recalc_rate, 891 + .round_rate = odf_divider_round_rate, 892 + .set_rate = odf_divider_set_rate, 893 + }; 894 + 895 + static int odf_gate_enable(struct clk_hw *hw) 896 + { 897 + struct clk_hw *hwp; 898 + int pll_status; 899 + int ret; 900 + 901 + if (clk_gate_ops.is_enabled(hw)) 902 + return 0; 903 + 904 + hwp = clk_hw_get_parent(hw); 905 + 906 + pll_status = pll_is_enabled(hwp); 907 + 908 + if (pll_status) 909 + pll_disable(hwp); 910 + 911 + ret = clk_gate_ops.enable(hw); 912 + 913 + if (pll_status) 914 + pll_enable(hwp); 915 + 916 + return ret; 917 + } 918 + 919 + static void odf_gate_disable(struct clk_hw *hw) 920 + { 921 + struct clk_hw *hwp; 922 + int pll_status; 923 + 924 + if (!clk_gate_ops.is_enabled(hw)) 925 + return; 926 + 927 + hwp = clk_hw_get_parent(hw); 928 + 929 + pll_status = pll_is_enabled(hwp); 930 + 931 + if (pll_status) 932 + pll_disable(hwp); 933 + 934 + clk_gate_ops.disable(hw); 935 + 936 + if (pll_status) 937 + pll_enable(hwp); 938 + } 939 + 940 + static const struct clk_ops odf_gate_ops = { 941 + .enable = odf_gate_enable, 942 + .disable = odf_gate_disable, 943 + .is_enabled = clk_gate_is_enabled, 944 + }; 945 + 946 + static struct composite_clk_gcfg odf_clk_gcfg = { 947 + M_CFG_DIV(&odf_divider_ops, 0), 948 + M_CFG_GATE(&odf_gate_ops, 0), 949 + }; 950 + 951 + #define M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ 952 + _rate_shift, _rate_width, _flags)\ 953 + {\ 954 + .mux = NULL,\ 955 + .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\ 956 + .gate = &(struct gate_cfg) {_gate_offset, _bit_idx },\ 957 + .name = _name,\ 958 + .parent_name = &(const char *) {_parent},\ 959 + .num_parents = 1,\ 960 + .flags = _flags,\ 961 + } 962 + 963 + #define M_ODF(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ 964 + _rate_shift, _rate_width)\ 965 + M_ODF_F(_name, _parent, _gate_offset, _bit_idx, _rate_offset,\ 966 + _rate_shift, _rate_width, 0)\ 967 + 968 + static const struct composite_clk_cfg stm32_odf[3][3] = { 969 + { 970 + M_ODF_F("pll1_p", "vco1", RCC_PLLCFGR, 16, RCC_PLL1DIVR, 9, 7, 971 + CLK_IGNORE_UNUSED), 972 + M_ODF_F("pll1_q", "vco1", RCC_PLLCFGR, 17, RCC_PLL1DIVR, 16, 7, 973 + CLK_IGNORE_UNUSED), 974 + M_ODF_F("pll1_r", "vco1", RCC_PLLCFGR, 18, RCC_PLL1DIVR, 24, 7, 975 + CLK_IGNORE_UNUSED), 976 + }, 977 + 978 + { 979 + M_ODF("pll2_p", "vco2", RCC_PLLCFGR, 19, RCC_PLL2DIVR, 9, 7), 980 + M_ODF("pll2_q", "vco2", RCC_PLLCFGR, 20, RCC_PLL2DIVR, 16, 7), 981 + M_ODF("pll2_r", "vco2", RCC_PLLCFGR, 21, RCC_PLL2DIVR, 24, 7), 982 + }, 983 + { 984 + M_ODF("pll3_p", "vco3", RCC_PLLCFGR, 22, RCC_PLL3DIVR, 9, 7), 985 + M_ODF("pll3_q", "vco3", RCC_PLLCFGR, 23, RCC_PLL3DIVR, 16, 7), 986 + M_ODF("pll3_r", "vco3", RCC_PLLCFGR, 24, RCC_PLL3DIVR, 24, 7), 987 + } 988 + }; 989 + 990 + /* PERIF CLOCKS */ 991 + struct pclk_t { 992 + u32 gate_offset; 993 + u8 bit_idx; 994 + const char *name; 995 + const char *parent; 996 + u32 flags; 997 + }; 998 + 999 + #define PER_CLKF(_gate_offset, _bit_idx, _name, _parent, _flags)\ 1000 + {\ 1001 + .gate_offset = _gate_offset,\ 1002 + .bit_idx = _bit_idx,\ 1003 + .name = _name,\ 1004 + .parent = _parent,\ 1005 + .flags = _flags,\ 1006 + } 1007 + 1008 + #define PER_CLK(_gate_offset, _bit_idx, _name, _parent)\ 1009 + PER_CLKF(_gate_offset, _bit_idx, _name, _parent, 0) 1010 + 1011 + static const struct pclk_t pclk[] = { 1012 + PER_CLK(RCC_AHB3ENR, 31, "d1sram1", "hclk"), 1013 + PER_CLK(RCC_AHB3ENR, 30, "itcm", "hclk"), 1014 + PER_CLK(RCC_AHB3ENR, 29, "dtcm2", "hclk"), 1015 + PER_CLK(RCC_AHB3ENR, 28, "dtcm1", "hclk"), 1016 + PER_CLK(RCC_AHB3ENR, 8, "flitf", "hclk"), 1017 + PER_CLK(RCC_AHB3ENR, 5, "jpgdec", "hclk"), 1018 + PER_CLK(RCC_AHB3ENR, 4, "dma2d", "hclk"), 1019 + PER_CLK(RCC_AHB3ENR, 0, "mdma", "hclk"), 1020 + PER_CLK(RCC_AHB1ENR, 28, "usb2ulpi", "hclk"), 1021 + PER_CLK(RCC_AHB1ENR, 26, "usb1ulpi", "hclk"), 1022 + PER_CLK(RCC_AHB1ENR, 17, "eth1rx", "hclk"), 1023 + PER_CLK(RCC_AHB1ENR, 16, "eth1tx", "hclk"), 1024 + PER_CLK(RCC_AHB1ENR, 15, "eth1mac", "hclk"), 1025 + PER_CLK(RCC_AHB1ENR, 14, "art", "hclk"), 1026 + PER_CLK(RCC_AHB1ENR, 1, "dma2", "hclk"), 1027 + PER_CLK(RCC_AHB1ENR, 0, "dma1", "hclk"), 1028 + PER_CLK(RCC_AHB2ENR, 31, "d2sram3", "hclk"), 1029 + PER_CLK(RCC_AHB2ENR, 30, "d2sram2", "hclk"), 1030 + PER_CLK(RCC_AHB2ENR, 29, "d2sram1", "hclk"), 1031 + PER_CLK(RCC_AHB2ENR, 5, "hash", "hclk"), 1032 + PER_CLK(RCC_AHB2ENR, 4, "crypt", "hclk"), 1033 + PER_CLK(RCC_AHB2ENR, 0, "camitf", "hclk"), 1034 + PER_CLK(RCC_AHB4ENR, 28, "bkpram", "hclk"), 1035 + PER_CLK(RCC_AHB4ENR, 25, "hsem", "hclk"), 1036 + PER_CLK(RCC_AHB4ENR, 21, "bdma", "hclk"), 1037 + PER_CLK(RCC_AHB4ENR, 19, "crc", "hclk"), 1038 + PER_CLK(RCC_AHB4ENR, 10, "gpiok", "hclk"), 1039 + PER_CLK(RCC_AHB4ENR, 9, "gpioj", "hclk"), 1040 + PER_CLK(RCC_AHB4ENR, 8, "gpioi", "hclk"), 1041 + PER_CLK(RCC_AHB4ENR, 7, "gpioh", "hclk"), 1042 + PER_CLK(RCC_AHB4ENR, 6, "gpiog", "hclk"), 1043 + PER_CLK(RCC_AHB4ENR, 5, "gpiof", "hclk"), 1044 + PER_CLK(RCC_AHB4ENR, 4, "gpioe", "hclk"), 1045 + PER_CLK(RCC_AHB4ENR, 3, "gpiod", "hclk"), 1046 + PER_CLK(RCC_AHB4ENR, 2, "gpioc", "hclk"), 1047 + PER_CLK(RCC_AHB4ENR, 1, "gpiob", "hclk"), 1048 + PER_CLK(RCC_AHB4ENR, 0, "gpioa", "hclk"), 1049 + PER_CLK(RCC_APB3ENR, 6, "wwdg1", "pclk3"), 1050 + PER_CLK(RCC_APB1LENR, 29, "dac12", "pclk1"), 1051 + PER_CLK(RCC_APB1LENR, 11, "wwdg2", "pclk1"), 1052 + PER_CLK(RCC_APB1LENR, 8, "tim14", "tim1_ker"), 1053 + PER_CLK(RCC_APB1LENR, 7, "tim13", "tim1_ker"), 1054 + PER_CLK(RCC_APB1LENR, 6, "tim12", "tim1_ker"), 1055 + PER_CLK(RCC_APB1LENR, 5, "tim7", "tim1_ker"), 1056 + PER_CLK(RCC_APB1LENR, 4, "tim6", "tim1_ker"), 1057 + PER_CLK(RCC_APB1LENR, 3, "tim5", "tim1_ker"), 1058 + PER_CLK(RCC_APB1LENR, 2, "tim4", "tim1_ker"), 1059 + PER_CLK(RCC_APB1LENR, 1, "tim3", "tim1_ker"), 1060 + PER_CLK(RCC_APB1LENR, 0, "tim2", "tim1_ker"), 1061 + PER_CLK(RCC_APB1HENR, 5, "mdios", "pclk1"), 1062 + PER_CLK(RCC_APB1HENR, 4, "opamp", "pclk1"), 1063 + PER_CLK(RCC_APB1HENR, 1, "crs", "pclk1"), 1064 + PER_CLK(RCC_APB2ENR, 18, "tim17", "tim2_ker"), 1065 + PER_CLK(RCC_APB2ENR, 17, "tim16", "tim2_ker"), 1066 + PER_CLK(RCC_APB2ENR, 16, "tim15", "tim2_ker"), 1067 + PER_CLK(RCC_APB2ENR, 1, "tim8", "tim2_ker"), 1068 + PER_CLK(RCC_APB2ENR, 0, "tim1", "tim2_ker"), 1069 + PER_CLK(RCC_APB4ENR, 26, "tmpsens", "pclk4"), 1070 + PER_CLK(RCC_APB4ENR, 16, "rtcapb", "pclk4"), 1071 + PER_CLK(RCC_APB4ENR, 15, "vref", "pclk4"), 1072 + PER_CLK(RCC_APB4ENR, 14, "comp12", "pclk4"), 1073 + PER_CLK(RCC_APB4ENR, 1, "syscfg", "pclk4"), 1074 + }; 1075 + 1076 + /* KERNEL CLOCKS */ 1077 + #define KER_CLKF(_gate_offset, _bit_idx,\ 1078 + _mux_offset, _mux_shift, _mux_width,\ 1079 + _name, _parent_name,\ 1080 + _flags) \ 1081 + { \ 1082 + .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\ 1083 + .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\ 1084 + .name = _name, \ 1085 + .parent_name = _parent_name, \ 1086 + .num_parents = ARRAY_SIZE(_parent_name),\ 1087 + .flags = _flags,\ 1088 + } 1089 + 1090 + #define KER_CLK(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\ 1091 + _name, _parent_name) \ 1092 + KER_CLKF(_gate_offset, _bit_idx, _mux_offset, _mux_shift, _mux_width,\ 1093 + _name, _parent_name, 0)\ 1094 + 1095 + #define KER_CLKF_NOMUX(_gate_offset, _bit_idx,\ 1096 + _name, _parent_name,\ 1097 + _flags) \ 1098 + { \ 1099 + .gate = &(struct gate_cfg) {_gate_offset, _bit_idx},\ 1100 + .mux = NULL,\ 1101 + .name = _name, \ 1102 + .parent_name = _parent_name, \ 1103 + .num_parents = 1,\ 1104 + .flags = _flags,\ 1105 + } 1106 + 1107 + static const struct composite_clk_cfg kclk[] = { 1108 + KER_CLK(RCC_AHB3ENR, 16, RCC_D1CCIPR, 16, 1, "sdmmc1", sdmmc_src), 1109 + KER_CLKF(RCC_AHB3ENR, 14, RCC_D1CCIPR, 4, 2, "quadspi", qspi_src, 1110 + CLK_IGNORE_UNUSED), 1111 + KER_CLKF(RCC_AHB3ENR, 12, RCC_D1CCIPR, 0, 2, "fmc", fmc_src, 1112 + CLK_IGNORE_UNUSED), 1113 + KER_CLK(RCC_AHB1ENR, 27, RCC_D2CCIP2R, 20, 2, "usb2otg", usbotg_src), 1114 + KER_CLK(RCC_AHB1ENR, 25, RCC_D2CCIP2R, 20, 2, "usb1otg", usbotg_src), 1115 + KER_CLK(RCC_AHB1ENR, 5, RCC_D3CCIPR, 16, 2, "adc12", adc_src), 1116 + KER_CLK(RCC_AHB2ENR, 9, RCC_D1CCIPR, 16, 1, "sdmmc2", sdmmc_src), 1117 + KER_CLK(RCC_AHB2ENR, 6, RCC_D2CCIP2R, 8, 2, "rng", rng_src), 1118 + KER_CLK(RCC_AHB4ENR, 24, RCC_D3CCIPR, 16, 2, "adc3", adc_src), 1119 + KER_CLKF(RCC_APB3ENR, 4, RCC_D1CCIPR, 8, 1, "dsi", dsi_src, 1120 + CLK_SET_RATE_PARENT), 1121 + KER_CLKF_NOMUX(RCC_APB3ENR, 3, "ltdc", ltdc_src, CLK_SET_RATE_PARENT), 1122 + KER_CLK(RCC_APB1LENR, 31, RCC_D2CCIP2R, 0, 3, "usart8", usart_src2), 1123 + KER_CLK(RCC_APB1LENR, 30, RCC_D2CCIP2R, 0, 3, "usart7", usart_src2), 1124 + KER_CLK(RCC_APB1LENR, 27, RCC_D2CCIP2R, 22, 2, "hdmicec", cec_src), 1125 + KER_CLK(RCC_APB1LENR, 23, RCC_D2CCIP2R, 12, 2, "i2c3", i2c_src1), 1126 + KER_CLK(RCC_APB1LENR, 22, RCC_D2CCIP2R, 12, 2, "i2c2", i2c_src1), 1127 + KER_CLK(RCC_APB1LENR, 21, RCC_D2CCIP2R, 12, 2, "i2c1", i2c_src1), 1128 + KER_CLK(RCC_APB1LENR, 20, RCC_D2CCIP2R, 0, 3, "uart5", usart_src2), 1129 + KER_CLK(RCC_APB1LENR, 19, RCC_D2CCIP2R, 0, 3, "uart4", usart_src2), 1130 + KER_CLK(RCC_APB1LENR, 18, RCC_D2CCIP2R, 0, 3, "usart3", usart_src2), 1131 + KER_CLK(RCC_APB1LENR, 17, RCC_D2CCIP2R, 0, 3, "usart2", usart_src2), 1132 + KER_CLK(RCC_APB1LENR, 16, RCC_D2CCIP1R, 20, 2, "spdifrx", spdifrx_src), 1133 + KER_CLK(RCC_APB1LENR, 15, RCC_D2CCIP1R, 16, 3, "spi3", spi_src1), 1134 + KER_CLK(RCC_APB1LENR, 14, RCC_D2CCIP1R, 16, 3, "spi2", spi_src1), 1135 + KER_CLK(RCC_APB1LENR, 9, RCC_D2CCIP2R, 28, 3, "lptim1", lptim_src1), 1136 + KER_CLK(RCC_APB1HENR, 8, RCC_D2CCIP1R, 28, 2, "fdcan", fdcan_src), 1137 + KER_CLK(RCC_APB1HENR, 2, RCC_D2CCIP1R, 31, 1, "swp", swp_src), 1138 + KER_CLK(RCC_APB2ENR, 29, RCC_CFGR, 14, 1, "hrtim", hrtim_src), 1139 + KER_CLK(RCC_APB2ENR, 28, RCC_D2CCIP1R, 24, 1, "dfsdm1", dfsdm1_src), 1140 + KER_CLKF(RCC_APB2ENR, 24, RCC_D2CCIP1R, 6, 3, "sai3", sai_src, 1141 + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), 1142 + KER_CLKF(RCC_APB2ENR, 23, RCC_D2CCIP1R, 6, 3, "sai2", sai_src, 1143 + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), 1144 + KER_CLKF(RCC_APB2ENR, 22, RCC_D2CCIP1R, 0, 3, "sai1", sai_src, 1145 + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT), 1146 + KER_CLK(RCC_APB2ENR, 20, RCC_D2CCIP1R, 16, 3, "spi5", spi_src2), 1147 + KER_CLK(RCC_APB2ENR, 13, RCC_D2CCIP1R, 16, 3, "spi4", spi_src2), 1148 + KER_CLK(RCC_APB2ENR, 12, RCC_D2CCIP1R, 16, 3, "spi1", spi_src1), 1149 + KER_CLK(RCC_APB2ENR, 5, RCC_D2CCIP2R, 3, 3, "usart6", usart_src1), 1150 + KER_CLK(RCC_APB2ENR, 4, RCC_D2CCIP2R, 3, 3, "usart1", usart_src1), 1151 + KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 24, 3, "sai4b", sai_src), 1152 + KER_CLK(RCC_APB4ENR, 21, RCC_D3CCIPR, 21, 3, "sai4a", sai_src), 1153 + KER_CLK(RCC_APB4ENR, 12, RCC_D3CCIPR, 13, 3, "lptim5", lptim_src2), 1154 + KER_CLK(RCC_APB4ENR, 11, RCC_D3CCIPR, 13, 3, "lptim4", lptim_src2), 1155 + KER_CLK(RCC_APB4ENR, 10, RCC_D3CCIPR, 13, 3, "lptim3", lptim_src2), 1156 + KER_CLK(RCC_APB4ENR, 9, RCC_D3CCIPR, 10, 3, "lptim2", lptim_src2), 1157 + KER_CLK(RCC_APB4ENR, 7, RCC_D3CCIPR, 8, 2, "i2c4", i2c_src2), 1158 + KER_CLK(RCC_APB4ENR, 5, RCC_D3CCIPR, 28, 3, "spi6", spi_src3), 1159 + KER_CLK(RCC_APB4ENR, 3, RCC_D3CCIPR, 0, 3, "lpuart1", lpuart1_src), 1160 + }; 1161 + 1162 + static struct composite_clk_gcfg kernel_clk_cfg = { 1163 + M_CFG_MUX(NULL, 0), 1164 + M_CFG_GATE(NULL, 0), 1165 + }; 1166 + 1167 + /* RTC clock */ 1168 + /* 1169 + * RTC & LSE registers are protected against parasitic write access. 1170 + * PWR_CR_DBP bit must be set to enable write access to RTC registers. 1171 + */ 1172 + /* STM32_PWR_CR */ 1173 + #define PWR_CR 0x00 1174 + /* STM32_PWR_CR bit field */ 1175 + #define PWR_CR_DBP BIT(8) 1176 + 1177 + static struct composite_clk_gcfg rtc_clk_cfg = { 1178 + M_CFG_MUX(NULL, 0), 1179 + M_CFG_GATE(NULL, 0), 1180 + }; 1181 + 1182 + static const struct composite_clk_cfg rtc_clk = 1183 + KER_CLK(RCC_BDCR, 15, RCC_BDCR, 8, 2, "rtc_ck", rtc_src); 1184 + 1185 + /* Micro-controller output clock */ 1186 + static struct composite_clk_gcfg mco_clk_cfg = { 1187 + M_CFG_MUX(NULL, 0), 1188 + M_CFG_DIV(NULL, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), 1189 + }; 1190 + 1191 + #define M_MCO_F(_name, _parents, _mux_offset, _mux_shift, _mux_width,\ 1192 + _rate_offset, _rate_shift, _rate_width,\ 1193 + _flags)\ 1194 + {\ 1195 + .mux = &(struct muxdiv_cfg) {_mux_offset, _mux_shift, _mux_width },\ 1196 + .div = &(struct muxdiv_cfg) {_rate_offset, _rate_shift, _rate_width},\ 1197 + .gate = NULL,\ 1198 + .name = _name,\ 1199 + .parent_name = _parents,\ 1200 + .num_parents = ARRAY_SIZE(_parents),\ 1201 + .flags = _flags,\ 1202 + } 1203 + 1204 + static const struct composite_clk_cfg mco_clk[] = { 1205 + M_MCO_F("mco1", mco_src1, RCC_CFGR, 22, 4, RCC_CFGR, 18, 4, 0), 1206 + M_MCO_F("mco2", mco_src2, RCC_CFGR, 29, 3, RCC_CFGR, 25, 4, 0), 1207 + }; 1208 + 1209 + static void __init stm32h7_rcc_init(struct device_node *np) 1210 + { 1211 + struct clk_hw_onecell_data *clk_data; 1212 + struct composite_cfg c_cfg; 1213 + int n; 1214 + const char *hse_clk, *lse_clk, *i2s_clk; 1215 + struct regmap *pdrm; 1216 + 1217 + clk_data = kzalloc(sizeof(*clk_data) + 1218 + sizeof(*clk_data->hws) * STM32H7_MAX_CLKS, 1219 + GFP_KERNEL); 1220 + if (!clk_data) 1221 + return; 1222 + 1223 + clk_data->num = STM32H7_MAX_CLKS; 1224 + 1225 + hws = clk_data->hws; 1226 + 1227 + for (n = 0; n < STM32H7_MAX_CLKS; n++) 1228 + hws[n] = ERR_PTR(-ENOENT); 1229 + 1230 + /* get RCC base @ from DT */ 1231 + base = of_iomap(np, 0); 1232 + if (!base) { 1233 + pr_err("%s: unable to map resource", np->name); 1234 + goto err_free_clks; 1235 + } 1236 + 1237 + pdrm = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); 1238 + if (IS_ERR(pdrm)) 1239 + pr_warn("%s: Unable to get syscfg\n", __func__); 1240 + else 1241 + /* In any case disable backup domain write protection 1242 + * and will never be enabled. 1243 + * Needed by LSE & RTC clocks. 1244 + */ 1245 + regmap_update_bits(pdrm, PWR_CR, PWR_CR_DBP, PWR_CR_DBP); 1246 + 1247 + /* Put parent names from DT */ 1248 + hse_clk = of_clk_get_parent_name(np, 0); 1249 + lse_clk = of_clk_get_parent_name(np, 1); 1250 + i2s_clk = of_clk_get_parent_name(np, 2); 1251 + 1252 + sai_src[3] = i2s_clk; 1253 + spi_src1[3] = i2s_clk; 1254 + 1255 + /* Register Internal oscillators */ 1256 + clk_hw_register_fixed_rate(NULL, "clk-hsi", NULL, 0, 64000000); 1257 + clk_hw_register_fixed_rate(NULL, "clk-csi", NULL, 0, 4000000); 1258 + clk_hw_register_fixed_rate(NULL, "clk-lsi", NULL, 0, 32000); 1259 + clk_hw_register_fixed_rate(NULL, "clk-rc48", NULL, 0, 48000); 1260 + 1261 + /* This clock is coming from outside. Frequencies unknown */ 1262 + hws[CK_DSI_PHY] = clk_hw_register_fixed_rate(NULL, "ck_dsi_phy", NULL, 1263 + 0, 0); 1264 + 1265 + hws[HSI_DIV] = clk_hw_register_divider(NULL, "hsidiv", "clk-hsi", 0, 1266 + base + RCC_CR, 3, 2, CLK_DIVIDER_POWER_OF_TWO, 1267 + &stm32rcc_lock); 1268 + 1269 + hws[HSE_1M] = clk_hw_register_divider(NULL, "hse_1M", "hse_ck", 0, 1270 + base + RCC_CFGR, 8, 6, CLK_DIVIDER_ONE_BASED | 1271 + CLK_DIVIDER_ALLOW_ZERO, 1272 + &stm32rcc_lock); 1273 + 1274 + /* Mux system clocks */ 1275 + for (n = 0; n < ARRAY_SIZE(stm32_mclk); n++) 1276 + hws[MCLK_BANK + n] = clk_hw_register_mux(NULL, 1277 + stm32_mclk[n].name, 1278 + stm32_mclk[n].parents, 1279 + stm32_mclk[n].num_parents, 1280 + stm32_mclk[n].flags, 1281 + stm32_mclk[n].offset + base, 1282 + stm32_mclk[n].shift, 1283 + stm32_mclk[n].width, 1284 + 0, 1285 + &stm32rcc_lock); 1286 + 1287 + register_core_and_bus_clocks(); 1288 + 1289 + /* Oscillary clocks */ 1290 + for (n = 0; n < ARRAY_SIZE(stm32_oclk); n++) 1291 + hws[OSC_BANK + n] = clk_register_ready_gate(NULL, 1292 + stm32_oclk[n].name, 1293 + stm32_oclk[n].parent, 1294 + stm32_oclk[n].gate_offset + base, 1295 + stm32_oclk[n].bit_idx, 1296 + stm32_oclk[n].bit_rdy, 1297 + stm32_oclk[n].flags, 1298 + &stm32rcc_lock); 1299 + 1300 + hws[HSE_CK] = clk_register_ready_gate(NULL, 1301 + "hse_ck", 1302 + hse_clk, 1303 + RCC_CR + base, 1304 + 16, 17, 1305 + 0, 1306 + &stm32rcc_lock); 1307 + 1308 + hws[LSE_CK] = clk_register_ready_gate(NULL, 1309 + "lse_ck", 1310 + lse_clk, 1311 + RCC_BDCR + base, 1312 + 0, 1, 1313 + 0, 1314 + &stm32rcc_lock); 1315 + 1316 + hws[CSI_KER_DIV122 + n] = clk_hw_register_fixed_factor(NULL, 1317 + "csi_ker_div122", "csi_ker", 0, 1, 122); 1318 + 1319 + /* PLLs */ 1320 + for (n = 0; n < ARRAY_SIZE(stm32_pll); n++) { 1321 + int odf; 1322 + 1323 + /* Register the VCO */ 1324 + clk_register_stm32_pll(NULL, stm32_pll[n].name, 1325 + stm32_pll[n].parent_name, stm32_pll[n].flags, 1326 + stm32_pll[n].cfg, 1327 + &stm32rcc_lock); 1328 + 1329 + /* Register the 3 output dividers */ 1330 + for (odf = 0; odf < 3; odf++) { 1331 + int idx = n * 3 + odf; 1332 + 1333 + get_cfg_composite_div(&odf_clk_gcfg, &stm32_odf[n][odf], 1334 + &c_cfg, &stm32rcc_lock); 1335 + 1336 + hws[ODF_BANK + idx] = clk_hw_register_composite(NULL, 1337 + stm32_odf[n][odf].name, 1338 + stm32_odf[n][odf].parent_name, 1339 + stm32_odf[n][odf].num_parents, 1340 + c_cfg.mux_hw, c_cfg.mux_ops, 1341 + c_cfg.div_hw, c_cfg.div_ops, 1342 + c_cfg.gate_hw, c_cfg.gate_ops, 1343 + stm32_odf[n][odf].flags); 1344 + } 1345 + } 1346 + 1347 + /* Peripheral clocks */ 1348 + for (n = 0; n < ARRAY_SIZE(pclk); n++) 1349 + hws[PERIF_BANK + n] = clk_hw_register_gate(NULL, pclk[n].name, 1350 + pclk[n].parent, 1351 + pclk[n].flags, base + pclk[n].gate_offset, 1352 + pclk[n].bit_idx, pclk[n].flags, &stm32rcc_lock); 1353 + 1354 + /* Kernel clocks */ 1355 + for (n = 0; n < ARRAY_SIZE(kclk); n++) { 1356 + get_cfg_composite_div(&kernel_clk_cfg, &kclk[n], &c_cfg, 1357 + &stm32rcc_lock); 1358 + 1359 + hws[KERN_BANK + n] = clk_hw_register_composite(NULL, 1360 + kclk[n].name, 1361 + kclk[n].parent_name, 1362 + kclk[n].num_parents, 1363 + c_cfg.mux_hw, c_cfg.mux_ops, 1364 + c_cfg.div_hw, c_cfg.div_ops, 1365 + c_cfg.gate_hw, c_cfg.gate_ops, 1366 + kclk[n].flags); 1367 + } 1368 + 1369 + /* RTC clock (default state is off) */ 1370 + clk_hw_register_fixed_rate(NULL, "off", NULL, 0, 0); 1371 + 1372 + get_cfg_composite_div(&rtc_clk_cfg, &rtc_clk, &c_cfg, &stm32rcc_lock); 1373 + 1374 + hws[RTC_CK] = clk_hw_register_composite(NULL, 1375 + rtc_clk.name, 1376 + rtc_clk.parent_name, 1377 + rtc_clk.num_parents, 1378 + c_cfg.mux_hw, c_cfg.mux_ops, 1379 + c_cfg.div_hw, c_cfg.div_ops, 1380 + c_cfg.gate_hw, c_cfg.gate_ops, 1381 + rtc_clk.flags); 1382 + 1383 + /* Micro-controller clocks */ 1384 + for (n = 0; n < ARRAY_SIZE(mco_clk); n++) { 1385 + get_cfg_composite_div(&mco_clk_cfg, &mco_clk[n], &c_cfg, 1386 + &stm32rcc_lock); 1387 + 1388 + hws[MCO_BANK + n] = clk_hw_register_composite(NULL, 1389 + mco_clk[n].name, 1390 + mco_clk[n].parent_name, 1391 + mco_clk[n].num_parents, 1392 + c_cfg.mux_hw, c_cfg.mux_ops, 1393 + c_cfg.div_hw, c_cfg.div_ops, 1394 + c_cfg.gate_hw, c_cfg.gate_ops, 1395 + mco_clk[n].flags); 1396 + } 1397 + 1398 + of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data); 1399 + 1400 + return; 1401 + 1402 + err_free_clks: 1403 + kfree(clk_data); 1404 + } 1405 + 1406 + /* The RCC node is a clock and reset controller, and these 1407 + * functionalities are supported by different drivers that 1408 + * matches the same compatible strings. 1409 + */ 1410 + CLK_OF_DECLARE_DRIVER(stm32h7_rcc, "st,stm32h743-rcc", stm32h7_rcc_init);
+159 -13
drivers/clk/clk-versaclock5.c
··· 57 57 #define VC5_PRIM_SRC_SHDN 0x10 58 58 #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7) 59 59 #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6) 60 + #define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ BIT(3) 60 61 #define VC5_PRIM_SRC_SHDN_SP BIT(1) 61 62 #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0) 62 63 ··· 123 122 /* flags to describe chip features */ 124 123 /* chip has built-in oscilator */ 125 124 #define VC5_HAS_INTERNAL_XTAL BIT(0) 125 + /* chip has PFD requency doubler */ 126 + #define VC5_HAS_PFD_FREQ_DBL BIT(1) 126 127 127 128 /* Supported IDT VC5 models. */ 128 129 enum vc5_model { 129 130 IDT_VC5_5P49V5923, 131 + IDT_VC5_5P49V5925, 130 132 IDT_VC5_5P49V5933, 131 133 IDT_VC5_5P49V5935, 134 + IDT_VC6_5P49V6901, 132 135 }; 133 136 134 137 /* Structure to describe features of a particular VC5 model */ ··· 162 157 struct clk *pin_clkin; 163 158 unsigned char clk_mux_ins; 164 159 struct clk_hw clk_mux; 160 + struct clk_hw clk_mul; 161 + struct clk_hw clk_pfd; 165 162 struct vc5_hw_data clk_pll; 166 163 struct vc5_hw_data clk_fod[VC5_MAX_FOD_NUM]; 167 164 struct vc5_hw_data clk_out[VC5_MAX_CLK_OUT_NUM]; ··· 171 164 172 165 static const char * const vc5_mux_names[] = { 173 166 "mux" 167 + }; 168 + 169 + static const char * const vc5_dbl_names[] = { 170 + "dbl" 171 + }; 172 + 173 + static const char * const vc5_pfd_names[] = { 174 + "pfd" 174 175 }; 175 176 176 177 static const char * const vc5_pll_names[] = { ··· 269 254 return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src); 270 255 } 271 256 272 - static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw, 257 + static const struct clk_ops vc5_mux_ops = { 258 + .set_parent = vc5_mux_set_parent, 259 + .get_parent = vc5_mux_get_parent, 260 + }; 261 + 262 + static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw, 273 263 unsigned long parent_rate) 274 264 { 275 265 struct vc5_driver_data *vc5 = 276 - container_of(hw, struct vc5_driver_data, clk_mux); 266 + container_of(hw, struct vc5_driver_data, clk_mul); 267 + unsigned int premul; 268 + 269 + regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &premul); 270 + if (premul & VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ) 271 + parent_rate *= 2; 272 + 273 + return parent_rate; 274 + } 275 + 276 + static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate, 277 + unsigned long *parent_rate) 278 + { 279 + if ((*parent_rate == rate) || ((*parent_rate * 2) == rate)) 280 + return rate; 281 + else 282 + return -EINVAL; 283 + } 284 + 285 + static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate, 286 + unsigned long parent_rate) 287 + { 288 + struct vc5_driver_data *vc5 = 289 + container_of(hw, struct vc5_driver_data, clk_mul); 290 + u32 mask; 291 + 292 + if ((parent_rate * 2) == rate) 293 + mask = VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ; 294 + else 295 + mask = 0; 296 + 297 + regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, 298 + VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ, 299 + mask); 300 + 301 + return 0; 302 + } 303 + 304 + static const struct clk_ops vc5_dbl_ops = { 305 + .recalc_rate = vc5_dbl_recalc_rate, 306 + .round_rate = vc5_dbl_round_rate, 307 + .set_rate = vc5_dbl_set_rate, 308 + }; 309 + 310 + static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw, 311 + unsigned long parent_rate) 312 + { 313 + struct vc5_driver_data *vc5 = 314 + container_of(hw, struct vc5_driver_data, clk_pfd); 277 315 unsigned int prediv, div; 278 316 279 317 regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv); ··· 344 276 return parent_rate / VC5_REF_DIVIDER_REF_DIV(div); 345 277 } 346 278 347 - static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate, 279 + static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate, 348 280 unsigned long *parent_rate) 349 281 { 350 282 unsigned long idiv; ··· 364 296 return *parent_rate / idiv; 365 297 } 366 298 367 - static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate, 299 + static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate, 368 300 unsigned long parent_rate) 369 301 { 370 302 struct vc5_driver_data *vc5 = 371 - container_of(hw, struct vc5_driver_data, clk_mux); 303 + container_of(hw, struct vc5_driver_data, clk_pfd); 372 304 unsigned long idiv; 373 305 u8 div; 374 306 ··· 396 328 return 0; 397 329 } 398 330 399 - static const struct clk_ops vc5_mux_ops = { 400 - .set_parent = vc5_mux_set_parent, 401 - .get_parent = vc5_mux_get_parent, 402 - .recalc_rate = vc5_mux_recalc_rate, 403 - .round_rate = vc5_mux_round_rate, 404 - .set_rate = vc5_mux_set_rate, 331 + static const struct clk_ops vc5_pfd_ops = { 332 + .recalc_rate = vc5_pfd_recalc_rate, 333 + .round_rate = vc5_pfd_round_rate, 334 + .set_rate = vc5_pfd_set_rate, 405 335 }; 406 336 407 337 /* ··· 492 426 div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) | 493 427 (od_frc[2] << 6) | (od_frc[3] >> 2); 494 428 429 + /* Avoid division by zero if the output is not configured. */ 430 + if (div_int == 0 && div_frc == 0) 431 + return 0; 432 + 495 433 /* The PLL divider has 12 integer bits and 30 fractional bits */ 496 434 return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc); 497 435 } ··· 573 503 { 574 504 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 575 505 struct vc5_driver_data *vc5 = hwdata->vc5; 506 + const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM | 507 + VC5_OUT_DIV_CONTROL_SEL_EXT | 508 + VC5_OUT_DIV_CONTROL_EN_FOD; 509 + unsigned int src; 510 + int ret; 511 + 512 + /* 513 + * If the input mux is disabled, enable it first and 514 + * select source from matching FOD. 515 + */ 516 + regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); 517 + if ((src & mask) == 0) { 518 + src = VC5_OUT_DIV_CONTROL_RESET | VC5_OUT_DIV_CONTROL_EN_FOD; 519 + ret = regmap_update_bits(vc5->regmap, 520 + VC5_OUT_DIV_CONTROL(hwdata->num), 521 + mask | VC5_OUT_DIV_CONTROL_RESET, src); 522 + if (ret) 523 + return ret; 524 + } 576 525 577 526 /* Enable the clock buffer */ 578 527 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), ··· 605 516 struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw); 606 517 struct vc5_driver_data *vc5 = hwdata->vc5; 607 518 608 - /* Enable the clock buffer */ 519 + /* Disable the clock buffer */ 609 520 regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1), 610 521 VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0); 611 522 } ··· 625 536 626 537 regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src); 627 538 src &= mask; 539 + 540 + if (src == 0) /* Input mux set to DISABLED */ 541 + return 0; 628 542 629 543 if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD) 630 544 return 0; ··· 687 595 case IDT_VC5_5P49V5933: 688 596 return (n == 0) ? 0 : 3; 689 597 case IDT_VC5_5P49V5923: 598 + case IDT_VC5_5P49V5925: 690 599 case IDT_VC5_5P49V5935: 600 + case IDT_VC6_5P49V6901: 691 601 default: 692 602 return n; 693 603 } ··· 766 672 goto err_clk; 767 673 } 768 674 675 + if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) { 676 + /* Register frequency doubler */ 677 + memset(&init, 0, sizeof(init)); 678 + init.name = vc5_dbl_names[0]; 679 + init.ops = &vc5_dbl_ops; 680 + init.flags = CLK_SET_RATE_PARENT; 681 + init.parent_names = vc5_mux_names; 682 + init.num_parents = 1; 683 + vc5->clk_mul.init = &init; 684 + ret = devm_clk_hw_register(&client->dev, &vc5->clk_mul); 685 + if (ret) { 686 + dev_err(&client->dev, "unable to register %s\n", 687 + init.name); 688 + goto err_clk; 689 + } 690 + } 691 + 692 + /* Register PFD */ 693 + memset(&init, 0, sizeof(init)); 694 + init.name = vc5_pfd_names[0]; 695 + init.ops = &vc5_pfd_ops; 696 + init.flags = CLK_SET_RATE_PARENT; 697 + if (vc5->chip_info->flags & VC5_HAS_PFD_FREQ_DBL) 698 + init.parent_names = vc5_dbl_names; 699 + else 700 + init.parent_names = vc5_mux_names; 701 + init.num_parents = 1; 702 + vc5->clk_pfd.init = &init; 703 + ret = devm_clk_hw_register(&client->dev, &vc5->clk_pfd); 704 + if (ret) { 705 + dev_err(&client->dev, "unable to register %s\n", init.name); 706 + goto err_clk; 707 + } 708 + 769 709 /* Register PLL */ 770 710 memset(&init, 0, sizeof(init)); 771 711 init.name = vc5_pll_names[0]; 772 712 init.ops = &vc5_pll_ops; 773 713 init.flags = CLK_SET_RATE_PARENT; 774 - init.parent_names = vc5_mux_names; 714 + init.parent_names = vc5_pfd_names; 775 715 init.num_parents = 1; 776 716 vc5->clk_pll.num = 0; 777 717 vc5->clk_pll.vc5 = vc5; ··· 913 785 .flags = 0, 914 786 }; 915 787 788 + static const struct vc5_chip_info idt_5p49v5925_info = { 789 + .model = IDT_VC5_5P49V5925, 790 + .clk_fod_cnt = 4, 791 + .clk_out_cnt = 5, 792 + .flags = 0, 793 + }; 794 + 916 795 static const struct vc5_chip_info idt_5p49v5933_info = { 917 796 .model = IDT_VC5_5P49V5933, 918 797 .clk_fod_cnt = 2, ··· 934 799 .flags = VC5_HAS_INTERNAL_XTAL, 935 800 }; 936 801 802 + static const struct vc5_chip_info idt_5p49v6901_info = { 803 + .model = IDT_VC6_5P49V6901, 804 + .clk_fod_cnt = 4, 805 + .clk_out_cnt = 5, 806 + .flags = VC5_HAS_PFD_FREQ_DBL, 807 + }; 808 + 937 809 static const struct i2c_device_id vc5_id[] = { 938 810 { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 }, 811 + { "5p49v5925", .driver_data = IDT_VC5_5P49V5925 }, 939 812 { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 }, 940 813 { "5p49v5935", .driver_data = IDT_VC5_5P49V5935 }, 814 + { "5p49v6901", .driver_data = IDT_VC6_5P49V6901 }, 941 815 { } 942 816 }; 943 817 MODULE_DEVICE_TABLE(i2c, vc5_id); 944 818 945 819 static const struct of_device_id clk_vc5_of_match[] = { 946 820 { .compatible = "idt,5p49v5923", .data = &idt_5p49v5923_info }, 821 + { .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info }, 947 822 { .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info }, 948 823 { .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info }, 824 + { .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info }, 949 825 { }, 950 826 }; 951 827 MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
+6 -9
drivers/clk/clk-xgene.c
··· 192 192 193 193 reg = of_iomap(np, 0); 194 194 if (reg == NULL) { 195 - pr_err("Unable to map CSR register for %s\n", np->full_name); 195 + pr_err("Unable to map CSR register for %pOF\n", np); 196 196 return; 197 197 } 198 198 of_property_read_string(np, "clock-output-names", &clk_name); ··· 409 409 /* Parse the DTS register for resource */ 410 410 rc = of_address_to_resource(np, 0, &res); 411 411 if (rc != 0) { 412 - pr_err("no DTS register for %s\n", np->full_name); 412 + pr_err("no DTS register for %pOF\n", np); 413 413 return; 414 414 } 415 415 csr_reg = of_iomap(np, 0); 416 416 if (!csr_reg) { 417 - pr_err("Unable to map resource for %s\n", np->full_name); 417 + pr_err("Unable to map resource for %pOF\n", np); 418 418 return; 419 419 } 420 420 of_property_read_string(np, "clock-output-names", &clk_name); ··· 703 703 rc = of_address_to_resource(np, i, &res); 704 704 if (rc != 0) { 705 705 if (i == 0) { 706 - pr_err("no DTS register for %s\n", 707 - np->full_name); 706 + pr_err("no DTS register for %pOF\n", np); 708 707 return; 709 708 } 710 709 break; 711 710 } 712 711 map_res = of_iomap(np, i); 713 712 if (map_res == NULL) { 714 - pr_err("Unable to map resource %d for %s\n", 715 - i, np->full_name); 713 + pr_err("Unable to map resource %d for %pOF\n", i, np); 716 714 goto err; 717 715 } 718 716 if (strcmp(res.name, "div-reg") == 0) ··· 745 747 pr_debug("Add %s clock\n", clk_name); 746 748 rc = of_clk_add_provider(np, of_clk_src_simple_get, clk); 747 749 if (rc != 0) 748 - pr_err("%s: could register provider clk %s\n", __func__, 749 - np->full_name); 750 + pr_err("%s: could register provider clk %pOF\n", __func__, np); 750 751 751 752 return; 752 753
+2 -2
drivers/clk/clk.c
··· 3132 3132 mutex_lock(&of_clk_mutex); 3133 3133 list_add(&cp->link, &of_clk_providers); 3134 3134 mutex_unlock(&of_clk_mutex); 3135 - pr_debug("Added clock from %s\n", np->full_name); 3135 + pr_debug("Added clock from %pOF\n", np); 3136 3136 3137 3137 ret = of_clk_set_defaults(np, true); 3138 3138 if (ret < 0) ··· 3167 3167 mutex_lock(&of_clk_mutex); 3168 3168 list_add(&cp->link, &of_clk_providers); 3169 3169 mutex_unlock(&of_clk_mutex); 3170 - pr_debug("Added clk_hw provider from %s\n", np->full_name); 3170 + pr_debug("Added clk_hw provider from %pOF\n", np); 3171 3171 3172 3172 ret = of_clk_set_defaults(np, true); 3173 3173 if (ret < 0)
+2 -2
drivers/clk/clkdev.c
··· 77 77 break; 78 78 } else if (name && index >= 0) { 79 79 if (PTR_ERR(clk) != -EPROBE_DEFER) 80 - pr_err("ERROR: could not get clock %s:%s(%i)\n", 81 - np->full_name, name ? name : "", index); 80 + pr_err("ERROR: could not get clock %pOF:%s(%i)\n", 81 + np, name ? name : "", index); 82 82 return clk; 83 83 } 84 84
+3 -3
drivers/clk/hisilicon/clk-hi6220.c
··· 55 55 }; 56 56 57 57 static struct hisi_gate_clock hi6220_separated_gate_clks_ao[] __initdata = { 58 - { HI6220_WDT0_PCLK, "wdt0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, }, 59 - { HI6220_WDT1_PCLK, "wdt1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, }, 60 - { HI6220_WDT2_PCLK, "wdt2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, }, 58 + { HI6220_WDT0_PCLK, "wdt0_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 12, 0, }, 59 + { HI6220_WDT1_PCLK, "wdt1_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 13, 0, }, 60 + { HI6220_WDT2_PCLK, "wdt2_pclk", "ref32k", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 14, 0, }, 61 61 { HI6220_TIMER0_PCLK, "timer0_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 15, 0, }, 62 62 { HI6220_TIMER1_PCLK, "timer1_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 16, 0, }, 63 63 { HI6220_TIMER2_PCLK, "timer2_pclk", "clk_tcxo", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x630, 17, 0, },
+4 -4
drivers/clk/imx/clk-imx51-imx53.c
··· 416 416 417 417 clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, 418 418 lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); 419 - clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 420 - mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); 421 - clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 422 - mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); 419 + clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux_flags("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, 420 + mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel), CLK_SET_RATE_PARENT); 421 + clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux_flags("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, 422 + mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel), CLK_SET_RATE_PARENT); 423 423 clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, 424 424 mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); 425 425 clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1,
+3 -3
drivers/clk/imx/clk-imx6sl.c
··· 71 71 static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; 72 72 static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; 73 73 74 - static struct clk_div_table clk_enet_ref_table[] = { 74 + static const struct clk_div_table clk_enet_ref_table[] = { 75 75 { .val = 0, .div = 20, }, 76 76 { .val = 1, .div = 10, }, 77 77 { .val = 2, .div = 5, }, ··· 79 79 { } 80 80 }; 81 81 82 - static struct clk_div_table post_div_table[] = { 82 + static const struct clk_div_table post_div_table[] = { 83 83 { .val = 2, .div = 1, }, 84 84 { .val = 1, .div = 2, }, 85 85 { .val = 0, .div = 4, }, 86 86 { } 87 87 }; 88 88 89 - static struct clk_div_table video_div_table[] = { 89 + static const struct clk_div_table video_div_table[] = { 90 90 { .val = 0, .div = 1, }, 91 91 { .val = 1, .div = 2, }, 92 92 { .val = 2, .div = 1, },
+3 -3
drivers/clk/imx/clk-imx6sx.c
··· 105 105 IMX6SX_CLK_EPIT2, 106 106 }; 107 107 108 - static struct clk_div_table clk_enet_ref_table[] = { 108 + static const struct clk_div_table clk_enet_ref_table[] = { 109 109 { .val = 0, .div = 20, }, 110 110 { .val = 1, .div = 10, }, 111 111 { .val = 2, .div = 5, }, ··· 113 113 { } 114 114 }; 115 115 116 - static struct clk_div_table post_div_table[] = { 116 + static const struct clk_div_table post_div_table[] = { 117 117 { .val = 2, .div = 1, }, 118 118 { .val = 1, .div = 2, }, 119 119 { .val = 0, .div = 4, }, 120 120 { } 121 121 }; 122 122 123 - static struct clk_div_table video_div_table[] = { 123 + static const struct clk_div_table video_div_table[] = { 124 124 { .val = 0, .div = 1, }, 125 125 { .val = 1, .div = 2, }, 126 126 { .val = 2, .div = 1, },
+3 -3
drivers/clk/imx/clk-imx6ul.c
··· 78 78 IMX6UL_CLK_MMDC_P0_FAST, IMX6UL_CLK_MMDC_P0_IPG, 79 79 }; 80 80 81 - static struct clk_div_table clk_enet_ref_table[] = { 81 + static const struct clk_div_table clk_enet_ref_table[] = { 82 82 { .val = 0, .div = 20, }, 83 83 { .val = 1, .div = 10, }, 84 84 { .val = 2, .div = 5, }, ··· 86 86 { } 87 87 }; 88 88 89 - static struct clk_div_table post_div_table[] = { 89 + static const struct clk_div_table post_div_table[] = { 90 90 { .val = 2, .div = 1, }, 91 91 { .val = 1, .div = 2, }, 92 92 { .val = 0, .div = 4, }, 93 93 { } 94 94 }; 95 95 96 - static struct clk_div_table video_div_table[] = { 96 + static const struct clk_div_table video_div_table[] = { 97 97 { .val = 0, .div = 1, }, 98 98 { .val = 1, .div = 2, }, 99 99 { .val = 2, .div = 1, },
+2 -2
drivers/clk/imx/clk-imx7d.c
··· 27 27 static u32 share_count_sai3; 28 28 static u32 share_count_nand; 29 29 30 - static struct clk_div_table test_div_table[] = { 30 + static const struct clk_div_table test_div_table[] = { 31 31 { .val = 3, .div = 1, }, 32 32 { .val = 2, .div = 1, }, 33 33 { .val = 1, .div = 2, }, ··· 35 35 { } 36 36 }; 37 37 38 - static struct clk_div_table post_div_table[] = { 38 + static const struct clk_div_table post_div_table[] = { 39 39 { .val = 3, .div = 4, }, 40 40 { .val = 2, .div = 1, }, 41 41 { .val = 1, .div = 2, },
+1 -1
drivers/clk/imx/clk-vf610.c
··· 102 102 static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", }; 103 103 104 104 105 - static struct clk_div_table pll4_audio_div_table[] = { 105 + static const struct clk_div_table pll4_audio_div_table[] = { 106 106 { .val = 0, .div = 1 }, 107 107 { .val = 1, .div = 2 }, 108 108 { .val = 2, .div = 6 },
+1 -5
drivers/clk/mediatek/clk-cpumux.c
··· 27 27 static u8 clk_cpumux_get_parent(struct clk_hw *hw) 28 28 { 29 29 struct mtk_clk_cpumux *mux = to_mtk_clk_cpumux(hw); 30 - int num_parents = clk_hw_get_num_parents(hw); 31 30 unsigned int val; 32 31 33 32 regmap_read(mux->regmap, mux->reg, &val); 34 33 35 34 val >>= mux->shift; 36 35 val &= mux->mask; 37 - 38 - if (val >= num_parents) 39 - return -EINVAL; 40 36 41 37 return val; 42 38 } ··· 94 98 95 99 regmap = syscon_node_to_regmap(node); 96 100 if (IS_ERR(regmap)) { 97 - pr_err("Cannot find regmap for %s: %ld\n", node->full_name, 101 + pr_err("Cannot find regmap for %pOF: %ld\n", node, 98 102 PTR_ERR(regmap)); 99 103 return PTR_ERR(regmap); 100 104 }
+1 -1
drivers/clk/mediatek/clk-mtk.c
··· 114 114 115 115 regmap = syscon_node_to_regmap(node); 116 116 if (IS_ERR(regmap)) { 117 - pr_err("Cannot find regmap for %s: %ld\n", node->full_name, 117 + pr_err("Cannot find regmap for %pOF: %ld\n", node, 118 118 PTR_ERR(regmap)); 119 119 return PTR_ERR(regmap); 120 120 }
+1 -1
drivers/clk/mediatek/reset.c
··· 72 72 73 73 regmap = syscon_node_to_regmap(np); 74 74 if (IS_ERR(regmap)) { 75 - pr_err("Cannot find regmap for %s: %ld\n", np->full_name, 75 + pr_err("Cannot find regmap for %pOF: %ld\n", np, 76 76 PTR_ERR(regmap)); 77 77 return; 78 78 }
+1
drivers/clk/meson/Kconfig
··· 6 6 config COMMON_CLK_MESON8B 7 7 bool 8 8 depends on COMMON_CLK_AMLOGIC 9 + select RESET_CONTROLLER 9 10 help 10 11 Support for the clock controller on AmLogic S802 (Meson8), 11 12 S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
+1 -1
drivers/clk/meson/Makefile
··· 4 4 5 5 obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-cpu.o clk-mpll.o clk-audio-divider.o 6 6 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o 7 - obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o 7 + obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-regmap.o gxbb-aoclk-32k.o
+194
drivers/clk/meson/gxbb-aoclk-32k.c
··· 1 + /* 2 + * Copyright (c) 2017 BayLibre, SAS. 3 + * Author: Neil Armstrong <narmstrong@baylibre.com> 4 + * 5 + * SPDX-License-Identifier: GPL-2.0+ 6 + */ 7 + 8 + #include <linux/clk-provider.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/regmap.h> 11 + #include "gxbb-aoclk.h" 12 + 13 + /* 14 + * The AO Domain embeds a dual/divider to generate a more precise 15 + * 32,768KHz clock for low-power suspend mode and CEC. 16 + * ______ ______ 17 + * | | | | 18 + * ______ | Div1 |-| Cnt1 | ______ 19 + * | | /|______| |______|\ | | 20 + * Xtal-->| Gate |---| ______ ______ X-X--| Gate |--> 21 + * |______| | \| | | |/ | |______| 22 + * | | Div2 |-| Cnt2 | | 23 + * | |______| |______| | 24 + * |_______________________| 25 + * 26 + * The dividing can be switched to single or dual, with a counter 27 + * for each divider to set when the switching is done. 28 + * The entire dividing mechanism can be also bypassed. 29 + */ 30 + 31 + #define CLK_CNTL0_N1_MASK GENMASK(11, 0) 32 + #define CLK_CNTL0_N2_MASK GENMASK(23, 12) 33 + #define CLK_CNTL0_DUALDIV_EN BIT(28) 34 + #define CLK_CNTL0_OUT_GATE_EN BIT(30) 35 + #define CLK_CNTL0_IN_GATE_EN BIT(31) 36 + 37 + #define CLK_CNTL1_M1_MASK GENMASK(11, 0) 38 + #define CLK_CNTL1_M2_MASK GENMASK(23, 12) 39 + #define CLK_CNTL1_BYPASS_EN BIT(24) 40 + #define CLK_CNTL1_SELECT_OSC BIT(27) 41 + 42 + #define PWR_CNTL_ALT_32K_SEL GENMASK(13, 10) 43 + 44 + struct cec_32k_freq_table { 45 + unsigned long parent_rate; 46 + unsigned long target_rate; 47 + bool dualdiv; 48 + unsigned int n1; 49 + unsigned int n2; 50 + unsigned int m1; 51 + unsigned int m2; 52 + }; 53 + 54 + static const struct cec_32k_freq_table aoclk_cec_32k_table[] = { 55 + [0] = { 56 + .parent_rate = 24000000, 57 + .target_rate = 32768, 58 + .dualdiv = true, 59 + .n1 = 733, 60 + .n2 = 732, 61 + .m1 = 8, 62 + .m2 = 11, 63 + }, 64 + }; 65 + 66 + /* 67 + * If CLK_CNTL0_DUALDIV_EN == 0 68 + * - will use N1 divider only 69 + * If CLK_CNTL0_DUALDIV_EN == 1 70 + * - hold M1 cycles of N1 divider then changes to N2 71 + * - hold M2 cycles of N2 divider then changes to N1 72 + * Then we can get more accurate division. 73 + */ 74 + static unsigned long aoclk_cec_32k_recalc_rate(struct clk_hw *hw, 75 + unsigned long parent_rate) 76 + { 77 + struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); 78 + unsigned long n1; 79 + u32 reg0, reg1; 80 + 81 + regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, &reg0); 82 + regmap_read(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, &reg1); 83 + 84 + if (reg1 & CLK_CNTL1_BYPASS_EN) 85 + return parent_rate; 86 + 87 + if (reg0 & CLK_CNTL0_DUALDIV_EN) { 88 + unsigned long n2, m1, m2, f1, f2, p1, p2; 89 + 90 + n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; 91 + n2 = FIELD_GET(CLK_CNTL0_N2_MASK, reg0) + 1; 92 + 93 + m1 = FIELD_GET(CLK_CNTL1_M1_MASK, reg1) + 1; 94 + m2 = FIELD_GET(CLK_CNTL1_M2_MASK, reg1) + 1; 95 + 96 + f1 = DIV_ROUND_CLOSEST(parent_rate, n1); 97 + f2 = DIV_ROUND_CLOSEST(parent_rate, n2); 98 + 99 + p1 = DIV_ROUND_CLOSEST(100000000 * m1, f1 * (m1 + m2)); 100 + p2 = DIV_ROUND_CLOSEST(100000000 * m2, f2 * (m1 + m2)); 101 + 102 + return DIV_ROUND_UP(100000000, p1 + p2); 103 + } 104 + 105 + n1 = FIELD_GET(CLK_CNTL0_N1_MASK, reg0) + 1; 106 + 107 + return DIV_ROUND_CLOSEST(parent_rate, n1); 108 + } 109 + 110 + static const struct cec_32k_freq_table *find_cec_32k_freq(unsigned long rate, 111 + unsigned long prate) 112 + { 113 + int i; 114 + 115 + for (i = 0 ; i < ARRAY_SIZE(aoclk_cec_32k_table) ; ++i) 116 + if (aoclk_cec_32k_table[i].parent_rate == prate && 117 + aoclk_cec_32k_table[i].target_rate == rate) 118 + return &aoclk_cec_32k_table[i]; 119 + 120 + return NULL; 121 + } 122 + 123 + static long aoclk_cec_32k_round_rate(struct clk_hw *hw, unsigned long rate, 124 + unsigned long *prate) 125 + { 126 + const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, 127 + *prate); 128 + 129 + /* If invalid return first one */ 130 + if (!freq) 131 + return aoclk_cec_32k_table[0].target_rate; 132 + 133 + return freq->target_rate; 134 + } 135 + 136 + /* 137 + * From the Amlogic init procedure, the IN and OUT gates needs to be handled 138 + * in the init procedure to avoid any glitches. 139 + */ 140 + 141 + static int aoclk_cec_32k_set_rate(struct clk_hw *hw, unsigned long rate, 142 + unsigned long parent_rate) 143 + { 144 + const struct cec_32k_freq_table *freq = find_cec_32k_freq(rate, 145 + parent_rate); 146 + struct aoclk_cec_32k *cec_32k = to_aoclk_cec_32k(hw); 147 + u32 reg = 0; 148 + 149 + if (!freq) 150 + return -EINVAL; 151 + 152 + /* Disable clock */ 153 + regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, 154 + CLK_CNTL0_IN_GATE_EN | CLK_CNTL0_OUT_GATE_EN, 0); 155 + 156 + reg = FIELD_PREP(CLK_CNTL0_N1_MASK, freq->n1 - 1); 157 + if (freq->dualdiv) 158 + reg |= CLK_CNTL0_DUALDIV_EN | 159 + FIELD_PREP(CLK_CNTL0_N2_MASK, freq->n2 - 1); 160 + 161 + regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, reg); 162 + 163 + reg = FIELD_PREP(CLK_CNTL1_M1_MASK, freq->m1 - 1); 164 + if (freq->dualdiv) 165 + reg |= FIELD_PREP(CLK_CNTL1_M2_MASK, freq->m2 - 1); 166 + 167 + regmap_write(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL1, reg); 168 + 169 + /* Enable clock */ 170 + regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, 171 + CLK_CNTL0_IN_GATE_EN, CLK_CNTL0_IN_GATE_EN); 172 + 173 + udelay(200); 174 + 175 + regmap_update_bits(cec_32k->regmap, AO_RTC_ALT_CLK_CNTL0, 176 + CLK_CNTL0_OUT_GATE_EN, CLK_CNTL0_OUT_GATE_EN); 177 + 178 + regmap_update_bits(cec_32k->regmap, AO_CRT_CLK_CNTL1, 179 + CLK_CNTL1_SELECT_OSC, CLK_CNTL1_SELECT_OSC); 180 + 181 + /* Select 32k from XTAL */ 182 + regmap_update_bits(cec_32k->regmap, 183 + AO_RTI_PWR_CNTL_REG0, 184 + PWR_CNTL_ALT_32K_SEL, 185 + FIELD_PREP(PWR_CNTL_ALT_32K_SEL, 4)); 186 + 187 + return 0; 188 + } 189 + 190 + const struct clk_ops meson_aoclk_cec_32k_ops = { 191 + .recalc_rate = aoclk_cec_32k_recalc_rate, 192 + .round_rate = aoclk_cec_32k_round_rate, 193 + .set_rate = aoclk_cec_32k_set_rate, 194 + };
+46
drivers/clk/meson/gxbb-aoclk-regmap.c
··· 1 + /* 2 + * Copyright (c) 2017 BayLibre, SAS. 3 + * Author: Neil Armstrong <narmstrong@baylibre.com> 4 + * 5 + * SPDX-License-Identifier: GPL-2.0+ 6 + */ 7 + 8 + #include <linux/clk-provider.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/regmap.h> 11 + #include "gxbb-aoclk.h" 12 + 13 + static int aoclk_gate_regmap_enable(struct clk_hw *hw) 14 + { 15 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 16 + 17 + return regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, 18 + BIT(gate->bit_idx), BIT(gate->bit_idx)); 19 + } 20 + 21 + static void aoclk_gate_regmap_disable(struct clk_hw *hw) 22 + { 23 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 24 + 25 + regmap_update_bits(gate->regmap, AO_RTI_GEN_CNTL_REG0, 26 + BIT(gate->bit_idx), 0); 27 + } 28 + 29 + static int aoclk_gate_regmap_is_enabled(struct clk_hw *hw) 30 + { 31 + struct aoclk_gate_regmap *gate = to_aoclk_gate_regmap(hw); 32 + unsigned int val; 33 + int ret; 34 + 35 + ret = regmap_read(gate->regmap, AO_RTI_GEN_CNTL_REG0, &val); 36 + if (ret) 37 + return ret; 38 + 39 + return (val & BIT(gate->bit_idx)) != 0; 40 + } 41 + 42 + const struct clk_ops meson_aoclk_gate_regmap_ops = { 43 + .enable = aoclk_gate_regmap_enable, 44 + .disable = aoclk_gate_regmap_disable, 45 + .is_enabled = aoclk_gate_regmap_is_enabled, 46 + };
+42 -23
drivers/clk/meson/gxbb-aoclk.c
··· 56 56 #include <linux/of_address.h> 57 57 #include <linux/platform_device.h> 58 58 #include <linux/reset-controller.h> 59 + #include <linux/mfd/syscon.h> 60 + #include <linux/regmap.h> 59 61 #include <linux/init.h> 62 + #include <linux/delay.h> 60 63 #include <dt-bindings/clock/gxbb-aoclkc.h> 61 64 #include <dt-bindings/reset/gxbb-aoclkc.h> 65 + #include "gxbb-aoclk.h" 62 66 63 67 static DEFINE_SPINLOCK(gxbb_aoclk_lock); 64 68 65 69 struct gxbb_aoclk_reset_controller { 66 70 struct reset_controller_dev reset; 67 71 unsigned int *data; 68 - void __iomem *base; 72 + struct regmap *regmap; 69 73 }; 70 74 71 75 static int gxbb_aoclk_do_reset(struct reset_controller_dev *rcdev, ··· 78 74 struct gxbb_aoclk_reset_controller *reset = 79 75 container_of(rcdev, struct gxbb_aoclk_reset_controller, reset); 80 76 81 - writel(BIT(reset->data[id]), reset->base); 82 - 83 - return 0; 77 + return regmap_write(reset->regmap, AO_RTI_GEN_CNTL_REG0, 78 + BIT(reset->data[id])); 84 79 } 85 80 86 81 static const struct reset_control_ops gxbb_aoclk_reset_ops = { ··· 87 84 }; 88 85 89 86 #define GXBB_AO_GATE(_name, _bit) \ 90 - static struct clk_gate _name##_ao = { \ 91 - .reg = (void __iomem *)0, \ 87 + static struct aoclk_gate_regmap _name##_ao = { \ 92 88 .bit_idx = (_bit), \ 93 89 .lock = &gxbb_aoclk_lock, \ 94 90 .hw.init = &(struct clk_init_data) { \ 95 91 .name = #_name "_ao", \ 96 - .ops = &clk_gate_ops, \ 92 + .ops = &meson_aoclk_gate_regmap_ops, \ 97 93 .parent_names = (const char *[]){ "clk81" }, \ 98 94 .num_parents = 1, \ 99 95 .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \ ··· 106 104 GXBB_AO_GATE(uart2, 5); 107 105 GXBB_AO_GATE(ir_blaster, 6); 108 106 107 + static struct aoclk_cec_32k cec_32k_ao = { 108 + .lock = &gxbb_aoclk_lock, 109 + .hw.init = &(struct clk_init_data) { 110 + .name = "cec_32k_ao", 111 + .ops = &meson_aoclk_cec_32k_ops, 112 + .parent_names = (const char *[]){ "xtal" }, 113 + .num_parents = 1, 114 + .flags = CLK_IGNORE_UNUSED, 115 + }, 116 + }; 117 + 109 118 static unsigned int gxbb_aoclk_reset[] = { 110 119 [RESET_AO_REMOTE] = 16, 111 120 [RESET_AO_I2C_MASTER] = 18, ··· 126 113 [RESET_AO_IR_BLASTER] = 23, 127 114 }; 128 115 129 - static struct clk_gate *gxbb_aoclk_gate[] = { 116 + static struct aoclk_gate_regmap *gxbb_aoclk_gate[] = { 130 117 [CLKID_AO_REMOTE] = &remote_ao, 131 118 [CLKID_AO_I2C_MASTER] = &i2c_master_ao, 132 119 [CLKID_AO_I2C_SLAVE] = &i2c_slave_ao, ··· 143 130 [CLKID_AO_UART1] = &uart1_ao.hw, 144 131 [CLKID_AO_UART2] = &uart2_ao.hw, 145 132 [CLKID_AO_IR_BLASTER] = &ir_blaster_ao.hw, 133 + [CLKID_AO_CEC_32K] = &cec_32k_ao.hw, 146 134 }, 147 - .num = ARRAY_SIZE(gxbb_aoclk_gate), 135 + .num = 7, 148 136 }; 149 137 150 138 static int gxbb_aoclkc_probe(struct platform_device *pdev) 151 139 { 152 - struct resource *res; 153 - void __iomem *base; 154 - int ret, clkid; 155 - struct device *dev = &pdev->dev; 156 140 struct gxbb_aoclk_reset_controller *rstc; 141 + struct device *dev = &pdev->dev; 142 + struct regmap *regmap; 143 + int ret, clkid; 157 144 158 145 rstc = devm_kzalloc(dev, sizeof(*rstc), GFP_KERNEL); 159 146 if (!rstc) 160 147 return -ENOMEM; 161 148 162 - /* Generic clocks */ 163 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 164 - base = devm_ioremap_resource(dev, res); 165 - if (IS_ERR(base)) 166 - return PTR_ERR(base); 149 + regmap = syscon_node_to_regmap(of_get_parent(dev->of_node)); 150 + if (IS_ERR(regmap)) { 151 + dev_err(dev, "failed to get regmap\n"); 152 + return -ENODEV; 153 + } 167 154 168 155 /* Reset Controller */ 169 - rstc->base = base; 156 + rstc->regmap = regmap; 170 157 rstc->data = gxbb_aoclk_reset; 171 158 rstc->reset.ops = &gxbb_aoclk_reset_ops; 172 159 rstc->reset.nr_resets = ARRAY_SIZE(gxbb_aoclk_reset); ··· 174 161 ret = devm_reset_controller_register(dev, &rstc->reset); 175 162 176 163 /* 177 - * Populate base address and register all clks 164 + * Populate regmap and register all clks 178 165 */ 179 - for (clkid = 0; clkid < gxbb_aoclk_onecell_data.num; clkid++) { 180 - gxbb_aoclk_gate[clkid]->reg = base; 166 + for (clkid = 0; clkid < ARRAY_SIZE(gxbb_aoclk_gate); clkid++) { 167 + gxbb_aoclk_gate[clkid]->regmap = regmap; 181 168 182 169 ret = devm_clk_hw_register(dev, 183 170 gxbb_aoclk_onecell_data.hws[clkid]); ··· 185 172 return ret; 186 173 } 187 174 175 + /* Specific clocks */ 176 + cec_32k_ao.regmap = regmap; 177 + ret = devm_clk_hw_register(dev, &cec_32k_ao.hw); 178 + if (ret) 179 + return ret; 180 + 188 181 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 189 182 &gxbb_aoclk_onecell_data); 190 183 } 191 184 192 185 static const struct of_device_id gxbb_aoclkc_match_table[] = { 193 - { .compatible = "amlogic,gxbb-aoclkc" }, 186 + { .compatible = "amlogic,meson-gx-aoclkc" }, 194 187 { } 195 188 }; 196 189
+42
drivers/clk/meson/gxbb-aoclk.h
··· 1 + /* 2 + * Copyright (c) 2017 BayLibre, SAS 3 + * Author: Neil Armstrong <narmstrong@baylibre.com> 4 + * 5 + * SPDX-License-Identifier: GPL-2.0+ 6 + */ 7 + 8 + #ifndef __GXBB_AOCLKC_H 9 + #define __GXBB_AOCLKC_H 10 + 11 + /* AO Configuration Clock registers offsets */ 12 + #define AO_RTI_PWR_CNTL_REG1 0x0c 13 + #define AO_RTI_PWR_CNTL_REG0 0x10 14 + #define AO_RTI_GEN_CNTL_REG0 0x40 15 + #define AO_OSCIN_CNTL 0x58 16 + #define AO_CRT_CLK_CNTL1 0x68 17 + #define AO_RTC_ALT_CLK_CNTL0 0x94 18 + #define AO_RTC_ALT_CLK_CNTL1 0x98 19 + 20 + struct aoclk_gate_regmap { 21 + struct clk_hw hw; 22 + unsigned bit_idx; 23 + struct regmap *regmap; 24 + spinlock_t *lock; 25 + }; 26 + 27 + #define to_aoclk_gate_regmap(_hw) \ 28 + container_of(_hw, struct aoclk_gate_regmap, hw) 29 + 30 + extern const struct clk_ops meson_aoclk_gate_regmap_ops; 31 + 32 + struct aoclk_cec_32k { 33 + struct clk_hw hw; 34 + struct regmap *regmap; 35 + spinlock_t *lock; 36 + }; 37 + 38 + #define to_aoclk_cec_32k(_hw) container_of(_hw, struct aoclk_cec_32k, hw) 39 + 40 + extern const struct clk_ops meson_aoclk_cec_32k_ops; 41 + 42 + #endif /* __GXBB_AOCLKC_H */
+183 -4
drivers/clk/meson/gxbb.c
··· 850 850 .shift = 0, 851 851 .width = 8, 852 852 }, 853 + .flags = CLK_DIVIDER_ROUND_CLOSEST, 853 854 .lock = &clk_lock, 854 855 .hw.init = &(struct clk_init_data){ 855 856 .name = "cts_amclk_div", 856 857 .ops = &meson_clk_audio_divider_ops, 857 858 .parent_names = (const char *[]){ "cts_amclk_sel" }, 858 859 .num_parents = 1, 859 - .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 860 + .flags = CLK_SET_RATE_PARENT, 860 861 }, 861 862 }; 862 863 ··· 881 880 /* Default parent unknown (register reset value: 0) */ 882 881 .table = (u32[]){ 1, 2, 3 }, 883 882 .lock = &clk_lock, 884 - .hw.init = &(struct clk_init_data){ 883 + .hw.init = &(struct clk_init_data) { 885 884 .name = "cts_mclk_i958_sel", 886 885 .ops = &clk_mux_ops, 887 886 .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" }, ··· 895 894 .shift = 16, 896 895 .width = 8, 897 896 .lock = &clk_lock, 898 - .hw.init = &(struct clk_init_data){ 897 + .flags = CLK_DIVIDER_ROUND_CLOSEST, 898 + .hw.init = &(struct clk_init_data) { 899 899 .name = "cts_mclk_i958_div", 900 900 .ops = &clk_divider_ops, 901 901 .parent_names = (const char *[]){ "cts_mclk_i958_sel" }, 902 902 .num_parents = 1, 903 - .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST, 903 + .flags = CLK_SET_RATE_PARENT, 904 904 }, 905 905 }; 906 906 ··· 978 976 .parent_names = gxbb_32k_clk_parent_names, 979 977 .num_parents = 4, 980 978 .flags = CLK_SET_RATE_PARENT, 979 + }, 980 + }; 981 + 982 + static const char * const gxbb_sd_emmc_clk0_parent_names[] = { 983 + "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", 984 + 985 + /* 986 + * Following these parent clocks, we should also have had mpll2, mpll3 987 + * and gp0_pll but these clocks are too precious to be used here. All 988 + * the necessary rates for MMC and NAND operation can be acheived using 989 + * xtal or fclk_div clocks 990 + */ 991 + }; 992 + 993 + /* SDIO clock */ 994 + static struct clk_mux gxbb_sd_emmc_a_clk0_sel = { 995 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 996 + .mask = 0x7, 997 + .shift = 9, 998 + .lock = &clk_lock, 999 + .hw.init = &(struct clk_init_data) { 1000 + .name = "sd_emmc_a_clk0_sel", 1001 + .ops = &clk_mux_ops, 1002 + .parent_names = gxbb_sd_emmc_clk0_parent_names, 1003 + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1004 + .flags = CLK_SET_RATE_PARENT, 1005 + }, 1006 + }; 1007 + 1008 + static struct clk_divider gxbb_sd_emmc_a_clk0_div = { 1009 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1010 + .shift = 0, 1011 + .width = 7, 1012 + .lock = &clk_lock, 1013 + .flags = CLK_DIVIDER_ROUND_CLOSEST, 1014 + .hw.init = &(struct clk_init_data) { 1015 + .name = "sd_emmc_a_clk0_div", 1016 + .ops = &clk_divider_ops, 1017 + .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" }, 1018 + .num_parents = 1, 1019 + .flags = CLK_SET_RATE_PARENT, 1020 + }, 1021 + }; 1022 + 1023 + static struct clk_gate gxbb_sd_emmc_a_clk0 = { 1024 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1025 + .bit_idx = 7, 1026 + .lock = &clk_lock, 1027 + .hw.init = &(struct clk_init_data){ 1028 + .name = "sd_emmc_a_clk0", 1029 + .ops = &clk_gate_ops, 1030 + .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" }, 1031 + .num_parents = 1, 1032 + 1033 + /* 1034 + * FIXME: 1035 + * We need CLK_IGNORE_UNUSED because mmc DT node point to xtal 1036 + * instead of this clock. CCF would gate this on boot, killing 1037 + * the mmc controller. Please remove this flag once DT properly 1038 + * point to this clock instead of xtal 1039 + * 1040 + * Same goes for emmc B and C clocks 1041 + */ 1042 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1043 + }, 1044 + }; 1045 + 1046 + /* SDcard clock */ 1047 + static struct clk_mux gxbb_sd_emmc_b_clk0_sel = { 1048 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1049 + .mask = 0x7, 1050 + .shift = 25, 1051 + .lock = &clk_lock, 1052 + .hw.init = &(struct clk_init_data) { 1053 + .name = "sd_emmc_b_clk0_sel", 1054 + .ops = &clk_mux_ops, 1055 + .parent_names = gxbb_sd_emmc_clk0_parent_names, 1056 + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1057 + .flags = CLK_SET_RATE_PARENT, 1058 + }, 1059 + }; 1060 + 1061 + static struct clk_divider gxbb_sd_emmc_b_clk0_div = { 1062 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1063 + .shift = 16, 1064 + .width = 7, 1065 + .lock = &clk_lock, 1066 + .flags = CLK_DIVIDER_ROUND_CLOSEST, 1067 + .hw.init = &(struct clk_init_data) { 1068 + .name = "sd_emmc_b_clk0_div", 1069 + .ops = &clk_divider_ops, 1070 + .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" }, 1071 + .num_parents = 1, 1072 + .flags = CLK_SET_RATE_PARENT, 1073 + }, 1074 + }; 1075 + 1076 + static struct clk_gate gxbb_sd_emmc_b_clk0 = { 1077 + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, 1078 + .bit_idx = 23, 1079 + .lock = &clk_lock, 1080 + .hw.init = &(struct clk_init_data){ 1081 + .name = "sd_emmc_b_clk0", 1082 + .ops = &clk_gate_ops, 1083 + .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" }, 1084 + .num_parents = 1, 1085 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 1086 + }, 1087 + }; 1088 + 1089 + /* EMMC/NAND clock */ 1090 + static struct clk_mux gxbb_sd_emmc_c_clk0_sel = { 1091 + .reg = (void *)HHI_NAND_CLK_CNTL, 1092 + .mask = 0x7, 1093 + .shift = 9, 1094 + .lock = &clk_lock, 1095 + .hw.init = &(struct clk_init_data) { 1096 + .name = "sd_emmc_c_clk0_sel", 1097 + .ops = &clk_mux_ops, 1098 + .parent_names = gxbb_sd_emmc_clk0_parent_names, 1099 + .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names), 1100 + .flags = CLK_SET_RATE_PARENT, 1101 + }, 1102 + }; 1103 + 1104 + static struct clk_divider gxbb_sd_emmc_c_clk0_div = { 1105 + .reg = (void *)HHI_NAND_CLK_CNTL, 1106 + .shift = 0, 1107 + .width = 7, 1108 + .lock = &clk_lock, 1109 + .flags = CLK_DIVIDER_ROUND_CLOSEST, 1110 + .hw.init = &(struct clk_init_data) { 1111 + .name = "sd_emmc_c_clk0_div", 1112 + .ops = &clk_divider_ops, 1113 + .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" }, 1114 + .num_parents = 1, 1115 + .flags = CLK_SET_RATE_PARENT, 1116 + }, 1117 + }; 1118 + 1119 + static struct clk_gate gxbb_sd_emmc_c_clk0 = { 1120 + .reg = (void *)HHI_NAND_CLK_CNTL, 1121 + .bit_idx = 7, 1122 + .lock = &clk_lock, 1123 + .hw.init = &(struct clk_init_data){ 1124 + .name = "sd_emmc_c_clk0", 1125 + .ops = &clk_gate_ops, 1126 + .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" }, 1127 + .num_parents = 1, 1128 + .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, 981 1129 }, 982 1130 }; 983 1131 ··· 1340 1188 [CLKID_32K_CLK] = &gxbb_32k_clk.hw, 1341 1189 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, 1342 1190 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, 1191 + [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw, 1192 + [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw, 1193 + [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw, 1194 + [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw, 1195 + [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw, 1196 + [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw, 1197 + [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw, 1198 + [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw, 1199 + [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw, 1343 1200 [NR_CLKS] = NULL, 1344 1201 }, 1345 1202 .num = NR_CLKS, ··· 1472 1311 [CLKID_32K_CLK] = &gxbb_32k_clk.hw, 1473 1312 [CLKID_32K_CLK_SEL] = &gxbb_32k_clk_sel.hw, 1474 1313 [CLKID_32K_CLK_DIV] = &gxbb_32k_clk_div.hw, 1314 + [CLKID_SD_EMMC_A_CLK0_SEL] = &gxbb_sd_emmc_a_clk0_sel.hw, 1315 + [CLKID_SD_EMMC_A_CLK0_DIV] = &gxbb_sd_emmc_a_clk0_div.hw, 1316 + [CLKID_SD_EMMC_A_CLK0] = &gxbb_sd_emmc_a_clk0.hw, 1317 + [CLKID_SD_EMMC_B_CLK0_SEL] = &gxbb_sd_emmc_b_clk0_sel.hw, 1318 + [CLKID_SD_EMMC_B_CLK0_DIV] = &gxbb_sd_emmc_b_clk0_div.hw, 1319 + [CLKID_SD_EMMC_B_CLK0] = &gxbb_sd_emmc_b_clk0.hw, 1320 + [CLKID_SD_EMMC_C_CLK0_SEL] = &gxbb_sd_emmc_c_clk0_sel.hw, 1321 + [CLKID_SD_EMMC_C_CLK0_DIV] = &gxbb_sd_emmc_c_clk0_div.hw, 1322 + [CLKID_SD_EMMC_C_CLK0] = &gxbb_sd_emmc_c_clk0.hw, 1475 1323 [NR_CLKS] = NULL, 1476 1324 }, 1477 1325 .num = NR_CLKS, ··· 1597 1427 &gxbb_cts_amclk, 1598 1428 &gxbb_cts_mclk_i958, 1599 1429 &gxbb_32k_clk, 1430 + &gxbb_sd_emmc_a_clk0, 1431 + &gxbb_sd_emmc_b_clk0, 1432 + &gxbb_sd_emmc_c_clk0, 1600 1433 }; 1601 1434 1602 1435 static struct clk_mux *const gxbb_clk_muxes[] = { ··· 1612 1439 &gxbb_cts_mclk_i958_sel, 1613 1440 &gxbb_cts_i958, 1614 1441 &gxbb_32k_clk_sel, 1442 + &gxbb_sd_emmc_a_clk0_sel, 1443 + &gxbb_sd_emmc_b_clk0_sel, 1444 + &gxbb_sd_emmc_c_clk0_sel, 1615 1445 }; 1616 1446 1617 1447 static struct clk_divider *const gxbb_clk_dividers[] = { ··· 1624 1448 &gxbb_mali_1_div, 1625 1449 &gxbb_cts_mclk_i958_div, 1626 1450 &gxbb_32k_clk_div, 1451 + &gxbb_sd_emmc_a_clk0_div, 1452 + &gxbb_sd_emmc_b_clk0_div, 1453 + &gxbb_sd_emmc_c_clk0_div, 1627 1454 }; 1628 1455 1629 1456 static struct meson_clk_audio_divider *const gxbb_audio_dividers[] = {
+147 -12
drivers/clk/meson/meson8b.c
··· 25 25 #include <linux/clk-provider.h> 26 26 #include <linux/of_address.h> 27 27 #include <linux/platform_device.h> 28 + #include <linux/reset-controller.h> 29 + #include <linux/slab.h> 28 30 #include <linux/init.h> 29 31 30 32 #include "clkc.h" 31 33 #include "meson8b.h" 32 34 33 35 static DEFINE_SPINLOCK(clk_lock); 36 + 37 + static void __iomem *clk_base; 38 + 39 + struct meson8b_clk_reset { 40 + struct reset_controller_dev reset; 41 + void __iomem *base; 42 + }; 34 43 35 44 static const struct pll_rate_table sys_pll_rate_table[] = { 36 45 PLL_RATE(312000000, 52, 1, 2), ··· 705 696 &meson8b_mpeg_clk_div, 706 697 }; 707 698 699 + static const struct meson8b_clk_reset_line { 700 + u32 reg; 701 + u8 bit_idx; 702 + } meson8b_clk_reset_bits[] = { 703 + [CLKC_RESET_L2_CACHE_SOFT_RESET] = { 704 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30 705 + }, 706 + [CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = { 707 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29 708 + }, 709 + [CLKC_RESET_SCU_SOFT_RESET] = { 710 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28 711 + }, 712 + [CLKC_RESET_CPU3_SOFT_RESET] = { 713 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27 714 + }, 715 + [CLKC_RESET_CPU2_SOFT_RESET] = { 716 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26 717 + }, 718 + [CLKC_RESET_CPU1_SOFT_RESET] = { 719 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25 720 + }, 721 + [CLKC_RESET_CPU0_SOFT_RESET] = { 722 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24 723 + }, 724 + [CLKC_RESET_A5_GLOBAL_RESET] = { 725 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18 726 + }, 727 + [CLKC_RESET_A5_AXI_SOFT_RESET] = { 728 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17 729 + }, 730 + [CLKC_RESET_A5_ABP_SOFT_RESET] = { 731 + .reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16 732 + }, 733 + [CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = { 734 + .reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30 735 + }, 736 + [CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = { 737 + .reg = HHI_VID_CLK_CNTL, .bit_idx = 15 738 + }, 739 + [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = { 740 + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7 741 + }, 742 + [CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = { 743 + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3 744 + }, 745 + [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = { 746 + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1 747 + }, 748 + [CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = { 749 + .reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0 750 + }, 751 + }; 752 + 753 + static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev, 754 + unsigned long id, bool assert) 755 + { 756 + struct meson8b_clk_reset *meson8b_clk_reset = 757 + container_of(rcdev, struct meson8b_clk_reset, reset); 758 + unsigned long flags; 759 + const struct meson8b_clk_reset_line *reset; 760 + u32 val; 761 + 762 + if (id >= ARRAY_SIZE(meson8b_clk_reset_bits)) 763 + return -EINVAL; 764 + 765 + reset = &meson8b_clk_reset_bits[id]; 766 + 767 + spin_lock_irqsave(&clk_lock, flags); 768 + 769 + val = readl(meson8b_clk_reset->base + reset->reg); 770 + if (assert) 771 + val |= BIT(reset->bit_idx); 772 + else 773 + val &= ~BIT(reset->bit_idx); 774 + writel(val, meson8b_clk_reset->base + reset->reg); 775 + 776 + spin_unlock_irqrestore(&clk_lock, flags); 777 + 778 + return 0; 779 + } 780 + 781 + static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev, 782 + unsigned long id) 783 + { 784 + return meson8b_clk_reset_update(rcdev, id, true); 785 + } 786 + 787 + static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev, 788 + unsigned long id) 789 + { 790 + return meson8b_clk_reset_update(rcdev, id, false); 791 + } 792 + 793 + static const struct reset_control_ops meson8b_clk_reset_ops = { 794 + .assert = meson8b_clk_reset_assert, 795 + .deassert = meson8b_clk_reset_deassert, 796 + }; 797 + 708 798 static int meson8b_clkc_probe(struct platform_device *pdev) 709 799 { 710 - void __iomem *clk_base; 711 800 int ret, clkid, i; 712 801 struct clk_hw *parent_hw; 713 802 struct clk *parent_clk; 714 803 struct device *dev = &pdev->dev; 715 804 716 - /* Generic clocks and PLLs */ 717 - clk_base = of_iomap(dev->of_node, 1); 718 - if (!clk_base) { 719 - pr_err("%s: Unable to map clk base\n", __func__); 805 + if (!clk_base) 720 806 return -ENXIO; 721 - } 722 807 723 808 /* Populate base address for PLLs */ 724 809 for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++) ··· 852 749 /* FIXME convert to devm_clk_register */ 853 750 ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[clkid]); 854 751 if (ret) 855 - goto iounmap; 752 + return ret; 856 753 } 857 754 858 755 /* ··· 875 772 if (ret) { 876 773 pr_err("%s: failed to register clock notifier for cpu_clk\n", 877 774 __func__); 878 - goto iounmap; 775 + return ret; 879 776 } 880 777 881 778 return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, 882 779 &meson8b_hw_onecell_data); 883 - 884 - iounmap: 885 - iounmap(clk_base); 886 - return ret; 887 780 } 888 781 889 782 static const struct of_device_id meson8b_clkc_match_table[] = { ··· 898 799 }; 899 800 900 801 builtin_platform_driver(meson8b_driver); 802 + 803 + static void __init meson8b_clkc_reset_init(struct device_node *np) 804 + { 805 + struct meson8b_clk_reset *rstc; 806 + int ret; 807 + 808 + /* Generic clocks, PLLs and some of the reset-bits */ 809 + clk_base = of_iomap(np, 1); 810 + if (!clk_base) { 811 + pr_err("%s: Unable to map clk base\n", __func__); 812 + return; 813 + } 814 + 815 + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); 816 + if (!rstc) 817 + return; 818 + 819 + /* Reset Controller */ 820 + rstc->base = clk_base; 821 + rstc->reset.ops = &meson8b_clk_reset_ops; 822 + rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits); 823 + rstc->reset.of_node = np; 824 + ret = reset_controller_register(&rstc->reset); 825 + if (ret) { 826 + pr_err("%s: Failed to register clkc reset controller: %d\n", 827 + __func__, ret); 828 + return; 829 + } 830 + } 831 + 832 + CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc", 833 + meson8b_clkc_reset_init); 834 + CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc", 835 + meson8b_clkc_reset_init); 836 + CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc", 837 + meson8b_clkc_reset_init);
+8 -1
drivers/clk/meson/meson8b.h
··· 37 37 #define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */ 38 38 #define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */ 39 39 #define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ 40 + #define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ 41 + #define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ 42 + #define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ 40 43 #define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ 41 44 #define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ 42 45 #define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ ··· 71 68 72 69 #define CLK_NR_CLKS 96 73 70 74 - /* include the CLKIDs that have been made part of the stable DT binding */ 71 + /* 72 + * include the CLKID and RESETID that have 73 + * been made part of the stable DT binding 74 + */ 75 75 #include <dt-bindings/clock/meson8b-clkc.h> 76 + #include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h> 76 77 77 78 #endif /* __MESON8B_H */
+1 -1
drivers/clk/mmp/clk.c
··· 9 9 void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, 10 10 int nr_clks) 11 11 { 12 - static struct clk **clk_table; 12 + struct clk **clk_table; 13 13 14 14 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 15 15 if (!clk_table)
+6 -6
drivers/clk/nxp/clk-lpc32xx.c
··· 885 885 .recalc_rate = clk_usb_i2c_recalc_rate, 886 886 }; 887 887 888 - static int clk_gate_enable(struct clk_hw *hw) 888 + static int lpc32xx_clk_gate_enable(struct clk_hw *hw) 889 889 { 890 890 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 891 891 u32 mask = BIT(clk->bit_idx); ··· 894 894 return regmap_update_bits(clk_regmap, clk->reg, mask, val); 895 895 } 896 896 897 - static void clk_gate_disable(struct clk_hw *hw) 897 + static void lpc32xx_clk_gate_disable(struct clk_hw *hw) 898 898 { 899 899 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 900 900 u32 mask = BIT(clk->bit_idx); ··· 903 903 regmap_update_bits(clk_regmap, clk->reg, mask, val); 904 904 } 905 905 906 - static int clk_gate_is_enabled(struct clk_hw *hw) 906 + static int lpc32xx_clk_gate_is_enabled(struct clk_hw *hw) 907 907 { 908 908 struct lpc32xx_clk_gate *clk = to_lpc32xx_gate(hw); 909 909 u32 val; ··· 916 916 } 917 917 918 918 static const struct clk_ops lpc32xx_clk_gate_ops = { 919 - .enable = clk_gate_enable, 920 - .disable = clk_gate_disable, 921 - .is_enabled = clk_gate_is_enabled, 919 + .enable = lpc32xx_clk_gate_enable, 920 + .disable = lpc32xx_clk_gate_disable, 921 + .is_enabled = lpc32xx_clk_gate_is_enabled, 922 922 }; 923 923 924 924 #define div_mask(width) ((1 << (width)) - 1)
-2
drivers/clk/qcom/clk-smd-rpm.c
··· 412 412 static const struct clk_ops clk_smd_rpm_branch_ops = { 413 413 .prepare = clk_smd_rpm_prepare, 414 414 .unprepare = clk_smd_rpm_unprepare, 415 - .round_rate = clk_smd_rpm_round_rate, 416 - .recalc_rate = clk_smd_rpm_recalc_rate, 417 415 }; 418 416 419 417 /* msm8916 */
+1 -1
drivers/clk/qcom/gcc-msm8916.c
··· 1176 1176 .parent_names = gcc_xo_gpll0_bimc, 1177 1177 .num_parents = 3, 1178 1178 .flags = CLK_GET_RATE_NOCACHE, 1179 - .ops = &clk_rcg2_shared_ops, 1179 + .ops = &clk_rcg2_ops, 1180 1180 }, 1181 1181 }; 1182 1182
+28
drivers/clk/qcom/gcc-msm8996.c
··· 2730 2730 }, 2731 2731 }; 2732 2732 2733 + static struct clk_branch gcc_hlos1_vote_lpass_core_smmu_clk = { 2734 + .halt_reg = 0x7d010, 2735 + .halt_check = BRANCH_HALT_VOTED, 2736 + .clkr = { 2737 + .enable_reg = 0x7d010, 2738 + .enable_mask = BIT(0), 2739 + .hw.init = &(struct clk_init_data){ 2740 + .name = "hlos1_vote_lpass_core_smmu_clk", 2741 + .ops = &clk_branch2_ops, 2742 + }, 2743 + }, 2744 + }; 2745 + 2746 + static struct clk_branch gcc_hlos1_vote_lpass_adsp_smmu_clk = { 2747 + .halt_reg = 0x7d014, 2748 + .halt_check = BRANCH_HALT_VOTED, 2749 + .clkr = { 2750 + .enable_reg = 0x7d014, 2751 + .enable_mask = BIT(0), 2752 + .hw.init = &(struct clk_init_data){ 2753 + .name = "hlos1_vote_lpass_adsp_smmu_clk", 2754 + .ops = &clk_branch2_ops, 2755 + }, 2756 + }, 2757 + }; 2758 + 2733 2759 static struct clk_branch gcc_ufs_rx_cfg_clk = { 2734 2760 .halt_reg = 0x75014, 2735 2761 .clkr = { ··· 3333 3307 [GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr, 3334 3308 [GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr, 3335 3309 [GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr, 3310 + [GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK] = &gcc_hlos1_vote_lpass_core_smmu_clk.clkr, 3311 + [GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] = &gcc_hlos1_vote_lpass_adsp_smmu_clk.clkr, 3336 3312 [GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr, 3337 3313 [GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr, 3338 3314 [GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
+29 -19
drivers/clk/renesas/Kconfig
··· 15 15 select CLK_R8A7794 if ARCH_R8A7794 16 16 select CLK_R8A7795 if ARCH_R8A7795 17 17 select CLK_R8A7796 if ARCH_R8A7796 18 + select CLK_R8A77995 if ARCH_R8A77995 18 19 select CLK_SH73A0 if ARCH_SH73A0 19 20 20 21 if CLK_RENESAS ··· 35 34 bool "Emma Mobile EV2 clock support" if COMPILE_TEST 36 35 37 36 config CLK_RZA1 38 - bool 37 + bool "RZ/A1H clock support" if COMPILE_TEST 39 38 select CLK_RENESAS_CPG_MSTP 40 39 41 40 config CLK_R8A73A4 42 - bool 41 + bool "R-Mobile APE6 clock support" if COMPILE_TEST 43 42 select CLK_RENESAS_CPG_MSTP 44 43 select CLK_RENESAS_DIV6 45 44 46 45 config CLK_R8A7740 47 - bool 46 + bool "R-Mobile A1 clock support" if COMPILE_TEST 48 47 select CLK_RENESAS_CPG_MSTP 49 48 select CLK_RENESAS_DIV6 50 49 51 50 config CLK_R8A7743 52 - bool 51 + bool "RZ/G1M clock support" if COMPILE_TEST 53 52 select CLK_RCAR_GEN2_CPG 54 53 55 54 config CLK_R8A7745 56 - bool 55 + bool "RZ/G1E clock support" if COMPILE_TEST 57 56 select CLK_RCAR_GEN2_CPG 58 57 59 58 config CLK_R8A7778 60 - bool 59 + bool "R-Car M1A clock support" if COMPILE_TEST 61 60 select CLK_RENESAS_CPG_MSTP 62 61 63 62 config CLK_R8A7779 64 - bool 63 + bool "R-Car H1 clock support" if COMPILE_TEST 65 64 select CLK_RENESAS_CPG_MSTP 66 65 67 66 config CLK_R8A7790 68 - bool 67 + bool "R-Car H2 clock support" if COMPILE_TEST 69 68 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 70 69 select CLK_RCAR_GEN2_CPG 71 70 select CLK_RENESAS_DIV6 72 71 73 72 config CLK_R8A7791 74 - bool 73 + bool "R-Car M2-W/N clock support" if COMPILE_TEST 75 74 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 76 75 select CLK_RCAR_GEN2_CPG 77 76 select CLK_RENESAS_DIV6 78 77 79 78 config CLK_R8A7792 80 - bool 79 + bool "R-Car V2H clock support" if COMPILE_TEST 81 80 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 82 81 select CLK_RCAR_GEN2_CPG 83 82 84 83 config CLK_R8A7794 85 - bool 84 + bool "R-Car E2 clock support" if COMPILE_TEST 86 85 select CLK_RCAR_GEN2 if CLK_RENESAS_LEGACY 87 86 select CLK_RCAR_GEN2_CPG 88 87 select CLK_RENESAS_DIV6 89 88 90 89 config CLK_R8A7795 91 - bool 90 + bool "R-Car H3 clock support" if COMPILE_TEST 92 91 select CLK_RCAR_GEN3_CPG 93 92 94 93 config CLK_R8A7796 95 - bool 94 + bool "R-Car M3-W clock support" if COMPILE_TEST 95 + select CLK_RCAR_GEN3_CPG 96 + 97 + config CLK_R8A77995 98 + bool "R-Car D3 clock support" if COMPILE_TEST 96 99 select CLK_RCAR_GEN3_CPG 97 100 98 101 config CLK_SH73A0 99 - bool 102 + bool "SH-Mobile AG5 clock support" if COMPILE_TEST 100 103 select CLK_RENESAS_CPG_MSTP 101 104 select CLK_RENESAS_DIV6 102 105 103 106 104 107 # Family 105 108 config CLK_RCAR_GEN2 106 - bool 109 + bool "R-Car Gen2 legacy clock support" if COMPILE_TEST 107 110 select CLK_RENESAS_CPG_MSTP 108 111 select CLK_RENESAS_DIV6 109 112 110 113 config CLK_RCAR_GEN2_CPG 111 - bool 114 + bool "R-Car Gen2 CPG clock support" if COMPILE_TEST 112 115 select CLK_RENESAS_CPG_MSSR 113 116 114 117 config CLK_RCAR_GEN3_CPG 115 - bool 118 + bool "R-Car Gen3 CPG clock support" if COMPILE_TEST 116 119 select CLK_RENESAS_CPG_MSSR 117 120 121 + config CLK_RCAR_USB2_CLOCK_SEL 122 + bool "Renesas R-Car USB2 clock selector support" 123 + depends on ARCH_RENESAS || COMPILE_TEST 124 + help 125 + This is a driver for R-Car USB2 clock selector 118 126 119 127 # Generic 120 128 config CLK_RENESAS_CPG_MSSR 121 - bool 129 + bool "CPG/MSSR clock support" if COMPILE_TEST 122 130 select CLK_RENESAS_DIV6 123 131 124 132 config CLK_RENESAS_CPG_MSTP 125 - bool 133 + bool "MSTP clock support" if COMPILE_TEST 126 134 127 135 config CLK_RENESAS_DIV6 128 136 bool "DIV6 clock support" if COMPILE_TEST
+2
drivers/clk/renesas/Makefile
··· 13 13 obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o 14 14 obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o 15 15 obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o 16 + obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o 16 17 obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o 17 18 18 19 # Family 19 20 obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o 20 21 obj-$(CONFIG_CLK_RCAR_GEN2_CPG) += rcar-gen2-cpg.o 21 22 obj-$(CONFIG_CLK_RCAR_GEN3_CPG) += rcar-gen3-cpg.o 23 + obj-$(CONFIG_CLK_RCAR_USB2_CLOCK_SEL) += rcar-usb2-clock-sel.o 22 24 23 25 # Generic 24 26 obj-$(CONFIG_CLK_RENESAS_CPG_MSSR) += renesas-cpg-mssr.o
+3
drivers/clk/renesas/clk-div6.c
··· 29 29 * @hw: handle between common and hardware-specific interfaces 30 30 * @reg: IO-remapped register 31 31 * @div: divisor value (1-64) 32 + * @src_shift: Shift to access the register bits to select the parent clock 33 + * @src_width: Number of register bits to select the parent clock (may be 0) 34 + * @parents: Array to map from valid parent clocks indices to hardware indices 32 35 */ 33 36 struct div6_clock { 34 37 struct clk_hw hw;
+1 -1
drivers/clk/renesas/clk-mstp.c
··· 335 335 u32 ncells; 336 336 337 337 if (of_property_read_u32(np, "#power-domain-cells", &ncells)) { 338 - pr_warn("%s lacks #power-domain-cells\n", np->full_name); 338 + pr_warn("%pOF lacks #power-domain-cells\n", np); 339 339 return; 340 340 } 341 341
+1 -2
drivers/clk/renesas/clk-rcar-gen2.c
··· 407 407 408 408 if (rcar_rst_read_mode_pins(&cpg_mode)) { 409 409 /* Backward-compatibility with old DT */ 410 - pr_warn("%s: failed to obtain mode pins from RST\n", 411 - np->full_name); 410 + pr_warn("%pOF: failed to obtain mode pins from RST\n", np); 412 411 cpg_mode = rcar_gen2_read_mode_pins(); 413 412 } 414 413
+7
drivers/clk/renesas/r8a7792-cpg-mssr.c
··· 118 118 DEF_MOD("vin1", 810, R8A7792_CLK_ZG), 119 119 DEF_MOD("vin0", 811, R8A7792_CLK_ZG), 120 120 DEF_MOD("etheravb", 812, R8A7792_CLK_HP), 121 + DEF_MOD("imr-lx3", 821, R8A7792_CLK_ZG), 122 + DEF_MOD("imr-lsx3-1", 822, R8A7792_CLK_ZG), 123 + DEF_MOD("imr-lsx3-0", 823, R8A7792_CLK_ZG), 124 + DEF_MOD("imr-lsx3-5", 825, R8A7792_CLK_ZG), 125 + DEF_MOD("imr-lsx3-4", 826, R8A7792_CLK_ZG), 126 + DEF_MOD("imr-lsx3-3", 827, R8A7792_CLK_ZG), 127 + DEF_MOD("imr-lsx3-2", 828, R8A7792_CLK_ZG), 121 128 DEF_MOD("gyro-adc", 901, R8A7792_CLK_P), 122 129 DEF_MOD("gpio7", 904, R8A7792_CLK_CP), 123 130 DEF_MOD("gpio6", 905, R8A7792_CLK_CP),
+17 -17
drivers/clk/renesas/r8a7795-cpg-mssr.c
··· 305 305 (((md) & BIT(17)) >> 17)) 306 306 307 307 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { 308 - /* EXTAL div PLL1 mult PLL3 mult */ 309 - { 1, 192, 192, }, 310 - { 1, 192, 128, }, 311 - { 0, /* Prohibited setting */ }, 312 - { 1, 192, 192, }, 313 - { 1, 160, 160, }, 314 - { 1, 160, 106, }, 315 - { 0, /* Prohibited setting */ }, 316 - { 1, 160, 160, }, 317 - { 1, 128, 128, }, 318 - { 1, 128, 84, }, 319 - { 0, /* Prohibited setting */ }, 320 - { 1, 128, 128, }, 321 - { 2, 192, 192, }, 322 - { 2, 192, 128, }, 323 - { 0, /* Prohibited setting */ }, 324 - { 2, 192, 192, }, 308 + /* EXTAL div PLL1 mult/div PLL3 mult/div */ 309 + { 1, 192, 1, 192, 1, }, 310 + { 1, 192, 1, 128, 1, }, 311 + { 0, /* Prohibited setting */ }, 312 + { 1, 192, 1, 192, 1, }, 313 + { 1, 160, 1, 160, 1, }, 314 + { 1, 160, 1, 106, 1, }, 315 + { 0, /* Prohibited setting */ }, 316 + { 1, 160, 1, 160, 1, }, 317 + { 1, 128, 1, 128, 1, }, 318 + { 1, 128, 1, 84, 1, }, 319 + { 0, /* Prohibited setting */ }, 320 + { 1, 128, 1, 128, 1, }, 321 + { 2, 192, 1, 192, 1, }, 322 + { 2, 192, 1, 128, 1, }, 323 + { 0, /* Prohibited setting */ }, 324 + { 2, 192, 1, 192, 1, }, 325 325 }; 326 326 327 327 static const struct soc_device_attribute r8a7795es1[] __initconst = {
+18 -17
drivers/clk/renesas/r8a7796-cpg-mssr.c
··· 138 138 DEF_MOD("sdif0", 314, R8A7796_CLK_SD0), 139 139 DEF_MOD("pcie1", 318, R8A7796_CLK_S3D1), 140 140 DEF_MOD("pcie0", 319, R8A7796_CLK_S3D1), 141 + DEF_MOD("usb3-if0", 328, R8A7796_CLK_S3D1), 141 142 DEF_MOD("usb-dmac0", 330, R8A7796_CLK_S3D1), 142 143 DEF_MOD("usb-dmac1", 331, R8A7796_CLK_S3D1), 143 144 DEF_MOD("rwdt", 402, R8A7796_CLK_R), ··· 278 277 (((md) & BIT(17)) >> 17)) 279 278 280 279 static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { 281 - /* EXTAL div PLL1 mult PLL3 mult */ 282 - { 1, 192, 192, }, 283 - { 1, 192, 128, }, 284 - { 0, /* Prohibited setting */ }, 285 - { 1, 192, 192, }, 286 - { 1, 160, 160, }, 287 - { 1, 160, 106, }, 288 - { 0, /* Prohibited setting */ }, 289 - { 1, 160, 160, }, 290 - { 1, 128, 128, }, 291 - { 1, 128, 84, }, 292 - { 0, /* Prohibited setting */ }, 293 - { 1, 128, 128, }, 294 - { 2, 192, 192, }, 295 - { 2, 192, 128, }, 296 - { 0, /* Prohibited setting */ }, 297 - { 2, 192, 192, }, 280 + /* EXTAL div PLL1 mult/div PLL3 mult/div */ 281 + { 1, 192, 1, 192, 1, }, 282 + { 1, 192, 1, 128, 1, }, 283 + { 0, /* Prohibited setting */ }, 284 + { 1, 192, 1, 192, 1, }, 285 + { 1, 160, 1, 160, 1, }, 286 + { 1, 160, 1, 106, 1, }, 287 + { 0, /* Prohibited setting */ }, 288 + { 1, 160, 1, 160, 1, }, 289 + { 1, 128, 1, 128, 1, }, 290 + { 1, 128, 1, 84, 1, }, 291 + { 0, /* Prohibited setting */ }, 292 + { 1, 128, 1, 128, 1, }, 293 + { 2, 192, 1, 192, 1, }, 294 + { 2, 192, 1, 128, 1, }, 295 + { 0, /* Prohibited setting */ }, 296 + { 2, 192, 1, 192, 1, }, 298 297 }; 299 298 300 299 static int __init r8a7796_cpg_mssr_init(struct device *dev)
+236
drivers/clk/renesas/r8a77995-cpg-mssr.c
··· 1 + /* 2 + * r8a77995 Clock Pulse Generator / Module Standby and Software Reset 3 + * 4 + * Copyright (C) 2017 Glider bvba 5 + * 6 + * Based on r8a7795-cpg-mssr.c 7 + * 8 + * Copyright (C) 2015 Glider bvba 9 + * Copyright (C) 2015 Renesas Electronics Corp. 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License as published by 13 + * the Free Software Foundation; version 2 of the License. 14 + */ 15 + 16 + #include <linux/device.h> 17 + #include <linux/init.h> 18 + #include <linux/kernel.h> 19 + #include <linux/soc/renesas/rcar-rst.h> 20 + 21 + #include <dt-bindings/clock/r8a77995-cpg-mssr.h> 22 + 23 + #include "renesas-cpg-mssr.h" 24 + #include "rcar-gen3-cpg.h" 25 + 26 + enum clk_ids { 27 + /* Core Clock Outputs exported to DT */ 28 + LAST_DT_CORE_CLK = R8A77995_CLK_CP, 29 + 30 + /* External Input Clocks */ 31 + CLK_EXTAL, 32 + 33 + /* Internal Core Clocks */ 34 + CLK_MAIN, 35 + CLK_PLL0, 36 + CLK_PLL1, 37 + CLK_PLL3, 38 + CLK_PLL0D2, 39 + CLK_PLL0D3, 40 + CLK_PLL0D5, 41 + CLK_PLL1D2, 42 + CLK_PE, 43 + CLK_S0, 44 + CLK_S1, 45 + CLK_S2, 46 + CLK_S3, 47 + CLK_SDSRC, 48 + CLK_SSPSRC, 49 + 50 + /* Module Clocks */ 51 + MOD_CLK_BASE 52 + }; 53 + 54 + static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { 55 + /* External Clock Inputs */ 56 + DEF_INPUT("extal", CLK_EXTAL), 57 + 58 + /* Internal Core Clocks */ 59 + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), 60 + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), 61 + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), 62 + 63 + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 4, 250), 64 + DEF_FIXED(".pll0d2", CLK_PLL0D2, CLK_PLL0, 2, 1), 65 + DEF_FIXED(".pll0d3", CLK_PLL0D3, CLK_PLL0, 3, 1), 66 + DEF_FIXED(".pll0d5", CLK_PLL0D5, CLK_PLL0, 5, 1), 67 + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), 68 + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D3, 4, 1), 69 + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), 70 + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), 71 + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), 72 + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), 73 + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), 74 + 75 + /* Core Clock Outputs */ 76 + DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), 77 + DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), 78 + DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), 79 + DEF_FIXED("zx", R8A77995_CLK_ZX, CLK_PLL1, 3, 1), 80 + DEF_FIXED("s0d1", R8A77995_CLK_S0D1, CLK_S0, 1, 1), 81 + DEF_FIXED("s1d1", R8A77995_CLK_S1D1, CLK_S1, 1, 1), 82 + DEF_FIXED("s1d2", R8A77995_CLK_S1D2, CLK_S1, 2, 1), 83 + DEF_FIXED("s1d4", R8A77995_CLK_S1D4, CLK_S1, 4, 1), 84 + DEF_FIXED("s2d1", R8A77995_CLK_S2D1, CLK_S2, 1, 1), 85 + DEF_FIXED("s2d2", R8A77995_CLK_S2D2, CLK_S2, 2, 1), 86 + DEF_FIXED("s2d4", R8A77995_CLK_S2D4, CLK_S2, 4, 1), 87 + DEF_FIXED("s3d1", R8A77995_CLK_S3D1, CLK_S3, 1, 1), 88 + DEF_FIXED("s3d2", R8A77995_CLK_S3D2, CLK_S3, 2, 1), 89 + DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1), 90 + 91 + DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1), 92 + DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1), 93 + DEF_FIXED("osc", R8A77995_CLK_OSC, CLK_EXTAL, 384, 1), 94 + DEF_FIXED("r", R8A77995_CLK_R, CLK_EXTAL, 1536, 1), 95 + 96 + DEF_GEN3_PE("s1d4c", R8A77995_CLK_S1D4C, CLK_S1, 4, CLK_PE, 2), 97 + DEF_GEN3_PE("s3d1c", R8A77995_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), 98 + DEF_GEN3_PE("s3d2c", R8A77995_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), 99 + DEF_GEN3_PE("s3d4c", R8A77995_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), 100 + 101 + DEF_GEN3_SD("sd0", R8A77995_CLK_SD0, CLK_SDSRC, 0x268), 102 + 103 + DEF_DIV6P1("canfd", R8A77995_CLK_CANFD, CLK_PLL0D3, 0x244), 104 + DEF_DIV6P1("mso", R8A77995_CLK_MSO, CLK_PLL1D2, 0x014), 105 + }; 106 + 107 + static const struct mssr_mod_clk r8a77995_mod_clks[] __initconst = { 108 + DEF_MOD("scif5", 202, R8A77995_CLK_S3D4C), 109 + DEF_MOD("scif4", 203, R8A77995_CLK_S3D4C), 110 + DEF_MOD("scif3", 204, R8A77995_CLK_S3D4C), 111 + DEF_MOD("scif1", 206, R8A77995_CLK_S3D4C), 112 + DEF_MOD("scif0", 207, R8A77995_CLK_S3D4C), 113 + DEF_MOD("msiof3", 208, R8A77995_CLK_MSO), 114 + DEF_MOD("msiof2", 209, R8A77995_CLK_MSO), 115 + DEF_MOD("msiof1", 210, R8A77995_CLK_MSO), 116 + DEF_MOD("msiof0", 211, R8A77995_CLK_MSO), 117 + DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1), 118 + DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1), 119 + DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1), 120 + DEF_MOD("cmt3", 300, R8A77995_CLK_R), 121 + DEF_MOD("cmt2", 301, R8A77995_CLK_R), 122 + DEF_MOD("cmt1", 302, R8A77995_CLK_R), 123 + DEF_MOD("cmt0", 303, R8A77995_CLK_R), 124 + DEF_MOD("scif2", 310, R8A77995_CLK_S3D4C), 125 + DEF_MOD("emmc0", 312, R8A77995_CLK_SD0), 126 + DEF_MOD("usb-dmac0", 330, R8A77995_CLK_S3D1), 127 + DEF_MOD("usb-dmac1", 331, R8A77995_CLK_S3D1), 128 + DEF_MOD("rwdt", 402, R8A77995_CLK_R), 129 + DEF_MOD("intc-ex", 407, R8A77995_CLK_CP), 130 + DEF_MOD("intc-ap", 408, R8A77995_CLK_S3D1), 131 + DEF_MOD("audmac0", 502, R8A77995_CLK_S3D1), 132 + DEF_MOD("hscif3", 517, R8A77995_CLK_S3D1C), 133 + DEF_MOD("hscif0", 520, R8A77995_CLK_S3D1C), 134 + DEF_MOD("thermal", 522, R8A77995_CLK_CP), 135 + DEF_MOD("pwm", 523, R8A77995_CLK_S3D4C), 136 + DEF_MOD("fcpvd1", 602, R8A77995_CLK_S1D2), 137 + DEF_MOD("fcpvd0", 603, R8A77995_CLK_S1D2), 138 + DEF_MOD("fcpvbs", 607, R8A77995_CLK_S0D1), 139 + DEF_MOD("vspd1", 622, R8A77995_CLK_S1D2), 140 + DEF_MOD("vspd0", 623, R8A77995_CLK_S1D2), 141 + DEF_MOD("vspbs", 627, R8A77995_CLK_S0D1), 142 + DEF_MOD("ehci0", 703, R8A77995_CLK_S3D2), 143 + DEF_MOD("hsusb", 704, R8A77995_CLK_S3D2), 144 + DEF_MOD("du1", 723, R8A77995_CLK_S2D1), 145 + DEF_MOD("du0", 724, R8A77995_CLK_S2D1), 146 + DEF_MOD("lvds", 727, R8A77995_CLK_S2D1), 147 + DEF_MOD("vin7", 804, R8A77995_CLK_S1D2), 148 + DEF_MOD("vin6", 805, R8A77995_CLK_S1D2), 149 + DEF_MOD("vin5", 806, R8A77995_CLK_S1D2), 150 + DEF_MOD("vin4", 807, R8A77995_CLK_S1D2), 151 + DEF_MOD("etheravb", 812, R8A77995_CLK_S3D2), 152 + DEF_MOD("imr0", 823, R8A77995_CLK_S1D2), 153 + DEF_MOD("gpio6", 906, R8A77995_CLK_S3D4), 154 + DEF_MOD("gpio5", 907, R8A77995_CLK_S3D4), 155 + DEF_MOD("gpio4", 908, R8A77995_CLK_S3D4), 156 + DEF_MOD("gpio3", 909, R8A77995_CLK_S3D4), 157 + DEF_MOD("gpio2", 910, R8A77995_CLK_S3D4), 158 + DEF_MOD("gpio1", 911, R8A77995_CLK_S3D4), 159 + DEF_MOD("gpio0", 912, R8A77995_CLK_S3D4), 160 + DEF_MOD("can-fd", 914, R8A77995_CLK_S3D2), 161 + DEF_MOD("can-if1", 915, R8A77995_CLK_S3D4), 162 + DEF_MOD("can-if0", 916, R8A77995_CLK_S3D4), 163 + DEF_MOD("i2c3", 928, R8A77995_CLK_S3D2), 164 + DEF_MOD("i2c2", 929, R8A77995_CLK_S3D2), 165 + DEF_MOD("i2c1", 930, R8A77995_CLK_S3D2), 166 + DEF_MOD("i2c0", 931, R8A77995_CLK_S3D2), 167 + DEF_MOD("ssi-all", 1005, R8A77995_CLK_S3D4), 168 + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), 169 + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), 170 + DEF_MOD("scu-all", 1017, R8A77995_CLK_S3D4), 171 + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), 172 + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), 173 + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), 174 + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), 175 + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), 176 + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), 177 + }; 178 + 179 + static const unsigned int r8a77995_crit_mod_clks[] __initconst = { 180 + MOD_CLK_ID(408), /* INTC-AP (GIC) */ 181 + }; 182 + 183 + 184 + /* 185 + * CPG Clock Data 186 + */ 187 + 188 + /* 189 + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 190 + *-------------------------------------------------------------------- 191 + * 0 48 x 1 x250/4 x100/3 x100/3 192 + * 1 48 x 1 x250/4 x100/3 x116/6 193 + */ 194 + #define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) 195 + 196 + static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { 197 + /* EXTAL div PLL1 mult/div PLL3 mult/div */ 198 + { 1, 100, 3, 100, 3, }, 199 + { 1, 100, 3, 116, 6, }, 200 + }; 201 + 202 + static int __init r8a77995_cpg_mssr_init(struct device *dev) 203 + { 204 + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; 205 + u32 cpg_mode; 206 + int error; 207 + 208 + error = rcar_rst_read_mode_pins(&cpg_mode); 209 + if (error) 210 + return error; 211 + 212 + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; 213 + 214 + return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); 215 + } 216 + 217 + const struct cpg_mssr_info r8a77995_cpg_mssr_info __initconst = { 218 + /* Core Clocks */ 219 + .core_clks = r8a77995_core_clks, 220 + .num_core_clks = ARRAY_SIZE(r8a77995_core_clks), 221 + .last_dt_core_clk = LAST_DT_CORE_CLK, 222 + .num_total_core_clks = MOD_CLK_BASE, 223 + 224 + /* Module Clocks */ 225 + .mod_clks = r8a77995_mod_clks, 226 + .num_mod_clks = ARRAY_SIZE(r8a77995_mod_clks), 227 + .num_hw_mod_clks = 12 * 32, 228 + 229 + /* Critical Module Clocks */ 230 + .crit_mod_clks = r8a77995_crit_mod_clks, 231 + .num_crit_mod_clks = ARRAY_SIZE(r8a77995_crit_mod_clks), 232 + 233 + /* Callbacks */ 234 + .init = r8a77995_cpg_mssr_init, 235 + .cpg_clk_register = rcar_gen3_cpg_clk_register, 236 + };
+41 -28
drivers/clk/renesas/rcar-gen3-cpg.c
··· 60 60 unsigned int div_num; 61 61 unsigned int div_min; 62 62 unsigned int div_max; 63 + unsigned int cur_div_idx; 63 64 }; 64 65 65 66 /* SDn divider ··· 97 96 static int cpg_sd_clock_enable(struct clk_hw *hw) 98 97 { 99 98 struct sd_clock *clock = to_sd_clock(hw); 100 - u32 val, sd_fc; 101 - unsigned int i; 102 - 103 - val = readl(clock->reg); 104 - 105 - sd_fc = val & CPG_SD_FC_MASK; 106 - for (i = 0; i < clock->div_num; i++) 107 - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 108 - break; 109 - 110 - if (i >= clock->div_num) 111 - return -EINVAL; 99 + u32 val = readl(clock->reg); 112 100 113 101 val &= ~(CPG_SD_STP_MASK); 114 - val |= clock->div_table[i].val & CPG_SD_STP_MASK; 102 + val |= clock->div_table[clock->cur_div_idx].val & CPG_SD_STP_MASK; 115 103 116 104 writel(val, clock->reg); 117 105 ··· 125 135 unsigned long parent_rate) 126 136 { 127 137 struct sd_clock *clock = to_sd_clock(hw); 128 - unsigned long rate = parent_rate; 129 - u32 val, sd_fc; 130 - unsigned int i; 131 138 132 - val = readl(clock->reg); 133 - 134 - sd_fc = val & CPG_SD_FC_MASK; 135 - for (i = 0; i < clock->div_num; i++) 136 - if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 137 - break; 138 - 139 - if (i >= clock->div_num) 140 - return -EINVAL; 141 - 142 - return DIV_ROUND_CLOSEST(rate, clock->div_table[i].div); 139 + return DIV_ROUND_CLOSEST(parent_rate, 140 + clock->div_table[clock->cur_div_idx].div); 143 141 } 144 142 145 143 static unsigned int cpg_sd_clock_calc_div(struct sd_clock *clock, ··· 168 190 if (i >= clock->div_num) 169 191 return -EINVAL; 170 192 193 + clock->cur_div_idx = i; 194 + 171 195 val = readl(clock->reg); 172 196 val &= ~(CPG_SD_STP_MASK | CPG_SD_FC_MASK); 173 197 val |= clock->div_table[i].val & (CPG_SD_STP_MASK | CPG_SD_FC_MASK); ··· 195 215 struct sd_clock *clock; 196 216 struct clk *clk; 197 217 unsigned int i; 218 + u32 sd_fc; 198 219 199 220 clock = kzalloc(sizeof(*clock), GFP_KERNEL); 200 221 if (!clock) ··· 211 230 clock->hw.init = &init; 212 231 clock->div_table = cpg_sd_div_table; 213 232 clock->div_num = ARRAY_SIZE(cpg_sd_div_table); 233 + 234 + sd_fc = readl(clock->reg) & CPG_SD_FC_MASK; 235 + for (i = 0; i < clock->div_num; i++) 236 + if (sd_fc == (clock->div_table[i].val & CPG_SD_FC_MASK)) 237 + break; 238 + 239 + if (WARN_ON(i >= clock->div_num)) { 240 + kfree(clock); 241 + return ERR_PTR(-EINVAL); 242 + } 243 + 244 + clock->cur_div_idx = i; 214 245 215 246 clock->div_max = clock->div_table[0].div; 216 247 clock->div_min = clock->div_max; ··· 272 279 unsigned int div = 1; 273 280 u32 value; 274 281 275 - parent = clks[core->parent]; 282 + parent = clks[core->parent & 0xffff]; /* CLK_TYPE_PE uses high bits */ 276 283 if (IS_ERR(parent)) 277 284 return ERR_CAST(parent); 278 285 ··· 296 303 297 304 case CLK_TYPE_GEN3_PLL1: 298 305 mult = cpg_pll_config->pll1_mult; 306 + div = cpg_pll_config->pll1_div; 299 307 break; 300 308 301 309 case CLK_TYPE_GEN3_PLL2: ··· 314 320 315 321 case CLK_TYPE_GEN3_PLL3: 316 322 mult = cpg_pll_config->pll3_mult; 323 + div = cpg_pll_config->pll3_div; 317 324 break; 318 325 319 326 case CLK_TYPE_GEN3_PLL4: ··· 353 358 /* Select parent clock of RCLK by MD28 */ 354 359 if (cpg_mode & BIT(28)) 355 360 parent = clks[cpg_clk_extalr]; 361 + break; 362 + 363 + case CLK_TYPE_GEN3_PE: 364 + /* 365 + * Peripheral clock with a fixed divider, selectable between 366 + * clean and spread spectrum parents using MD12 367 + */ 368 + if (cpg_mode & BIT(12)) { 369 + /* Clean */ 370 + div = core->div & 0xffff; 371 + } else { 372 + /* SCCG */ 373 + parent = clks[core->parent >> 16]; 374 + if (IS_ERR(parent)) 375 + return ERR_CAST(parent); 376 + div = core->div >> 16; 377 + } 378 + mult = 1; 356 379 break; 357 380 358 381 default:
+12 -3
drivers/clk/renesas/rcar-gen3-cpg.h
··· 20 20 CLK_TYPE_GEN3_PLL4, 21 21 CLK_TYPE_GEN3_SD, 22 22 CLK_TYPE_GEN3_R, 23 + CLK_TYPE_GEN3_PE, 23 24 }; 24 25 25 26 #define DEF_GEN3_SD(_name, _id, _parent, _offset) \ 26 27 DEF_BASE(_name, _id, CLK_TYPE_GEN3_SD, _parent, .offset = _offset) 27 28 29 + #define DEF_GEN3_PE(_name, _id, _parent_sscg, _div_sscg, _parent_clean, \ 30 + _div_clean) \ 31 + DEF_BASE(_name, _id, CLK_TYPE_GEN3_PE, \ 32 + (_parent_sscg) << 16 | (_parent_clean), \ 33 + .div = (_div_sscg) << 16 | (_div_clean)) 34 + 28 35 struct rcar_gen3_cpg_pll_config { 29 - unsigned int extal_div; 30 - unsigned int pll1_mult; 31 - unsigned int pll3_mult; 36 + u8 extal_div; 37 + u8 pll1_mult; 38 + u8 pll1_div; 39 + u8 pll3_mult; 40 + u8 pll3_div; 32 41 }; 33 42 34 43 #define CPG_RCKCR 0x240
+188
drivers/clk/renesas/rcar-usb2-clock-sel.c
··· 1 + /* 2 + * Renesas R-Car USB2.0 clock selector 3 + * 4 + * Copyright (C) 2017 Renesas Electronics Corp. 5 + * 6 + * Based on renesas-cpg-mssr.c 7 + * 8 + * Copyright (C) 2015 Glider bvba 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License as published by 12 + * the Free Software Foundation; version 2 of the License. 13 + */ 14 + 15 + #include <linux/clk.h> 16 + #include <linux/clk-provider.h> 17 + #include <linux/device.h> 18 + #include <linux/init.h> 19 + #include <linux/module.h> 20 + #include <linux/of_device.h> 21 + #include <linux/platform_device.h> 22 + #include <linux/pm.h> 23 + #include <linux/pm_runtime.h> 24 + #include <linux/slab.h> 25 + 26 + #define USB20_CLKSET0 0x00 27 + #define CLKSET0_INTCLK_EN BIT(11) 28 + #define CLKSET0_PRIVATE BIT(0) 29 + #define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE) 30 + 31 + struct usb2_clock_sel_priv { 32 + void __iomem *base; 33 + struct clk_hw hw; 34 + bool extal; 35 + bool xtal; 36 + }; 37 + #define to_priv(_hw) container_of(_hw, struct usb2_clock_sel_priv, hw) 38 + 39 + static void usb2_clock_sel_enable_extal_only(struct usb2_clock_sel_priv *priv) 40 + { 41 + u16 val = readw(priv->base + USB20_CLKSET0); 42 + 43 + pr_debug("%s: enter %d %d %x\n", __func__, 44 + priv->extal, priv->xtal, val); 45 + 46 + if (priv->extal && !priv->xtal && val != CLKSET0_EXTAL_ONLY) 47 + writew(CLKSET0_EXTAL_ONLY, priv->base + USB20_CLKSET0); 48 + } 49 + 50 + static void usb2_clock_sel_disable_extal_only(struct usb2_clock_sel_priv *priv) 51 + { 52 + if (priv->extal && !priv->xtal) 53 + writew(CLKSET0_PRIVATE, priv->base + USB20_CLKSET0); 54 + } 55 + 56 + static int usb2_clock_sel_enable(struct clk_hw *hw) 57 + { 58 + usb2_clock_sel_enable_extal_only(to_priv(hw)); 59 + 60 + return 0; 61 + } 62 + 63 + static void usb2_clock_sel_disable(struct clk_hw *hw) 64 + { 65 + usb2_clock_sel_disable_extal_only(to_priv(hw)); 66 + } 67 + 68 + /* 69 + * This module seems a mux, but this driver assumes a gate because 70 + * ehci/ohci platform drivers don't support clk_set_parent() for now. 71 + * If this driver acts as a gate, ehci/ohci-platform drivers don't need 72 + * any modification. 73 + */ 74 + static const struct clk_ops usb2_clock_sel_clock_ops = { 75 + .enable = usb2_clock_sel_enable, 76 + .disable = usb2_clock_sel_disable, 77 + }; 78 + 79 + static const struct of_device_id rcar_usb2_clock_sel_match[] = { 80 + { .compatible = "renesas,rcar-gen3-usb2-clock-sel" }, 81 + { } 82 + }; 83 + 84 + static int rcar_usb2_clock_sel_suspend(struct device *dev) 85 + { 86 + struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); 87 + 88 + usb2_clock_sel_disable_extal_only(priv); 89 + pm_runtime_put(dev); 90 + 91 + return 0; 92 + } 93 + 94 + static int rcar_usb2_clock_sel_resume(struct device *dev) 95 + { 96 + struct usb2_clock_sel_priv *priv = dev_get_drvdata(dev); 97 + 98 + pm_runtime_get_sync(dev); 99 + usb2_clock_sel_enable_extal_only(priv); 100 + 101 + return 0; 102 + } 103 + 104 + static int rcar_usb2_clock_sel_remove(struct platform_device *pdev) 105 + { 106 + struct device *dev = &pdev->dev; 107 + struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev); 108 + 109 + of_clk_del_provider(dev->of_node); 110 + clk_hw_unregister(&priv->hw); 111 + pm_runtime_put(dev); 112 + pm_runtime_disable(dev); 113 + 114 + return 0; 115 + } 116 + 117 + static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) 118 + { 119 + struct device *dev = &pdev->dev; 120 + struct device_node *np = dev->of_node; 121 + struct usb2_clock_sel_priv *priv; 122 + struct resource *res; 123 + struct clk *clk; 124 + struct clk_init_data init; 125 + 126 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 127 + if (!priv) 128 + return -ENOMEM; 129 + 130 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 131 + priv->base = devm_ioremap_resource(dev, res); 132 + if (IS_ERR(priv->base)) 133 + return PTR_ERR(priv->base); 134 + 135 + pm_runtime_enable(dev); 136 + pm_runtime_get_sync(dev); 137 + 138 + clk = devm_clk_get(dev, "usb_extal"); 139 + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { 140 + priv->extal = !!clk_get_rate(clk); 141 + clk_disable_unprepare(clk); 142 + } 143 + clk = devm_clk_get(dev, "usb_xtal"); 144 + if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { 145 + priv->xtal = !!clk_get_rate(clk); 146 + clk_disable_unprepare(clk); 147 + } 148 + 149 + if (!priv->extal && !priv->xtal) { 150 + dev_err(dev, "This driver needs usb_extal or usb_xtal\n"); 151 + return -ENOENT; 152 + } 153 + 154 + platform_set_drvdata(pdev, priv); 155 + dev_set_drvdata(dev, priv); 156 + 157 + init.name = "rcar_usb2_clock_sel"; 158 + init.ops = &usb2_clock_sel_clock_ops; 159 + init.flags = 0; 160 + init.parent_names = NULL; 161 + init.num_parents = 0; 162 + priv->hw.init = &init; 163 + 164 + clk = clk_register(NULL, &priv->hw); 165 + if (IS_ERR(clk)) 166 + return PTR_ERR(clk); 167 + 168 + return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); 169 + } 170 + 171 + static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = { 172 + .suspend = rcar_usb2_clock_sel_suspend, 173 + .resume = rcar_usb2_clock_sel_resume, 174 + }; 175 + 176 + static struct platform_driver rcar_usb2_clock_sel_driver = { 177 + .driver = { 178 + .name = "rcar-usb2-clock-sel", 179 + .of_match_table = rcar_usb2_clock_sel_match, 180 + .pm = &rcar_usb2_clock_sel_pm_ops, 181 + }, 182 + .probe = rcar_usb2_clock_sel_probe, 183 + .remove = rcar_usb2_clock_sel_remove, 184 + }; 185 + builtin_platform_driver(rcar_usb2_clock_sel_driver); 186 + 187 + MODULE_DESCRIPTION("Renesas R-Car USB2 clock selector Driver"); 188 + MODULE_LICENSE("GPL v2");
+6
drivers/clk/renesas/renesas-cpg-mssr.c
··· 680 680 .data = &r8a7796_cpg_mssr_info, 681 681 }, 682 682 #endif 683 + #ifdef CONFIG_CLK_R8A77995 684 + { 685 + .compatible = "renesas,r8a77995-cpg-mssr", 686 + .data = &r8a77995_cpg_mssr_info, 687 + }, 688 + #endif 683 689 { /* sentinel */ } 684 690 }; 685 691
+1
drivers/clk/renesas/renesas-cpg-mssr.h
··· 138 138 extern const struct cpg_mssr_info r8a7794_cpg_mssr_info; 139 139 extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; 140 140 extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; 141 + extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; 141 142 142 143 143 144 /*
+55 -14
drivers/clk/rockchip/clk-rk3128.c
··· 201 201 MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, 202 202 RK2928_CLKSEL_CON(15), 8, 2, MFLAGS); 203 203 204 - static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { 204 + static struct rockchip_clk_branch common_clk_branches[] __initdata = { 205 205 /* 206 206 * Clock-Architecture Diagram 1 207 207 */ ··· 459 459 RK2928_CLKSEL_CON(2), 14, 2, MFLAGS, 8, 5, DFLAGS, 460 460 RK2928_CLKGATE_CON(10), 15, GFLAGS), 461 461 462 - COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0, 463 - RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, 464 - RK2928_CLKGATE_CON(3), 15, GFLAGS), 465 - 466 462 COMPOSITE_NOMUX(PCLK_PMU_PRE, "pclk_pmu_pre", "cpll", 0, 467 463 RK2928_CLKSEL_CON(29), 8, 6, DFLAGS, 468 464 RK2928_CLKGATE_CON(1), 0, GFLAGS), ··· 491 495 GATE(ACLK_DMAC, "aclk_dmac", "aclk_peri", 0, RK2928_CLKGATE_CON(5), 1, GFLAGS), 492 496 GATE(0, "aclk_peri_niu", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(9), 15, GFLAGS), 493 497 GATE(0, "aclk_cpu_to_peri", "aclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 2, GFLAGS), 494 - GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), 495 498 496 499 GATE(HCLK_I2S_8CH, "hclk_i2s_8ch", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), 497 500 GATE(0, "hclk_peri_matrix", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(4), 0, GFLAGS), ··· 536 541 GATE(0, "hclk_rom", "hclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 6, GFLAGS), 537 542 GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_cpu", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), 538 543 539 - GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), 540 544 GATE(PCLK_ACODEC, "pclk_acodec", "pclk_cpu", 0, RK2928_CLKGATE_CON(5), 14, GFLAGS), 541 545 GATE(0, "pclk_ddrupctl", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 7, GFLAGS), 542 546 GATE(0, "pclk_grf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 4, GFLAGS), ··· 555 561 MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "sclk_emmc", RK3228_EMMC_CON1, 0), 556 562 }; 557 563 564 + static struct rockchip_clk_branch rk3126_clk_branches[] __initdata = { 565 + GATE(0, "pclk_stimer", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 15, GFLAGS), 566 + GATE(0, "pclk_s_efuse", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), 567 + GATE(0, "pclk_sgrf", "pclk_cpu", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 8, GFLAGS), 568 + }; 569 + 570 + static struct rockchip_clk_branch rk3128_clk_branches[] __initdata = { 571 + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_sclk_sfc_src_p, 0, 572 + RK2928_CLKSEL_CON(11), 14, 2, MFLAGS, 8, 5, DFLAGS, 573 + RK2928_CLKGATE_CON(3), 15, GFLAGS), 574 + 575 + GATE(HCLK_GPS, "hclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), 576 + GATE(PCLK_HDMI, "pclk_hdmi", "pclk_cpu", 0, RK2928_CLKGATE_CON(3), 8, GFLAGS), 577 + }; 578 + 558 579 static const char *const rk3128_critical_clocks[] __initconst = { 559 580 "aclk_cpu", 560 581 "hclk_cpu", ··· 579 570 "pclk_peri", 580 571 }; 581 572 582 - static void __init rk3128_clk_init(struct device_node *np) 573 + static struct rockchip_clk_provider *__init rk3128_common_clk_init(struct device_node *np) 583 574 { 584 575 struct rockchip_clk_provider *ctx; 585 576 void __iomem *reg_base; ··· 587 578 reg_base = of_iomap(np, 0); 588 579 if (!reg_base) { 589 580 pr_err("%s: could not map cru region\n", __func__); 590 - return; 581 + return ERR_PTR(-ENOMEM); 591 582 } 592 583 593 584 ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 594 585 if (IS_ERR(ctx)) { 595 586 pr_err("%s: rockchip clk init failed\n", __func__); 596 587 iounmap(reg_base); 597 - return; 588 + return ERR_PTR(-ENOMEM); 598 589 } 599 590 600 591 rockchip_clk_register_plls(ctx, rk3128_pll_clks, 601 592 ARRAY_SIZE(rk3128_pll_clks), 602 593 RK3128_GRF_SOC_STATUS0); 603 - rockchip_clk_register_branches(ctx, rk3128_clk_branches, 604 - ARRAY_SIZE(rk3128_clk_branches)); 605 - rockchip_clk_protect_critical(rk3128_critical_clocks, 606 - ARRAY_SIZE(rk3128_critical_clocks)); 594 + rockchip_clk_register_branches(ctx, common_clk_branches, 595 + ARRAY_SIZE(common_clk_branches)); 607 596 608 597 rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 609 598 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), ··· 612 605 ROCKCHIP_SOFTRST_HIWORD_MASK); 613 606 614 607 rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); 608 + 609 + return ctx; 610 + } 611 + 612 + static void __init rk3126_clk_init(struct device_node *np) 613 + { 614 + struct rockchip_clk_provider *ctx; 615 + 616 + ctx = rk3128_common_clk_init(np); 617 + if (IS_ERR(ctx)) 618 + return; 619 + 620 + rockchip_clk_register_branches(ctx, rk3126_clk_branches, 621 + ARRAY_SIZE(rk3126_clk_branches)); 622 + rockchip_clk_protect_critical(rk3128_critical_clocks, 623 + ARRAY_SIZE(rk3128_critical_clocks)); 624 + 625 + rockchip_clk_of_add_provider(np, ctx); 626 + } 627 + 628 + CLK_OF_DECLARE(rk3126_cru, "rockchip,rk3126-cru", rk3126_clk_init); 629 + 630 + static void __init rk3128_clk_init(struct device_node *np) 631 + { 632 + struct rockchip_clk_provider *ctx; 633 + 634 + ctx = rk3128_common_clk_init(np); 635 + if (IS_ERR(ctx)) 636 + return; 637 + 638 + rockchip_clk_register_branches(ctx, rk3128_clk_branches, 639 + ARRAY_SIZE(rk3128_clk_branches)); 640 + rockchip_clk_protect_critical(rk3128_critical_clocks, 641 + ARRAY_SIZE(rk3128_critical_clocks)); 615 642 616 643 rockchip_clk_of_add_provider(np, ctx); 617 644 }
+1 -1
drivers/clk/rockchip/clk-rk3228.c
··· 391 391 RK2928_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 8, DFLAGS, 392 392 RK2928_CLKGATE_CON(2), 11, GFLAGS), 393 393 394 - COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0, 394 + COMPOSITE_NODIV(SCLK_SDIO_SRC, "sclk_sdio_src", mux_mmc_src_p, 0, 395 395 RK2928_CLKSEL_CON(11), 10, 2, MFLAGS, 396 396 RK2928_CLKGATE_CON(2), 13, GFLAGS), 397 397 DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
+381 -81
drivers/clk/rockchip/clk-rv1108.c
··· 93 93 } 94 94 95 95 static struct rockchip_cpuclk_rate_table rv1108_cpuclk_rates[] __initdata = { 96 - RV1108_CPUCLK_RATE(816000000, 4), 97 - RV1108_CPUCLK_RATE(600000000, 4), 98 - RV1108_CPUCLK_RATE(312000000, 4), 96 + RV1108_CPUCLK_RATE(1608000000, 7), 97 + RV1108_CPUCLK_RATE(1512000000, 7), 98 + RV1108_CPUCLK_RATE(1488000000, 5), 99 + RV1108_CPUCLK_RATE(1416000000, 5), 100 + RV1108_CPUCLK_RATE(1392000000, 5), 101 + RV1108_CPUCLK_RATE(1296000000, 5), 102 + RV1108_CPUCLK_RATE(1200000000, 5), 103 + RV1108_CPUCLK_RATE(1104000000, 5), 104 + RV1108_CPUCLK_RATE(1008000000, 5), 105 + RV1108_CPUCLK_RATE(912000000, 5), 106 + RV1108_CPUCLK_RATE(816000000, 3), 107 + RV1108_CPUCLK_RATE(696000000, 3), 108 + RV1108_CPUCLK_RATE(600000000, 3), 109 + RV1108_CPUCLK_RATE(500000000, 3), 110 + RV1108_CPUCLK_RATE(408000000, 1), 111 + RV1108_CPUCLK_RATE(312000000, 1), 112 + RV1108_CPUCLK_RATE(216000000, 1), 113 + RV1108_CPUCLK_RATE(96000000, 1), 99 114 }; 100 115 101 116 static const struct rockchip_cpuclk_reg_data rv1108_cpuclk_data = { ··· 120 105 .mux_core_alt = 1, 121 106 .mux_core_main = 0, 122 107 .mux_core_shift = 8, 123 - .mux_core_mask = 0x1, 108 + .mux_core_mask = 0x3, 124 109 }; 125 110 126 111 PNAME(mux_pll_p) = { "xin24m", "xin24m"}; ··· 129 114 PNAME(mux_usb480m_pre_p) = { "usbphy", "xin24m" }; 130 115 PNAME(mux_hdmiphy_phy_p) = { "hdmiphy", "xin24m" }; 131 116 PNAME(mux_dclk_hdmiphy_pre_p) = { "dclk_hdmiphy_src_gpll", "dclk_hdmiphy_src_dpll" }; 132 - PNAME(mux_pll_src_4plls_p) = { "dpll", "hdmiphy", "gpll", "usb480m" }; 117 + PNAME(mux_pll_src_4plls_p) = { "dpll", "gpll", "hdmiphy", "usb480m" }; 133 118 PNAME(mux_pll_src_3plls_p) = { "apll", "gpll", "dpll" }; 134 119 PNAME(mux_pll_src_2plls_p) = { "dpll", "gpll" }; 135 120 PNAME(mux_pll_src_apll_gpll_p) = { "apll", "gpll" }; 136 - PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_dpll", "aclk_peri_src_gpll" }; 121 + PNAME(mux_aclk_peri_src_p) = { "aclk_peri_src_gpll", "aclk_peri_src_dpll" }; 137 122 PNAME(mux_aclk_bus_src_p) = { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" }; 138 123 PNAME(mux_mmc_src_p) = { "dpll", "gpll", "xin24m", "usb480m" }; 139 124 PNAME(mux_pll_src_dpll_gpll_usb480m_p) = { "dpll", "gpll", "usb480m" }; 140 125 PNAME(mux_uart0_p) = { "uart0_src", "uart0_frac", "xin24m" }; 141 126 PNAME(mux_uart1_p) = { "uart1_src", "uart1_frac", "xin24m" }; 142 127 PNAME(mux_uart2_p) = { "uart2_src", "uart2_frac", "xin24m" }; 143 - PNAME(mux_sclk_macphy_p) = { "sclk_macphy_pre", "ext_gmac" }; 128 + PNAME(mux_sclk_mac_p) = { "sclk_mac_pre", "ext_gmac" }; 144 129 PNAME(mux_i2s0_pre_p) = { "i2s0_src", "i2s0_frac", "ext_i2s", "xin12m" }; 145 130 PNAME(mux_i2s_out_p) = { "i2s0_pre", "xin12m" }; 146 - PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "xin12m" }; 147 - PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "xin12m" }; 131 + PNAME(mux_i2s1_p) = { "i2s1_src", "i2s1_frac", "dummy", "xin12m" }; 132 + PNAME(mux_i2s2_p) = { "i2s2_src", "i2s2_frac", "dummy", "xin12m" }; 133 + PNAME(mux_wifi_src_p) = { "gpll", "xin24m" }; 134 + PNAME(mux_cifout_src_p) = { "hdmiphy", "gpll" }; 135 + PNAME(mux_cifout_p) = { "sclk_cifout_src", "xin24m" }; 136 + PNAME(mux_sclk_cif0_src_p) = { "pclk_vip", "clk_cif0_chn_out", "pclkin_cvbs2cif" }; 137 + PNAME(mux_sclk_cif1_src_p) = { "pclk_vip", "clk_cif1_chn_out", "pclkin_cvbs2cif" }; 138 + PNAME(mux_sclk_cif2_src_p) = { "pclk_vip", "clk_cif2_chn_out", "pclkin_cvbs2cif" }; 139 + PNAME(mux_sclk_cif3_src_p) = { "pclk_vip", "clk_cif3_chn_out", "pclkin_cvbs2cif" }; 140 + PNAME(mux_dsp_src_p) = { "dpll", "gpll", "apll", "usb480m" }; 141 + PNAME(mux_dclk_hdmiphy_p) = { "hdmiphy", "xin24m" }; 142 + PNAME(mux_dclk_vop_p) = { "dclk_hdmiphy", "dclk_vop_src" }; 143 + PNAME(mux_hdmi_cec_src_p) = { "dpll", "gpll", "xin24m" }; 144 + PNAME(mux_cvbs_src_p) = { "apll", "io_cvbs_clkin", "hdmiphy", "gpll" }; 148 145 149 146 static struct rockchip_pll_clock rv1108_pll_clks[] __initdata = { 150 147 [apll] = PLL(pll_rk3399, PLL_APLL, "apll", mux_pll_p, 0, RV1108_PLL_CON(0), 151 - RV1108_PLL_CON(3), 8, 31, 0, rv1108_pll_rates), 148 + RV1108_PLL_CON(3), 8, 0, 0, rv1108_pll_rates), 152 149 [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RV1108_PLL_CON(8), 153 - RV1108_PLL_CON(11), 8, 31, 0, NULL), 150 + RV1108_PLL_CON(11), 8, 1, 0, NULL), 154 151 [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RV1108_PLL_CON(16), 155 - RV1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rv1108_pll_rates), 152 + RV1108_PLL_CON(19), 8, 2, 0, rv1108_pll_rates), 156 153 }; 157 154 158 155 #define MFLAGS CLK_MUX_HIWORD_MASK ··· 197 170 RV1108_CLKSEL_CON(7), 12, 2, MFLAGS); 198 171 199 172 static struct rockchip_clk_branch rv1108_clk_branches[] __initdata = { 200 - MUX(0, "hdmi_phy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT, 201 - RV1108_MISC_CON, 13, 2, MFLAGS), 173 + MUX(0, "hdmiphy", mux_hdmiphy_phy_p, CLK_SET_RATE_PARENT, 174 + RV1108_MISC_CON, 13, 1, MFLAGS), 202 175 MUX(0, "usb480m", mux_usb480m_pre_p, CLK_SET_RATE_PARENT, 203 - RV1108_MISC_CON, 15, 2, MFLAGS), 176 + RV1108_MISC_CON, 15, 1, MFLAGS), 204 177 /* 205 178 * Clock-Architecture Diagram 2 206 179 */ ··· 224 197 RV1108_CLKGATE_CON(11), 1, GFLAGS), 225 198 226 199 /* PD_RKVENC */ 200 + COMPOSITE(0, "aclk_rkvenc_pre", mux_pll_src_4plls_p, 0, 201 + RV1108_CLKSEL_CON(37), 6, 2, MFLAGS, 0, 5, DFLAGS, 202 + RV1108_CLKGATE_CON(8), 8, GFLAGS), 203 + FACTOR_GATE(0, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0, 1, 4, 204 + RV1108_CLKGATE_CON(8), 10, GFLAGS), 205 + COMPOSITE(SCLK_VENC_CORE, "clk_venc_core", mux_pll_src_4plls_p, 0, 206 + RV1108_CLKSEL_CON(37), 14, 2, MFLAGS, 8, 5, DFLAGS, 207 + RV1108_CLKGATE_CON(8), 9, GFLAGS), 208 + GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0, 209 + RV1108_CLKGATE_CON(19), 8, GFLAGS), 210 + GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0, 211 + RV1108_CLKGATE_CON(19), 9, GFLAGS), 212 + GATE(0, "aclk_rkvenc_niu", "aclk_rkvenc_pre", CLK_IGNORE_UNUSED, 213 + RV1108_CLKGATE_CON(19), 11, GFLAGS), 214 + GATE(0, "hclk_rkvenc_niu", "hclk_rkvenc_pre", CLK_IGNORE_UNUSED, 215 + RV1108_CLKGATE_CON(19), 10, GFLAGS), 227 216 228 217 /* PD_RKVDEC */ 218 + COMPOSITE(SCLK_HEVC_CORE, "sclk_hevc_core", mux_pll_src_4plls_p, 0, 219 + RV1108_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 5, DFLAGS, 220 + RV1108_CLKGATE_CON(8), 2, GFLAGS), 221 + FACTOR_GATE(0, "hclk_rkvdec_pre", "sclk_hevc_core", 0, 1, 4, 222 + RV1108_CLKGATE_CON(8), 10, GFLAGS), 223 + COMPOSITE(SCLK_HEVC_CABAC, "clk_hevc_cabac", mux_pll_src_4plls_p, 0, 224 + RV1108_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 5, DFLAGS, 225 + RV1108_CLKGATE_CON(8), 1, GFLAGS), 226 + 227 + COMPOSITE(0, "aclk_rkvdec_pre", mux_pll_src_4plls_p, 0, 228 + RV1108_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, 229 + RV1108_CLKGATE_CON(8), 0, GFLAGS), 230 + COMPOSITE(0, "aclk_vpu_pre", mux_pll_src_4plls_p, 0, 231 + RV1108_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 5, DFLAGS, 232 + RV1108_CLKGATE_CON(8), 3, GFLAGS), 233 + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, 234 + RV1108_CLKGATE_CON(19), 0, GFLAGS), 235 + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, 236 + RV1108_CLKGATE_CON(19), 1, GFLAGS), 237 + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, 238 + RV1108_CLKGATE_CON(19), 2, GFLAGS), 239 + GATE(HCLK_VPU, "hclk_vpu", "hclk_rkvdec_pre", 0, 240 + RV1108_CLKGATE_CON(19), 3, GFLAGS), 241 + GATE(0, "aclk_rkvdec_niu", "aclk_rkvdec_pre", CLK_IGNORE_UNUSED, 242 + RV1108_CLKGATE_CON(19), 4, GFLAGS), 243 + GATE(0, "hclk_rkvdec_niu", "hclk_rkvdec_pre", CLK_IGNORE_UNUSED, 244 + RV1108_CLKGATE_CON(19), 5, GFLAGS), 245 + GATE(0, "aclk_vpu_niu", "aclk_vpu_pre", CLK_IGNORE_UNUSED, 246 + RV1108_CLKGATE_CON(19), 6, GFLAGS), 229 247 230 248 /* PD_PMU_wrapper */ 231 249 COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED, 232 250 RV1108_CLKSEL_CON(38), 0, 5, DFLAGS, 233 251 RV1108_CLKGATE_CON(8), 12, GFLAGS), 234 - GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 252 + GATE(0, "pclk_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 235 253 RV1108_CLKGATE_CON(10), 0, GFLAGS), 236 - GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED, 254 + GATE(0, "pclk_intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED, 237 255 RV1108_CLKGATE_CON(10), 1, GFLAGS), 238 - GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 256 + GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pmu_24m_ena", 0, 239 257 RV1108_CLKGATE_CON(10), 2, GFLAGS), 240 - GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED, 258 + GATE(0, "pclk_pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED, 241 259 RV1108_CLKGATE_CON(10), 3, GFLAGS), 242 - GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED, 260 + GATE(0, "pclk_pmu_niu", "pmu_24m_ena", CLK_IGNORE_UNUSED, 243 261 RV1108_CLKGATE_CON(10), 4, GFLAGS), 244 - GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, 262 + GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pmu_24m_ena", 0, 245 263 RV1108_CLKGATE_CON(10), 5, GFLAGS), 246 - GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED, 264 + GATE(PCLK_PWM0_PMU, "pclk_pwm0_pmu", "pmu_24m_ena", 0, 247 265 RV1108_CLKGATE_CON(10), 6, GFLAGS), 248 - COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 266 + COMPOSITE(SCLK_PWM0_PMU, "sclk_pwm0_pmu", mux_pll_src_2plls_p, 0, 249 267 RV1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS, 250 268 RV1108_CLKGATE_CON(8), 15, GFLAGS), 251 - COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 269 + COMPOSITE(SCLK_I2C0_PMU, "sclk_i2c0_pmu", mux_pll_src_2plls_p, 0, 252 270 RV1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS, 253 271 RV1108_CLKGATE_CON(8), 14, GFLAGS), 254 272 GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, 255 273 RV1108_CLKGATE_CON(8), 13, GFLAGS), 256 274 257 275 /* 276 + * Clock-Architecture Diagram 3 277 + */ 278 + COMPOSITE(SCLK_WIFI, "sclk_wifi", mux_wifi_src_p, 0, 279 + RV1108_CLKSEL_CON(28), 15, 1, MFLAGS, 8, 6, DFLAGS, 280 + RV1108_CLKGATE_CON(9), 8, GFLAGS), 281 + COMPOSITE_NODIV(0, "sclk_cifout_src", mux_cifout_src_p, 0, 282 + RV1108_CLKSEL_CON(40), 8, 1, MFLAGS, 283 + RV1108_CLKGATE_CON(9), 11, GFLAGS), 284 + COMPOSITE_NOGATE(SCLK_CIFOUT, "sclk_cifout", mux_cifout_p, 0, 285 + RV1108_CLKSEL_CON(40), 12, 1, MFLAGS, 0, 5, DFLAGS), 286 + COMPOSITE_NOMUX(SCLK_MIPI_CSI_OUT, "sclk_mipi_csi_out", "xin24m", 0, 287 + RV1108_CLKSEL_CON(41), 0, 5, DFLAGS, 288 + RV1108_CLKGATE_CON(9), 12, GFLAGS), 289 + 290 + GATE(0, "pclk_acodecphy", "pclk_top_pre", CLK_IGNORE_UNUSED, 291 + RV1108_CLKGATE_CON(14), 6, GFLAGS), 292 + GATE(0, "pclk_usbgrf", "pclk_top_pre", CLK_IGNORE_UNUSED, 293 + RV1108_CLKGATE_CON(14), 14, GFLAGS), 294 + 295 + GATE(ACLK_CIF0, "aclk_cif0", "aclk_vio1_pre", 0, 296 + RV1108_CLKGATE_CON(18), 10, GFLAGS), 297 + GATE(HCLK_CIF0, "hclk_cif0", "hclk_vio_pre", 0, 298 + RV1108_CLKGATE_CON(18), 10, GFLAGS), 299 + COMPOSITE_NODIV(SCLK_CIF0, "sclk_cif0", mux_sclk_cif0_src_p, 0, 300 + RV1108_CLKSEL_CON(31), 0, 2, MFLAGS, 301 + RV1108_CLKGATE_CON(7), 9, GFLAGS), 302 + GATE(ACLK_CIF1, "aclk_cif1", "aclk_vio1_pre", 0, 303 + RV1108_CLKGATE_CON(17), 6, GFLAGS), 304 + GATE(HCLK_CIF1, "hclk_cif1", "hclk_vio_pre", 0, 305 + RV1108_CLKGATE_CON(17), 7, GFLAGS), 306 + COMPOSITE_NODIV(SCLK_CIF1, "sclk_cif1", mux_sclk_cif1_src_p, 0, 307 + RV1108_CLKSEL_CON(31), 2, 2, MFLAGS, 308 + RV1108_CLKGATE_CON(7), 10, GFLAGS), 309 + GATE(ACLK_CIF2, "aclk_cif2", "aclk_vio1_pre", 0, 310 + RV1108_CLKGATE_CON(17), 8, GFLAGS), 311 + GATE(HCLK_CIF2, "hclk_cif2", "hclk_vio_pre", 0, 312 + RV1108_CLKGATE_CON(17), 9, GFLAGS), 313 + COMPOSITE_NODIV(SCLK_CIF2, "sclk_cif2", mux_sclk_cif2_src_p, 0, 314 + RV1108_CLKSEL_CON(31), 4, 2, MFLAGS, 315 + RV1108_CLKGATE_CON(7), 11, GFLAGS), 316 + GATE(ACLK_CIF3, "aclk_cif3", "aclk_vio1_pre", 0, 317 + RV1108_CLKGATE_CON(17), 10, GFLAGS), 318 + GATE(HCLK_CIF3, "hclk_cif3", "hclk_vio_pre", 0, 319 + RV1108_CLKGATE_CON(17), 11, GFLAGS), 320 + COMPOSITE_NODIV(SCLK_CIF3, "sclk_cif3", mux_sclk_cif3_src_p, 0, 321 + RV1108_CLKSEL_CON(31), 6, 2, MFLAGS, 322 + RV1108_CLKGATE_CON(7), 12, GFLAGS), 323 + GATE(0, "pclk_cif1to4", "pclk_vip", CLK_IGNORE_UNUSED, 324 + RV1108_CLKGATE_CON(7), 8, GFLAGS), 325 + 326 + /* PD_DSP_wrapper */ 327 + COMPOSITE(SCLK_DSP, "sclk_dsp", mux_dsp_src_p, 0, 328 + RV1108_CLKSEL_CON(42), 8, 2, MFLAGS, 0, 5, DFLAGS, 329 + RV1108_CLKGATE_CON(9), 0, GFLAGS), 330 + GATE(0, "clk_dsp_sys_wd", "sclk_dsp", CLK_IGNORE_UNUSED, 331 + RV1108_CLKGATE_CON(16), 0, GFLAGS), 332 + GATE(0, "clk_dsp_epp_wd", "sclk_dsp", CLK_IGNORE_UNUSED, 333 + RV1108_CLKGATE_CON(16), 1, GFLAGS), 334 + GATE(0, "clk_dsp_edp_wd", "sclk_dsp", CLK_IGNORE_UNUSED, 335 + RV1108_CLKGATE_CON(16), 2, GFLAGS), 336 + GATE(0, "clk_dsp_iop_wd", "sclk_dsp", CLK_IGNORE_UNUSED, 337 + RV1108_CLKGATE_CON(16), 3, GFLAGS), 338 + GATE(0, "clk_dsp_free", "sclk_dsp", CLK_IGNORE_UNUSED, 339 + RV1108_CLKGATE_CON(16), 13, GFLAGS), 340 + COMPOSITE_NOMUX(SCLK_DSP_IOP, "sclk_dsp_iop", "sclk_dsp", 0, 341 + RV1108_CLKSEL_CON(44), 0, 5, DFLAGS, 342 + RV1108_CLKGATE_CON(9), 1, GFLAGS), 343 + COMPOSITE_NOMUX(SCLK_DSP_EPP, "sclk_dsp_epp", "sclk_dsp", 0, 344 + RV1108_CLKSEL_CON(44), 8, 5, DFLAGS, 345 + RV1108_CLKGATE_CON(9), 2, GFLAGS), 346 + COMPOSITE_NOMUX(SCLK_DSP_EDP, "sclk_dsp_edp", "sclk_dsp", 0, 347 + RV1108_CLKSEL_CON(45), 0, 5, DFLAGS, 348 + RV1108_CLKGATE_CON(9), 3, GFLAGS), 349 + COMPOSITE_NOMUX(SCLK_DSP_EDAP, "sclk_dsp_edap", "sclk_dsp", 0, 350 + RV1108_CLKSEL_CON(45), 8, 5, DFLAGS, 351 + RV1108_CLKGATE_CON(9), 4, GFLAGS), 352 + GATE(0, "pclk_dsp_iop_niu", "sclk_dsp_iop", CLK_IGNORE_UNUSED, 353 + RV1108_CLKGATE_CON(16), 4, GFLAGS), 354 + GATE(0, "aclk_dsp_epp_niu", "sclk_dsp_epp", CLK_IGNORE_UNUSED, 355 + RV1108_CLKGATE_CON(16), 5, GFLAGS), 356 + GATE(0, "aclk_dsp_edp_niu", "sclk_dsp_edp", CLK_IGNORE_UNUSED, 357 + RV1108_CLKGATE_CON(16), 6, GFLAGS), 358 + GATE(0, "pclk_dsp_dbg_niu", "sclk_dsp", CLK_IGNORE_UNUSED, 359 + RV1108_CLKGATE_CON(16), 7, GFLAGS), 360 + GATE(0, "aclk_dsp_edap_niu", "sclk_dsp_edap", CLK_IGNORE_UNUSED, 361 + RV1108_CLKGATE_CON(16), 14, GFLAGS), 362 + COMPOSITE_NOMUX(SCLK_DSP_PFM, "sclk_dsp_pfm", "sclk_dsp", 0, 363 + RV1108_CLKSEL_CON(43), 0, 5, DFLAGS, 364 + RV1108_CLKGATE_CON(9), 5, GFLAGS), 365 + COMPOSITE_NOMUX(PCLK_DSP_CFG, "pclk_dsp_cfg", "sclk_dsp", 0, 366 + RV1108_CLKSEL_CON(43), 8, 5, DFLAGS, 367 + RV1108_CLKGATE_CON(9), 6, GFLAGS), 368 + GATE(0, "pclk_dsp_cfg_niu", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, 369 + RV1108_CLKGATE_CON(16), 8, GFLAGS), 370 + GATE(0, "pclk_dsp_pfm_mon", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, 371 + RV1108_CLKGATE_CON(16), 9, GFLAGS), 372 + GATE(0, "pclk_intc", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, 373 + RV1108_CLKGATE_CON(16), 10, GFLAGS), 374 + GATE(0, "pclk_dsp_grf", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, 375 + RV1108_CLKGATE_CON(16), 11, GFLAGS), 376 + GATE(0, "pclk_mailbox", "pclk_dsp_cfg", CLK_IGNORE_UNUSED, 377 + RV1108_CLKGATE_CON(16), 12, GFLAGS), 378 + GATE(0, "aclk_dsp_epp_perf", "sclk_dsp_epp", CLK_IGNORE_UNUSED, 379 + RV1108_CLKGATE_CON(16), 15, GFLAGS), 380 + GATE(0, "aclk_dsp_edp_perf", "sclk_dsp_edp", CLK_IGNORE_UNUSED, 381 + RV1108_CLKGATE_CON(11), 8, GFLAGS), 382 + 383 + /* 258 384 * Clock-Architecture Diagram 4 259 385 */ 260 - COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, 386 + COMPOSITE(0, "aclk_vio0_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, 261 387 RV1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS, 262 388 RV1108_CLKGATE_CON(6), 0, GFLAGS), 263 - GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED, 389 + GATE(ACLK_VIO0, "aclk_vio0", "aclk_vio0_pre", 0, 264 390 RV1108_CLKGATE_CON(17), 0, GFLAGS), 265 391 COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0, 266 392 RV1108_CLKSEL_CON(29), 0, 5, DFLAGS, 267 393 RV1108_CLKGATE_CON(7), 2, GFLAGS), 394 + GATE(HCLK_VIO, "hclk_vio", "hclk_vio_pre", 0, 395 + RV1108_CLKGATE_CON(17), 2, GFLAGS), 268 396 COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0, 269 397 RV1108_CLKSEL_CON(29), 8, 5, DFLAGS, 270 398 RV1108_CLKGATE_CON(7), 3, GFLAGS), 399 + GATE(PCLK_VIO, "pclk_vio", "pclk_vio_pre", 0, 400 + RV1108_CLKGATE_CON(17), 3, GFLAGS), 401 + COMPOSITE(0, "aclk_vio1_pre", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED, 402 + RV1108_CLKSEL_CON(28), 14, 2, MFLAGS, 8, 5, DFLAGS, 403 + RV1108_CLKGATE_CON(6), 1, GFLAGS), 404 + GATE(ACLK_VIO1, "aclk_vio1", "aclk_vio1_pre", 0, 405 + RV1108_CLKGATE_CON(17), 1, GFLAGS), 271 406 272 407 INVERTER(0, "pclk_vip", "ext_vip", 273 408 RV1108_CLKSEL_CON(31), 8, IFLAGS), ··· 441 252 RV1108_CLKGATE_CON(6), 5, GFLAGS), 442 253 GATE(0, "dclk_hdmiphy_src_dpll", "dpll", CLK_IGNORE_UNUSED, 443 254 RV1108_CLKGATE_CON(6), 4, GFLAGS), 444 - COMPOSITE_NOGATE(0, "dclk_hdmiphy", mux_dclk_hdmiphy_pre_p, 0, 445 - RV1108_CLKSEL_CON(32), 6, 2, MFLAGS, 8, 6, DFLAGS), 255 + COMPOSITE_NOGATE(0, "dclk_hdmiphy_pre", mux_dclk_hdmiphy_pre_p, 0, 256 + RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 8, 6, DFLAGS), 257 + COMPOSITE_NOGATE(DCLK_VOP_SRC, "dclk_vop_src", mux_dclk_hdmiphy_pre_p, 0, 258 + RV1108_CLKSEL_CON(32), 6, 1, MFLAGS, 0, 6, DFLAGS), 259 + MUX(DCLK_HDMIPHY, "dclk_hdmiphy", mux_dclk_hdmiphy_p, CLK_SET_RATE_PARENT, 260 + RV1108_CLKSEL_CON(32), 15, 1, MFLAGS), 261 + MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT, 262 + RV1108_CLKSEL_CON(32), 7, 1, MFLAGS), 263 + GATE(ACLK_VOP, "aclk_vop", "aclk_vio0_pre", 0, 264 + RV1108_CLKGATE_CON(18), 0, GFLAGS), 265 + GATE(HCLK_VOP, "hclk_vop", "hclk_vio_pre", 0, 266 + RV1108_CLKGATE_CON(18), 1, GFLAGS), 267 + GATE(ACLK_IEP, "aclk_iep", "aclk_vio0_pre", 0, 268 + RV1108_CLKGATE_CON(18), 2, GFLAGS), 269 + GATE(HCLK_IEP, "hclk_iep", "hclk_vio_pre", 0, 270 + RV1108_CLKGATE_CON(18), 3, GFLAGS), 271 + 272 + GATE(ACLK_RGA, "aclk_rga", "aclk_vio1_pre", 0, 273 + RV1108_CLKGATE_CON(18), 4, GFLAGS), 274 + GATE(HCLK_RGA, "hclk_rga", "hclk_vio_pre", 0, 275 + RV1108_CLKGATE_CON(18), 5, GFLAGS), 276 + COMPOSITE(SCLK_RGA, "sclk_rga", mux_pll_src_4plls_p, 0, 277 + RV1108_CLKSEL_CON(33), 6, 2, MFLAGS, 0, 5, DFLAGS, 278 + RV1108_CLKGATE_CON(6), 6, GFLAGS), 279 + 280 + COMPOSITE(SCLK_CVBS_HOST, "sclk_cvbs_host", mux_cvbs_src_p, 0, 281 + RV1108_CLKSEL_CON(33), 13, 2, MFLAGS, 8, 5, DFLAGS, 282 + RV1108_CLKGATE_CON(6), 7, GFLAGS), 283 + FACTOR(0, "sclk_cvbs_27m", "sclk_cvbs_host", 0, 1, 2), 284 + 285 + GATE(SCLK_HDMI_SFR, "sclk_hdmi_sfr", "xin24m", 0, 286 + RV1108_CLKGATE_CON(6), 8, GFLAGS), 287 + 288 + COMPOSITE(SCLK_HDMI_CEC, "sclk_hdmi_cec", mux_hdmi_cec_src_p, 0, 289 + RV1108_CLKSEL_CON(34), 14, 2, MFLAGS, 0, 14, DFLAGS, 290 + RV1108_CLKGATE_CON(6), 9, GFLAGS), 291 + GATE(PCLK_MIPI_DSI, "pclk_mipi_dsi", "pclk_vio_pre", 0, 292 + RV1108_CLKGATE_CON(18), 8, GFLAGS), 293 + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_vio_pre", 0, 294 + RV1108_CLKGATE_CON(18), 9, GFLAGS), 295 + 296 + GATE(ACLK_ISP, "aclk_isp", "aclk_vio1_pre", 0, 297 + RV1108_CLKGATE_CON(18), 12, GFLAGS), 298 + GATE(HCLK_ISP, "hclk_isp", "hclk_vio_pre", 0, 299 + RV1108_CLKGATE_CON(18), 11, GFLAGS), 300 + COMPOSITE(SCLK_ISP, "sclk_isp", mux_pll_src_4plls_p, 0, 301 + RV1108_CLKSEL_CON(30), 14, 2, MFLAGS, 8, 5, DFLAGS, 302 + RV1108_CLKGATE_CON(6), 3, GFLAGS), 303 + 304 + GATE(0, "clk_dsiphy24m", "xin24m", CLK_IGNORE_UNUSED, 305 + RV1108_CLKGATE_CON(9), 10, GFLAGS), 306 + GATE(0, "pclk_vdacphy", "pclk_top_pre", CLK_IGNORE_UNUSED, 307 + RV1108_CLKGATE_CON(14), 9, GFLAGS), 308 + GATE(0, "pclk_mipi_dsiphy", "pclk_top_pre", CLK_IGNORE_UNUSED, 309 + RV1108_CLKGATE_CON(14), 11, GFLAGS), 310 + GATE(0, "pclk_mipi_csiphy", "pclk_top_pre", CLK_IGNORE_UNUSED, 311 + RV1108_CLKGATE_CON(14), 12, GFLAGS), 446 312 447 313 /* 448 314 * Clock-Architecture Diagram 5 ··· 505 261 506 262 FACTOR(0, "xin12m", "xin24m", 0, 1, 2), 507 263 508 - COMPOSITE(0, "i2s0_src", mux_pll_src_2plls_p, 0, 264 + 265 + COMPOSITE(SCLK_I2S0_SRC, "i2s0_src", mux_pll_src_2plls_p, 0, 509 266 RV1108_CLKSEL_CON(5), 8, 1, MFLAGS, 0, 7, DFLAGS, 510 267 RV1108_CLKGATE_CON(2), 0, GFLAGS), 511 - COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, 268 + COMPOSITE_FRACMUX(0, "i2s0_frac", "i2s0_src", CLK_SET_RATE_PARENT, 512 269 RV1108_CLKSEL_CON(8), 0, 513 270 RV1108_CLKGATE_CON(2), 1, GFLAGS, 514 271 &rv1108_i2s0_fracmux), ··· 519 274 RV1108_CLKSEL_CON(5), 15, 1, MFLAGS, 520 275 RV1108_CLKGATE_CON(2), 3, GFLAGS), 521 276 522 - COMPOSITE(0, "i2s1_src", mux_pll_src_2plls_p, 0, 277 + COMPOSITE(SCLK_I2S1_SRC, "i2s1_src", mux_pll_src_2plls_p, 0, 523 278 RV1108_CLKSEL_CON(6), 8, 1, MFLAGS, 0, 7, DFLAGS, 524 279 RV1108_CLKGATE_CON(2), 4, GFLAGS), 525 280 COMPOSITE_FRACMUX(0, "i2s1_frac", "i2s1_src", CLK_SET_RATE_PARENT, ··· 529 284 GATE(SCLK_I2S1, "sclk_i2s1", "i2s1_pre", CLK_SET_RATE_PARENT, 530 285 RV1108_CLKGATE_CON(2), 6, GFLAGS), 531 286 532 - COMPOSITE(0, "i2s2_src", mux_pll_src_2plls_p, 0, 287 + COMPOSITE(SCLK_I2S2_SRC, "i2s2_src", mux_pll_src_2plls_p, 0, 533 288 RV1108_CLKSEL_CON(7), 8, 1, MFLAGS, 0, 7, DFLAGS, 534 289 RV1108_CLKGATE_CON(3), 8, GFLAGS), 535 290 COMPOSITE_FRACMUX(0, "i2s2_frac", "i2s2_src", CLK_SET_RATE_PARENT, ··· 548 303 RV1108_CLKGATE_CON(1), 2, GFLAGS), 549 304 COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0, 550 305 RV1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS), 551 - COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0, 306 + COMPOSITE_NOMUX(HCLK_BUS, "hclk_bus_pre", "aclk_bus_pre", 0, 552 307 RV1108_CLKSEL_CON(3), 0, 5, DFLAGS, 553 308 RV1108_CLKGATE_CON(1), 4, GFLAGS), 554 - COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0, 309 + COMPOSITE_NOMUX(0, "pclk_bus_pre", "aclk_bus_pre", 0, 555 310 RV1108_CLKSEL_CON(3), 8, 5, DFLAGS, 556 311 RV1108_CLKGATE_CON(1), 5, GFLAGS), 557 - GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED, 312 + GATE(PCLK_BUS, "pclk_bus", "pclk_bus_pre", 0, 558 313 RV1108_CLKGATE_CON(1), 6, GFLAGS), 559 - GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED, 314 + GATE(0, "pclk_top_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, 560 315 RV1108_CLKGATE_CON(1), 7, GFLAGS), 561 - GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED, 316 + GATE(0, "pclk_ddr_pre", "pclk_bus_pre", CLK_IGNORE_UNUSED, 562 317 RV1108_CLKGATE_CON(1), 8, GFLAGS), 563 - GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED, 318 + GATE(SCLK_TIMER0, "clk_timer0", "xin24m", 0, 564 319 RV1108_CLKGATE_CON(1), 9, GFLAGS), 565 - GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED, 320 + GATE(SCLK_TIMER1, "clk_timer1", "xin24m", CLK_IGNORE_UNUSED, 566 321 RV1108_CLKGATE_CON(1), 10, GFLAGS), 567 - GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED, 322 + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED, 568 323 RV1108_CLKGATE_CON(13), 4, GFLAGS), 569 324 570 - COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 325 + GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_bus_pre", 0, 326 + RV1108_CLKGATE_CON(12), 7, GFLAGS), 327 + GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_bus_pre", 0, 328 + RV1108_CLKGATE_CON(12), 8, GFLAGS), 329 + GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_bus_pre", 0, 330 + RV1108_CLKGATE_CON(12), 9, GFLAGS), 331 + 332 + GATE(HCLK_CRYPTO_MST, "hclk_crypto_mst", "hclk_bus_pre", 0, 333 + RV1108_CLKGATE_CON(12), 10, GFLAGS), 334 + GATE(HCLK_CRYPTO_SLV, "hclk_crypto_slv", "hclk_bus_pre", 0, 335 + RV1108_CLKGATE_CON(12), 11, GFLAGS), 336 + COMPOSITE(SCLK_CRYPTO, "sclk_crypto", mux_pll_src_2plls_p, 0, 337 + RV1108_CLKSEL_CON(11), 7, 1, MFLAGS, 0, 5, DFLAGS, 338 + RV1108_CLKGATE_CON(2), 12, GFLAGS), 339 + 340 + COMPOSITE(SCLK_SPI, "sclk_spi", mux_pll_src_2plls_p, 0, 341 + RV1108_CLKSEL_CON(11), 15, 1, MFLAGS, 8, 5, DFLAGS, 342 + RV1108_CLKGATE_CON(3), 0, GFLAGS), 343 + GATE(PCLK_SPI, "pclk_spi", "pclk_bus_pre", 0, 344 + RV1108_CLKGATE_CON(13), 5, GFLAGS), 345 + 346 + COMPOSITE(SCLK_UART0_SRC, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 571 347 RV1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS, 572 348 RV1108_CLKGATE_CON(3), 1, GFLAGS), 573 - COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 349 + COMPOSITE(SCLK_UART1_SRC, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 574 350 RV1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS, 575 351 RV1108_CLKGATE_CON(3), 3, GFLAGS), 576 - COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 352 + COMPOSITE(SCLK_UART2_SRC, "uart2_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED, 577 353 RV1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS, 578 354 RV1108_CLKGATE_CON(3), 5, GFLAGS), 579 355 ··· 610 344 RV1108_CLKSEL_CON(18), 0, 611 345 RV1108_CLKGATE_CON(3), 6, GFLAGS, 612 346 &rv1108_uart2_fracmux), 613 - GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED, 347 + GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", 0, 614 348 RV1108_CLKGATE_CON(13), 10, GFLAGS), 615 - GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 349 + GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", 0, 616 350 RV1108_CLKGATE_CON(13), 11, GFLAGS), 617 - GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 351 + GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", 0, 618 352 RV1108_CLKGATE_CON(13), 12, GFLAGS), 619 353 620 - COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 621 - RV1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS, 354 + COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_2plls_p, 0, 355 + RV1108_CLKSEL_CON(19), 15, 1, MFLAGS, 8, 7, DFLAGS, 622 356 RV1108_CLKGATE_CON(3), 7, GFLAGS), 623 - COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 624 - RV1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS, 357 + COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_2plls_p, 0, 358 + RV1108_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 7, DFLAGS, 625 359 RV1108_CLKGATE_CON(3), 8, GFLAGS), 626 - COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 627 - RV1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS, 360 + COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_2plls_p, 0, 361 + RV1108_CLKSEL_CON(20), 15, 1, MFLAGS, 8, 7, DFLAGS, 628 362 RV1108_CLKGATE_CON(3), 9, GFLAGS), 629 - GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 363 + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_pre", 0, 630 364 RV1108_CLKGATE_CON(13), 0, GFLAGS), 631 - GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 365 + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_pre", 0, 632 366 RV1108_CLKGATE_CON(13), 1, GFLAGS), 633 - GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED, 367 + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_pre", 0, 634 368 RV1108_CLKGATE_CON(13), 2, GFLAGS), 635 - COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED, 369 + COMPOSITE(SCLK_PWM, "clk_pwm", mux_pll_src_2plls_p, 0, 636 370 RV1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS, 637 371 RV1108_CLKGATE_CON(3), 10, GFLAGS), 638 - GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 372 + GATE(PCLK_PWM, "pclk_pwm", "pclk_bus_pre", 0, 639 373 RV1108_CLKGATE_CON(13), 6, GFLAGS), 640 - GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED, 374 + GATE(PCLK_WDT, "pclk_wdt", "pclk_bus_pre", 0, 641 375 RV1108_CLKGATE_CON(13), 3, GFLAGS), 642 - GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED, 376 + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_pre", 0, 643 377 RV1108_CLKGATE_CON(13), 7, GFLAGS), 644 - GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED, 378 + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_pre", 0, 645 379 RV1108_CLKGATE_CON(13), 8, GFLAGS), 646 - GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED, 380 + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_pre", 0, 647 381 RV1108_CLKGATE_CON(13), 9, GFLAGS), 648 382 649 383 GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED, 650 384 RV1108_CLKGATE_CON(14), 0, GFLAGS), 385 + GATE(PCLK_EFUSE0, "pclk_efuse0", "pclk_bus_pre", 0, 386 + RV1108_CLKGATE_CON(12), 12, GFLAGS), 387 + GATE(PCLK_EFUSE1, "pclk_efuse1", "pclk_bus_pre", 0, 388 + RV1108_CLKGATE_CON(12), 13, GFLAGS), 389 + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_pre", 0, 390 + RV1108_CLKGATE_CON(13), 13, GFLAGS), 391 + COMPOSITE_NOMUX(SCLK_TSADC, "sclk_tsadc", "xin24m", 0, 392 + RV1108_CLKSEL_CON(21), 0, 10, DFLAGS, 393 + RV1108_CLKGATE_CON(3), 11, GFLAGS), 394 + GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_pre", 0, 395 + RV1108_CLKGATE_CON(13), 14, GFLAGS), 396 + COMPOSITE_NOMUX(SCLK_SARADC, "sclk_saradc", "xin24m", 0, 397 + RV1108_CLKSEL_CON(22), 0, 10, DFLAGS, 398 + RV1108_CLKGATE_CON(3), 12, GFLAGS), 651 399 652 400 GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0, 653 401 RV1108_CLKGATE_CON(12), 2, GFLAGS), ··· 677 397 RV1108_CLKGATE_CON(0), 9, GFLAGS), 678 398 GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED, 679 399 RV1108_CLKGATE_CON(0), 10, GFLAGS), 680 - COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED, 400 + COMPOSITE_NOGATE(0, "clk_ddrphy_src", mux_ddrphy_p, CLK_IGNORE_UNUSED, 681 401 RV1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, 682 - DFLAGS | CLK_DIVIDER_POWER_OF_TWO, 402 + DFLAGS | CLK_DIVIDER_POWER_OF_TWO), 403 + FACTOR(0, "clk_ddr", "clk_ddrphy_src", 0, 1, 2), 404 + GATE(0, "clk_ddrphy4x", "clk_ddr", CLK_IGNORE_UNUSED, 683 405 RV1108_CLKGATE_CON(10), 9, GFLAGS), 684 - GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED, 406 + GATE(0, "pclk_ddrupctl", "pclk_ddr_pre", CLK_IGNORE_UNUSED, 685 407 RV1108_CLKGATE_CON(12), 4, GFLAGS), 686 - GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED, 408 + GATE(0, "nclk_ddrupctl", "clk_ddr", CLK_IGNORE_UNUSED, 687 409 RV1108_CLKGATE_CON(12), 5, GFLAGS), 688 - GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED, 410 + GATE(0, "pclk_ddrmon", "pclk_ddr_pre", CLK_IGNORE_UNUSED, 689 411 RV1108_CLKGATE_CON(12), 6, GFLAGS), 690 412 GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED, 691 413 RV1108_CLKGATE_CON(0), 11, GFLAGS), 414 + GATE(0, "pclk_mschniu", "pclk_ddr_pre", CLK_IGNORE_UNUSED, 415 + RV1108_CLKGATE_CON(14), 2, GFLAGS), 416 + GATE(0, "pclk_ddrphy", "pclk_ddr_pre", CLK_IGNORE_UNUSED, 417 + RV1108_CLKGATE_CON(14), 4, GFLAGS), 692 418 693 419 /* 694 420 * Clock-Architecture Diagram 6 ··· 704 418 COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0, 705 419 RV1108_CLKSEL_CON(23), 10, 5, DFLAGS, 706 420 RV1108_CLKGATE_CON(4), 5, GFLAGS), 707 - GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED, 421 + GATE(PCLK_PERI, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED, 708 422 RV1108_CLKGATE_CON(15), 13, GFLAGS), 709 423 COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0, 710 424 RV1108_CLKSEL_CON(23), 5, 5, DFLAGS, 711 425 RV1108_CLKGATE_CON(4), 4, GFLAGS), 712 - GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED, 426 + GATE(HCLK_PERI, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED, 713 427 RV1108_CLKGATE_CON(15), 12, GFLAGS), 714 428 715 429 GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED, 716 430 RV1108_CLKGATE_CON(4), 1, GFLAGS), 717 431 GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED, 718 432 RV1108_CLKGATE_CON(4), 2, GFLAGS), 719 - COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED, 720 - RV1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS, 433 + COMPOSITE(ACLK_PERI, "aclk_periph", mux_aclk_peri_src_p, 0, 434 + RV1108_CLKSEL_CON(23), 15, 1, MFLAGS, 0, 5, DFLAGS, 721 435 RV1108_CLKGATE_CON(15), 11, GFLAGS), 722 436 723 - COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0, 437 + COMPOSITE(SCLK_SDMMC, "sclk_sdmmc", mux_mmc_src_p, 0, 724 438 RV1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS, 725 439 RV1108_CLKGATE_CON(5), 0, GFLAGS), 726 440 ··· 740 454 GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 2, GFLAGS), 741 455 742 456 COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0, 743 - RV1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS, 457 + RV1108_CLKSEL_CON(27), 14, 1, MFLAGS, 8, 5, DFLAGS, 744 458 RV1108_CLKGATE_CON(5), 3, GFLAGS), 745 459 GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 3, GFLAGS), 746 460 461 + GATE(HCLK_HOST0, "hclk_host0", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 6, GFLAGS), 462 + GATE(0, "hclk_host0_arb", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 7, GFLAGS), 463 + GATE(HCLK_OTG, "hclk_otg", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 8, GFLAGS), 464 + GATE(0, "hclk_otg_pmu", "hclk_periph", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(15), 9, GFLAGS), 465 + GATE(SCLK_USBPHY, "clk_usbphy", "xin24m", CLK_IGNORE_UNUSED, RV1108_CLKGATE_CON(5), 5, GFLAGS), 466 + 747 467 COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0, 748 - RV1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS, 468 + RV1108_CLKSEL_CON(27), 7, 1, MFLAGS, 0, 7, DFLAGS, 749 469 RV1108_CLKGATE_CON(5), 4, GFLAGS), 750 470 GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RV1108_CLKGATE_CON(15), 10, GFLAGS), 751 471 752 - COMPOSITE(0, "sclk_macphy_pre", mux_pll_src_apll_gpll_p, 0, 753 - RV1108_CLKSEL_CON(24), 12, 2, MFLAGS, 0, 5, DFLAGS, 472 + COMPOSITE(SCLK_MAC_PRE, "sclk_mac_pre", mux_pll_src_apll_gpll_p, 0, 473 + RV1108_CLKSEL_CON(24), 12, 1, MFLAGS, 0, 5, DFLAGS, 754 474 RV1108_CLKGATE_CON(4), 10, GFLAGS), 755 - MUX(0, "sclk_macphy", mux_sclk_macphy_p, CLK_SET_RATE_PARENT, 756 - RV1108_CLKSEL_CON(24), 8, 2, MFLAGS), 757 - GATE(0, "sclk_macphy_rx", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS), 758 - GATE(0, "sclk_mac_ref", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS), 759 - GATE(0, "sclk_mac_refout", "sclk_macphy", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS), 475 + MUX(SCLK_MAC, "sclk_mac", mux_sclk_mac_p, CLK_SET_RATE_PARENT, 476 + RV1108_CLKSEL_CON(24), 8, 1, MFLAGS), 477 + GATE(SCLK_MAC_RX, "sclk_mac_rx", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 8, GFLAGS), 478 + GATE(SCLK_MAC_REF, "sclk_mac_ref", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 6, GFLAGS), 479 + GATE(SCLK_MAC_REFOUT, "sclk_mac_refout", "sclk_mac", 0, RV1108_CLKGATE_CON(4), 7, GFLAGS), 480 + GATE(ACLK_GMAC, "aclk_gmac", "aclk_periph", 0, RV1108_CLKGATE_CON(15), 4, GFLAGS), 481 + GATE(PCLK_GMAC, "pclk_gmac", "pclk_periph", 0, RV1108_CLKGATE_CON(15), 5, GFLAGS), 760 482 761 483 MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "sclk_sdmmc", RV1108_SDMMC_CON0, 1), 762 484 MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RV1108_SDMMC_CON1, 1), ··· 778 484 779 485 static const char *const rv1108_critical_clocks[] __initconst = { 780 486 "aclk_core", 781 - "aclk_bus_src_gpll", 487 + "aclk_bus", 488 + "hclk_bus", 489 + "pclk_bus", 782 490 "aclk_periph", 783 491 "hclk_periph", 784 492 "pclk_periph", 493 + "nclk_ddrupctl", 494 + "pclk_ddrmon", 495 + "pclk_acodecphy", 496 + "pclk_pmu", 785 497 }; 786 498 787 499 static void __init rv1108_clk_init(struct device_node *np)
+36
drivers/clk/rockchip/clk.c
··· 29 29 #include <linux/mfd/syscon.h> 30 30 #include <linux/regmap.h> 31 31 #include <linux/reboot.h> 32 + #include <linux/rational.h> 32 33 #include "clk.h" 33 34 34 35 /** ··· 165 164 return notifier_from_errno(ret); 166 165 } 167 166 167 + /** 168 + * fractional divider must set that denominator is 20 times larger than 169 + * numerator to generate precise clock frequency. 170 + */ 171 + static void rockchip_fractional_approximation(struct clk_hw *hw, 172 + unsigned long rate, unsigned long *parent_rate, 173 + unsigned long *m, unsigned long *n) 174 + { 175 + struct clk_fractional_divider *fd = to_clk_fd(hw); 176 + unsigned long p_rate, p_parent_rate; 177 + struct clk_hw *p_parent; 178 + unsigned long scale; 179 + 180 + p_rate = clk_hw_get_rate(clk_hw_get_parent(hw)); 181 + if ((rate * 20 > p_rate) && (p_rate % rate != 0)) { 182 + p_parent = clk_hw_get_parent(clk_hw_get_parent(hw)); 183 + p_parent_rate = clk_hw_get_rate(p_parent); 184 + *parent_rate = p_parent_rate; 185 + } 186 + 187 + /* 188 + * Get rate closer to *parent_rate to guarantee there is no overflow 189 + * for m and n. In the result it will be the nearest rate left shifted 190 + * by (scale - fd->nwidth) bits. 191 + */ 192 + scale = fls_long(*parent_rate / rate - 1); 193 + if (scale > fd->nwidth) 194 + rate <<= scale - fd->nwidth; 195 + 196 + rational_best_approximation(rate, *parent_rate, 197 + GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0), 198 + m, n); 199 + } 200 + 168 201 static struct clk *rockchip_clk_register_frac_branch( 169 202 struct rockchip_clk_provider *ctx, const char *name, 170 203 const char *const *parent_names, u8 num_parents, ··· 245 210 div->nwidth = 16; 246 211 div->nmask = GENMASK(div->nwidth - 1, 0) << div->nshift; 247 212 div->lock = lock; 213 + div->approximation = rockchip_fractional_approximation; 248 214 div_ops = &clk_fractional_divider_ops; 249 215 250 216 clk = clk_register_composite(NULL, name, parent_names, num_parents,
+4 -4
drivers/clk/samsung/clk-exynos-audss.c
··· 180 180 } 181 181 clk_table[EXYNOS_MOUT_AUDSS] = clk_hw_register_mux(NULL, "mout_audss", 182 182 mout_audss_p, ARRAY_SIZE(mout_audss_p), 183 - CLK_SET_RATE_NO_REPARENT, 183 + CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT, 184 184 reg_base + ASS_CLK_SRC, 0, 1, 0, &lock); 185 185 186 186 cdclk = devm_clk_get(&pdev->dev, "cdclk"); ··· 195 195 reg_base + ASS_CLK_SRC, 2, 2, 0, &lock); 196 196 197 197 clk_table[EXYNOS_DOUT_SRP] = clk_hw_register_divider(NULL, "dout_srp", 198 - "mout_audss", 0, reg_base + ASS_CLK_DIV, 0, 4, 199 - 0, &lock); 198 + "mout_audss", CLK_SET_RATE_PARENT, 199 + reg_base + ASS_CLK_DIV, 0, 4, 0, &lock); 200 200 201 201 clk_table[EXYNOS_DOUT_AUD_BUS] = clk_hw_register_divider(NULL, 202 - "dout_aud_bus", "dout_srp", 0, 202 + "dout_aud_bus", "dout_srp", CLK_SET_RATE_PARENT, 203 203 reg_base + ASS_CLK_DIV, 4, 4, 0, &lock); 204 204 205 205 clk_table[EXYNOS_DOUT_I2S] = clk_hw_register_divider(NULL, "dout_i2s",
+15 -8
drivers/clk/samsung/clk-exynos5420.c
··· 537 537 538 538 MUX(CLK_MOUT_MX_MSPLL_CCORE, "mout_mx_mspll_ccore", 539 539 mout_mx_mspll_ccore_p, SRC_TOP7, 16, 2), 540 - MUX(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, 541 - SRC_TOP7, 20, 2), 540 + MUX_F(CLK_MOUT_MAU_EPLL, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, 541 + SRC_TOP7, 20, 2, CLK_SET_RATE_PARENT, 0), 542 542 MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), 543 543 MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), 544 544 ··· 547 547 MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), 548 548 MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), 549 549 550 - MUX(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, 551 - SRC_TOP9, 8, 1), 550 + MUX_F(CLK_MOUT_USER_MAU_EPLL, "mout_user_mau_epll", mout_group16_5800_p, 551 + SRC_TOP9, 8, 1, CLK_SET_RATE_PARENT, 0), 552 552 MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, 553 553 SRC_TOP9, 16, 1), 554 554 MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, ··· 590 590 GATE_BUS_TOP, 24, 0, 0), 591 591 GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", 592 592 GATE_BUS_TOP, 27, CLK_IS_CRITICAL, 0), 593 + GATE(CLK_MAU_EPLL, "mau_epll", "mout_user_mau_epll", 594 + SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), 593 595 }; 594 596 595 597 static const struct samsung_mux_clock exynos5420_mux_clks[] __initconst = { ··· 629 627 static const struct samsung_div_clock exynos5420_div_clks[] __initconst = { 630 628 DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore", 631 629 "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3), 630 + }; 631 + 632 + static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = { 633 + GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", 634 + SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0), 632 635 }; 633 636 634 637 static const struct samsung_mux_clock exynos5x_mux_clks[] __initconst = { ··· 713 706 MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), 714 707 MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), 715 708 MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), 716 - MUX(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), 709 + MUX_F(CLK_MOUT_EPLL, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1, 710 + CLK_SET_RATE_PARENT, 0), 717 711 MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), 718 712 MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), 719 713 ··· 1008 1000 1009 1001 GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", 1010 1002 SRC_MASK_TOP2, 24, CLK_IS_CRITICAL, 0), 1011 - 1012 - GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", 1013 - SRC_MASK_TOP7, 20, 0, 0), 1014 1003 1015 1004 /* sclk */ 1016 1005 GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", ··· 1445 1440 ARRAY_SIZE(exynos5420_mux_clks)); 1446 1441 samsung_clk_register_div(ctx, exynos5420_div_clks, 1447 1442 ARRAY_SIZE(exynos5420_div_clks)); 1443 + samsung_clk_register_gate(ctx, exynos5420_gate_clks, 1444 + ARRAY_SIZE(exynos5420_gate_clks)); 1448 1445 } else { 1449 1446 samsung_clk_register_fixed_factor( 1450 1447 ctx, exynos5800_fixed_factor_clks,
+18
drivers/clk/sunxi-ng/Kconfig
··· 11 11 default ARM64 && ARCH_SUNXI 12 12 depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST 13 13 14 + config SUN4I_A10_CCU 15 + bool "Support for the Allwinner A10/A20 CCU" 16 + select SUNXI_CCU_DIV 17 + select SUNXI_CCU_MULT 18 + select SUNXI_CCU_NK 19 + select SUNXI_CCU_NKM 20 + select SUNXI_CCU_NM 21 + select SUNXI_CCU_MP 22 + select SUNXI_CCU_PHASE 23 + default MACH_SUN4I 24 + default MACH_SUN7I 25 + depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST 26 + 14 27 config SUN5I_CCU 15 28 bool "Support for the Allwinner sun5i family CCM" 16 29 default MACH_SUN5I ··· 60 47 61 48 config SUN8I_DE2_CCU 62 49 bool "Support for the Allwinner SoCs DE2 CCU" 50 + 51 + config SUN8I_R40_CCU 52 + bool "Support for the Allwinner R40 CCU" 53 + default MACH_SUN8I 54 + depends on MACH_SUN8I || COMPILE_TEST 63 55 64 56 config SUN9I_A80_CCU 65 57 bool "Support for the Allwinner A80 CCU"
+2
drivers/clk/sunxi-ng/Makefile
··· 20 20 21 21 # SoC support 22 22 obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o 23 + obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o 23 24 obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o 24 25 obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o 25 26 obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o ··· 30 29 obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o 31 30 obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o 32 31 obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o 32 + obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o 33 33 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o 34 34 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o 35 35 obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
+1456
drivers/clk/sunxi-ng/ccu-sun4i-a10.c
··· 1 + /* 2 + * Copyright (c) 2017 Priit Laes <plaes@plaes.org>. 3 + * Copyright (c) 2017 Maxime Ripard. 4 + * Copyright (c) 2017 Jonathan Liu. 5 + * 6 + * This software is licensed under the terms of the GNU General Public 7 + * License version 2, as published by the Free Software Foundation, and 8 + * may be copied, distributed, and modified under those terms. 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_address.h> 18 + 19 + #include "ccu_common.h" 20 + #include "ccu_reset.h" 21 + 22 + #include "ccu_div.h" 23 + #include "ccu_gate.h" 24 + #include "ccu_mp.h" 25 + #include "ccu_mult.h" 26 + #include "ccu_nk.h" 27 + #include "ccu_nkm.h" 28 + #include "ccu_nkmp.h" 29 + #include "ccu_nm.h" 30 + #include "ccu_phase.h" 31 + 32 + #include "ccu-sun4i-a10.h" 33 + 34 + static struct ccu_nkmp pll_core_clk = { 35 + .enable = BIT(31), 36 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 37 + .k = _SUNXI_CCU_MULT(4, 2), 38 + .m = _SUNXI_CCU_DIV(0, 2), 39 + .p = _SUNXI_CCU_DIV(16, 2), 40 + .common = { 41 + .reg = 0x000, 42 + .hw.init = CLK_HW_INIT("pll-core", 43 + "hosc", 44 + &ccu_nkmp_ops, 45 + 0), 46 + }, 47 + }; 48 + 49 + /* 50 + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from 51 + * the base (2x, 4x and 8x), and one variable divider (the one true 52 + * pll audio). 53 + * 54 + * We don't have any need for the variable divider for now, so we just 55 + * hardcode it to match with the clock names. 56 + */ 57 + #define SUN4I_PLL_AUDIO_REG 0x008 58 + static struct ccu_nm pll_audio_base_clk = { 59 + .enable = BIT(31), 60 + .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0), 61 + .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0), 62 + .common = { 63 + .reg = 0x008, 64 + .hw.init = CLK_HW_INIT("pll-audio-base", 65 + "hosc", 66 + &ccu_nm_ops, 67 + 0), 68 + }, 69 + 70 + }; 71 + 72 + static struct ccu_mult pll_video0_clk = { 73 + .enable = BIT(31), 74 + .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127), 75 + .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14), 76 + 270000000, 297000000), 77 + .common = { 78 + .reg = 0x010, 79 + .features = (CCU_FEATURE_FRACTIONAL | 80 + CCU_FEATURE_ALL_PREDIV), 81 + .prediv = 8, 82 + .hw.init = CLK_HW_INIT("pll-video0", 83 + "hosc", 84 + &ccu_mult_ops, 85 + 0), 86 + }, 87 + }; 88 + 89 + static struct ccu_nkmp pll_ve_sun4i_clk = { 90 + .enable = BIT(31), 91 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 92 + .k = _SUNXI_CCU_MULT(4, 2), 93 + .m = _SUNXI_CCU_DIV(0, 2), 94 + .p = _SUNXI_CCU_DIV(16, 2), 95 + .common = { 96 + .reg = 0x018, 97 + .hw.init = CLK_HW_INIT("pll-ve", 98 + "hosc", 99 + &ccu_nkmp_ops, 100 + 0), 101 + }, 102 + }; 103 + 104 + static struct ccu_nk pll_ve_sun7i_clk = { 105 + .enable = BIT(31), 106 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 107 + .k = _SUNXI_CCU_MULT(4, 2), 108 + .common = { 109 + .reg = 0x018, 110 + .hw.init = CLK_HW_INIT("pll-ve", 111 + "hosc", 112 + &ccu_nk_ops, 113 + 0), 114 + }, 115 + }; 116 + 117 + static struct ccu_nk pll_ddr_base_clk = { 118 + .enable = BIT(31), 119 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 120 + .k = _SUNXI_CCU_MULT(4, 2), 121 + .common = { 122 + .reg = 0x020, 123 + .hw.init = CLK_HW_INIT("pll-ddr-base", 124 + "hosc", 125 + &ccu_nk_ops, 126 + 0), 127 + }, 128 + }; 129 + 130 + static SUNXI_CCU_M(pll_ddr_clk, "pll-ddr", "pll-ddr-base", 0x020, 0, 2, 131 + CLK_IS_CRITICAL); 132 + 133 + static struct ccu_div pll_ddr_other_clk = { 134 + .div = _SUNXI_CCU_DIV_FLAGS(16, 2, CLK_DIVIDER_POWER_OF_TWO), 135 + .common = { 136 + .reg = 0x020, 137 + .hw.init = CLK_HW_INIT("pll-ddr-other", "pll-ddr-base", 138 + &ccu_div_ops, 139 + 0), 140 + }, 141 + }; 142 + 143 + static struct ccu_nk pll_periph_base_clk = { 144 + .enable = BIT(31), 145 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 146 + .k = _SUNXI_CCU_MULT(4, 2), 147 + .common = { 148 + .reg = 0x028, 149 + .hw.init = CLK_HW_INIT("pll-periph-base", 150 + "hosc", 151 + &ccu_nk_ops, 152 + 0), 153 + }, 154 + }; 155 + 156 + static CLK_FIXED_FACTOR(pll_periph_clk, "pll-periph", "pll-periph-base", 157 + 2, 1, CLK_SET_RATE_PARENT); 158 + 159 + /* Not documented on A10 */ 160 + static struct ccu_div pll_periph_sata_clk = { 161 + .enable = BIT(14), 162 + .div = _SUNXI_CCU_DIV(0, 2), 163 + .fixed_post_div = 6, 164 + .common = { 165 + .reg = 0x028, 166 + .features = CCU_FEATURE_FIXED_POSTDIV, 167 + .hw.init = CLK_HW_INIT("pll-periph-sata", 168 + "pll-periph-base", 169 + &ccu_div_ops, 0), 170 + }, 171 + }; 172 + 173 + static struct ccu_mult pll_video1_clk = { 174 + .enable = BIT(31), 175 + .mult = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(0, 7, 0, 9, 127), 176 + .frac = _SUNXI_CCU_FRAC(BIT(15), BIT(14), 177 + 270000000, 297000000), 178 + .common = { 179 + .reg = 0x030, 180 + .features = (CCU_FEATURE_FRACTIONAL | 181 + CCU_FEATURE_ALL_PREDIV), 182 + .prediv = 8, 183 + .hw.init = CLK_HW_INIT("pll-video1", 184 + "hosc", 185 + &ccu_mult_ops, 186 + 0), 187 + }, 188 + }; 189 + 190 + /* Not present on A10 */ 191 + static struct ccu_nk pll_gpu_clk = { 192 + .enable = BIT(31), 193 + .n = _SUNXI_CCU_MULT_OFFSET(8, 5, 0), 194 + .k = _SUNXI_CCU_MULT(4, 2), 195 + .common = { 196 + .reg = 0x040, 197 + .hw.init = CLK_HW_INIT("pll-gpu", 198 + "hosc", 199 + &ccu_nk_ops, 200 + 0), 201 + }, 202 + }; 203 + 204 + static SUNXI_CCU_GATE(hosc_clk, "hosc", "osc24M", 0x050, BIT(0), 0); 205 + 206 + static const char *const cpu_parents[] = { "osc32k", "hosc", 207 + "pll-core", "pll-periph" }; 208 + static const struct ccu_mux_fixed_prediv cpu_predivs[] = { 209 + { .index = 3, .div = 3, }, 210 + }; 211 + 212 + #define SUN4I_AHB_REG 0x054 213 + static struct ccu_mux cpu_clk = { 214 + .mux = { 215 + .shift = 16, 216 + .width = 2, 217 + .fixed_predivs = cpu_predivs, 218 + .n_predivs = ARRAY_SIZE(cpu_predivs), 219 + }, 220 + .common = { 221 + .reg = 0x054, 222 + .features = CCU_FEATURE_FIXED_PREDIV, 223 + .hw.init = CLK_HW_INIT_PARENTS("cpu", 224 + cpu_parents, 225 + &ccu_mux_ops, 226 + CLK_IS_CRITICAL), 227 + } 228 + }; 229 + 230 + static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x054, 0, 2, 0); 231 + 232 + static struct ccu_div ahb_sun4i_clk = { 233 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 234 + .common = { 235 + .reg = 0x054, 236 + .hw.init = CLK_HW_INIT("ahb", "axi", &ccu_div_ops, 0), 237 + }, 238 + }; 239 + 240 + static const char *const ahb_sun7i_parents[] = { "axi", "pll-periph", 241 + "pll-periph" }; 242 + static const struct ccu_mux_fixed_prediv ahb_sun7i_predivs[] = { 243 + { .index = 1, .div = 2, }, 244 + { /* Sentinel */ }, 245 + }; 246 + static struct ccu_div ahb_sun7i_clk = { 247 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 248 + .mux = { 249 + .shift = 6, 250 + .width = 2, 251 + .fixed_predivs = ahb_sun7i_predivs, 252 + .n_predivs = ARRAY_SIZE(ahb_sun7i_predivs), 253 + }, 254 + 255 + .common = { 256 + .reg = 0x054, 257 + .hw.init = CLK_HW_INIT_PARENTS("ahb", 258 + ahb_sun7i_parents, 259 + &ccu_div_ops, 260 + 0), 261 + }, 262 + }; 263 + 264 + static struct clk_div_table apb0_div_table[] = { 265 + { .val = 0, .div = 2 }, 266 + { .val = 1, .div = 2 }, 267 + { .val = 2, .div = 4 }, 268 + { .val = 3, .div = 8 }, 269 + { /* Sentinel */ }, 270 + }; 271 + static SUNXI_CCU_DIV_TABLE(apb0_clk, "apb0", "ahb", 272 + 0x054, 8, 2, apb0_div_table, 0); 273 + 274 + static const char *const apb1_parents[] = { "hosc", "pll-periph", "osc32k" }; 275 + static SUNXI_CCU_MP_WITH_MUX(apb1_clk, "apb1", apb1_parents, 0x058, 276 + 0, 5, /* M */ 277 + 16, 2, /* P */ 278 + 24, 2, /* mux */ 279 + 0); 280 + 281 + /* Not present on A20 */ 282 + static SUNXI_CCU_GATE(axi_dram_clk, "axi-dram", "ahb", 283 + 0x05c, BIT(31), 0); 284 + 285 + static SUNXI_CCU_GATE(ahb_otg_clk, "ahb-otg", "ahb", 286 + 0x060, BIT(0), 0); 287 + static SUNXI_CCU_GATE(ahb_ehci0_clk, "ahb-ehci0", "ahb", 288 + 0x060, BIT(1), 0); 289 + static SUNXI_CCU_GATE(ahb_ohci0_clk, "ahb-ohci0", "ahb", 290 + 0x060, BIT(2), 0); 291 + static SUNXI_CCU_GATE(ahb_ehci1_clk, "ahb-ehci1", "ahb", 292 + 0x060, BIT(3), 0); 293 + static SUNXI_CCU_GATE(ahb_ohci1_clk, "ahb-ohci1", "ahb", 294 + 0x060, BIT(4), 0); 295 + static SUNXI_CCU_GATE(ahb_ss_clk, "ahb-ss", "ahb", 296 + 0x060, BIT(5), 0); 297 + static SUNXI_CCU_GATE(ahb_dma_clk, "ahb-dma", "ahb", 298 + 0x060, BIT(6), 0); 299 + static SUNXI_CCU_GATE(ahb_bist_clk, "ahb-bist", "ahb", 300 + 0x060, BIT(7), 0); 301 + static SUNXI_CCU_GATE(ahb_mmc0_clk, "ahb-mmc0", "ahb", 302 + 0x060, BIT(8), 0); 303 + static SUNXI_CCU_GATE(ahb_mmc1_clk, "ahb-mmc1", "ahb", 304 + 0x060, BIT(9), 0); 305 + static SUNXI_CCU_GATE(ahb_mmc2_clk, "ahb-mmc2", "ahb", 306 + 0x060, BIT(10), 0); 307 + static SUNXI_CCU_GATE(ahb_mmc3_clk, "ahb-mmc3", "ahb", 308 + 0x060, BIT(11), 0); 309 + static SUNXI_CCU_GATE(ahb_ms_clk, "ahb-ms", "ahb", 310 + 0x060, BIT(12), 0); 311 + static SUNXI_CCU_GATE(ahb_nand_clk, "ahb-nand", "ahb", 312 + 0x060, BIT(13), 0); 313 + static SUNXI_CCU_GATE(ahb_sdram_clk, "ahb-sdram", "ahb", 314 + 0x060, BIT(14), CLK_IS_CRITICAL); 315 + 316 + static SUNXI_CCU_GATE(ahb_ace_clk, "ahb-ace", "ahb", 317 + 0x060, BIT(16), 0); 318 + static SUNXI_CCU_GATE(ahb_emac_clk, "ahb-emac", "ahb", 319 + 0x060, BIT(17), 0); 320 + static SUNXI_CCU_GATE(ahb_ts_clk, "ahb-ts", "ahb", 321 + 0x060, BIT(18), 0); 322 + static SUNXI_CCU_GATE(ahb_spi0_clk, "ahb-spi0", "ahb", 323 + 0x060, BIT(20), 0); 324 + static SUNXI_CCU_GATE(ahb_spi1_clk, "ahb-spi1", "ahb", 325 + 0x060, BIT(21), 0); 326 + static SUNXI_CCU_GATE(ahb_spi2_clk, "ahb-spi2", "ahb", 327 + 0x060, BIT(22), 0); 328 + static SUNXI_CCU_GATE(ahb_spi3_clk, "ahb-spi3", "ahb", 329 + 0x060, BIT(23), 0); 330 + static SUNXI_CCU_GATE(ahb_pata_clk, "ahb-pata", "ahb", 331 + 0x060, BIT(24), 0); 332 + /* Not documented on A20 */ 333 + static SUNXI_CCU_GATE(ahb_sata_clk, "ahb-sata", "ahb", 334 + 0x060, BIT(25), 0); 335 + /* Not present on A20 */ 336 + static SUNXI_CCU_GATE(ahb_gps_clk, "ahb-gps", "ahb", 337 + 0x060, BIT(26), 0); 338 + /* Not present on A10 */ 339 + static SUNXI_CCU_GATE(ahb_hstimer_clk, "ahb-hstimer", "ahb", 340 + 0x060, BIT(28), 0); 341 + 342 + static SUNXI_CCU_GATE(ahb_ve_clk, "ahb-ve", "ahb", 343 + 0x064, BIT(0), 0); 344 + static SUNXI_CCU_GATE(ahb_tvd_clk, "ahb-tvd", "ahb", 345 + 0x064, BIT(1), 0); 346 + static SUNXI_CCU_GATE(ahb_tve0_clk, "ahb-tve0", "ahb", 347 + 0x064, BIT(2), 0); 348 + static SUNXI_CCU_GATE(ahb_tve1_clk, "ahb-tve1", "ahb", 349 + 0x064, BIT(3), 0); 350 + static SUNXI_CCU_GATE(ahb_lcd0_clk, "ahb-lcd0", "ahb", 351 + 0x064, BIT(4), 0); 352 + static SUNXI_CCU_GATE(ahb_lcd1_clk, "ahb-lcd1", "ahb", 353 + 0x064, BIT(5), 0); 354 + static SUNXI_CCU_GATE(ahb_csi0_clk, "ahb-csi0", "ahb", 355 + 0x064, BIT(8), 0); 356 + static SUNXI_CCU_GATE(ahb_csi1_clk, "ahb-csi1", "ahb", 357 + 0x064, BIT(9), 0); 358 + /* Not present on A10 */ 359 + static SUNXI_CCU_GATE(ahb_hdmi1_clk, "ahb-hdmi1", "ahb", 360 + 0x064, BIT(10), 0); 361 + static SUNXI_CCU_GATE(ahb_hdmi0_clk, "ahb-hdmi0", "ahb", 362 + 0x064, BIT(11), 0); 363 + static SUNXI_CCU_GATE(ahb_de_be0_clk, "ahb-de-be0", "ahb", 364 + 0x064, BIT(12), 0); 365 + static SUNXI_CCU_GATE(ahb_de_be1_clk, "ahb-de-be1", "ahb", 366 + 0x064, BIT(13), 0); 367 + static SUNXI_CCU_GATE(ahb_de_fe0_clk, "ahb-de-fe0", "ahb", 368 + 0x064, BIT(14), 0); 369 + static SUNXI_CCU_GATE(ahb_de_fe1_clk, "ahb-de-fe1", "ahb", 370 + 0x064, BIT(15), 0); 371 + /* Not present on A10 */ 372 + static SUNXI_CCU_GATE(ahb_gmac_clk, "ahb-gmac", "ahb", 373 + 0x064, BIT(17), 0); 374 + static SUNXI_CCU_GATE(ahb_mp_clk, "ahb-mp", "ahb", 375 + 0x064, BIT(18), 0); 376 + static SUNXI_CCU_GATE(ahb_gpu_clk, "ahb-gpu", "ahb", 377 + 0x064, BIT(20), 0); 378 + 379 + static SUNXI_CCU_GATE(apb0_codec_clk, "apb0-codec", "apb0", 380 + 0x068, BIT(0), 0); 381 + static SUNXI_CCU_GATE(apb0_spdif_clk, "apb0-spdif", "apb0", 382 + 0x068, BIT(1), 0); 383 + static SUNXI_CCU_GATE(apb0_ac97_clk, "apb0-ac97", "apb0", 384 + 0x068, BIT(2), 0); 385 + static SUNXI_CCU_GATE(apb0_i2s0_clk, "apb0-i2s0", "apb0", 386 + 0x068, BIT(3), 0); 387 + /* Not present on A10 */ 388 + static SUNXI_CCU_GATE(apb0_i2s1_clk, "apb0-i2s1", "apb0", 389 + 0x068, BIT(4), 0); 390 + static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", 391 + 0x068, BIT(5), 0); 392 + static SUNXI_CCU_GATE(apb0_ir0_clk, "apb0-ir0", "apb0", 393 + 0x068, BIT(6), 0); 394 + static SUNXI_CCU_GATE(apb0_ir1_clk, "apb0-ir1", "apb0", 395 + 0x068, BIT(7), 0); 396 + /* Not present on A10 */ 397 + static SUNXI_CCU_GATE(apb0_i2s2_clk, "apb0-i2s2", "apb0", 398 + 0x068, BIT(8), 0); 399 + static SUNXI_CCU_GATE(apb0_keypad_clk, "apb0-keypad", "apb0", 400 + 0x068, BIT(10), 0); 401 + 402 + static SUNXI_CCU_GATE(apb1_i2c0_clk, "apb1-i2c0", "apb1", 403 + 0x06c, BIT(0), 0); 404 + static SUNXI_CCU_GATE(apb1_i2c1_clk, "apb1-i2c1", "apb1", 405 + 0x06c, BIT(1), 0); 406 + static SUNXI_CCU_GATE(apb1_i2c2_clk, "apb1-i2c2", "apb1", 407 + 0x06c, BIT(2), 0); 408 + /* Not present on A10 */ 409 + static SUNXI_CCU_GATE(apb1_i2c3_clk, "apb1-i2c3", "apb1", 410 + 0x06c, BIT(3), 0); 411 + static SUNXI_CCU_GATE(apb1_can_clk, "apb1-can", "apb1", 412 + 0x06c, BIT(4), 0); 413 + static SUNXI_CCU_GATE(apb1_scr_clk, "apb1-scr", "apb1", 414 + 0x06c, BIT(5), 0); 415 + static SUNXI_CCU_GATE(apb1_ps20_clk, "apb1-ps20", "apb1", 416 + 0x06c, BIT(6), 0); 417 + static SUNXI_CCU_GATE(apb1_ps21_clk, "apb1-ps21", "apb1", 418 + 0x06c, BIT(7), 0); 419 + /* Not present on A10 */ 420 + static SUNXI_CCU_GATE(apb1_i2c4_clk, "apb1-i2c4", "apb1", 421 + 0x06c, BIT(15), 0); 422 + static SUNXI_CCU_GATE(apb1_uart0_clk, "apb1-uart0", "apb1", 423 + 0x06c, BIT(16), 0); 424 + static SUNXI_CCU_GATE(apb1_uart1_clk, "apb1-uart1", "apb1", 425 + 0x06c, BIT(17), 0); 426 + static SUNXI_CCU_GATE(apb1_uart2_clk, "apb1-uart2", "apb1", 427 + 0x06c, BIT(18), 0); 428 + static SUNXI_CCU_GATE(apb1_uart3_clk, "apb1-uart3", "apb1", 429 + 0x06c, BIT(19), 0); 430 + static SUNXI_CCU_GATE(apb1_uart4_clk, "apb1-uart4", "apb1", 431 + 0x06c, BIT(20), 0); 432 + static SUNXI_CCU_GATE(apb1_uart5_clk, "apb1-uart5", "apb1", 433 + 0x06c, BIT(21), 0); 434 + static SUNXI_CCU_GATE(apb1_uart6_clk, "apb1-uart6", "apb1", 435 + 0x06c, BIT(22), 0); 436 + static SUNXI_CCU_GATE(apb1_uart7_clk, "apb1-uart7", "apb1", 437 + 0x06c, BIT(23), 0); 438 + 439 + static const char *const mod0_default_parents[] = { "hosc", "pll-periph", 440 + "pll-ddr-other" }; 441 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, 442 + 0, 4, /* M */ 443 + 16, 2, /* P */ 444 + 24, 2, /* mux */ 445 + BIT(31), /* gate */ 446 + 0); 447 + 448 + /* Undocumented on A10 */ 449 + static SUNXI_CCU_MP_WITH_MUX_GATE(ms_clk, "ms", mod0_default_parents, 0x084, 450 + 0, 4, /* M */ 451 + 16, 2, /* P */ 452 + 24, 2, /* mux */ 453 + BIT(31), /* gate */ 454 + 0); 455 + 456 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, 457 + 0, 4, /* M */ 458 + 16, 2, /* P */ 459 + 24, 2, /* mux */ 460 + BIT(31), /* gate */ 461 + 0); 462 + 463 + /* MMC output and sample clocks are not present on A10 */ 464 + static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0", 465 + 0x088, 8, 3, 0); 466 + static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0", 467 + 0x088, 20, 3, 0); 468 + 469 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, 470 + 0, 4, /* M */ 471 + 16, 2, /* P */ 472 + 24, 2, /* mux */ 473 + BIT(31), /* gate */ 474 + 0); 475 + 476 + /* MMC output and sample clocks are not present on A10 */ 477 + static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1", 478 + 0x08c, 8, 3, 0); 479 + static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1", 480 + 0x08c, 20, 3, 0); 481 + 482 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, 483 + 0, 4, /* M */ 484 + 16, 2, /* P */ 485 + 24, 2, /* mux */ 486 + BIT(31), /* gate */ 487 + 0); 488 + 489 + /* MMC output and sample clocks are not present on A10 */ 490 + static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2", 491 + 0x090, 8, 3, 0); 492 + static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2", 493 + 0x090, 20, 3, 0); 494 + 495 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094, 496 + 0, 4, /* M */ 497 + 16, 2, /* P */ 498 + 24, 2, /* mux */ 499 + BIT(31), /* gate */ 500 + 0); 501 + 502 + /* MMC output and sample clocks are not present on A10 */ 503 + static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3", 504 + 0x094, 8, 3, 0); 505 + static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3", 506 + 0x094, 20, 3, 0); 507 + 508 + static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098, 509 + 0, 4, /* M */ 510 + 16, 2, /* P */ 511 + 24, 2, /* mux */ 512 + BIT(31), /* gate */ 513 + 0); 514 + 515 + static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c, 516 + 0, 4, /* M */ 517 + 16, 2, /* P */ 518 + 24, 2, /* mux */ 519 + BIT(31), /* gate */ 520 + 0); 521 + 522 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, 523 + 0, 4, /* M */ 524 + 16, 2, /* P */ 525 + 24, 2, /* mux */ 526 + BIT(31), /* gate */ 527 + 0); 528 + 529 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, 530 + 0, 4, /* M */ 531 + 16, 2, /* P */ 532 + 24, 2, /* mux */ 533 + BIT(31), /* gate */ 534 + 0); 535 + 536 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, 537 + 0, 4, /* M */ 538 + 16, 2, /* P */ 539 + 24, 2, /* mux */ 540 + BIT(31), /* gate */ 541 + 0); 542 + 543 + /* Undocumented on A10 */ 544 + static SUNXI_CCU_MP_WITH_MUX_GATE(pata_clk, "pata", mod0_default_parents, 0x0ac, 545 + 0, 4, /* M */ 546 + 16, 2, /* P */ 547 + 24, 2, /* mux */ 548 + BIT(31), /* gate */ 549 + 0); 550 + 551 + /* TODO: Check whether A10 actually supports osc32k as 4th parent? */ 552 + static const char *const ir_parents_sun4i[] = { "hosc", "pll-periph", 553 + "pll-ddr-other" }; 554 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun4i_clk, "ir0", ir_parents_sun4i, 0x0b0, 555 + 0, 4, /* M */ 556 + 16, 2, /* P */ 557 + 24, 2, /* mux */ 558 + BIT(31), /* gate */ 559 + 0); 560 + 561 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun4i_clk, "ir1", ir_parents_sun4i, 0x0b4, 562 + 0, 4, /* M */ 563 + 16, 2, /* P */ 564 + 24, 2, /* mux */ 565 + BIT(31), /* gate */ 566 + 0); 567 + static const char *const ir_parents_sun7i[] = { "hosc", "pll-periph", 568 + "pll-ddr-other", "osc32k" }; 569 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_sun7i_clk, "ir0", ir_parents_sun7i, 0x0b0, 570 + 0, 4, /* M */ 571 + 16, 2, /* P */ 572 + 24, 2, /* mux */ 573 + BIT(31), /* gate */ 574 + 0); 575 + 576 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_sun7i_clk, "ir1", ir_parents_sun7i, 0x0b4, 577 + 0, 4, /* M */ 578 + 16, 2, /* P */ 579 + 24, 2, /* mux */ 580 + BIT(31), /* gate */ 581 + 0); 582 + 583 + static const char *const audio_parents[] = { "pll-audio-8x", "pll-audio-4x", 584 + "pll-audio-2x", "pll-audio" }; 585 + static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", audio_parents, 586 + 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 587 + 588 + static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", audio_parents, 589 + 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 590 + 591 + /* Undocumented on A10 */ 592 + static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", audio_parents, 593 + 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 594 + 595 + static const char *const keypad_parents[] = { "hosc", "losc"}; 596 + static const u8 keypad_table[] = { 0, 2 }; 597 + static struct ccu_mp keypad_clk = { 598 + .enable = BIT(31), 599 + .m = _SUNXI_CCU_DIV(0, 5), 600 + .p = _SUNXI_CCU_DIV(16, 2), 601 + .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table), 602 + .common = { 603 + .reg = 0x0c4, 604 + .hw.init = CLK_HW_INIT_PARENTS("keypad", 605 + keypad_parents, 606 + &ccu_mp_ops, 607 + 0), 608 + }, 609 + }; 610 + 611 + /* 612 + * SATA supports external clock as parent via BIT(24) and is probably an 613 + * optional crystal or oscillator that can be connected to the 614 + * SATA-CLKM / SATA-CLKP pins. 615 + */ 616 + static const char *const sata_parents[] = {"pll-periph-sata", "sata-ext"}; 617 + static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents, 618 + 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT); 619 + 620 + 621 + static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "pll-periph", 622 + 0x0cc, BIT(6), 0); 623 + static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "pll-periph", 624 + 0x0cc, BIT(7), 0); 625 + static SUNXI_CCU_GATE(usb_phy_clk, "usb-phy", "pll-periph", 626 + 0x0cc, BIT(8), 0); 627 + 628 + /* TODO: GPS CLK 0x0d0 */ 629 + 630 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0d4, 631 + 0, 4, /* M */ 632 + 16, 2, /* P */ 633 + 24, 2, /* mux */ 634 + BIT(31), /* gate */ 635 + 0); 636 + 637 + /* Not present on A10 */ 638 + static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", audio_parents, 639 + 0x0d8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 640 + 641 + /* Not present on A10 */ 642 + static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", audio_parents, 643 + 0x0dc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 644 + 645 + static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr", 646 + 0x100, BIT(0), 0); 647 + static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "pll-ddr", 648 + 0x100, BIT(1), 0); 649 + static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "pll-ddr", 650 + 0x100, BIT(2), 0); 651 + static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "pll-ddr", 652 + 0x100, BIT(3), 0); 653 + static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "pll-ddr", 654 + 0x100, BIT(4), 0); 655 + static SUNXI_CCU_GATE(dram_tve0_clk, "dram-tve0", "pll-ddr", 656 + 0x100, BIT(5), 0); 657 + static SUNXI_CCU_GATE(dram_tve1_clk, "dram-tve1", "pll-ddr", 658 + 0x100, BIT(6), 0); 659 + 660 + /* Clock seems to be critical only on sun4i */ 661 + static SUNXI_CCU_GATE(dram_out_clk, "dram-out", "pll-ddr", 662 + 0x100, BIT(15), CLK_IS_CRITICAL); 663 + static SUNXI_CCU_GATE(dram_de_fe1_clk, "dram-de-fe1", "pll-ddr", 664 + 0x100, BIT(24), 0); 665 + static SUNXI_CCU_GATE(dram_de_fe0_clk, "dram-de-fe0", "pll-ddr", 666 + 0x100, BIT(25), 0); 667 + static SUNXI_CCU_GATE(dram_de_be0_clk, "dram-de-be0", "pll-ddr", 668 + 0x100, BIT(26), 0); 669 + static SUNXI_CCU_GATE(dram_de_be1_clk, "dram-de-be1", "pll-ddr", 670 + 0x100, BIT(27), 0); 671 + static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "pll-ddr", 672 + 0x100, BIT(28), 0); 673 + static SUNXI_CCU_GATE(dram_ace_clk, "dram-ace", "pll-ddr", 674 + 0x100, BIT(29), 0); 675 + 676 + static const char *const de_parents[] = { "pll-video0", "pll-video1", 677 + "pll-ddr-other" }; 678 + static SUNXI_CCU_M_WITH_MUX_GATE(de_be0_clk, "de-be0", de_parents, 679 + 0x104, 0, 4, 24, 2, BIT(31), 0); 680 + 681 + static SUNXI_CCU_M_WITH_MUX_GATE(de_be1_clk, "de-be1", de_parents, 682 + 0x108, 0, 4, 24, 2, BIT(31), 0); 683 + 684 + static SUNXI_CCU_M_WITH_MUX_GATE(de_fe0_clk, "de-fe0", de_parents, 685 + 0x10c, 0, 4, 24, 2, BIT(31), 0); 686 + 687 + static SUNXI_CCU_M_WITH_MUX_GATE(de_fe1_clk, "de-fe1", de_parents, 688 + 0x110, 0, 4, 24, 2, BIT(31), 0); 689 + 690 + /* Undocumented on A10 */ 691 + static SUNXI_CCU_M_WITH_MUX_GATE(de_mp_clk, "de-mp", de_parents, 692 + 0x114, 0, 4, 24, 2, BIT(31), 0); 693 + 694 + static const char *const disp_parents[] = { "pll-video0", "pll-video1", 695 + "pll-video0-2x", "pll-video1-2x" }; 696 + static SUNXI_CCU_MUX_WITH_GATE(tcon0_ch0_clk, "tcon0-ch0-sclk", disp_parents, 697 + 0x118, 24, 2, BIT(31), CLK_SET_RATE_PARENT); 698 + static SUNXI_CCU_MUX_WITH_GATE(tcon1_ch0_clk, "tcon1-ch0-sclk", disp_parents, 699 + 0x11c, 24, 2, BIT(31), CLK_SET_RATE_PARENT); 700 + 701 + static const char *const csi_sclk_parents[] = { "pll-video0", "pll-ve", 702 + "pll-ddr-other", "pll-periph" }; 703 + 704 + static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", 705 + csi_sclk_parents, 706 + 0x120, 0, 4, 24, 2, BIT(31), 0); 707 + 708 + /* TVD clock setup for A10 */ 709 + static const char *const tvd_parents[] = { "pll-video0", "pll-video1" }; 710 + static SUNXI_CCU_MUX_WITH_GATE(tvd_sun4i_clk, "tvd", tvd_parents, 711 + 0x128, 24, 1, BIT(31), 0); 712 + 713 + /* TVD clock setup for A20 */ 714 + static SUNXI_CCU_MP_WITH_MUX_GATE(tvd_sclk2_sun7i_clk, 715 + "tvd-sclk2", tvd_parents, 716 + 0x128, 717 + 0, 4, /* M */ 718 + 16, 4, /* P */ 719 + 8, 1, /* mux */ 720 + BIT(15), /* gate */ 721 + 0); 722 + 723 + static SUNXI_CCU_M_WITH_GATE(tvd_sclk1_sun7i_clk, "tvd-sclk1", "tvd-sclk2", 724 + 0x128, 0, 4, BIT(31), 0); 725 + 726 + static SUNXI_CCU_M_WITH_MUX_GATE(tcon0_ch1_sclk2_clk, "tcon0-ch1-sclk2", 727 + disp_parents, 728 + 0x12c, 0, 4, 24, 2, BIT(31), 729 + CLK_SET_RATE_PARENT); 730 + 731 + static SUNXI_CCU_M_WITH_GATE(tcon0_ch1_clk, 732 + "tcon0-ch1-sclk1", "tcon0-ch1-sclk2", 733 + 0x12c, 11, 1, BIT(15), 734 + CLK_SET_RATE_PARENT); 735 + 736 + static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_ch1_sclk2_clk, "tcon1-ch1-sclk2", 737 + disp_parents, 738 + 0x130, 0, 4, 24, 2, BIT(31), 739 + CLK_SET_RATE_PARENT); 740 + 741 + static SUNXI_CCU_M_WITH_GATE(tcon1_ch1_clk, 742 + "tcon1-ch1-sclk1", "tcon1-ch1-sclk2", 743 + 0x130, 11, 1, BIT(15), 744 + CLK_SET_RATE_PARENT); 745 + 746 + static const char *const csi_parents[] = { "hosc", "pll-video0", "pll-video1", 747 + "pll-video0-2x", "pll-video1-2x"}; 748 + static const u8 csi_table[] = { 0, 1, 2, 5, 6}; 749 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi0_clk, "csi0", 750 + csi_parents, csi_table, 751 + 0x134, 0, 5, 24, 3, BIT(31), 0); 752 + 753 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi1_clk, "csi1", 754 + csi_parents, csi_table, 755 + 0x138, 0, 5, 24, 3, BIT(31), 0); 756 + 757 + static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 0x13c, 16, 8, BIT(31), 0); 758 + 759 + static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", 760 + 0x140, BIT(31), CLK_SET_RATE_PARENT); 761 + 762 + static SUNXI_CCU_GATE(avs_clk, "avs", "hosc", 0x144, BIT(31), 0); 763 + 764 + static const char *const ace_parents[] = { "pll-ve", "pll-ddr-other" }; 765 + static SUNXI_CCU_M_WITH_MUX_GATE(ace_clk, "ace", ace_parents, 766 + 0x148, 0, 4, 24, 1, BIT(31), 0); 767 + 768 + static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", disp_parents, 769 + 0x150, 0, 4, 24, 2, BIT(31), 770 + CLK_SET_RATE_PARENT); 771 + 772 + static const char *const gpu_parents_sun4i[] = { "pll-video0", "pll-ve", 773 + "pll-ddr-other", 774 + "pll-video1" }; 775 + static SUNXI_CCU_M_WITH_MUX_GATE(gpu_sun4i_clk, "gpu", gpu_parents_sun4i, 776 + 0x154, 0, 4, 24, 2, BIT(31), 777 + CLK_SET_RATE_PARENT); 778 + 779 + static const char *const gpu_parents_sun7i[] = { "pll-video0", "pll-ve", 780 + "pll-ddr-other", "pll-video1", 781 + "pll-gpu" }; 782 + static const u8 gpu_table_sun7i[] = { 0, 1, 2, 3, 4 }; 783 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(gpu_sun7i_clk, "gpu", 784 + gpu_parents_sun7i, gpu_table_sun7i, 785 + 0x154, 0, 4, 24, 3, BIT(31), 786 + CLK_SET_RATE_PARENT); 787 + 788 + static const char *const mbus_sun4i_parents[] = { "hosc", "pll-periph", 789 + "pll-ddr-other" }; 790 + static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun4i_clk, "mbus", mbus_sun4i_parents, 791 + 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), 792 + 0); 793 + static const char *const mbus_sun7i_parents[] = { "hosc", "pll-periph-base", 794 + "pll-ddr-other" }; 795 + static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_sun7i_clk, "mbus", mbus_sun7i_parents, 796 + 0x15c, 0, 4, 16, 2, 24, 2, BIT(31), 797 + CLK_IS_CRITICAL); 798 + 799 + static SUNXI_CCU_GATE(hdmi1_slow_clk, "hdmi1-slow", "hosc", 0x178, BIT(31), 0); 800 + 801 + static const char *const hdmi1_parents[] = { "pll-video0", "pll-video1" }; 802 + static const u8 hdmi1_table[] = { 0, 1}; 803 + static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(hdmi1_clk, "hdmi1", 804 + hdmi1_parents, hdmi1_table, 805 + 0x17c, 0, 4, 24, 2, BIT(31), 806 + CLK_SET_RATE_PARENT); 807 + 808 + static const char *const out_parents[] = { "hosc", "osc32k", "hosc" }; 809 + static const struct ccu_mux_fixed_prediv clk_out_predivs[] = { 810 + { .index = 0, .div = 750, }, 811 + }; 812 + 813 + static struct ccu_mp out_a_clk = { 814 + .enable = BIT(31), 815 + .m = _SUNXI_CCU_DIV(8, 5), 816 + .p = _SUNXI_CCU_DIV(20, 2), 817 + .mux = { 818 + .shift = 24, 819 + .width = 2, 820 + .fixed_predivs = clk_out_predivs, 821 + .n_predivs = ARRAY_SIZE(clk_out_predivs), 822 + }, 823 + .common = { 824 + .reg = 0x1f0, 825 + .features = CCU_FEATURE_FIXED_PREDIV, 826 + .hw.init = CLK_HW_INIT_PARENTS("out-a", 827 + out_parents, 828 + &ccu_mp_ops, 829 + 0), 830 + }, 831 + }; 832 + static struct ccu_mp out_b_clk = { 833 + .enable = BIT(31), 834 + .m = _SUNXI_CCU_DIV(8, 5), 835 + .p = _SUNXI_CCU_DIV(20, 2), 836 + .mux = { 837 + .shift = 24, 838 + .width = 2, 839 + .fixed_predivs = clk_out_predivs, 840 + .n_predivs = ARRAY_SIZE(clk_out_predivs), 841 + }, 842 + .common = { 843 + .reg = 0x1f4, 844 + .features = CCU_FEATURE_FIXED_PREDIV, 845 + .hw.init = CLK_HW_INIT_PARENTS("out-b", 846 + out_parents, 847 + &ccu_mp_ops, 848 + 0), 849 + }, 850 + }; 851 + 852 + static struct ccu_common *sun4i_sun7i_ccu_clks[] = { 853 + &hosc_clk.common, 854 + &pll_core_clk.common, 855 + &pll_audio_base_clk.common, 856 + &pll_video0_clk.common, 857 + &pll_ve_sun4i_clk.common, 858 + &pll_ve_sun7i_clk.common, 859 + &pll_ddr_base_clk.common, 860 + &pll_ddr_clk.common, 861 + &pll_ddr_other_clk.common, 862 + &pll_periph_base_clk.common, 863 + &pll_periph_sata_clk.common, 864 + &pll_video1_clk.common, 865 + &pll_gpu_clk.common, 866 + &cpu_clk.common, 867 + &axi_clk.common, 868 + &axi_dram_clk.common, 869 + &ahb_sun4i_clk.common, 870 + &ahb_sun7i_clk.common, 871 + &apb0_clk.common, 872 + &apb1_clk.common, 873 + &ahb_otg_clk.common, 874 + &ahb_ehci0_clk.common, 875 + &ahb_ohci0_clk.common, 876 + &ahb_ehci1_clk.common, 877 + &ahb_ohci1_clk.common, 878 + &ahb_ss_clk.common, 879 + &ahb_dma_clk.common, 880 + &ahb_bist_clk.common, 881 + &ahb_mmc0_clk.common, 882 + &ahb_mmc1_clk.common, 883 + &ahb_mmc2_clk.common, 884 + &ahb_mmc3_clk.common, 885 + &ahb_ms_clk.common, 886 + &ahb_nand_clk.common, 887 + &ahb_sdram_clk.common, 888 + &ahb_ace_clk.common, 889 + &ahb_emac_clk.common, 890 + &ahb_ts_clk.common, 891 + &ahb_spi0_clk.common, 892 + &ahb_spi1_clk.common, 893 + &ahb_spi2_clk.common, 894 + &ahb_spi3_clk.common, 895 + &ahb_pata_clk.common, 896 + &ahb_sata_clk.common, 897 + &ahb_gps_clk.common, 898 + &ahb_hstimer_clk.common, 899 + &ahb_ve_clk.common, 900 + &ahb_tvd_clk.common, 901 + &ahb_tve0_clk.common, 902 + &ahb_tve1_clk.common, 903 + &ahb_lcd0_clk.common, 904 + &ahb_lcd1_clk.common, 905 + &ahb_csi0_clk.common, 906 + &ahb_csi1_clk.common, 907 + &ahb_hdmi1_clk.common, 908 + &ahb_hdmi0_clk.common, 909 + &ahb_de_be0_clk.common, 910 + &ahb_de_be1_clk.common, 911 + &ahb_de_fe0_clk.common, 912 + &ahb_de_fe1_clk.common, 913 + &ahb_gmac_clk.common, 914 + &ahb_mp_clk.common, 915 + &ahb_gpu_clk.common, 916 + &apb0_codec_clk.common, 917 + &apb0_spdif_clk.common, 918 + &apb0_ac97_clk.common, 919 + &apb0_i2s0_clk.common, 920 + &apb0_i2s1_clk.common, 921 + &apb0_pio_clk.common, 922 + &apb0_ir0_clk.common, 923 + &apb0_ir1_clk.common, 924 + &apb0_i2s2_clk.common, 925 + &apb0_keypad_clk.common, 926 + &apb1_i2c0_clk.common, 927 + &apb1_i2c1_clk.common, 928 + &apb1_i2c2_clk.common, 929 + &apb1_i2c3_clk.common, 930 + &apb1_can_clk.common, 931 + &apb1_scr_clk.common, 932 + &apb1_ps20_clk.common, 933 + &apb1_ps21_clk.common, 934 + &apb1_i2c4_clk.common, 935 + &apb1_uart0_clk.common, 936 + &apb1_uart1_clk.common, 937 + &apb1_uart2_clk.common, 938 + &apb1_uart3_clk.common, 939 + &apb1_uart4_clk.common, 940 + &apb1_uart5_clk.common, 941 + &apb1_uart6_clk.common, 942 + &apb1_uart7_clk.common, 943 + &nand_clk.common, 944 + &ms_clk.common, 945 + &mmc0_clk.common, 946 + &mmc0_output_clk.common, 947 + &mmc0_sample_clk.common, 948 + &mmc1_clk.common, 949 + &mmc1_output_clk.common, 950 + &mmc1_sample_clk.common, 951 + &mmc2_clk.common, 952 + &mmc2_output_clk.common, 953 + &mmc2_sample_clk.common, 954 + &mmc3_clk.common, 955 + &mmc3_output_clk.common, 956 + &mmc3_sample_clk.common, 957 + &ts_clk.common, 958 + &ss_clk.common, 959 + &spi0_clk.common, 960 + &spi1_clk.common, 961 + &spi2_clk.common, 962 + &pata_clk.common, 963 + &ir0_sun4i_clk.common, 964 + &ir1_sun4i_clk.common, 965 + &ir0_sun7i_clk.common, 966 + &ir1_sun7i_clk.common, 967 + &i2s0_clk.common, 968 + &ac97_clk.common, 969 + &spdif_clk.common, 970 + &keypad_clk.common, 971 + &sata_clk.common, 972 + &usb_ohci0_clk.common, 973 + &usb_ohci1_clk.common, 974 + &usb_phy_clk.common, 975 + &spi3_clk.common, 976 + &i2s1_clk.common, 977 + &i2s2_clk.common, 978 + &dram_ve_clk.common, 979 + &dram_csi0_clk.common, 980 + &dram_csi1_clk.common, 981 + &dram_ts_clk.common, 982 + &dram_tvd_clk.common, 983 + &dram_tve0_clk.common, 984 + &dram_tve1_clk.common, 985 + &dram_out_clk.common, 986 + &dram_de_fe1_clk.common, 987 + &dram_de_fe0_clk.common, 988 + &dram_de_be0_clk.common, 989 + &dram_de_be1_clk.common, 990 + &dram_mp_clk.common, 991 + &dram_ace_clk.common, 992 + &de_be0_clk.common, 993 + &de_be1_clk.common, 994 + &de_fe0_clk.common, 995 + &de_fe1_clk.common, 996 + &de_mp_clk.common, 997 + &tcon0_ch0_clk.common, 998 + &tcon1_ch0_clk.common, 999 + &csi_sclk_clk.common, 1000 + &tvd_sun4i_clk.common, 1001 + &tvd_sclk1_sun7i_clk.common, 1002 + &tvd_sclk2_sun7i_clk.common, 1003 + &tcon0_ch1_sclk2_clk.common, 1004 + &tcon0_ch1_clk.common, 1005 + &tcon1_ch1_sclk2_clk.common, 1006 + &tcon1_ch1_clk.common, 1007 + &csi0_clk.common, 1008 + &csi1_clk.common, 1009 + &ve_clk.common, 1010 + &codec_clk.common, 1011 + &avs_clk.common, 1012 + &ace_clk.common, 1013 + &hdmi_clk.common, 1014 + &gpu_sun4i_clk.common, 1015 + &gpu_sun7i_clk.common, 1016 + &mbus_sun4i_clk.common, 1017 + &mbus_sun7i_clk.common, 1018 + &hdmi1_slow_clk.common, 1019 + &hdmi1_clk.common, 1020 + &out_a_clk.common, 1021 + &out_b_clk.common 1022 + }; 1023 + 1024 + /* Post-divider for pll-audio is hardcoded to 4 */ 1025 + static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 1026 + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 1027 + static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1028 + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 1029 + static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 1030 + "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 1031 + static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 1032 + "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); 1033 + static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", 1034 + "pll-video0", 1, 2, CLK_SET_RATE_PARENT); 1035 + static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", 1036 + "pll-video1", 1, 2, CLK_SET_RATE_PARENT); 1037 + 1038 + 1039 + static struct clk_hw_onecell_data sun4i_a10_hw_clks = { 1040 + .hws = { 1041 + [CLK_HOSC] = &hosc_clk.common.hw, 1042 + [CLK_PLL_CORE] = &pll_core_clk.common.hw, 1043 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 1044 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 1045 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 1046 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 1047 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 1048 + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, 1049 + [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, 1050 + [CLK_PLL_VE] = &pll_ve_sun4i_clk.common.hw, 1051 + [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw, 1052 + [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, 1053 + [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw, 1054 + [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw, 1055 + [CLK_PLL_PERIPH] = &pll_periph_clk.hw, 1056 + [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw, 1057 + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, 1058 + [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, 1059 + [CLK_CPU] = &cpu_clk.common.hw, 1060 + [CLK_AXI] = &axi_clk.common.hw, 1061 + [CLK_AXI_DRAM] = &axi_dram_clk.common.hw, 1062 + [CLK_AHB] = &ahb_sun4i_clk.common.hw, 1063 + [CLK_APB0] = &apb0_clk.common.hw, 1064 + [CLK_APB1] = &apb1_clk.common.hw, 1065 + [CLK_AHB_OTG] = &ahb_otg_clk.common.hw, 1066 + [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw, 1067 + [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw, 1068 + [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw, 1069 + [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw, 1070 + [CLK_AHB_SS] = &ahb_ss_clk.common.hw, 1071 + [CLK_AHB_DMA] = &ahb_dma_clk.common.hw, 1072 + [CLK_AHB_BIST] = &ahb_bist_clk.common.hw, 1073 + [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw, 1074 + [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw, 1075 + [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw, 1076 + [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw, 1077 + [CLK_AHB_MS] = &ahb_ms_clk.common.hw, 1078 + [CLK_AHB_NAND] = &ahb_nand_clk.common.hw, 1079 + [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw, 1080 + [CLK_AHB_ACE] = &ahb_ace_clk.common.hw, 1081 + [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw, 1082 + [CLK_AHB_TS] = &ahb_ts_clk.common.hw, 1083 + [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw, 1084 + [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw, 1085 + [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw, 1086 + [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw, 1087 + [CLK_AHB_PATA] = &ahb_pata_clk.common.hw, 1088 + [CLK_AHB_SATA] = &ahb_sata_clk.common.hw, 1089 + [CLK_AHB_GPS] = &ahb_gps_clk.common.hw, 1090 + [CLK_AHB_VE] = &ahb_ve_clk.common.hw, 1091 + [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw, 1092 + [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw, 1093 + [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw, 1094 + [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw, 1095 + [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw, 1096 + [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw, 1097 + [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw, 1098 + [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw, 1099 + [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw, 1100 + [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw, 1101 + [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw, 1102 + [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw, 1103 + [CLK_AHB_MP] = &ahb_mp_clk.common.hw, 1104 + [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw, 1105 + [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw, 1106 + [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw, 1107 + [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw, 1108 + [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw, 1109 + [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, 1110 + [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw, 1111 + [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw, 1112 + [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw, 1113 + [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw, 1114 + [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw, 1115 + [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw, 1116 + [CLK_APB1_CAN] = &apb1_can_clk.common.hw, 1117 + [CLK_APB1_SCR] = &apb1_scr_clk.common.hw, 1118 + [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw, 1119 + [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw, 1120 + [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw, 1121 + [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw, 1122 + [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw, 1123 + [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw, 1124 + [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw, 1125 + [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw, 1126 + [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw, 1127 + [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw, 1128 + [CLK_NAND] = &nand_clk.common.hw, 1129 + [CLK_MS] = &ms_clk.common.hw, 1130 + [CLK_MMC0] = &mmc0_clk.common.hw, 1131 + [CLK_MMC1] = &mmc1_clk.common.hw, 1132 + [CLK_MMC2] = &mmc2_clk.common.hw, 1133 + [CLK_MMC3] = &mmc3_clk.common.hw, 1134 + [CLK_TS] = &ts_clk.common.hw, 1135 + [CLK_SS] = &ss_clk.common.hw, 1136 + [CLK_SPI0] = &spi0_clk.common.hw, 1137 + [CLK_SPI1] = &spi1_clk.common.hw, 1138 + [CLK_SPI2] = &spi2_clk.common.hw, 1139 + [CLK_PATA] = &pata_clk.common.hw, 1140 + [CLK_IR0] = &ir0_sun4i_clk.common.hw, 1141 + [CLK_IR1] = &ir1_sun4i_clk.common.hw, 1142 + [CLK_I2S0] = &i2s0_clk.common.hw, 1143 + [CLK_AC97] = &ac97_clk.common.hw, 1144 + [CLK_SPDIF] = &spdif_clk.common.hw, 1145 + [CLK_KEYPAD] = &keypad_clk.common.hw, 1146 + [CLK_SATA] = &sata_clk.common.hw, 1147 + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 1148 + [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, 1149 + [CLK_USB_PHY] = &usb_phy_clk.common.hw, 1150 + /* CLK_GPS is unimplemented */ 1151 + [CLK_SPI3] = &spi3_clk.common.hw, 1152 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 1153 + [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, 1154 + [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, 1155 + [CLK_DRAM_TS] = &dram_ts_clk.common.hw, 1156 + [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, 1157 + [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw, 1158 + [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw, 1159 + [CLK_DRAM_OUT] = &dram_out_clk.common.hw, 1160 + [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw, 1161 + [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw, 1162 + [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw, 1163 + [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw, 1164 + [CLK_DRAM_MP] = &dram_mp_clk.common.hw, 1165 + [CLK_DRAM_ACE] = &dram_ace_clk.common.hw, 1166 + [CLK_DE_BE0] = &de_be0_clk.common.hw, 1167 + [CLK_DE_BE1] = &de_be1_clk.common.hw, 1168 + [CLK_DE_FE0] = &de_fe0_clk.common.hw, 1169 + [CLK_DE_FE1] = &de_fe1_clk.common.hw, 1170 + [CLK_DE_MP] = &de_mp_clk.common.hw, 1171 + [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw, 1172 + [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw, 1173 + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, 1174 + [CLK_TVD] = &tvd_sun4i_clk.common.hw, 1175 + [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw, 1176 + [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw, 1177 + [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw, 1178 + [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw, 1179 + [CLK_CSI0] = &csi0_clk.common.hw, 1180 + [CLK_CSI1] = &csi1_clk.common.hw, 1181 + [CLK_VE] = &ve_clk.common.hw, 1182 + [CLK_CODEC] = &codec_clk.common.hw, 1183 + [CLK_AVS] = &avs_clk.common.hw, 1184 + [CLK_ACE] = &ace_clk.common.hw, 1185 + [CLK_HDMI] = &hdmi_clk.common.hw, 1186 + [CLK_GPU] = &gpu_sun7i_clk.common.hw, 1187 + [CLK_MBUS] = &mbus_sun4i_clk.common.hw, 1188 + }, 1189 + .num = CLK_NUMBER_SUN4I, 1190 + }; 1191 + static struct clk_hw_onecell_data sun7i_a20_hw_clks = { 1192 + .hws = { 1193 + [CLK_HOSC] = &hosc_clk.common.hw, 1194 + [CLK_PLL_CORE] = &pll_core_clk.common.hw, 1195 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 1196 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 1197 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 1198 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 1199 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 1200 + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, 1201 + [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, 1202 + [CLK_PLL_VE] = &pll_ve_sun7i_clk.common.hw, 1203 + [CLK_PLL_DDR_BASE] = &pll_ddr_base_clk.common.hw, 1204 + [CLK_PLL_DDR] = &pll_ddr_clk.common.hw, 1205 + [CLK_PLL_DDR_OTHER] = &pll_ddr_other_clk.common.hw, 1206 + [CLK_PLL_PERIPH_BASE] = &pll_periph_base_clk.common.hw, 1207 + [CLK_PLL_PERIPH] = &pll_periph_clk.hw, 1208 + [CLK_PLL_PERIPH_SATA] = &pll_periph_sata_clk.common.hw, 1209 + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, 1210 + [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, 1211 + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 1212 + [CLK_CPU] = &cpu_clk.common.hw, 1213 + [CLK_AXI] = &axi_clk.common.hw, 1214 + [CLK_AHB] = &ahb_sun7i_clk.common.hw, 1215 + [CLK_APB0] = &apb0_clk.common.hw, 1216 + [CLK_APB1] = &apb1_clk.common.hw, 1217 + [CLK_AHB_OTG] = &ahb_otg_clk.common.hw, 1218 + [CLK_AHB_EHCI0] = &ahb_ehci0_clk.common.hw, 1219 + [CLK_AHB_OHCI0] = &ahb_ohci0_clk.common.hw, 1220 + [CLK_AHB_EHCI1] = &ahb_ehci1_clk.common.hw, 1221 + [CLK_AHB_OHCI1] = &ahb_ohci1_clk.common.hw, 1222 + [CLK_AHB_SS] = &ahb_ss_clk.common.hw, 1223 + [CLK_AHB_DMA] = &ahb_dma_clk.common.hw, 1224 + [CLK_AHB_BIST] = &ahb_bist_clk.common.hw, 1225 + [CLK_AHB_MMC0] = &ahb_mmc0_clk.common.hw, 1226 + [CLK_AHB_MMC1] = &ahb_mmc1_clk.common.hw, 1227 + [CLK_AHB_MMC2] = &ahb_mmc2_clk.common.hw, 1228 + [CLK_AHB_MMC3] = &ahb_mmc3_clk.common.hw, 1229 + [CLK_AHB_MS] = &ahb_ms_clk.common.hw, 1230 + [CLK_AHB_NAND] = &ahb_nand_clk.common.hw, 1231 + [CLK_AHB_SDRAM] = &ahb_sdram_clk.common.hw, 1232 + [CLK_AHB_ACE] = &ahb_ace_clk.common.hw, 1233 + [CLK_AHB_EMAC] = &ahb_emac_clk.common.hw, 1234 + [CLK_AHB_TS] = &ahb_ts_clk.common.hw, 1235 + [CLK_AHB_SPI0] = &ahb_spi0_clk.common.hw, 1236 + [CLK_AHB_SPI1] = &ahb_spi1_clk.common.hw, 1237 + [CLK_AHB_SPI2] = &ahb_spi2_clk.common.hw, 1238 + [CLK_AHB_SPI3] = &ahb_spi3_clk.common.hw, 1239 + [CLK_AHB_PATA] = &ahb_pata_clk.common.hw, 1240 + [CLK_AHB_SATA] = &ahb_sata_clk.common.hw, 1241 + [CLK_AHB_HSTIMER] = &ahb_hstimer_clk.common.hw, 1242 + [CLK_AHB_VE] = &ahb_ve_clk.common.hw, 1243 + [CLK_AHB_TVD] = &ahb_tvd_clk.common.hw, 1244 + [CLK_AHB_TVE0] = &ahb_tve0_clk.common.hw, 1245 + [CLK_AHB_TVE1] = &ahb_tve1_clk.common.hw, 1246 + [CLK_AHB_LCD0] = &ahb_lcd0_clk.common.hw, 1247 + [CLK_AHB_LCD1] = &ahb_lcd1_clk.common.hw, 1248 + [CLK_AHB_CSI0] = &ahb_csi0_clk.common.hw, 1249 + [CLK_AHB_CSI1] = &ahb_csi1_clk.common.hw, 1250 + [CLK_AHB_HDMI1] = &ahb_hdmi1_clk.common.hw, 1251 + [CLK_AHB_HDMI0] = &ahb_hdmi0_clk.common.hw, 1252 + [CLK_AHB_DE_BE0] = &ahb_de_be0_clk.common.hw, 1253 + [CLK_AHB_DE_BE1] = &ahb_de_be1_clk.common.hw, 1254 + [CLK_AHB_DE_FE0] = &ahb_de_fe0_clk.common.hw, 1255 + [CLK_AHB_DE_FE1] = &ahb_de_fe1_clk.common.hw, 1256 + [CLK_AHB_GMAC] = &ahb_gmac_clk.common.hw, 1257 + [CLK_AHB_MP] = &ahb_mp_clk.common.hw, 1258 + [CLK_AHB_GPU] = &ahb_gpu_clk.common.hw, 1259 + [CLK_APB0_CODEC] = &apb0_codec_clk.common.hw, 1260 + [CLK_APB0_SPDIF] = &apb0_spdif_clk.common.hw, 1261 + [CLK_APB0_AC97] = &apb0_ac97_clk.common.hw, 1262 + [CLK_APB0_I2S0] = &apb0_i2s0_clk.common.hw, 1263 + [CLK_APB0_I2S1] = &apb0_i2s1_clk.common.hw, 1264 + [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, 1265 + [CLK_APB0_IR0] = &apb0_ir0_clk.common.hw, 1266 + [CLK_APB0_IR1] = &apb0_ir1_clk.common.hw, 1267 + [CLK_APB0_I2S2] = &apb0_i2s2_clk.common.hw, 1268 + [CLK_APB0_KEYPAD] = &apb0_keypad_clk.common.hw, 1269 + [CLK_APB1_I2C0] = &apb1_i2c0_clk.common.hw, 1270 + [CLK_APB1_I2C1] = &apb1_i2c1_clk.common.hw, 1271 + [CLK_APB1_I2C2] = &apb1_i2c2_clk.common.hw, 1272 + [CLK_APB1_I2C3] = &apb1_i2c3_clk.common.hw, 1273 + [CLK_APB1_CAN] = &apb1_can_clk.common.hw, 1274 + [CLK_APB1_SCR] = &apb1_scr_clk.common.hw, 1275 + [CLK_APB1_PS20] = &apb1_ps20_clk.common.hw, 1276 + [CLK_APB1_PS21] = &apb1_ps21_clk.common.hw, 1277 + [CLK_APB1_I2C4] = &apb1_i2c4_clk.common.hw, 1278 + [CLK_APB1_UART0] = &apb1_uart0_clk.common.hw, 1279 + [CLK_APB1_UART1] = &apb1_uart1_clk.common.hw, 1280 + [CLK_APB1_UART2] = &apb1_uart2_clk.common.hw, 1281 + [CLK_APB1_UART3] = &apb1_uart3_clk.common.hw, 1282 + [CLK_APB1_UART4] = &apb1_uart4_clk.common.hw, 1283 + [CLK_APB1_UART5] = &apb1_uart5_clk.common.hw, 1284 + [CLK_APB1_UART6] = &apb1_uart6_clk.common.hw, 1285 + [CLK_APB1_UART7] = &apb1_uart7_clk.common.hw, 1286 + [CLK_NAND] = &nand_clk.common.hw, 1287 + [CLK_MS] = &ms_clk.common.hw, 1288 + [CLK_MMC0] = &mmc0_clk.common.hw, 1289 + [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw, 1290 + [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw, 1291 + [CLK_MMC1] = &mmc1_clk.common.hw, 1292 + [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw, 1293 + [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw, 1294 + [CLK_MMC2] = &mmc2_clk.common.hw, 1295 + [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw, 1296 + [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw, 1297 + [CLK_MMC3] = &mmc3_clk.common.hw, 1298 + [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw, 1299 + [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw, 1300 + [CLK_TS] = &ts_clk.common.hw, 1301 + [CLK_SS] = &ss_clk.common.hw, 1302 + [CLK_SPI0] = &spi0_clk.common.hw, 1303 + [CLK_SPI1] = &spi1_clk.common.hw, 1304 + [CLK_SPI2] = &spi2_clk.common.hw, 1305 + [CLK_PATA] = &pata_clk.common.hw, 1306 + [CLK_IR0] = &ir0_sun7i_clk.common.hw, 1307 + [CLK_IR1] = &ir1_sun7i_clk.common.hw, 1308 + [CLK_I2S0] = &i2s0_clk.common.hw, 1309 + [CLK_AC97] = &ac97_clk.common.hw, 1310 + [CLK_SPDIF] = &spdif_clk.common.hw, 1311 + [CLK_KEYPAD] = &keypad_clk.common.hw, 1312 + [CLK_SATA] = &sata_clk.common.hw, 1313 + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 1314 + [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, 1315 + [CLK_USB_PHY] = &usb_phy_clk.common.hw, 1316 + /* CLK_GPS is unimplemented */ 1317 + [CLK_SPI3] = &spi3_clk.common.hw, 1318 + [CLK_I2S1] = &i2s1_clk.common.hw, 1319 + [CLK_I2S2] = &i2s2_clk.common.hw, 1320 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 1321 + [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, 1322 + [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, 1323 + [CLK_DRAM_TS] = &dram_ts_clk.common.hw, 1324 + [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, 1325 + [CLK_DRAM_TVE0] = &dram_tve0_clk.common.hw, 1326 + [CLK_DRAM_TVE1] = &dram_tve1_clk.common.hw, 1327 + [CLK_DRAM_OUT] = &dram_out_clk.common.hw, 1328 + [CLK_DRAM_DE_FE1] = &dram_de_fe1_clk.common.hw, 1329 + [CLK_DRAM_DE_FE0] = &dram_de_fe0_clk.common.hw, 1330 + [CLK_DRAM_DE_BE0] = &dram_de_be0_clk.common.hw, 1331 + [CLK_DRAM_DE_BE1] = &dram_de_be1_clk.common.hw, 1332 + [CLK_DRAM_MP] = &dram_mp_clk.common.hw, 1333 + [CLK_DRAM_ACE] = &dram_ace_clk.common.hw, 1334 + [CLK_DE_BE0] = &de_be0_clk.common.hw, 1335 + [CLK_DE_BE1] = &de_be1_clk.common.hw, 1336 + [CLK_DE_FE0] = &de_fe0_clk.common.hw, 1337 + [CLK_DE_FE1] = &de_fe1_clk.common.hw, 1338 + [CLK_DE_MP] = &de_mp_clk.common.hw, 1339 + [CLK_TCON0_CH0] = &tcon0_ch0_clk.common.hw, 1340 + [CLK_TCON1_CH0] = &tcon1_ch0_clk.common.hw, 1341 + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, 1342 + [CLK_TVD_SCLK2] = &tvd_sclk2_sun7i_clk.common.hw, 1343 + [CLK_TVD] = &tvd_sclk1_sun7i_clk.common.hw, 1344 + [CLK_TCON0_CH1_SCLK2] = &tcon0_ch1_sclk2_clk.common.hw, 1345 + [CLK_TCON0_CH1] = &tcon0_ch1_clk.common.hw, 1346 + [CLK_TCON1_CH1_SCLK2] = &tcon1_ch1_sclk2_clk.common.hw, 1347 + [CLK_TCON1_CH1] = &tcon1_ch1_clk.common.hw, 1348 + [CLK_CSI0] = &csi0_clk.common.hw, 1349 + [CLK_CSI1] = &csi1_clk.common.hw, 1350 + [CLK_VE] = &ve_clk.common.hw, 1351 + [CLK_CODEC] = &codec_clk.common.hw, 1352 + [CLK_AVS] = &avs_clk.common.hw, 1353 + [CLK_ACE] = &ace_clk.common.hw, 1354 + [CLK_HDMI] = &hdmi_clk.common.hw, 1355 + [CLK_GPU] = &gpu_sun7i_clk.common.hw, 1356 + [CLK_MBUS] = &mbus_sun7i_clk.common.hw, 1357 + [CLK_HDMI1_SLOW] = &hdmi1_slow_clk.common.hw, 1358 + [CLK_HDMI1] = &hdmi1_clk.common.hw, 1359 + [CLK_OUT_A] = &out_a_clk.common.hw, 1360 + [CLK_OUT_B] = &out_b_clk.common.hw, 1361 + }, 1362 + .num = CLK_NUMBER_SUN7I, 1363 + }; 1364 + 1365 + static struct ccu_reset_map sunxi_a10_a20_ccu_resets[] = { 1366 + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, 1367 + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, 1368 + [RST_USB_PHY2] = { 0x0cc, BIT(2) }, 1369 + [RST_GPS] = { 0x0d0, BIT(0) }, 1370 + [RST_DE_BE0] = { 0x104, BIT(30) }, 1371 + [RST_DE_BE1] = { 0x108, BIT(30) }, 1372 + [RST_DE_FE0] = { 0x10c, BIT(30) }, 1373 + [RST_DE_FE1] = { 0x110, BIT(30) }, 1374 + [RST_DE_MP] = { 0x114, BIT(30) }, 1375 + [RST_TVE0] = { 0x118, BIT(29) }, 1376 + [RST_TCON0] = { 0x118, BIT(30) }, 1377 + [RST_TVE1] = { 0x11c, BIT(29) }, 1378 + [RST_TCON1] = { 0x11c, BIT(30) }, 1379 + [RST_CSI0] = { 0x134, BIT(30) }, 1380 + [RST_CSI1] = { 0x138, BIT(30) }, 1381 + [RST_VE] = { 0x13c, BIT(0) }, 1382 + [RST_ACE] = { 0x148, BIT(16) }, 1383 + [RST_LVDS] = { 0x14c, BIT(0) }, 1384 + [RST_GPU] = { 0x154, BIT(30) }, 1385 + [RST_HDMI_H] = { 0x170, BIT(0) }, 1386 + [RST_HDMI_SYS] = { 0x170, BIT(1) }, 1387 + [RST_HDMI_AUDIO_DMA] = { 0x170, BIT(2) }, 1388 + }; 1389 + 1390 + static const struct sunxi_ccu_desc sun4i_a10_ccu_desc = { 1391 + .ccu_clks = sun4i_sun7i_ccu_clks, 1392 + .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks), 1393 + 1394 + .hw_clks = &sun4i_a10_hw_clks, 1395 + 1396 + .resets = sunxi_a10_a20_ccu_resets, 1397 + .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets), 1398 + }; 1399 + 1400 + static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = { 1401 + .ccu_clks = sun4i_sun7i_ccu_clks, 1402 + .num_ccu_clks = ARRAY_SIZE(sun4i_sun7i_ccu_clks), 1403 + 1404 + .hw_clks = &sun7i_a20_hw_clks, 1405 + 1406 + .resets = sunxi_a10_a20_ccu_resets, 1407 + .num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets), 1408 + }; 1409 + 1410 + static void __init sun4i_ccu_init(struct device_node *node, 1411 + const struct sunxi_ccu_desc *desc) 1412 + { 1413 + void __iomem *reg; 1414 + u32 val; 1415 + 1416 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1417 + if (IS_ERR(reg)) { 1418 + pr_err("%s: Could not map the clock registers\n", 1419 + of_node_full_name(node)); 1420 + return; 1421 + } 1422 + 1423 + /* Force the PLL-Audio-1x divider to 4 */ 1424 + val = readl(reg + SUN4I_PLL_AUDIO_REG); 1425 + val &= ~GENMASK(29, 26); 1426 + writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG); 1427 + 1428 + /* 1429 + * Use the peripheral PLL6 as the AHB parent, instead of CPU / 1430 + * AXI which have rate changes due to cpufreq. 1431 + * 1432 + * This is especially a big deal for the HS timer whose parent 1433 + * clock is AHB. 1434 + * 1435 + * NB! These bits are undocumented in A10 manual. 1436 + */ 1437 + val = readl(reg + SUN4I_AHB_REG); 1438 + val &= ~GENMASK(7, 6); 1439 + writel(val | (2 << 6), reg + SUN4I_AHB_REG); 1440 + 1441 + sunxi_ccu_probe(node, reg, desc); 1442 + } 1443 + 1444 + static void __init sun4i_a10_ccu_setup(struct device_node *node) 1445 + { 1446 + sun4i_ccu_init(node, &sun4i_a10_ccu_desc); 1447 + } 1448 + CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu", 1449 + sun4i_a10_ccu_setup); 1450 + 1451 + static void __init sun7i_a20_ccu_setup(struct device_node *node) 1452 + { 1453 + sun4i_ccu_init(node, &sun7i_a20_ccu_desc); 1454 + } 1455 + CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu", 1456 + sun7i_a20_ccu_setup);
+61
drivers/clk/sunxi-ng/ccu-sun4i-a10.h
··· 1 + /* 2 + * Copyright 2017 Priit Laes 3 + * 4 + * Priit Laes <plaes@plaes.org> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef _CCU_SUN4I_A10_H_ 18 + #define _CCU_SUN4I_A10_H_ 19 + 20 + #include <dt-bindings/clock/sun4i-a10-ccu.h> 21 + #include <dt-bindings/clock/sun7i-a20-ccu.h> 22 + #include <dt-bindings/reset/sun4i-a10-ccu.h> 23 + 24 + /* The HOSC is exported */ 25 + #define CLK_PLL_CORE 2 26 + #define CLK_PLL_AUDIO_BASE 3 27 + #define CLK_PLL_AUDIO 4 28 + #define CLK_PLL_AUDIO_2X 5 29 + #define CLK_PLL_AUDIO_4X 6 30 + #define CLK_PLL_AUDIO_8X 7 31 + #define CLK_PLL_VIDEO0 8 32 + #define CLK_PLL_VIDEO0_2X 9 33 + #define CLK_PLL_VE 10 34 + #define CLK_PLL_DDR_BASE 11 35 + #define CLK_PLL_DDR 12 36 + #define CLK_PLL_DDR_OTHER 13 37 + #define CLK_PLL_PERIPH_BASE 14 38 + #define CLK_PLL_PERIPH 15 39 + #define CLK_PLL_PERIPH_SATA 16 40 + #define CLK_PLL_VIDEO1 17 41 + #define CLK_PLL_VIDEO1_2X 18 42 + #define CLK_PLL_GPU 19 43 + 44 + /* The CPU clock is exported */ 45 + #define CLK_AXI 21 46 + #define CLK_AXI_DRAM 22 47 + #define CLK_AHB 23 48 + #define CLK_APB0 24 49 + #define CLK_APB1 25 50 + 51 + /* AHB gates are exported (23..68) */ 52 + /* APB0 gates are exported (69..78) */ 53 + /* APB1 gates are exported (79..95) */ 54 + /* IP module clocks are exported (96..128) */ 55 + /* DRAM gates are exported (129..142)*/ 56 + /* Media (display engine clocks & etc) are exported (143..169) */ 57 + 58 + #define CLK_NUMBER_SUN4I (CLK_MBUS + 1) 59 + #define CLK_NUMBER_SUN7I (CLK_OUT_B + 1) 60 + 61 + #endif /* _CCU_SUN4I_A10_H_ */
+1 -2
drivers/clk/sunxi-ng/ccu-sun5i.c
··· 976 976 977 977 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 978 978 if (IS_ERR(reg)) { 979 - pr_err("%s: Could not map the clock registers\n", 980 - of_node_full_name(node)); 979 + pr_err("%pOF: Could not map the clock registers\n", node); 981 980 return; 982 981 } 983 982
+1 -2
drivers/clk/sunxi-ng/ccu-sun6i-a31.c
··· 1217 1217 1218 1218 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1219 1219 if (IS_ERR(reg)) { 1220 - pr_err("%s: Could not map the clock registers\n", 1221 - of_node_full_name(node)); 1220 + pr_err("%pOF: Could not map the clock registers\n", node); 1222 1221 return; 1223 1222 } 1224 1223
+1 -2
drivers/clk/sunxi-ng/ccu-sun8i-a23.c
··· 716 716 717 717 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 718 718 if (IS_ERR(reg)) { 719 - pr_err("%s: Could not map the clock registers\n", 720 - of_node_full_name(node)); 719 + pr_err("%pOF: Could not map the clock registers\n", node); 721 720 return; 722 721 } 723 722
+1 -2
drivers/clk/sunxi-ng/ccu-sun8i-a33.c
··· 777 777 778 778 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 779 779 if (IS_ERR(reg)) { 780 - pr_err("%s: Could not map the clock registers\n", 781 - of_node_full_name(node)); 780 + pr_err("%pOF: Could not map the clock registers\n", node); 782 781 return; 783 782 } 784 783
+13 -3
drivers/clk/sunxi-ng/ccu-sun8i-h3.c
··· 135 135 static const char * const cpux_parents[] = { "osc32k", "osc24M", 136 136 "pll-cpux" , "pll-cpux" }; 137 137 static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents, 138 - 0x050, 16, 2, CLK_IS_CRITICAL); 138 + 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT); 139 139 140 140 static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0); 141 141 ··· 1103 1103 .num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets), 1104 1104 }; 1105 1105 1106 + static struct ccu_pll_nb sun8i_h3_pll_cpu_nb = { 1107 + .common = &pll_cpux_clk.common, 1108 + /* copy from pll_cpux_clk */ 1109 + .enable = BIT(31), 1110 + .lock = BIT(28), 1111 + }; 1112 + 1106 1113 static struct ccu_mux_nb sun8i_h3_cpu_nb = { 1107 1114 .common = &cpux_clk.common, 1108 1115 .cm = &cpux_clk.mux, ··· 1125 1118 1126 1119 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1127 1120 if (IS_ERR(reg)) { 1128 - pr_err("%s: Could not map the clock registers\n", 1129 - of_node_full_name(node)); 1121 + pr_err("%pOF: Could not map the clock registers\n", node); 1130 1122 return; 1131 1123 } 1132 1124 ··· 1136 1130 1137 1131 sunxi_ccu_probe(node, reg, desc); 1138 1132 1133 + /* Gate then ungate PLL CPU after any rate changes */ 1134 + ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb); 1135 + 1136 + /* Reparent CPU during PLL CPU rate changes */ 1139 1137 ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk, 1140 1138 &sun8i_h3_cpu_nb); 1141 1139 }
+1 -2
drivers/clk/sunxi-ng/ccu-sun8i-r.c
··· 290 290 291 291 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 292 292 if (IS_ERR(reg)) { 293 - pr_err("%s: Could not map the clock registers\n", 294 - of_node_full_name(node)); 293 + pr_err("%pOF: Could not map the clock registers\n", node); 295 294 return; 296 295 } 297 296
+1 -1
drivers/clk/sunxi-ng/ccu-sun8i-r.h
··· 13 13 */ 14 14 15 15 #ifndef _CCU_SUN8I_R_H 16 - #define _CCU_SUN8I_R_H_ 16 + #define _CCU_SUN8I_R_H 17 17 18 18 #include <dt-bindings/clock/sun8i-r-ccu.h> 19 19 #include <dt-bindings/reset/sun8i-r-ccu.h>
+1290
drivers/clk/sunxi-ng/ccu-sun8i-r40.c
··· 1 + /* 2 + * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> 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 + */ 13 + 14 + #include <linux/clk-provider.h> 15 + #include <linux/of_address.h> 16 + 17 + #include "ccu_common.h" 18 + #include "ccu_reset.h" 19 + 20 + #include "ccu_div.h" 21 + #include "ccu_gate.h" 22 + #include "ccu_mp.h" 23 + #include "ccu_mult.h" 24 + #include "ccu_nk.h" 25 + #include "ccu_nkm.h" 26 + #include "ccu_nkmp.h" 27 + #include "ccu_nm.h" 28 + #include "ccu_phase.h" 29 + 30 + #include "ccu-sun8i-r40.h" 31 + 32 + /* TODO: The result of N*K is required to be in [10, 88] range. */ 33 + static struct ccu_nkmp pll_cpu_clk = { 34 + .enable = BIT(31), 35 + .lock = BIT(28), 36 + .n = _SUNXI_CCU_MULT(8, 5), 37 + .k = _SUNXI_CCU_MULT(4, 2), 38 + .m = _SUNXI_CCU_DIV(0, 2), 39 + .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), 40 + .common = { 41 + .reg = 0x000, 42 + .hw.init = CLK_HW_INIT("pll-cpu", 43 + "osc24M", 44 + &ccu_nkmp_ops, 45 + CLK_SET_RATE_UNGATE), 46 + }, 47 + }; 48 + 49 + /* 50 + * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from 51 + * the base (2x, 4x and 8x), and one variable divider (the one true 52 + * pll audio). 53 + * 54 + * We don't have any need for the variable divider for now, so we just 55 + * hardcode it to match with the clock names 56 + */ 57 + #define SUN8I_R40_PLL_AUDIO_REG 0x008 58 + 59 + static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", 60 + "osc24M", 0x008, 61 + 8, 7, /* N */ 62 + 0, 5, /* M */ 63 + BIT(31), /* gate */ 64 + BIT(28), /* lock */ 65 + CLK_SET_RATE_UNGATE); 66 + 67 + /* TODO: The result of N/M is required to be in [8, 25] range. */ 68 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", 69 + "osc24M", 0x0010, 70 + 8, 7, /* N */ 71 + 0, 4, /* M */ 72 + BIT(24), /* frac enable */ 73 + BIT(25), /* frac select */ 74 + 270000000, /* frac rate 0 */ 75 + 297000000, /* frac rate 1 */ 76 + BIT(31), /* gate */ 77 + BIT(28), /* lock */ 78 + CLK_SET_RATE_UNGATE); 79 + 80 + /* TODO: The result of N/M is required to be in [8, 25] range. */ 81 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", 82 + "osc24M", 0x0018, 83 + 8, 7, /* N */ 84 + 0, 4, /* M */ 85 + BIT(24), /* frac enable */ 86 + BIT(25), /* frac select */ 87 + 270000000, /* frac rate 0 */ 88 + 297000000, /* frac rate 1 */ 89 + BIT(31), /* gate */ 90 + BIT(28), /* lock */ 91 + CLK_SET_RATE_UNGATE); 92 + 93 + /* TODO: The result of N*K is required to be in [10, 77] range. */ 94 + static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0", 95 + "osc24M", 0x020, 96 + 8, 5, /* N */ 97 + 4, 2, /* K */ 98 + 0, 2, /* M */ 99 + BIT(31), /* gate */ 100 + BIT(28), /* lock */ 101 + CLK_SET_RATE_UNGATE); 102 + 103 + /* TODO: The result of N*K is required to be in [21, 58] range. */ 104 + static struct ccu_nk pll_periph0_clk = { 105 + .enable = BIT(31), 106 + .lock = BIT(28), 107 + .n = _SUNXI_CCU_MULT(8, 5), 108 + .k = _SUNXI_CCU_MULT(4, 2), 109 + .fixed_post_div = 2, 110 + .common = { 111 + .reg = 0x028, 112 + .features = CCU_FEATURE_FIXED_POSTDIV, 113 + .hw.init = CLK_HW_INIT("pll-periph0", "osc24M", 114 + &ccu_nk_ops, 115 + CLK_SET_RATE_UNGATE), 116 + }, 117 + }; 118 + 119 + static struct ccu_div pll_periph0_sata_clk = { 120 + .enable = BIT(24), 121 + .div = _SUNXI_CCU_DIV(0, 2), 122 + /* 123 + * The formula of pll-periph0 (1x) is 24MHz*N*K/2, and the formula 124 + * of pll-periph0-sata is 24MHz*N*K/M/6, so the postdiv here is 125 + * 6/2 = 3. 126 + */ 127 + .fixed_post_div = 3, 128 + .common = { 129 + .reg = 0x028, 130 + .features = CCU_FEATURE_FIXED_POSTDIV, 131 + .hw.init = CLK_HW_INIT("pll-periph0-sata", 132 + "pll-periph0", 133 + &ccu_div_ops, 0), 134 + }, 135 + }; 136 + 137 + /* TODO: The result of N*K is required to be in [21, 58] range. */ 138 + static struct ccu_nk pll_periph1_clk = { 139 + .enable = BIT(31), 140 + .lock = BIT(28), 141 + .n = _SUNXI_CCU_MULT(8, 5), 142 + .k = _SUNXI_CCU_MULT(4, 2), 143 + .fixed_post_div = 2, 144 + .common = { 145 + .reg = 0x02c, 146 + .features = CCU_FEATURE_FIXED_POSTDIV, 147 + .hw.init = CLK_HW_INIT("pll-periph1", "osc24M", 148 + &ccu_nk_ops, 149 + CLK_SET_RATE_UNGATE), 150 + }, 151 + }; 152 + 153 + /* TODO: The result of N/M is required to be in [8, 25] range. */ 154 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", 155 + "osc24M", 0x030, 156 + 8, 7, /* N */ 157 + 0, 4, /* M */ 158 + BIT(24), /* frac enable */ 159 + BIT(25), /* frac select */ 160 + 270000000, /* frac rate 0 */ 161 + 297000000, /* frac rate 1 */ 162 + BIT(31), /* gate */ 163 + BIT(28), /* lock */ 164 + CLK_SET_RATE_UNGATE); 165 + 166 + static struct ccu_nkm pll_sata_clk = { 167 + .enable = BIT(31), 168 + .lock = BIT(28), 169 + .n = _SUNXI_CCU_MULT(8, 5), 170 + .k = _SUNXI_CCU_MULT(4, 2), 171 + .m = _SUNXI_CCU_DIV(0, 2), 172 + .fixed_post_div = 6, 173 + .common = { 174 + .reg = 0x034, 175 + .features = CCU_FEATURE_FIXED_POSTDIV, 176 + .hw.init = CLK_HW_INIT("pll-sata", "osc24M", 177 + &ccu_nkm_ops, 178 + CLK_SET_RATE_UNGATE), 179 + }, 180 + }; 181 + 182 + static const char * const pll_sata_out_parents[] = { "pll-sata", 183 + "pll-periph0-sata" }; 184 + static SUNXI_CCU_MUX_WITH_GATE(pll_sata_out_clk, "pll-sata-out", 185 + pll_sata_out_parents, 0x034, 186 + 30, 1, /* mux */ 187 + BIT(14), /* gate */ 188 + CLK_SET_RATE_PARENT); 189 + 190 + /* TODO: The result of N/M is required to be in [8, 25] range. */ 191 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu", 192 + "osc24M", 0x038, 193 + 8, 7, /* N */ 194 + 0, 4, /* M */ 195 + BIT(24), /* frac enable */ 196 + BIT(25), /* frac select */ 197 + 270000000, /* frac rate 0 */ 198 + 297000000, /* frac rate 1 */ 199 + BIT(31), /* gate */ 200 + BIT(28), /* lock */ 201 + CLK_SET_RATE_UNGATE); 202 + 203 + /* 204 + * The MIPI PLL has 2 modes: "MIPI" and "HDMI". 205 + * 206 + * The MIPI mode is a standard NKM-style clock. The HDMI mode is an 207 + * integer / fractional clock with switchable multipliers and dividers. 208 + * This is not supported here. We hardcode the PLL to MIPI mode. 209 + * 210 + * TODO: In the MIPI mode, M/N is required to be equal or lesser than 3, 211 + * which cannot be implemented now. 212 + */ 213 + #define SUN8I_R40_PLL_MIPI_REG 0x040 214 + 215 + static const char * const pll_mipi_parents[] = { "pll-video0" }; 216 + static struct ccu_nkm pll_mipi_clk = { 217 + .enable = BIT(31) | BIT(23) | BIT(22), 218 + .lock = BIT(28), 219 + .n = _SUNXI_CCU_MULT(8, 4), 220 + .k = _SUNXI_CCU_MULT_MIN(4, 2, 2), 221 + .m = _SUNXI_CCU_DIV(0, 4), 222 + .mux = _SUNXI_CCU_MUX(21, 1), 223 + .common = { 224 + .reg = 0x040, 225 + .hw.init = CLK_HW_INIT_PARENTS("pll-mipi", 226 + pll_mipi_parents, 227 + &ccu_nkm_ops, 228 + CLK_SET_RATE_UNGATE) 229 + }, 230 + }; 231 + 232 + /* TODO: The result of N/M is required to be in [8, 25] range. */ 233 + static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de", 234 + "osc24M", 0x048, 235 + 8, 7, /* N */ 236 + 0, 4, /* M */ 237 + BIT(24), /* frac enable */ 238 + BIT(25), /* frac select */ 239 + 270000000, /* frac rate 0 */ 240 + 297000000, /* frac rate 1 */ 241 + BIT(31), /* gate */ 242 + BIT(28), /* lock */ 243 + CLK_SET_RATE_UNGATE); 244 + 245 + /* TODO: The N factor is required to be in [16, 75] range. */ 246 + static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1", 247 + "osc24M", 0x04c, 248 + 8, 7, /* N */ 249 + 0, 2, /* M */ 250 + BIT(31), /* gate */ 251 + BIT(28), /* lock */ 252 + CLK_SET_RATE_UNGATE); 253 + 254 + static const char * const cpu_parents[] = { "osc32k", "osc24M", 255 + "pll-cpu", "pll-cpu" }; 256 + static SUNXI_CCU_MUX(cpu_clk, "cpu", cpu_parents, 257 + 0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT); 258 + 259 + static SUNXI_CCU_M(axi_clk, "axi", "cpu", 0x050, 0, 2, 0); 260 + 261 + static const char * const ahb1_parents[] = { "osc32k", "osc24M", 262 + "axi", "pll-periph0" }; 263 + static const struct ccu_mux_var_prediv ahb1_predivs[] = { 264 + { .index = 3, .shift = 6, .width = 2 }, 265 + }; 266 + static struct ccu_div ahb1_clk = { 267 + .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), 268 + 269 + .mux = { 270 + .shift = 12, 271 + .width = 2, 272 + 273 + .var_predivs = ahb1_predivs, 274 + .n_var_predivs = ARRAY_SIZE(ahb1_predivs), 275 + }, 276 + 277 + .common = { 278 + .reg = 0x054, 279 + .features = CCU_FEATURE_VARIABLE_PREDIV, 280 + .hw.init = CLK_HW_INIT_PARENTS("ahb1", 281 + ahb1_parents, 282 + &ccu_div_ops, 283 + 0), 284 + }, 285 + }; 286 + 287 + static struct clk_div_table apb1_div_table[] = { 288 + { .val = 0, .div = 2 }, 289 + { .val = 1, .div = 2 }, 290 + { .val = 2, .div = 4 }, 291 + { .val = 3, .div = 8 }, 292 + { /* Sentinel */ }, 293 + }; 294 + static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1", 295 + 0x054, 8, 2, apb1_div_table, 0); 296 + 297 + static const char * const apb2_parents[] = { "osc32k", "osc24M", 298 + "pll-periph0-2x", 299 + "pll-periph0-2x" }; 300 + static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058, 301 + 0, 5, /* M */ 302 + 16, 2, /* P */ 303 + 24, 2, /* mux */ 304 + 0); 305 + 306 + static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1", 307 + 0x060, BIT(1), 0); 308 + static SUNXI_CCU_GATE(bus_ce_clk, "bus-ce", "ahb1", 309 + 0x060, BIT(5), 0); 310 + static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1", 311 + 0x060, BIT(6), 0); 312 + static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1", 313 + 0x060, BIT(8), 0); 314 + static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1", 315 + 0x060, BIT(9), 0); 316 + static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1", 317 + 0x060, BIT(10), 0); 318 + static SUNXI_CCU_GATE(bus_mmc3_clk, "bus-mmc3", "ahb1", 319 + 0x060, BIT(11), 0); 320 + static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1", 321 + 0x060, BIT(13), 0); 322 + static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1", 323 + 0x060, BIT(14), 0); 324 + static SUNXI_CCU_GATE(bus_emac_clk, "bus-emac", "ahb1", 325 + 0x060, BIT(17), 0); 326 + static SUNXI_CCU_GATE(bus_ts_clk, "bus-ts", "ahb1", 327 + 0x060, BIT(18), 0); 328 + static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1", 329 + 0x060, BIT(19), 0); 330 + static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1", 331 + 0x060, BIT(20), 0); 332 + static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1", 333 + 0x060, BIT(21), 0); 334 + static SUNXI_CCU_GATE(bus_spi2_clk, "bus-spi2", "ahb1", 335 + 0x060, BIT(22), 0); 336 + static SUNXI_CCU_GATE(bus_spi3_clk, "bus-spi3", "ahb1", 337 + 0x060, BIT(23), 0); 338 + static SUNXI_CCU_GATE(bus_sata_clk, "bus-sata", "ahb1", 339 + 0x060, BIT(24), 0); 340 + static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1", 341 + 0x060, BIT(25), 0); 342 + static SUNXI_CCU_GATE(bus_ehci0_clk, "bus-ehci0", "ahb1", 343 + 0x060, BIT(26), 0); 344 + static SUNXI_CCU_GATE(bus_ehci1_clk, "bus-ehci1", "ahb1", 345 + 0x060, BIT(27), 0); 346 + static SUNXI_CCU_GATE(bus_ehci2_clk, "bus-ehci2", "ahb1", 347 + 0x060, BIT(28), 0); 348 + static SUNXI_CCU_GATE(bus_ohci0_clk, "bus-ohci0", "ahb1", 349 + 0x060, BIT(29), 0); 350 + static SUNXI_CCU_GATE(bus_ohci1_clk, "bus-ohci1", "ahb1", 351 + 0x060, BIT(30), 0); 352 + static SUNXI_CCU_GATE(bus_ohci2_clk, "bus-ohci2", "ahb1", 353 + 0x060, BIT(31), 0); 354 + 355 + static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1", 356 + 0x064, BIT(0), 0); 357 + static SUNXI_CCU_GATE(bus_mp_clk, "bus-mp", "ahb1", 358 + 0x064, BIT(2), 0); 359 + static SUNXI_CCU_GATE(bus_deinterlace_clk, "bus-deinterlace", "ahb1", 360 + 0x064, BIT(5), 0); 361 + static SUNXI_CCU_GATE(bus_csi0_clk, "bus-csi0", "ahb1", 362 + 0x064, BIT(8), 0); 363 + static SUNXI_CCU_GATE(bus_csi1_clk, "bus-csi1", "ahb1", 364 + 0x064, BIT(9), 0); 365 + static SUNXI_CCU_GATE(bus_hdmi0_clk, "bus-hdmi0", "ahb1", 366 + 0x064, BIT(10), 0); 367 + static SUNXI_CCU_GATE(bus_hdmi1_clk, "bus-hdmi1", "ahb1", 368 + 0x064, BIT(11), 0); 369 + static SUNXI_CCU_GATE(bus_de_clk, "bus-de", "ahb1", 370 + 0x064, BIT(12), 0); 371 + static SUNXI_CCU_GATE(bus_tve0_clk, "bus-tve0", "ahb1", 372 + 0x064, BIT(13), 0); 373 + static SUNXI_CCU_GATE(bus_tve1_clk, "bus-tve1", "ahb1", 374 + 0x064, BIT(14), 0); 375 + static SUNXI_CCU_GATE(bus_tve_top_clk, "bus-tve-top", "ahb1", 376 + 0x064, BIT(15), 0); 377 + static SUNXI_CCU_GATE(bus_gmac_clk, "bus-gmac", "ahb1", 378 + 0x064, BIT(17), 0); 379 + static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1", 380 + 0x064, BIT(20), 0); 381 + static SUNXI_CCU_GATE(bus_tvd0_clk, "bus-tvd0", "ahb1", 382 + 0x064, BIT(21), 0); 383 + static SUNXI_CCU_GATE(bus_tvd1_clk, "bus-tvd1", "ahb1", 384 + 0x064, BIT(22), 0); 385 + static SUNXI_CCU_GATE(bus_tvd2_clk, "bus-tvd2", "ahb1", 386 + 0x064, BIT(23), 0); 387 + static SUNXI_CCU_GATE(bus_tvd3_clk, "bus-tvd3", "ahb1", 388 + 0x064, BIT(24), 0); 389 + static SUNXI_CCU_GATE(bus_tvd_top_clk, "bus-tvd-top", "ahb1", 390 + 0x064, BIT(25), 0); 391 + static SUNXI_CCU_GATE(bus_tcon_lcd0_clk, "bus-tcon-lcd0", "ahb1", 392 + 0x064, BIT(26), 0); 393 + static SUNXI_CCU_GATE(bus_tcon_lcd1_clk, "bus-tcon-lcd1", "ahb1", 394 + 0x064, BIT(27), 0); 395 + static SUNXI_CCU_GATE(bus_tcon_tv0_clk, "bus-tcon-tv0", "ahb1", 396 + 0x064, BIT(28), 0); 397 + static SUNXI_CCU_GATE(bus_tcon_tv1_clk, "bus-tcon-tv1", "ahb1", 398 + 0x064, BIT(29), 0); 399 + static SUNXI_CCU_GATE(bus_tcon_top_clk, "bus-tcon-top", "ahb1", 400 + 0x064, BIT(30), 0); 401 + 402 + static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1", 403 + 0x068, BIT(0), 0); 404 + static SUNXI_CCU_GATE(bus_spdif_clk, "bus-spdif", "apb1", 405 + 0x068, BIT(1), 0); 406 + static SUNXI_CCU_GATE(bus_ac97_clk, "bus-ac97", "apb1", 407 + 0x068, BIT(2), 0); 408 + static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1", 409 + 0x068, BIT(5), 0); 410 + static SUNXI_CCU_GATE(bus_ir0_clk, "bus-ir0", "apb1", 411 + 0x068, BIT(6), 0); 412 + static SUNXI_CCU_GATE(bus_ir1_clk, "bus-ir1", "apb1", 413 + 0x068, BIT(7), 0); 414 + static SUNXI_CCU_GATE(bus_ths_clk, "bus-ths", "apb1", 415 + 0x068, BIT(8), 0); 416 + static SUNXI_CCU_GATE(bus_keypad_clk, "bus-keypad", "apb1", 417 + 0x068, BIT(10), 0); 418 + static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1", 419 + 0x068, BIT(12), 0); 420 + static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1", 421 + 0x068, BIT(13), 0); 422 + static SUNXI_CCU_GATE(bus_i2s2_clk, "bus-i2s2", "apb1", 423 + 0x068, BIT(14), 0); 424 + 425 + static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2", 426 + 0x06c, BIT(0), 0); 427 + static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2", 428 + 0x06c, BIT(1), 0); 429 + static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2", 430 + 0x06c, BIT(2), 0); 431 + static SUNXI_CCU_GATE(bus_i2c3_clk, "bus-i2c3", "apb2", 432 + 0x06c, BIT(3), 0); 433 + /* 434 + * In datasheet here's "Reserved", however the gate exists in BSP soucre 435 + * code. 436 + */ 437 + static SUNXI_CCU_GATE(bus_can_clk, "bus-can", "apb2", 438 + 0x06c, BIT(4), 0); 439 + static SUNXI_CCU_GATE(bus_scr_clk, "bus-scr", "apb2", 440 + 0x06c, BIT(5), 0); 441 + static SUNXI_CCU_GATE(bus_ps20_clk, "bus-ps20", "apb2", 442 + 0x06c, BIT(6), 0); 443 + static SUNXI_CCU_GATE(bus_ps21_clk, "bus-ps21", "apb2", 444 + 0x06c, BIT(7), 0); 445 + static SUNXI_CCU_GATE(bus_i2c4_clk, "bus-i2c4", "apb2", 446 + 0x06c, BIT(15), 0); 447 + static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2", 448 + 0x06c, BIT(16), 0); 449 + static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2", 450 + 0x06c, BIT(17), 0); 451 + static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2", 452 + 0x06c, BIT(18), 0); 453 + static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2", 454 + 0x06c, BIT(19), 0); 455 + static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2", 456 + 0x06c, BIT(20), 0); 457 + static SUNXI_CCU_GATE(bus_uart5_clk, "bus-uart5", "apb2", 458 + 0x06c, BIT(21), 0); 459 + static SUNXI_CCU_GATE(bus_uart6_clk, "bus-uart6", "apb2", 460 + 0x06c, BIT(22), 0); 461 + static SUNXI_CCU_GATE(bus_uart7_clk, "bus-uart7", "apb2", 462 + 0x06c, BIT(23), 0); 463 + 464 + static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1", 465 + 0x070, BIT(7), 0); 466 + 467 + static const char * const ths_parents[] = { "osc24M" }; 468 + static struct ccu_div ths_clk = { 469 + .enable = BIT(31), 470 + .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), 471 + .mux = _SUNXI_CCU_MUX(24, 2), 472 + .common = { 473 + .reg = 0x074, 474 + .hw.init = CLK_HW_INIT_PARENTS("ths", 475 + ths_parents, 476 + &ccu_div_ops, 477 + 0), 478 + }, 479 + }; 480 + 481 + static const char * const mod0_default_parents[] = { "osc24M", "pll-periph0", 482 + "pll-periph1" }; 483 + static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080, 484 + 0, 4, /* M */ 485 + 16, 2, /* P */ 486 + 24, 2, /* mux */ 487 + BIT(31), /* gate */ 488 + 0); 489 + 490 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088, 491 + 0, 4, /* M */ 492 + 16, 2, /* P */ 493 + 24, 2, /* mux */ 494 + BIT(31), /* gate */ 495 + 0); 496 + 497 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c, 498 + 0, 4, /* M */ 499 + 16, 2, /* P */ 500 + 24, 2, /* mux */ 501 + BIT(31), /* gate */ 502 + 0); 503 + 504 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090, 505 + 0, 4, /* M */ 506 + 16, 2, /* P */ 507 + 24, 2, /* mux */ 508 + BIT(31), /* gate */ 509 + 0); 510 + 511 + static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents, 0x094, 512 + 0, 4, /* M */ 513 + 16, 2, /* P */ 514 + 24, 2, /* mux */ 515 + BIT(31), /* gate */ 516 + 0); 517 + 518 + static const char * const ts_parents[] = { "osc24M", "pll-periph0", }; 519 + static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098, 520 + 0, 4, /* M */ 521 + 16, 2, /* P */ 522 + 24, 4, /* mux */ 523 + BIT(31), /* gate */ 524 + 0); 525 + 526 + static const char * const ce_parents[] = { "osc24M", "pll-periph0-2x", 527 + "pll-periph1-2x" }; 528 + static SUNXI_CCU_MP_WITH_MUX_GATE(ce_clk, "ce", ce_parents, 0x09c, 529 + 0, 4, /* M */ 530 + 16, 2, /* P */ 531 + 24, 2, /* mux */ 532 + BIT(31), /* gate */ 533 + 0); 534 + 535 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0, 536 + 0, 4, /* M */ 537 + 16, 2, /* P */ 538 + 24, 2, /* mux */ 539 + BIT(31), /* gate */ 540 + 0); 541 + 542 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4, 543 + 0, 4, /* M */ 544 + 16, 2, /* P */ 545 + 24, 2, /* mux */ 546 + BIT(31), /* gate */ 547 + 0); 548 + 549 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8, 550 + 0, 4, /* M */ 551 + 16, 2, /* P */ 552 + 24, 2, /* mux */ 553 + BIT(31), /* gate */ 554 + 0); 555 + 556 + static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac, 557 + 0, 4, /* M */ 558 + 16, 2, /* P */ 559 + 24, 2, /* mux */ 560 + BIT(31), /* gate */ 561 + 0); 562 + 563 + static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x", 564 + "pll-audio-2x", "pll-audio" }; 565 + static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents, 566 + 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 567 + 568 + static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents, 569 + 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 570 + 571 + static SUNXI_CCU_MUX_WITH_GATE(i2s2_clk, "i2s2", i2s_parents, 572 + 0x0b8, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 573 + 574 + static SUNXI_CCU_MUX_WITH_GATE(ac97_clk, "ac97", i2s_parents, 575 + 0x0bc, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 576 + 577 + static SUNXI_CCU_MUX_WITH_GATE(spdif_clk, "spdif", i2s_parents, 578 + 0x0c0, 16, 2, BIT(31), CLK_SET_RATE_PARENT); 579 + 580 + static const char * const keypad_parents[] = { "osc24M", "osc32k" }; 581 + static const u8 keypad_table[] = { 0, 2 }; 582 + static struct ccu_mp keypad_clk = { 583 + .enable = BIT(31), 584 + .m = _SUNXI_CCU_DIV(0, 5), 585 + .p = _SUNXI_CCU_DIV(16, 2), 586 + .mux = _SUNXI_CCU_MUX_TABLE(24, 2, keypad_table), 587 + .common = { 588 + .reg = 0x0c4, 589 + .hw.init = CLK_HW_INIT_PARENTS("keypad", 590 + keypad_parents, 591 + &ccu_mp_ops, 592 + 0), 593 + } 594 + }; 595 + 596 + static const char * const sata_parents[] = { "pll-sata-out", "sata-ext" }; 597 + static SUNXI_CCU_MUX_WITH_GATE(sata_clk, "sata", sata_parents, 598 + 0x0c8, 24, 1, BIT(31), CLK_SET_RATE_PARENT); 599 + 600 + /* 601 + * There are 3 OHCI 12M clock source selection bits in this register. 602 + * We will force them to 0 (12M divided from 48M). 603 + */ 604 + #define SUN8I_R40_USB_CLK_REG 0x0cc 605 + 606 + static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M", 607 + 0x0cc, BIT(8), 0); 608 + static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M", 609 + 0x0cc, BIT(9), 0); 610 + static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M", 611 + 0x0cc, BIT(10), 0); 612 + static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc12M", 613 + 0x0cc, BIT(16), 0); 614 + static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc12M", 615 + 0x0cc, BIT(17), 0); 616 + static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc12M", 617 + 0x0cc, BIT(18), 0); 618 + 619 + static const char * const ir_parents[] = { "osc24M", "pll-periph0", 620 + "pll-periph1", "osc32k" }; 621 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir0_clk, "ir0", ir_parents, 0x0d0, 622 + 0, 4, /* M */ 623 + 16, 2, /* P */ 624 + 24, 2, /* mux */ 625 + BIT(31), /* gate */ 626 + 0); 627 + 628 + static SUNXI_CCU_MP_WITH_MUX_GATE(ir1_clk, "ir1", ir_parents, 0x0d4, 629 + 0, 4, /* M */ 630 + 16, 2, /* P */ 631 + 24, 2, /* mux */ 632 + BIT(31), /* gate */ 633 + 0); 634 + 635 + static const char * const dram_parents[] = { "pll-ddr0", "pll-ddr1" }; 636 + static SUNXI_CCU_M_WITH_MUX(dram_clk, "dram", dram_parents, 637 + 0x0f4, 0, 2, 20, 2, CLK_IS_CRITICAL); 638 + 639 + static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram", 640 + 0x100, BIT(0), 0); 641 + static SUNXI_CCU_GATE(dram_csi0_clk, "dram-csi0", "dram", 642 + 0x100, BIT(1), 0); 643 + static SUNXI_CCU_GATE(dram_csi1_clk, "dram-csi1", "dram", 644 + 0x100, BIT(2), 0); 645 + static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "dram", 646 + 0x100, BIT(3), 0); 647 + static SUNXI_CCU_GATE(dram_tvd_clk, "dram-tvd", "dram", 648 + 0x100, BIT(4), 0); 649 + static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "dram", 650 + 0x100, BIT(5), 0); 651 + static SUNXI_CCU_GATE(dram_deinterlace_clk, "dram-deinterlace", "dram", 652 + 0x100, BIT(6), 0); 653 + 654 + static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" }; 655 + static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents, 656 + 0x104, 0, 4, 24, 3, BIT(31), 0); 657 + static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", de_parents, 658 + 0x108, 0, 4, 24, 3, BIT(31), 0); 659 + 660 + static const char * const tcon_parents[] = { "pll-video0", "pll-video1", 661 + "pll-video0-2x", "pll-video1-2x", 662 + "pll-mipi" }; 663 + static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd0_clk, "tcon-lcd0", tcon_parents, 664 + 0x110, 24, 3, BIT(31), CLK_SET_RATE_PARENT); 665 + static SUNXI_CCU_MUX_WITH_GATE(tcon_lcd1_clk, "tcon-lcd1", tcon_parents, 666 + 0x114, 24, 3, BIT(31), CLK_SET_RATE_PARENT); 667 + static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv0_clk, "tcon-tv0", tcon_parents, 668 + 0x118, 0, 4, 24, 3, BIT(31), 0); 669 + static SUNXI_CCU_M_WITH_MUX_GATE(tcon_tv1_clk, "tcon-tv1", tcon_parents, 670 + 0x11c, 0, 4, 24, 3, BIT(31), 0); 671 + 672 + static const char * const deinterlace_parents[] = { "pll-periph0", 673 + "pll-periph1" }; 674 + static SUNXI_CCU_M_WITH_MUX_GATE(deinterlace_clk, "deinterlace", 675 + deinterlace_parents, 0x124, 0, 4, 24, 3, 676 + BIT(31), 0); 677 + 678 + static const char * const csi_mclk_parents[] = { "osc24M", "pll-video1", 679 + "pll-periph1" }; 680 + static SUNXI_CCU_M_WITH_MUX_GATE(csi1_mclk_clk, "csi1-mclk", csi_mclk_parents, 681 + 0x130, 0, 5, 8, 3, BIT(15), 0); 682 + 683 + static const char * const csi_sclk_parents[] = { "pll-periph0", "pll-periph1" }; 684 + static SUNXI_CCU_M_WITH_MUX_GATE(csi_sclk_clk, "csi-sclk", csi_sclk_parents, 685 + 0x134, 16, 4, 24, 3, BIT(31), 0); 686 + 687 + static SUNXI_CCU_M_WITH_MUX_GATE(csi0_mclk_clk, "csi0-mclk", csi_mclk_parents, 688 + 0x134, 0, 5, 8, 3, BIT(15), 0); 689 + 690 + static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve", 691 + 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT); 692 + 693 + static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio", 694 + 0x140, BIT(31), CLK_SET_RATE_PARENT); 695 + static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M", 696 + 0x144, BIT(31), 0); 697 + 698 + static const char * const hdmi_parents[] = { "pll-video0", "pll-video1" }; 699 + static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", hdmi_parents, 700 + 0x150, 0, 4, 24, 2, BIT(31), 0); 701 + 702 + static SUNXI_CCU_GATE(hdmi_slow_clk, "hdmi-slow", "osc24M", 703 + 0x154, BIT(31), 0); 704 + 705 + /* 706 + * In the SoC's user manual, the P factor is mentioned, but not used in 707 + * the frequency formula. 708 + * 709 + * Here the factor is included, according to the BSP kernel source, 710 + * which contains the P factor of this clock. 711 + */ 712 + static const char * const mbus_parents[] = { "osc24M", "pll-periph0-2x", 713 + "pll-ddr0" }; 714 + static SUNXI_CCU_MP_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents, 0x15c, 715 + 0, 4, /* M */ 716 + 16, 2, /* P */ 717 + 24, 2, /* mux */ 718 + BIT(31), /* gate */ 719 + CLK_IS_CRITICAL); 720 + 721 + static const char * const dsi_dphy_parents[] = { "pll-video0", "pll-video1", 722 + "pll-periph0" }; 723 + static SUNXI_CCU_M_WITH_MUX_GATE(dsi_dphy_clk, "dsi-dphy", dsi_dphy_parents, 724 + 0x168, 0, 4, 8, 2, BIT(15), 0); 725 + 726 + static SUNXI_CCU_M_WITH_MUX_GATE(tve0_clk, "tve0", tcon_parents, 727 + 0x180, 0, 4, 24, 3, BIT(31), 0); 728 + static SUNXI_CCU_M_WITH_MUX_GATE(tve1_clk, "tve1", tcon_parents, 729 + 0x184, 0, 4, 24, 3, BIT(31), 0); 730 + 731 + static const char * const tvd_parents[] = { "pll-video0", "pll-video1", 732 + "pll-video0-2x", "pll-video1-2x" }; 733 + static SUNXI_CCU_M_WITH_MUX_GATE(tvd0_clk, "tvd0", tvd_parents, 734 + 0x188, 0, 4, 24, 3, BIT(31), 0); 735 + static SUNXI_CCU_M_WITH_MUX_GATE(tvd1_clk, "tvd1", tvd_parents, 736 + 0x18c, 0, 4, 24, 3, BIT(31), 0); 737 + static SUNXI_CCU_M_WITH_MUX_GATE(tvd2_clk, "tvd2", tvd_parents, 738 + 0x190, 0, 4, 24, 3, BIT(31), 0); 739 + static SUNXI_CCU_M_WITH_MUX_GATE(tvd3_clk, "tvd3", tvd_parents, 740 + 0x194, 0, 4, 24, 3, BIT(31), 0); 741 + 742 + static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu", 743 + 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT); 744 + 745 + static const char * const out_parents[] = { "osc24M", "osc32k", "osc24M" }; 746 + static const struct ccu_mux_fixed_prediv out_predivs[] = { 747 + { .index = 0, .div = 750, }, 748 + }; 749 + 750 + static struct ccu_mp outa_clk = { 751 + .enable = BIT(31), 752 + .m = _SUNXI_CCU_DIV(8, 5), 753 + .p = _SUNXI_CCU_DIV(20, 2), 754 + .mux = { 755 + .shift = 24, 756 + .width = 2, 757 + .fixed_predivs = out_predivs, 758 + .n_predivs = ARRAY_SIZE(out_predivs), 759 + }, 760 + .common = { 761 + .reg = 0x1f0, 762 + .features = CCU_FEATURE_FIXED_PREDIV, 763 + .hw.init = CLK_HW_INIT_PARENTS("outa", out_parents, 764 + &ccu_mp_ops, 0), 765 + } 766 + }; 767 + 768 + static struct ccu_mp outb_clk = { 769 + .enable = BIT(31), 770 + .m = _SUNXI_CCU_DIV(8, 5), 771 + .p = _SUNXI_CCU_DIV(20, 2), 772 + .mux = { 773 + .shift = 24, 774 + .width = 2, 775 + .fixed_predivs = out_predivs, 776 + .n_predivs = ARRAY_SIZE(out_predivs), 777 + }, 778 + .common = { 779 + .reg = 0x1f4, 780 + .features = CCU_FEATURE_FIXED_PREDIV, 781 + .hw.init = CLK_HW_INIT_PARENTS("outb", out_parents, 782 + &ccu_mp_ops, 0), 783 + } 784 + }; 785 + 786 + static struct ccu_common *sun8i_r40_ccu_clks[] = { 787 + &pll_cpu_clk.common, 788 + &pll_audio_base_clk.common, 789 + &pll_video0_clk.common, 790 + &pll_ve_clk.common, 791 + &pll_ddr0_clk.common, 792 + &pll_periph0_clk.common, 793 + &pll_periph0_sata_clk.common, 794 + &pll_periph1_clk.common, 795 + &pll_video1_clk.common, 796 + &pll_sata_clk.common, 797 + &pll_sata_out_clk.common, 798 + &pll_gpu_clk.common, 799 + &pll_mipi_clk.common, 800 + &pll_de_clk.common, 801 + &pll_ddr1_clk.common, 802 + &cpu_clk.common, 803 + &axi_clk.common, 804 + &ahb1_clk.common, 805 + &apb1_clk.common, 806 + &apb2_clk.common, 807 + &bus_mipi_dsi_clk.common, 808 + &bus_ce_clk.common, 809 + &bus_dma_clk.common, 810 + &bus_mmc0_clk.common, 811 + &bus_mmc1_clk.common, 812 + &bus_mmc2_clk.common, 813 + &bus_mmc3_clk.common, 814 + &bus_nand_clk.common, 815 + &bus_dram_clk.common, 816 + &bus_emac_clk.common, 817 + &bus_ts_clk.common, 818 + &bus_hstimer_clk.common, 819 + &bus_spi0_clk.common, 820 + &bus_spi1_clk.common, 821 + &bus_spi2_clk.common, 822 + &bus_spi3_clk.common, 823 + &bus_sata_clk.common, 824 + &bus_otg_clk.common, 825 + &bus_ehci0_clk.common, 826 + &bus_ehci1_clk.common, 827 + &bus_ehci2_clk.common, 828 + &bus_ohci0_clk.common, 829 + &bus_ohci1_clk.common, 830 + &bus_ohci2_clk.common, 831 + &bus_ve_clk.common, 832 + &bus_mp_clk.common, 833 + &bus_deinterlace_clk.common, 834 + &bus_csi0_clk.common, 835 + &bus_csi1_clk.common, 836 + &bus_hdmi0_clk.common, 837 + &bus_hdmi1_clk.common, 838 + &bus_de_clk.common, 839 + &bus_tve0_clk.common, 840 + &bus_tve1_clk.common, 841 + &bus_tve_top_clk.common, 842 + &bus_gmac_clk.common, 843 + &bus_gpu_clk.common, 844 + &bus_tvd0_clk.common, 845 + &bus_tvd1_clk.common, 846 + &bus_tvd2_clk.common, 847 + &bus_tvd3_clk.common, 848 + &bus_tvd_top_clk.common, 849 + &bus_tcon_lcd0_clk.common, 850 + &bus_tcon_lcd1_clk.common, 851 + &bus_tcon_tv0_clk.common, 852 + &bus_tcon_tv1_clk.common, 853 + &bus_tcon_top_clk.common, 854 + &bus_codec_clk.common, 855 + &bus_spdif_clk.common, 856 + &bus_ac97_clk.common, 857 + &bus_pio_clk.common, 858 + &bus_ir0_clk.common, 859 + &bus_ir1_clk.common, 860 + &bus_ths_clk.common, 861 + &bus_keypad_clk.common, 862 + &bus_i2s0_clk.common, 863 + &bus_i2s1_clk.common, 864 + &bus_i2s2_clk.common, 865 + &bus_i2c0_clk.common, 866 + &bus_i2c1_clk.common, 867 + &bus_i2c2_clk.common, 868 + &bus_i2c3_clk.common, 869 + &bus_can_clk.common, 870 + &bus_scr_clk.common, 871 + &bus_ps20_clk.common, 872 + &bus_ps21_clk.common, 873 + &bus_i2c4_clk.common, 874 + &bus_uart0_clk.common, 875 + &bus_uart1_clk.common, 876 + &bus_uart2_clk.common, 877 + &bus_uart3_clk.common, 878 + &bus_uart4_clk.common, 879 + &bus_uart5_clk.common, 880 + &bus_uart6_clk.common, 881 + &bus_uart7_clk.common, 882 + &bus_dbg_clk.common, 883 + &ths_clk.common, 884 + &nand_clk.common, 885 + &mmc0_clk.common, 886 + &mmc1_clk.common, 887 + &mmc2_clk.common, 888 + &mmc3_clk.common, 889 + &ts_clk.common, 890 + &ce_clk.common, 891 + &spi0_clk.common, 892 + &spi1_clk.common, 893 + &spi2_clk.common, 894 + &spi3_clk.common, 895 + &i2s0_clk.common, 896 + &i2s1_clk.common, 897 + &i2s2_clk.common, 898 + &ac97_clk.common, 899 + &spdif_clk.common, 900 + &keypad_clk.common, 901 + &sata_clk.common, 902 + &usb_phy0_clk.common, 903 + &usb_phy1_clk.common, 904 + &usb_phy2_clk.common, 905 + &usb_ohci0_clk.common, 906 + &usb_ohci1_clk.common, 907 + &usb_ohci2_clk.common, 908 + &ir0_clk.common, 909 + &ir1_clk.common, 910 + &dram_clk.common, 911 + &dram_ve_clk.common, 912 + &dram_csi0_clk.common, 913 + &dram_csi1_clk.common, 914 + &dram_ts_clk.common, 915 + &dram_tvd_clk.common, 916 + &dram_mp_clk.common, 917 + &dram_deinterlace_clk.common, 918 + &de_clk.common, 919 + &mp_clk.common, 920 + &tcon_lcd0_clk.common, 921 + &tcon_lcd1_clk.common, 922 + &tcon_tv0_clk.common, 923 + &tcon_tv1_clk.common, 924 + &deinterlace_clk.common, 925 + &csi1_mclk_clk.common, 926 + &csi_sclk_clk.common, 927 + &csi0_mclk_clk.common, 928 + &ve_clk.common, 929 + &codec_clk.common, 930 + &avs_clk.common, 931 + &hdmi_clk.common, 932 + &hdmi_slow_clk.common, 933 + &mbus_clk.common, 934 + &dsi_dphy_clk.common, 935 + &tve0_clk.common, 936 + &tve1_clk.common, 937 + &tvd0_clk.common, 938 + &tvd1_clk.common, 939 + &tvd2_clk.common, 940 + &tvd3_clk.common, 941 + &gpu_clk.common, 942 + &outa_clk.common, 943 + &outb_clk.common, 944 + }; 945 + 946 + /* Fixed Factor clocks */ 947 + static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0); 948 + 949 + /* We hardcode the divider to 4 for now */ 950 + static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 951 + "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 952 + static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 953 + "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 954 + static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 955 + "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT); 956 + static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x", 957 + "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT); 958 + static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x", 959 + "pll-periph0", 1, 2, 0); 960 + static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x", 961 + "pll-periph1", 1, 2, 0); 962 + static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x", 963 + "pll-video0", 1, 2, 0); 964 + static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x", 965 + "pll-video1", 1, 2, 0); 966 + 967 + static struct clk_hw_onecell_data sun8i_r40_hw_clks = { 968 + .hws = { 969 + [CLK_OSC_12M] = &osc12M_clk.hw, 970 + [CLK_PLL_CPU] = &pll_cpu_clk.common.hw, 971 + [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw, 972 + [CLK_PLL_AUDIO] = &pll_audio_clk.hw, 973 + [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw, 974 + [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw, 975 + [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw, 976 + [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw, 977 + [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw, 978 + [CLK_PLL_VE] = &pll_ve_clk.common.hw, 979 + [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw, 980 + [CLK_PLL_PERIPH0] = &pll_periph0_clk.common.hw, 981 + [CLK_PLL_PERIPH0_SATA] = &pll_periph0_sata_clk.common.hw, 982 + [CLK_PLL_PERIPH0_2X] = &pll_periph0_2x_clk.hw, 983 + [CLK_PLL_PERIPH1] = &pll_periph1_clk.common.hw, 984 + [CLK_PLL_PERIPH1_2X] = &pll_periph1_2x_clk.hw, 985 + [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw, 986 + [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw, 987 + [CLK_PLL_SATA] = &pll_sata_clk.common.hw, 988 + [CLK_PLL_SATA_OUT] = &pll_sata_out_clk.common.hw, 989 + [CLK_PLL_GPU] = &pll_gpu_clk.common.hw, 990 + [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw, 991 + [CLK_PLL_DE] = &pll_de_clk.common.hw, 992 + [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw, 993 + [CLK_CPU] = &cpu_clk.common.hw, 994 + [CLK_AXI] = &axi_clk.common.hw, 995 + [CLK_AHB1] = &ahb1_clk.common.hw, 996 + [CLK_APB1] = &apb1_clk.common.hw, 997 + [CLK_APB2] = &apb2_clk.common.hw, 998 + [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw, 999 + [CLK_BUS_CE] = &bus_ce_clk.common.hw, 1000 + [CLK_BUS_DMA] = &bus_dma_clk.common.hw, 1001 + [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw, 1002 + [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw, 1003 + [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw, 1004 + [CLK_BUS_MMC3] = &bus_mmc3_clk.common.hw, 1005 + [CLK_BUS_NAND] = &bus_nand_clk.common.hw, 1006 + [CLK_BUS_DRAM] = &bus_dram_clk.common.hw, 1007 + [CLK_BUS_EMAC] = &bus_emac_clk.common.hw, 1008 + [CLK_BUS_TS] = &bus_ts_clk.common.hw, 1009 + [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw, 1010 + [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw, 1011 + [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw, 1012 + [CLK_BUS_SPI2] = &bus_spi2_clk.common.hw, 1013 + [CLK_BUS_SPI3] = &bus_spi3_clk.common.hw, 1014 + [CLK_BUS_SATA] = &bus_sata_clk.common.hw, 1015 + [CLK_BUS_OTG] = &bus_otg_clk.common.hw, 1016 + [CLK_BUS_EHCI0] = &bus_ehci0_clk.common.hw, 1017 + [CLK_BUS_EHCI1] = &bus_ehci1_clk.common.hw, 1018 + [CLK_BUS_EHCI2] = &bus_ehci2_clk.common.hw, 1019 + [CLK_BUS_OHCI0] = &bus_ohci0_clk.common.hw, 1020 + [CLK_BUS_OHCI1] = &bus_ohci1_clk.common.hw, 1021 + [CLK_BUS_OHCI2] = &bus_ohci2_clk.common.hw, 1022 + [CLK_BUS_VE] = &bus_ve_clk.common.hw, 1023 + [CLK_BUS_MP] = &bus_mp_clk.common.hw, 1024 + [CLK_BUS_DEINTERLACE] = &bus_deinterlace_clk.common.hw, 1025 + [CLK_BUS_CSI0] = &bus_csi0_clk.common.hw, 1026 + [CLK_BUS_CSI1] = &bus_csi1_clk.common.hw, 1027 + [CLK_BUS_HDMI0] = &bus_hdmi0_clk.common.hw, 1028 + [CLK_BUS_HDMI1] = &bus_hdmi1_clk.common.hw, 1029 + [CLK_BUS_DE] = &bus_de_clk.common.hw, 1030 + [CLK_BUS_TVE0] = &bus_tve0_clk.common.hw, 1031 + [CLK_BUS_TVE1] = &bus_tve1_clk.common.hw, 1032 + [CLK_BUS_TVE_TOP] = &bus_tve_top_clk.common.hw, 1033 + [CLK_BUS_GMAC] = &bus_gmac_clk.common.hw, 1034 + [CLK_BUS_GPU] = &bus_gpu_clk.common.hw, 1035 + [CLK_BUS_TVD0] = &bus_tvd0_clk.common.hw, 1036 + [CLK_BUS_TVD1] = &bus_tvd1_clk.common.hw, 1037 + [CLK_BUS_TVD2] = &bus_tvd2_clk.common.hw, 1038 + [CLK_BUS_TVD3] = &bus_tvd3_clk.common.hw, 1039 + [CLK_BUS_TVD_TOP] = &bus_tvd_top_clk.common.hw, 1040 + [CLK_BUS_TCON_LCD0] = &bus_tcon_lcd0_clk.common.hw, 1041 + [CLK_BUS_TCON_LCD1] = &bus_tcon_lcd1_clk.common.hw, 1042 + [CLK_BUS_TCON_TV0] = &bus_tcon_tv0_clk.common.hw, 1043 + [CLK_BUS_TCON_TV1] = &bus_tcon_tv1_clk.common.hw, 1044 + [CLK_BUS_TCON_TOP] = &bus_tcon_top_clk.common.hw, 1045 + [CLK_BUS_CODEC] = &bus_codec_clk.common.hw, 1046 + [CLK_BUS_SPDIF] = &bus_spdif_clk.common.hw, 1047 + [CLK_BUS_AC97] = &bus_ac97_clk.common.hw, 1048 + [CLK_BUS_PIO] = &bus_pio_clk.common.hw, 1049 + [CLK_BUS_IR0] = &bus_ir0_clk.common.hw, 1050 + [CLK_BUS_IR1] = &bus_ir1_clk.common.hw, 1051 + [CLK_BUS_THS] = &bus_ths_clk.common.hw, 1052 + [CLK_BUS_KEYPAD] = &bus_keypad_clk.common.hw, 1053 + [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw, 1054 + [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw, 1055 + [CLK_BUS_I2S2] = &bus_i2s2_clk.common.hw, 1056 + [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw, 1057 + [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw, 1058 + [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw, 1059 + [CLK_BUS_I2C3] = &bus_i2c3_clk.common.hw, 1060 + [CLK_BUS_CAN] = &bus_can_clk.common.hw, 1061 + [CLK_BUS_SCR] = &bus_scr_clk.common.hw, 1062 + [CLK_BUS_PS20] = &bus_ps20_clk.common.hw, 1063 + [CLK_BUS_PS21] = &bus_ps21_clk.common.hw, 1064 + [CLK_BUS_I2C4] = &bus_i2c4_clk.common.hw, 1065 + [CLK_BUS_UART0] = &bus_uart0_clk.common.hw, 1066 + [CLK_BUS_UART1] = &bus_uart1_clk.common.hw, 1067 + [CLK_BUS_UART2] = &bus_uart2_clk.common.hw, 1068 + [CLK_BUS_UART3] = &bus_uart3_clk.common.hw, 1069 + [CLK_BUS_UART4] = &bus_uart4_clk.common.hw, 1070 + [CLK_BUS_UART5] = &bus_uart5_clk.common.hw, 1071 + [CLK_BUS_UART6] = &bus_uart6_clk.common.hw, 1072 + [CLK_BUS_UART7] = &bus_uart7_clk.common.hw, 1073 + [CLK_BUS_DBG] = &bus_dbg_clk.common.hw, 1074 + [CLK_THS] = &ths_clk.common.hw, 1075 + [CLK_NAND] = &nand_clk.common.hw, 1076 + [CLK_MMC0] = &mmc0_clk.common.hw, 1077 + [CLK_MMC1] = &mmc1_clk.common.hw, 1078 + [CLK_MMC2] = &mmc2_clk.common.hw, 1079 + [CLK_MMC3] = &mmc3_clk.common.hw, 1080 + [CLK_TS] = &ts_clk.common.hw, 1081 + [CLK_CE] = &ce_clk.common.hw, 1082 + [CLK_SPI0] = &spi0_clk.common.hw, 1083 + [CLK_SPI1] = &spi1_clk.common.hw, 1084 + [CLK_SPI2] = &spi2_clk.common.hw, 1085 + [CLK_SPI3] = &spi3_clk.common.hw, 1086 + [CLK_I2S0] = &i2s0_clk.common.hw, 1087 + [CLK_I2S1] = &i2s1_clk.common.hw, 1088 + [CLK_I2S2] = &i2s2_clk.common.hw, 1089 + [CLK_AC97] = &ac97_clk.common.hw, 1090 + [CLK_SPDIF] = &spdif_clk.common.hw, 1091 + [CLK_KEYPAD] = &keypad_clk.common.hw, 1092 + [CLK_SATA] = &sata_clk.common.hw, 1093 + [CLK_USB_PHY0] = &usb_phy0_clk.common.hw, 1094 + [CLK_USB_PHY1] = &usb_phy1_clk.common.hw, 1095 + [CLK_USB_PHY2] = &usb_phy2_clk.common.hw, 1096 + [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw, 1097 + [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw, 1098 + [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw, 1099 + [CLK_IR0] = &ir0_clk.common.hw, 1100 + [CLK_IR1] = &ir1_clk.common.hw, 1101 + [CLK_DRAM] = &dram_clk.common.hw, 1102 + [CLK_DRAM_VE] = &dram_ve_clk.common.hw, 1103 + [CLK_DRAM_CSI0] = &dram_csi0_clk.common.hw, 1104 + [CLK_DRAM_CSI1] = &dram_csi1_clk.common.hw, 1105 + [CLK_DRAM_TS] = &dram_ts_clk.common.hw, 1106 + [CLK_DRAM_TVD] = &dram_tvd_clk.common.hw, 1107 + [CLK_DRAM_MP] = &dram_mp_clk.common.hw, 1108 + [CLK_DRAM_DEINTERLACE] = &dram_deinterlace_clk.common.hw, 1109 + [CLK_DE] = &de_clk.common.hw, 1110 + [CLK_MP] = &mp_clk.common.hw, 1111 + [CLK_TCON_LCD0] = &tcon_lcd0_clk.common.hw, 1112 + [CLK_TCON_LCD1] = &tcon_lcd1_clk.common.hw, 1113 + [CLK_TCON_TV0] = &tcon_tv0_clk.common.hw, 1114 + [CLK_TCON_TV1] = &tcon_tv1_clk.common.hw, 1115 + [CLK_DEINTERLACE] = &deinterlace_clk.common.hw, 1116 + [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw, 1117 + [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw, 1118 + [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw, 1119 + [CLK_VE] = &ve_clk.common.hw, 1120 + [CLK_CODEC] = &codec_clk.common.hw, 1121 + [CLK_AVS] = &avs_clk.common.hw, 1122 + [CLK_HDMI] = &hdmi_clk.common.hw, 1123 + [CLK_HDMI_SLOW] = &hdmi_slow_clk.common.hw, 1124 + [CLK_MBUS] = &mbus_clk.common.hw, 1125 + [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw, 1126 + [CLK_TVE0] = &tve0_clk.common.hw, 1127 + [CLK_TVE1] = &tve1_clk.common.hw, 1128 + [CLK_TVD0] = &tvd0_clk.common.hw, 1129 + [CLK_TVD1] = &tvd1_clk.common.hw, 1130 + [CLK_TVD2] = &tvd2_clk.common.hw, 1131 + [CLK_TVD3] = &tvd3_clk.common.hw, 1132 + [CLK_GPU] = &gpu_clk.common.hw, 1133 + [CLK_OUTA] = &outa_clk.common.hw, 1134 + [CLK_OUTB] = &outb_clk.common.hw, 1135 + }, 1136 + .num = CLK_NUMBER, 1137 + }; 1138 + 1139 + static struct ccu_reset_map sun8i_r40_ccu_resets[] = { 1140 + [RST_USB_PHY0] = { 0x0cc, BIT(0) }, 1141 + [RST_USB_PHY1] = { 0x0cc, BIT(1) }, 1142 + [RST_USB_PHY2] = { 0x0cc, BIT(2) }, 1143 + 1144 + [RST_DRAM] = { 0x0f4, BIT(31) }, 1145 + [RST_MBUS] = { 0x0fc, BIT(31) }, 1146 + 1147 + [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) }, 1148 + [RST_BUS_CE] = { 0x2c0, BIT(5) }, 1149 + [RST_BUS_DMA] = { 0x2c0, BIT(6) }, 1150 + [RST_BUS_MMC0] = { 0x2c0, BIT(8) }, 1151 + [RST_BUS_MMC1] = { 0x2c0, BIT(9) }, 1152 + [RST_BUS_MMC2] = { 0x2c0, BIT(10) }, 1153 + [RST_BUS_MMC3] = { 0x2c0, BIT(11) }, 1154 + [RST_BUS_NAND] = { 0x2c0, BIT(13) }, 1155 + [RST_BUS_DRAM] = { 0x2c0, BIT(14) }, 1156 + [RST_BUS_EMAC] = { 0x2c0, BIT(17) }, 1157 + [RST_BUS_TS] = { 0x2c0, BIT(18) }, 1158 + [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) }, 1159 + [RST_BUS_SPI0] = { 0x2c0, BIT(20) }, 1160 + [RST_BUS_SPI1] = { 0x2c0, BIT(21) }, 1161 + [RST_BUS_SPI2] = { 0x2c0, BIT(22) }, 1162 + [RST_BUS_SPI3] = { 0x2c0, BIT(23) }, 1163 + [RST_BUS_SATA] = { 0x2c0, BIT(24) }, 1164 + [RST_BUS_OTG] = { 0x2c0, BIT(25) }, 1165 + [RST_BUS_EHCI0] = { 0x2c0, BIT(26) }, 1166 + [RST_BUS_EHCI1] = { 0x2c0, BIT(27) }, 1167 + [RST_BUS_EHCI2] = { 0x2c0, BIT(28) }, 1168 + [RST_BUS_OHCI0] = { 0x2c0, BIT(29) }, 1169 + [RST_BUS_OHCI1] = { 0x2c0, BIT(30) }, 1170 + [RST_BUS_OHCI2] = { 0x2c0, BIT(31) }, 1171 + 1172 + [RST_BUS_VE] = { 0x2c4, BIT(0) }, 1173 + [RST_BUS_MP] = { 0x2c4, BIT(2) }, 1174 + [RST_BUS_DEINTERLACE] = { 0x2c4, BIT(5) }, 1175 + [RST_BUS_CSI0] = { 0x2c4, BIT(8) }, 1176 + [RST_BUS_CSI1] = { 0x2c4, BIT(9) }, 1177 + [RST_BUS_HDMI0] = { 0x2c4, BIT(10) }, 1178 + [RST_BUS_HDMI1] = { 0x2c4, BIT(11) }, 1179 + [RST_BUS_DE] = { 0x2c4, BIT(12) }, 1180 + [RST_BUS_TVE0] = { 0x2c4, BIT(13) }, 1181 + [RST_BUS_TVE1] = { 0x2c4, BIT(14) }, 1182 + [RST_BUS_TVE_TOP] = { 0x2c4, BIT(15) }, 1183 + [RST_BUS_GMAC] = { 0x2c4, BIT(17) }, 1184 + [RST_BUS_GPU] = { 0x2c4, BIT(20) }, 1185 + [RST_BUS_TVD0] = { 0x2c4, BIT(21) }, 1186 + [RST_BUS_TVD1] = { 0x2c4, BIT(22) }, 1187 + [RST_BUS_TVD2] = { 0x2c4, BIT(23) }, 1188 + [RST_BUS_TVD3] = { 0x2c4, BIT(24) }, 1189 + [RST_BUS_TVD_TOP] = { 0x2c4, BIT(25) }, 1190 + [RST_BUS_TCON_LCD0] = { 0x2c4, BIT(26) }, 1191 + [RST_BUS_TCON_LCD1] = { 0x2c4, BIT(27) }, 1192 + [RST_BUS_TCON_TV0] = { 0x2c4, BIT(28) }, 1193 + [RST_BUS_TCON_TV1] = { 0x2c4, BIT(29) }, 1194 + [RST_BUS_TCON_TOP] = { 0x2c4, BIT(30) }, 1195 + [RST_BUS_DBG] = { 0x2c4, BIT(31) }, 1196 + 1197 + [RST_BUS_LVDS] = { 0x2c8, BIT(0) }, 1198 + 1199 + [RST_BUS_CODEC] = { 0x2d0, BIT(0) }, 1200 + [RST_BUS_SPDIF] = { 0x2d0, BIT(1) }, 1201 + [RST_BUS_AC97] = { 0x2d0, BIT(2) }, 1202 + [RST_BUS_IR0] = { 0x2d0, BIT(6) }, 1203 + [RST_BUS_IR1] = { 0x2d0, BIT(7) }, 1204 + [RST_BUS_THS] = { 0x2d0, BIT(8) }, 1205 + [RST_BUS_KEYPAD] = { 0x2d0, BIT(10) }, 1206 + [RST_BUS_I2S0] = { 0x2d0, BIT(12) }, 1207 + [RST_BUS_I2S1] = { 0x2d0, BIT(13) }, 1208 + [RST_BUS_I2S2] = { 0x2d0, BIT(14) }, 1209 + 1210 + [RST_BUS_I2C0] = { 0x2d8, BIT(0) }, 1211 + [RST_BUS_I2C1] = { 0x2d8, BIT(1) }, 1212 + [RST_BUS_I2C2] = { 0x2d8, BIT(2) }, 1213 + [RST_BUS_I2C3] = { 0x2d8, BIT(3) }, 1214 + [RST_BUS_CAN] = { 0x2d8, BIT(4) }, 1215 + [RST_BUS_SCR] = { 0x2d8, BIT(5) }, 1216 + [RST_BUS_PS20] = { 0x2d8, BIT(6) }, 1217 + [RST_BUS_PS21] = { 0x2d8, BIT(7) }, 1218 + [RST_BUS_I2C4] = { 0x2d8, BIT(15) }, 1219 + [RST_BUS_UART0] = { 0x2d8, BIT(16) }, 1220 + [RST_BUS_UART1] = { 0x2d8, BIT(17) }, 1221 + [RST_BUS_UART2] = { 0x2d8, BIT(18) }, 1222 + [RST_BUS_UART3] = { 0x2d8, BIT(19) }, 1223 + [RST_BUS_UART4] = { 0x2d8, BIT(20) }, 1224 + [RST_BUS_UART5] = { 0x2d8, BIT(21) }, 1225 + [RST_BUS_UART6] = { 0x2d8, BIT(22) }, 1226 + [RST_BUS_UART7] = { 0x2d8, BIT(23) }, 1227 + }; 1228 + 1229 + static const struct sunxi_ccu_desc sun8i_r40_ccu_desc = { 1230 + .ccu_clks = sun8i_r40_ccu_clks, 1231 + .num_ccu_clks = ARRAY_SIZE(sun8i_r40_ccu_clks), 1232 + 1233 + .hw_clks = &sun8i_r40_hw_clks, 1234 + 1235 + .resets = sun8i_r40_ccu_resets, 1236 + .num_resets = ARRAY_SIZE(sun8i_r40_ccu_resets), 1237 + }; 1238 + 1239 + static struct ccu_pll_nb sun8i_r40_pll_cpu_nb = { 1240 + .common = &pll_cpu_clk.common, 1241 + /* copy from pll_cpu_clk */ 1242 + .enable = BIT(31), 1243 + .lock = BIT(28), 1244 + }; 1245 + 1246 + static struct ccu_mux_nb sun8i_r40_cpu_nb = { 1247 + .common = &cpu_clk.common, 1248 + .cm = &cpu_clk.mux, 1249 + .delay_us = 1, /* > 8 clock cycles at 24 MHz */ 1250 + .bypass_index = 1, /* index of 24 MHz oscillator */ 1251 + }; 1252 + 1253 + static void __init sun8i_r40_ccu_setup(struct device_node *node) 1254 + { 1255 + void __iomem *reg; 1256 + u32 val; 1257 + 1258 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 1259 + if (IS_ERR(reg)) { 1260 + pr_err("%s: Could not map the clock registers\n", 1261 + of_node_full_name(node)); 1262 + return; 1263 + } 1264 + 1265 + /* Force the PLL-Audio-1x divider to 4 */ 1266 + val = readl(reg + SUN8I_R40_PLL_AUDIO_REG); 1267 + val &= ~GENMASK(19, 16); 1268 + writel(val | (3 << 16), reg + SUN8I_R40_PLL_AUDIO_REG); 1269 + 1270 + /* Force PLL-MIPI to MIPI mode */ 1271 + val = readl(reg + SUN8I_R40_PLL_MIPI_REG); 1272 + val &= ~BIT(16); 1273 + writel(val, reg + SUN8I_R40_PLL_MIPI_REG); 1274 + 1275 + /* Force OHCI 12M parent to 12M divided from 48M */ 1276 + val = readl(reg + SUN8I_R40_USB_CLK_REG); 1277 + val &= ~GENMASK(25, 20); 1278 + writel(val, reg + SUN8I_R40_USB_CLK_REG); 1279 + 1280 + sunxi_ccu_probe(node, reg, &sun8i_r40_ccu_desc); 1281 + 1282 + /* Gate then ungate PLL CPU after any rate changes */ 1283 + ccu_pll_notifier_register(&sun8i_r40_pll_cpu_nb); 1284 + 1285 + /* Reparent CPU during PLL CPU rate changes */ 1286 + ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk, 1287 + &sun8i_r40_cpu_nb); 1288 + } 1289 + CLK_OF_DECLARE(sun8i_r40_ccu, "allwinner,sun8i-r40-ccu", 1290 + sun8i_r40_ccu_setup);
+69
drivers/clk/sunxi-ng/ccu-sun8i-r40.h
··· 1 + /* 2 + * Copyright 2017 Icenowy Zheng <icenowy@aosc.io> 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 as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + * This program is distributed in the hope that it will be useful, 10 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + * GNU General Public License for more details. 13 + */ 14 + 15 + #ifndef _CCU_SUN8I_R40_H_ 16 + #define _CCU_SUN8I_R40_H_ 17 + 18 + #include <dt-bindings/clock/sun8i-r40-ccu.h> 19 + #include <dt-bindings/reset/sun8i-r40-ccu.h> 20 + 21 + #define CLK_OSC_12M 0 22 + #define CLK_PLL_CPU 1 23 + #define CLK_PLL_AUDIO_BASE 2 24 + #define CLK_PLL_AUDIO 3 25 + #define CLK_PLL_AUDIO_2X 4 26 + #define CLK_PLL_AUDIO_4X 5 27 + #define CLK_PLL_AUDIO_8X 6 28 + #define CLK_PLL_VIDEO0 7 29 + #define CLK_PLL_VIDEO0_2X 8 30 + #define CLK_PLL_VE 9 31 + #define CLK_PLL_DDR0 10 32 + #define CLK_PLL_PERIPH0 11 33 + #define CLK_PLL_PERIPH0_SATA 12 34 + #define CLK_PLL_PERIPH0_2X 13 35 + #define CLK_PLL_PERIPH1 14 36 + #define CLK_PLL_PERIPH1_2X 15 37 + #define CLK_PLL_VIDEO1 16 38 + #define CLK_PLL_VIDEO1_2X 17 39 + #define CLK_PLL_SATA 18 40 + #define CLK_PLL_SATA_OUT 19 41 + #define CLK_PLL_GPU 20 42 + #define CLK_PLL_MIPI 21 43 + #define CLK_PLL_DE 22 44 + #define CLK_PLL_DDR1 23 45 + 46 + /* The CPU clock is exported */ 47 + 48 + #define CLK_AXI 25 49 + #define CLK_AHB1 26 50 + #define CLK_APB1 27 51 + #define CLK_APB2 28 52 + 53 + /* All the bus gates are exported */ 54 + 55 + /* The first bunch of module clocks are exported */ 56 + 57 + #define CLK_DRAM 132 58 + 59 + /* All the DRAM gates are exported */ 60 + 61 + /* Some more module clocks are exported */ 62 + 63 + #define CLK_MBUS 155 64 + 65 + /* Another bunch of module clocks are exported */ 66 + 67 + #define CLK_NUMBER (CLK_OUTB + 1) 68 + 69 + #endif /* _CCU_SUN8I_R40_H_ */
+1 -2
drivers/clk/sunxi-ng/ccu-sun8i-v3s.c
··· 575 575 576 576 reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 577 577 if (IS_ERR(reg)) { 578 - pr_err("%s: Could not map the clock registers\n", 579 - of_node_full_name(node)); 578 + pr_err("%pOF: Could not map the clock registers\n", node); 580 579 return; 581 580 } 582 581
+19 -3
drivers/clk/sunxi-ng/ccu_div.c
··· 21 21 { 22 22 struct ccu_div *cd = data; 23 23 24 - return divider_round_rate_parent(&cd->common.hw, parent, 24 + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) 25 + rate *= cd->fixed_post_div; 26 + 27 + rate = divider_round_rate_parent(&cd->common.hw, parent, 25 28 rate, parent_rate, 26 29 cd->div.table, cd->div.width, 27 30 cd->div.flags); 31 + 32 + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) 33 + rate /= cd->fixed_post_div; 34 + 35 + return rate; 28 36 } 29 37 30 38 static void ccu_div_disable(struct clk_hw *hw) ··· 70 62 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, 71 63 parent_rate); 72 64 73 - return divider_recalc_rate(hw, parent_rate, val, cd->div.table, 74 - cd->div.flags); 65 + val = divider_recalc_rate(hw, parent_rate, val, cd->div.table, 66 + cd->div.flags); 67 + 68 + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) 69 + val /= cd->fixed_post_div; 70 + 71 + return val; 75 72 } 76 73 77 74 static int ccu_div_determine_rate(struct clk_hw *hw, ··· 98 85 99 86 parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1, 100 87 parent_rate); 88 + 89 + if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) 90 + rate *= cd->fixed_post_div; 101 91 102 92 val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width, 103 93 cd->div.flags);
+2 -1
drivers/clk/sunxi-ng/ccu_div.h
··· 86 86 struct ccu_div { 87 87 u32 enable; 88 88 89 - struct ccu_div_internal div; 89 + struct ccu_div_internal div; 90 90 struct ccu_mux_internal mux; 91 91 struct ccu_common common; 92 + unsigned int fixed_post_div; 92 93 }; 93 94 94 95 #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
+8 -6
drivers/clk/sunxi-ng/ccu_frac.c
··· 67 67 { 68 68 u32 reg; 69 69 70 - printk("%s: Read fractional\n", clk_hw_get_name(&common->hw)); 70 + pr_debug("%s: Read fractional\n", clk_hw_get_name(&common->hw)); 71 71 72 72 if (!(common->features & CCU_FEATURE_FRACTIONAL)) 73 73 return 0; 74 74 75 - printk("%s: clock is fractional (rates %lu and %lu)\n", 76 - clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]); 75 + pr_debug("%s: clock is fractional (rates %lu and %lu)\n", 76 + clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]); 77 77 78 78 reg = readl(common->base + common->reg); 79 79 80 - printk("%s: clock reg is 0x%x (select is 0x%x)\n", 81 - clk_hw_get_name(&common->hw), reg, cf->select); 80 + pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n", 81 + clk_hw_get_name(&common->hw), reg, cf->select); 82 82 83 83 return (reg & cf->select) ? cf->rates[1] : cf->rates[0]; 84 84 } 85 85 86 86 int ccu_frac_helper_set_rate(struct ccu_common *common, 87 87 struct ccu_frac_internal *cf, 88 - unsigned long rate) 88 + unsigned long rate, u32 lock) 89 89 { 90 90 unsigned long flags; 91 91 u32 reg, sel; ··· 105 105 reg &= ~cf->select; 106 106 writel(reg | sel, common->base + common->reg); 107 107 spin_unlock_irqrestore(common->lock, flags); 108 + 109 + ccu_helper_wait_for_lock(common, lock); 108 110 109 111 return 0; 110 112 }
+1 -1
drivers/clk/sunxi-ng/ccu_frac.h
··· 48 48 49 49 int ccu_frac_helper_set_rate(struct ccu_common *common, 50 50 struct ccu_frac_internal *cf, 51 - unsigned long rate); 51 + unsigned long rate, u32 lock); 52 52 53 53 #endif /* _CCU_FRAC_H_ */
+7 -3
drivers/clk/sunxi-ng/ccu_mult.c
··· 111 111 unsigned long flags; 112 112 u32 reg; 113 113 114 - if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) 115 - return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate); 116 - else 114 + if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) { 115 + ccu_frac_helper_enable(&cm->common, &cm->frac); 116 + 117 + return ccu_frac_helper_set_rate(&cm->common, &cm->frac, 118 + rate, cm->lock); 119 + } else { 117 120 ccu_frac_helper_disable(&cm->common, &cm->frac); 121 + } 118 122 119 123 parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1, 120 124 parent_rate);
+19 -3
drivers/clk/sunxi-ng/ccu_nkm.c
··· 75 75 unsigned long parent_rate) 76 76 { 77 77 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 78 - unsigned long n, m, k; 78 + unsigned long n, m, k, rate; 79 79 u32 reg; 80 80 81 81 reg = readl(nkm->common.base + nkm->common.reg); ··· 98 98 if (!m) 99 99 m++; 100 100 101 - return parent_rate * n * k / m; 101 + rate = parent_rate * n * k / m; 102 + 103 + if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) 104 + rate /= nkm->fixed_post_div; 105 + 106 + return rate; 102 107 } 103 108 104 109 static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, ··· 122 117 _nkm.min_m = 1; 123 118 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; 124 119 120 + if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) 121 + rate *= nkm->fixed_post_div; 122 + 125 123 ccu_nkm_find_best(*parent_rate, rate, &_nkm); 126 124 127 - return *parent_rate * _nkm.n * _nkm.k / _nkm.m; 125 + rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m; 126 + 127 + if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) 128 + rate /= nkm->fixed_post_div; 129 + 130 + return rate; 128 131 } 129 132 130 133 static int ccu_nkm_determine_rate(struct clk_hw *hw, ··· 151 138 struct _ccu_nkm _nkm; 152 139 unsigned long flags; 153 140 u32 reg; 141 + 142 + if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) 143 + rate *= nkm->fixed_post_div; 154 144 155 145 _nkm.min_n = nkm->n.min ?: 1; 156 146 _nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
+2
drivers/clk/sunxi-ng/ccu_nkm.h
··· 34 34 struct ccu_div_internal m; 35 35 struct ccu_mux_internal mux; 36 36 37 + unsigned int fixed_post_div; 38 + 37 39 struct ccu_common common; 38 40 }; 39 41
+16 -3
drivers/clk/sunxi-ng/ccu_nm.c
··· 117 117 unsigned long flags; 118 118 u32 reg; 119 119 120 - if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) 121 - return ccu_frac_helper_set_rate(&nm->common, &nm->frac, rate); 122 - else 120 + if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) { 121 + spin_lock_irqsave(nm->common.lock, flags); 122 + 123 + /* most SoCs require M to be 0 if fractional mode is used */ 124 + reg = readl(nm->common.base + nm->common.reg); 125 + reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift); 126 + writel(reg, nm->common.base + nm->common.reg); 127 + 128 + spin_unlock_irqrestore(nm->common.lock, flags); 129 + 130 + ccu_frac_helper_enable(&nm->common, &nm->frac); 131 + 132 + return ccu_frac_helper_set_rate(&nm->common, &nm->frac, 133 + rate, nm->lock); 134 + } else { 123 135 ccu_frac_helper_disable(&nm->common, &nm->frac); 136 + } 124 137 125 138 _nm.min_n = nm->n.min ?: 1; 126 139 _nm.max_n = nm->n.max ?: 1 << nm->n.width;
+4
drivers/clk/sunxi/clk-sun8i-bus-gates.c
··· 78 78 clk_parent = APB1; 79 79 else if (index >= 96 && index <= 127) 80 80 clk_parent = APB2; 81 + else { 82 + WARN_ON(true); 83 + continue; 84 + } 81 85 82 86 clk_reg = reg + 4 * (index / 32); 83 87 clk_bit = index % 32;
+7 -10
drivers/clk/sunxi/clk-sunxi.c
··· 666 666 667 667 reg = of_iomap(node, 0); 668 668 if (!reg) { 669 - pr_err("Could not map registers for mux-clk: %s\n", 670 - of_node_full_name(node)); 669 + pr_err("Could not map registers for mux-clk: %pOF\n", node); 671 670 return NULL; 672 671 } 673 672 674 673 i = of_clk_parent_fill(node, parents, SUNXI_MAX_PARENTS); 675 674 if (of_property_read_string(node, "clock-output-names", &clk_name)) { 676 - pr_err("%s: could not read clock-output-names from \"%s\"\n", 677 - __func__, of_node_full_name(node)); 675 + pr_err("%s: could not read clock-output-names from \"%pOF\"\n", 676 + __func__, node); 678 677 goto out_unmap; 679 678 } 680 679 ··· 796 797 797 798 reg = of_iomap(node, 0); 798 799 if (!reg) { 799 - pr_err("Could not map registers for mux-clk: %s\n", 800 - of_node_full_name(node)); 800 + pr_err("Could not map registers for mux-clk: %pOF\n", node); 801 801 return; 802 802 } 803 803 804 804 clk_parent = of_clk_get_parent_name(node, 0); 805 805 806 806 if (of_property_read_string(node, "clock-output-names", &clk_name)) { 807 - pr_err("%s: could not read clock-output-names from \"%s\"\n", 808 - __func__, of_node_full_name(node)); 807 + pr_err("%s: could not read clock-output-names from \"%pOF\"\n", 808 + __func__, node); 809 809 goto out_unmap; 810 810 } 811 811 ··· 1008 1010 1009 1011 reg = of_iomap(node, 0); 1010 1012 if (!reg) { 1011 - pr_err("Could not map registers for divs-clk: %s\n", 1012 - of_node_full_name(node)); 1013 + pr_err("Could not map registers for divs-clk: %pOF\n", node); 1013 1014 return NULL; 1014 1015 } 1015 1016
+5 -7
drivers/clk/tegra/clk-emc.c
··· 378 378 379 379 err = of_property_read_u32(node, "clock-frequency", &tmp); 380 380 if (err) { 381 - pr_err("timing %s: failed to read rate\n", node->full_name); 381 + pr_err("timing %pOF: failed to read rate\n", node); 382 382 return err; 383 383 } 384 384 ··· 386 386 387 387 err = of_property_read_u32(node, "nvidia,parent-clock-frequency", &tmp); 388 388 if (err) { 389 - pr_err("timing %s: failed to read parent rate\n", 390 - node->full_name); 389 + pr_err("timing %pOF: failed to read parent rate\n", node); 391 390 return err; 392 391 } 393 392 ··· 394 395 395 396 timing->parent = of_clk_get_by_name(node, "emc-parent"); 396 397 if (IS_ERR(timing->parent)) { 397 - pr_err("timing %s: failed to get parent clock\n", 398 - node->full_name); 398 + pr_err("timing %pOF: failed to get parent clock\n", node); 399 399 return PTR_ERR(timing->parent); 400 400 } 401 401 ··· 407 409 } 408 410 } 409 411 if (timing->parent_index == 0xff) { 410 - pr_err("timing %s: %s is not a valid parent\n", 411 - node->full_name, __clk_get_name(timing->parent)); 412 + pr_err("timing %pOF: %s is not a valid parent\n", 413 + node, __clk_get_name(timing->parent)); 412 414 clk_put(timing->parent); 413 415 return -EINVAL; 414 416 }
+38 -121
drivers/clk/tegra/clk-pll.c
··· 363 363 val = pll_readl(pll->params->iddq_reg, pll); 364 364 val &= ~BIT(pll->params->iddq_bit_idx); 365 365 pll_writel(val, pll->params->iddq_reg, pll); 366 - udelay(2); 366 + udelay(5); 367 367 } 368 368 369 369 if (pll->params->reset_reg) { ··· 418 418 } 419 419 } 420 420 421 + static void pll_clk_start_ss(struct tegra_clk_pll *pll) 422 + { 423 + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { 424 + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); 425 + 426 + val |= pll->params->ssc_ctrl_en_mask; 427 + pll_writel(val, pll->params->ssc_ctrl_reg, pll); 428 + } 429 + } 430 + 431 + static void pll_clk_stop_ss(struct tegra_clk_pll *pll) 432 + { 433 + if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { 434 + u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); 435 + 436 + val &= ~pll->params->ssc_ctrl_en_mask; 437 + pll_writel(val, pll->params->ssc_ctrl_reg, pll); 438 + } 439 + } 440 + 421 441 static int clk_pll_enable(struct clk_hw *hw) 422 442 { 423 443 struct tegra_clk_pll *pll = to_clk_pll(hw); ··· 450 430 _clk_pll_enable(hw); 451 431 452 432 ret = clk_pll_wait_for_lock(pll); 433 + 434 + pll_clk_start_ss(pll); 453 435 454 436 if (pll->lock) 455 437 spin_unlock_irqrestore(pll->lock, flags); ··· 466 444 467 445 if (pll->lock) 468 446 spin_lock_irqsave(pll->lock, flags); 447 + 448 + pll_clk_stop_ss(pll); 469 449 470 450 _clk_pll_disable(hw); 471 451 ··· 690 666 struct tegra_clk_pll_params *params = pll->params; 691 667 struct div_nmp *div_nmp = params->div_nmp; 692 668 669 + *cfg = (struct tegra_clk_pll_freq_table) { }; 670 + 693 671 if ((params->flags & (TEGRA_PLLM | TEGRA_PLLMB)) && 694 672 (pll_override_readl(PMC_PLLP_WB0_OVERRIDE, pll) & 695 673 PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)) { ··· 740 714 } 741 715 742 716 pll_writel_misc(val, pll); 743 - } 744 - 745 - static void pll_clk_start_ss(struct tegra_clk_pll *pll) 746 - { 747 - if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { 748 - u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); 749 - 750 - val |= pll->params->ssc_ctrl_en_mask; 751 - pll_writel(val, pll->params->ssc_ctrl_reg, pll); 752 - } 753 - } 754 - 755 - static void pll_clk_stop_ss(struct tegra_clk_pll *pll) 756 - { 757 - if (pll->params->defaults_set && pll->params->ssc_ctrl_reg) { 758 - u32 val = pll_readl(pll->params->ssc_ctrl_reg, pll); 759 - 760 - val &= ~pll->params->ssc_ctrl_en_mask; 761 - pll_writel(val, pll->params->ssc_ctrl_reg, pll); 762 - } 763 717 } 764 718 765 719 static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg, ··· 2257 2251 } 2258 2252 #endif 2259 2253 2260 - #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) 2254 + #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) || defined(CONFIG_ARCH_TEGRA_210_SOC) 2261 2255 static const struct clk_ops tegra_clk_pllss_ops = { 2262 2256 .is_enabled = clk_pll_is_enabled, 2263 2257 .enable = clk_pll_enable, ··· 2355 2349 struct tegra_clk_pll_params *pll_params, 2356 2350 spinlock_t *lock, unsigned long parent_rate) 2357 2351 { 2358 - u32 val; 2359 2352 struct tegra_clk_pll *pll; 2360 2353 struct clk *clk; 2361 2354 ··· 2368 2363 if (IS_ERR(pll)) 2369 2364 return ERR_CAST(pll); 2370 2365 2371 - /* program minimum rate by default */ 2372 - 2373 - val = pll_readl_base(pll); 2374 - if (val & PLL_BASE_ENABLE) 2375 - WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) & 2376 - BIT(pll_params->iddq_bit_idx)); 2377 - else { 2378 - val = 0x4 << divm_shift(pll); 2379 - val |= 0x41 << divn_shift(pll); 2380 - pll_writel_base(val, pll); 2381 - } 2382 - 2383 - /* disable lock override */ 2384 - 2385 - val = pll_readl_misc(pll); 2386 - val &= ~BIT(29); 2387 - pll_writel_misc(val, pll); 2388 - 2389 2366 clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2390 - &tegra_clk_pllre_ops); 2367 + &tegra_clk_pll_ops); 2391 2368 if (IS_ERR(clk)) 2392 2369 kfree(pll); 2393 2370 ··· 2591 2604 return clk; 2592 2605 } 2593 2606 2594 - struct clk *tegra_clk_register_pllxc_tegra210(const char *name, 2595 - const char *parent_name, void __iomem *clk_base, 2596 - void __iomem *pmc, unsigned long flags, 2597 - struct tegra_clk_pll_params *pll_params, 2598 - spinlock_t *lock) 2599 - { 2600 - struct tegra_clk_pll *pll; 2601 - struct clk *clk, *parent; 2602 - unsigned long parent_rate; 2603 - 2604 - parent = __clk_lookup(parent_name); 2605 - if (!parent) { 2606 - WARN(1, "parent clk %s of %s must be registered first\n", 2607 - name, parent_name); 2608 - return ERR_PTR(-EINVAL); 2609 - } 2610 - 2611 - if (!pll_params->pdiv_tohw) 2612 - return ERR_PTR(-EINVAL); 2613 - 2614 - parent_rate = clk_get_rate(parent); 2615 - 2616 - pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); 2617 - 2618 - if (pll_params->adjust_vco) 2619 - pll_params->vco_min = pll_params->adjust_vco(pll_params, 2620 - parent_rate); 2621 - 2622 - pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); 2623 - if (IS_ERR(pll)) 2624 - return ERR_CAST(pll); 2625 - 2626 - clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2627 - &tegra_clk_pll_ops); 2628 - if (IS_ERR(clk)) 2629 - kfree(pll); 2630 - 2631 - return clk; 2632 - } 2633 - 2634 2607 struct clk *tegra_clk_register_pllss_tegra210(const char *name, 2635 2608 const char *parent_name, void __iomem *clk_base, 2636 2609 unsigned long flags, ··· 2599 2652 { 2600 2653 struct tegra_clk_pll *pll; 2601 2654 struct clk *clk, *parent; 2602 - struct tegra_clk_pll_freq_table cfg; 2603 2655 unsigned long parent_rate; 2604 2656 u32 val; 2605 - int i; 2606 2657 2607 2658 if (!pll_params->div_nmp) 2608 2659 return ERR_PTR(-EINVAL); ··· 2612 2667 return ERR_PTR(-EINVAL); 2613 2668 } 2614 2669 2615 - pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); 2616 - if (IS_ERR(pll)) 2617 - return ERR_CAST(pll); 2618 - 2619 - val = pll_readl_base(pll); 2620 - val &= ~PLLSS_REF_SRC_SEL_MASK; 2621 - pll_writel_base(val, pll); 2670 + val = readl_relaxed(clk_base + pll_params->base_reg); 2671 + if (val & PLLSS_REF_SRC_SEL_MASK) { 2672 + WARN(1, "not supported reference clock for %s\n", name); 2673 + return ERR_PTR(-EINVAL); 2674 + } 2622 2675 2623 2676 parent_rate = clk_get_rate(parent); 2624 2677 ··· 2626 2683 pll_params->vco_min = pll_params->adjust_vco(pll_params, 2627 2684 parent_rate); 2628 2685 2629 - /* initialize PLL to minimum rate */ 2630 - 2631 - cfg.m = _pll_fixed_mdiv(pll_params, parent_rate); 2632 - cfg.n = cfg.m * pll_params->vco_min / parent_rate; 2633 - 2634 - for (i = 0; pll_params->pdiv_tohw[i].pdiv; i++) 2635 - ; 2636 - if (!i) { 2637 - kfree(pll); 2638 - return ERR_PTR(-EINVAL); 2639 - } 2640 - 2641 - cfg.p = pll_params->pdiv_tohw[i-1].hw_val; 2642 - 2643 - _update_pll_mnp(pll, &cfg); 2644 - 2645 - pll_writel_misc(PLLSS_MISC_DEFAULT, pll); 2646 - 2647 - val = pll_readl_base(pll); 2648 - if (val & PLL_BASE_ENABLE) { 2649 - if (val & BIT(pll_params->iddq_bit_idx)) { 2650 - WARN(1, "%s is on but IDDQ set\n", name); 2651 - kfree(pll); 2652 - return ERR_PTR(-EINVAL); 2653 - } 2654 - } else 2655 - val |= BIT(pll_params->iddq_bit_idx); 2656 - 2657 - val &= ~PLLSS_LOCK_OVERRIDE; 2658 - pll_writel_base(val, pll); 2686 + pll_params->flags |= TEGRA_PLL_BYPASS; 2687 + pll = _tegra_init_pll(clk_base, NULL, pll_params, lock); 2688 + if (IS_ERR(pll)) 2689 + return ERR_CAST(pll); 2659 2690 2660 2691 clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2661 2692 &tegra_clk_pll_ops);
+2 -1
drivers/clk/tegra/clk-tegra-periph.c
··· 216 216 _clk_num, _clk_id) \ 217 217 TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ 218 218 30, MASK(2), 0, 0, 16, 0, TEGRA_DIVIDER_ROUND_UP,\ 219 - _clk_num, 0, _clk_id, _parents##_idx, 0, NULL) 219 + _clk_num, TEGRA_PERIPH_ON_APB, _clk_id, \ 220 + _parents##_idx, 0, NULL) 220 221 221 222 #define XUSB(_name, _parents, _offset, \ 222 223 _clk_num, _gate_flags, _clk_id) \
+9 -2
drivers/clk/tegra/clk-tegra-super-gen4.c
··· 232 232 if (!dt_clk) 233 233 return; 234 234 235 - clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, 236 - pmc_base, CLK_IGNORE_UNUSED, params, NULL); 235 + #if defined(CONFIG_ARCH_TEGRA_210_SOC) 236 + if (gen_info->gen == gen5) 237 + clk = tegra_clk_register_pllc_tegra210("pll_x", "pll_ref", 238 + clk_base, pmc_base, CLK_IGNORE_UNUSED, params, NULL); 239 + else 240 + #endif 241 + clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base, 242 + pmc_base, CLK_IGNORE_UNUSED, params, NULL); 243 + 237 244 *dt_clk = clk; 238 245 239 246 /* PLLX_OUT0 */
+18 -14
drivers/clk/tegra/clk-tegra210.c
··· 146 146 #define PLLD_SDM_EN_MASK BIT(16) 147 147 148 148 #define PLLD2_SDM_EN_MASK BIT(31) 149 - #define PLLD2_SSC_EN_MASK BIT(30) 149 + #define PLLD2_SSC_EN_MASK 0 150 150 151 151 #define PLLDP_SS_CFG 0x598 152 152 #define PLLDP_SDM_EN_MASK BIT(31) ··· 241 241 #define PLL_SDM_COEFF BIT(13) 242 242 #define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU)) 243 243 #define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat) 244 + /* This macro returns ndiv effective scaled to SDM range */ 245 + #define sdin_get_n_eff(cfg) ((cfg)->n * PLL_SDM_COEFF + ((cfg)->sdm_data ? \ 246 + (PLL_SDM_COEFF/2 + sdin_data_to_din((cfg)->sdm_data)) : 0)) 244 247 245 248 /* Tegra CPU clock and reset control regs */ 246 249 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 ··· 718 715 plldss->params->defaults_set = true; 719 716 720 717 if (val & PLL_ENABLE) { 721 - pr_warn("%s already enabled. Postponing set full defaults\n", 722 - pll_name); 723 718 724 719 /* 725 720 * PLL is ON: check if defaults already set, then set those ··· 755 754 default_val, PLLDSS_MISC1_CFG_WRITE_MASK & 756 755 (~PLLDSS_MISC1_CFG_EN_SDM)); 757 756 } 757 + 758 + if (!plldss->params->defaults_set) 759 + pr_warn("%s already enabled. Postponing set full defaults\n", 760 + pll_name); 758 761 759 762 /* Enable lock detect */ 760 763 if (val & PLLDSS_BASE_LOCK_OVERRIDE) { ··· 1293 1288 s -= PLL_SDM_COEFF / 2; 1294 1289 cfg->sdm_data = sdin_din_to_data(s); 1295 1290 } 1296 - cfg->output_rate *= cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + 1297 - sdin_data_to_din(cfg->sdm_data); 1291 + cfg->output_rate *= sdin_get_n_eff(cfg); 1298 1292 cfg->output_rate /= p * cfg->m * PLL_SDM_COEFF; 1299 1293 } else { 1300 1294 cfg->output_rate *= cfg->n; ··· 1318 1314 */ 1319 1315 static void tegra210_clk_pll_set_gain(struct tegra_clk_pll_freq_table *cfg) 1320 1316 { 1321 - cfg->n = cfg->n * PLL_SDM_COEFF + PLL_SDM_COEFF/2 + 1322 - sdin_data_to_din(cfg->sdm_data); 1317 + cfg->n = sdin_get_n_eff(cfg); 1323 1318 cfg->m *= PLL_SDM_COEFF; 1324 1319 } 1325 1320 ··· 2207 2204 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, 2208 2205 [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, 2209 2206 [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, 2210 - [tegra_clk_vfir] = { .dt_id = TEGRA210_CLK_VFIR, .present = true }, 2211 2207 [tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true }, 2212 2208 [tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true }, 2213 2209 [tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true }, ··· 2472 2470 reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count); 2473 2471 2474 2472 reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0); 2475 - 2476 2473 reg |= 2477 2474 UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].active_delay_count); 2478 2475 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2); 2479 2476 2480 2477 /* Program UTMIP PLL delay and oscillator frequency counts */ 2481 2478 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1); 2482 - reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); 2483 2479 2480 + reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0); 2484 2481 reg |= 2485 2482 UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].enable_delay_count); 2486 2483 ··· 2495 2494 reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN; 2496 2495 reg |= UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP; 2497 2496 writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1); 2498 - udelay(1); 2497 + 2498 + udelay(20); 2499 2499 2500 2500 /* Enable samplers for SNPS, XUSB_HOST, XUSB_DEV */ 2501 2501 reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2); ··· 2554 2552 reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); 2555 2553 reg &= ~BIT(pllu.params->iddq_bit_idx); 2556 2554 writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); 2555 + udelay(5); 2557 2556 2558 2557 reg = readl_relaxed(clk_base + PLLU_BASE); 2559 2558 reg &= ~GENMASK(20, 0); ··· 2562 2559 reg |= fentry->n << 8; 2563 2560 reg |= fentry->p << 16; 2564 2561 writel(reg, clk_base + PLLU_BASE); 2562 + udelay(1); 2565 2563 reg |= PLL_ENABLE; 2566 2564 writel(reg, clk_base + PLLU_BASE); 2567 2565 ··· 2703 2699 struct clk *clk; 2704 2700 2705 2701 /* PLLC */ 2706 - clk = tegra_clk_register_pllxc_tegra210("pll_c", "pll_ref", clk_base, 2702 + clk = tegra_clk_register_pllc_tegra210("pll_c", "pll_ref", clk_base, 2707 2703 pmc, 0, &pll_c_params, NULL); 2708 2704 if (!WARN_ON(IS_ERR(clk))) 2709 2705 clk_register_clkdev(clk, "pll_c", NULL); ··· 2802 2798 /* PLLU_60M */ 2803 2799 clk = clk_register_gate(NULL, "pll_u_60M", "pll_u_out2", 2804 2800 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 2805 - 23, 0, NULL); 2801 + 23, 0, &pll_u_lock); 2806 2802 clk_register_clkdev(clk, "pll_u_60M", NULL); 2807 2803 clks[TEGRA210_CLK_PLL_U_60M] = clk; 2808 2804 2809 2805 /* PLLU_48M */ 2810 2806 clk = clk_register_gate(NULL, "pll_u_48M", "pll_u_out1", 2811 2807 CLK_SET_RATE_PARENT, clk_base + PLLU_BASE, 2812 - 25, 0, NULL); 2808 + 25, 0, &pll_u_lock); 2813 2809 clk_register_clkdev(clk, "pll_u_48M", NULL); 2814 2810 clks[TEGRA210_CLK_PLL_U_48M] = clk; 2815 2811
-6
drivers/clk/tegra/clk.h
··· 362 362 struct tegra_clk_pll_params *pll_params, 363 363 spinlock_t *lock); 364 364 365 - struct clk *tegra_clk_register_pllxc_tegra210(const char *name, 366 - const char *parent_name, void __iomem *clk_base, 367 - void __iomem *pmc, unsigned long flags, 368 - struct tegra_clk_pll_params *pll_params, 369 - spinlock_t *lock); 370 - 371 365 struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name, 372 366 void __iomem *clk_base, void __iomem *pmc, 373 367 unsigned long flags,
+2 -2
drivers/clk/ti/adpll.c
··· 222 222 223 223 /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ 224 224 postfix = strrchr(name, '.'); 225 - if (strlen(postfix) > 1) { 225 + if (postfix && strlen(postfix) > 1) { 226 226 if (strlen(postfix) > ADPLL_MAX_CON_ID) 227 227 dev_warn(d->dev, "clock %s con_id lookup may fail\n", 228 228 name); ··· 486 486 return 0; 487 487 } 488 488 489 - static struct clk_ops ti_adpll_ops = { 489 + static const struct clk_ops ti_adpll_ops = { 490 490 .prepare = ti_adpll_prepare, 491 491 .unprepare = ti_adpll_unprepare, 492 492 .is_prepared = ti_adpll_is_prepared,
+1 -1
drivers/clk/ti/apll.c
··· 304 304 ti_clk_ll_ops->clk_writel(v, &ad->control_reg); 305 305 } 306 306 307 - static struct clk_ops omap2_apll_ops = { 307 + static const struct clk_ops omap2_apll_ops = { 308 308 .enable = &omap2_apll_enable, 309 309 .disable = &omap2_apll_disable, 310 310 .is_enabled = &omap2_apll_is_enabled,
+2 -2
drivers/clk/ti/clockdomain.c
··· 138 138 for (i = 0; i < num_clks; i++) { 139 139 clk = of_clk_get(node, i); 140 140 if (IS_ERR(clk)) { 141 - pr_err("%s: Failed get %s' clock nr %d (%ld)\n", 142 - __func__, node->full_name, i, PTR_ERR(clk)); 141 + pr_err("%s: Failed get %pOF' clock nr %d (%ld)\n", 142 + __func__, node, i, PTR_ERR(clk)); 143 143 continue; 144 144 } 145 145 clk_hw = __clk_get_hw(clk);
+2 -2
drivers/clk/ti/fapll.c
··· 268 268 return 0; 269 269 } 270 270 271 - static struct clk_ops ti_fapll_ops = { 271 + static const struct clk_ops ti_fapll_ops = { 272 272 .enable = ti_fapll_enable, 273 273 .disable = ti_fapll_disable, 274 274 .is_enabled = ti_fapll_is_enabled, ··· 478 478 return 0; 479 479 } 480 480 481 - static struct clk_ops ti_fapll_synt_ops = { 481 + static const struct clk_ops ti_fapll_synt_ops = { 482 482 .enable = ti_fapll_synth_enable, 483 483 .disable = ti_fapll_synth_disable, 484 484 .is_enabled = ti_fapll_synth_is_enabled,
+16 -12
drivers/clk/uniphier/clk-uniphier-core.c
··· 111 111 static const struct of_device_id uniphier_clk_match[] = { 112 112 /* System clock */ 113 113 { 114 - .compatible = "socionext,uniphier-sld3-clock", 115 - .data = uniphier_sld3_sys_clk_data, 116 - }, 117 - { 118 114 .compatible = "socionext,uniphier-ld4-clock", 119 115 .data = uniphier_ld4_sys_clk_data, 120 116 }, ··· 138 142 .compatible = "socionext,uniphier-ld20-clock", 139 143 .data = uniphier_ld20_sys_clk_data, 140 144 }, 145 + { 146 + .compatible = "socionext,uniphier-pxs3-clock", 147 + .data = uniphier_pxs3_sys_clk_data, 148 + }, 141 149 /* Media I/O clock, SD clock */ 142 150 { 143 - .compatible = "socionext,uniphier-sld3-mio-clock", 144 - .data = uniphier_sld3_mio_clk_data, 145 - }, 146 - { 147 151 .compatible = "socionext,uniphier-ld4-mio-clock", 148 - .data = uniphier_sld3_mio_clk_data, 152 + .data = uniphier_ld4_mio_clk_data, 149 153 }, 150 154 { 151 155 .compatible = "socionext,uniphier-pro4-mio-clock", 152 - .data = uniphier_sld3_mio_clk_data, 156 + .data = uniphier_ld4_mio_clk_data, 153 157 }, 154 158 { 155 159 .compatible = "socionext,uniphier-sld8-mio-clock", 156 - .data = uniphier_sld3_mio_clk_data, 160 + .data = uniphier_ld4_mio_clk_data, 157 161 }, 158 162 { 159 163 .compatible = "socionext,uniphier-pro5-sd-clock", ··· 165 169 }, 166 170 { 167 171 .compatible = "socionext,uniphier-ld11-mio-clock", 168 - .data = uniphier_sld3_mio_clk_data, 172 + .data = uniphier_ld4_mio_clk_data, 169 173 }, 170 174 { 171 175 .compatible = "socionext,uniphier-ld20-sd-clock", 176 + .data = uniphier_pro5_sd_clk_data, 177 + }, 178 + { 179 + .compatible = "socionext,uniphier-pxs3-sd-clock", 172 180 .data = uniphier_pro5_sd_clk_data, 173 181 }, 174 182 /* Peripheral clock */ ··· 202 202 }, 203 203 { 204 204 .compatible = "socionext,uniphier-ld20-peri-clock", 205 + .data = uniphier_pro4_peri_clk_data, 206 + }, 207 + { 208 + .compatible = "socionext,uniphier-pxs3-peri-clock", 205 209 .data = uniphier_pro4_peri_clk_data, 206 210 }, 207 211 { /* sentinel */ }
+1 -3
drivers/clk/uniphier/clk-uniphier-mio.c
··· 76 76 #define UNIPHIER_MIO_CLK_DMAC(idx) \ 77 77 UNIPHIER_CLK_GATE("miodmac", (idx), "stdmac", 0x20, 25) 78 78 79 - const struct uniphier_clk_data uniphier_sld3_mio_clk_data[] = { 79 + const struct uniphier_clk_data uniphier_ld4_mio_clk_data[] = { 80 80 UNIPHIER_MIO_CLK_SD_FIXED, 81 81 UNIPHIER_MIO_CLK_SD(0, 0), 82 82 UNIPHIER_MIO_CLK_SD(1, 1), ··· 85 85 UNIPHIER_MIO_CLK_USB2(8, 0), 86 86 UNIPHIER_MIO_CLK_USB2(9, 1), 87 87 UNIPHIER_MIO_CLK_USB2(10, 2), 88 - UNIPHIER_MIO_CLK_USB2(11, 3), 89 88 UNIPHIER_MIO_CLK_USB2_PHY(12, 0), 90 89 UNIPHIER_MIO_CLK_USB2_PHY(13, 1), 91 90 UNIPHIER_MIO_CLK_USB2_PHY(14, 2), 92 - UNIPHIER_MIO_CLK_USB2_PHY(15, 3), 93 91 { /* sentinel */ } 94 92 }; 95 93
+71 -27
drivers/clk/uniphier/clk-uniphier-sys.c
··· 17 17 18 18 #include "clk-uniphier.h" 19 19 20 - #define UNIPHIER_SLD3_SYS_CLK_SD \ 20 + #define UNIPHIER_LD4_SYS_CLK_SD \ 21 21 UNIPHIER_CLK_FACTOR("sd-200m", -1, "spll", 1, 8), \ 22 22 UNIPHIER_CLK_FACTOR("sd-133m", -1, "vpll27a", 1, 2) 23 23 ··· 30 30 UNIPHIER_CLK_FACTOR("sd-133m", -1, "spll", 1, 15) 31 31 32 32 /* Denali driver requires clk_x rate (clk: 50MHz, clk_x & ecc_clk: 200MHz) */ 33 - #define UNIPHIER_SLD3_SYS_CLK_NAND(idx) \ 33 + #define UNIPHIER_LD4_SYS_CLK_NAND(idx) \ 34 34 UNIPHIER_CLK_FACTOR("nand-200m", -1, "spll", 1, 8), \ 35 35 UNIPHIER_CLK_GATE("nand", (idx), "nand-200m", 0x2104, 2) 36 36 ··· 45 45 #define UNIPHIER_LD11_SYS_CLK_EMMC(idx) \ 46 46 UNIPHIER_CLK_GATE("emmc", (idx), NULL, 0x210c, 2) 47 47 48 - #define UNIPHIER_SLD3_SYS_CLK_STDMAC(idx) \ 48 + #define UNIPHIER_LD4_SYS_CLK_STDMAC(idx) \ 49 49 UNIPHIER_CLK_GATE("stdmac", (idx), NULL, 0x2104, 10) 50 50 51 51 #define UNIPHIER_LD11_SYS_CLK_STDMAC(idx) \ ··· 57 57 #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch) \ 58 58 UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch)) 59 59 60 - const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = { 61 - UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ 62 - UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512), /* 288 MHz */ 63 - UNIPHIER_CLK_FACTOR("a2pll", -1, "ref", 24, 1), /* 589.824 MHz */ 64 - UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 65 - UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 66 - UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 67 - UNIPHIER_SLD3_SYS_CLK_NAND(2), 68 - UNIPHIER_SLD3_SYS_CLK_SD, 69 - UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 70 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), 71 - { /* sentinel */ } 72 - }; 60 + #define UNIPHIER_LD11_SYS_CLK_AIO(idx) \ 61 + UNIPHIER_CLK_FACTOR("aio-io200m", -1, "spll", 1, 10), \ 62 + UNIPHIER_CLK_GATE("aio", (idx), "aio-io200m", 0x2108, 0) 63 + 64 + #define UNIPHIER_LD11_SYS_CLK_EVEA(idx) \ 65 + UNIPHIER_CLK_FACTOR("evea-io100m", -1, "spll", 1, 20), \ 66 + UNIPHIER_CLK_GATE("evea", (idx), "evea-io100m", 0x2108, 1) 67 + 68 + #define UNIPHIER_LD11_SYS_CLK_EXIV(idx) \ 69 + UNIPHIER_CLK_FACTOR("exiv-io200m", -1, "spll", 1, 10), \ 70 + UNIPHIER_CLK_GATE("exiv", (idx), "exiv-io200m", 0x2110, 2) 71 + 72 + #define UNIPHIER_PRO4_SYS_CLK_ETHER(idx) \ 73 + UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x2104, 12) 74 + 75 + #define UNIPHIER_LD11_SYS_CLK_ETHER(idx) \ 76 + UNIPHIER_CLK_GATE("ether", (idx), NULL, 0x210c, 6) 73 77 74 78 const struct uniphier_clk_data uniphier_ld4_sys_clk_data[] = { 75 79 UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1), /* 1597.44 MHz */ ··· 82 78 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 5625, 512), /* 270 MHz */ 83 79 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 16), 84 80 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 85 - UNIPHIER_SLD3_SYS_CLK_NAND(2), 86 - UNIPHIER_SLD3_SYS_CLK_SD, 81 + UNIPHIER_LD4_SYS_CLK_NAND(2), 82 + UNIPHIER_LD4_SYS_CLK_SD, 87 83 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 88 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 84 + UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 89 85 { /* sentinel */ } 90 86 }; 91 87 ··· 96 92 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 97 93 UNIPHIER_CLK_FACTOR("uart", 0, "a2pll", 1, 8), 98 94 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 32), 99 - UNIPHIER_SLD3_SYS_CLK_NAND(2), 100 - UNIPHIER_SLD3_SYS_CLK_SD, 95 + UNIPHIER_LD4_SYS_CLK_NAND(2), 96 + UNIPHIER_LD4_SYS_CLK_SD, 101 97 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 102 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ 98 + UNIPHIER_PRO4_SYS_CLK_ETHER(6), 99 + UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, MIO, RLE */ 103 100 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* Ether, SATA, USB3 */ 104 101 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 105 102 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), ··· 113 108 UNIPHIER_CLK_FACTOR("vpll27a", -1, "ref", 270, 25), /* 270 MHz */ 114 109 UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 20), 115 110 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 16), 116 - UNIPHIER_SLD3_SYS_CLK_NAND(2), 117 - UNIPHIER_SLD3_SYS_CLK_SD, 111 + UNIPHIER_LD4_SYS_CLK_NAND(2), 112 + UNIPHIER_LD4_SYS_CLK_SD, 118 113 UNIPHIER_CLK_FACTOR("usb2", -1, "upll", 1, 12), 119 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 114 + UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* Ether, HSC, MIO */ 120 115 { /* sentinel */ } 121 116 }; 122 117 ··· 128 123 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 129 124 UNIPHIER_PRO5_SYS_CLK_NAND(2), 130 125 UNIPHIER_PRO5_SYS_CLK_SD, 131 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC */ 126 + UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC */ 132 127 UNIPHIER_PRO4_SYS_CLK_GIO(12), /* PCIe, USB3 */ 133 128 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 134 129 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), ··· 141 136 UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48), 142 137 UNIPHIER_PRO5_SYS_CLK_NAND(2), 143 138 UNIPHIER_PRO5_SYS_CLK_SD, 144 - UNIPHIER_SLD3_SYS_CLK_STDMAC(8), /* HSC, RLE */ 139 + UNIPHIER_PRO4_SYS_CLK_ETHER(6), 140 + UNIPHIER_LD4_SYS_CLK_STDMAC(8), /* HSC, RLE */ 145 141 /* GIO is always clock-enabled: no function for 0x2104 bit6 */ 146 142 UNIPHIER_PRO4_SYS_CLK_USB3(14, 0), 147 143 UNIPHIER_PRO4_SYS_CLK_USB3(15, 1), ··· 162 156 UNIPHIER_LD11_SYS_CLK_NAND(2), 163 157 UNIPHIER_LD11_SYS_CLK_EMMC(4), 164 158 /* Index 5 reserved for eMMC PHY */ 159 + UNIPHIER_LD11_SYS_CLK_ETHER(6), 165 160 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC, MIO */ 166 161 UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25), 162 + UNIPHIER_LD11_SYS_CLK_AIO(40), 163 + UNIPHIER_LD11_SYS_CLK_EVEA(41), 164 + UNIPHIER_LD11_SYS_CLK_EXIV(42), 167 165 /* CPU gears */ 168 166 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), 169 167 UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8), ··· 195 185 UNIPHIER_LD11_SYS_CLK_EMMC(4), 196 186 /* Index 5 reserved for eMMC PHY */ 197 187 UNIPHIER_LD20_SYS_CLK_SD, 188 + UNIPHIER_LD11_SYS_CLK_ETHER(6), 198 189 UNIPHIER_LD11_SYS_CLK_STDMAC(8), /* HSC */ 199 190 /* GIO is always clock-enabled: no function for 0x210c bit5 */ 200 191 /* ··· 205 194 UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14), 206 195 UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12), 207 196 UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13), 197 + UNIPHIER_LD11_SYS_CLK_AIO(40), 198 + UNIPHIER_LD11_SYS_CLK_EVEA(41), 199 + UNIPHIER_LD11_SYS_CLK_EXIV(42), 208 200 /* CPU gears */ 209 201 UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), 210 202 UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), ··· 215 201 UNIPHIER_CLK_CPUGEAR("cpu-ca72", 32, 0x8000, 0xf, 8, 216 202 "cpll/2", "spll/2", "cpll/3", "spll/3", 217 203 "spll/4", "spll/8", "cpll/4", "cpll/8"), 204 + UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8, 205 + "cpll/2", "spll/2", "cpll/3", "spll/3", 206 + "spll/4", "spll/8", "cpll/4", "cpll/8"), 207 + UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8, 208 + "s2pll/2", "spll/2", "s2pll/3", "spll/3", 209 + "spll/4", "spll/8", "s2pll/4", "s2pll/8"), 210 + { /* sentinel */ } 211 + }; 212 + 213 + const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[] = { 214 + UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 104, 1), /* ARM: 2600 MHz */ 215 + UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1), /* 2000 MHz */ 216 + UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1), /* IPP: 2400 MHz */ 217 + UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34), 218 + UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40), 219 + UNIPHIER_LD20_SYS_CLK_SD, 220 + UNIPHIER_LD11_SYS_CLK_NAND(2), 221 + UNIPHIER_LD11_SYS_CLK_EMMC(4), 222 + UNIPHIER_CLK_GATE("usb30", 12, NULL, 0x2104, 4), /* =GIO0 */ 223 + UNIPHIER_CLK_GATE("usb31-0", 13, NULL, 0x2104, 5), /* =GIO1 */ 224 + UNIPHIER_CLK_GATE("usb31-1", 14, NULL, 0x2104, 6), /* =GIO1-1 */ 225 + UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 16), 226 + UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 18), 227 + UNIPHIER_CLK_GATE("usb30-phy2", 18, NULL, 0x210c, 20), 228 + UNIPHIER_CLK_GATE("usb31-phy0", 20, NULL, 0x210c, 17), 229 + UNIPHIER_CLK_GATE("usb31-phy1", 21, NULL, 0x210c, 19), 230 + /* CPU gears */ 231 + UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8), 232 + UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8), 233 + UNIPHIER_CLK_DIV4("s2pll", 2, 3, 4, 8), 218 234 UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8, 219 235 "cpll/2", "spll/2", "cpll/3", "spll/3", 220 236 "spll/4", "spll/8", "cpll/4", "cpll/8"),
+2 -2
drivers/clk/uniphier/clk-uniphier.h
··· 147 147 const char *name, 148 148 const struct uniphier_clk_mux_data *data); 149 149 150 - extern const struct uniphier_clk_data uniphier_sld3_sys_clk_data[]; 151 150 extern const struct uniphier_clk_data uniphier_ld4_sys_clk_data[]; 152 151 extern const struct uniphier_clk_data uniphier_pro4_sys_clk_data[]; 153 152 extern const struct uniphier_clk_data uniphier_sld8_sys_clk_data[]; ··· 154 155 extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[]; 155 156 extern const struct uniphier_clk_data uniphier_ld11_sys_clk_data[]; 156 157 extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[]; 157 - extern const struct uniphier_clk_data uniphier_sld3_mio_clk_data[]; 158 + extern const struct uniphier_clk_data uniphier_pxs3_sys_clk_data[]; 159 + extern const struct uniphier_clk_data uniphier_ld4_mio_clk_data[]; 158 160 extern const struct uniphier_clk_data uniphier_pro5_sd_clk_data[]; 159 161 extern const struct uniphier_clk_data uniphier_ld4_peri_clk_data[]; 160 162 extern const struct uniphier_clk_data uniphier_pro4_peri_clk_data[];
+3 -3
drivers/clk/ux500/clk-prcc.c
··· 79 79 return clk->is_enabled; 80 80 } 81 81 82 - static struct clk_ops clk_prcc_pclk_ops = { 82 + static const struct clk_ops clk_prcc_pclk_ops = { 83 83 .enable = clk_prcc_pclk_enable, 84 84 .disable = clk_prcc_pclk_disable, 85 85 .is_enabled = clk_prcc_is_enabled, 86 86 }; 87 87 88 - static struct clk_ops clk_prcc_kclk_ops = { 88 + static const struct clk_ops clk_prcc_kclk_ops = { 89 89 .enable = clk_prcc_kclk_enable, 90 90 .disable = clk_prcc_kclk_disable, 91 91 .is_enabled = clk_prcc_is_enabled, ··· 96 96 resource_size_t phy_base, 97 97 u32 cg_sel, 98 98 unsigned long flags, 99 - struct clk_ops *clk_prcc_ops) 99 + const struct clk_ops *clk_prcc_ops) 100 100 { 101 101 struct clk_prcc *clk; 102 102 struct clk_init_data clk_prcc_init;
+7 -7
drivers/clk/ux500/clk-prcmu.c
··· 186 186 clk->is_prepared = 0; 187 187 } 188 188 189 - static struct clk_ops clk_prcmu_scalable_ops = { 189 + static const struct clk_ops clk_prcmu_scalable_ops = { 190 190 .prepare = clk_prcmu_prepare, 191 191 .unprepare = clk_prcmu_unprepare, 192 192 .is_prepared = clk_prcmu_is_prepared, ··· 198 198 .set_rate = clk_prcmu_set_rate, 199 199 }; 200 200 201 - static struct clk_ops clk_prcmu_gate_ops = { 201 + static const struct clk_ops clk_prcmu_gate_ops = { 202 202 .prepare = clk_prcmu_prepare, 203 203 .unprepare = clk_prcmu_unprepare, 204 204 .is_prepared = clk_prcmu_is_prepared, ··· 208 208 .recalc_rate = clk_prcmu_recalc_rate, 209 209 }; 210 210 211 - static struct clk_ops clk_prcmu_scalable_rate_ops = { 211 + static const struct clk_ops clk_prcmu_scalable_rate_ops = { 212 212 .is_enabled = clk_prcmu_is_enabled, 213 213 .recalc_rate = clk_prcmu_recalc_rate, 214 214 .round_rate = clk_prcmu_round_rate, 215 215 .set_rate = clk_prcmu_set_rate, 216 216 }; 217 217 218 - static struct clk_ops clk_prcmu_rate_ops = { 218 + static const struct clk_ops clk_prcmu_rate_ops = { 219 219 .is_enabled = clk_prcmu_is_enabled, 220 220 .recalc_rate = clk_prcmu_recalc_rate, 221 221 }; 222 222 223 - static struct clk_ops clk_prcmu_opp_gate_ops = { 223 + static const struct clk_ops clk_prcmu_opp_gate_ops = { 224 224 .prepare = clk_prcmu_opp_prepare, 225 225 .unprepare = clk_prcmu_opp_unprepare, 226 226 .is_prepared = clk_prcmu_is_prepared, ··· 230 230 .recalc_rate = clk_prcmu_recalc_rate, 231 231 }; 232 232 233 - static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { 233 + static const struct clk_ops clk_prcmu_opp_volt_scalable_ops = { 234 234 .prepare = clk_prcmu_opp_volt_prepare, 235 235 .unprepare = clk_prcmu_opp_volt_unprepare, 236 236 .is_prepared = clk_prcmu_is_prepared, ··· 247 247 u8 cg_sel, 248 248 unsigned long rate, 249 249 unsigned long flags, 250 - struct clk_ops *clk_prcmu_ops) 250 + const struct clk_ops *clk_prcmu_ops) 251 251 { 252 252 struct clk_prcmu *clk; 253 253 struct clk_init_data clk_prcmu_init;
+4 -4
drivers/clk/ux500/clk-sysctrl.c
··· 98 98 return clk->parent_index; 99 99 } 100 100 101 - static struct clk_ops clk_sysctrl_gate_ops = { 101 + static const struct clk_ops clk_sysctrl_gate_ops = { 102 102 .prepare = clk_sysctrl_prepare, 103 103 .unprepare = clk_sysctrl_unprepare, 104 104 }; 105 105 106 - static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { 106 + static const struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { 107 107 .prepare = clk_sysctrl_prepare, 108 108 .unprepare = clk_sysctrl_unprepare, 109 109 .recalc_rate = clk_sysctrl_recalc_rate, 110 110 }; 111 111 112 - static struct clk_ops clk_sysctrl_set_parent_ops = { 112 + static const struct clk_ops clk_sysctrl_set_parent_ops = { 113 113 .set_parent = clk_sysctrl_set_parent, 114 114 .get_parent = clk_sysctrl_get_parent, 115 115 }; ··· 124 124 unsigned long rate, 125 125 unsigned long enable_delay_us, 126 126 unsigned long flags, 127 - struct clk_ops *clk_sysctrl_ops) 127 + const struct clk_ops *clk_sysctrl_ops) 128 128 { 129 129 struct clk_sysctrl *clk; 130 130 struct clk_init_data clk_sysctrl_init;
+1 -1
drivers/clk/versatile/clk-vexpress-osc.c
··· 61 61 return regmap_write(osc->reg, 0, rate); 62 62 } 63 63 64 - static struct clk_ops vexpress_osc_ops = { 64 + static const struct clk_ops vexpress_osc_ops = { 65 65 .recalc_rate = vexpress_osc_recalc_rate, 66 66 .round_rate = vexpress_osc_round_rate, 67 67 .set_rate = vexpress_osc_set_rate,
+3 -3
drivers/clk/zte/clk-zx296718.c
··· 451 451 FFACTOR(0, "emmc_mux_div2", "emmc_mux", 1, 2, CLK_SET_RATE_PARENT), 452 452 }; 453 453 454 - static struct clk_div_table noc_div_table[] = { 454 + static const struct clk_div_table noc_div_table[] = { 455 455 { .val = 1, .div = 2, }, 456 456 { .val = 3, .div = 4, }, 457 457 }; ··· 644 644 return 0; 645 645 } 646 646 647 - static struct clk_div_table common_even_div_table[] = { 647 + static const struct clk_div_table common_even_div_table[] = { 648 648 { .val = 0, .div = 1, }, 649 649 { .val = 1, .div = 2, }, 650 650 { .val = 3, .div = 4, }, ··· 656 656 { .val = 15, .div = 16, }, 657 657 }; 658 658 659 - static struct clk_div_table common_div_table[] = { 659 + static const struct clk_div_table common_div_table[] = { 660 660 { .val = 0, .div = 1, }, 661 661 { .val = 1, .div = 2, }, 662 662 { .val = 2, .div = 3, },
+2
include/dt-bindings/clock/qcom,gcc-msm8996.h
··· 233 233 #define GCC_PCIE_CLKREF_CLK 216 234 234 #define GCC_RX2_USB2_CLKREF_CLK 217 235 235 #define GCC_RX1_USB2_CLKREF_CLK 218 236 + #define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 219 237 + #define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 220 236 238 237 239 #define GCC_SYSTEM_NOC_BCR 0 238 240 #define GCC_CONFIG_NOC_BCR 1
+57
include/dt-bindings/clock/r8a77995-cpg-mssr.h
··· 1 + /* 2 + * Copyright (C) 2017 Glider bvba 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 as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + */ 9 + #ifndef __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ 10 + #define __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ 11 + 12 + #include <dt-bindings/clock/renesas-cpg-mssr.h> 13 + 14 + /* r8a77995 CPG Core Clocks */ 15 + #define R8A77995_CLK_Z2 0 16 + #define R8A77995_CLK_ZG 1 17 + #define R8A77995_CLK_ZTR 2 18 + #define R8A77995_CLK_ZT 3 19 + #define R8A77995_CLK_ZX 4 20 + #define R8A77995_CLK_S0D1 5 21 + #define R8A77995_CLK_S1D1 6 22 + #define R8A77995_CLK_S1D2 7 23 + #define R8A77995_CLK_S1D4 8 24 + #define R8A77995_CLK_S2D1 9 25 + #define R8A77995_CLK_S2D2 10 26 + #define R8A77995_CLK_S2D4 11 27 + #define R8A77995_CLK_S3D1 12 28 + #define R8A77995_CLK_S3D2 13 29 + #define R8A77995_CLK_S3D4 14 30 + #define R8A77995_CLK_S1D4C 15 31 + #define R8A77995_CLK_S3D1C 16 32 + #define R8A77995_CLK_S3D2C 17 33 + #define R8A77995_CLK_S3D4C 18 34 + #define R8A77995_CLK_LB 19 35 + #define R8A77995_CLK_CL 20 36 + #define R8A77995_CLK_ZB3 21 37 + #define R8A77995_CLK_ZB3D2 22 38 + #define R8A77995_CLK_CR 23 39 + #define R8A77995_CLK_CRD2 24 40 + #define R8A77995_CLK_SD0H 25 41 + #define R8A77995_CLK_SD0 26 42 + #define R8A77995_CLK_SSP2 27 43 + #define R8A77995_CLK_SSP1 28 44 + #define R8A77995_CLK_RPC 29 45 + #define R8A77995_CLK_RPCD2 30 46 + #define R8A77995_CLK_ZA2 31 47 + #define R8A77995_CLK_ZA8 32 48 + #define R8A77995_CLK_Z2D 33 49 + #define R8A77995_CLK_CANFD 34 50 + #define R8A77995_CLK_MSO 35 51 + #define R8A77995_CLK_R 36 52 + #define R8A77995_CLK_OSC 37 53 + #define R8A77995_CLK_LV0 38 54 + #define R8A77995_CLK_LV1 39 55 + #define R8A77995_CLK_CP 40 56 + 57 + #endif /* __DT_BINDINGS_CLOCK_R8A77995_CPG_MSSR_H__ */
+1
include/dt-bindings/clock/rk3228-cru.h
··· 49 49 #define SCLK_EMMC_DRV 117 50 50 #define SCLK_SDMMC_SAMPLE 118 51 51 #define SCLK_SDIO_SAMPLE 119 52 + #define SCLK_SDIO_SRC 120 52 53 #define SCLK_EMMC_SAMPLE 121 53 54 #define SCLK_VOP 122 54 55 #define SCLK_HDMI_HDCP 123
+5 -3
include/dt-bindings/clock/rv1108-cru.h
··· 67 67 #define SCLK_SPI 108 68 68 #define SCLK_SARADC 109 69 69 #define SCLK_TSADC 110 70 - #define SCLK_MACPHY_PRE 111 71 - #define SCLK_MACPHY 112 72 - #define SCLK_MACPHY_RX 113 70 + #define SCLK_MAC_PRE 111 71 + #define SCLK_MAC 112 72 + #define SCLK_MAC_RX 113 73 73 #define SCLK_MAC_REF 114 74 74 #define SCLK_MAC_REFOUT 115 75 75 #define SCLK_DSP_PFM 116 ··· 110 110 #define ACLK_CIF2 207 111 111 #define ACLK_CIF3 208 112 112 #define ACLK_PERI 209 113 + #define ACLK_GMAC 210 113 114 114 115 /* pclk gates */ 115 116 #define PCLK_GPIO1 256 ··· 142 141 #define PCLK_EFUSE0 282 143 142 #define PCLK_EFUSE1 283 144 143 #define PCLK_WDT 284 144 + #define PCLK_GMAC 285 145 145 146 146 /* hclk gates */ 147 147 #define HCLK_I2S0_8CH 320
+165
include/dt-bindings/clock/stm32h7-clks.h
··· 1 + /* SYS, CORE AND BUS CLOCKS */ 2 + #define SYS_D1CPRE 0 3 + #define HCLK 1 4 + #define PCLK1 2 5 + #define PCLK2 3 6 + #define PCLK3 4 7 + #define PCLK4 5 8 + #define HSI_DIV 6 9 + #define HSE_1M 7 10 + #define I2S_CKIN 8 11 + #define CK_DSI_PHY 9 12 + #define HSE_CK 10 13 + #define LSE_CK 11 14 + #define CSI_KER_DIV122 12 15 + #define RTC_CK 13 16 + #define CPU_SYSTICK 14 17 + 18 + /* OSCILLATOR BANK */ 19 + #define OSC_BANK 18 20 + #define HSI_CK 18 21 + #define HSI_KER_CK 19 22 + #define CSI_CK 20 23 + #define CSI_KER_CK 21 24 + #define RC48_CK 22 25 + #define LSI_CK 23 26 + 27 + /* MCLOCK BANK */ 28 + #define MCLK_BANK 28 29 + #define PER_CK 28 30 + #define PLLSRC 29 31 + #define SYS_CK 30 32 + #define TRACEIN_CK 31 33 + 34 + /* ODF BANK */ 35 + #define ODF_BANK 32 36 + #define PLL1_P 32 37 + #define PLL1_Q 33 38 + #define PLL1_R 34 39 + #define PLL2_P 35 40 + #define PLL2_Q 36 41 + #define PLL2_R 37 42 + #define PLL3_P 38 43 + #define PLL3_Q 39 44 + #define PLL3_R 40 45 + 46 + /* MCO BANK */ 47 + #define MCO_BANK 41 48 + #define MCO1 41 49 + #define MCO2 42 50 + 51 + /* PERIF BANK */ 52 + #define PERIF_BANK 50 53 + #define D1SRAM1_CK 50 54 + #define ITCM_CK 51 55 + #define DTCM2_CK 52 56 + #define DTCM1_CK 53 57 + #define FLITF_CK 54 58 + #define JPGDEC_CK 55 59 + #define DMA2D_CK 56 60 + #define MDMA_CK 57 61 + #define USB2ULPI_CK 58 62 + #define USB1ULPI_CK 59 63 + #define ETH1RX_CK 60 64 + #define ETH1TX_CK 61 65 + #define ETH1MAC_CK 62 66 + #define ART_CK 63 67 + #define DMA2_CK 64 68 + #define DMA1_CK 65 69 + #define D2SRAM3_CK 66 70 + #define D2SRAM2_CK 67 71 + #define D2SRAM1_CK 68 72 + #define HASH_CK 69 73 + #define CRYPT_CK 70 74 + #define CAMITF_CK 71 75 + #define BKPRAM_CK 72 76 + #define HSEM_CK 73 77 + #define BDMA_CK 74 78 + #define CRC_CK 75 79 + #define GPIOK_CK 76 80 + #define GPIOJ_CK 77 81 + #define GPIOI_CK 78 82 + #define GPIOH_CK 79 83 + #define GPIOG_CK 80 84 + #define GPIOF_CK 81 85 + #define GPIOE_CK 82 86 + #define GPIOD_CK 83 87 + #define GPIOC_CK 84 88 + #define GPIOB_CK 85 89 + #define GPIOA_CK 86 90 + #define WWDG1_CK 87 91 + #define DAC12_CK 88 92 + #define WWDG2_CK 89 93 + #define TIM14_CK 90 94 + #define TIM13_CK 91 95 + #define TIM12_CK 92 96 + #define TIM7_CK 93 97 + #define TIM6_CK 94 98 + #define TIM5_CK 95 99 + #define TIM4_CK 96 100 + #define TIM3_CK 97 101 + #define TIM2_CK 98 102 + #define MDIOS_CK 99 103 + #define OPAMP_CK 100 104 + #define CRS_CK 101 105 + #define TIM17_CK 102 106 + #define TIM16_CK 103 107 + #define TIM15_CK 104 108 + #define TIM8_CK 105 109 + #define TIM1_CK 106 110 + #define TMPSENS_CK 107 111 + #define RTCAPB_CK 108 112 + #define VREF_CK 109 113 + #define COMP12_CK 110 114 + #define SYSCFG_CK 111 115 + 116 + /* KERNEL BANK */ 117 + #define KERN_BANK 120 118 + #define SDMMC1_CK 120 119 + #define QUADSPI_CK 121 120 + #define FMC_CK 122 121 + #define USB2OTG_CK 123 122 + #define USB1OTG_CK 124 123 + #define ADC12_CK 125 124 + #define SDMMC2_CK 126 125 + #define RNG_CK 127 126 + #define ADC3_CK 128 127 + #define DSI_CK 129 128 + #define LTDC_CK 130 129 + #define USART8_CK 131 130 + #define USART7_CK 132 131 + #define HDMICEC_CK 133 132 + #define I2C3_CK 134 133 + #define I2C2_CK 135 134 + #define I2C1_CK 136 135 + #define UART5_CK 137 136 + #define UART4_CK 138 137 + #define USART3_CK 139 138 + #define USART2_CK 140 139 + #define SPDIFRX_CK 141 140 + #define SPI3_CK 142 141 + #define SPI2_CK 143 142 + #define LPTIM1_CK 144 143 + #define FDCAN_CK 145 144 + #define SWP_CK 146 145 + #define HRTIM_CK 147 146 + #define DFSDM1_CK 148 147 + #define SAI3_CK 149 148 + #define SAI2_CK 150 149 + #define SAI1_CK 151 150 + #define SPI5_CK 152 151 + #define SPI4_CK 153 152 + #define SPI1_CK 154 153 + #define USART6_CK 155 154 + #define USART1_CK 156 155 + #define SAI4B_CK 157 156 + #define SAI4A_CK 158 157 + #define LPTIM5_CK 159 158 + #define LPTIM4_CK 160 159 + #define LPTIM3_CK 161 160 + #define LPTIM2_CK 162 161 + #define I2C4_CK 163 162 + #define SPI6_CK 164 163 + #define LPUART1_CK 165 164 + 165 + #define STM32H7_MAX_CLKS 166
+200
include/dt-bindings/clock/sun4i-a10-ccu.h
··· 1 + /* 2 + * Copyright (C) 2017 Priit Laes <plaes@plaes.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 39 + * OTHER DEALINGS IN THE SOFTWARE. 40 + */ 41 + 42 + #ifndef _DT_BINDINGS_CLK_SUN4I_A10_H_ 43 + #define _DT_BINDINGS_CLK_SUN4I_A10_H_ 44 + 45 + #define CLK_HOSC 1 46 + #define CLK_CPU 20 47 + 48 + /* AHB Gates */ 49 + #define CLK_AHB_OTG 26 50 + #define CLK_AHB_EHCI0 27 51 + #define CLK_AHB_OHCI0 28 52 + #define CLK_AHB_EHCI1 29 53 + #define CLK_AHB_OHCI1 30 54 + #define CLK_AHB_SS 31 55 + #define CLK_AHB_DMA 32 56 + #define CLK_AHB_BIST 33 57 + #define CLK_AHB_MMC0 34 58 + #define CLK_AHB_MMC1 35 59 + #define CLK_AHB_MMC2 36 60 + #define CLK_AHB_MMC3 37 61 + #define CLK_AHB_MS 38 62 + #define CLK_AHB_NAND 39 63 + #define CLK_AHB_SDRAM 40 64 + #define CLK_AHB_ACE 41 65 + #define CLK_AHB_EMAC 42 66 + #define CLK_AHB_TS 43 67 + #define CLK_AHB_SPI0 44 68 + #define CLK_AHB_SPI1 45 69 + #define CLK_AHB_SPI2 46 70 + #define CLK_AHB_SPI3 47 71 + #define CLK_AHB_PATA 48 72 + #define CLK_AHB_SATA 49 73 + #define CLK_AHB_GPS 50 74 + #define CLK_AHB_HSTIMER 51 75 + #define CLK_AHB_VE 52 76 + #define CLK_AHB_TVD 53 77 + #define CLK_AHB_TVE0 54 78 + #define CLK_AHB_TVE1 55 79 + #define CLK_AHB_LCD0 56 80 + #define CLK_AHB_LCD1 57 81 + #define CLK_AHB_CSI0 58 82 + #define CLK_AHB_CSI1 59 83 + #define CLK_AHB_HDMI0 60 84 + #define CLK_AHB_HDMI1 61 85 + #define CLK_AHB_DE_BE0 62 86 + #define CLK_AHB_DE_BE1 63 87 + #define CLK_AHB_DE_FE0 64 88 + #define CLK_AHB_DE_FE1 65 89 + #define CLK_AHB_GMAC 66 90 + #define CLK_AHB_MP 67 91 + #define CLK_AHB_GPU 68 92 + 93 + /* APB0 Gates */ 94 + #define CLK_APB0_CODEC 69 95 + #define CLK_APB0_SPDIF 70 96 + #define CLK_APB0_I2S0 71 97 + #define CLK_APB0_AC97 72 98 + #define CLK_APB0_I2S1 73 99 + #define CLK_APB0_PIO 74 100 + #define CLK_APB0_IR0 75 101 + #define CLK_APB0_IR1 76 102 + #define CLK_APB0_I2S2 77 103 + #define CLK_APB0_KEYPAD 78 104 + 105 + /* APB1 Gates */ 106 + #define CLK_APB1_I2C0 79 107 + #define CLK_APB1_I2C1 80 108 + #define CLK_APB1_I2C2 81 109 + #define CLK_APB1_I2C3 82 110 + #define CLK_APB1_CAN 83 111 + #define CLK_APB1_SCR 84 112 + #define CLK_APB1_PS20 85 113 + #define CLK_APB1_PS21 86 114 + #define CLK_APB1_I2C4 87 115 + #define CLK_APB1_UART0 88 116 + #define CLK_APB1_UART1 89 117 + #define CLK_APB1_UART2 90 118 + #define CLK_APB1_UART3 91 119 + #define CLK_APB1_UART4 92 120 + #define CLK_APB1_UART5 93 121 + #define CLK_APB1_UART6 94 122 + #define CLK_APB1_UART7 95 123 + 124 + /* IP clocks */ 125 + #define CLK_NAND 96 126 + #define CLK_MS 97 127 + #define CLK_MMC0 98 128 + #define CLK_MMC0_OUTPUT 99 129 + #define CLK_MMC0_SAMPLE 100 130 + #define CLK_MMC1 101 131 + #define CLK_MMC1_OUTPUT 102 132 + #define CLK_MMC1_SAMPLE 103 133 + #define CLK_MMC2 104 134 + #define CLK_MMC2_OUTPUT 105 135 + #define CLK_MMC2_SAMPLE 106 136 + #define CLK_MMC3 107 137 + #define CLK_MMC3_OUTPUT 108 138 + #define CLK_MMC3_SAMPLE 109 139 + #define CLK_TS 110 140 + #define CLK_SS 111 141 + #define CLK_SPI0 112 142 + #define CLK_SPI1 113 143 + #define CLK_SPI2 114 144 + #define CLK_PATA 115 145 + #define CLK_IR0 116 146 + #define CLK_IR1 117 147 + #define CLK_I2S0 118 148 + #define CLK_AC97 119 149 + #define CLK_SPDIF 120 150 + #define CLK_KEYPAD 121 151 + #define CLK_SATA 122 152 + #define CLK_USB_OHCI0 123 153 + #define CLK_USB_OHCI1 124 154 + #define CLK_USB_PHY 125 155 + #define CLK_GPS 126 156 + #define CLK_SPI3 127 157 + #define CLK_I2S1 128 158 + #define CLK_I2S2 129 159 + 160 + /* DRAM Gates */ 161 + #define CLK_DRAM_VE 130 162 + #define CLK_DRAM_CSI0 131 163 + #define CLK_DRAM_CSI1 132 164 + #define CLK_DRAM_TS 133 165 + #define CLK_DRAM_TVD 134 166 + #define CLK_DRAM_TVE0 135 167 + #define CLK_DRAM_TVE1 136 168 + #define CLK_DRAM_OUT 137 169 + #define CLK_DRAM_DE_FE1 138 170 + #define CLK_DRAM_DE_FE0 139 171 + #define CLK_DRAM_DE_BE0 140 172 + #define CLK_DRAM_DE_BE1 141 173 + #define CLK_DRAM_MP 142 174 + #define CLK_DRAM_ACE 143 175 + 176 + /* Display Engine Clocks */ 177 + #define CLK_DE_BE0 144 178 + #define CLK_DE_BE1 145 179 + #define CLK_DE_FE0 146 180 + #define CLK_DE_FE1 147 181 + #define CLK_DE_MP 148 182 + #define CLK_TCON0_CH0 149 183 + #define CLK_TCON1_CH0 150 184 + #define CLK_CSI_SCLK 151 185 + #define CLK_TVD_SCLK2 152 186 + #define CLK_TVD 153 187 + #define CLK_TCON0_CH1_SCLK2 154 188 + #define CLK_TCON0_CH1 155 189 + #define CLK_TCON1_CH1_SCLK2 156 190 + #define CLK_TCON1_CH1 157 191 + #define CLK_CSI0 158 192 + #define CLK_CSI1 159 193 + #define CLK_CODEC 160 194 + #define CLK_VE 161 195 + #define CLK_AVS 162 196 + #define CLK_ACE 163 197 + #define CLK_HDMI 164 198 + #define CLK_GPU 165 199 + 200 + #endif /* _DT_BINDINGS_CLK_SUN4I_A10_H_ */
+53
include/dt-bindings/clock/sun7i-a20-ccu.h
··· 1 + /* 2 + * Copyright (C) 2017 Priit Laes <plaes@plaes.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 39 + * OTHER DEALINGS IN THE SOFTWARE. 40 + */ 41 + 42 + #ifndef _DT_BINDINGS_CLK_SUN7I_A20_H_ 43 + #define _DT_BINDINGS_CLK_SUN7I_A20_H_ 44 + 45 + #include <dt-bindings/clock/sun4i-a10-ccu.h> 46 + 47 + #define CLK_MBUS 166 48 + #define CLK_HDMI1_SLOW 167 49 + #define CLK_HDMI1 168 50 + #define CLK_OUT_A 169 51 + #define CLK_OUT_B 170 52 + 53 + #endif /* _DT_BINDINGS_CLK_SUN7I_A20_H_ */
+187
include/dt-bindings/clock/sun8i-r40-ccu.h
··· 1 + /* 2 + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_ 44 + #define _DT_BINDINGS_CLK_SUN8I_R40_H_ 45 + 46 + #define CLK_CPU 24 47 + 48 + #define CLK_BUS_MIPI_DSI 29 49 + #define CLK_BUS_CE 30 50 + #define CLK_BUS_DMA 31 51 + #define CLK_BUS_MMC0 32 52 + #define CLK_BUS_MMC1 33 53 + #define CLK_BUS_MMC2 34 54 + #define CLK_BUS_MMC3 35 55 + #define CLK_BUS_NAND 36 56 + #define CLK_BUS_DRAM 37 57 + #define CLK_BUS_EMAC 38 58 + #define CLK_BUS_TS 39 59 + #define CLK_BUS_HSTIMER 40 60 + #define CLK_BUS_SPI0 41 61 + #define CLK_BUS_SPI1 42 62 + #define CLK_BUS_SPI2 43 63 + #define CLK_BUS_SPI3 44 64 + #define CLK_BUS_SATA 45 65 + #define CLK_BUS_OTG 46 66 + #define CLK_BUS_EHCI0 47 67 + #define CLK_BUS_EHCI1 48 68 + #define CLK_BUS_EHCI2 49 69 + #define CLK_BUS_OHCI0 50 70 + #define CLK_BUS_OHCI1 51 71 + #define CLK_BUS_OHCI2 52 72 + #define CLK_BUS_VE 53 73 + #define CLK_BUS_MP 54 74 + #define CLK_BUS_DEINTERLACE 55 75 + #define CLK_BUS_CSI0 56 76 + #define CLK_BUS_CSI1 57 77 + #define CLK_BUS_HDMI1 58 78 + #define CLK_BUS_HDMI0 59 79 + #define CLK_BUS_DE 60 80 + #define CLK_BUS_TVE0 61 81 + #define CLK_BUS_TVE1 62 82 + #define CLK_BUS_TVE_TOP 63 83 + #define CLK_BUS_GMAC 64 84 + #define CLK_BUS_GPU 65 85 + #define CLK_BUS_TVD0 66 86 + #define CLK_BUS_TVD1 67 87 + #define CLK_BUS_TVD2 68 88 + #define CLK_BUS_TVD3 69 89 + #define CLK_BUS_TVD_TOP 70 90 + #define CLK_BUS_TCON_LCD0 71 91 + #define CLK_BUS_TCON_LCD1 72 92 + #define CLK_BUS_TCON_TV0 73 93 + #define CLK_BUS_TCON_TV1 74 94 + #define CLK_BUS_TCON_TOP 75 95 + #define CLK_BUS_CODEC 76 96 + #define CLK_BUS_SPDIF 77 97 + #define CLK_BUS_AC97 78 98 + #define CLK_BUS_PIO 79 99 + #define CLK_BUS_IR0 80 100 + #define CLK_BUS_IR1 81 101 + #define CLK_BUS_THS 82 102 + #define CLK_BUS_KEYPAD 83 103 + #define CLK_BUS_I2S0 84 104 + #define CLK_BUS_I2S1 85 105 + #define CLK_BUS_I2S2 86 106 + #define CLK_BUS_I2C0 87 107 + #define CLK_BUS_I2C1 88 108 + #define CLK_BUS_I2C2 89 109 + #define CLK_BUS_I2C3 90 110 + #define CLK_BUS_CAN 91 111 + #define CLK_BUS_SCR 92 112 + #define CLK_BUS_PS20 93 113 + #define CLK_BUS_PS21 94 114 + #define CLK_BUS_I2C4 95 115 + #define CLK_BUS_UART0 96 116 + #define CLK_BUS_UART1 97 117 + #define CLK_BUS_UART2 98 118 + #define CLK_BUS_UART3 99 119 + #define CLK_BUS_UART4 100 120 + #define CLK_BUS_UART5 101 121 + #define CLK_BUS_UART6 102 122 + #define CLK_BUS_UART7 103 123 + #define CLK_BUS_DBG 104 124 + 125 + #define CLK_THS 105 126 + #define CLK_NAND 106 127 + #define CLK_MMC0 107 128 + #define CLK_MMC1 108 129 + #define CLK_MMC2 109 130 + #define CLK_MMC3 110 131 + #define CLK_TS 111 132 + #define CLK_CE 112 133 + #define CLK_SPI0 113 134 + #define CLK_SPI1 114 135 + #define CLK_SPI2 115 136 + #define CLK_SPI3 116 137 + #define CLK_I2S0 117 138 + #define CLK_I2S1 118 139 + #define CLK_I2S2 119 140 + #define CLK_AC97 120 141 + #define CLK_SPDIF 121 142 + #define CLK_KEYPAD 122 143 + #define CLK_SATA 123 144 + #define CLK_USB_PHY0 124 145 + #define CLK_USB_PHY1 125 146 + #define CLK_USB_PHY2 126 147 + #define CLK_USB_OHCI0 127 148 + #define CLK_USB_OHCI1 128 149 + #define CLK_USB_OHCI2 129 150 + #define CLK_IR0 130 151 + #define CLK_IR1 131 152 + 153 + #define CLK_DRAM_VE 133 154 + #define CLK_DRAM_CSI0 134 155 + #define CLK_DRAM_CSI1 135 156 + #define CLK_DRAM_TS 136 157 + #define CLK_DRAM_TVD 137 158 + #define CLK_DRAM_MP 138 159 + #define CLK_DRAM_DEINTERLACE 139 160 + #define CLK_DE 140 161 + #define CLK_MP 141 162 + #define CLK_TCON_LCD0 142 163 + #define CLK_TCON_LCD1 143 164 + #define CLK_TCON_TV0 144 165 + #define CLK_TCON_TV1 145 166 + #define CLK_DEINTERLACE 146 167 + #define CLK_CSI1_MCLK 147 168 + #define CLK_CSI_SCLK 148 169 + #define CLK_CSI0_MCLK 149 170 + #define CLK_VE 150 171 + #define CLK_CODEC 151 172 + #define CLK_AVS 152 173 + #define CLK_HDMI 153 174 + #define CLK_HDMI_SLOW 154 175 + 176 + #define CLK_DSI_DPHY 156 177 + #define CLK_TVE0 157 178 + #define CLK_TVE1 158 179 + #define CLK_TVD0 159 180 + #define CLK_TVD1 160 181 + #define CLK_TVD2 161 182 + #define CLK_TVD3 162 183 + #define CLK_GPU 163 184 + #define CLK_OUTA 164 185 + #define CLK_OUTB 165 186 + 187 + #endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */
+136
include/dt-bindings/mfd/stm32h7-rcc.h
··· 1 + /* 2 + * This header provides constants for the STM32H7 RCC IP 3 + */ 4 + 5 + #ifndef _DT_BINDINGS_MFD_STM32H7_RCC_H 6 + #define _DT_BINDINGS_MFD_STM32H7_RCC_H 7 + 8 + /* AHB3 */ 9 + #define STM32H7_RCC_AHB3_MDMA 0 10 + #define STM32H7_RCC_AHB3_DMA2D 4 11 + #define STM32H7_RCC_AHB3_JPGDEC 5 12 + #define STM32H7_RCC_AHB3_FMC 12 13 + #define STM32H7_RCC_AHB3_QUADSPI 14 14 + #define STM32H7_RCC_AHB3_SDMMC1 16 15 + #define STM32H7_RCC_AHB3_CPU 31 16 + 17 + #define STM32H7_AHB3_RESET(bit) (STM32H7_RCC_AHB3_##bit + (0x7C * 8)) 18 + 19 + /* AHB1 */ 20 + #define STM32H7_RCC_AHB1_DMA1 0 21 + #define STM32H7_RCC_AHB1_DMA2 1 22 + #define STM32H7_RCC_AHB1_ADC12 5 23 + #define STM32H7_RCC_AHB1_ART 14 24 + #define STM32H7_RCC_AHB1_ETH1MAC 15 25 + #define STM32H7_RCC_AHB1_USB1OTG 25 26 + #define STM32H7_RCC_AHB1_USB2OTG 27 27 + 28 + #define STM32H7_AHB1_RESET(bit) (STM32H7_RCC_AHB1_##bit + (0x80 * 8)) 29 + 30 + /* AHB2 */ 31 + #define STM32H7_RCC_AHB2_CAMITF 0 32 + #define STM32H7_RCC_AHB2_CRYPT 4 33 + #define STM32H7_RCC_AHB2_HASH 5 34 + #define STM32H7_RCC_AHB2_RNG 6 35 + #define STM32H7_RCC_AHB2_SDMMC2 9 36 + 37 + #define STM32H7_AHB2_RESET(bit) (STM32H7_RCC_AHB2_##bit + (0x84 * 8)) 38 + 39 + /* AHB4 */ 40 + #define STM32H7_RCC_AHB4_GPIOA 0 41 + #define STM32H7_RCC_AHB4_GPIOB 1 42 + #define STM32H7_RCC_AHB4_GPIOC 2 43 + #define STM32H7_RCC_AHB4_GPIOD 3 44 + #define STM32H7_RCC_AHB4_GPIOE 4 45 + #define STM32H7_RCC_AHB4_GPIOF 5 46 + #define STM32H7_RCC_AHB4_GPIOG 6 47 + #define STM32H7_RCC_AHB4_GPIOH 7 48 + #define STM32H7_RCC_AHB4_GPIOI 8 49 + #define STM32H7_RCC_AHB4_GPIOJ 9 50 + #define STM32H7_RCC_AHB4_GPIOK 10 51 + #define STM32H7_RCC_AHB4_CRC 19 52 + #define STM32H7_RCC_AHB4_BDMA 21 53 + #define STM32H7_RCC_AHB4_ADC3 24 54 + #define STM32H7_RCC_AHB4_HSEM 25 55 + 56 + #define STM32H7_AHB4_RESET(bit) (STM32H7_RCC_AHB4_##bit + (0x88 * 8)) 57 + 58 + /* APB3 */ 59 + #define STM32H7_RCC_APB3_LTDC 3 60 + #define STM32H7_RCC_APB3_DSI 4 61 + 62 + #define STM32H7_APB3_RESET(bit) (STM32H7_RCC_APB3_##bit + (0x8C * 8)) 63 + 64 + /* APB1L */ 65 + #define STM32H7_RCC_APB1L_TIM2 0 66 + #define STM32H7_RCC_APB1L_TIM3 1 67 + #define STM32H7_RCC_APB1L_TIM4 2 68 + #define STM32H7_RCC_APB1L_TIM5 3 69 + #define STM32H7_RCC_APB1L_TIM6 4 70 + #define STM32H7_RCC_APB1L_TIM7 5 71 + #define STM32H7_RCC_APB1L_TIM12 6 72 + #define STM32H7_RCC_APB1L_TIM13 7 73 + #define STM32H7_RCC_APB1L_TIM14 8 74 + #define STM32H7_RCC_APB1L_LPTIM1 9 75 + #define STM32H7_RCC_APB1L_SPI2 14 76 + #define STM32H7_RCC_APB1L_SPI3 15 77 + #define STM32H7_RCC_APB1L_SPDIF_RX 16 78 + #define STM32H7_RCC_APB1L_USART2 17 79 + #define STM32H7_RCC_APB1L_USART3 18 80 + #define STM32H7_RCC_APB1L_UART4 19 81 + #define STM32H7_RCC_APB1L_UART5 20 82 + #define STM32H7_RCC_APB1L_I2C1 21 83 + #define STM32H7_RCC_APB1L_I2C2 22 84 + #define STM32H7_RCC_APB1L_I2C3 23 85 + #define STM32H7_RCC_APB1L_HDMICEC 27 86 + #define STM32H7_RCC_APB1L_DAC12 29 87 + #define STM32H7_RCC_APB1L_USART7 30 88 + #define STM32H7_RCC_APB1L_USART8 31 89 + 90 + #define STM32H7_APB1L_RESET(bit) (STM32H7_RCC_APB1L_##bit + (0x90 * 8)) 91 + 92 + /* APB1H */ 93 + #define STM32H7_RCC_APB1H_CRS 1 94 + #define STM32H7_RCC_APB1H_SWP 2 95 + #define STM32H7_RCC_APB1H_OPAMP 4 96 + #define STM32H7_RCC_APB1H_MDIOS 5 97 + #define STM32H7_RCC_APB1H_FDCAN 8 98 + 99 + #define STM32H7_APB1H_RESET(bit) (STM32H7_RCC_APB1H_##bit + (0x94 * 8)) 100 + 101 + /* APB2 */ 102 + #define STM32H7_RCC_APB2_TIM1 0 103 + #define STM32H7_RCC_APB2_TIM8 1 104 + #define STM32H7_RCC_APB2_USART1 4 105 + #define STM32H7_RCC_APB2_USART6 5 106 + #define STM32H7_RCC_APB2_SPI1 12 107 + #define STM32H7_RCC_APB2_SPI4 13 108 + #define STM32H7_RCC_APB2_TIM15 16 109 + #define STM32H7_RCC_APB2_TIM16 17 110 + #define STM32H7_RCC_APB2_TIM17 18 111 + #define STM32H7_RCC_APB2_SPI5 20 112 + #define STM32H7_RCC_APB2_SAI1 22 113 + #define STM32H7_RCC_APB2_SAI2 23 114 + #define STM32H7_RCC_APB2_SAI3 24 115 + #define STM32H7_RCC_APB2_DFSDM1 28 116 + #define STM32H7_RCC_APB2_HRTIM 29 117 + 118 + #define STM32H7_APB2_RESET(bit) (STM32H7_RCC_APB2_##bit + (0x98 * 8)) 119 + 120 + /* APB4 */ 121 + #define STM32H7_RCC_APB4_SYSCFG 1 122 + #define STM32H7_RCC_APB4_LPUART1 3 123 + #define STM32H7_RCC_APB4_SPI6 5 124 + #define STM32H7_RCC_APB4_I2C4 7 125 + #define STM32H7_RCC_APB4_LPTIM2 9 126 + #define STM32H7_RCC_APB4_LPTIM3 10 127 + #define STM32H7_RCC_APB4_LPTIM4 11 128 + #define STM32H7_RCC_APB4_LPTIM5 12 129 + #define STM32H7_RCC_APB4_COMP12 14 130 + #define STM32H7_RCC_APB4_VREF 15 131 + #define STM32H7_RCC_APB4_SAI4 21 132 + #define STM32H7_RCC_APB4_TMPSENS 26 133 + 134 + #define STM32H7_APB4_RESET(bit) (STM32H7_RCC_APB4_##bit + (0x9C * 8)) 135 + 136 + #endif /* _DT_BINDINGS_MFD_STM32H7_RCC_H */
+69
include/dt-bindings/reset/sun4i-a10-ccu.h
··· 1 + /* 2 + * Copyright (C) 2017 Priit Laes <plaes@plaes.org> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_RST_SUN4I_A10_H 44 + #define _DT_BINDINGS_RST_SUN4I_A10_H 45 + 46 + #define RST_USB_PHY0 1 47 + #define RST_USB_PHY1 2 48 + #define RST_USB_PHY2 3 49 + #define RST_GPS 4 50 + #define RST_DE_BE0 5 51 + #define RST_DE_BE1 6 52 + #define RST_DE_FE0 7 53 + #define RST_DE_FE1 8 54 + #define RST_DE_MP 9 55 + #define RST_TVE0 10 56 + #define RST_TCON0 11 57 + #define RST_TVE1 12 58 + #define RST_TCON1 13 59 + #define RST_CSI0 14 60 + #define RST_CSI1 15 61 + #define RST_VE 16 62 + #define RST_ACE 17 63 + #define RST_LVDS 18 64 + #define RST_GPU 19 65 + #define RST_HDMI_H 20 66 + #define RST_HDMI_SYS 21 67 + #define RST_HDMI_AUDIO_DMA 22 68 + 69 + #endif /* DT_BINDINGS_RST_SUN4I_A10_H */
+130
include/dt-bindings/reset/sun8i-r40-ccu.h
··· 1 + /* 2 + * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io> 3 + * 4 + * This file is dual-licensed: you can use it either under the terms 5 + * of the GPL or the X11 license, at your option. Note that this dual 6 + * licensing only applies to this file, and not this project as a 7 + * whole. 8 + * 9 + * a) This file is free software; you can redistribute it and/or 10 + * modify it under the terms of the GNU General Public License as 11 + * published by the Free Software Foundation; either version 2 of the 12 + * License, or (at your option) any later version. 13 + * 14 + * This file is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * Or, alternatively, 20 + * 21 + * b) Permission is hereby granted, free of charge, to any person 22 + * obtaining a copy of this software and associated documentation 23 + * files (the "Software"), to deal in the Software without 24 + * restriction, including without limitation the rights to use, 25 + * copy, modify, merge, publish, distribute, sublicense, and/or 26 + * sell copies of the Software, and to permit persons to whom the 27 + * Software is furnished to do so, subject to the following 28 + * conditions: 29 + * 30 + * The above copyright notice and this permission notice shall be 31 + * included in all copies or substantial portions of the Software. 32 + * 33 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 34 + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 35 + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 36 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 37 + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 38 + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 39 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 40 + * OTHER DEALINGS IN THE SOFTWARE. 41 + */ 42 + 43 + #ifndef _DT_BINDINGS_RST_SUN8I_R40_H_ 44 + #define _DT_BINDINGS_RST_SUN8I_R40_H_ 45 + 46 + #define RST_USB_PHY0 0 47 + #define RST_USB_PHY1 1 48 + #define RST_USB_PHY2 2 49 + 50 + #define RST_DRAM 3 51 + #define RST_MBUS 4 52 + 53 + #define RST_BUS_MIPI_DSI 5 54 + #define RST_BUS_CE 6 55 + #define RST_BUS_DMA 7 56 + #define RST_BUS_MMC0 8 57 + #define RST_BUS_MMC1 9 58 + #define RST_BUS_MMC2 10 59 + #define RST_BUS_MMC3 11 60 + #define RST_BUS_NAND 12 61 + #define RST_BUS_DRAM 13 62 + #define RST_BUS_EMAC 14 63 + #define RST_BUS_TS 15 64 + #define RST_BUS_HSTIMER 16 65 + #define RST_BUS_SPI0 17 66 + #define RST_BUS_SPI1 18 67 + #define RST_BUS_SPI2 19 68 + #define RST_BUS_SPI3 20 69 + #define RST_BUS_SATA 21 70 + #define RST_BUS_OTG 22 71 + #define RST_BUS_EHCI0 23 72 + #define RST_BUS_EHCI1 24 73 + #define RST_BUS_EHCI2 25 74 + #define RST_BUS_OHCI0 26 75 + #define RST_BUS_OHCI1 27 76 + #define RST_BUS_OHCI2 28 77 + #define RST_BUS_VE 29 78 + #define RST_BUS_MP 30 79 + #define RST_BUS_DEINTERLACE 31 80 + #define RST_BUS_CSI0 32 81 + #define RST_BUS_CSI1 33 82 + #define RST_BUS_HDMI0 34 83 + #define RST_BUS_HDMI1 35 84 + #define RST_BUS_DE 36 85 + #define RST_BUS_TVE0 37 86 + #define RST_BUS_TVE1 38 87 + #define RST_BUS_TVE_TOP 39 88 + #define RST_BUS_GMAC 40 89 + #define RST_BUS_GPU 41 90 + #define RST_BUS_TVD0 42 91 + #define RST_BUS_TVD1 43 92 + #define RST_BUS_TVD2 44 93 + #define RST_BUS_TVD3 45 94 + #define RST_BUS_TVD_TOP 46 95 + #define RST_BUS_TCON_LCD0 47 96 + #define RST_BUS_TCON_LCD1 48 97 + #define RST_BUS_TCON_TV0 49 98 + #define RST_BUS_TCON_TV1 50 99 + #define RST_BUS_TCON_TOP 51 100 + #define RST_BUS_DBG 52 101 + #define RST_BUS_LVDS 53 102 + #define RST_BUS_CODEC 54 103 + #define RST_BUS_SPDIF 55 104 + #define RST_BUS_AC97 56 105 + #define RST_BUS_IR0 57 106 + #define RST_BUS_IR1 58 107 + #define RST_BUS_THS 59 108 + #define RST_BUS_KEYPAD 60 109 + #define RST_BUS_I2S0 61 110 + #define RST_BUS_I2S1 62 111 + #define RST_BUS_I2S2 63 112 + #define RST_BUS_I2C0 64 113 + #define RST_BUS_I2C1 65 114 + #define RST_BUS_I2C2 66 115 + #define RST_BUS_I2C3 67 116 + #define RST_BUS_CAN 68 117 + #define RST_BUS_SCR 69 118 + #define RST_BUS_PS20 70 119 + #define RST_BUS_PS21 71 120 + #define RST_BUS_I2C4 72 121 + #define RST_BUS_UART0 73 122 + #define RST_BUS_UART1 74 123 + #define RST_BUS_UART2 75 124 + #define RST_BUS_UART3 76 125 + #define RST_BUS_UART4 77 126 + #define RST_BUS_UART5 78 127 + #define RST_BUS_UART6 79 128 + #define RST_BUS_UART7 80 129 + 130 + #endif /* _DT_BINDINGS_RST_SUN8I_R40_H_ */
+4
include/linux/clk-provider.h
··· 343 343 u8 clk_gate_flags, spinlock_t *lock); 344 344 void clk_unregister_gate(struct clk *clk); 345 345 void clk_hw_unregister_gate(struct clk_hw *hw); 346 + int clk_gate_is_enabled(struct clk_hw *hw); 346 347 347 348 struct clk_div_table { 348 349 unsigned int val; ··· 566 565 u8 nwidth; 567 566 u32 nmask; 568 567 u8 flags; 568 + void (*approximation)(struct clk_hw *hw, 569 + unsigned long rate, unsigned long *parent_rate, 570 + unsigned long *m, unsigned long *n); 569 571 spinlock_t *lock; 570 572 }; 571 573
+25
include/linux/clk/at91_pmc.h
··· 185 185 #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ 186 186 #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ 187 187 188 + #define AT91_PMC_AUDIO_PLL0 0x14c 189 + #define AT91_PMC_AUDIO_PLL_PLLEN (1 << 0) 190 + #define AT91_PMC_AUDIO_PLL_PADEN (1 << 1) 191 + #define AT91_PMC_AUDIO_PLL_PMCEN (1 << 2) 192 + #define AT91_PMC_AUDIO_PLL_RESETN (1 << 3) 193 + #define AT91_PMC_AUDIO_PLL_ND_OFFSET 8 194 + #define AT91_PMC_AUDIO_PLL_ND_MASK (0x7f << AT91_PMC_AUDIO_PLL_ND_OFFSET) 195 + #define AT91_PMC_AUDIO_PLL_ND(n) ((n) << AT91_PMC_AUDIO_PLL_ND_OFFSET) 196 + #define AT91_PMC_AUDIO_PLL_QDPMC_OFFSET 16 197 + #define AT91_PMC_AUDIO_PLL_QDPMC_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) 198 + #define AT91_PMC_AUDIO_PLL_QDPMC(n) ((n) << AT91_PMC_AUDIO_PLL_QDPMC_OFFSET) 199 + 200 + #define AT91_PMC_AUDIO_PLL1 0x150 201 + #define AT91_PMC_AUDIO_PLL_FRACR_MASK 0x3fffff 202 + #define AT91_PMC_AUDIO_PLL_QDPAD_OFFSET 24 203 + #define AT91_PMC_AUDIO_PLL_QDPAD_MASK (0x7f << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) 204 + #define AT91_PMC_AUDIO_PLL_QDPAD(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_OFFSET) 205 + #define AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET AT91_PMC_AUDIO_PLL_QDPAD_OFFSET 206 + #define AT91_PMC_AUDIO_PLL_QDPAD_DIV_MASK (0x3 << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) 207 + #define AT91_PMC_AUDIO_PLL_QDPAD_DIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_DIV_OFFSET) 208 + #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET 26 209 + #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX 0x1f 210 + #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MASK (AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_MAX << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) 211 + #define AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV(n) ((n) << AT91_PMC_AUDIO_PLL_QDPAD_EXTDIV_OFFSET) 212 + 188 213 #endif
+14 -33
sound/soc/atmel/atmel-classd.c
··· 32 32 struct regmap *regmap; 33 33 struct clk *pclk; 34 34 struct clk *gclk; 35 - struct clk *aclk; 36 35 int irq; 37 36 const struct atmel_classd_pdata *pdata; 38 37 }; ··· 329 330 { 330 331 struct snd_soc_pcm_runtime *rtd = substream->private_data; 331 332 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); 332 - int ret; 333 - 334 - ret = clk_prepare_enable(dd->aclk); 335 - if (ret) 336 - return ret; 337 333 338 334 return clk_prepare_enable(dd->gclk); 339 335 } ··· 351 357 return 0; 352 358 } 353 359 354 - #define CLASSD_ACLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) 355 - #define CLASSD_ACLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) 360 + #define CLASSD_GCLK_RATE_11M2896_MPY_8 (112896 * 100 * 8) 361 + #define CLASSD_GCLK_RATE_12M288_MPY_8 (12288 * 1000 * 8) 356 362 357 363 static struct { 358 364 int rate; 359 365 int sample_rate; 360 366 int dsp_clk; 361 - unsigned long aclk_rate; 367 + unsigned long gclk_rate; 362 368 } const sample_rates[] = { 363 369 { 8000, CLASSD_INTPMR_FRAME_8K, 364 - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 370 + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, 365 371 { 16000, CLASSD_INTPMR_FRAME_16K, 366 - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 372 + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, 367 373 { 32000, CLASSD_INTPMR_FRAME_32K, 368 - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 374 + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, 369 375 { 48000, CLASSD_INTPMR_FRAME_48K, 370 - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 376 + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, 371 377 { 96000, CLASSD_INTPMR_FRAME_96K, 372 - CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_ACLK_RATE_12M288_MPY_8 }, 378 + CLASSD_INTPMR_DSP_CLK_FREQ_12M288, CLASSD_GCLK_RATE_12M288_MPY_8 }, 373 379 { 22050, CLASSD_INTPMR_FRAME_22K, 374 - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 380 + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, 375 381 { 44100, CLASSD_INTPMR_FRAME_44K, 376 - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 382 + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, 377 383 { 88200, CLASSD_INTPMR_FRAME_88K, 378 - CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_ACLK_RATE_11M2896_MPY_8 }, 384 + CLASSD_INTPMR_DSP_CLK_FREQ_11M2896, CLASSD_GCLK_RATE_11M2896_MPY_8 }, 379 385 }; 380 386 381 387 static int ··· 404 410 } 405 411 406 412 dev_dbg(codec->dev, 407 - "Selected SAMPLE_RATE of %dHz, ACLK_RATE of %ldHz\n", 408 - sample_rates[best].rate, sample_rates[best].aclk_rate); 413 + "Selected SAMPLE_RATE of %dHz, GCLK_RATE of %ldHz\n", 414 + sample_rates[best].rate, sample_rates[best].gclk_rate); 409 415 410 416 clk_disable_unprepare(dd->gclk); 411 - clk_disable_unprepare(dd->aclk); 412 417 413 - ret = clk_set_rate(dd->aclk, sample_rates[best].aclk_rate); 418 + ret = clk_set_rate(dd->gclk, sample_rates[best].gclk_rate); 414 419 if (ret) 415 420 return ret; 416 421 ··· 418 425 | (sample_rates[best].sample_rate << CLASSD_INTPMR_FRAME_SHIFT); 419 426 420 427 snd_soc_update_bits(codec, CLASSD_INTPMR, mask, val); 421 - 422 - ret = clk_prepare_enable(dd->aclk); 423 - if (ret) 424 - return ret; 425 428 426 429 return clk_prepare_enable(dd->gclk); 427 430 } ··· 430 441 struct atmel_classd *dd = snd_soc_card_get_drvdata(rtd->card); 431 442 432 443 clk_disable_unprepare(dd->gclk); 433 - clk_disable_unprepare(dd->aclk); 434 444 } 435 445 436 446 static int atmel_classd_codec_dai_prepare(struct snd_pcm_substream *substream, ··· 581 593 if (IS_ERR(dd->gclk)) { 582 594 ret = PTR_ERR(dd->gclk); 583 595 dev_err(dev, "failed to get GCK clock: %d\n", ret); 584 - return ret; 585 - } 586 - 587 - dd->aclk = devm_clk_get(dev, "aclk"); 588 - if (IS_ERR(dd->aclk)) { 589 - ret = PTR_ERR(dd->aclk); 590 - dev_err(dev, "failed to get audio clock: %d\n", ret); 591 596 return ret; 592 597 } 593 598