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

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

Pull clk updates from Stephen Boyd:
"It's the usual big pile of driver updates and additions, but we do
have a couple core changes in here as well.

Core:

- CLK_IS_CRITICAL support has been added. This should allow drivers
to properly express that a certain clk should stay on even if their
prepare/enable count drops to 0 (and in turn the parents of these
clks should stay enabled).

- A clk registration API has been added, clk_hw_register(), and an OF
clk provider API has been added, of_clk_add_hw_provider(). These
APIs have been put in place to further split clk providers from clk
consumers, with the goal being to have clk providers never deal
with struct clk pointers at all. Conversion of provider drivers is
on going. clkdev has also gained support for registering clk_hw
pointers directly so we can convert drivers that don't use
devicetree.

New Drivers:

- Marvell ap806 and cp110 system controllers (with clks inside!)
- Hisilicon Hi3519 clock and reset controller
- Axis ARTPEC-6 clock controllers
- Oxford Semiconductor OXNAS clock controllers
- AXS10X I2S PLL
- Rockchip RK3399 clock and reset controller

Updates:

- MMC2 and UART2 clks on Samsung Exynos 3250, ACLK on Samsung Exynos
542x SoCs, and some more clk ID exporting for bus frequency scaling
- Proper BCM2835 PCM clk support and various other clks
- i.MX clk updates for i.MX6SX, i.MX7, and VF610
- Renesas updates for R-Car H3
- Tegra210 got updates for DisplayPort and HDMI 2.0
- Rockchip driver refactorings and fixes due to adding RK3399 support"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (139 commits)
clk: fix critical clock locking
clk: qcom: mmcc-8996: Remove clocks that should be controlled by RPM
clk: ingenic: Allow divider value to be divided
clk: sunxi: Add display and TCON0 clocks driver
clk: rockchip: drop old_rate calculation on pll rate changes
clk: rockchip: simplify GRF handling in pll clocks
clk: rockchip: lookup General Register Files in rockchip_clk_init
clk: rockchip: fix the rk3399 sdmmc sample / drv name
clk: mvebu: new driver for Armada CP110 system controller
dt-bindings: arm: add DT binding for Marvell CP110 system controller
clk: mvebu: new driver for Armada AP806 system controller
clk: hisilicon: add CRG driver for hi3519 soc
clk: hisilicon: export some hisilicon APIs to modules
reset: hisilicon: add reset controller driver for hisilicon SOCs
clk: bcm/kona: Do not use sizeof on pointer type
clk: qcom: msm8916: Fix crypto clock flags
clk: nxp: lpc18xx: Initialize clk_init_data::flags to 0
clk/axs10x: Add I2S PLL clock driver
clk: imx7d: fix ahb clock mux 1
clk: fix comment of devm_clk_hw_register()
...

+7163 -1121
+35
Documentation/devicetree/bindings/arm/marvell/ap806-system-controller.txt
··· 1 + Marvell Armada AP806 System Controller 2 + ====================================== 3 + 4 + The AP806 is one of the two core HW blocks of the Marvell Armada 7K/8K 5 + SoCs. It contains a system controller, which provides a number 6 + registers giving access to numerous features: clocks, pin-muxing and 7 + many other SoC configuration items. This DT binding allows to describe 8 + this system controller. 9 + 10 + The Device Tree node representing the AP806 system controller provides 11 + a number of clocks: 12 + 13 + - 0: clock of CPU cluster 0 14 + - 1: clock of CPU cluster 1 15 + - 2: fixed PLL at 1200 Mhz 16 + - 3: MSS clock, derived from the fixed PLL 17 + 18 + Required properties: 19 + 20 + - compatible: must be: 21 + "marvell,ap806-system-controller", "syscon" 22 + - reg: register area of the AP806 system controller 23 + - #clock-cells: must be set to 1 24 + - clock-output-names: must be defined to: 25 + "ap-cpu-cluster-0", "ap-cpu-cluster-1", "ap-fixed", "ap-mss" 26 + 27 + Example: 28 + 29 + syscon: system-controller@6f4000 { 30 + compatible = "marvell,ap806-system-controller", "syscon"; 31 + #clock-cells = <1>; 32 + clock-output-names = "ap-cpu-cluster-0", "ap-cpu-cluster-1", 33 + "ap-fixed", "ap-mss"; 34 + reg = <0x6f4000 0x1000>; 35 + };
+83
Documentation/devicetree/bindings/arm/marvell/cp110-system-controller0.txt
··· 1 + Marvell Armada CP110 System Controller 0 2 + ======================================== 3 + 4 + The CP110 is one of the two core HW blocks of the Marvell Armada 7K/8K 5 + SoCs. It contains two sets of system control registers, System 6 + Controller 0 and System Controller 1. This Device Tree binding allows 7 + to describe the first system controller, which provides registers to 8 + configure various aspects of the SoC. 9 + 10 + The Device Tree node representing this System Controller 0 provides a 11 + number of clocks: 12 + 13 + - a set of core clocks 14 + - a set of gatable clocks 15 + 16 + Those clocks can be referenced by other Device Tree nodes using two 17 + cells: 18 + - The first cell must be 0 or 1. 0 for the core clocks and 1 for the 19 + gatable clocks. 20 + - The second cell identifies the particular core clock or gatable 21 + clocks. 22 + 23 + The following clocks are available: 24 + - Core clocks 25 + - 0 0 APLL 26 + - 0 1 PPv2 core 27 + - 0 2 EIP 28 + - 0 3 Core 29 + - 0 4 NAND core 30 + - Gatable clocks 31 + - 1 0 Audio 32 + - 1 1 Comm Unit 33 + - 1 2 NAND 34 + - 1 3 PPv2 35 + - 1 4 SDIO 36 + - 1 5 MG Domain 37 + - 1 6 MG Core 38 + - 1 7 XOR1 39 + - 1 8 XOR0 40 + - 1 9 GOP DP 41 + - 1 11 PCIe x1 0 42 + - 1 12 PCIe x1 1 43 + - 1 13 PCIe x4 44 + - 1 14 PCIe / XOR 45 + - 1 15 SATA 46 + - 1 16 SATA USB 47 + - 1 17 Main 48 + - 1 18 SD/MMC 49 + - 1 21 Slow IO (SPI, NOR, BootROM, I2C, UART) 50 + - 1 22 USB3H0 51 + - 1 23 USB3H1 52 + - 1 24 USB3 Device 53 + - 1 25 EIP150 54 + - 1 26 EIP197 55 + 56 + Required properties: 57 + 58 + - compatible: must be: 59 + "marvell,cp110-system-controller0", "syscon"; 60 + - reg: register area of the CP110 system controller 0 61 + - #clock-cells: must be set to 2 62 + - core-clock-output-names must be set to: 63 + "cpm-apll", "cpm-ppv2-core", "cpm-eip", "cpm-core", "cpm-nand-core" 64 + - gate-clock-output-names must be set to: 65 + "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio", 66 + "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none", 67 + "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata", 68 + "cpm-sata-usb", "cpm-main", "cpm-sd-mmc", "none", "none", "cpm-slow-io", 69 + "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197"; 70 + 71 + Example: 72 + 73 + cpm_syscon0: system-controller@440000 { 74 + compatible = "marvell,cp110-system-controller0", "syscon"; 75 + reg = <0x440000 0x1000>; 76 + #clock-cells = <2>; 77 + core-clock-output-names = "cpm-apll", "cpm-ppv2-core", "cpm-eip", "cpm-core", "cpm-nand-core"; 78 + gate-clock-output-names = "cpm-audio", "cpm-communit", "cpm-nand", "cpm-ppv2", "cpm-sdio", 79 + "cpm-mg-domain", "cpm-mg-core", "cpm-xor1", "cpm-xor0", "cpm-gop-dp", "none", 80 + "cpm-pcie_x10", "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", "cpm-sata", 81 + "cpm-sata-usb", "cpm-main", "cpm-sd-mmc", "none", "none", "cpm-slow-io", 82 + "cpm-usb3h0", "cpm-usb3h1", "cpm-usb3dev", "cpm-eip150", "cpm-eip197"; 83 + };
+41
Documentation/devicetree/bindings/clock/artpec6.txt
··· 1 + * Clock bindings for Axis ARTPEC-6 chip 2 + 3 + The bindings are based on the clock provider binding in 4 + Documentation/devicetree/bindings/clock/clock-bindings.txt 5 + 6 + External clocks: 7 + ---------------- 8 + 9 + There are two external inputs to the main clock controller which should be 10 + provided using the common clock bindings. 11 + - "sys_refclk": External 50 Mhz oscillator (required) 12 + - "i2s_refclk": Alternate audio reference clock (optional). 13 + 14 + Main clock controller 15 + --------------------- 16 + 17 + Required properties: 18 + - #clock-cells: Should be <1> 19 + See dt-bindings/clock/axis,artpec6-clkctrl.h for the list of valid identifiers. 20 + - compatible: Should be "axis,artpec6-clkctrl" 21 + - reg: Must contain the base address and length of the system controller 22 + - clocks: Must contain a phandle entry for each clock in clock-names 23 + - clock-names: Must include the external oscillator ("sys_refclk"). Optional 24 + ones are the audio reference clock ("i2s_refclk") and the audio fractional 25 + dividers ("frac_clk0" and "frac_clk1"). 26 + 27 + Examples: 28 + 29 + ext_clk: ext_clk { 30 + #clock-cells = <0>; 31 + compatible = "fixed-clock"; 32 + clock-frequency = <50000000>; 33 + }; 34 + 35 + clkctrl: clkctrl@f8000000 { 36 + #clock-cells = <1>; 37 + compatible = "axis,artpec6-clkctrl"; 38 + reg = <0xf8000000 0x48>; 39 + clocks = <&ext_clk>; 40 + clock-names = "sys_refclk"; 41 + };
+25
Documentation/devicetree/bindings/clock/axs10x-i2s-pll-clock.txt
··· 1 + Binding for the AXS10X I2S 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: shall be "snps,axs10x-i2s-pll-clock" 9 + - reg : address and length of the I2S PLL register set. 10 + - clocks: shall be the input parent clock phandle for the PLL. 11 + - #clock-cells: from common clock binding; Should always be set to 0. 12 + 13 + Example: 14 + pll_clock: pll_clock { 15 + compatible = "fixed-clock"; 16 + clock-frequency = <27000000>; 17 + #clock-cells = <0>; 18 + }; 19 + 20 + i2s_clock@100a0 { 21 + compatible = "snps,axs10x-i2s-pll-clock"; 22 + reg = <0x100a0 0x10>; 23 + clocks = <&pll_clock>; 24 + #clock-cells = <0>; 25 + };
+46
Documentation/devicetree/bindings/clock/hi3519-crg.txt
··· 1 + * Hisilicon Hi3519 Clock and Reset Generator(CRG) 2 + 3 + The Hi3519 CRG module provides clock and reset signals to various 4 + controllers within the SoC. 5 + 6 + This binding uses the following bindings: 7 + Documentation/devicetree/bindings/clock/clock-bindings.txt 8 + Documentation/devicetree/bindings/reset/reset.txt 9 + 10 + Required Properties: 11 + 12 + - compatible: should be one of the following. 13 + - "hisilicon,hi3519-crg" - controller compatible with Hi3519 SoC. 14 + 15 + - reg: physical base address of the controller and length of memory mapped 16 + region. 17 + 18 + - #clock-cells: should be 1. 19 + 20 + Each clock is assigned an identifier and client nodes use this identifier 21 + to specify the clock which they consume. 22 + 23 + All these identifier could be found in <dt-bindings/clock/hi3519-clock.h>. 24 + 25 + - #reset-cells: should be 2. 26 + 27 + A reset signal can be controlled by writing a bit register in the CRG module. 28 + The reset specifier consists of two cells. The first cell represents the 29 + register offset relative to the base address. The second cell represents the 30 + bit index in the register. 31 + 32 + Example: CRG nodes 33 + CRG: clock-reset-controller@12010000 { 34 + compatible = "hisilicon,hi3519-crg"; 35 + reg = <0x12010000 0x10000>; 36 + #clock-cells = <1>; 37 + #reset-cells = <2>; 38 + }; 39 + 40 + Example: consumer nodes 41 + i2c0: i2c@12110000 { 42 + compatible = "hisilicon,hi3519-i2c"; 43 + reg = <0x12110000 0x1000>; 44 + clocks = <&CRG HI3519_I2C0_RST>; 45 + resets = <&CRG 0xe4 0>; 46 + };
+1
Documentation/devicetree/bindings/clock/imx35-clock.txt
··· 94 94 csi_sel 79 95 95 iim_gate 80 96 96 gpu2d_gate 81 97 + ckli_gate 82 97 98 98 99 Examples: 99 100
+35
Documentation/devicetree/bindings/clock/oxnas,stdclk.txt
··· 1 + Oxford Semiconductor OXNAS SoC Family Standard Clocks 2 + ================================================ 3 + 4 + Please also refer to clock-bindings.txt in this directory for common clock 5 + bindings usage. 6 + 7 + Required properties: 8 + - compatible: Should be "oxsemi,ox810se-stdclk" 9 + - #clock-cells: 1, see below 10 + 11 + Parent node should have the following properties : 12 + - compatible: Should be "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd" 13 + 14 + For OX810SE, the clock indices are : 15 + - 0: LEON 16 + - 1: DMA_SGDMA 17 + - 2: CIPHER 18 + - 3: SATA 19 + - 4: AUDIO 20 + - 5: USBMPH 21 + - 6: ETHA 22 + - 7: PCIA 23 + - 8: NAND 24 + 25 + example: 26 + 27 + sys: sys-ctrl@000000 { 28 + compatible = "oxsemi,ox810se-sys-ctrl", "syscon", "simple-mfd"; 29 + reg = <0x000000 0x100000>; 30 + 31 + stdclk: stdclk { 32 + compatible = "oxsemi,ox810se-stdclk"; 33 + #clock-cells = <1>; 34 + }; 35 + };
+62
Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
··· 1 + * Rockchip RK3399 Clock and Reset Unit 2 + 3 + The RK3399 clock controller generates and supplies clock to various 4 + controllers within the SoC and also implements a reset controller for SoC 5 + peripherals. 6 + 7 + Required Properties: 8 + 9 + - compatible: PMU for CRU should be "rockchip,rk3399-pmucru" 10 + - compatible: CRU should be "rockchip,rk3399-cru" 11 + - reg: physical base address of the controller and length of memory mapped 12 + region. 13 + - #clock-cells: should be 1. 14 + - #reset-cells: should be 1. 15 + 16 + Each clock is assigned an identifier and client nodes can use this identifier 17 + to specify the clock which they consume. All available clocks are defined as 18 + preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be 19 + used in device tree sources. Similar macros exist for the reset sources in 20 + these files. 21 + 22 + External clocks: 23 + 24 + There are several clocks that are generated outside the SoC. It is expected 25 + that they are defined using standard clock bindings with following 26 + clock-output-names: 27 + - "xin24m" - crystal input - required, 28 + - "xin32k" - rtc clock - optional, 29 + - "clkin_gmac" - external GMAC clock - optional, 30 + - "clkin_i2s" - external I2S clock - optional, 31 + - "pclkin_cif" - external ISP clock - optional, 32 + - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 33 + - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 34 + 35 + Example: Clock controller node: 36 + 37 + pmucru: pmu-clock-controller@ff750000 { 38 + compatible = "rockchip,rk3399-pmucru"; 39 + reg = <0x0 0xff750000 0x0 0x1000>; 40 + #clock-cells = <1>; 41 + #reset-cells = <1>; 42 + }; 43 + 44 + cru: clock-controller@ff760000 { 45 + compatible = "rockchip,rk3399-cru"; 46 + reg = <0x0 0xff760000 0x0 0x1000>; 47 + #clock-cells = <1>; 48 + #reset-cells = <1>; 49 + }; 50 + 51 + Example: UART controller node that consumes the clock generated by the clock 52 + controller: 53 + 54 + uart0: serial@ff1a0000 { 55 + compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; 56 + reg = <0x0 0xff180000 0x0 0x100>; 57 + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; 58 + clock-names = "baudclk", "apb_pclk"; 59 + interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; 60 + reg-shift = <2>; 61 + reg-io-width = <4>; 62 + };
+6
Documentation/devicetree/bindings/clock/sunxi.txt
··· 10 10 "allwinner,sun4i-a10-pll1-clk" - for the main PLL clock and PLL4 11 11 "allwinner,sun6i-a31-pll1-clk" - for the main PLL clock on A31 12 12 "allwinner,sun8i-a23-pll1-clk" - for the main PLL clock on A23 13 + "allwinner,sun4i-a10-pll3-clk" - for the video PLL clock on A10 13 14 "allwinner,sun9i-a80-pll4-clk" - for the peripheral PLLs on A80 14 15 "allwinner,sun4i-a10-pll5-clk" - for the PLL5 clock 15 16 "allwinner,sun4i-a10-pll6-clk" - for the PLL6 clock ··· 64 63 "allwinner,sun8i-a83t-bus-gates-clk" - for the bus gates on A83T 65 64 "allwinner,sun8i-h3-bus-gates-clk" - for the bus gates on H3 66 65 "allwinner,sun9i-a80-apbs-gates-clk" - for the APBS gates on A80 66 + "allwinner,sun4i-a10-display-clk" - for the display clocks on the A10 67 67 "allwinner,sun4i-a10-dram-gates-clk" - for the DRAM gates on A10 68 + "allwinner,sun5i-a13-dram-gates-clk" - for the DRAM gates on A13 68 69 "allwinner,sun5i-a13-mbus-clk" - for the MBUS clock on A13 69 70 "allwinner,sun4i-a10-mmc-clk" - for the MMC clock 70 71 "allwinner,sun9i-a80-mmc-clk" - for mmc module clocks on A80 ··· 76 73 "allwinner,sun8i-a23-mbus-clk" - for the MBUS clock on A23 77 74 "allwinner,sun7i-a20-out-clk" - for the external output clocks 78 75 "allwinner,sun7i-a20-gmac-clk" - for the GMAC clock module on A20/A31 76 + "allwinner,sun4i-a10-tcon-ch0-clk" - for the TCON channel 0 clock on the A10 77 + "allwinner,sun4i-a10-tcon-ch1-clk" - for the TCON channel 1 clock on the A10 79 78 "allwinner,sun4i-a10-usb-clk" - for usb gates + resets on A10 / A20 80 79 "allwinner,sun5i-a13-usb-clk" - for usb gates + resets on A13 81 80 "allwinner,sun6i-a31-usb-clk" - for usb gates + resets on A31 ··· 86 81 "allwinner,sun9i-a80-usb-mod-clk" - for usb gates + resets on A80 87 82 "allwinner,sun9i-a80-usb-phy-clk" - for usb phy gates + resets on A80 88 83 "allwinner,sun4i-a10-ve-clk" - for the Video Engine clock 84 + "allwinner,sun6i-a31-display-clk" - for the display clocks 89 85 90 86 Required properties for all clocks: 91 87 - reg : shall be the control register address for the clock.
+1
Documentation/driver-model/devres.txt
··· 236 236 CLOCK 237 237 devm_clk_get() 238 238 devm_clk_put() 239 + devm_clk_hw_register() 239 240 240 241 DMA 241 242 dmam_alloc_coherent()
+1 -1
MAINTAINERS
··· 977 977 L: linux-arm-kernel@axis.com 978 978 F: arch/arm/mach-artpec 979 979 F: arch/arm/boot/dts/artpec6* 980 - F: drivers/clk/clk-artpec6.c 980 + F: drivers/clk/axis 981 981 982 982 ARM/ASPEED MACHINE SUPPORT 983 983 M: Joel Stanley <joel@jms.id.au>
+6
drivers/clk/Kconfig
··· 200 200 config COMMON_CLK_PIC32 201 201 def_bool COMMON_CLK && MACH_PIC32 202 202 203 + config COMMON_CLK_OXNAS 204 + bool "Clock driver for the OXNAS SoC Family" 205 + select MFD_SYSCON 206 + ---help--- 207 + Support for the OXNAS SoC Family clocks. 208 + 203 209 source "drivers/clk/bcm/Kconfig" 204 210 source "drivers/clk/hisilicon/Kconfig" 205 211 source "drivers/clk/mvebu/Kconfig"
+4 -1
drivers/clk/Makefile
··· 33 33 obj-$(CONFIG_ARCH_MOXART) += clk-moxart.o 34 34 obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o 35 35 obj-$(CONFIG_ARCH_NSPIRE) += clk-nspire.o 36 + obj-$(CONFIG_COMMON_CLK_OXNAS) += clk-oxnas.o 36 37 obj-$(CONFIG_COMMON_CLK_PALMAS) += clk-palmas.o 37 38 obj-$(CONFIG_CLK_QORIQ) += clk-qoriq.o 38 39 obj-$(CONFIG_COMMON_CLK_RK808) += clk-rk808.o ··· 52 51 obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o 53 52 obj-$(CONFIG_COMMON_CLK_PWM) += clk-pwm.o 54 53 obj-$(CONFIG_COMMON_CLK_AT91) += at91/ 54 + obj-$(CONFIG_ARCH_ARTPEC) += axis/ 55 55 obj-y += bcm/ 56 56 obj-$(CONFIG_ARCH_BERLIN) += berlin/ 57 57 obj-$(CONFIG_ARCH_HISI) += hisilicon/ ··· 64 62 ifeq ($(CONFIG_COMMON_CLK), y) 65 63 obj-$(CONFIG_ARCH_MMP) += mmp/ 66 64 endif 67 - obj-$(CONFIG_PLAT_ORION) += mvebu/ 65 + obj-y += mvebu/ 68 66 obj-$(CONFIG_ARCH_MESON) += meson/ 69 67 obj-$(CONFIG_ARCH_MXS) += mxs/ 70 68 obj-$(CONFIG_MACH_PISTACHIO) += pistachio/ ··· 87 85 obj-$(CONFIG_ARCH_ZX) += zte/ 88 86 obj-$(CONFIG_ARCH_ZYNQ) += zynq/ 89 87 obj-$(CONFIG_H8300) += h8300/ 88 + obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/
+1 -1
drivers/clk/at91/clk-h32mx.c
··· 114 114 h32mxclk->regmap = regmap; 115 115 116 116 clk = clk_register(NULL, &h32mxclk->hw); 117 - if (!clk) { 117 + if (IS_ERR(clk)) { 118 118 kfree(h32mxclk); 119 119 return; 120 120 }
+1
drivers/clk/axis/Makefile
··· 1 + obj-$(CONFIG_MACH_ARTPEC6) += clk-artpec6.o
+242
drivers/clk/axis/clk-artpec6.c
··· 1 + /* 2 + * ARTPEC-6 clock initialization 3 + * 4 + * Copyright 2015-2016 Axis Comunications AB. 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 version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #include <linux/clk-provider.h> 12 + #include <linux/device.h> 13 + #include <linux/io.h> 14 + #include <linux/of.h> 15 + #include <linux/of_address.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/slab.h> 18 + #include <dt-bindings/clock/axis,artpec6-clkctrl.h> 19 + 20 + #define NUM_I2S_CLOCKS 2 21 + 22 + struct artpec6_clkctrl_drvdata { 23 + struct clk *clk_table[ARTPEC6_CLK_NUMCLOCKS]; 24 + void __iomem *syscon_base; 25 + struct clk_onecell_data clk_data; 26 + spinlock_t i2scfg_lock; 27 + }; 28 + 29 + static struct artpec6_clkctrl_drvdata *clkdata; 30 + 31 + static const char *const i2s_clk_names[NUM_I2S_CLOCKS] = { 32 + "i2s0", 33 + "i2s1", 34 + }; 35 + 36 + static const int i2s_clk_indexes[NUM_I2S_CLOCKS] = { 37 + ARTPEC6_CLK_I2S0_CLK, 38 + ARTPEC6_CLK_I2S1_CLK, 39 + }; 40 + 41 + static void of_artpec6_clkctrl_setup(struct device_node *np) 42 + { 43 + int i; 44 + const char *sys_refclk_name; 45 + u32 pll_mode, pll_m, pll_n; 46 + struct clk **clks; 47 + 48 + /* Mandatory parent clock. */ 49 + i = of_property_match_string(np, "clock-names", "sys_refclk"); 50 + if (i < 0) 51 + return; 52 + 53 + sys_refclk_name = of_clk_get_parent_name(np, i); 54 + 55 + clkdata = kzalloc(sizeof(*clkdata), GFP_KERNEL); 56 + if (!clkdata) 57 + return; 58 + 59 + clks = clkdata->clk_table; 60 + 61 + for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i) 62 + clks[i] = ERR_PTR(-EPROBE_DEFER); 63 + 64 + clkdata->syscon_base = of_iomap(np, 0); 65 + BUG_ON(clkdata->syscon_base == NULL); 66 + 67 + /* Read PLL1 factors configured by boot strap pins. */ 68 + pll_mode = (readl(clkdata->syscon_base) >> 6) & 3; 69 + switch (pll_mode) { 70 + case 0: /* DDR3-2133 mode */ 71 + pll_m = 4; 72 + pll_n = 85; 73 + break; 74 + case 1: /* DDR3-1866 mode */ 75 + pll_m = 6; 76 + pll_n = 112; 77 + break; 78 + case 2: /* DDR3-1600 mode */ 79 + pll_m = 4; 80 + pll_n = 64; 81 + break; 82 + case 3: /* DDR3-1333 mode */ 83 + pll_m = 8; 84 + pll_n = 106; 85 + break; 86 + } 87 + 88 + clks[ARTPEC6_CLK_CPU] = 89 + clk_register_fixed_factor(NULL, "cpu", sys_refclk_name, 0, pll_n, 90 + pll_m); 91 + clks[ARTPEC6_CLK_CPU_PERIPH] = 92 + clk_register_fixed_factor(NULL, "cpu_periph", "cpu", 0, 1, 2); 93 + 94 + /* EPROBE_DEFER on the apb_clock is not handled in amba devices. */ 95 + clks[ARTPEC6_CLK_UART_PCLK] = 96 + clk_register_fixed_factor(NULL, "uart_pclk", "cpu", 0, 1, 8); 97 + clks[ARTPEC6_CLK_UART_REFCLK] = 98 + clk_register_fixed_rate(NULL, "uart_ref", sys_refclk_name, 0, 99 + 50000000); 100 + 101 + clks[ARTPEC6_CLK_SPI_PCLK] = 102 + clk_register_fixed_factor(NULL, "spi_pclk", "cpu", 0, 1, 8); 103 + clks[ARTPEC6_CLK_SPI_SSPCLK] = 104 + clk_register_fixed_rate(NULL, "spi_sspclk", sys_refclk_name, 0, 105 + 50000000); 106 + 107 + clks[ARTPEC6_CLK_DBG_PCLK] = 108 + clk_register_fixed_factor(NULL, "dbg_pclk", "cpu", 0, 1, 8); 109 + 110 + clkdata->clk_data.clks = clkdata->clk_table; 111 + clkdata->clk_data.clk_num = ARTPEC6_CLK_NUMCLOCKS; 112 + 113 + of_clk_add_provider(np, of_clk_src_onecell_get, &clkdata->clk_data); 114 + } 115 + 116 + CLK_OF_DECLARE(artpec6_clkctrl, "axis,artpec6-clkctrl", 117 + of_artpec6_clkctrl_setup); 118 + 119 + static int artpec6_clkctrl_probe(struct platform_device *pdev) 120 + { 121 + int propidx; 122 + struct device_node *np = pdev->dev.of_node; 123 + struct device *dev = &pdev->dev; 124 + struct clk **clks = clkdata->clk_table; 125 + const char *sys_refclk_name; 126 + const char *i2s_refclk_name = NULL; 127 + const char *frac_clk_name[2] = { NULL, NULL }; 128 + const char *i2s_mux_parents[2]; 129 + u32 muxreg; 130 + int i; 131 + int err = 0; 132 + 133 + /* Mandatory parent clock. */ 134 + propidx = of_property_match_string(np, "clock-names", "sys_refclk"); 135 + if (propidx < 0) 136 + return -EINVAL; 137 + 138 + sys_refclk_name = of_clk_get_parent_name(np, propidx); 139 + 140 + /* Find clock names of optional parent clocks. */ 141 + propidx = of_property_match_string(np, "clock-names", "i2s_refclk"); 142 + if (propidx >= 0) 143 + i2s_refclk_name = of_clk_get_parent_name(np, propidx); 144 + 145 + propidx = of_property_match_string(np, "clock-names", "frac_clk0"); 146 + if (propidx >= 0) 147 + frac_clk_name[0] = of_clk_get_parent_name(np, propidx); 148 + propidx = of_property_match_string(np, "clock-names", "frac_clk1"); 149 + if (propidx >= 0) 150 + frac_clk_name[1] = of_clk_get_parent_name(np, propidx); 151 + 152 + spin_lock_init(&clkdata->i2scfg_lock); 153 + 154 + clks[ARTPEC6_CLK_NAND_CLKA] = 155 + clk_register_fixed_factor(dev, "nand_clka", "cpu", 0, 1, 8); 156 + clks[ARTPEC6_CLK_NAND_CLKB] = 157 + clk_register_fixed_rate(dev, "nand_clkb", sys_refclk_name, 0, 158 + 100000000); 159 + clks[ARTPEC6_CLK_ETH_ACLK] = 160 + clk_register_fixed_factor(dev, "eth_aclk", "cpu", 0, 1, 4); 161 + clks[ARTPEC6_CLK_DMA_ACLK] = 162 + clk_register_fixed_factor(dev, "dma_aclk", "cpu", 0, 1, 4); 163 + clks[ARTPEC6_CLK_PTP_REF] = 164 + clk_register_fixed_rate(dev, "ptp_ref", sys_refclk_name, 0, 165 + 100000000); 166 + clks[ARTPEC6_CLK_SD_PCLK] = 167 + clk_register_fixed_rate(dev, "sd_pclk", sys_refclk_name, 0, 168 + 100000000); 169 + clks[ARTPEC6_CLK_SD_IMCLK] = 170 + clk_register_fixed_rate(dev, "sd_imclk", sys_refclk_name, 0, 171 + 100000000); 172 + clks[ARTPEC6_CLK_I2S_HST] = 173 + clk_register_fixed_factor(dev, "i2s_hst", "cpu", 0, 1, 8); 174 + 175 + for (i = 0; i < NUM_I2S_CLOCKS; ++i) { 176 + if (i2s_refclk_name && frac_clk_name[i]) { 177 + i2s_mux_parents[0] = frac_clk_name[i]; 178 + i2s_mux_parents[1] = i2s_refclk_name; 179 + 180 + clks[i2s_clk_indexes[i]] = 181 + clk_register_mux(dev, i2s_clk_names[i], 182 + i2s_mux_parents, 2, 183 + CLK_SET_RATE_NO_REPARENT | 184 + CLK_SET_RATE_PARENT, 185 + clkdata->syscon_base + 0x14, i, 1, 186 + 0, &clkdata->i2scfg_lock); 187 + } else if (frac_clk_name[i]) { 188 + /* Lock the mux for internal clock reference. */ 189 + muxreg = readl(clkdata->syscon_base + 0x14); 190 + muxreg &= ~BIT(i); 191 + writel(muxreg, clkdata->syscon_base + 0x14); 192 + clks[i2s_clk_indexes[i]] = 193 + clk_register_fixed_factor(dev, i2s_clk_names[i], 194 + frac_clk_name[i], 0, 1, 195 + 1); 196 + } else if (i2s_refclk_name) { 197 + /* Lock the mux for external clock reference. */ 198 + muxreg = readl(clkdata->syscon_base + 0x14); 199 + muxreg |= BIT(i); 200 + writel(muxreg, clkdata->syscon_base + 0x14); 201 + clks[i2s_clk_indexes[i]] = 202 + clk_register_fixed_factor(dev, i2s_clk_names[i], 203 + i2s_refclk_name, 0, 1, 1); 204 + } 205 + } 206 + 207 + clks[ARTPEC6_CLK_I2C] = 208 + clk_register_fixed_rate(dev, "i2c", sys_refclk_name, 0, 100000000); 209 + 210 + clks[ARTPEC6_CLK_SYS_TIMER] = 211 + clk_register_fixed_rate(dev, "timer", sys_refclk_name, 0, 212 + 100000000); 213 + clks[ARTPEC6_CLK_FRACDIV_IN] = 214 + clk_register_fixed_rate(dev, "fracdiv_in", sys_refclk_name, 0, 215 + 600000000); 216 + 217 + for (i = 0; i < ARTPEC6_CLK_NUMCLOCKS; ++i) { 218 + if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -EPROBE_DEFER) { 219 + dev_err(dev, 220 + "Failed to register clock at index %d err=%ld\n", 221 + i, PTR_ERR(clks[i])); 222 + err = PTR_ERR(clks[i]); 223 + } 224 + } 225 + 226 + return err; 227 + } 228 + 229 + static const struct of_device_id artpec_clkctrl_of_match[] = { 230 + { .compatible = "axis,artpec6-clkctrl" }, 231 + {} 232 + }; 233 + 234 + static struct platform_driver artpec6_clkctrl_driver = { 235 + .probe = artpec6_clkctrl_probe, 236 + .driver = { 237 + .name = "artpec6_clkctrl", 238 + .of_match_table = artpec_clkctrl_of_match, 239 + }, 240 + }; 241 + 242 + builtin_platform_driver(artpec6_clkctrl_driver);
+1
drivers/clk/axs10x/Makefile
··· 1 + obj-y += i2s_pll_clock.o
+228
drivers/clk/axs10x/i2s_pll_clock.c
··· 1 + /* 2 + * Synopsys AXS10X SDP I2S PLL clock driver 3 + * 4 + * Copyright (C) 2016 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/err.h> 15 + #include <linux/device.h> 16 + #include <linux/of_address.h> 17 + #include <linux/slab.h> 18 + #include <linux/of.h> 19 + 20 + /* PLL registers addresses */ 21 + #define PLL_IDIV_REG 0x0 22 + #define PLL_FBDIV_REG 0x4 23 + #define PLL_ODIV0_REG 0x8 24 + #define PLL_ODIV1_REG 0xC 25 + 26 + struct i2s_pll_cfg { 27 + unsigned int rate; 28 + unsigned int idiv; 29 + unsigned int fbdiv; 30 + unsigned int odiv0; 31 + unsigned int odiv1; 32 + }; 33 + 34 + static const struct i2s_pll_cfg i2s_pll_cfg_27m[] = { 35 + /* 27 Mhz */ 36 + { 1024000, 0x104, 0x451, 0x10E38, 0x2000 }, 37 + { 1411200, 0x104, 0x596, 0x10D35, 0x2000 }, 38 + { 1536000, 0x208, 0xA28, 0x10B2C, 0x2000 }, 39 + { 2048000, 0x82, 0x451, 0x10E38, 0x2000 }, 40 + { 2822400, 0x82, 0x596, 0x10D35, 0x2000 }, 41 + { 3072000, 0x104, 0xA28, 0x10B2C, 0x2000 }, 42 + { 2116800, 0x82, 0x3CF, 0x10C30, 0x2000 }, 43 + { 2304000, 0x104, 0x79E, 0x10B2C, 0x2000 }, 44 + { 0, 0, 0, 0, 0 }, 45 + }; 46 + 47 + static const struct i2s_pll_cfg i2s_pll_cfg_28m[] = { 48 + /* 28.224 Mhz */ 49 + { 1024000, 0x82, 0x105, 0x107DF, 0x2000 }, 50 + { 1411200, 0x28A, 0x1, 0x10001, 0x2000 }, 51 + { 1536000, 0xA28, 0x187, 0x10042, 0x2000 }, 52 + { 2048000, 0x41, 0x105, 0x107DF, 0x2000 }, 53 + { 2822400, 0x145, 0x1, 0x10001, 0x2000 }, 54 + { 3072000, 0x514, 0x187, 0x10042, 0x2000 }, 55 + { 2116800, 0x514, 0x42, 0x10001, 0x2000 }, 56 + { 2304000, 0x619, 0x82, 0x10001, 0x2000 }, 57 + { 0, 0, 0, 0, 0 }, 58 + }; 59 + 60 + struct i2s_pll_clk { 61 + void __iomem *base; 62 + struct clk_hw hw; 63 + struct device *dev; 64 + }; 65 + 66 + static inline void i2s_pll_write(struct i2s_pll_clk *clk, unsigned int reg, 67 + unsigned int val) 68 + { 69 + writel_relaxed(val, clk->base + reg); 70 + } 71 + 72 + static inline unsigned int i2s_pll_read(struct i2s_pll_clk *clk, 73 + unsigned int reg) 74 + { 75 + return readl_relaxed(clk->base + reg); 76 + } 77 + 78 + static inline struct i2s_pll_clk *to_i2s_pll_clk(struct clk_hw *hw) 79 + { 80 + return container_of(hw, struct i2s_pll_clk, hw); 81 + } 82 + 83 + static inline unsigned int i2s_pll_get_value(unsigned int val) 84 + { 85 + return (val & 0x3F) + ((val >> 6) & 0x3F); 86 + } 87 + 88 + static const struct i2s_pll_cfg *i2s_pll_get_cfg(unsigned long prate) 89 + { 90 + switch (prate) { 91 + case 27000000: 92 + return i2s_pll_cfg_27m; 93 + case 28224000: 94 + return i2s_pll_cfg_28m; 95 + default: 96 + return NULL; 97 + } 98 + } 99 + 100 + static unsigned long i2s_pll_recalc_rate(struct clk_hw *hw, 101 + unsigned long parent_rate) 102 + { 103 + struct i2s_pll_clk *clk = to_i2s_pll_clk(hw); 104 + unsigned int idiv, fbdiv, odiv; 105 + 106 + idiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_IDIV_REG)); 107 + fbdiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_FBDIV_REG)); 108 + odiv = i2s_pll_get_value(i2s_pll_read(clk, PLL_ODIV0_REG)); 109 + 110 + return ((parent_rate / idiv) * fbdiv) / odiv; 111 + } 112 + 113 + static long i2s_pll_round_rate(struct clk_hw *hw, unsigned long rate, 114 + unsigned long *prate) 115 + { 116 + struct i2s_pll_clk *clk = to_i2s_pll_clk(hw); 117 + const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(*prate); 118 + int i; 119 + 120 + if (!pll_cfg) { 121 + dev_err(clk->dev, "invalid parent rate=%ld\n", *prate); 122 + return -EINVAL; 123 + } 124 + 125 + for (i = 0; pll_cfg[i].rate != 0; i++) 126 + if (pll_cfg[i].rate == rate) 127 + return rate; 128 + 129 + return -EINVAL; 130 + } 131 + 132 + static int i2s_pll_set_rate(struct clk_hw *hw, unsigned long rate, 133 + unsigned long parent_rate) 134 + { 135 + struct i2s_pll_clk *clk = to_i2s_pll_clk(hw); 136 + const struct i2s_pll_cfg *pll_cfg = i2s_pll_get_cfg(parent_rate); 137 + int i; 138 + 139 + if (!pll_cfg) { 140 + dev_err(clk->dev, "invalid parent rate=%ld\n", parent_rate); 141 + return -EINVAL; 142 + } 143 + 144 + for (i = 0; pll_cfg[i].rate != 0; i++) { 145 + if (pll_cfg[i].rate == rate) { 146 + i2s_pll_write(clk, PLL_IDIV_REG, pll_cfg[i].idiv); 147 + i2s_pll_write(clk, PLL_FBDIV_REG, pll_cfg[i].fbdiv); 148 + i2s_pll_write(clk, PLL_ODIV0_REG, pll_cfg[i].odiv0); 149 + i2s_pll_write(clk, PLL_ODIV1_REG, pll_cfg[i].odiv1); 150 + return 0; 151 + } 152 + } 153 + 154 + dev_err(clk->dev, "invalid rate=%ld, parent_rate=%ld\n", rate, 155 + parent_rate); 156 + return -EINVAL; 157 + } 158 + 159 + static const struct clk_ops i2s_pll_ops = { 160 + .recalc_rate = i2s_pll_recalc_rate, 161 + .round_rate = i2s_pll_round_rate, 162 + .set_rate = i2s_pll_set_rate, 163 + }; 164 + 165 + static int i2s_pll_clk_probe(struct platform_device *pdev) 166 + { 167 + struct device *dev = &pdev->dev; 168 + struct device_node *node = dev->of_node; 169 + const char *clk_name; 170 + const char *parent_name; 171 + struct clk *clk; 172 + struct i2s_pll_clk *pll_clk; 173 + struct clk_init_data init; 174 + struct resource *mem; 175 + 176 + pll_clk = devm_kzalloc(dev, sizeof(*pll_clk), GFP_KERNEL); 177 + if (!pll_clk) 178 + return -ENOMEM; 179 + 180 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 181 + pll_clk->base = devm_ioremap_resource(dev, mem); 182 + if (IS_ERR(pll_clk->base)) 183 + return PTR_ERR(pll_clk->base); 184 + 185 + clk_name = node->name; 186 + init.name = clk_name; 187 + init.ops = &i2s_pll_ops; 188 + parent_name = of_clk_get_parent_name(node, 0); 189 + init.parent_names = &parent_name; 190 + init.num_parents = 1; 191 + pll_clk->hw.init = &init; 192 + pll_clk->dev = dev; 193 + 194 + clk = devm_clk_register(dev, &pll_clk->hw); 195 + if (IS_ERR(clk)) { 196 + dev_err(dev, "failed to register %s clock (%ld)\n", 197 + clk_name, PTR_ERR(clk)); 198 + return PTR_ERR(clk); 199 + } 200 + 201 + return of_clk_add_provider(node, of_clk_src_simple_get, clk); 202 + } 203 + 204 + static int i2s_pll_clk_remove(struct platform_device *pdev) 205 + { 206 + of_clk_del_provider(pdev->dev.of_node); 207 + return 0; 208 + } 209 + 210 + static const struct of_device_id i2s_pll_clk_id[] = { 211 + { .compatible = "snps,axs10x-i2s-pll-clock", }, 212 + { }, 213 + }; 214 + MODULE_DEVICE_TABLE(of, i2s_pll_clk_id); 215 + 216 + static struct platform_driver i2s_pll_clk_driver = { 217 + .driver = { 218 + .name = "axs10x-i2s-pll-clock", 219 + .of_match_table = i2s_pll_clk_id, 220 + }, 221 + .probe = i2s_pll_clk_probe, 222 + .remove = i2s_pll_clk_remove, 223 + }; 224 + module_platform_driver(i2s_pll_clk_driver); 225 + 226 + MODULE_AUTHOR("Jose Abreu <joabreu@synopsys.com>"); 227 + MODULE_DESCRIPTION("Synopsys AXS10X SDP I2S PLL Clock Driver"); 228 + MODULE_LICENSE("GPL v2");
+722 -493
drivers/clk/bcm/clk-bcm2835.c
··· 12 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 13 * GNU General Public License for more details. 14 14 * 15 - * You should have received a copy of the GNU General Public License 16 - * along with this program; if not, write to the Free Software 17 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 15 */ 19 16 20 17 /** ··· 37 40 #include <linux/clk-provider.h> 38 41 #include <linux/clkdev.h> 39 42 #include <linux/clk/bcm2835.h> 43 + #include <linux/debugfs.h> 40 44 #include <linux/module.h> 41 45 #include <linux/of.h> 42 46 #include <linux/platform_device.h> ··· 49 51 #define CM_GNRICCTL 0x000 50 52 #define CM_GNRICDIV 0x004 51 53 # define CM_DIV_FRAC_BITS 12 54 + # define CM_DIV_FRAC_MASK GENMASK(CM_DIV_FRAC_BITS - 1, 0) 52 55 53 56 #define CM_VPUCTL 0x008 54 57 #define CM_VPUDIV 0x00c ··· 117 118 #define CM_SDCCTL 0x1a8 118 119 #define CM_SDCDIV 0x1ac 119 120 #define CM_ARMCTL 0x1b0 121 + #define CM_AVEOCTL 0x1b8 122 + #define CM_AVEODIV 0x1bc 120 123 #define CM_EMMCCTL 0x1c0 121 124 #define CM_EMMCDIV 0x1c4 122 125 ··· 129 128 # define CM_GATE BIT(CM_GATE_BIT) 130 129 # define CM_BUSY BIT(7) 131 130 # define CM_BUSYD BIT(8) 131 + # define CM_FRAC BIT(9) 132 132 # define CM_SRC_SHIFT 0 133 133 # define CM_SRC_BITS 4 134 134 # define CM_SRC_MASK 0xf ··· 299 297 struct bcm2835_cprman { 300 298 struct device *dev; 301 299 void __iomem *regs; 302 - spinlock_t regs_lock; 300 + spinlock_t regs_lock; /* spinlock for all clocks */ 303 301 const char *osc_name; 304 302 305 303 struct clk_onecell_data onecell; 306 - struct clk *clks[BCM2835_CLOCK_COUNT]; 304 + struct clk *clks[]; 307 305 }; 308 306 309 307 static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val) ··· 314 312 static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) 315 313 { 316 314 return readl(cprman->regs + reg); 315 + } 316 + 317 + static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base, 318 + struct debugfs_reg32 *regs, size_t nregs, 319 + struct dentry *dentry) 320 + { 321 + struct dentry *regdump; 322 + struct debugfs_regset32 *regset; 323 + 324 + regset = devm_kzalloc(cprman->dev, sizeof(*regset), GFP_KERNEL); 325 + if (!regset) 326 + return -ENOMEM; 327 + 328 + regset->regs = regs; 329 + regset->nregs = nregs; 330 + regset->base = cprman->regs + base; 331 + 332 + regdump = debugfs_create_regset32("regdump", S_IRUGO, dentry, 333 + regset); 334 + 335 + return regdump ? 0 : -ENOMEM; 317 336 } 318 337 319 338 /* ··· 400 377 static const struct bcm2835_pll_ana_bits bcm2835_ana_default = { 401 378 .mask0 = 0, 402 379 .set0 = 0, 403 - .mask1 = ~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), 380 + .mask1 = (u32)~(A2W_PLL_KI_MASK | A2W_PLL_KP_MASK), 404 381 .set1 = (2 << A2W_PLL_KI_SHIFT) | (8 << A2W_PLL_KP_SHIFT), 405 - .mask3 = ~A2W_PLL_KA_MASK, 382 + .mask3 = (u32)~A2W_PLL_KA_MASK, 406 383 .set3 = (2 << A2W_PLL_KA_SHIFT), 407 384 .fb_prediv_mask = BIT(14), 408 385 }; 409 386 410 387 static const struct bcm2835_pll_ana_bits bcm2835_ana_pllh = { 411 - .mask0 = ~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), 388 + .mask0 = (u32)~(A2W_PLLH_KA_MASK | A2W_PLLH_KI_LOW_MASK), 412 389 .set0 = (2 << A2W_PLLH_KA_SHIFT) | (2 << A2W_PLLH_KI_LOW_SHIFT), 413 - .mask1 = ~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), 390 + .mask1 = (u32)~(A2W_PLLH_KI_HIGH_MASK | A2W_PLLH_KP_MASK), 414 391 .set1 = (6 << A2W_PLLH_KP_SHIFT), 415 392 .mask3 = 0, 416 393 .set3 = 0, 417 394 .fb_prediv_mask = BIT(11), 418 395 }; 419 396 420 - /* 421 - * PLLA is the auxiliary PLL, used to drive the CCP2 (Compact Camera 422 - * Port 2) transmitter clock. 423 - * 424 - * It is in the PX LDO power domain, which is on when the AUDIO domain 425 - * is on. 426 - */ 427 - static const struct bcm2835_pll_data bcm2835_plla_data = { 428 - .name = "plla", 429 - .cm_ctrl_reg = CM_PLLA, 430 - .a2w_ctrl_reg = A2W_PLLA_CTRL, 431 - .frac_reg = A2W_PLLA_FRAC, 432 - .ana_reg_base = A2W_PLLA_ANA0, 433 - .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE, 434 - .lock_mask = CM_LOCK_FLOCKA, 435 - 436 - .ana = &bcm2835_ana_default, 437 - 438 - .min_rate = 600000000u, 439 - .max_rate = 2400000000u, 440 - .max_fb_rate = BCM2835_MAX_FB_RATE, 441 - }; 442 - 443 - /* PLLB is used for the ARM's clock. */ 444 - static const struct bcm2835_pll_data bcm2835_pllb_data = { 445 - .name = "pllb", 446 - .cm_ctrl_reg = CM_PLLB, 447 - .a2w_ctrl_reg = A2W_PLLB_CTRL, 448 - .frac_reg = A2W_PLLB_FRAC, 449 - .ana_reg_base = A2W_PLLB_ANA0, 450 - .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, 451 - .lock_mask = CM_LOCK_FLOCKB, 452 - 453 - .ana = &bcm2835_ana_default, 454 - 455 - .min_rate = 600000000u, 456 - .max_rate = 3000000000u, 457 - .max_fb_rate = BCM2835_MAX_FB_RATE, 458 - }; 459 - 460 - /* 461 - * PLLC is the core PLL, used to drive the core VPU clock. 462 - * 463 - * It is in the PX LDO power domain, which is on when the AUDIO domain 464 - * is on. 465 - */ 466 - static const struct bcm2835_pll_data bcm2835_pllc_data = { 467 - .name = "pllc", 468 - .cm_ctrl_reg = CM_PLLC, 469 - .a2w_ctrl_reg = A2W_PLLC_CTRL, 470 - .frac_reg = A2W_PLLC_FRAC, 471 - .ana_reg_base = A2W_PLLC_ANA0, 472 - .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, 473 - .lock_mask = CM_LOCK_FLOCKC, 474 - 475 - .ana = &bcm2835_ana_default, 476 - 477 - .min_rate = 600000000u, 478 - .max_rate = 3000000000u, 479 - .max_fb_rate = BCM2835_MAX_FB_RATE, 480 - }; 481 - 482 - /* 483 - * PLLD is the display PLL, used to drive DSI display panels. 484 - * 485 - * It is in the PX LDO power domain, which is on when the AUDIO domain 486 - * is on. 487 - */ 488 - static const struct bcm2835_pll_data bcm2835_plld_data = { 489 - .name = "plld", 490 - .cm_ctrl_reg = CM_PLLD, 491 - .a2w_ctrl_reg = A2W_PLLD_CTRL, 492 - .frac_reg = A2W_PLLD_FRAC, 493 - .ana_reg_base = A2W_PLLD_ANA0, 494 - .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE, 495 - .lock_mask = CM_LOCK_FLOCKD, 496 - 497 - .ana = &bcm2835_ana_default, 498 - 499 - .min_rate = 600000000u, 500 - .max_rate = 2400000000u, 501 - .max_fb_rate = BCM2835_MAX_FB_RATE, 502 - }; 503 - 504 - /* 505 - * PLLH is used to supply the pixel clock or the AUX clock for the TV 506 - * encoder. 507 - * 508 - * It is in the HDMI power domain. 509 - */ 510 - static const struct bcm2835_pll_data bcm2835_pllh_data = { 511 - "pllh", 512 - .cm_ctrl_reg = CM_PLLH, 513 - .a2w_ctrl_reg = A2W_PLLH_CTRL, 514 - .frac_reg = A2W_PLLH_FRAC, 515 - .ana_reg_base = A2W_PLLH_ANA0, 516 - .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, 517 - .lock_mask = CM_LOCK_FLOCKH, 518 - 519 - .ana = &bcm2835_ana_pllh, 520 - 521 - .min_rate = 600000000u, 522 - .max_rate = 3000000000u, 523 - .max_fb_rate = BCM2835_MAX_FB_RATE, 524 - }; 525 - 526 397 struct bcm2835_pll_divider_data { 527 398 const char *name; 528 - const struct bcm2835_pll_data *source_pll; 399 + const char *source_pll; 400 + 529 401 u32 cm_reg; 530 402 u32 a2w_reg; 531 403 532 404 u32 load_mask; 533 405 u32 hold_mask; 534 406 u32 fixed_divider; 535 - }; 536 - 537 - static const struct bcm2835_pll_divider_data bcm2835_plla_core_data = { 538 - .name = "plla_core", 539 - .source_pll = &bcm2835_plla_data, 540 - .cm_reg = CM_PLLA, 541 - .a2w_reg = A2W_PLLA_CORE, 542 - .load_mask = CM_PLLA_LOADCORE, 543 - .hold_mask = CM_PLLA_HOLDCORE, 544 - .fixed_divider = 1, 545 - }; 546 - 547 - static const struct bcm2835_pll_divider_data bcm2835_plla_per_data = { 548 - .name = "plla_per", 549 - .source_pll = &bcm2835_plla_data, 550 - .cm_reg = CM_PLLA, 551 - .a2w_reg = A2W_PLLA_PER, 552 - .load_mask = CM_PLLA_LOADPER, 553 - .hold_mask = CM_PLLA_HOLDPER, 554 - .fixed_divider = 1, 555 - }; 556 - 557 - static const struct bcm2835_pll_divider_data bcm2835_pllb_arm_data = { 558 - .name = "pllb_arm", 559 - .source_pll = &bcm2835_pllb_data, 560 - .cm_reg = CM_PLLB, 561 - .a2w_reg = A2W_PLLB_ARM, 562 - .load_mask = CM_PLLB_LOADARM, 563 - .hold_mask = CM_PLLB_HOLDARM, 564 - .fixed_divider = 1, 565 - }; 566 - 567 - static const struct bcm2835_pll_divider_data bcm2835_pllc_core0_data = { 568 - .name = "pllc_core0", 569 - .source_pll = &bcm2835_pllc_data, 570 - .cm_reg = CM_PLLC, 571 - .a2w_reg = A2W_PLLC_CORE0, 572 - .load_mask = CM_PLLC_LOADCORE0, 573 - .hold_mask = CM_PLLC_HOLDCORE0, 574 - .fixed_divider = 1, 575 - }; 576 - 577 - static const struct bcm2835_pll_divider_data bcm2835_pllc_core1_data = { 578 - .name = "pllc_core1", .source_pll = &bcm2835_pllc_data, 579 - .cm_reg = CM_PLLC, A2W_PLLC_CORE1, 580 - .load_mask = CM_PLLC_LOADCORE1, 581 - .hold_mask = CM_PLLC_HOLDCORE1, 582 - .fixed_divider = 1, 583 - }; 584 - 585 - static const struct bcm2835_pll_divider_data bcm2835_pllc_core2_data = { 586 - .name = "pllc_core2", 587 - .source_pll = &bcm2835_pllc_data, 588 - .cm_reg = CM_PLLC, 589 - .a2w_reg = A2W_PLLC_CORE2, 590 - .load_mask = CM_PLLC_LOADCORE2, 591 - .hold_mask = CM_PLLC_HOLDCORE2, 592 - .fixed_divider = 1, 593 - }; 594 - 595 - static const struct bcm2835_pll_divider_data bcm2835_pllc_per_data = { 596 - .name = "pllc_per", 597 - .source_pll = &bcm2835_pllc_data, 598 - .cm_reg = CM_PLLC, 599 - .a2w_reg = A2W_PLLC_PER, 600 - .load_mask = CM_PLLC_LOADPER, 601 - .hold_mask = CM_PLLC_HOLDPER, 602 - .fixed_divider = 1, 603 - }; 604 - 605 - static const struct bcm2835_pll_divider_data bcm2835_plld_core_data = { 606 - .name = "plld_core", 607 - .source_pll = &bcm2835_plld_data, 608 - .cm_reg = CM_PLLD, 609 - .a2w_reg = A2W_PLLD_CORE, 610 - .load_mask = CM_PLLD_LOADCORE, 611 - .hold_mask = CM_PLLD_HOLDCORE, 612 - .fixed_divider = 1, 613 - }; 614 - 615 - static const struct bcm2835_pll_divider_data bcm2835_plld_per_data = { 616 - .name = "plld_per", 617 - .source_pll = &bcm2835_plld_data, 618 - .cm_reg = CM_PLLD, 619 - .a2w_reg = A2W_PLLD_PER, 620 - .load_mask = CM_PLLD_LOADPER, 621 - .hold_mask = CM_PLLD_HOLDPER, 622 - .fixed_divider = 1, 623 - }; 624 - 625 - static const struct bcm2835_pll_divider_data bcm2835_pllh_rcal_data = { 626 - .name = "pllh_rcal", 627 - .source_pll = &bcm2835_pllh_data, 628 - .cm_reg = CM_PLLH, 629 - .a2w_reg = A2W_PLLH_RCAL, 630 - .load_mask = CM_PLLH_LOADRCAL, 631 - .hold_mask = 0, 632 - .fixed_divider = 10, 633 - }; 634 - 635 - static const struct bcm2835_pll_divider_data bcm2835_pllh_aux_data = { 636 - .name = "pllh_aux", 637 - .source_pll = &bcm2835_pllh_data, 638 - .cm_reg = CM_PLLH, 639 - .a2w_reg = A2W_PLLH_AUX, 640 - .load_mask = CM_PLLH_LOADAUX, 641 - .hold_mask = 0, 642 - .fixed_divider = 10, 643 - }; 644 - 645 - static const struct bcm2835_pll_divider_data bcm2835_pllh_pix_data = { 646 - .name = "pllh_pix", 647 - .source_pll = &bcm2835_pllh_data, 648 - .cm_reg = CM_PLLH, 649 - .a2w_reg = A2W_PLLH_PIX, 650 - .load_mask = CM_PLLH_LOADPIX, 651 - .hold_mask = 0, 652 - .fixed_divider = 10, 653 407 }; 654 408 655 409 struct bcm2835_clock_data { ··· 444 644 u32 frac_bits; 445 645 446 646 bool is_vpu_clock; 647 + bool is_mash_clock; 447 648 }; 448 649 449 - static const char *const bcm2835_clock_per_parents[] = { 450 - "gnd", 451 - "xosc", 452 - "testdebug0", 453 - "testdebug1", 454 - "plla_per", 455 - "pllc_per", 456 - "plld_per", 457 - "pllh_aux", 458 - }; 650 + struct bcm2835_gate_data { 651 + const char *name; 652 + const char *parent; 459 653 460 - static const char *const bcm2835_clock_vpu_parents[] = { 461 - "gnd", 462 - "xosc", 463 - "testdebug0", 464 - "testdebug1", 465 - "plla_core", 466 - "pllc_core0", 467 - "plld_core", 468 - "pllh_aux", 469 - "pllc_core1", 470 - "pllc_core2", 471 - }; 472 - 473 - static const char *const bcm2835_clock_osc_parents[] = { 474 - "gnd", 475 - "xosc", 476 - "testdebug0", 477 - "testdebug1" 478 - }; 479 - 480 - /* 481 - * Used for a 1Mhz clock for the system clocksource, and also used by 482 - * the watchdog timer and the camera pulse generator. 483 - */ 484 - static const struct bcm2835_clock_data bcm2835_clock_timer_data = { 485 - .name = "timer", 486 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), 487 - .parents = bcm2835_clock_osc_parents, 488 - .ctl_reg = CM_TIMERCTL, 489 - .div_reg = CM_TIMERDIV, 490 - .int_bits = 6, 491 - .frac_bits = 12, 492 - }; 493 - 494 - /* One Time Programmable Memory clock. Maximum 10Mhz. */ 495 - static const struct bcm2835_clock_data bcm2835_clock_otp_data = { 496 - .name = "otp", 497 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), 498 - .parents = bcm2835_clock_osc_parents, 499 - .ctl_reg = CM_OTPCTL, 500 - .div_reg = CM_OTPDIV, 501 - .int_bits = 4, 502 - .frac_bits = 0, 503 - }; 504 - 505 - /* 506 - * VPU clock. This doesn't have an enable bit, since it drives the 507 - * bus for everything else, and is special so it doesn't need to be 508 - * gated for rate changes. It is also known as "clk_audio" in various 509 - * hardware documentation. 510 - */ 511 - static const struct bcm2835_clock_data bcm2835_clock_vpu_data = { 512 - .name = "vpu", 513 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), 514 - .parents = bcm2835_clock_vpu_parents, 515 - .ctl_reg = CM_VPUCTL, 516 - .div_reg = CM_VPUDIV, 517 - .int_bits = 12, 518 - .frac_bits = 8, 519 - .is_vpu_clock = true, 520 - }; 521 - 522 - static const struct bcm2835_clock_data bcm2835_clock_v3d_data = { 523 - .name = "v3d", 524 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), 525 - .parents = bcm2835_clock_vpu_parents, 526 - .ctl_reg = CM_V3DCTL, 527 - .div_reg = CM_V3DDIV, 528 - .int_bits = 4, 529 - .frac_bits = 8, 530 - }; 531 - 532 - static const struct bcm2835_clock_data bcm2835_clock_isp_data = { 533 - .name = "isp", 534 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), 535 - .parents = bcm2835_clock_vpu_parents, 536 - .ctl_reg = CM_ISPCTL, 537 - .div_reg = CM_ISPDIV, 538 - .int_bits = 4, 539 - .frac_bits = 8, 540 - }; 541 - 542 - static const struct bcm2835_clock_data bcm2835_clock_h264_data = { 543 - .name = "h264", 544 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), 545 - .parents = bcm2835_clock_vpu_parents, 546 - .ctl_reg = CM_H264CTL, 547 - .div_reg = CM_H264DIV, 548 - .int_bits = 4, 549 - .frac_bits = 8, 550 - }; 551 - 552 - /* TV encoder clock. Only operating frequency is 108Mhz. */ 553 - static const struct bcm2835_clock_data bcm2835_clock_vec_data = { 554 - .name = "vec", 555 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), 556 - .parents = bcm2835_clock_per_parents, 557 - .ctl_reg = CM_VECCTL, 558 - .div_reg = CM_VECDIV, 559 - .int_bits = 4, 560 - .frac_bits = 0, 561 - }; 562 - 563 - static const struct bcm2835_clock_data bcm2835_clock_uart_data = { 564 - .name = "uart", 565 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), 566 - .parents = bcm2835_clock_per_parents, 567 - .ctl_reg = CM_UARTCTL, 568 - .div_reg = CM_UARTDIV, 569 - .int_bits = 10, 570 - .frac_bits = 12, 571 - }; 572 - 573 - /* HDMI state machine */ 574 - static const struct bcm2835_clock_data bcm2835_clock_hsm_data = { 575 - .name = "hsm", 576 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), 577 - .parents = bcm2835_clock_per_parents, 578 - .ctl_reg = CM_HSMCTL, 579 - .div_reg = CM_HSMDIV, 580 - .int_bits = 4, 581 - .frac_bits = 8, 582 - }; 583 - 584 - /* 585 - * Secondary SDRAM clock. Used for low-voltage modes when the PLL in 586 - * the SDRAM controller can't be used. 587 - */ 588 - static const struct bcm2835_clock_data bcm2835_clock_sdram_data = { 589 - .name = "sdram", 590 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), 591 - .parents = bcm2835_clock_vpu_parents, 592 - .ctl_reg = CM_SDCCTL, 593 - .div_reg = CM_SDCDIV, 594 - .int_bits = 6, 595 - .frac_bits = 0, 596 - }; 597 - 598 - /* Clock for the temperature sensor. Generally run at 2Mhz, max 5Mhz. */ 599 - static const struct bcm2835_clock_data bcm2835_clock_tsens_data = { 600 - .name = "tsens", 601 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), 602 - .parents = bcm2835_clock_osc_parents, 603 - .ctl_reg = CM_TSENSCTL, 604 - .div_reg = CM_TSENSDIV, 605 - .int_bits = 5, 606 - .frac_bits = 0, 607 - }; 608 - 609 - /* Arasan EMMC clock */ 610 - static const struct bcm2835_clock_data bcm2835_clock_emmc_data = { 611 - .name = "emmc", 612 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), 613 - .parents = bcm2835_clock_per_parents, 614 - .ctl_reg = CM_EMMCCTL, 615 - .div_reg = CM_EMMCDIV, 616 - .int_bits = 4, 617 - .frac_bits = 8, 618 - }; 619 - 620 - static const struct bcm2835_clock_data bcm2835_clock_pwm_data = { 621 - .name = "pwm", 622 - .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), 623 - .parents = bcm2835_clock_per_parents, 624 - .ctl_reg = CM_PWMCTL, 625 - .div_reg = CM_PWMDIV, 626 - .int_bits = 12, 627 - .frac_bits = 12, 654 + u32 ctl_reg; 628 655 }; 629 656 630 657 struct bcm2835_pll { ··· 537 910 struct bcm2835_cprman *cprman = pll->cprman; 538 911 const struct bcm2835_pll_data *data = pll->data; 539 912 540 - cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST); 541 - cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN); 913 + spin_lock(&cprman->regs_lock); 914 + cprman_write(cprman, data->cm_ctrl_reg, 915 + cprman_read(cprman, data->cm_ctrl_reg) | 916 + CM_PLL_ANARST); 917 + cprman_write(cprman, data->a2w_ctrl_reg, 918 + cprman_read(cprman, data->a2w_ctrl_reg) | 919 + A2W_PLL_CTRL_PWRDN); 920 + spin_unlock(&cprman->regs_lock); 542 921 } 543 922 544 923 static int bcm2835_pll_on(struct clk_hw *hw) ··· 553 920 struct bcm2835_cprman *cprman = pll->cprman; 554 921 const struct bcm2835_pll_data *data = pll->data; 555 922 ktime_t timeout; 923 + 924 + cprman_write(cprman, data->a2w_ctrl_reg, 925 + cprman_read(cprman, data->a2w_ctrl_reg) & 926 + ~A2W_PLL_CTRL_PWRDN); 556 927 557 928 /* Take the PLL out of reset. */ 558 929 cprman_write(cprman, data->cm_ctrl_reg, ··· 667 1030 return 0; 668 1031 } 669 1032 1033 + static int bcm2835_pll_debug_init(struct clk_hw *hw, 1034 + struct dentry *dentry) 1035 + { 1036 + struct bcm2835_pll *pll = container_of(hw, struct bcm2835_pll, hw); 1037 + struct bcm2835_cprman *cprman = pll->cprman; 1038 + const struct bcm2835_pll_data *data = pll->data; 1039 + struct debugfs_reg32 *regs; 1040 + 1041 + regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); 1042 + if (!regs) 1043 + return -ENOMEM; 1044 + 1045 + regs[0].name = "cm_ctrl"; 1046 + regs[0].offset = data->cm_ctrl_reg; 1047 + regs[1].name = "a2w_ctrl"; 1048 + regs[1].offset = data->a2w_ctrl_reg; 1049 + regs[2].name = "frac"; 1050 + regs[2].offset = data->frac_reg; 1051 + regs[3].name = "ana0"; 1052 + regs[3].offset = data->ana_reg_base + 0 * 4; 1053 + regs[4].name = "ana1"; 1054 + regs[4].offset = data->ana_reg_base + 1 * 4; 1055 + regs[5].name = "ana2"; 1056 + regs[5].offset = data->ana_reg_base + 2 * 4; 1057 + regs[6].name = "ana3"; 1058 + regs[6].offset = data->ana_reg_base + 3 * 4; 1059 + 1060 + return bcm2835_debugfs_regset(cprman, 0, regs, 7, dentry); 1061 + } 1062 + 670 1063 static const struct clk_ops bcm2835_pll_clk_ops = { 671 1064 .is_prepared = bcm2835_pll_is_on, 672 1065 .prepare = bcm2835_pll_on, ··· 704 1037 .recalc_rate = bcm2835_pll_get_rate, 705 1038 .set_rate = bcm2835_pll_set_rate, 706 1039 .round_rate = bcm2835_pll_round_rate, 1040 + .debug_init = bcm2835_pll_debug_init, 707 1041 }; 708 1042 709 1043 struct bcm2835_pll_divider { ··· 747 1079 struct bcm2835_cprman *cprman = divider->cprman; 748 1080 const struct bcm2835_pll_divider_data *data = divider->data; 749 1081 1082 + spin_lock(&cprman->regs_lock); 750 1083 cprman_write(cprman, data->cm_reg, 751 1084 (cprman_read(cprman, data->cm_reg) & 752 1085 ~data->load_mask) | data->hold_mask); 753 1086 cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE); 1087 + spin_unlock(&cprman->regs_lock); 754 1088 } 755 1089 756 1090 static int bcm2835_pll_divider_on(struct clk_hw *hw) ··· 761 1091 struct bcm2835_cprman *cprman = divider->cprman; 762 1092 const struct bcm2835_pll_divider_data *data = divider->data; 763 1093 1094 + spin_lock(&cprman->regs_lock); 764 1095 cprman_write(cprman, data->a2w_reg, 765 1096 cprman_read(cprman, data->a2w_reg) & 766 1097 ~A2W_PLL_CHANNEL_DISABLE); 767 1098 768 1099 cprman_write(cprman, data->cm_reg, 769 1100 cprman_read(cprman, data->cm_reg) & ~data->hold_mask); 1101 + spin_unlock(&cprman->regs_lock); 770 1102 771 1103 return 0; 772 1104 } ··· 796 1124 return 0; 797 1125 } 798 1126 1127 + static int bcm2835_pll_divider_debug_init(struct clk_hw *hw, 1128 + struct dentry *dentry) 1129 + { 1130 + struct bcm2835_pll_divider *divider = bcm2835_pll_divider_from_hw(hw); 1131 + struct bcm2835_cprman *cprman = divider->cprman; 1132 + const struct bcm2835_pll_divider_data *data = divider->data; 1133 + struct debugfs_reg32 *regs; 1134 + 1135 + regs = devm_kzalloc(cprman->dev, 7 * sizeof(*regs), GFP_KERNEL); 1136 + if (!regs) 1137 + return -ENOMEM; 1138 + 1139 + regs[0].name = "cm"; 1140 + regs[0].offset = data->cm_reg; 1141 + regs[1].name = "a2w"; 1142 + regs[1].offset = data->a2w_reg; 1143 + 1144 + return bcm2835_debugfs_regset(cprman, 0, regs, 2, dentry); 1145 + } 1146 + 799 1147 static const struct clk_ops bcm2835_pll_divider_clk_ops = { 800 1148 .is_prepared = bcm2835_pll_divider_is_on, 801 1149 .prepare = bcm2835_pll_divider_on, ··· 823 1131 .recalc_rate = bcm2835_pll_divider_get_rate, 824 1132 .set_rate = bcm2835_pll_divider_set_rate, 825 1133 .round_rate = bcm2835_pll_divider_round_rate, 1134 + .debug_init = bcm2835_pll_divider_debug_init, 826 1135 }; 827 1136 828 1137 /* ··· 863 1170 GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1; 864 1171 u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS; 865 1172 u64 rem; 866 - u32 div; 1173 + u32 div, mindiv, maxdiv; 867 1174 868 1175 rem = do_div(temp, rate); 869 1176 div = temp; ··· 873 1180 div += unused_frac_mask + 1; 874 1181 div &= ~unused_frac_mask; 875 1182 876 - /* Clamp to the limits. */ 877 - div = max(div, unused_frac_mask + 1); 878 - div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, 879 - CM_DIV_FRAC_BITS - data->frac_bits)); 1183 + /* different clamping limits apply for a mash clock */ 1184 + if (data->is_mash_clock) { 1185 + /* clamp to min divider of 2 */ 1186 + mindiv = 2 << CM_DIV_FRAC_BITS; 1187 + /* clamp to the highest possible integer divider */ 1188 + maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS; 1189 + } else { 1190 + /* clamp to min divider of 1 */ 1191 + mindiv = 1 << CM_DIV_FRAC_BITS; 1192 + /* clamp to the highest possible fractional divider */ 1193 + maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1, 1194 + CM_DIV_FRAC_BITS - data->frac_bits); 1195 + } 1196 + 1197 + /* apply the clamping limits */ 1198 + div = max_t(u32, div, mindiv); 1199 + div = min_t(u32, div, maxdiv); 880 1200 881 1201 return div; 882 1202 } ··· 983 1277 struct bcm2835_cprman *cprman = clock->cprman; 984 1278 const struct bcm2835_clock_data *data = clock->data; 985 1279 u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); 1280 + u32 ctl; 1281 + 1282 + spin_lock(&cprman->regs_lock); 1283 + 1284 + /* 1285 + * Setting up frac support 1286 + * 1287 + * In principle it is recommended to stop/start the clock first, 1288 + * but as we set CLK_SET_RATE_GATE during registration of the 1289 + * clock this requirement should be take care of by the 1290 + * clk-framework. 1291 + */ 1292 + ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC; 1293 + ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0; 1294 + cprman_write(cprman, data->ctl_reg, ctl); 986 1295 987 1296 cprman_write(cprman, data->div_reg, div); 1297 + 1298 + spin_unlock(&cprman->regs_lock); 988 1299 989 1300 return 0; 990 1301 } 991 1302 992 1303 static int bcm2835_clock_determine_rate(struct clk_hw *hw, 993 - struct clk_rate_request *req) 1304 + struct clk_rate_request *req) 994 1305 { 995 1306 struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); 996 1307 struct clk_hw *parent, *best_parent = NULL; ··· 1065 1342 return (src & CM_SRC_MASK) >> CM_SRC_SHIFT; 1066 1343 } 1067 1344 1345 + static struct debugfs_reg32 bcm2835_debugfs_clock_reg32[] = { 1346 + { 1347 + .name = "ctl", 1348 + .offset = 0, 1349 + }, 1350 + { 1351 + .name = "div", 1352 + .offset = 4, 1353 + }, 1354 + }; 1355 + 1356 + static int bcm2835_clock_debug_init(struct clk_hw *hw, 1357 + struct dentry *dentry) 1358 + { 1359 + struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); 1360 + struct bcm2835_cprman *cprman = clock->cprman; 1361 + const struct bcm2835_clock_data *data = clock->data; 1362 + 1363 + return bcm2835_debugfs_regset( 1364 + cprman, data->ctl_reg, 1365 + bcm2835_debugfs_clock_reg32, 1366 + ARRAY_SIZE(bcm2835_debugfs_clock_reg32), 1367 + dentry); 1368 + } 1068 1369 1069 1370 static const struct clk_ops bcm2835_clock_clk_ops = { 1070 1371 .is_prepared = bcm2835_clock_is_on, ··· 1099 1352 .determine_rate = bcm2835_clock_determine_rate, 1100 1353 .set_parent = bcm2835_clock_set_parent, 1101 1354 .get_parent = bcm2835_clock_get_parent, 1355 + .debug_init = bcm2835_clock_debug_init, 1102 1356 }; 1103 1357 1104 1358 static int bcm2835_vpu_clock_is_on(struct clk_hw *hw) ··· 1118 1370 .determine_rate = bcm2835_clock_determine_rate, 1119 1371 .set_parent = bcm2835_clock_set_parent, 1120 1372 .get_parent = bcm2835_clock_get_parent, 1373 + .debug_init = bcm2835_clock_debug_init, 1121 1374 }; 1122 1375 1123 1376 static struct clk *bcm2835_register_pll(struct bcm2835_cprman *cprman, ··· 1167 1418 1168 1419 memset(&init, 0, sizeof(init)); 1169 1420 1170 - init.parent_names = &data->source_pll->name; 1421 + init.parent_names = &data->source_pll; 1171 1422 init.num_parents = 1; 1172 1423 init.name = divider_name; 1173 1424 init.ops = &bcm2835_pll_divider_clk_ops; ··· 1250 1501 return devm_clk_register(cprman->dev, &clock->hw); 1251 1502 } 1252 1503 1504 + static struct clk *bcm2835_register_gate(struct bcm2835_cprman *cprman, 1505 + const struct bcm2835_gate_data *data) 1506 + { 1507 + return clk_register_gate(cprman->dev, data->name, data->parent, 1508 + CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 1509 + cprman->regs + data->ctl_reg, 1510 + CM_GATE_BIT, 0, &cprman->regs_lock); 1511 + } 1512 + 1513 + typedef struct clk *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman, 1514 + const void *data); 1515 + struct bcm2835_clk_desc { 1516 + bcm2835_clk_register clk_register; 1517 + const void *data; 1518 + }; 1519 + 1520 + /* assignment helper macros for different clock types */ 1521 + #define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \ 1522 + .data = __VA_ARGS__ } 1523 + #define REGISTER_PLL(...) _REGISTER(&bcm2835_register_pll, \ 1524 + &(struct bcm2835_pll_data) \ 1525 + {__VA_ARGS__}) 1526 + #define REGISTER_PLL_DIV(...) _REGISTER(&bcm2835_register_pll_divider, \ 1527 + &(struct bcm2835_pll_divider_data) \ 1528 + {__VA_ARGS__}) 1529 + #define REGISTER_CLK(...) _REGISTER(&bcm2835_register_clock, \ 1530 + &(struct bcm2835_clock_data) \ 1531 + {__VA_ARGS__}) 1532 + #define REGISTER_GATE(...) _REGISTER(&bcm2835_register_gate, \ 1533 + &(struct bcm2835_gate_data) \ 1534 + {__VA_ARGS__}) 1535 + 1536 + /* parent mux arrays plus helper macros */ 1537 + 1538 + /* main oscillator parent mux */ 1539 + static const char *const bcm2835_clock_osc_parents[] = { 1540 + "gnd", 1541 + "xosc", 1542 + "testdebug0", 1543 + "testdebug1" 1544 + }; 1545 + 1546 + #define REGISTER_OSC_CLK(...) REGISTER_CLK( \ 1547 + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents), \ 1548 + .parents = bcm2835_clock_osc_parents, \ 1549 + __VA_ARGS__) 1550 + 1551 + /* main peripherial parent mux */ 1552 + static const char *const bcm2835_clock_per_parents[] = { 1553 + "gnd", 1554 + "xosc", 1555 + "testdebug0", 1556 + "testdebug1", 1557 + "plla_per", 1558 + "pllc_per", 1559 + "plld_per", 1560 + "pllh_aux", 1561 + }; 1562 + 1563 + #define REGISTER_PER_CLK(...) REGISTER_CLK( \ 1564 + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), \ 1565 + .parents = bcm2835_clock_per_parents, \ 1566 + __VA_ARGS__) 1567 + 1568 + /* main vpu parent mux */ 1569 + static const char *const bcm2835_clock_vpu_parents[] = { 1570 + "gnd", 1571 + "xosc", 1572 + "testdebug0", 1573 + "testdebug1", 1574 + "plla_core", 1575 + "pllc_core0", 1576 + "plld_core", 1577 + "pllh_aux", 1578 + "pllc_core1", 1579 + "pllc_core2", 1580 + }; 1581 + 1582 + #define REGISTER_VPU_CLK(...) REGISTER_CLK( \ 1583 + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents), \ 1584 + .parents = bcm2835_clock_vpu_parents, \ 1585 + __VA_ARGS__) 1586 + 1587 + /* 1588 + * the real definition of all the pll, pll_dividers and clocks 1589 + * these make use of the above REGISTER_* macros 1590 + */ 1591 + static const struct bcm2835_clk_desc clk_desc_array[] = { 1592 + /* the PLL + PLL dividers */ 1593 + 1594 + /* 1595 + * PLLA is the auxiliary PLL, used to drive the CCP2 1596 + * (Compact Camera Port 2) transmitter clock. 1597 + * 1598 + * It is in the PX LDO power domain, which is on when the 1599 + * AUDIO domain is on. 1600 + */ 1601 + [BCM2835_PLLA] = REGISTER_PLL( 1602 + .name = "plla", 1603 + .cm_ctrl_reg = CM_PLLA, 1604 + .a2w_ctrl_reg = A2W_PLLA_CTRL, 1605 + .frac_reg = A2W_PLLA_FRAC, 1606 + .ana_reg_base = A2W_PLLA_ANA0, 1607 + .reference_enable_mask = A2W_XOSC_CTRL_PLLA_ENABLE, 1608 + .lock_mask = CM_LOCK_FLOCKA, 1609 + 1610 + .ana = &bcm2835_ana_default, 1611 + 1612 + .min_rate = 600000000u, 1613 + .max_rate = 2400000000u, 1614 + .max_fb_rate = BCM2835_MAX_FB_RATE), 1615 + [BCM2835_PLLA_CORE] = REGISTER_PLL_DIV( 1616 + .name = "plla_core", 1617 + .source_pll = "plla", 1618 + .cm_reg = CM_PLLA, 1619 + .a2w_reg = A2W_PLLA_CORE, 1620 + .load_mask = CM_PLLA_LOADCORE, 1621 + .hold_mask = CM_PLLA_HOLDCORE, 1622 + .fixed_divider = 1), 1623 + [BCM2835_PLLA_PER] = REGISTER_PLL_DIV( 1624 + .name = "plla_per", 1625 + .source_pll = "plla", 1626 + .cm_reg = CM_PLLA, 1627 + .a2w_reg = A2W_PLLA_PER, 1628 + .load_mask = CM_PLLA_LOADPER, 1629 + .hold_mask = CM_PLLA_HOLDPER, 1630 + .fixed_divider = 1), 1631 + [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( 1632 + .name = "plla_dsi0", 1633 + .source_pll = "plla", 1634 + .cm_reg = CM_PLLA, 1635 + .a2w_reg = A2W_PLLA_DSI0, 1636 + .load_mask = CM_PLLA_LOADDSI0, 1637 + .hold_mask = CM_PLLA_HOLDDSI0, 1638 + .fixed_divider = 1), 1639 + [BCM2835_PLLA_CCP2] = REGISTER_PLL_DIV( 1640 + .name = "plla_ccp2", 1641 + .source_pll = "plla", 1642 + .cm_reg = CM_PLLA, 1643 + .a2w_reg = A2W_PLLA_CCP2, 1644 + .load_mask = CM_PLLA_LOADCCP2, 1645 + .hold_mask = CM_PLLA_HOLDCCP2, 1646 + .fixed_divider = 1), 1647 + 1648 + /* PLLB is used for the ARM's clock. */ 1649 + [BCM2835_PLLB] = REGISTER_PLL( 1650 + .name = "pllb", 1651 + .cm_ctrl_reg = CM_PLLB, 1652 + .a2w_ctrl_reg = A2W_PLLB_CTRL, 1653 + .frac_reg = A2W_PLLB_FRAC, 1654 + .ana_reg_base = A2W_PLLB_ANA0, 1655 + .reference_enable_mask = A2W_XOSC_CTRL_PLLB_ENABLE, 1656 + .lock_mask = CM_LOCK_FLOCKB, 1657 + 1658 + .ana = &bcm2835_ana_default, 1659 + 1660 + .min_rate = 600000000u, 1661 + .max_rate = 3000000000u, 1662 + .max_fb_rate = BCM2835_MAX_FB_RATE), 1663 + [BCM2835_PLLB_ARM] = REGISTER_PLL_DIV( 1664 + .name = "pllb_arm", 1665 + .source_pll = "pllb", 1666 + .cm_reg = CM_PLLB, 1667 + .a2w_reg = A2W_PLLB_ARM, 1668 + .load_mask = CM_PLLB_LOADARM, 1669 + .hold_mask = CM_PLLB_HOLDARM, 1670 + .fixed_divider = 1), 1671 + 1672 + /* 1673 + * PLLC is the core PLL, used to drive the core VPU clock. 1674 + * 1675 + * It is in the PX LDO power domain, which is on when the 1676 + * AUDIO domain is on. 1677 + */ 1678 + [BCM2835_PLLC] = REGISTER_PLL( 1679 + .name = "pllc", 1680 + .cm_ctrl_reg = CM_PLLC, 1681 + .a2w_ctrl_reg = A2W_PLLC_CTRL, 1682 + .frac_reg = A2W_PLLC_FRAC, 1683 + .ana_reg_base = A2W_PLLC_ANA0, 1684 + .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, 1685 + .lock_mask = CM_LOCK_FLOCKC, 1686 + 1687 + .ana = &bcm2835_ana_default, 1688 + 1689 + .min_rate = 600000000u, 1690 + .max_rate = 3000000000u, 1691 + .max_fb_rate = BCM2835_MAX_FB_RATE), 1692 + [BCM2835_PLLC_CORE0] = REGISTER_PLL_DIV( 1693 + .name = "pllc_core0", 1694 + .source_pll = "pllc", 1695 + .cm_reg = CM_PLLC, 1696 + .a2w_reg = A2W_PLLC_CORE0, 1697 + .load_mask = CM_PLLC_LOADCORE0, 1698 + .hold_mask = CM_PLLC_HOLDCORE0, 1699 + .fixed_divider = 1), 1700 + [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( 1701 + .name = "pllc_core1", 1702 + .source_pll = "pllc", 1703 + .cm_reg = CM_PLLC, 1704 + .a2w_reg = A2W_PLLC_CORE1, 1705 + .load_mask = CM_PLLC_LOADCORE1, 1706 + .hold_mask = CM_PLLC_HOLDCORE1, 1707 + .fixed_divider = 1), 1708 + [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( 1709 + .name = "pllc_core2", 1710 + .source_pll = "pllc", 1711 + .cm_reg = CM_PLLC, 1712 + .a2w_reg = A2W_PLLC_CORE2, 1713 + .load_mask = CM_PLLC_LOADCORE2, 1714 + .hold_mask = CM_PLLC_HOLDCORE2, 1715 + .fixed_divider = 1), 1716 + [BCM2835_PLLC_PER] = REGISTER_PLL_DIV( 1717 + .name = "pllc_per", 1718 + .source_pll = "pllc", 1719 + .cm_reg = CM_PLLC, 1720 + .a2w_reg = A2W_PLLC_PER, 1721 + .load_mask = CM_PLLC_LOADPER, 1722 + .hold_mask = CM_PLLC_HOLDPER, 1723 + .fixed_divider = 1), 1724 + 1725 + /* 1726 + * PLLD is the display PLL, used to drive DSI display panels. 1727 + * 1728 + * It is in the PX LDO power domain, which is on when the 1729 + * AUDIO domain is on. 1730 + */ 1731 + [BCM2835_PLLD] = REGISTER_PLL( 1732 + .name = "plld", 1733 + .cm_ctrl_reg = CM_PLLD, 1734 + .a2w_ctrl_reg = A2W_PLLD_CTRL, 1735 + .frac_reg = A2W_PLLD_FRAC, 1736 + .ana_reg_base = A2W_PLLD_ANA0, 1737 + .reference_enable_mask = A2W_XOSC_CTRL_DDR_ENABLE, 1738 + .lock_mask = CM_LOCK_FLOCKD, 1739 + 1740 + .ana = &bcm2835_ana_default, 1741 + 1742 + .min_rate = 600000000u, 1743 + .max_rate = 2400000000u, 1744 + .max_fb_rate = BCM2835_MAX_FB_RATE), 1745 + [BCM2835_PLLD_CORE] = REGISTER_PLL_DIV( 1746 + .name = "plld_core", 1747 + .source_pll = "plld", 1748 + .cm_reg = CM_PLLD, 1749 + .a2w_reg = A2W_PLLD_CORE, 1750 + .load_mask = CM_PLLD_LOADCORE, 1751 + .hold_mask = CM_PLLD_HOLDCORE, 1752 + .fixed_divider = 1), 1753 + [BCM2835_PLLD_PER] = REGISTER_PLL_DIV( 1754 + .name = "plld_per", 1755 + .source_pll = "plld", 1756 + .cm_reg = CM_PLLD, 1757 + .a2w_reg = A2W_PLLD_PER, 1758 + .load_mask = CM_PLLD_LOADPER, 1759 + .hold_mask = CM_PLLD_HOLDPER, 1760 + .fixed_divider = 1), 1761 + [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( 1762 + .name = "plld_dsi0", 1763 + .source_pll = "plld", 1764 + .cm_reg = CM_PLLD, 1765 + .a2w_reg = A2W_PLLD_DSI0, 1766 + .load_mask = CM_PLLD_LOADDSI0, 1767 + .hold_mask = CM_PLLD_HOLDDSI0, 1768 + .fixed_divider = 1), 1769 + [BCM2835_PLLD_DSI1] = REGISTER_PLL_DIV( 1770 + .name = "plld_dsi1", 1771 + .source_pll = "plld", 1772 + .cm_reg = CM_PLLD, 1773 + .a2w_reg = A2W_PLLD_DSI1, 1774 + .load_mask = CM_PLLD_LOADDSI1, 1775 + .hold_mask = CM_PLLD_HOLDDSI1, 1776 + .fixed_divider = 1), 1777 + 1778 + /* 1779 + * PLLH is used to supply the pixel clock or the AUX clock for the 1780 + * TV encoder. 1781 + * 1782 + * It is in the HDMI power domain. 1783 + */ 1784 + [BCM2835_PLLH] = REGISTER_PLL( 1785 + "pllh", 1786 + .cm_ctrl_reg = CM_PLLH, 1787 + .a2w_ctrl_reg = A2W_PLLH_CTRL, 1788 + .frac_reg = A2W_PLLH_FRAC, 1789 + .ana_reg_base = A2W_PLLH_ANA0, 1790 + .reference_enable_mask = A2W_XOSC_CTRL_PLLC_ENABLE, 1791 + .lock_mask = CM_LOCK_FLOCKH, 1792 + 1793 + .ana = &bcm2835_ana_pllh, 1794 + 1795 + .min_rate = 600000000u, 1796 + .max_rate = 3000000000u, 1797 + .max_fb_rate = BCM2835_MAX_FB_RATE), 1798 + [BCM2835_PLLH_RCAL] = REGISTER_PLL_DIV( 1799 + .name = "pllh_rcal", 1800 + .source_pll = "pllh", 1801 + .cm_reg = CM_PLLH, 1802 + .a2w_reg = A2W_PLLH_RCAL, 1803 + .load_mask = CM_PLLH_LOADRCAL, 1804 + .hold_mask = 0, 1805 + .fixed_divider = 10), 1806 + [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( 1807 + .name = "pllh_aux", 1808 + .source_pll = "pllh", 1809 + .cm_reg = CM_PLLH, 1810 + .a2w_reg = A2W_PLLH_AUX, 1811 + .load_mask = CM_PLLH_LOADAUX, 1812 + .hold_mask = 0, 1813 + .fixed_divider = 10), 1814 + [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( 1815 + .name = "pllh_pix", 1816 + .source_pll = "pllh", 1817 + .cm_reg = CM_PLLH, 1818 + .a2w_reg = A2W_PLLH_PIX, 1819 + .load_mask = CM_PLLH_LOADPIX, 1820 + .hold_mask = 0, 1821 + .fixed_divider = 10), 1822 + 1823 + /* the clocks */ 1824 + 1825 + /* clocks with oscillator parent mux */ 1826 + 1827 + /* One Time Programmable Memory clock. Maximum 10Mhz. */ 1828 + [BCM2835_CLOCK_OTP] = REGISTER_OSC_CLK( 1829 + .name = "otp", 1830 + .ctl_reg = CM_OTPCTL, 1831 + .div_reg = CM_OTPDIV, 1832 + .int_bits = 4, 1833 + .frac_bits = 0), 1834 + /* 1835 + * Used for a 1Mhz clock for the system clocksource, and also used 1836 + * bythe watchdog timer and the camera pulse generator. 1837 + */ 1838 + [BCM2835_CLOCK_TIMER] = REGISTER_OSC_CLK( 1839 + .name = "timer", 1840 + .ctl_reg = CM_TIMERCTL, 1841 + .div_reg = CM_TIMERDIV, 1842 + .int_bits = 6, 1843 + .frac_bits = 12), 1844 + /* 1845 + * Clock for the temperature sensor. 1846 + * Generally run at 2Mhz, max 5Mhz. 1847 + */ 1848 + [BCM2835_CLOCK_TSENS] = REGISTER_OSC_CLK( 1849 + .name = "tsens", 1850 + .ctl_reg = CM_TSENSCTL, 1851 + .div_reg = CM_TSENSDIV, 1852 + .int_bits = 5, 1853 + .frac_bits = 0), 1854 + [BCM2835_CLOCK_TEC] = REGISTER_OSC_CLK( 1855 + .name = "tec", 1856 + .ctl_reg = CM_TECCTL, 1857 + .div_reg = CM_TECDIV, 1858 + .int_bits = 6, 1859 + .frac_bits = 0), 1860 + 1861 + /* clocks with vpu parent mux */ 1862 + [BCM2835_CLOCK_H264] = REGISTER_VPU_CLK( 1863 + .name = "h264", 1864 + .ctl_reg = CM_H264CTL, 1865 + .div_reg = CM_H264DIV, 1866 + .int_bits = 4, 1867 + .frac_bits = 8), 1868 + [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( 1869 + .name = "isp", 1870 + .ctl_reg = CM_ISPCTL, 1871 + .div_reg = CM_ISPDIV, 1872 + .int_bits = 4, 1873 + .frac_bits = 8), 1874 + 1875 + /* 1876 + * Secondary SDRAM clock. Used for low-voltage modes when the PLL 1877 + * in the SDRAM controller can't be used. 1878 + */ 1879 + [BCM2835_CLOCK_SDRAM] = REGISTER_VPU_CLK( 1880 + .name = "sdram", 1881 + .ctl_reg = CM_SDCCTL, 1882 + .div_reg = CM_SDCDIV, 1883 + .int_bits = 6, 1884 + .frac_bits = 0), 1885 + [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( 1886 + .name = "v3d", 1887 + .ctl_reg = CM_V3DCTL, 1888 + .div_reg = CM_V3DDIV, 1889 + .int_bits = 4, 1890 + .frac_bits = 8), 1891 + /* 1892 + * VPU clock. This doesn't have an enable bit, since it drives 1893 + * the bus for everything else, and is special so it doesn't need 1894 + * to be gated for rate changes. It is also known as "clk_audio" 1895 + * in various hardware documentation. 1896 + */ 1897 + [BCM2835_CLOCK_VPU] = REGISTER_VPU_CLK( 1898 + .name = "vpu", 1899 + .ctl_reg = CM_VPUCTL, 1900 + .div_reg = CM_VPUDIV, 1901 + .int_bits = 12, 1902 + .frac_bits = 8, 1903 + .is_vpu_clock = true), 1904 + 1905 + /* clocks with per parent mux */ 1906 + [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( 1907 + .name = "aveo", 1908 + .ctl_reg = CM_AVEOCTL, 1909 + .div_reg = CM_AVEODIV, 1910 + .int_bits = 4, 1911 + .frac_bits = 0), 1912 + [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( 1913 + .name = "cam0", 1914 + .ctl_reg = CM_CAM0CTL, 1915 + .div_reg = CM_CAM0DIV, 1916 + .int_bits = 4, 1917 + .frac_bits = 8), 1918 + [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( 1919 + .name = "cam1", 1920 + .ctl_reg = CM_CAM1CTL, 1921 + .div_reg = CM_CAM1DIV, 1922 + .int_bits = 4, 1923 + .frac_bits = 8), 1924 + [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( 1925 + .name = "dft", 1926 + .ctl_reg = CM_DFTCTL, 1927 + .div_reg = CM_DFTDIV, 1928 + .int_bits = 5, 1929 + .frac_bits = 0), 1930 + [BCM2835_CLOCK_DPI] = REGISTER_PER_CLK( 1931 + .name = "dpi", 1932 + .ctl_reg = CM_DPICTL, 1933 + .div_reg = CM_DPIDIV, 1934 + .int_bits = 4, 1935 + .frac_bits = 8), 1936 + 1937 + /* Arasan EMMC clock */ 1938 + [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( 1939 + .name = "emmc", 1940 + .ctl_reg = CM_EMMCCTL, 1941 + .div_reg = CM_EMMCDIV, 1942 + .int_bits = 4, 1943 + .frac_bits = 8), 1944 + 1945 + /* General purpose (GPIO) clocks */ 1946 + [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( 1947 + .name = "gp0", 1948 + .ctl_reg = CM_GP0CTL, 1949 + .div_reg = CM_GP0DIV, 1950 + .int_bits = 12, 1951 + .frac_bits = 12, 1952 + .is_mash_clock = true), 1953 + [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( 1954 + .name = "gp1", 1955 + .ctl_reg = CM_GP1CTL, 1956 + .div_reg = CM_GP1DIV, 1957 + .int_bits = 12, 1958 + .frac_bits = 12, 1959 + .is_mash_clock = true), 1960 + [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( 1961 + .name = "gp2", 1962 + .ctl_reg = CM_GP2CTL, 1963 + .div_reg = CM_GP2DIV, 1964 + .int_bits = 12, 1965 + .frac_bits = 12), 1966 + 1967 + /* HDMI state machine */ 1968 + [BCM2835_CLOCK_HSM] = REGISTER_PER_CLK( 1969 + .name = "hsm", 1970 + .ctl_reg = CM_HSMCTL, 1971 + .div_reg = CM_HSMDIV, 1972 + .int_bits = 4, 1973 + .frac_bits = 8), 1974 + [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( 1975 + .name = "pcm", 1976 + .ctl_reg = CM_PCMCTL, 1977 + .div_reg = CM_PCMDIV, 1978 + .int_bits = 12, 1979 + .frac_bits = 12, 1980 + .is_mash_clock = true), 1981 + [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( 1982 + .name = "pwm", 1983 + .ctl_reg = CM_PWMCTL, 1984 + .div_reg = CM_PWMDIV, 1985 + .int_bits = 12, 1986 + .frac_bits = 12, 1987 + .is_mash_clock = true), 1988 + [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( 1989 + .name = "slim", 1990 + .ctl_reg = CM_SLIMCTL, 1991 + .div_reg = CM_SLIMDIV, 1992 + .int_bits = 12, 1993 + .frac_bits = 12, 1994 + .is_mash_clock = true), 1995 + [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( 1996 + .name = "smi", 1997 + .ctl_reg = CM_SMICTL, 1998 + .div_reg = CM_SMIDIV, 1999 + .int_bits = 4, 2000 + .frac_bits = 8), 2001 + [BCM2835_CLOCK_UART] = REGISTER_PER_CLK( 2002 + .name = "uart", 2003 + .ctl_reg = CM_UARTCTL, 2004 + .div_reg = CM_UARTDIV, 2005 + .int_bits = 10, 2006 + .frac_bits = 12), 2007 + 2008 + /* TV encoder clock. Only operating frequency is 108Mhz. */ 2009 + [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( 2010 + .name = "vec", 2011 + .ctl_reg = CM_VECCTL, 2012 + .div_reg = CM_VECDIV, 2013 + .int_bits = 4, 2014 + .frac_bits = 0), 2015 + 2016 + /* dsi clocks */ 2017 + [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( 2018 + .name = "dsi0e", 2019 + .ctl_reg = CM_DSI0ECTL, 2020 + .div_reg = CM_DSI0EDIV, 2021 + .int_bits = 4, 2022 + .frac_bits = 8), 2023 + [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( 2024 + .name = "dsi1e", 2025 + .ctl_reg = CM_DSI1ECTL, 2026 + .div_reg = CM_DSI1EDIV, 2027 + .int_bits = 4, 2028 + .frac_bits = 8), 2029 + 2030 + /* the gates */ 2031 + 2032 + /* 2033 + * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if 2034 + * you have the debug bit set in the power manager, which we 2035 + * don't bother exposing) are individual gates off of the 2036 + * non-stop vpu clock. 2037 + */ 2038 + [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( 2039 + .name = "peri_image", 2040 + .parent = "vpu", 2041 + .ctl_reg = CM_PERIICTL), 2042 + }; 2043 + 1253 2044 static int bcm2835_clk_probe(struct platform_device *pdev) 1254 2045 { 1255 2046 struct device *dev = &pdev->dev; 1256 2047 struct clk **clks; 1257 2048 struct bcm2835_cprman *cprman; 1258 2049 struct resource *res; 2050 + const struct bcm2835_clk_desc *desc; 2051 + const size_t asize = ARRAY_SIZE(clk_desc_array); 2052 + size_t i; 1259 2053 1260 - cprman = devm_kzalloc(dev, sizeof(*cprman), GFP_KERNEL); 2054 + cprman = devm_kzalloc(dev, 2055 + sizeof(*cprman) + asize * sizeof(*clks), 2056 + GFP_KERNEL); 1261 2057 if (!cprman) 1262 2058 return -ENOMEM; 1263 2059 ··· 1819 1525 1820 1526 platform_set_drvdata(pdev, cprman); 1821 1527 1822 - cprman->onecell.clk_num = BCM2835_CLOCK_COUNT; 1528 + cprman->onecell.clk_num = asize; 1823 1529 cprman->onecell.clks = cprman->clks; 1824 1530 clks = cprman->clks; 1825 1531 1826 - clks[BCM2835_PLLA] = bcm2835_register_pll(cprman, &bcm2835_plla_data); 1827 - clks[BCM2835_PLLB] = bcm2835_register_pll(cprman, &bcm2835_pllb_data); 1828 - clks[BCM2835_PLLC] = bcm2835_register_pll(cprman, &bcm2835_pllc_data); 1829 - clks[BCM2835_PLLD] = bcm2835_register_pll(cprman, &bcm2835_plld_data); 1830 - clks[BCM2835_PLLH] = bcm2835_register_pll(cprman, &bcm2835_pllh_data); 1831 - 1832 - clks[BCM2835_PLLA_CORE] = 1833 - bcm2835_register_pll_divider(cprman, &bcm2835_plla_core_data); 1834 - clks[BCM2835_PLLA_PER] = 1835 - bcm2835_register_pll_divider(cprman, &bcm2835_plla_per_data); 1836 - clks[BCM2835_PLLC_CORE0] = 1837 - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core0_data); 1838 - clks[BCM2835_PLLC_CORE1] = 1839 - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core1_data); 1840 - clks[BCM2835_PLLC_CORE2] = 1841 - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_core2_data); 1842 - clks[BCM2835_PLLC_PER] = 1843 - bcm2835_register_pll_divider(cprman, &bcm2835_pllc_per_data); 1844 - clks[BCM2835_PLLD_CORE] = 1845 - bcm2835_register_pll_divider(cprman, &bcm2835_plld_core_data); 1846 - clks[BCM2835_PLLD_PER] = 1847 - bcm2835_register_pll_divider(cprman, &bcm2835_plld_per_data); 1848 - clks[BCM2835_PLLH_RCAL] = 1849 - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_rcal_data); 1850 - clks[BCM2835_PLLH_AUX] = 1851 - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_aux_data); 1852 - clks[BCM2835_PLLH_PIX] = 1853 - bcm2835_register_pll_divider(cprman, &bcm2835_pllh_pix_data); 1854 - 1855 - clks[BCM2835_CLOCK_TIMER] = 1856 - bcm2835_register_clock(cprman, &bcm2835_clock_timer_data); 1857 - clks[BCM2835_CLOCK_OTP] = 1858 - bcm2835_register_clock(cprman, &bcm2835_clock_otp_data); 1859 - clks[BCM2835_CLOCK_TSENS] = 1860 - bcm2835_register_clock(cprman, &bcm2835_clock_tsens_data); 1861 - clks[BCM2835_CLOCK_VPU] = 1862 - bcm2835_register_clock(cprman, &bcm2835_clock_vpu_data); 1863 - clks[BCM2835_CLOCK_V3D] = 1864 - bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); 1865 - clks[BCM2835_CLOCK_ISP] = 1866 - bcm2835_register_clock(cprman, &bcm2835_clock_isp_data); 1867 - clks[BCM2835_CLOCK_H264] = 1868 - bcm2835_register_clock(cprman, &bcm2835_clock_h264_data); 1869 - clks[BCM2835_CLOCK_V3D] = 1870 - bcm2835_register_clock(cprman, &bcm2835_clock_v3d_data); 1871 - clks[BCM2835_CLOCK_SDRAM] = 1872 - bcm2835_register_clock(cprman, &bcm2835_clock_sdram_data); 1873 - clks[BCM2835_CLOCK_UART] = 1874 - bcm2835_register_clock(cprman, &bcm2835_clock_uart_data); 1875 - clks[BCM2835_CLOCK_VEC] = 1876 - bcm2835_register_clock(cprman, &bcm2835_clock_vec_data); 1877 - clks[BCM2835_CLOCK_HSM] = 1878 - bcm2835_register_clock(cprman, &bcm2835_clock_hsm_data); 1879 - clks[BCM2835_CLOCK_EMMC] = 1880 - bcm2835_register_clock(cprman, &bcm2835_clock_emmc_data); 1881 - 1882 - /* 1883 - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if 1884 - * you have the debug bit set in the power manager, which we 1885 - * don't bother exposing) are individual gates off of the 1886 - * non-stop vpu clock. 1887 - */ 1888 - clks[BCM2835_CLOCK_PERI_IMAGE] = 1889 - clk_register_gate(dev, "peri_image", "vpu", 1890 - CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 1891 - cprman->regs + CM_PERIICTL, CM_GATE_BIT, 1892 - 0, &cprman->regs_lock); 1893 - 1894 - clks[BCM2835_CLOCK_PWM] = 1895 - bcm2835_register_clock(cprman, &bcm2835_clock_pwm_data); 1532 + for (i = 0; i < asize; i++) { 1533 + desc = &clk_desc_array[i]; 1534 + if (desc->clk_register && desc->data) 1535 + clks[i] = desc->clk_register(cprman, desc->data); 1536 + } 1896 1537 1897 1538 return of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, 1898 1539 &cprman->onecell);
+2 -1
drivers/clk/bcm/clk-kona-setup.c
··· 577 577 * selector is not required, but we allocate space for the 578 578 * array anyway to keep things simple. 579 579 */ 580 - parent_names = kmalloc(parent_count * sizeof(parent_names), GFP_KERNEL); 580 + parent_names = kmalloc_array(parent_count, sizeof(*parent_names), 581 + GFP_KERNEL); 581 582 if (!parent_names) { 582 583 pr_err("%s: error allocating %u parent names\n", __func__, 583 584 parent_count);
+8 -11
drivers/clk/clk-clps711x.c
··· 107 107 writel(tmp, base + CLPS711X_SYSCON1); 108 108 109 109 clps711x_clk->clks[CLPS711X_CLK_DUMMY] = 110 - clk_register_fixed_rate(NULL, "dummy", NULL, CLK_IS_ROOT, 0); 110 + clk_register_fixed_rate(NULL, "dummy", NULL, 0, 0); 111 111 clps711x_clk->clks[CLPS711X_CLK_CPU] = 112 - clk_register_fixed_rate(NULL, "cpu", NULL, CLK_IS_ROOT, f_cpu); 112 + clk_register_fixed_rate(NULL, "cpu", NULL, 0, f_cpu); 113 113 clps711x_clk->clks[CLPS711X_CLK_BUS] = 114 - clk_register_fixed_rate(NULL, "bus", NULL, CLK_IS_ROOT, f_bus); 114 + clk_register_fixed_rate(NULL, "bus", NULL, 0, f_bus); 115 115 clps711x_clk->clks[CLPS711X_CLK_PLL] = 116 - clk_register_fixed_rate(NULL, "pll", NULL, CLK_IS_ROOT, f_pll); 116 + clk_register_fixed_rate(NULL, "pll", NULL, 0, f_pll); 117 117 clps711x_clk->clks[CLPS711X_CLK_TIMERREF] = 118 - clk_register_fixed_rate(NULL, "timer_ref", NULL, CLK_IS_ROOT, 119 - f_tim); 118 + clk_register_fixed_rate(NULL, "timer_ref", NULL, 0, f_tim); 120 119 clps711x_clk->clks[CLPS711X_CLK_TIMER1] = 121 120 clk_register_divider_table(NULL, "timer1", "timer_ref", 0, 122 121 base + CLPS711X_SYSCON1, 5, 1, 0, ··· 125 126 base + CLPS711X_SYSCON1, 7, 1, 0, 126 127 timer_div_table, &clps711x_clk->lock); 127 128 clps711x_clk->clks[CLPS711X_CLK_PWM] = 128 - clk_register_fixed_rate(NULL, "pwm", NULL, CLK_IS_ROOT, f_pwm); 129 + clk_register_fixed_rate(NULL, "pwm", NULL, 0, f_pwm); 129 130 clps711x_clk->clks[CLPS711X_CLK_SPIREF] = 130 - clk_register_fixed_rate(NULL, "spi_ref", NULL, CLK_IS_ROOT, 131 - f_spi); 131 + clk_register_fixed_rate(NULL, "spi_ref", NULL, 0, f_spi); 132 132 clps711x_clk->clks[CLPS711X_CLK_SPI] = 133 133 clk_register_divider_table(NULL, "spi", "spi_ref", 0, 134 134 base + CLPS711X_SYSCON1, 16, 2, 0, ··· 135 137 clps711x_clk->clks[CLPS711X_CLK_UART] = 136 138 clk_register_fixed_factor(NULL, "uart", "bus", 0, 1, 10); 137 139 clps711x_clk->clks[CLPS711X_CLK_TICK] = 138 - clk_register_fixed_rate(NULL, "tick", NULL, CLK_IS_ROOT, 64); 139 - 140 + clk_register_fixed_rate(NULL, "tick", NULL, 0, 64); 140 141 for (i = 0; i < CLPS711X_CLK_MAX; i++) 141 142 if (IS_ERR(clps711x_clk->clks[i])) 142 143 pr_err("clk %i: register failed with %ld\n",
+81 -12
drivers/clk/clk-composite.c
··· 151 151 return rate_ops->set_rate(rate_hw, rate, parent_rate); 152 152 } 153 153 154 + static int clk_composite_set_rate_and_parent(struct clk_hw *hw, 155 + unsigned long rate, 156 + unsigned long parent_rate, 157 + u8 index) 158 + { 159 + struct clk_composite *composite = to_clk_composite(hw); 160 + const struct clk_ops *rate_ops = composite->rate_ops; 161 + const struct clk_ops *mux_ops = composite->mux_ops; 162 + struct clk_hw *rate_hw = composite->rate_hw; 163 + struct clk_hw *mux_hw = composite->mux_hw; 164 + unsigned long temp_rate; 165 + 166 + __clk_hw_set_clk(rate_hw, hw); 167 + __clk_hw_set_clk(mux_hw, hw); 168 + 169 + temp_rate = rate_ops->recalc_rate(rate_hw, parent_rate); 170 + if (temp_rate > rate) { 171 + rate_ops->set_rate(rate_hw, rate, parent_rate); 172 + mux_ops->set_parent(mux_hw, index); 173 + } else { 174 + mux_ops->set_parent(mux_hw, index); 175 + rate_ops->set_rate(rate_hw, rate, parent_rate); 176 + } 177 + 178 + return 0; 179 + } 180 + 154 181 static int clk_composite_is_enabled(struct clk_hw *hw) 155 182 { 156 183 struct clk_composite *composite = to_clk_composite(hw); ··· 211 184 gate_ops->disable(gate_hw); 212 185 } 213 186 214 - struct clk *clk_register_composite(struct device *dev, const char *name, 187 + struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, 215 188 const char * const *parent_names, int num_parents, 216 189 struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 217 190 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 218 191 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 219 192 unsigned long flags) 220 193 { 221 - struct clk *clk; 194 + struct clk_hw *hw; 222 195 struct clk_init_data init; 223 196 struct clk_composite *composite; 224 197 struct clk_ops *clk_composite_ops; 198 + int ret; 225 199 226 200 composite = kzalloc(sizeof(*composite), GFP_KERNEL); 227 201 if (!composite) ··· 232 204 init.flags = flags | CLK_IS_BASIC; 233 205 init.parent_names = parent_names; 234 206 init.num_parents = num_parents; 207 + hw = &composite->hw; 235 208 236 209 clk_composite_ops = &composite->ops; 237 210 238 211 if (mux_hw && mux_ops) { 239 212 if (!mux_ops->get_parent) { 240 - clk = ERR_PTR(-EINVAL); 213 + hw = ERR_PTR(-EINVAL); 241 214 goto err; 242 215 } 243 216 ··· 253 224 254 225 if (rate_hw && rate_ops) { 255 226 if (!rate_ops->recalc_rate) { 256 - clk = ERR_PTR(-EINVAL); 227 + hw = ERR_PTR(-EINVAL); 257 228 goto err; 258 229 } 259 230 clk_composite_ops->recalc_rate = clk_composite_recalc_rate; ··· 279 250 composite->rate_ops = rate_ops; 280 251 } 281 252 253 + if (mux_hw && mux_ops && rate_hw && rate_ops) { 254 + if (mux_ops->set_parent && rate_ops->set_rate) 255 + clk_composite_ops->set_rate_and_parent = 256 + clk_composite_set_rate_and_parent; 257 + } 258 + 282 259 if (gate_hw && gate_ops) { 283 260 if (!gate_ops->is_enabled || !gate_ops->enable || 284 261 !gate_ops->disable) { 285 - clk = ERR_PTR(-EINVAL); 262 + hw = ERR_PTR(-EINVAL); 286 263 goto err; 287 264 } 288 265 ··· 302 267 init.ops = clk_composite_ops; 303 268 composite->hw.init = &init; 304 269 305 - clk = clk_register(dev, &composite->hw); 306 - if (IS_ERR(clk)) 270 + ret = clk_hw_register(dev, hw); 271 + if (ret) { 272 + hw = ERR_PTR(ret); 307 273 goto err; 274 + } 308 275 309 276 if (composite->mux_hw) 310 - composite->mux_hw->clk = clk; 277 + composite->mux_hw->clk = hw->clk; 311 278 312 279 if (composite->rate_hw) 313 - composite->rate_hw->clk = clk; 280 + composite->rate_hw->clk = hw->clk; 314 281 315 282 if (composite->gate_hw) 316 - composite->gate_hw->clk = clk; 283 + composite->gate_hw->clk = hw->clk; 317 284 318 - return clk; 285 + return hw; 319 286 320 287 err: 321 288 kfree(composite); 322 - return clk; 289 + return hw; 290 + } 291 + 292 + struct clk *clk_register_composite(struct device *dev, const char *name, 293 + const char * const *parent_names, int num_parents, 294 + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 295 + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 296 + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 297 + unsigned long flags) 298 + { 299 + struct clk_hw *hw; 300 + 301 + hw = clk_hw_register_composite(dev, name, parent_names, num_parents, 302 + mux_hw, mux_ops, rate_hw, rate_ops, gate_hw, gate_ops, 303 + flags); 304 + if (IS_ERR(hw)) 305 + return ERR_CAST(hw); 306 + return hw->clk; 307 + } 308 + 309 + void clk_unregister_composite(struct clk *clk) 310 + { 311 + struct clk_composite *composite; 312 + struct clk_hw *hw; 313 + 314 + hw = __clk_get_hw(clk); 315 + if (!hw) 316 + return; 317 + 318 + composite = to_clk_composite(hw); 319 + 320 + clk_unregister(clk); 321 + kfree(composite); 323 322 }
+83 -8
drivers/clk/clk-divider.c
··· 426 426 }; 427 427 EXPORT_SYMBOL_GPL(clk_divider_ro_ops); 428 428 429 - static struct clk *_register_divider(struct device *dev, const char *name, 429 + static struct clk_hw *_register_divider(struct device *dev, const char *name, 430 430 const char *parent_name, unsigned long flags, 431 431 void __iomem *reg, u8 shift, u8 width, 432 432 u8 clk_divider_flags, const struct clk_div_table *table, 433 433 spinlock_t *lock) 434 434 { 435 435 struct clk_divider *div; 436 - struct clk *clk; 436 + struct clk_hw *hw; 437 437 struct clk_init_data init; 438 + int ret; 438 439 439 440 if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { 440 441 if (width + shift > 16) { ··· 468 467 div->table = table; 469 468 470 469 /* register the clock */ 471 - clk = clk_register(dev, &div->hw); 472 - 473 - if (IS_ERR(clk)) 470 + hw = &div->hw; 471 + ret = clk_hw_register(dev, hw); 472 + if (ret) { 474 473 kfree(div); 474 + hw = ERR_PTR(ret); 475 + } 475 476 476 - return clk; 477 + return hw; 477 478 } 478 479 479 480 /** ··· 495 492 void __iomem *reg, u8 shift, u8 width, 496 493 u8 clk_divider_flags, spinlock_t *lock) 497 494 { 495 + struct clk_hw *hw; 496 + 497 + hw = _register_divider(dev, name, parent_name, flags, reg, shift, 498 + width, clk_divider_flags, NULL, lock); 499 + if (IS_ERR(hw)) 500 + return ERR_CAST(hw); 501 + return hw->clk; 502 + } 503 + EXPORT_SYMBOL_GPL(clk_register_divider); 504 + 505 + /** 506 + * clk_hw_register_divider - register a divider clock with the clock framework 507 + * @dev: device registering this clock 508 + * @name: name of this clock 509 + * @parent_name: name of clock's parent 510 + * @flags: framework-specific flags 511 + * @reg: register address to adjust divider 512 + * @shift: number of bits to shift the bitfield 513 + * @width: width of the bitfield 514 + * @clk_divider_flags: divider-specific flags for this clock 515 + * @lock: shared register lock for this clock 516 + */ 517 + struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name, 518 + const char *parent_name, unsigned long flags, 519 + void __iomem *reg, u8 shift, u8 width, 520 + u8 clk_divider_flags, spinlock_t *lock) 521 + { 498 522 return _register_divider(dev, name, parent_name, flags, reg, shift, 499 523 width, clk_divider_flags, NULL, lock); 500 524 } 501 - EXPORT_SYMBOL_GPL(clk_register_divider); 525 + EXPORT_SYMBOL_GPL(clk_hw_register_divider); 502 526 503 527 /** 504 528 * clk_register_divider_table - register a table based divider clock with ··· 547 517 u8 clk_divider_flags, const struct clk_div_table *table, 548 518 spinlock_t *lock) 549 519 { 520 + struct clk_hw *hw; 521 + 522 + hw = _register_divider(dev, name, parent_name, flags, reg, shift, 523 + width, clk_divider_flags, table, lock); 524 + if (IS_ERR(hw)) 525 + return ERR_CAST(hw); 526 + return hw->clk; 527 + } 528 + EXPORT_SYMBOL_GPL(clk_register_divider_table); 529 + 530 + /** 531 + * clk_hw_register_divider_table - register a table based divider clock with 532 + * the clock framework 533 + * @dev: device registering this clock 534 + * @name: name of this clock 535 + * @parent_name: name of clock's parent 536 + * @flags: framework-specific flags 537 + * @reg: register address to adjust divider 538 + * @shift: number of bits to shift the bitfield 539 + * @width: width of the bitfield 540 + * @clk_divider_flags: divider-specific flags for this clock 541 + * @table: array of divider/value pairs ending with a div set to 0 542 + * @lock: shared register lock for this clock 543 + */ 544 + struct clk_hw *clk_hw_register_divider_table(struct device *dev, 545 + const char *name, const char *parent_name, unsigned long flags, 546 + void __iomem *reg, u8 shift, u8 width, 547 + u8 clk_divider_flags, const struct clk_div_table *table, 548 + spinlock_t *lock) 549 + { 550 550 return _register_divider(dev, name, parent_name, flags, reg, shift, 551 551 width, clk_divider_flags, table, lock); 552 552 } 553 - EXPORT_SYMBOL_GPL(clk_register_divider_table); 553 + EXPORT_SYMBOL_GPL(clk_hw_register_divider_table); 554 554 555 555 void clk_unregister_divider(struct clk *clk) 556 556 { ··· 597 537 kfree(div); 598 538 } 599 539 EXPORT_SYMBOL_GPL(clk_unregister_divider); 540 + 541 + /** 542 + * clk_hw_unregister_divider - unregister a clk divider 543 + * @hw: hardware-specific clock data to unregister 544 + */ 545 + void clk_hw_unregister_divider(struct clk_hw *hw) 546 + { 547 + struct clk_divider *div; 548 + 549 + div = to_clk_divider(hw); 550 + 551 + clk_hw_unregister(hw); 552 + kfree(div); 553 + } 554 + EXPORT_SYMBOL_GPL(clk_hw_unregister_divider);
+35 -7
drivers/clk/clk-fixed-factor.c
··· 68 68 }; 69 69 EXPORT_SYMBOL_GPL(clk_fixed_factor_ops); 70 70 71 - struct clk *clk_register_fixed_factor(struct device *dev, const char *name, 72 - const char *parent_name, unsigned long flags, 71 + struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, 72 + const char *name, const char *parent_name, unsigned long flags, 73 73 unsigned int mult, unsigned int div) 74 74 { 75 75 struct clk_fixed_factor *fix; 76 76 struct clk_init_data init; 77 - struct clk *clk; 77 + struct clk_hw *hw; 78 + int ret; 78 79 79 80 fix = kmalloc(sizeof(*fix), GFP_KERNEL); 80 81 if (!fix) ··· 92 91 init.parent_names = &parent_name; 93 92 init.num_parents = 1; 94 93 95 - clk = clk_register(dev, &fix->hw); 96 - 97 - if (IS_ERR(clk)) 94 + hw = &fix->hw; 95 + ret = clk_hw_register(dev, hw); 96 + if (ret) { 98 97 kfree(fix); 98 + hw = ERR_PTR(ret); 99 + } 99 100 100 - return clk; 101 + return hw; 102 + } 103 + EXPORT_SYMBOL_GPL(clk_hw_register_fixed_factor); 104 + 105 + struct clk *clk_register_fixed_factor(struct device *dev, const char *name, 106 + const char *parent_name, unsigned long flags, 107 + unsigned int mult, unsigned int div) 108 + { 109 + struct clk_hw *hw; 110 + 111 + hw = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult, 112 + div); 113 + if (IS_ERR(hw)) 114 + return ERR_CAST(hw); 115 + return hw->clk; 101 116 } 102 117 EXPORT_SYMBOL_GPL(clk_register_fixed_factor); 103 118 ··· 129 112 kfree(to_clk_fixed_factor(hw)); 130 113 } 131 114 EXPORT_SYMBOL_GPL(clk_unregister_fixed_factor); 115 + 116 + void clk_hw_unregister_fixed_factor(struct clk_hw *hw) 117 + { 118 + struct clk_fixed_factor *fix; 119 + 120 + fix = to_clk_fixed_factor(hw); 121 + 122 + clk_hw_unregister(hw); 123 + kfree(fix); 124 + } 125 + EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_factor); 132 126 133 127 #ifdef CONFIG_OF 134 128 /**
+36 -8
drivers/clk/clk-fixed-rate.c
··· 45 45 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); 46 46 47 47 /** 48 - * clk_register_fixed_rate_with_accuracy - register fixed-rate clock with the 49 - * clock framework 48 + * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with 49 + * the clock framework 50 50 * @dev: device that is registering this clock 51 51 * @name: name of this clock 52 52 * @parent_name: name of clock's parent ··· 54 54 * @fixed_rate: non-adjustable clock rate 55 55 * @fixed_accuracy: non-adjustable clock rate 56 56 */ 57 - struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, 57 + struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, 58 58 const char *name, const char *parent_name, unsigned long flags, 59 59 unsigned long fixed_rate, unsigned long fixed_accuracy) 60 60 { 61 61 struct clk_fixed_rate *fixed; 62 - struct clk *clk; 62 + struct clk_hw *hw; 63 63 struct clk_init_data init; 64 + int ret; 64 65 65 66 /* allocate fixed-rate clock */ 66 67 fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); ··· 80 79 fixed->hw.init = &init; 81 80 82 81 /* register the clock */ 83 - clk = clk_register(dev, &fixed->hw); 84 - if (IS_ERR(clk)) 82 + hw = &fixed->hw; 83 + ret = clk_hw_register(dev, hw); 84 + if (ret) { 85 85 kfree(fixed); 86 + hw = ERR_PTR(ret); 87 + } 86 88 87 - return clk; 89 + return hw; 90 + } 91 + EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy); 92 + 93 + struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, 94 + const char *name, const char *parent_name, unsigned long flags, 95 + unsigned long fixed_rate, unsigned long fixed_accuracy) 96 + { 97 + struct clk_hw *hw; 98 + 99 + hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name, 100 + flags, fixed_rate, fixed_accuracy); 101 + if (IS_ERR(hw)) 102 + return ERR_CAST(hw); 103 + return hw->clk; 88 104 } 89 105 EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy); 90 106 91 107 /** 92 - * clk_register_fixed_rate - register fixed-rate clock with the clock framework 108 + * clk_hw_register_fixed_rate - register fixed-rate clock with the clock 109 + * framework 93 110 * @dev: device that is registering this clock 94 111 * @name: name of this clock 95 112 * @parent_name: name of clock's parent 96 113 * @flags: framework-specific flags 97 114 * @fixed_rate: non-adjustable clock rate 98 115 */ 116 + struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name, 117 + const char *parent_name, unsigned long flags, 118 + unsigned long fixed_rate) 119 + { 120 + return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name, 121 + flags, fixed_rate, 0); 122 + } 123 + EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate); 124 + 99 125 struct clk *clk_register_fixed_rate(struct device *dev, const char *name, 100 126 const char *parent_name, unsigned long flags, 101 127 unsigned long fixed_rate)
+35 -5
drivers/clk/clk-fractional-divider.c
··· 116 116 }; 117 117 EXPORT_SYMBOL_GPL(clk_fractional_divider_ops); 118 118 119 - struct clk *clk_register_fractional_divider(struct device *dev, 119 + struct clk_hw *clk_hw_register_fractional_divider(struct device *dev, 120 120 const char *name, const char *parent_name, unsigned long flags, 121 121 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 122 122 u8 clk_divider_flags, spinlock_t *lock) 123 123 { 124 124 struct clk_fractional_divider *fd; 125 125 struct clk_init_data init; 126 - struct clk *clk; 126 + struct clk_hw *hw; 127 + int ret; 127 128 128 129 fd = kzalloc(sizeof(*fd), GFP_KERNEL); 129 130 if (!fd) ··· 147 146 fd->lock = lock; 148 147 fd->hw.init = &init; 149 148 150 - clk = clk_register(dev, &fd->hw); 151 - if (IS_ERR(clk)) 149 + hw = &fd->hw; 150 + ret = clk_hw_register(dev, hw); 151 + if (ret) { 152 152 kfree(fd); 153 + hw = ERR_PTR(ret); 154 + } 153 155 154 - return clk; 156 + return hw; 157 + } 158 + EXPORT_SYMBOL_GPL(clk_hw_register_fractional_divider); 159 + 160 + struct clk *clk_register_fractional_divider(struct device *dev, 161 + const char *name, const char *parent_name, unsigned long flags, 162 + void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 163 + u8 clk_divider_flags, spinlock_t *lock) 164 + { 165 + struct clk_hw *hw; 166 + 167 + hw = clk_hw_register_fractional_divider(dev, name, parent_name, flags, 168 + reg, mshift, mwidth, nshift, nwidth, clk_divider_flags, 169 + lock); 170 + if (IS_ERR(hw)) 171 + return ERR_CAST(hw); 172 + return hw->clk; 155 173 } 156 174 EXPORT_SYMBOL_GPL(clk_register_fractional_divider); 175 + 176 + void clk_hw_unregister_fractional_divider(struct clk_hw *hw) 177 + { 178 + struct clk_fractional_divider *fd; 179 + 180 + fd = to_clk_fd(hw); 181 + 182 + clk_hw_unregister(hw); 183 + kfree(fd); 184 + }
+36 -7
drivers/clk/clk-gate.c
··· 110 110 EXPORT_SYMBOL_GPL(clk_gate_ops); 111 111 112 112 /** 113 - * clk_register_gate - register a gate clock with the clock framework 113 + * clk_hw_register_gate - register a gate clock with the clock framework 114 114 * @dev: device that is registering this clock 115 115 * @name: name of this clock 116 116 * @parent_name: name of this clock's parent ··· 120 120 * @clk_gate_flags: gate-specific flags for this clock 121 121 * @lock: shared register lock for this clock 122 122 */ 123 - struct clk *clk_register_gate(struct device *dev, const char *name, 123 + struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, 124 124 const char *parent_name, unsigned long flags, 125 125 void __iomem *reg, u8 bit_idx, 126 126 u8 clk_gate_flags, spinlock_t *lock) 127 127 { 128 128 struct clk_gate *gate; 129 - struct clk *clk; 129 + struct clk_hw *hw; 130 130 struct clk_init_data init; 131 + int ret; 131 132 132 133 if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { 133 134 if (bit_idx > 15) { ··· 155 154 gate->lock = lock; 156 155 gate->hw.init = &init; 157 156 158 - clk = clk_register(dev, &gate->hw); 159 - 160 - if (IS_ERR(clk)) 157 + hw = &gate->hw; 158 + ret = clk_hw_register(dev, hw); 159 + if (ret) { 161 160 kfree(gate); 161 + hw = ERR_PTR(ret); 162 + } 162 163 163 - return clk; 164 + return hw; 165 + } 166 + EXPORT_SYMBOL_GPL(clk_hw_register_gate); 167 + 168 + struct clk *clk_register_gate(struct device *dev, const char *name, 169 + const char *parent_name, unsigned long flags, 170 + void __iomem *reg, u8 bit_idx, 171 + u8 clk_gate_flags, spinlock_t *lock) 172 + { 173 + struct clk_hw *hw; 174 + 175 + hw = clk_hw_register_gate(dev, name, parent_name, flags, reg, 176 + bit_idx, clk_gate_flags, lock); 177 + if (IS_ERR(hw)) 178 + return ERR_CAST(hw); 179 + return hw->clk; 164 180 } 165 181 EXPORT_SYMBOL_GPL(clk_register_gate); 166 182 ··· 196 178 kfree(gate); 197 179 } 198 180 EXPORT_SYMBOL_GPL(clk_unregister_gate); 181 + 182 + void clk_hw_unregister_gate(struct clk_hw *hw) 183 + { 184 + struct clk_gate *gate; 185 + 186 + gate = to_clk_gate(hw); 187 + 188 + clk_hw_unregister(hw); 189 + kfree(gate); 190 + } 191 + EXPORT_SYMBOL_GPL(clk_hw_unregister_gate);
+41 -11
drivers/clk/clk-gpio.c
··· 94 94 }; 95 95 EXPORT_SYMBOL_GPL(clk_gpio_mux_ops); 96 96 97 - static struct clk *clk_register_gpio(struct device *dev, const char *name, 97 + static struct clk_hw *clk_register_gpio(struct device *dev, const char *name, 98 98 const char * const *parent_names, u8 num_parents, unsigned gpio, 99 99 bool active_low, unsigned long flags, 100 100 const struct clk_ops *clk_gpio_ops) 101 101 { 102 102 struct clk_gpio *clk_gpio; 103 - struct clk *clk; 103 + struct clk_hw *hw; 104 104 struct clk_init_data init = {}; 105 105 unsigned long gpio_flags; 106 106 int err; ··· 141 141 clk_gpio->gpiod = gpio_to_desc(gpio); 142 142 clk_gpio->hw.init = &init; 143 143 144 + hw = &clk_gpio->hw; 144 145 if (dev) 145 - clk = devm_clk_register(dev, &clk_gpio->hw); 146 + err = devm_clk_hw_register(dev, hw); 146 147 else 147 - clk = clk_register(NULL, &clk_gpio->hw); 148 + err = clk_hw_register(NULL, hw); 148 149 149 - if (!IS_ERR(clk)) 150 - return clk; 150 + if (!err) 151 + return hw; 151 152 152 153 if (!dev) { 153 154 gpiod_put(clk_gpio->gpiod); 154 155 kfree(clk_gpio); 155 156 } 156 157 157 - return clk; 158 + return ERR_PTR(err); 158 159 } 159 160 160 161 /** 161 - * clk_register_gpio_gate - register a gpio clock gate with the clock framework 162 + * clk_hw_register_gpio_gate - register a gpio clock gate with the clock 163 + * framework 162 164 * @dev: device that is registering this clock 163 165 * @name: name of this clock 164 166 * @parent_name: name of this clock's parent ··· 168 166 * @active_low: true if gpio should be set to 0 to enable clock 169 167 * @flags: clock flags 170 168 */ 171 - struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 169 + struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, 172 170 const char *parent_name, unsigned gpio, bool active_low, 173 171 unsigned long flags) 174 172 { ··· 177 175 (parent_name ? 1 : 0), gpio, active_low, flags, 178 176 &clk_gpio_gate_ops); 179 177 } 178 + EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate); 179 + 180 + struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 181 + const char *parent_name, unsigned gpio, bool active_low, 182 + unsigned long flags) 183 + { 184 + struct clk_hw *hw; 185 + 186 + hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpio, active_low, 187 + flags); 188 + if (IS_ERR(hw)) 189 + return ERR_CAST(hw); 190 + return hw->clk; 191 + } 180 192 EXPORT_SYMBOL_GPL(clk_register_gpio_gate); 181 193 182 194 /** 183 - * clk_register_gpio_mux - register a gpio clock mux with the clock framework 195 + * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework 184 196 * @dev: device that is registering this clock 185 197 * @name: name of this clock 186 198 * @parent_names: names of this clock's parents ··· 203 187 * @active_low: true if gpio should be set to 0 to enable clock 204 188 * @flags: clock flags 205 189 */ 206 - struct clk *clk_register_gpio_mux(struct device *dev, const char *name, 190 + struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name, 207 191 const char * const *parent_names, u8 num_parents, unsigned gpio, 208 192 bool active_low, unsigned long flags) 209 193 { ··· 214 198 215 199 return clk_register_gpio(dev, name, parent_names, num_parents, 216 200 gpio, active_low, flags, &clk_gpio_mux_ops); 201 + } 202 + EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux); 203 + 204 + struct clk *clk_register_gpio_mux(struct device *dev, const char *name, 205 + const char * const *parent_names, u8 num_parents, unsigned gpio, 206 + bool active_low, unsigned long flags) 207 + { 208 + struct clk_hw *hw; 209 + 210 + hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents, 211 + gpio, active_low, flags); 212 + if (IS_ERR(hw)) 213 + return ERR_CAST(hw); 214 + return hw->clk; 217 215 } 218 216 EXPORT_SYMBOL_GPL(clk_register_gpio_mux); 219 217
+1 -2
drivers/clk/clk-ls1x.c
··· 88 88 { 89 89 struct clk *clk; 90 90 91 - clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, CLK_IS_ROOT, 92 - OSC); 91 + clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, 0, OSC); 93 92 clk_register_clkdev(clk, "osc_33m_clk", NULL); 94 93 95 94 /* clock derived from 33 MHz OSC clk */
+51 -6
drivers/clk/clk-mux.c
··· 113 113 }; 114 114 EXPORT_SYMBOL_GPL(clk_mux_ro_ops); 115 115 116 - struct clk *clk_register_mux_table(struct device *dev, const char *name, 116 + struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, 117 117 const char * const *parent_names, u8 num_parents, 118 118 unsigned long flags, 119 119 void __iomem *reg, u8 shift, u32 mask, 120 120 u8 clk_mux_flags, u32 *table, spinlock_t *lock) 121 121 { 122 122 struct clk_mux *mux; 123 - struct clk *clk; 123 + struct clk_hw *hw; 124 124 struct clk_init_data init; 125 125 u8 width = 0; 126 + int ret; 126 127 127 128 if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { 128 129 width = fls(mask) - ffs(mask) + 1; ··· 158 157 mux->table = table; 159 158 mux->hw.init = &init; 160 159 161 - clk = clk_register(dev, &mux->hw); 162 - 163 - if (IS_ERR(clk)) 160 + hw = &mux->hw; 161 + ret = clk_hw_register(dev, hw); 162 + if (ret) { 164 163 kfree(mux); 164 + hw = ERR_PTR(ret); 165 + } 165 166 166 - return clk; 167 + return hw; 168 + } 169 + EXPORT_SYMBOL_GPL(clk_hw_register_mux_table); 170 + 171 + struct clk *clk_register_mux_table(struct device *dev, const char *name, 172 + const char * const *parent_names, u8 num_parents, 173 + unsigned long flags, 174 + void __iomem *reg, u8 shift, u32 mask, 175 + u8 clk_mux_flags, u32 *table, spinlock_t *lock) 176 + { 177 + struct clk_hw *hw; 178 + 179 + hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents, 180 + flags, reg, shift, mask, clk_mux_flags, 181 + table, lock); 182 + if (IS_ERR(hw)) 183 + return ERR_CAST(hw); 184 + return hw->clk; 167 185 } 168 186 EXPORT_SYMBOL_GPL(clk_register_mux_table); 169 187 ··· 200 180 } 201 181 EXPORT_SYMBOL_GPL(clk_register_mux); 202 182 183 + struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name, 184 + const char * const *parent_names, u8 num_parents, 185 + unsigned long flags, 186 + void __iomem *reg, u8 shift, u8 width, 187 + u8 clk_mux_flags, spinlock_t *lock) 188 + { 189 + u32 mask = BIT(width) - 1; 190 + 191 + return clk_hw_register_mux_table(dev, name, parent_names, num_parents, 192 + flags, reg, shift, mask, clk_mux_flags, 193 + NULL, lock); 194 + } 195 + EXPORT_SYMBOL_GPL(clk_hw_register_mux); 196 + 203 197 void clk_unregister_mux(struct clk *clk) 204 198 { 205 199 struct clk_mux *mux; ··· 229 195 kfree(mux); 230 196 } 231 197 EXPORT_SYMBOL_GPL(clk_unregister_mux); 198 + 199 + void clk_hw_unregister_mux(struct clk_hw *hw) 200 + { 201 + struct clk_mux *mux; 202 + 203 + mux = to_clk_mux(hw); 204 + 205 + clk_hw_unregister(hw); 206 + kfree(mux); 207 + } 208 + EXPORT_SYMBOL_GPL(clk_hw_unregister_mux);
+1 -2
drivers/clk/clk-nspire.c
··· 125 125 126 126 of_property_read_string(node, "clock-output-names", &clk_name); 127 127 128 - clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, 129 - info.base_clock); 128 + clk = clk_register_fixed_rate(NULL, clk_name, NULL, 0, info.base_clock); 130 129 if (!IS_ERR(clk)) 131 130 of_clk_add_provider(node, of_clk_src_simple_get, clk); 132 131 else
+195
drivers/clk/clk-oxnas.c
··· 1 + /* 2 + * Copyright (C) 2010 Broadcom 3 + * Copyright (C) 2012 Stephen Warren 4 + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + 19 + #include <linux/clk-provider.h> 20 + #include <linux/kernel.h> 21 + #include <linux/module.h> 22 + #include <linux/of.h> 23 + #include <linux/platform_device.h> 24 + #include <linux/stringify.h> 25 + #include <linux/regmap.h> 26 + #include <linux/mfd/syscon.h> 27 + 28 + /* Standard regmap gate clocks */ 29 + struct clk_oxnas { 30 + struct clk_hw hw; 31 + signed char bit; 32 + struct regmap *regmap; 33 + }; 34 + 35 + /* Regmap offsets */ 36 + #define CLK_STAT_REGOFFSET 0x24 37 + #define CLK_SET_REGOFFSET 0x2c 38 + #define CLK_CLR_REGOFFSET 0x30 39 + 40 + static inline struct clk_oxnas *to_clk_oxnas(struct clk_hw *hw) 41 + { 42 + return container_of(hw, struct clk_oxnas, hw); 43 + } 44 + 45 + static int oxnas_clk_is_enabled(struct clk_hw *hw) 46 + { 47 + struct clk_oxnas *std = to_clk_oxnas(hw); 48 + int ret; 49 + unsigned int val; 50 + 51 + ret = regmap_read(std->regmap, CLK_STAT_REGOFFSET, &val); 52 + if (ret < 0) 53 + return ret; 54 + 55 + return val & BIT(std->bit); 56 + } 57 + 58 + static int oxnas_clk_enable(struct clk_hw *hw) 59 + { 60 + struct clk_oxnas *std = to_clk_oxnas(hw); 61 + 62 + regmap_write(std->regmap, CLK_SET_REGOFFSET, BIT(std->bit)); 63 + 64 + return 0; 65 + } 66 + 67 + static void oxnas_clk_disable(struct clk_hw *hw) 68 + { 69 + struct clk_oxnas *std = to_clk_oxnas(hw); 70 + 71 + regmap_write(std->regmap, CLK_CLR_REGOFFSET, BIT(std->bit)); 72 + } 73 + 74 + static const struct clk_ops oxnas_clk_ops = { 75 + .enable = oxnas_clk_enable, 76 + .disable = oxnas_clk_disable, 77 + .is_enabled = oxnas_clk_is_enabled, 78 + }; 79 + 80 + static const char *const oxnas_clk_parents[] = { 81 + "oscillator", 82 + }; 83 + 84 + static const char *const eth_parents[] = { 85 + "gmacclk", 86 + }; 87 + 88 + #define DECLARE_STD_CLKP(__clk, __parent) \ 89 + static const struct clk_init_data clk_##__clk##_init = { \ 90 + .name = __stringify(__clk), \ 91 + .ops = &oxnas_clk_ops, \ 92 + .parent_names = __parent, \ 93 + .num_parents = ARRAY_SIZE(__parent), \ 94 + } 95 + 96 + #define DECLARE_STD_CLK(__clk) DECLARE_STD_CLKP(__clk, oxnas_clk_parents) 97 + 98 + /* Hardware Bit - Clock association */ 99 + struct clk_oxnas_init_data { 100 + unsigned long bit; 101 + const struct clk_init_data *clk_init; 102 + }; 103 + 104 + /* Clk init data declaration */ 105 + DECLARE_STD_CLK(leon); 106 + DECLARE_STD_CLK(dma_sgdma); 107 + DECLARE_STD_CLK(cipher); 108 + DECLARE_STD_CLK(sata); 109 + DECLARE_STD_CLK(audio); 110 + DECLARE_STD_CLK(usbmph); 111 + DECLARE_STD_CLKP(etha, eth_parents); 112 + DECLARE_STD_CLK(pciea); 113 + DECLARE_STD_CLK(nand); 114 + 115 + /* Table index is clock indice */ 116 + static const struct clk_oxnas_init_data clk_oxnas_init[] = { 117 + [0] = {0, &clk_leon_init}, 118 + [1] = {1, &clk_dma_sgdma_init}, 119 + [2] = {2, &clk_cipher_init}, 120 + /* Skip & Do not touch to DDR clock */ 121 + [3] = {4, &clk_sata_init}, 122 + [4] = {5, &clk_audio_init}, 123 + [5] = {6, &clk_usbmph_init}, 124 + [6] = {7, &clk_etha_init}, 125 + [7] = {8, &clk_pciea_init}, 126 + [8] = {9, &clk_nand_init}, 127 + }; 128 + 129 + struct clk_oxnas_data { 130 + struct clk_oxnas clk_oxnas[ARRAY_SIZE(clk_oxnas_init)]; 131 + struct clk_onecell_data onecell_data[ARRAY_SIZE(clk_oxnas_init)]; 132 + struct clk *clks[ARRAY_SIZE(clk_oxnas_init)]; 133 + }; 134 + 135 + static int oxnas_stdclk_probe(struct platform_device *pdev) 136 + { 137 + struct device_node *np = pdev->dev.of_node; 138 + struct clk_oxnas_data *clk_oxnas; 139 + struct regmap *regmap; 140 + int i; 141 + 142 + clk_oxnas = devm_kzalloc(&pdev->dev, sizeof(*clk_oxnas), GFP_KERNEL); 143 + if (!clk_oxnas) 144 + return -ENOMEM; 145 + 146 + regmap = syscon_node_to_regmap(of_get_parent(np)); 147 + if (!regmap) { 148 + dev_err(&pdev->dev, "failed to have parent regmap\n"); 149 + return -EINVAL; 150 + } 151 + 152 + for (i = 0; i < ARRAY_SIZE(clk_oxnas_init); i++) { 153 + struct clk_oxnas *_clk; 154 + 155 + _clk = &clk_oxnas->clk_oxnas[i]; 156 + _clk->bit = clk_oxnas_init[i].bit; 157 + _clk->hw.init = clk_oxnas_init[i].clk_init; 158 + _clk->regmap = regmap; 159 + 160 + clk_oxnas->clks[i] = 161 + devm_clk_register(&pdev->dev, &_clk->hw); 162 + if (WARN_ON(IS_ERR(clk_oxnas->clks[i]))) 163 + return PTR_ERR(clk_oxnas->clks[i]); 164 + } 165 + 166 + clk_oxnas->onecell_data->clks = clk_oxnas->clks; 167 + clk_oxnas->onecell_data->clk_num = ARRAY_SIZE(clk_oxnas_init); 168 + 169 + return of_clk_add_provider(np, of_clk_src_onecell_get, 170 + clk_oxnas->onecell_data); 171 + } 172 + 173 + static int oxnas_stdclk_remove(struct platform_device *pdev) 174 + { 175 + of_clk_del_provider(pdev->dev.of_node); 176 + 177 + return 0; 178 + } 179 + 180 + static const struct of_device_id oxnas_stdclk_dt_ids[] = { 181 + { .compatible = "oxsemi,ox810se-stdclk" }, 182 + { } 183 + }; 184 + MODULE_DEVICE_TABLE(of, oxnas_stdclk_dt_ids); 185 + 186 + static struct platform_driver oxnas_stdclk_driver = { 187 + .probe = oxnas_stdclk_probe, 188 + .remove = oxnas_stdclk_remove, 189 + .driver = { 190 + .name = "oxnas-stdclk", 191 + .of_match_table = oxnas_stdclk_dt_ids, 192 + }, 193 + }; 194 + 195 + module_platform_driver(oxnas_stdclk_driver);
+2 -2
drivers/clk/clk-palmas.c
··· 132 132 .init = { 133 133 .name = "clk32kg", 134 134 .ops = &palmas_clks_ops, 135 - .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, 135 + .flags = CLK_IGNORE_UNUSED, 136 136 }, 137 137 .desc = { 138 138 .clk_name = "clk32kg", ··· 148 148 .init = { 149 149 .name = "clk32kgaudio", 150 150 .ops = &palmas_clks_ops, 151 - .flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED, 151 + .flags = CLK_IGNORE_UNUSED, 152 152 }, 153 153 .desc = { 154 154 .clk_name = "clk32kgaudio",
+3 -2
drivers/clk/clk-qoriq.c
··· 869 869 } 870 870 } 871 871 872 - static struct clk *sysclk_from_fixed(struct device_node *node, const char *name) 872 + static struct clk __init 873 + *sysclk_from_fixed(struct device_node *node, const char *name) 873 874 { 874 875 u32 rate; 875 876 876 877 if (of_property_read_u32(node, "clock-frequency", &rate)) 877 878 return ERR_PTR(-ENODEV); 878 879 879 - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); 880 + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); 880 881 } 881 882 882 883 static struct clk *sysclk_from_parent(const char *name)
-1
drivers/clk/clk-rk808.c
··· 106 106 if (!clk_table) 107 107 return -ENOMEM; 108 108 109 - init.flags = CLK_IS_ROOT; 110 109 init.parent_names = NULL; 111 110 init.num_parents = 0; 112 111 init.name = "rk808-clkout1";
+48 -25
drivers/clk/clk-tango4.c
··· 4 4 #include <linux/init.h> 5 5 #include <linux/io.h> 6 6 7 - static struct clk *out[2]; 8 - static struct clk_onecell_data clk_data = { out, 2 }; 7 + #define CLK_COUNT 4 /* cpu_clk, sys_clk, usb_clk, sdio_clk */ 8 + static struct clk *clks[CLK_COUNT]; 9 + static struct clk_onecell_data clk_data = { clks, CLK_COUNT }; 9 10 10 - #define SYSCLK_CTRL 0x20 11 - #define CPUCLK_CTRL 0x24 12 - #define LEGACY_DIV 0x3c 11 + #define SYSCLK_DIV 0x20 12 + #define CPUCLK_DIV 0x24 13 + #define DIV_BYPASS BIT(23) 13 14 14 - #define PLL_N(val) (((val) >> 0) & 0x7f) 15 - #define PLL_K(val) (((val) >> 13) & 0x7) 16 - #define PLL_M(val) (((val) >> 16) & 0x7) 17 - #define DIV_INDEX(val) (((val) >> 8) & 0xf) 15 + /*** CLKGEN_PLL ***/ 16 + #define extract_pll_n(val) ((val >> 0) & ((1u << 7) - 1)) 17 + #define extract_pll_k(val) ((val >> 13) & ((1u << 3) - 1)) 18 + #define extract_pll_m(val) ((val >> 16) & ((1u << 3) - 1)) 19 + #define extract_pll_isel(val) ((val >> 24) & ((1u << 3) - 1)) 18 20 19 21 static void __init make_pll(int idx, const char *parent, void __iomem *base) 20 22 { ··· 24 22 u32 val, mul, div; 25 23 26 24 sprintf(name, "pll%d", idx); 27 - val = readl_relaxed(base + idx*8); 28 - mul = PLL_N(val) + 1; 29 - div = (PLL_M(val) + 1) << PLL_K(val); 25 + val = readl(base + idx * 8); 26 + mul = extract_pll_n(val) + 1; 27 + div = (extract_pll_m(val) + 1) << extract_pll_k(val); 30 28 clk_register_fixed_factor(NULL, name, parent, 0, mul, div); 29 + if (extract_pll_isel(val) != 1) 30 + panic("%s: input not set to XTAL_IN\n", name); 31 31 } 32 32 33 - static int __init get_div(void __iomem *base) 33 + static void __init make_cd(int idx, void __iomem *base) 34 34 { 35 - u8 sysclk_tab[16] = { 2, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4 }; 36 - int idx = DIV_INDEX(readl_relaxed(base + LEGACY_DIV)); 35 + char name[8]; 36 + u32 val, mul, div; 37 37 38 - return sysclk_tab[idx]; 38 + sprintf(name, "cd%d", idx); 39 + val = readl(base + idx * 8); 40 + mul = 1 << 27; 41 + div = (2 << 27) + val; 42 + clk_register_fixed_factor(NULL, name, "pll2", 0, mul, div); 43 + if (val > 0xf0000000) 44 + panic("%s: unsupported divider %x\n", name, val); 39 45 } 40 46 41 47 static void __init tango4_clkgen_setup(struct device_node *np) 42 48 { 43 - int div, ret; 49 + struct clk **pp = clk_data.clks; 44 50 void __iomem *base = of_iomap(np, 0); 45 51 const char *parent = of_clk_get_parent_name(np, 0); 46 52 47 53 if (!base) 48 - panic("%s: invalid address\n", np->full_name); 54 + panic("%s: invalid address\n", np->name); 55 + 56 + if (readl(base + CPUCLK_DIV) & DIV_BYPASS) 57 + panic("%s: unsupported cpuclk setup\n", np->name); 58 + 59 + if (readl(base + SYSCLK_DIV) & DIV_BYPASS) 60 + panic("%s: unsupported sysclk setup\n", np->name); 61 + 62 + writel(0x100, base + CPUCLK_DIV); /* disable frequency ramping */ 49 63 50 64 make_pll(0, parent, base); 51 65 make_pll(1, parent, base); 66 + make_pll(2, parent, base); 67 + make_cd(2, base + 0x80); 68 + make_cd(6, base + 0x80); 52 69 53 - out[0] = clk_register_divider(NULL, "cpuclk", "pll0", 0, 54 - base + CPUCLK_CTRL, 8, 8, CLK_DIVIDER_ONE_BASED, NULL); 70 + pp[0] = clk_register_divider(NULL, "cpu_clk", "pll0", 0, 71 + base + CPUCLK_DIV, 8, 8, CLK_DIVIDER_ONE_BASED, NULL); 72 + pp[1] = clk_register_fixed_factor(NULL, "sys_clk", "pll1", 0, 1, 4); 73 + pp[2] = clk_register_fixed_factor(NULL, "usb_clk", "cd2", 0, 1, 2); 74 + pp[3] = clk_register_fixed_factor(NULL, "sdio_clk", "cd6", 0, 1, 2); 55 75 56 - div = readl_relaxed(base + SYSCLK_CTRL) & BIT(23) ? get_div(base) : 4; 57 - out[1] = clk_register_fixed_factor(NULL, "sysclk", "pll1", 0, 1, div); 76 + if (IS_ERR(pp[0]) || IS_ERR(pp[1]) || IS_ERR(pp[2]) || IS_ERR(pp[3])) 77 + panic("%s: clk registration failed\n", np->name); 58 78 59 - ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 60 - if (IS_ERR(out[0]) || IS_ERR(out[1]) || ret < 0) 61 - panic("%s: clk registration failed\n", np->full_name); 79 + if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) 80 + panic("%s: clk provider registration failed\n", np->name); 62 81 } 63 82 CLK_OF_DECLARE(tango4_clkgen, "sigma,tango4-clkgen", tango4_clkgen_setup);
-1
drivers/clk/clk-twl6040.c
··· 74 74 static struct clk_init_data wm831x_clkout_init = { 75 75 .name = "mcpdm_fclk", 76 76 .ops = &twl6040_mcpdm_ops, 77 - .flags = CLK_IS_ROOT, 78 77 }; 79 78 80 79 static int twl6040_clk_probe(struct platform_device *pdev)
-1
drivers/clk/clk-wm831x.c
··· 58 58 static struct clk_init_data wm831x_xtal_init = { 59 59 .name = "xtal", 60 60 .ops = &wm831x_xtal_ops, 61 - .flags = CLK_IS_ROOT, 62 61 }; 63 62 64 63 static const unsigned long wm831x_fll_auto_rates[] = {
+1 -1
drivers/clk/clk-xgene.c
··· 198 198 of_property_read_string(np, "clock-output-names", &clk_name); 199 199 clk = xgene_register_clk_pll(NULL, 200 200 clk_name, of_clk_get_parent_name(np, 0), 201 - CLK_IS_ROOT, reg, 0, pll_type, &clk_lock, 201 + 0, reg, 0, pll_type, &clk_lock, 202 202 version); 203 203 if (!IS_ERR(clk)) { 204 204 of_clk_add_provider(np, of_clk_src_simple_get, clk);
+218 -4
drivers/clk/clk.c
··· 574 574 if (WARN_ON(core->prepare_count == 0)) 575 575 return; 576 576 577 + if (WARN_ON(core->prepare_count == 1 && core->flags & CLK_IS_CRITICAL)) 578 + return; 579 + 577 580 if (--core->prepare_count > 0) 578 581 return; 579 582 ··· 680 677 return; 681 678 682 679 if (WARN_ON(core->enable_count == 0)) 680 + return; 681 + 682 + if (WARN_ON(core->enable_count == 1 && core->flags & CLK_IS_CRITICAL)) 683 683 return; 684 684 685 685 if (--core->enable_count > 0) ··· 2403 2397 if (core->ops->init) 2404 2398 core->ops->init(core->hw); 2405 2399 2400 + if (core->flags & CLK_IS_CRITICAL) { 2401 + unsigned long flags; 2402 + 2403 + clk_core_prepare(core); 2404 + 2405 + flags = clk_enable_lock(); 2406 + clk_core_enable(core); 2407 + clk_enable_unlock(flags); 2408 + } 2409 + 2406 2410 kref_init(&core->ref); 2407 2411 out: 2408 2412 clk_prepare_unlock(); ··· 2552 2536 } 2553 2537 EXPORT_SYMBOL_GPL(clk_register); 2554 2538 2539 + /** 2540 + * clk_hw_register - register a clk_hw and return an error code 2541 + * @dev: device that is registering this clock 2542 + * @hw: link to hardware-specific clock data 2543 + * 2544 + * clk_hw_register is the primary interface for populating the clock tree with 2545 + * new clock nodes. It returns an integer equal to zero indicating success or 2546 + * less than zero indicating failure. Drivers must test for an error code after 2547 + * calling clk_hw_register(). 2548 + */ 2549 + int clk_hw_register(struct device *dev, struct clk_hw *hw) 2550 + { 2551 + return PTR_ERR_OR_ZERO(clk_register(dev, hw)); 2552 + } 2553 + EXPORT_SYMBOL_GPL(clk_hw_register); 2554 + 2555 2555 /* Free memory allocated for a clock. */ 2556 2556 static void __clk_release(struct kref *ref) 2557 2557 { ··· 2669 2637 } 2670 2638 EXPORT_SYMBOL_GPL(clk_unregister); 2671 2639 2640 + /** 2641 + * clk_hw_unregister - unregister a currently registered clk_hw 2642 + * @hw: hardware-specific clock data to unregister 2643 + */ 2644 + void clk_hw_unregister(struct clk_hw *hw) 2645 + { 2646 + clk_unregister(hw->clk); 2647 + } 2648 + EXPORT_SYMBOL_GPL(clk_hw_unregister); 2649 + 2672 2650 static void devm_clk_release(struct device *dev, void *res) 2673 2651 { 2674 2652 clk_unregister(*(struct clk **)res); 2653 + } 2654 + 2655 + static void devm_clk_hw_release(struct device *dev, void *res) 2656 + { 2657 + clk_hw_unregister(*(struct clk_hw **)res); 2675 2658 } 2676 2659 2677 2660 /** ··· 2719 2672 } 2720 2673 EXPORT_SYMBOL_GPL(devm_clk_register); 2721 2674 2675 + /** 2676 + * devm_clk_hw_register - resource managed clk_hw_register() 2677 + * @dev: device that is registering this clock 2678 + * @hw: link to hardware-specific clock data 2679 + * 2680 + * Managed clk_hw_register(). Clocks registered by this function are 2681 + * automatically clk_hw_unregister()ed on driver detach. See clk_hw_register() 2682 + * for more information. 2683 + */ 2684 + int devm_clk_hw_register(struct device *dev, struct clk_hw *hw) 2685 + { 2686 + struct clk_hw **hwp; 2687 + int ret; 2688 + 2689 + hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL); 2690 + if (!hwp) 2691 + return -ENOMEM; 2692 + 2693 + ret = clk_hw_register(dev, hw); 2694 + if (!ret) { 2695 + *hwp = hw; 2696 + devres_add(dev, hwp); 2697 + } else { 2698 + devres_free(hwp); 2699 + } 2700 + 2701 + return ret; 2702 + } 2703 + EXPORT_SYMBOL_GPL(devm_clk_hw_register); 2704 + 2722 2705 static int devm_clk_match(struct device *dev, void *res, void *data) 2723 2706 { 2724 2707 struct clk *c = res; 2725 2708 if (WARN_ON(!c)) 2726 2709 return 0; 2727 2710 return c == data; 2711 + } 2712 + 2713 + static int devm_clk_hw_match(struct device *dev, void *res, void *data) 2714 + { 2715 + struct clk_hw *hw = res; 2716 + 2717 + if (WARN_ON(!hw)) 2718 + return 0; 2719 + return hw == data; 2728 2720 } 2729 2721 2730 2722 /** ··· 2779 2693 WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk)); 2780 2694 } 2781 2695 EXPORT_SYMBOL_GPL(devm_clk_unregister); 2696 + 2697 + /** 2698 + * devm_clk_hw_unregister - resource managed clk_hw_unregister() 2699 + * @dev: device that is unregistering the hardware-specific clock data 2700 + * @hw: link to hardware-specific clock data 2701 + * 2702 + * Unregister a clk_hw registered with devm_clk_hw_register(). Normally 2703 + * this function will not need to be called and the resource management 2704 + * code will ensure that the resource is freed. 2705 + */ 2706 + void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw) 2707 + { 2708 + WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match, 2709 + hw)); 2710 + } 2711 + EXPORT_SYMBOL_GPL(devm_clk_hw_unregister); 2782 2712 2783 2713 /* 2784 2714 * clkdev helpers ··· 2957 2855 2958 2856 struct device_node *node; 2959 2857 struct clk *(*get)(struct of_phandle_args *clkspec, void *data); 2858 + struct clk_hw *(*get_hw)(struct of_phandle_args *clkspec, void *data); 2960 2859 void *data; 2961 2860 }; 2962 2861 ··· 2974 2871 } 2975 2872 EXPORT_SYMBOL_GPL(of_clk_src_simple_get); 2976 2873 2874 + struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data) 2875 + { 2876 + return data; 2877 + } 2878 + EXPORT_SYMBOL_GPL(of_clk_hw_simple_get); 2879 + 2977 2880 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) 2978 2881 { 2979 2882 struct clk_onecell_data *clk_data = data; ··· 2993 2884 return clk_data->clks[idx]; 2994 2885 } 2995 2886 EXPORT_SYMBOL_GPL(of_clk_src_onecell_get); 2887 + 2888 + struct clk_hw * 2889 + of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data) 2890 + { 2891 + struct clk_hw_onecell_data *hw_data = data; 2892 + unsigned int idx = clkspec->args[0]; 2893 + 2894 + if (idx >= hw_data->num) { 2895 + pr_err("%s: invalid index %u\n", __func__, idx); 2896 + return ERR_PTR(-EINVAL); 2897 + } 2898 + 2899 + return hw_data->hws[idx]; 2900 + } 2901 + EXPORT_SYMBOL_GPL(of_clk_hw_onecell_get); 2996 2902 2997 2903 /** 2998 2904 * of_clk_add_provider() - Register a clock provider for a node ··· 3045 2921 EXPORT_SYMBOL_GPL(of_clk_add_provider); 3046 2922 3047 2923 /** 2924 + * of_clk_add_hw_provider() - Register a clock provider for a node 2925 + * @np: Device node pointer associated with clock provider 2926 + * @get: callback for decoding clk_hw 2927 + * @data: context pointer for @get callback. 2928 + */ 2929 + int of_clk_add_hw_provider(struct device_node *np, 2930 + struct clk_hw *(*get)(struct of_phandle_args *clkspec, 2931 + void *data), 2932 + void *data) 2933 + { 2934 + struct of_clk_provider *cp; 2935 + int ret; 2936 + 2937 + cp = kzalloc(sizeof(*cp), GFP_KERNEL); 2938 + if (!cp) 2939 + return -ENOMEM; 2940 + 2941 + cp->node = of_node_get(np); 2942 + cp->data = data; 2943 + cp->get_hw = get; 2944 + 2945 + mutex_lock(&of_clk_mutex); 2946 + list_add(&cp->link, &of_clk_providers); 2947 + mutex_unlock(&of_clk_mutex); 2948 + pr_debug("Added clk_hw provider from %s\n", np->full_name); 2949 + 2950 + ret = of_clk_set_defaults(np, true); 2951 + if (ret < 0) 2952 + of_clk_del_provider(np); 2953 + 2954 + return ret; 2955 + } 2956 + EXPORT_SYMBOL_GPL(of_clk_add_hw_provider); 2957 + 2958 + /** 3048 2959 * of_clk_del_provider() - Remove a previously registered clock provider 3049 2960 * @np: Device node pointer associated with clock provider 3050 2961 */ ··· 3100 2941 } 3101 2942 EXPORT_SYMBOL_GPL(of_clk_del_provider); 3102 2943 2944 + static struct clk_hw * 2945 + __of_clk_get_hw_from_provider(struct of_clk_provider *provider, 2946 + struct of_phandle_args *clkspec) 2947 + { 2948 + struct clk *clk; 2949 + struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); 2950 + 2951 + if (provider->get_hw) { 2952 + hw = provider->get_hw(clkspec, provider->data); 2953 + } else if (provider->get) { 2954 + clk = provider->get(clkspec, provider->data); 2955 + if (!IS_ERR(clk)) 2956 + hw = __clk_get_hw(clk); 2957 + else 2958 + hw = ERR_CAST(clk); 2959 + } 2960 + 2961 + return hw; 2962 + } 2963 + 3103 2964 struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec, 3104 2965 const char *dev_id, const char *con_id) 3105 2966 { 3106 2967 struct of_clk_provider *provider; 3107 2968 struct clk *clk = ERR_PTR(-EPROBE_DEFER); 2969 + struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER); 3108 2970 3109 2971 if (!clkspec) 3110 2972 return ERR_PTR(-EINVAL); ··· 3134 2954 mutex_lock(&of_clk_mutex); 3135 2955 list_for_each_entry(provider, &of_clk_providers, link) { 3136 2956 if (provider->node == clkspec->np) 3137 - clk = provider->get(clkspec, provider->data); 3138 - if (!IS_ERR(clk)) { 3139 - clk = __clk_create_clk(__clk_get_hw(clk), dev_id, 3140 - con_id); 2957 + hw = __of_clk_get_hw_from_provider(provider, clkspec); 2958 + if (!IS_ERR(hw)) { 2959 + clk = __clk_create_clk(hw, dev_id, con_id); 3141 2960 3142 2961 if (!IS_ERR(clk) && !__clk_get(clk)) { 3143 2962 __clk_free_clk(clk); ··· 3303 3124 */ 3304 3125 return 1; 3305 3126 } 3127 + } 3128 + 3129 + /** 3130 + * of_clk_detect_critical() - set CLK_IS_CRITICAL flag from Device Tree 3131 + * @np: Device node pointer associated with clock provider 3132 + * @index: clock index 3133 + * @flags: pointer to clk_core->flags 3134 + * 3135 + * Detects if the clock-critical property exists and, if so, sets the 3136 + * corresponding CLK_IS_CRITICAL flag. 3137 + * 3138 + * Do not use this function. It exists only for legacy Device Tree 3139 + * bindings, such as the one-clock-per-node style that are outdated. 3140 + * Those bindings typically put all clock data into .dts and the Linux 3141 + * driver has no clock data, thus making it impossible to set this flag 3142 + * correctly from the driver. Only those drivers may call 3143 + * of_clk_detect_critical from their setup functions. 3144 + * 3145 + * Return: error code or zero on success 3146 + */ 3147 + int of_clk_detect_critical(struct device_node *np, 3148 + int index, unsigned long *flags) 3149 + { 3150 + struct property *prop; 3151 + const __be32 *cur; 3152 + uint32_t idx; 3153 + 3154 + if (!np || !flags) 3155 + return -EINVAL; 3156 + 3157 + of_property_for_each_u32(np, "clock-critical", prop, cur, idx) 3158 + if (index == idx) 3159 + *flags |= CLK_IS_CRITICAL; 3160 + 3161 + return 0; 3306 3162 } 3307 3163 3308 3164 /**
+56 -19
drivers/clk/clkdev.c
··· 301 301 } 302 302 EXPORT_SYMBOL(clkdev_alloc); 303 303 304 + struct clk_lookup * 305 + clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...) 306 + { 307 + struct clk_lookup *cl; 308 + va_list ap; 309 + 310 + va_start(ap, dev_fmt); 311 + cl = vclkdev_alloc(hw, con_id, dev_fmt, ap); 312 + va_end(ap); 313 + 314 + return cl; 315 + } 316 + EXPORT_SYMBOL(clkdev_hw_alloc); 317 + 304 318 /** 305 319 * clkdev_create - allocate and add a clkdev lookup structure 306 320 * @clk: struct clk to associate with all clk_lookups ··· 337 323 return cl; 338 324 } 339 325 EXPORT_SYMBOL_GPL(clkdev_create); 326 + 327 + /** 328 + * clkdev_hw_create - allocate and add a clkdev lookup structure 329 + * @hw: struct clk_hw to associate with all clk_lookups 330 + * @con_id: connection ID string on device 331 + * @dev_fmt: format string describing device name 332 + * 333 + * Returns a clk_lookup structure, which can be later unregistered and 334 + * freed. 335 + */ 336 + struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id, 337 + const char *dev_fmt, ...) 338 + { 339 + struct clk_lookup *cl; 340 + va_list ap; 341 + 342 + va_start(ap, dev_fmt); 343 + cl = vclkdev_create(hw, con_id, dev_fmt, ap); 344 + va_end(ap); 345 + 346 + return cl; 347 + } 348 + EXPORT_SYMBOL_GPL(clkdev_hw_create); 340 349 341 350 int clk_add_alias(const char *alias, const char *alias_dev_name, 342 351 const char *con_id, struct device *dev) ··· 441 404 EXPORT_SYMBOL(clk_register_clkdev); 442 405 443 406 /** 444 - * clk_register_clkdevs - register a set of clk_lookup for a struct clk 445 - * @clk: struct clk to associate with all clk_lookups 446 - * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized 447 - * @num: number of clk_lookup structures to register 407 + * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw 408 + * @hw: struct clk_hw to associate with all clk_lookups 409 + * @con_id: connection ID string on device 410 + * @dev_id: format string describing device name 448 411 * 449 - * To make things easier for mass registration, we detect error clks 450 - * from a previous clk_register() call, and return the error code for 451 - * those. This is to permit this function to be called immediately 452 - * after clk_register(). 412 + * con_id or dev_id may be NULL as a wildcard, just as in the rest of 413 + * clkdev. 453 414 */ 454 - int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num) 415 + int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id, 416 + const char *dev_id) 455 417 { 456 - unsigned i; 418 + struct clk_lookup *cl; 457 419 458 - if (IS_ERR(clk)) 459 - return PTR_ERR(clk); 420 + /* 421 + * Since dev_id can be NULL, and NULL is handled specially, we must 422 + * pass it as either a NULL format string, or with "%s". 423 + */ 424 + if (dev_id) 425 + cl = __clk_register_clkdev(hw, con_id, "%s", dev_id); 426 + else 427 + cl = __clk_register_clkdev(hw, con_id, NULL); 460 428 461 - for (i = 0; i < num; i++, cl++) { 462 - cl->clk_hw = __clk_get_hw(clk); 463 - __clkdev_add(cl); 464 - } 465 - 466 - return 0; 429 + return cl ? 0 : -ENOMEM; 467 430 } 468 - EXPORT_SYMBOL(clk_register_clkdevs); 431 + EXPORT_SYMBOL(clk_hw_register_clkdev);
+15
drivers/clk/hisilicon/Kconfig
··· 1 + config COMMON_CLK_HI3519 2 + tristate "Hi3519 Clock Driver" 3 + depends on ARCH_HISI || COMPILE_TEST 4 + select RESET_HISI 5 + default ARCH_HISI 6 + help 7 + Build the clock driver for hi3519. 8 + 1 9 config COMMON_CLK_HI6220 2 10 bool "Hi6220 Clock Driver" 3 11 depends on ARCH_HISI || COMPILE_TEST 4 12 default ARCH_HISI 5 13 help 6 14 Build the Hisilicon Hi6220 clock driver based on the common clock framework. 15 + 16 + config RESET_HISI 17 + bool "HiSilicon Reset Controller Driver" 18 + depends on ARCH_HISI || COMPILE_TEST 19 + select RESET_CONTROLLER 20 + help 21 + Build reset controller driver for HiSilicon device chipsets. 7 22 8 23 config STUB_CLK_HI6220 9 24 bool "Hi6220 Stub Clock Driver"
+2
drivers/clk/hisilicon/Makefile
··· 7 7 obj-$(CONFIG_ARCH_HI3xxx) += clk-hi3620.o 8 8 obj-$(CONFIG_ARCH_HIP04) += clk-hip04.o 9 9 obj-$(CONFIG_ARCH_HIX5HD2) += clk-hix5hd2.o 10 + obj-$(CONFIG_COMMON_CLK_HI3519) += clk-hi3519.o 10 11 obj-$(CONFIG_COMMON_CLK_HI6220) += clk-hi6220.o 12 + obj-$(CONFIG_RESET_HISI) += reset.o 11 13 obj-$(CONFIG_STUB_CLK_HI6220) += clk-hi6220-stub.o
+131
drivers/clk/hisilicon/clk-hi3519.c
··· 1 + /* 2 + * Hi3519 Clock Driver 3 + * 4 + * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <dt-bindings/clock/hi3519-clock.h> 21 + #include <linux/clk-provider.h> 22 + #include <linux/module.h> 23 + #include <linux/platform_device.h> 24 + #include "clk.h" 25 + #include "reset.h" 26 + 27 + #define HI3519_INNER_CLK_OFFSET 64 28 + #define HI3519_FIXED_24M 65 29 + #define HI3519_FIXED_50M 66 30 + #define HI3519_FIXED_75M 67 31 + #define HI3519_FIXED_125M 68 32 + #define HI3519_FIXED_150M 69 33 + #define HI3519_FIXED_200M 70 34 + #define HI3519_FIXED_250M 71 35 + #define HI3519_FIXED_300M 72 36 + #define HI3519_FIXED_400M 73 37 + #define HI3519_FMC_MUX 74 38 + 39 + #define HI3519_NR_CLKS 128 40 + 41 + static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = { 42 + { HI3519_FIXED_24M, "24m", NULL, 0, 24000000, }, 43 + { HI3519_FIXED_50M, "50m", NULL, 0, 50000000, }, 44 + { HI3519_FIXED_75M, "75m", NULL, 0, 75000000, }, 45 + { HI3519_FIXED_125M, "125m", NULL, 0, 125000000, }, 46 + { HI3519_FIXED_150M, "150m", NULL, 0, 150000000, }, 47 + { HI3519_FIXED_200M, "200m", NULL, 0, 200000000, }, 48 + { HI3519_FIXED_250M, "250m", NULL, 0, 250000000, }, 49 + { HI3519_FIXED_300M, "300m", NULL, 0, 300000000, }, 50 + { HI3519_FIXED_400M, "400m", NULL, 0, 400000000, }, 51 + }; 52 + 53 + static const char *const fmc_mux_p[] = { 54 + "24m", "75m", "125m", "150m", "200m", "250m", "300m", "400m", }; 55 + static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7}; 56 + 57 + static const struct hisi_mux_clock hi3519_mux_clks[] = { 58 + { HI3519_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p), 59 + CLK_SET_RATE_PARENT, 0xc0, 2, 3, 0, fmc_mux_table, }, 60 + }; 61 + 62 + static const struct hisi_gate_clock hi3519_gate_clks[] = { 63 + { HI3519_FMC_CLK, "clk_fmc", "fmc_mux", 64 + CLK_SET_RATE_PARENT, 0xc0, 1, 0, }, 65 + { HI3519_UART0_CLK, "clk_uart0", "24m", 66 + CLK_SET_RATE_PARENT, 0xe4, 20, 0, }, 67 + { HI3519_UART1_CLK, "clk_uart1", "24m", 68 + CLK_SET_RATE_PARENT, 0xe4, 21, 0, }, 69 + { HI3519_UART2_CLK, "clk_uart2", "24m", 70 + CLK_SET_RATE_PARENT, 0xe4, 22, 0, }, 71 + { HI3519_UART3_CLK, "clk_uart3", "24m", 72 + CLK_SET_RATE_PARENT, 0xe4, 23, 0, }, 73 + { HI3519_UART4_CLK, "clk_uart4", "24m", 74 + CLK_SET_RATE_PARENT, 0xe4, 24, 0, }, 75 + { HI3519_SPI0_CLK, "clk_spi0", "50m", 76 + CLK_SET_RATE_PARENT, 0xe4, 16, 0, }, 77 + { HI3519_SPI1_CLK, "clk_spi1", "50m", 78 + CLK_SET_RATE_PARENT, 0xe4, 17, 0, }, 79 + { HI3519_SPI2_CLK, "clk_spi2", "50m", 80 + CLK_SET_RATE_PARENT, 0xe4, 18, 0, }, 81 + }; 82 + 83 + static int hi3519_clk_probe(struct platform_device *pdev) 84 + { 85 + struct device_node *np = pdev->dev.of_node; 86 + struct hisi_clock_data *clk_data; 87 + struct hisi_reset_controller *rstc; 88 + 89 + rstc = hisi_reset_init(np); 90 + if (!rstc) 91 + return -ENOMEM; 92 + 93 + clk_data = hisi_clk_init(np, HI3519_NR_CLKS); 94 + if (!clk_data) { 95 + hisi_reset_exit(rstc); 96 + return -ENODEV; 97 + } 98 + 99 + hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks, 100 + ARRAY_SIZE(hi3519_fixed_rate_clks), 101 + clk_data); 102 + hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks), 103 + clk_data); 104 + hisi_clk_register_gate(hi3519_gate_clks, 105 + ARRAY_SIZE(hi3519_gate_clks), clk_data); 106 + 107 + return 0; 108 + } 109 + 110 + static const struct of_device_id hi3519_clk_match_table[] = { 111 + { .compatible = "hisilicon,hi3519-crg" }, 112 + { } 113 + }; 114 + MODULE_DEVICE_TABLE(of, hi3519_clk_match_table); 115 + 116 + static struct platform_driver hi3519_clk_driver = { 117 + .probe = hi3519_clk_probe, 118 + .driver = { 119 + .name = "hi3519-clk", 120 + .of_match_table = hi3519_clk_match_table, 121 + }, 122 + }; 123 + 124 + static int __init hi3519_clk_init(void) 125 + { 126 + return platform_driver_register(&hi3519_clk_driver); 127 + } 128 + core_initcall(hi3519_clk_init); 129 + 130 + MODULE_LICENSE("GPL v2"); 131 + MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");
+15 -8
drivers/clk/hisilicon/clk.c
··· 37 37 38 38 static DEFINE_SPINLOCK(hisi_clk_lock); 39 39 40 - struct hisi_clock_data __init *hisi_clk_init(struct device_node *np, 40 + struct hisi_clock_data *hisi_clk_init(struct device_node *np, 41 41 int nr_clks) 42 42 { 43 43 struct hisi_clock_data *clk_data; ··· 71 71 err: 72 72 return NULL; 73 73 } 74 + EXPORT_SYMBOL_GPL(hisi_clk_init); 74 75 75 - void __init hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *clks, 76 + void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks, 76 77 int nums, struct hisi_clock_data *data) 77 78 { 78 79 struct clk *clk; ··· 92 91 data->clk_data.clks[clks[i].id] = clk; 93 92 } 94 93 } 94 + EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_rate); 95 95 96 - void __init hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *clks, 96 + void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks, 97 97 int nums, 98 98 struct hisi_clock_data *data) 99 99 { ··· 114 112 data->clk_data.clks[clks[i].id] = clk; 115 113 } 116 114 } 115 + EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_factor); 117 116 118 - void __init hisi_clk_register_mux(struct hisi_mux_clock *clks, 117 + void hisi_clk_register_mux(const struct hisi_mux_clock *clks, 119 118 int nums, struct hisi_clock_data *data) 120 119 { 121 120 struct clk *clk; ··· 144 141 data->clk_data.clks[clks[i].id] = clk; 145 142 } 146 143 } 144 + EXPORT_SYMBOL_GPL(hisi_clk_register_mux); 147 145 148 - void __init hisi_clk_register_divider(struct hisi_divider_clock *clks, 146 + void hisi_clk_register_divider(const struct hisi_divider_clock *clks, 149 147 int nums, struct hisi_clock_data *data) 150 148 { 151 149 struct clk *clk; ··· 174 170 data->clk_data.clks[clks[i].id] = clk; 175 171 } 176 172 } 173 + EXPORT_SYMBOL_GPL(hisi_clk_register_divider); 177 174 178 - void __init hisi_clk_register_gate(struct hisi_gate_clock *clks, 175 + void hisi_clk_register_gate(const struct hisi_gate_clock *clks, 179 176 int nums, struct hisi_clock_data *data) 180 177 { 181 178 struct clk *clk; ··· 203 198 data->clk_data.clks[clks[i].id] = clk; 204 199 } 205 200 } 201 + EXPORT_SYMBOL_GPL(hisi_clk_register_gate); 206 202 207 - void __init hisi_clk_register_gate_sep(struct hisi_gate_clock *clks, 203 + void hisi_clk_register_gate_sep(const struct hisi_gate_clock *clks, 208 204 int nums, struct hisi_clock_data *data) 209 205 { 210 206 struct clk *clk; ··· 232 226 data->clk_data.clks[clks[i].id] = clk; 233 227 } 234 228 } 229 + EXPORT_SYMBOL_GPL(hisi_clk_register_gate_sep); 235 230 236 - void __init hi6220_clk_register_divider(struct hi6220_divider_clock *clks, 231 + void __init hi6220_clk_register_divider(const struct hi6220_divider_clock *clks, 237 232 int nums, struct hisi_clock_data *data) 238 233 { 239 234 struct clk *clk;
+7 -7
drivers/clk/hisilicon/clk.h
··· 111 111 u8 shift, u8 width, u32 mask_bit, spinlock_t *lock); 112 112 113 113 struct hisi_clock_data *hisi_clk_init(struct device_node *, int); 114 - void hisi_clk_register_fixed_rate(struct hisi_fixed_rate_clock *, 114 + void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *, 115 115 int, struct hisi_clock_data *); 116 - void hisi_clk_register_fixed_factor(struct hisi_fixed_factor_clock *, 116 + void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *, 117 117 int, struct hisi_clock_data *); 118 - void hisi_clk_register_mux(struct hisi_mux_clock *, int, 118 + void hisi_clk_register_mux(const struct hisi_mux_clock *, int, 119 119 struct hisi_clock_data *); 120 - void hisi_clk_register_divider(struct hisi_divider_clock *, 120 + void hisi_clk_register_divider(const struct hisi_divider_clock *, 121 121 int, struct hisi_clock_data *); 122 - void hisi_clk_register_gate(struct hisi_gate_clock *, 122 + void hisi_clk_register_gate(const struct hisi_gate_clock *, 123 123 int, struct hisi_clock_data *); 124 - void hisi_clk_register_gate_sep(struct hisi_gate_clock *, 124 + void hisi_clk_register_gate_sep(const struct hisi_gate_clock *, 125 125 int, struct hisi_clock_data *); 126 - void hi6220_clk_register_divider(struct hi6220_divider_clock *, 126 + void hi6220_clk_register_divider(const struct hi6220_divider_clock *, 127 127 int, struct hisi_clock_data *); 128 128 #endif /* __HISI_CLK_H */
+134
drivers/clk/hisilicon/reset.c
··· 1 + /* 2 + * Hisilicon Reset Controller Driver 3 + * 4 + * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 17 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + 20 + #include <linux/io.h> 21 + #include <linux/of_address.h> 22 + #include <linux/reset-controller.h> 23 + #include <linux/slab.h> 24 + #include <linux/spinlock.h> 25 + #include "reset.h" 26 + 27 + #define HISI_RESET_BIT_MASK 0x1f 28 + #define HISI_RESET_OFFSET_SHIFT 8 29 + #define HISI_RESET_OFFSET_MASK 0xffff00 30 + 31 + struct hisi_reset_controller { 32 + spinlock_t lock; 33 + void __iomem *membase; 34 + struct reset_controller_dev rcdev; 35 + }; 36 + 37 + 38 + #define to_hisi_reset_controller(rcdev) \ 39 + container_of(rcdev, struct hisi_reset_controller, rcdev) 40 + 41 + static int hisi_reset_of_xlate(struct reset_controller_dev *rcdev, 42 + const struct of_phandle_args *reset_spec) 43 + { 44 + u32 offset; 45 + u8 bit; 46 + 47 + offset = (reset_spec->args[0] << HISI_RESET_OFFSET_SHIFT) 48 + & HISI_RESET_OFFSET_MASK; 49 + bit = reset_spec->args[1] & HISI_RESET_BIT_MASK; 50 + 51 + return (offset | bit); 52 + } 53 + 54 + static int hisi_reset_assert(struct reset_controller_dev *rcdev, 55 + unsigned long id) 56 + { 57 + struct hisi_reset_controller *rstc = to_hisi_reset_controller(rcdev); 58 + unsigned long flags; 59 + u32 offset, reg; 60 + u8 bit; 61 + 62 + offset = (id & HISI_RESET_OFFSET_MASK) >> HISI_RESET_OFFSET_SHIFT; 63 + bit = id & HISI_RESET_BIT_MASK; 64 + 65 + spin_lock_irqsave(&rstc->lock, flags); 66 + 67 + reg = readl(rstc->membase + offset); 68 + writel(reg | BIT(bit), rstc->membase + offset); 69 + 70 + spin_unlock_irqrestore(&rstc->lock, flags); 71 + 72 + return 0; 73 + } 74 + 75 + static int hisi_reset_deassert(struct reset_controller_dev *rcdev, 76 + unsigned long id) 77 + { 78 + struct hisi_reset_controller *rstc = to_hisi_reset_controller(rcdev); 79 + unsigned long flags; 80 + u32 offset, reg; 81 + u8 bit; 82 + 83 + offset = (id & HISI_RESET_OFFSET_MASK) >> HISI_RESET_OFFSET_SHIFT; 84 + bit = id & HISI_RESET_BIT_MASK; 85 + 86 + spin_lock_irqsave(&rstc->lock, flags); 87 + 88 + reg = readl(rstc->membase + offset); 89 + writel(reg & ~BIT(bit), rstc->membase + offset); 90 + 91 + spin_unlock_irqrestore(&rstc->lock, flags); 92 + 93 + return 0; 94 + } 95 + 96 + static const struct reset_control_ops hisi_reset_ops = { 97 + .assert = hisi_reset_assert, 98 + .deassert = hisi_reset_deassert, 99 + }; 100 + 101 + struct hisi_reset_controller *hisi_reset_init(struct device_node *np) 102 + { 103 + struct hisi_reset_controller *rstc; 104 + 105 + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); 106 + if (!rstc) 107 + return NULL; 108 + 109 + rstc->membase = of_iomap(np, 0); 110 + if (!rstc->membase) { 111 + kfree(rstc); 112 + return NULL; 113 + } 114 + 115 + spin_lock_init(&rstc->lock); 116 + 117 + rstc->rcdev.owner = THIS_MODULE; 118 + rstc->rcdev.ops = &hisi_reset_ops; 119 + rstc->rcdev.of_node = np; 120 + rstc->rcdev.of_reset_n_cells = 2; 121 + rstc->rcdev.of_xlate = hisi_reset_of_xlate; 122 + reset_controller_register(&rstc->rcdev); 123 + 124 + return rstc; 125 + } 126 + EXPORT_SYMBOL_GPL(hisi_reset_init); 127 + 128 + void hisi_reset_exit(struct hisi_reset_controller *rstc) 129 + { 130 + reset_controller_unregister(&rstc->rcdev); 131 + iounmap(rstc->membase); 132 + kfree(rstc); 133 + } 134 + EXPORT_SYMBOL_GPL(hisi_reset_exit);
+36
drivers/clk/hisilicon/reset.h
··· 1 + /* 2 + * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __HISI_RESET_H 19 + #define __HISI_RESET_H 20 + 21 + struct device_node; 22 + struct hisi_reset_controller; 23 + 24 + #ifdef CONFIG_RESET_CONTROLLER 25 + struct hisi_reset_controller *hisi_reset_init(struct device_node *np); 26 + void hisi_reset_exit(struct hisi_reset_controller *rstc); 27 + #else 28 + static inline hisi_reset_controller *hisi_reset_init(struct device_node *np) 29 + { 30 + return 0; 31 + } 32 + static inline void hisi_reset_exit(struct hisi_reset_controller *rstc) 33 + {} 34 + #endif 35 + 36 + #endif /* __HISI_RESET_H */
+5 -2
drivers/clk/imx/clk-gate2.c
··· 31 31 struct clk_hw hw; 32 32 void __iomem *reg; 33 33 u8 bit_idx; 34 + u8 cgr_val; 34 35 u8 flags; 35 36 spinlock_t *lock; 36 37 unsigned int *share_count; ··· 51 50 goto out; 52 51 53 52 reg = readl(gate->reg); 54 - reg |= 3 << gate->bit_idx; 53 + reg &= ~(3 << gate->bit_idx); 54 + reg |= gate->cgr_val << gate->bit_idx; 55 55 writel(reg, gate->reg); 56 56 57 57 out: ··· 127 125 128 126 struct clk *clk_register_gate2(struct device *dev, const char *name, 129 127 const char *parent_name, unsigned long flags, 130 - void __iomem *reg, u8 bit_idx, 128 + void __iomem *reg, u8 bit_idx, u8 cgr_val, 131 129 u8 clk_gate2_flags, spinlock_t *lock, 132 130 unsigned int *share_count) 133 131 { ··· 142 140 /* struct clk_gate2 assignments */ 143 141 gate->reg = reg; 144 142 gate->bit_idx = bit_idx; 143 + gate->cgr_val = cgr_val; 145 144 gate->flags = clk_gate2_flags; 146 145 gate->lock = lock; 147 146 gate->share_count = share_count;
+2 -2
drivers/clk/imx/clk-imx35.c
··· 66 66 static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; 67 67 68 68 enum mx35_clks { 69 - ckih, ckil, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, 69 + ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, 70 70 arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel, 71 71 esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre, 72 72 spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre, ··· 79 79 rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, 80 80 ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, 81 81 wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate, 82 - gpu2d_gate, clk_max 82 + gpu2d_gate, ckil, clk_max 83 83 }; 84 84 85 85 static struct clk *clk[clk_max];
+6 -4
drivers/clk/imx/clk-imx6sx.c
··· 134 134 static u32 share_count_ssi1; 135 135 static u32 share_count_ssi2; 136 136 static u32 share_count_ssi3; 137 + static u32 share_count_sai1; 138 + static u32 share_count_sai2; 137 139 138 140 static struct clk ** const uart_clks[] __initconst = { 139 141 &clks[IMX6SX_CLK_UART_IPG], ··· 471 469 clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); 472 470 clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); 473 471 clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26); 474 - clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28); 475 - clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30); 476 - clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28); 477 - clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30); 472 + clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2_shared("sai1_ipg", "ipg", base + 0x7c, 28, &share_count_sai1); 473 + clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2_shared("sai2_ipg", "ipg", base + 0x7c, 30, &share_count_sai2); 474 + clks[IMX6SX_CLK_SAI1] = imx_clk_gate2_shared("sai1", "ssi1_podf", base + 0x7c, 28, &share_count_sai1); 475 + clks[IMX6SX_CLK_SAI2] = imx_clk_gate2_shared("sai2", "ssi2_podf", base + 0x7c, 30, &share_count_sai2); 478 476 479 477 /* CCGR6 */ 480 478 clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
+3 -2
drivers/clk/imx/clk-imx7d.c
··· 56 56 "pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk", 57 57 "pll_audio_main_clk", }; 58 58 59 - static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_135m_clk", 59 + static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk", 60 60 "pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", 61 61 "pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_main_clk", 62 62 "pll_video_main_clk", }; ··· 342 342 343 343 static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk", 344 344 "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk", 345 - "pll_audio_main_clk", "pll_video_main_clk", "osc_32k_clk", }; 345 + "pll_audio_main_clk", "pll_video_main_clk", "ckil", }; 346 346 347 347 static const char *lvds1_sel[] = { "pll_arm_main_clk", 348 348 "pll_sys_main_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk", ··· 382 382 383 383 clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0); 384 384 clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc"); 385 + clks[IMX7D_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); 385 386 386 387 np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-anatop"); 387 388 base = of_iomap(np, 0);
+8 -1
drivers/clk/imx/clk-pllv3.c
··· 44 44 u32 powerdown; 45 45 u32 div_mask; 46 46 u32 div_shift; 47 + unsigned long ref_clock; 47 48 }; 48 49 49 50 #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) ··· 287 286 static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, 288 287 unsigned long parent_rate) 289 288 { 290 - return 500000000; 289 + struct clk_pllv3 *pll = to_clk_pllv3(hw); 290 + 291 + return pll->ref_clock; 291 292 } 292 293 293 294 static const struct clk_ops clk_pllv3_enet_ops = { ··· 329 326 break; 330 327 case IMX_PLLV3_ENET_IMX7: 331 328 pll->powerdown = IMX7_ENET_PLL_POWER; 329 + pll->ref_clock = 1000000000; 330 + ops = &clk_pllv3_enet_ops; 331 + break; 332 332 case IMX_PLLV3_ENET: 333 + pll->ref_clock = 500000000; 333 334 ops = &clk_pllv3_enet_ops; 334 335 break; 335 336 default:
+58 -2
drivers/clk/imx/clk-vf610.c
··· 10 10 11 11 #include <linux/of_address.h> 12 12 #include <linux/clk.h> 13 + #include <linux/syscore_ops.h> 13 14 #include <dt-bindings/clock/vf610-clock.h> 14 15 15 16 #include "clk.h" ··· 41 40 #define CCM_CCGR9 (ccm_base + 0x64) 42 41 #define CCM_CCGR10 (ccm_base + 0x68) 43 42 #define CCM_CCGR11 (ccm_base + 0x6c) 43 + #define CCM_CCGRx(x) (CCM_CCGR0 + (x) * 4) 44 44 #define CCM_CMEOR0 (ccm_base + 0x70) 45 45 #define CCM_CMEOR1 (ccm_base + 0x74) 46 46 #define CCM_CMEOR2 (ccm_base + 0x78) ··· 117 115 static struct clk *clk[VF610_CLK_END]; 118 116 static struct clk_onecell_data clk_data; 119 117 118 + static u32 cscmr1; 119 + static u32 cscmr2; 120 + static u32 cscdr1; 121 + static u32 cscdr2; 122 + static u32 cscdr3; 123 + static u32 ccgr[12]; 124 + 120 125 static unsigned int const clks_init_on[] __initconst = { 121 126 VF610_CLK_SYS_BUS, 122 127 VF610_CLK_DDR_SEL, 123 128 VF610_CLK_DAP, 129 + VF610_CLK_DDRMC, 130 + VF610_CLK_WKPU, 124 131 }; 125 132 126 133 static struct clk * __init vf610_get_fixed_clock( ··· 141 130 if (IS_ERR(clk)) 142 131 clk = imx_obtain_fixed_clock(name, 0); 143 132 return clk; 133 + }; 134 + 135 + static int vf610_clk_suspend(void) 136 + { 137 + int i; 138 + 139 + cscmr1 = readl_relaxed(CCM_CSCMR1); 140 + cscmr2 = readl_relaxed(CCM_CSCMR2); 141 + 142 + cscdr1 = readl_relaxed(CCM_CSCDR1); 143 + cscdr2 = readl_relaxed(CCM_CSCDR2); 144 + cscdr3 = readl_relaxed(CCM_CSCDR3); 145 + 146 + for (i = 0; i < 12; i++) 147 + ccgr[i] = readl_relaxed(CCM_CCGRx(i)); 148 + 149 + return 0; 150 + } 151 + 152 + static void vf610_clk_resume(void) 153 + { 154 + int i; 155 + 156 + writel_relaxed(cscmr1, CCM_CSCMR1); 157 + writel_relaxed(cscmr2, CCM_CSCMR2); 158 + 159 + writel_relaxed(cscdr1, CCM_CSCDR1); 160 + writel_relaxed(cscdr2, CCM_CSCDR2); 161 + writel_relaxed(cscdr3, CCM_CSCDR3); 162 + 163 + for (i = 0; i < 12; i++) 164 + writel_relaxed(ccgr[i], CCM_CCGRx(i)); 165 + } 166 + 167 + static struct syscore_ops vf610_clk_syscore_ops = { 168 + .suspend = vf610_clk_suspend, 169 + .resume = vf610_clk_resume, 144 170 }; 145 171 146 172 static void __init vf610_clocks_init(struct device_node *ccm_node) ··· 281 233 clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock); 282 234 clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1); 283 235 236 + clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2); 237 + clk[VF610_CLK_WKPU] = imx_clk_gate2_cgr("wkpu", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(10), 0x2); 238 + 284 239 clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6); 285 240 clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6); 286 241 ··· 372 321 clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2); 373 322 clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19); 374 323 clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3); 375 - clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8)); 324 + clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "ipg_bus", CCM_CCGR3, CCM_CCGRx_CGn(8)); 376 325 clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2); 377 326 clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23); 378 327 clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3); 379 - clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8)); 328 + clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(8)); 329 + 330 + clk[VF610_CLK_TCON0] = imx_clk_gate2("tcon0", "platform_bus", CCM_CCGR1, CCM_CCGRx_CGn(13)); 331 + clk[VF610_CLK_TCON1] = imx_clk_gate2("tcon1", "platform_bus", CCM_CCGR7, CCM_CCGRx_CGn(13)); 380 332 381 333 clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4); 382 334 clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30); ··· 462 408 463 409 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 464 410 clk_prepare_enable(clk[clks_init_on[i]]); 411 + 412 + register_syscore_ops(&vf610_clk_syscore_ops); 465 413 466 414 /* Add the clocks to provider list */ 467 415 clk_data.clks = clk;
+10 -3
drivers/clk/imx/clk.h
··· 41 41 42 42 struct clk *clk_register_gate2(struct device *dev, const char *name, 43 43 const char *parent_name, unsigned long flags, 44 - void __iomem *reg, u8 bit_idx, 44 + void __iomem *reg, u8 bit_idx, u8 cgr_val, 45 45 u8 clk_gate_flags, spinlock_t *lock, 46 46 unsigned int *share_count); 47 47 ··· 55 55 void __iomem *reg, u8 shift) 56 56 { 57 57 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 58 - shift, 0, &imx_ccm_lock, NULL); 58 + shift, 0x3, 0, &imx_ccm_lock, NULL); 59 59 } 60 60 61 61 static inline struct clk *imx_clk_gate2_shared(const char *name, ··· 63 63 unsigned int *share_count) 64 64 { 65 65 return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 66 - shift, 0, &imx_ccm_lock, share_count); 66 + shift, 0x3, 0, &imx_ccm_lock, share_count); 67 + } 68 + 69 + static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent, 70 + void __iomem *reg, u8 shift, u8 cgr_val) 71 + { 72 + return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, 73 + shift, cgr_val, 0, &imx_ccm_lock, NULL); 67 74 } 68 75 69 76 struct clk *imx_clk_pfd(const char *name, const char *parent_name,
+10 -1
drivers/clk/ingenic/cgu.c
··· 325 325 div = (div_reg >> clk_info->div.shift) & 326 326 GENMASK(clk_info->div.bits - 1, 0); 327 327 div += 1; 328 + div *= clk_info->div.div; 328 329 329 330 rate /= div; 330 331 } ··· 345 344 /* and impose hardware constraints */ 346 345 div = min_t(unsigned, div, 1 << clk_info->div.bits); 347 346 div = max_t(unsigned, div, 1); 347 + 348 + /* 349 + * If the divider value itself must be divided before being written to 350 + * the divider register, we must ensure we don't have any bits set that 351 + * would be lost as a result of doing so. 352 + */ 353 + div /= clk_info->div.div; 354 + div *= clk_info->div.div; 348 355 349 356 return div; 350 357 } ··· 404 395 /* update the divide */ 405 396 mask = GENMASK(clk_info->div.bits - 1, 0); 406 397 reg &= ~(mask << clk_info->div.shift); 407 - reg |= (div - 1) << clk_info->div.shift; 398 + reg |= ((div / clk_info->div.div) - 1) << clk_info->div.shift; 408 399 409 400 /* clear the stop bit */ 410 401 if (clk_info->div.stop_bit != -1)
+5 -1
drivers/clk/ingenic/cgu.h
··· 76 76 /** 77 77 * struct ingenic_cgu_div_info - information about a divider 78 78 * @reg: offset of the divider control register within the CGU 79 - * @shift: number of bits to shift the divide value by (ie. the index of 79 + * @shift: number of bits to left shift the divide value by (ie. the index of 80 80 * the lowest bit of the divide value within its control register) 81 + * @div: number of bits to divide the divider value by (i.e. if the 82 + * effective divider value is the value written to the register 83 + * multiplied by some constant) 81 84 * @bits: the size of the divide value in bits 82 85 * @ce_bit: the index of the change enable bit within reg, or -1 if there 83 86 * isn't one ··· 90 87 struct ingenic_cgu_div_info { 91 88 unsigned reg; 92 89 u8 shift; 90 + u8 div; 93 91 u8 bits; 94 92 s8 ce_bit; 95 93 s8 busy_bit;
+12 -12
drivers/clk/ingenic/jz4740-cgu.c
··· 90 90 [JZ4740_CLK_PLL_HALF] = { 91 91 "pll half", CGU_CLK_DIV, 92 92 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 93 - .div = { CGU_REG_CPCCR, 21, 1, -1, -1, -1 }, 93 + .div = { CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1 }, 94 94 }, 95 95 96 96 [JZ4740_CLK_CCLK] = { 97 97 "cclk", CGU_CLK_DIV, 98 98 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 99 - .div = { CGU_REG_CPCCR, 0, 4, 22, -1, -1 }, 99 + .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 }, 100 100 }, 101 101 102 102 [JZ4740_CLK_HCLK] = { 103 103 "hclk", CGU_CLK_DIV, 104 104 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 105 - .div = { CGU_REG_CPCCR, 4, 4, 22, -1, -1 }, 105 + .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 }, 106 106 }, 107 107 108 108 [JZ4740_CLK_PCLK] = { 109 109 "pclk", CGU_CLK_DIV, 110 110 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 111 - .div = { CGU_REG_CPCCR, 8, 4, 22, -1, -1 }, 111 + .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 }, 112 112 }, 113 113 114 114 [JZ4740_CLK_MCLK] = { 115 115 "mclk", CGU_CLK_DIV, 116 116 .parents = { JZ4740_CLK_PLL, -1, -1, -1 }, 117 - .div = { CGU_REG_CPCCR, 12, 4, 22, -1, -1 }, 117 + .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, 118 118 }, 119 119 120 120 [JZ4740_CLK_LCD] = { 121 121 "lcd", CGU_CLK_DIV | CGU_CLK_GATE, 122 122 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 123 - .div = { CGU_REG_CPCCR, 16, 5, 22, -1, -1 }, 123 + .div = { CGU_REG_CPCCR, 16, 1, 5, 22, -1, -1 }, 124 124 .gate = { CGU_REG_CLKGR, 10 }, 125 125 }, 126 126 127 127 [JZ4740_CLK_LCD_PCLK] = { 128 128 "lcd_pclk", CGU_CLK_DIV, 129 129 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 130 - .div = { CGU_REG_LPCDR, 0, 11, -1, -1, -1 }, 130 + .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, 131 131 }, 132 132 133 133 [JZ4740_CLK_I2S] = { 134 134 "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 135 135 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 136 136 .mux = { CGU_REG_CPCCR, 31, 1 }, 137 - .div = { CGU_REG_I2SCDR, 0, 8, -1, -1, -1 }, 137 + .div = { CGU_REG_I2SCDR, 0, 1, 8, -1, -1, -1 }, 138 138 .gate = { CGU_REG_CLKGR, 6 }, 139 139 }, 140 140 ··· 142 142 "spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, 143 143 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1, -1 }, 144 144 .mux = { CGU_REG_SSICDR, 31, 1 }, 145 - .div = { CGU_REG_SSICDR, 0, 4, -1, -1, -1 }, 145 + .div = { CGU_REG_SSICDR, 0, 1, 4, -1, -1, -1 }, 146 146 .gate = { CGU_REG_CLKGR, 4 }, 147 147 }, 148 148 149 149 [JZ4740_CLK_MMC] = { 150 150 "mmc", CGU_CLK_DIV | CGU_CLK_GATE, 151 151 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 152 - .div = { CGU_REG_MSCCDR, 0, 5, -1, -1, -1 }, 152 + .div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 }, 153 153 .gate = { CGU_REG_CLKGR, 7 }, 154 154 }, 155 155 156 156 [JZ4740_CLK_UHC] = { 157 157 "uhc", CGU_CLK_DIV | CGU_CLK_GATE, 158 158 .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 }, 159 - .div = { CGU_REG_UHCCDR, 0, 4, -1, -1, -1 }, 159 + .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, 160 160 .gate = { CGU_REG_CLKGR, 14 }, 161 161 }, 162 162 ··· 164 164 "udc", CGU_CLK_MUX | CGU_CLK_DIV, 165 165 .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 }, 166 166 .mux = { CGU_REG_CPCCR, 29, 1 }, 167 - .div = { CGU_REG_CPCCR, 23, 6, -1, -1, -1 }, 167 + .div = { CGU_REG_CPCCR, 23, 1, 6, -1, -1, -1 }, 168 168 .gate = { CGU_REG_SCR, 6 }, 169 169 }, 170 170
+20 -20
drivers/clk/ingenic/jz4780-cgu.c
··· 296 296 [JZ4780_CLK_CPU] = { 297 297 "cpu", CGU_CLK_DIV, 298 298 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 299 - .div = { CGU_REG_CLOCKCONTROL, 0, 4, 22, -1, -1 }, 299 + .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 }, 300 300 }, 301 301 302 302 [JZ4780_CLK_L2CACHE] = { 303 303 "l2cache", CGU_CLK_DIV, 304 304 .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, 305 - .div = { CGU_REG_CLOCKCONTROL, 4, 4, -1, -1, -1 }, 305 + .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 }, 306 306 }, 307 307 308 308 [JZ4780_CLK_AHB0] = { ··· 310 310 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 311 311 JZ4780_CLK_EPLL }, 312 312 .mux = { CGU_REG_CLOCKCONTROL, 26, 2 }, 313 - .div = { CGU_REG_CLOCKCONTROL, 8, 4, 21, -1, -1 }, 313 + .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 }, 314 314 }, 315 315 316 316 [JZ4780_CLK_AHB2PMUX] = { ··· 323 323 [JZ4780_CLK_AHB2] = { 324 324 "ahb2", CGU_CLK_DIV, 325 325 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 326 - .div = { CGU_REG_CLOCKCONTROL, 12, 4, 20, -1, -1 }, 326 + .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 }, 327 327 }, 328 328 329 329 [JZ4780_CLK_PCLK] = { 330 330 "pclk", CGU_CLK_DIV, 331 331 .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, 332 - .div = { CGU_REG_CLOCKCONTROL, 16, 4, 20, -1, -1 }, 332 + .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 }, 333 333 }, 334 334 335 335 [JZ4780_CLK_DDR] = { 336 336 "ddr", CGU_CLK_MUX | CGU_CLK_DIV, 337 337 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, 338 338 .mux = { CGU_REG_DDRCDR, 30, 2 }, 339 - .div = { CGU_REG_DDRCDR, 0, 4, 29, 28, 27 }, 339 + .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, 340 340 }, 341 341 342 342 [JZ4780_CLK_VPU] = { ··· 344 344 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 345 345 JZ4780_CLK_EPLL, -1 }, 346 346 .mux = { CGU_REG_VPUCDR, 30, 2 }, 347 - .div = { CGU_REG_VPUCDR, 0, 4, 29, 28, 27 }, 347 + .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 }, 348 348 .gate = { CGU_REG_CLKGR1, 2 }, 349 349 }, 350 350 ··· 352 352 "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV, 353 353 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 }, 354 354 .mux = { CGU_REG_I2SCDR, 30, 1 }, 355 - .div = { CGU_REG_I2SCDR, 0, 8, 29, 28, 27 }, 355 + .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 }, 356 356 }, 357 357 358 358 [JZ4780_CLK_I2S] = { ··· 366 366 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 367 367 JZ4780_CLK_VPLL, -1 }, 368 368 .mux = { CGU_REG_LP0CDR, 30, 2 }, 369 - .div = { CGU_REG_LP0CDR, 0, 8, 28, 27, 26 }, 369 + .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 }, 370 370 }, 371 371 372 372 [JZ4780_CLK_LCD1PIXCLK] = { ··· 374 374 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 375 375 JZ4780_CLK_VPLL, -1 }, 376 376 .mux = { CGU_REG_LP1CDR, 30, 2 }, 377 - .div = { CGU_REG_LP1CDR, 0, 8, 28, 27, 26 }, 377 + .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 }, 378 378 }, 379 379 380 380 [JZ4780_CLK_MSCMUX] = { ··· 386 386 [JZ4780_CLK_MSC0] = { 387 387 "msc0", CGU_CLK_DIV | CGU_CLK_GATE, 388 388 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 389 - .div = { CGU_REG_MSC0CDR, 0, 8, 29, 28, 27 }, 389 + .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, 390 390 .gate = { CGU_REG_CLKGR0, 3 }, 391 391 }, 392 392 393 393 [JZ4780_CLK_MSC1] = { 394 394 "msc1", CGU_CLK_DIV | CGU_CLK_GATE, 395 395 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 396 - .div = { CGU_REG_MSC1CDR, 0, 8, 29, 28, 27 }, 396 + .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, 397 397 .gate = { CGU_REG_CLKGR0, 11 }, 398 398 }, 399 399 400 400 [JZ4780_CLK_MSC2] = { 401 401 "msc2", CGU_CLK_DIV | CGU_CLK_GATE, 402 402 .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, 403 - .div = { CGU_REG_MSC2CDR, 0, 8, 29, 28, 27 }, 403 + .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 }, 404 404 .gate = { CGU_REG_CLKGR0, 12 }, 405 405 }, 406 406 ··· 409 409 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 410 410 JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY }, 411 411 .mux = { CGU_REG_UHCCDR, 30, 2 }, 412 - .div = { CGU_REG_UHCCDR, 0, 8, 29, 28, 27 }, 412 + .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 }, 413 413 .gate = { CGU_REG_CLKGR0, 24 }, 414 414 }, 415 415 ··· 417 417 "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, 418 418 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 419 419 .mux = { CGU_REG_SSICDR, 30, 1 }, 420 - .div = { CGU_REG_SSICDR, 0, 8, 29, 28, 27 }, 420 + .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, 421 421 }, 422 422 423 423 [JZ4780_CLK_SSI] = { ··· 430 430 "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV, 431 431 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, 432 432 .mux = { CGU_REG_CIMCDR, 31, 1 }, 433 - .div = { CGU_REG_CIMCDR, 0, 8, 30, 29, 28 }, 433 + .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 }, 434 434 }, 435 435 436 436 [JZ4780_CLK_PCMPLL] = { ··· 438 438 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 439 439 JZ4780_CLK_EPLL, JZ4780_CLK_VPLL }, 440 440 .mux = { CGU_REG_PCMCDR, 29, 2 }, 441 - .div = { CGU_REG_PCMCDR, 0, 8, 28, 27, 26 }, 441 + .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 }, 442 442 }, 443 443 444 444 [JZ4780_CLK_PCM] = { ··· 453 453 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 454 454 JZ4780_CLK_EPLL }, 455 455 .mux = { CGU_REG_GPUCDR, 30, 2 }, 456 - .div = { CGU_REG_GPUCDR, 0, 4, 29, 28, 27 }, 456 + .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 }, 457 457 .gate = { CGU_REG_CLKGR1, 4 }, 458 458 }, 459 459 ··· 462 462 .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 463 463 JZ4780_CLK_VPLL, -1 }, 464 464 .mux = { CGU_REG_HDMICDR, 30, 2 }, 465 - .div = { CGU_REG_HDMICDR, 0, 8, 29, 28, 26 }, 465 + .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 }, 466 466 .gate = { CGU_REG_CLKGR1, 9 }, 467 467 }, 468 468 ··· 471 471 .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, 472 472 JZ4780_CLK_EPLL }, 473 473 .mux = { CGU_REG_BCHCDR, 30, 2 }, 474 - .div = { CGU_REG_BCHCDR, 0, 4, 29, 28, 27 }, 474 + .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 }, 475 475 .gate = { CGU_REG_CLKGR0, 1 }, 476 476 }, 477 477
+3 -3
drivers/clk/meson/meson8b-clkc.c
··· 141 141 }; 142 142 143 143 static const struct clk_conf meson8b_xtal_conf __initconst = 144 - FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 145 - CLK_IS_ROOT, PARM(0x00, 4, 7)); 144 + FIXED_RATE_P(MESON8B_REG_CTL0_ADDR, CLKID_XTAL, "xtal", 0, 145 + PARM(0x00, 4, 7)); 146 146 147 147 static const struct clk_conf meson8b_clk_confs[] __initconst = { 148 - FIXED_RATE(CLKID_ZERO, "zero", CLK_IS_ROOT, 0), 148 + FIXED_RATE(CLKID_ZERO, "zero", 0, 0), 149 149 PLL(MESON8B_REG_PLL_FIXED, CLKID_PLL_FIXED, "fixed_pll", 150 150 p_xtal, 0, &pll_confs), 151 151 PLL(MESON8B_REG_PLL_VID, CLKID_PLL_VID, "vid_pll",
+5 -9
drivers/clk/mmp/clk-mmp2.c
··· 99 99 return; 100 100 } 101 101 102 - clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 102 + clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200); 103 103 clk_register_clkdev(clk, "clk32", NULL); 104 104 105 - vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 106 - 26000000); 105 + vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000); 107 106 clk_register_clkdev(vctcxo, "vctcxo", NULL); 108 107 109 - clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 110 - 800000000); 108 + clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 800000000); 111 109 clk_register_clkdev(clk, "pll1", NULL); 112 110 113 - clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, CLK_IS_ROOT, 114 - 480000000); 111 + clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, 0, 480000000); 115 112 clk_register_clkdev(clk, "usb_pll", NULL); 116 113 117 - clk = clk_register_fixed_rate(NULL, "pll2", NULL, CLK_IS_ROOT, 118 - 960000000); 114 + clk = clk_register_fixed_rate(NULL, "pll2", NULL, 0, 960000000); 119 115 clk_register_clkdev(clk, "pll2", NULL); 120 116 121 117 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
+5 -5
drivers/clk/mmp/clk-of-mmp2.c
··· 63 63 }; 64 64 65 65 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 66 - {MMP2_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 67 - {MMP2_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 68 - {MMP2_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 800000000}, 69 - {MMP2_CLK_PLL2, "pll2", NULL, CLK_IS_ROOT, 960000000}, 70 - {MMP2_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 66 + {MMP2_CLK_CLK32, "clk32", NULL, 0, 32768}, 67 + {MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000}, 68 + {MMP2_CLK_PLL1, "pll1", NULL, 0, 800000000}, 69 + {MMP2_CLK_PLL2, "pll2", NULL, 0, 960000000}, 70 + {MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000}, 71 71 }; 72 72 73 73 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+4 -4
drivers/clk/mmp/clk-of-pxa168.c
··· 56 56 }; 57 57 58 58 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 59 - {PXA168_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 60 - {PXA168_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 61 - {PXA168_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 62 - {PXA168_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 59 + {PXA168_CLK_CLK32, "clk32", NULL, 0, 32768}, 60 + {PXA168_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000}, 61 + {PXA168_CLK_PLL1, "pll1", NULL, 0, 624000000}, 62 + {PXA168_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000}, 63 63 }; 64 64 65 65 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+6 -6
drivers/clk/mmp/clk-of-pxa1928.c
··· 34 34 }; 35 35 36 36 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 37 - {0, "clk32", NULL, CLK_IS_ROOT, 32768}, 38 - {0, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 39 - {0, "pll1_624", NULL, CLK_IS_ROOT, 624000000}, 40 - {0, "pll5p", NULL, CLK_IS_ROOT, 832000000}, 41 - {0, "pll5", NULL, CLK_IS_ROOT, 1248000000}, 42 - {0, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 37 + {0, "clk32", NULL, 0, 32768}, 38 + {0, "vctcxo", NULL, 0, 26000000}, 39 + {0, "pll1_624", NULL, 0, 624000000}, 40 + {0, "pll5p", NULL, 0, 832000000}, 41 + {0, "pll5", NULL, 0, 1248000000}, 42 + {0, "usb_pll", NULL, 0, 480000000}, 43 43 }; 44 44 45 45 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+4 -4
drivers/clk/mmp/clk-of-pxa910.c
··· 56 56 }; 57 57 58 58 static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = { 59 - {PXA910_CLK_CLK32, "clk32", NULL, CLK_IS_ROOT, 32768}, 60 - {PXA910_CLK_VCTCXO, "vctcxo", NULL, CLK_IS_ROOT, 26000000}, 61 - {PXA910_CLK_PLL1, "pll1", NULL, CLK_IS_ROOT, 624000000}, 62 - {PXA910_CLK_USB_PLL, "usb_pll", NULL, CLK_IS_ROOT, 480000000}, 59 + {PXA910_CLK_CLK32, "clk32", NULL, 0, 32768}, 60 + {PXA910_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000}, 61 + {PXA910_CLK_PLL1, "pll1", NULL, 0, 624000000}, 62 + {PXA910_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000}, 63 63 }; 64 64 65 65 static struct mmp_param_fixed_factor_clk fixed_factor_clks[] = {
+3 -5
drivers/clk/mmp/clk-pxa168.c
··· 92 92 return; 93 93 } 94 94 95 - clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 95 + clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200); 96 96 clk_register_clkdev(clk, "clk32", NULL); 97 97 98 - clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 99 - 26000000); 98 + clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000); 100 99 clk_register_clkdev(clk, "vctcxo", NULL); 101 100 102 - clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 103 - 624000000); 101 + clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000); 104 102 clk_register_clkdev(clk, "pll1", NULL); 105 103 106 104 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
+3 -5
drivers/clk/mmp/clk-pxa910.c
··· 97 97 return; 98 98 } 99 99 100 - clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); 100 + clk = clk_register_fixed_rate(NULL, "clk32", NULL, 0, 3200); 101 101 clk_register_clkdev(clk, "clk32", NULL); 102 102 103 - clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, 104 - 26000000); 103 + clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, 0, 26000000); 105 104 clk_register_clkdev(clk, "vctcxo", NULL); 106 105 107 - clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, 108 - 624000000); 106 + clk = clk_register_fixed_rate(NULL, "pll1", NULL, 0, 624000000); 109 107 clk_register_clkdev(clk, "pll1", NULL); 110 108 111 109 clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1",
+6
drivers/clk/mvebu/Kconfig
··· 29 29 select MVEBU_CLK_COMMON 30 30 select MVEBU_CLK_CPU 31 31 32 + config ARMADA_AP806_SYSCON 33 + bool 34 + 35 + config ARMADA_CP110_SYSCON 36 + bool 37 + 32 38 config DOVE_CLK 33 39 bool 34 40 select MVEBU_CLK_COMMON
+2
drivers/clk/mvebu/Makefile
··· 7 7 obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o 8 8 obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o 9 9 obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o 10 + obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o 11 + obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o 10 12 obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o 11 13 obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o 12 14 obj-$(CONFIG_ORION_CLK) += orion.o
+168
drivers/clk/mvebu/ap806-system-controller.c
··· 1 + /* 2 + * Marvell Armada AP806 System Controller 3 + * 4 + * Copyright (C) 2016 Marvell 5 + * 6 + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public 9 + * License version 2. This program is licensed "as is" without any 10 + * warranty of any kind, whether express or implied. 11 + */ 12 + 13 + #define pr_fmt(fmt) "ap806-system-controller: " fmt 14 + 15 + #include <linux/clk-provider.h> 16 + #include <linux/mfd/syscon.h> 17 + #include <linux/module.h> 18 + #include <linux/of.h> 19 + #include <linux/of_address.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/regmap.h> 22 + 23 + #define AP806_SAR_REG 0x400 24 + #define AP806_SAR_CLKFREQ_MODE_MASK 0x1f 25 + 26 + #define AP806_CLK_NUM 4 27 + 28 + static struct clk *ap806_clks[AP806_CLK_NUM]; 29 + 30 + static struct clk_onecell_data ap806_clk_data = { 31 + .clks = ap806_clks, 32 + .clk_num = AP806_CLK_NUM, 33 + }; 34 + 35 + static int ap806_syscon_clk_probe(struct platform_device *pdev) 36 + { 37 + unsigned int freq_mode, cpuclk_freq; 38 + const char *name, *fixedclk_name; 39 + struct device_node *np = pdev->dev.of_node; 40 + struct regmap *regmap; 41 + u32 reg; 42 + int ret; 43 + 44 + regmap = syscon_node_to_regmap(np); 45 + if (IS_ERR(regmap)) { 46 + dev_err(&pdev->dev, "cannot get regmap\n"); 47 + return PTR_ERR(regmap); 48 + } 49 + 50 + ret = regmap_read(regmap, AP806_SAR_REG, &reg); 51 + if (ret) { 52 + dev_err(&pdev->dev, "cannot read from regmap\n"); 53 + return ret; 54 + } 55 + 56 + freq_mode = reg & AP806_SAR_CLKFREQ_MODE_MASK; 57 + switch (freq_mode) { 58 + case 0x0 ... 0x5: 59 + cpuclk_freq = 2000; 60 + break; 61 + case 0x6 ... 0xB: 62 + cpuclk_freq = 1800; 63 + break; 64 + case 0xC ... 0x11: 65 + cpuclk_freq = 1600; 66 + break; 67 + case 0x12 ... 0x16: 68 + cpuclk_freq = 1400; 69 + break; 70 + case 0x17 ... 0x19: 71 + cpuclk_freq = 1300; 72 + break; 73 + default: 74 + dev_err(&pdev->dev, "invalid SAR value\n"); 75 + return -EINVAL; 76 + } 77 + 78 + /* Convert to hertz */ 79 + cpuclk_freq *= 1000 * 1000; 80 + 81 + /* CPU clocks depend on the Sample At Reset configuration */ 82 + of_property_read_string_index(np, "clock-output-names", 83 + 0, &name); 84 + ap806_clks[0] = clk_register_fixed_rate(&pdev->dev, name, NULL, 85 + 0, cpuclk_freq); 86 + if (IS_ERR(ap806_clks[0])) { 87 + ret = PTR_ERR(ap806_clks[0]); 88 + goto fail0; 89 + } 90 + 91 + of_property_read_string_index(np, "clock-output-names", 92 + 1, &name); 93 + ap806_clks[1] = clk_register_fixed_rate(&pdev->dev, name, NULL, 0, 94 + cpuclk_freq); 95 + if (IS_ERR(ap806_clks[1])) { 96 + ret = PTR_ERR(ap806_clks[1]); 97 + goto fail1; 98 + } 99 + 100 + /* Fixed clock is always 1200 Mhz */ 101 + of_property_read_string_index(np, "clock-output-names", 102 + 2, &fixedclk_name); 103 + ap806_clks[2] = clk_register_fixed_rate(&pdev->dev, fixedclk_name, NULL, 104 + 0, 1200 * 1000 * 1000); 105 + if (IS_ERR(ap806_clks[2])) { 106 + ret = PTR_ERR(ap806_clks[2]); 107 + goto fail2; 108 + } 109 + 110 + /* MSS Clock is fixed clock divided by 6 */ 111 + of_property_read_string_index(np, "clock-output-names", 112 + 3, &name); 113 + ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name, 114 + 0, 1, 6); 115 + if (IS_ERR(ap806_clks[3])) { 116 + ret = PTR_ERR(ap806_clks[3]); 117 + goto fail3; 118 + } 119 + 120 + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); 121 + if (ret) 122 + goto fail_clk_add; 123 + 124 + return 0; 125 + 126 + fail_clk_add: 127 + clk_unregister_fixed_factor(ap806_clks[3]); 128 + fail3: 129 + clk_unregister_fixed_rate(ap806_clks[2]); 130 + fail2: 131 + clk_unregister_fixed_rate(ap806_clks[1]); 132 + fail1: 133 + clk_unregister_fixed_rate(ap806_clks[0]); 134 + fail0: 135 + return ret; 136 + } 137 + 138 + static int ap806_syscon_clk_remove(struct platform_device *pdev) 139 + { 140 + of_clk_del_provider(pdev->dev.of_node); 141 + clk_unregister_fixed_factor(ap806_clks[3]); 142 + clk_unregister_fixed_rate(ap806_clks[2]); 143 + clk_unregister_fixed_rate(ap806_clks[1]); 144 + clk_unregister_fixed_rate(ap806_clks[0]); 145 + 146 + return 0; 147 + } 148 + 149 + static const struct of_device_id ap806_syscon_of_match[] = { 150 + { .compatible = "marvell,ap806-system-controller", }, 151 + { } 152 + }; 153 + MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match); 154 + 155 + static struct platform_driver ap806_syscon_driver = { 156 + .probe = ap806_syscon_clk_probe, 157 + .remove = ap806_syscon_clk_remove, 158 + .driver = { 159 + .name = "marvell-ap806-system-controller", 160 + .of_match_table = ap806_syscon_of_match, 161 + }, 162 + }; 163 + 164 + module_platform_driver(ap806_syscon_driver); 165 + 166 + MODULE_DESCRIPTION("Marvell AP806 System Controller driver"); 167 + MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 168 + MODULE_LICENSE("GPL");
+406
drivers/clk/mvebu/cp110-system-controller.c
··· 1 + /* 2 + * Marvell Armada CP110 System Controller 3 + * 4 + * Copyright (C) 2016 Marvell 5 + * 6 + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public 9 + * License version 2. This program is licensed "as is" without any 10 + * warranty of any kind, whether express or implied. 11 + */ 12 + 13 + /* 14 + * CP110 has 5 core clocks: 15 + * 16 + * - APLL (1 Ghz) 17 + * - PPv2 core (1/3 APLL) 18 + * - EIP (1/2 APLL) 19 + * - Core (1/2 EIP) 20 + * 21 + * - NAND clock, which is either: 22 + * - Equal to the core clock 23 + * - 2/5 APLL 24 + * 25 + * CP110 has 32 gatable clocks, for the various peripherals in the 26 + * IP. They have fairly complicated parent/child relationships. 27 + */ 28 + 29 + #define pr_fmt(fmt) "cp110-system-controller: " fmt 30 + 31 + #include <linux/clk-provider.h> 32 + #include <linux/mfd/syscon.h> 33 + #include <linux/module.h> 34 + #include <linux/of.h> 35 + #include <linux/of_address.h> 36 + #include <linux/platform_device.h> 37 + #include <linux/regmap.h> 38 + #include <linux/slab.h> 39 + 40 + #define CP110_PM_CLOCK_GATING_REG 0x220 41 + #define CP110_NAND_FLASH_CLK_CTRL_REG 0x700 42 + #define NF_CLOCK_SEL_400_MASK BIT(0) 43 + 44 + enum { 45 + CP110_CLK_TYPE_CORE, 46 + CP110_CLK_TYPE_GATABLE, 47 + }; 48 + 49 + #define CP110_MAX_CORE_CLOCKS 5 50 + #define CP110_MAX_GATABLE_CLOCKS 32 51 + 52 + #define CP110_CLK_NUM \ 53 + (CP110_MAX_CORE_CLOCKS + CP110_MAX_GATABLE_CLOCKS) 54 + 55 + #define CP110_CORE_APLL 0 56 + #define CP110_CORE_PPV2 1 57 + #define CP110_CORE_EIP 2 58 + #define CP110_CORE_CORE 3 59 + #define CP110_CORE_NAND 4 60 + 61 + /* A number of gatable clocks need special handling */ 62 + #define CP110_GATE_AUDIO 0 63 + #define CP110_GATE_COMM_UNIT 1 64 + #define CP110_GATE_NAND 2 65 + #define CP110_GATE_PPV2 3 66 + #define CP110_GATE_SDIO 4 67 + #define CP110_GATE_XOR1 7 68 + #define CP110_GATE_XOR0 8 69 + #define CP110_GATE_PCIE_X1_0 11 70 + #define CP110_GATE_PCIE_X1_1 12 71 + #define CP110_GATE_PCIE_X4 13 72 + #define CP110_GATE_PCIE_XOR 14 73 + #define CP110_GATE_SATA 15 74 + #define CP110_GATE_SATA_USB 16 75 + #define CP110_GATE_MAIN 17 76 + #define CP110_GATE_SDMMC 18 77 + #define CP110_GATE_SLOW_IO 21 78 + #define CP110_GATE_USB3H0 22 79 + #define CP110_GATE_USB3H1 23 80 + #define CP110_GATE_USB3DEV 24 81 + #define CP110_GATE_EIP150 25 82 + #define CP110_GATE_EIP197 26 83 + 84 + static struct clk *cp110_clks[CP110_CLK_NUM]; 85 + 86 + static struct clk_onecell_data cp110_clk_data = { 87 + .clks = cp110_clks, 88 + .clk_num = CP110_CLK_NUM, 89 + }; 90 + 91 + struct cp110_gate_clk { 92 + struct clk_hw hw; 93 + struct regmap *regmap; 94 + u8 bit_idx; 95 + }; 96 + 97 + #define to_cp110_gate_clk(clk) container_of(clk, struct cp110_gate_clk, hw) 98 + 99 + static int cp110_gate_enable(struct clk_hw *hw) 100 + { 101 + struct cp110_gate_clk *gate = to_cp110_gate_clk(hw); 102 + 103 + regmap_update_bits(gate->regmap, CP110_PM_CLOCK_GATING_REG, 104 + BIT(gate->bit_idx), BIT(gate->bit_idx)); 105 + 106 + return 0; 107 + } 108 + 109 + static void cp110_gate_disable(struct clk_hw *hw) 110 + { 111 + struct cp110_gate_clk *gate = to_cp110_gate_clk(hw); 112 + 113 + regmap_update_bits(gate->regmap, CP110_PM_CLOCK_GATING_REG, 114 + BIT(gate->bit_idx), 0); 115 + } 116 + 117 + static int cp110_gate_is_enabled(struct clk_hw *hw) 118 + { 119 + struct cp110_gate_clk *gate = to_cp110_gate_clk(hw); 120 + u32 val; 121 + 122 + regmap_read(gate->regmap, CP110_PM_CLOCK_GATING_REG, &val); 123 + 124 + return val & BIT(gate->bit_idx); 125 + } 126 + 127 + static const struct clk_ops cp110_gate_ops = { 128 + .enable = cp110_gate_enable, 129 + .disable = cp110_gate_disable, 130 + .is_enabled = cp110_gate_is_enabled, 131 + }; 132 + 133 + static struct clk *cp110_register_gate(const char *name, 134 + const char *parent_name, 135 + struct regmap *regmap, u8 bit_idx) 136 + { 137 + struct cp110_gate_clk *gate; 138 + struct clk *clk; 139 + struct clk_init_data init; 140 + 141 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 142 + if (!gate) 143 + return ERR_PTR(-ENOMEM); 144 + 145 + init.name = name; 146 + init.ops = &cp110_gate_ops; 147 + init.parent_names = &parent_name; 148 + init.num_parents = 1; 149 + 150 + gate->regmap = regmap; 151 + gate->bit_idx = bit_idx; 152 + gate->hw.init = &init; 153 + 154 + clk = clk_register(NULL, &gate->hw); 155 + if (IS_ERR(clk)) 156 + kfree(gate); 157 + 158 + return clk; 159 + } 160 + 161 + static void cp110_unregister_gate(struct clk *clk) 162 + { 163 + struct clk_hw *hw; 164 + 165 + hw = __clk_get_hw(clk); 166 + if (!hw) 167 + return; 168 + 169 + clk_unregister(clk); 170 + kfree(to_cp110_gate_clk(hw)); 171 + } 172 + 173 + static struct clk *cp110_of_clk_get(struct of_phandle_args *clkspec, void *data) 174 + { 175 + struct clk_onecell_data *clk_data = data; 176 + unsigned int type = clkspec->args[0]; 177 + unsigned int idx = clkspec->args[1]; 178 + 179 + if (type == CP110_CLK_TYPE_CORE) { 180 + if (idx > CP110_MAX_CORE_CLOCKS) 181 + return ERR_PTR(-EINVAL); 182 + return clk_data->clks[idx]; 183 + } else if (type == CP110_CLK_TYPE_GATABLE) { 184 + if (idx > CP110_MAX_GATABLE_CLOCKS) 185 + return ERR_PTR(-EINVAL); 186 + return clk_data->clks[CP110_MAX_CORE_CLOCKS + idx]; 187 + } 188 + 189 + return ERR_PTR(-EINVAL); 190 + } 191 + 192 + static int cp110_syscon_clk_probe(struct platform_device *pdev) 193 + { 194 + struct regmap *regmap; 195 + struct device_node *np = pdev->dev.of_node; 196 + const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name; 197 + struct clk *clk; 198 + u32 nand_clk_ctrl; 199 + int i, ret; 200 + 201 + regmap = syscon_node_to_regmap(np); 202 + if (IS_ERR(regmap)) 203 + return PTR_ERR(regmap); 204 + 205 + ret = regmap_read(regmap, CP110_NAND_FLASH_CLK_CTRL_REG, 206 + &nand_clk_ctrl); 207 + if (ret) 208 + return ret; 209 + 210 + /* Register the APLL which is the root of the clk tree */ 211 + of_property_read_string_index(np, "core-clock-output-names", 212 + CP110_CORE_APLL, &apll_name); 213 + clk = clk_register_fixed_rate(NULL, apll_name, NULL, 0, 214 + 1000 * 1000 * 1000); 215 + if (IS_ERR(clk)) { 216 + ret = PTR_ERR(clk); 217 + goto fail0; 218 + } 219 + 220 + cp110_clks[CP110_CORE_APLL] = clk; 221 + 222 + /* PPv2 is APLL/3 */ 223 + of_property_read_string_index(np, "core-clock-output-names", 224 + CP110_CORE_PPV2, &ppv2_name); 225 + clk = clk_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3); 226 + if (IS_ERR(clk)) { 227 + ret = PTR_ERR(clk); 228 + goto fail1; 229 + } 230 + 231 + cp110_clks[CP110_CORE_PPV2] = clk; 232 + 233 + /* EIP clock is APLL/2 */ 234 + of_property_read_string_index(np, "core-clock-output-names", 235 + CP110_CORE_EIP, &eip_name); 236 + clk = clk_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2); 237 + if (IS_ERR(clk)) { 238 + ret = PTR_ERR(clk); 239 + goto fail2; 240 + } 241 + 242 + cp110_clks[CP110_CORE_EIP] = clk; 243 + 244 + /* Core clock is EIP/2 */ 245 + of_property_read_string_index(np, "core-clock-output-names", 246 + CP110_CORE_CORE, &core_name); 247 + clk = clk_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2); 248 + if (IS_ERR(clk)) { 249 + ret = PTR_ERR(clk); 250 + goto fail3; 251 + } 252 + 253 + cp110_clks[CP110_CORE_CORE] = clk; 254 + 255 + /* NAND can be either APLL/2.5 or core clock */ 256 + of_property_read_string_index(np, "core-clock-output-names", 257 + CP110_CORE_NAND, &nand_name); 258 + if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK) 259 + clk = clk_register_fixed_factor(NULL, nand_name, 260 + apll_name, 0, 2, 5); 261 + else 262 + clk = clk_register_fixed_factor(NULL, nand_name, 263 + core_name, 0, 1, 1); 264 + if (IS_ERR(clk)) { 265 + ret = PTR_ERR(clk); 266 + goto fail4; 267 + } 268 + 269 + cp110_clks[CP110_CORE_NAND] = clk; 270 + 271 + for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) { 272 + const char *parent, *name; 273 + int ret; 274 + 275 + ret = of_property_read_string_index(np, 276 + "gate-clock-output-names", 277 + i, &name); 278 + /* Reached the end of the list? */ 279 + if (ret < 0) 280 + break; 281 + 282 + if (!strcmp(name, "none")) 283 + continue; 284 + 285 + switch (i) { 286 + case CP110_GATE_AUDIO: 287 + case CP110_GATE_COMM_UNIT: 288 + case CP110_GATE_EIP150: 289 + case CP110_GATE_EIP197: 290 + case CP110_GATE_SLOW_IO: 291 + of_property_read_string_index(np, 292 + "gate-clock-output-names", 293 + CP110_GATE_MAIN, &parent); 294 + break; 295 + case CP110_GATE_NAND: 296 + parent = nand_name; 297 + break; 298 + case CP110_GATE_PPV2: 299 + parent = ppv2_name; 300 + break; 301 + case CP110_GATE_SDIO: 302 + of_property_read_string_index(np, 303 + "gate-clock-output-names", 304 + CP110_GATE_SDMMC, &parent); 305 + break; 306 + case CP110_GATE_XOR1: 307 + case CP110_GATE_XOR0: 308 + case CP110_GATE_PCIE_X1_0: 309 + case CP110_GATE_PCIE_X1_1: 310 + case CP110_GATE_PCIE_X4: 311 + of_property_read_string_index(np, 312 + "gate-clock-output-names", 313 + CP110_GATE_PCIE_XOR, &parent); 314 + break; 315 + case CP110_GATE_SATA: 316 + case CP110_GATE_USB3H0: 317 + case CP110_GATE_USB3H1: 318 + case CP110_GATE_USB3DEV: 319 + of_property_read_string_index(np, 320 + "gate-clock-output-names", 321 + CP110_GATE_SATA_USB, &parent); 322 + break; 323 + default: 324 + parent = core_name; 325 + break; 326 + } 327 + 328 + clk = cp110_register_gate(name, parent, regmap, i); 329 + if (IS_ERR(clk)) { 330 + ret = PTR_ERR(clk); 331 + goto fail_gate; 332 + } 333 + 334 + cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk; 335 + } 336 + 337 + ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data); 338 + if (ret) 339 + goto fail_clk_add; 340 + 341 + return 0; 342 + 343 + fail_clk_add: 344 + fail_gate: 345 + for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) { 346 + clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i]; 347 + 348 + if (clk) 349 + cp110_unregister_gate(clk); 350 + } 351 + 352 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]); 353 + fail4: 354 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]); 355 + fail3: 356 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]); 357 + fail2: 358 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]); 359 + fail1: 360 + clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]); 361 + fail0: 362 + return ret; 363 + } 364 + 365 + static int cp110_syscon_clk_remove(struct platform_device *pdev) 366 + { 367 + int i; 368 + 369 + of_clk_del_provider(pdev->dev.of_node); 370 + 371 + for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) { 372 + struct clk *clk = cp110_clks[CP110_MAX_CORE_CLOCKS + i]; 373 + 374 + if (clk) 375 + cp110_unregister_gate(clk); 376 + } 377 + 378 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_NAND]); 379 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_CORE]); 380 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_EIP]); 381 + clk_unregister_fixed_factor(cp110_clks[CP110_CORE_PPV2]); 382 + clk_unregister_fixed_rate(cp110_clks[CP110_CORE_APLL]); 383 + 384 + return 0; 385 + } 386 + 387 + static const struct of_device_id cp110_syscon_of_match[] = { 388 + { .compatible = "marvell,cp110-system-controller0", }, 389 + { } 390 + }; 391 + MODULE_DEVICE_TABLE(of, armada8k_pcie_of_match); 392 + 393 + static struct platform_driver cp110_syscon_driver = { 394 + .probe = cp110_syscon_clk_probe, 395 + .remove = cp110_syscon_clk_remove, 396 + .driver = { 397 + .name = "marvell-cp110-system-controller0", 398 + .of_match_table = cp110_syscon_of_match, 399 + }, 400 + }; 401 + 402 + module_platform_driver(cp110_syscon_driver); 403 + 404 + MODULE_DESCRIPTION("Marvell CP110 System Controller 0 driver"); 405 + MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@free-electrons.com>"); 406 + MODULE_LICENSE("GPL");
+1
drivers/clk/nxp/clk-lpc18xx-creg.c
··· 147 147 init.name = creg_clk->name; 148 148 init.parent_names = parent_name; 149 149 init.num_parents = 1; 150 + init.flags = 0; 150 151 151 152 creg_clk->reg = syscon; 152 153 creg_clk->hw.init = &init;
+2
drivers/clk/qcom/gcc-msm8916.c
··· 2346 2346 "pcnoc_bfdcd_clk_src", 2347 2347 }, 2348 2348 .num_parents = 1, 2349 + .flags = CLK_SET_RATE_PARENT, 2349 2350 .ops = &clk_branch2_ops, 2350 2351 }, 2351 2352 }, ··· 2382 2381 "crypto_clk_src", 2383 2382 }, 2384 2383 .num_parents = 1, 2384 + .flags = CLK_SET_RATE_PARENT, 2385 2385 .ops = &clk_branch2_ops, 2386 2386 }, 2387 2387 },
-32
drivers/clk/qcom/mmcc-msm8996.c
··· 1279 1279 }, 1280 1280 }; 1281 1281 1282 - static struct clk_branch mmss_mmagic_axi_clk = { 1283 - .halt_reg = 0x506c, 1284 - .clkr = { 1285 - .enable_reg = 0x506c, 1286 - .enable_mask = BIT(0), 1287 - .hw.init = &(struct clk_init_data){ 1288 - .name = "mmss_mmagic_axi_clk", 1289 - .parent_names = (const char *[]){ "axi_clk_src" }, 1290 - .num_parents = 1, 1291 - .flags = CLK_SET_RATE_PARENT, 1292 - .ops = &clk_branch2_ops, 1293 - }, 1294 - }, 1295 - }; 1296 - 1297 1282 static struct clk_branch mmss_mmagic_maxi_clk = { 1298 1283 .halt_reg = 0x5074, 1299 1284 .clkr = { ··· 1556 1571 .enable_mask = BIT(0), 1557 1572 .hw.init = &(struct clk_init_data){ 1558 1573 .name = "smmu_video_axi_clk", 1559 - .parent_names = (const char *[]){ "axi_clk_src" }, 1560 - .num_parents = 1, 1561 - .flags = CLK_SET_RATE_PARENT, 1562 - .ops = &clk_branch2_ops, 1563 - }, 1564 - }, 1565 - }; 1566 - 1567 - static struct clk_branch mmagic_bimc_axi_clk = { 1568 - .halt_reg = 0x5294, 1569 - .clkr = { 1570 - .enable_reg = 0x5294, 1571 - .enable_mask = BIT(0), 1572 - .hw.init = &(struct clk_init_data){ 1573 - .name = "mmagic_bimc_axi_clk", 1574 1574 .parent_names = (const char *[]){ "axi_clk_src" }, 1575 1575 .num_parents = 1, 1576 1576 .flags = CLK_SET_RATE_PARENT, ··· 3091 3121 [MMSS_MMAGIC_CFG_AHB_CLK] = &mmss_mmagic_cfg_ahb_clk.clkr, 3092 3122 [MMSS_MISC_AHB_CLK] = &mmss_misc_ahb_clk.clkr, 3093 3123 [MMSS_MISC_CXO_CLK] = &mmss_misc_cxo_clk.clkr, 3094 - [MMSS_MMAGIC_AXI_CLK] = &mmss_mmagic_axi_clk.clkr, 3095 3124 [MMSS_MMAGIC_MAXI_CLK] = &mmss_mmagic_maxi_clk.clkr, 3096 3125 [MMAGIC_CAMSS_AXI_CLK] = &mmagic_camss_axi_clk.clkr, 3097 3126 [MMAGIC_CAMSS_NOC_CFG_AHB_CLK] = &mmagic_camss_noc_cfg_ahb_clk.clkr, ··· 3110 3141 [MMAGIC_VIDEO_NOC_CFG_AHB_CLK] = &mmagic_video_noc_cfg_ahb_clk.clkr, 3111 3142 [SMMU_VIDEO_AHB_CLK] = &smmu_video_ahb_clk.clkr, 3112 3143 [SMMU_VIDEO_AXI_CLK] = &smmu_video_axi_clk.clkr, 3113 - [MMAGIC_BIMC_AXI_CLK] = &mmagic_bimc_axi_clk.clkr, 3114 3144 [MMAGIC_BIMC_NOC_CFG_AHB_CLK] = &mmagic_bimc_noc_cfg_ahb_clk.clkr, 3115 3145 [GPU_GX_GFX3D_CLK] = &gpu_gx_gfx3d_clk.clkr, 3116 3146 [GPU_GX_RBBMTIMER_CLK] = &gpu_gx_rbbmtimer_clk.clkr,
+1 -2
drivers/clk/renesas/clk-mstp.c
··· 316 316 return; 317 317 318 318 pd->name = np->name; 319 - 320 319 pd->flags = GENPD_FLAG_PM_CLK; 321 - pm_genpd_init(pd, &simple_qos_governor, false); 322 320 pd->attach_dev = cpg_mstp_attach_dev; 323 321 pd->detach_dev = cpg_mstp_detach_dev; 322 + pm_genpd_init(pd, &pm_domain_always_on_gov, false); 324 323 325 324 of_genpd_add_provider_simple(np, pd); 326 325 }
+13
drivers/clk/renesas/r8a7795-cpg-mssr.c
··· 120 120 DEF_DIV6P1("mso", R8A7795_CLK_MSO, CLK_PLL1_DIV4, 0x014), 121 121 DEF_DIV6P1("hdmi", R8A7795_CLK_HDMI, CLK_PLL1_DIV2, 0x250), 122 122 DEF_DIV6P1("canfd", R8A7795_CLK_CANFD, CLK_PLL1_DIV4, 0x244), 123 + DEF_DIV6P1("csi0", R8A7795_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), 123 124 124 125 DEF_DIV6_RO("osc", R8A7795_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), 125 126 DEF_DIV6_RO("r_int", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), ··· 191 190 DEF_MOD("ehci1", 702, R8A7795_CLK_S3D4), 192 191 DEF_MOD("ehci0", 703, R8A7795_CLK_S3D4), 193 192 DEF_MOD("hsusb", 704, R8A7795_CLK_S3D4), 193 + DEF_MOD("csi21", 713, R8A7795_CLK_CSI0), 194 + DEF_MOD("csi20", 714, R8A7795_CLK_CSI0), 195 + DEF_MOD("csi41", 715, R8A7795_CLK_CSI0), 196 + DEF_MOD("csi40", 716, R8A7795_CLK_CSI0), 194 197 DEF_MOD("du3", 721, R8A7795_CLK_S2D1), 195 198 DEF_MOD("du2", 722, R8A7795_CLK_S2D1), 196 199 DEF_MOD("du1", 723, R8A7795_CLK_S2D1), ··· 202 197 DEF_MOD("lvds", 727, R8A7795_CLK_S2D1), 203 198 DEF_MOD("hdmi1", 728, R8A7795_CLK_HDMI), 204 199 DEF_MOD("hdmi0", 729, R8A7795_CLK_HDMI), 200 + DEF_MOD("vin7", 804, R8A7795_CLK_S2D1), 201 + DEF_MOD("vin6", 805, R8A7795_CLK_S2D1), 202 + DEF_MOD("vin5", 806, R8A7795_CLK_S2D1), 203 + DEF_MOD("vin4", 807, R8A7795_CLK_S2D1), 204 + DEF_MOD("vin3", 808, R8A7795_CLK_S2D1), 205 + DEF_MOD("vin2", 809, R8A7795_CLK_S2D1), 206 + DEF_MOD("vin1", 810, R8A7795_CLK_S2D1), 207 + DEF_MOD("vin0", 811, R8A7795_CLK_S2D1), 205 208 DEF_MOD("etheravb", 812, R8A7795_CLK_S3D2), 206 209 DEF_MOD("sata0", 815, R8A7795_CLK_S3D2), 207 210 DEF_MOD("gpio7", 905, R8A7795_CLK_CP),
+1 -1
drivers/clk/renesas/renesas-cpg-mssr.c
··· 493 493 genpd = &pd->genpd; 494 494 genpd->name = np->name; 495 495 genpd->flags = GENPD_FLAG_PM_CLK; 496 - pm_genpd_init(genpd, &simple_qos_governor, false); 497 496 genpd->attach_dev = cpg_mssr_attach_dev; 498 497 genpd->detach_dev = cpg_mssr_detach_dev; 498 + pm_genpd_init(genpd, &pm_domain_always_on_gov, false); 499 499 cpg_mssr_clk_domain = pd; 500 500 501 501 of_genpd_add_provider_simple(np, genpd);
+1
drivers/clk/rockchip/Makefile
··· 15 15 obj-y += clk-rk3228.o 16 16 obj-y += clk-rk3288.o 17 17 obj-y += clk-rk3368.o 18 + obj-y += clk-rk3399.o
+18 -11
drivers/clk/rockchip/clk-cpu.c
··· 158 158 159 159 writel(HIWORD_UPDATE(alt_div, reg_data->div_core_mask, 160 160 reg_data->div_core_shift) | 161 - HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 161 + HIWORD_UPDATE(reg_data->mux_core_alt, 162 + reg_data->mux_core_mask, 163 + reg_data->mux_core_shift), 162 164 cpuclk->reg_base + reg_data->core_reg); 163 165 } else { 164 166 /* select alternate parent */ 165 - writel(HIWORD_UPDATE(1, 1, reg_data->mux_core_shift), 166 - cpuclk->reg_base + reg_data->core_reg); 167 + writel(HIWORD_UPDATE(reg_data->mux_core_alt, 168 + reg_data->mux_core_mask, 169 + reg_data->mux_core_shift), 170 + cpuclk->reg_base + reg_data->core_reg); 167 171 } 168 172 169 173 spin_unlock_irqrestore(cpuclk->lock, flags); ··· 202 198 203 199 writel(HIWORD_UPDATE(0, reg_data->div_core_mask, 204 200 reg_data->div_core_shift) | 205 - HIWORD_UPDATE(0, 1, reg_data->mux_core_shift), 201 + HIWORD_UPDATE(reg_data->mux_core_main, 202 + reg_data->mux_core_mask, 203 + reg_data->mux_core_shift), 206 204 cpuclk->reg_base + reg_data->core_reg); 207 205 208 206 if (ndata->old_rate > ndata->new_rate) ··· 258 252 return ERR_PTR(-ENOMEM); 259 253 260 254 init.name = name; 261 - init.parent_names = &parent_names[0]; 255 + init.parent_names = &parent_names[reg_data->mux_core_main]; 262 256 init.num_parents = 1; 263 257 init.ops = &rockchip_cpuclk_ops; 264 258 ··· 276 270 cpuclk->clk_nb.notifier_call = rockchip_cpuclk_notifier_cb; 277 271 cpuclk->hw.init = &init; 278 272 279 - cpuclk->alt_parent = __clk_lookup(parent_names[1]); 273 + cpuclk->alt_parent = __clk_lookup(parent_names[reg_data->mux_core_alt]); 280 274 if (!cpuclk->alt_parent) { 281 - pr_err("%s: could not lookup alternate parent\n", 282 - __func__); 275 + pr_err("%s: could not lookup alternate parent: (%d)\n", 276 + __func__, reg_data->mux_core_alt); 283 277 ret = -EINVAL; 284 278 goto free_cpuclk; 285 279 } ··· 291 285 goto free_cpuclk; 292 286 } 293 287 294 - clk = __clk_lookup(parent_names[0]); 288 + clk = __clk_lookup(parent_names[reg_data->mux_core_main]); 295 289 if (!clk) { 296 - pr_err("%s: could not lookup parent clock %s\n", 297 - __func__, parent_names[0]); 290 + pr_err("%s: could not lookup parent clock: (%d) %s\n", 291 + __func__, reg_data->mux_core_main, 292 + parent_names[reg_data->mux_core_main]); 298 293 ret = -EINVAL; 299 294 goto free_alt_parent; 300 295 }
+2 -1
drivers/clk/rockchip/clk-mmc-phase.c
··· 123 123 raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 124 124 raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 125 125 raw_value |= nineties; 126 - writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), mmc_clock->reg); 126 + writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), 127 + mmc_clock->reg); 127 128 128 129 pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", 129 130 clk_hw_get_name(hw), degrees, delay_num,
+291 -45
drivers/clk/rockchip/clk-pll.c
··· 46 46 const struct rockchip_pll_rate_table *rate_table; 47 47 unsigned int rate_count; 48 48 spinlock_t *lock; 49 + 50 + struct rockchip_clk_provider *ctx; 49 51 }; 50 52 51 53 #define to_rockchip_clk_pll(_hw) container_of(_hw, struct rockchip_clk_pll, hw) ··· 92 90 */ 93 91 static int rockchip_pll_wait_lock(struct rockchip_clk_pll *pll) 94 92 { 95 - struct regmap *grf = rockchip_clk_get_grf(); 93 + struct regmap *grf = pll->ctx->grf; 96 94 unsigned int val; 97 95 int delay = 24000000, ret; 98 - 99 - if (IS_ERR(grf)) { 100 - pr_err("%s: grf regmap not available\n", __func__); 101 - return PTR_ERR(grf); 102 - } 103 96 104 97 while (delay > 0) { 105 98 ret = regmap_read(grf, pll->lock_offset, &val); ··· 231 234 /* wait for the pll to lock */ 232 235 ret = rockchip_pll_wait_lock(pll); 233 236 if (ret) { 234 - pr_warn("%s: pll update unsucessful, trying to restore old params\n", 237 + pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 235 238 __func__); 236 239 rockchip_rk3036_pll_set_params(pll, &cur); 237 240 } ··· 247 250 { 248 251 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 249 252 const struct rockchip_pll_rate_table *rate; 250 - unsigned long old_rate = rockchip_rk3036_pll_recalc_rate(hw, prate); 251 - struct regmap *grf = rockchip_clk_get_grf(); 252 253 253 - if (IS_ERR(grf)) { 254 - pr_debug("%s: grf regmap not available, aborting rate change\n", 255 - __func__); 256 - return PTR_ERR(grf); 257 - } 258 - 259 - pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", 260 - __func__, __clk_get_name(hw->clk), old_rate, drate, prate); 254 + pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 255 + __func__, __clk_get_name(hw->clk), drate, prate); 261 256 262 257 /* Get required rate settings from table */ 263 258 rate = rockchip_get_pll_settings(pll, drate); ··· 462 473 /* wait for the pll to lock */ 463 474 ret = rockchip_pll_wait_lock(pll); 464 475 if (ret) { 465 - pr_warn("%s: pll update unsucessful, trying to restore old params\n", 476 + pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 466 477 __func__); 467 478 rockchip_rk3066_pll_set_params(pll, &cur); 468 479 } ··· 478 489 { 479 490 struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 480 491 const struct rockchip_pll_rate_table *rate; 481 - unsigned long old_rate = rockchip_rk3066_pll_recalc_rate(hw, prate); 482 - struct regmap *grf = rockchip_clk_get_grf(); 483 492 484 - if (IS_ERR(grf)) { 485 - pr_debug("%s: grf regmap not available, aborting rate change\n", 486 - __func__); 487 - return PTR_ERR(grf); 488 - } 489 - 490 - pr_debug("%s: changing %s from %lu to %lu with a parent rate of %lu\n", 491 - __func__, clk_hw_get_name(hw), old_rate, drate, prate); 493 + pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 494 + __func__, clk_hw_get_name(hw), drate, prate); 492 495 493 496 /* Get required rate settings from table */ 494 497 rate = rockchip_get_pll_settings(pll, drate); ··· 544 563 rate->no, cur.no, rate->nf, cur.nf, rate->nb, cur.nb); 545 564 if (rate->nr != cur.nr || rate->no != cur.no || rate->nf != cur.nf 546 565 || rate->nb != cur.nb) { 547 - struct regmap *grf = rockchip_clk_get_grf(); 548 - 549 - if (IS_ERR(grf)) 550 - return; 551 - 552 566 pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 553 567 __func__, clk_hw_get_name(hw)); 554 568 rockchip_rk3066_pll_set_params(pll, rate); ··· 567 591 .init = rockchip_rk3066_pll_init, 568 592 }; 569 593 594 + /** 595 + * PLL used in RK3399 596 + */ 597 + 598 + #define RK3399_PLLCON(i) (i * 0x4) 599 + #define RK3399_PLLCON0_FBDIV_MASK 0xfff 600 + #define RK3399_PLLCON0_FBDIV_SHIFT 0 601 + #define RK3399_PLLCON1_REFDIV_MASK 0x3f 602 + #define RK3399_PLLCON1_REFDIV_SHIFT 0 603 + #define RK3399_PLLCON1_POSTDIV1_MASK 0x7 604 + #define RK3399_PLLCON1_POSTDIV1_SHIFT 8 605 + #define RK3399_PLLCON1_POSTDIV2_MASK 0x7 606 + #define RK3399_PLLCON1_POSTDIV2_SHIFT 12 607 + #define RK3399_PLLCON2_FRAC_MASK 0xffffff 608 + #define RK3399_PLLCON2_FRAC_SHIFT 0 609 + #define RK3399_PLLCON2_LOCK_STATUS BIT(31) 610 + #define RK3399_PLLCON3_PWRDOWN BIT(0) 611 + #define RK3399_PLLCON3_DSMPD_MASK 0x1 612 + #define RK3399_PLLCON3_DSMPD_SHIFT 3 613 + 614 + static int rockchip_rk3399_pll_wait_lock(struct rockchip_clk_pll *pll) 615 + { 616 + u32 pllcon; 617 + int delay = 24000000; 618 + 619 + /* poll check the lock status in rk3399 xPLLCON2 */ 620 + while (delay > 0) { 621 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 622 + if (pllcon & RK3399_PLLCON2_LOCK_STATUS) 623 + return 0; 624 + 625 + delay--; 626 + } 627 + 628 + pr_err("%s: timeout waiting for pll to lock\n", __func__); 629 + return -ETIMEDOUT; 630 + } 631 + 632 + static void rockchip_rk3399_pll_get_params(struct rockchip_clk_pll *pll, 633 + struct rockchip_pll_rate_table *rate) 634 + { 635 + u32 pllcon; 636 + 637 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(0)); 638 + rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) 639 + & RK3399_PLLCON0_FBDIV_MASK); 640 + 641 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(1)); 642 + rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) 643 + & RK3399_PLLCON1_REFDIV_MASK); 644 + rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) 645 + & RK3399_PLLCON1_POSTDIV1_MASK); 646 + rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) 647 + & RK3399_PLLCON1_POSTDIV2_MASK); 648 + 649 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 650 + rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) 651 + & RK3399_PLLCON2_FRAC_MASK); 652 + 653 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(3)); 654 + rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) 655 + & RK3399_PLLCON3_DSMPD_MASK); 656 + } 657 + 658 + static unsigned long rockchip_rk3399_pll_recalc_rate(struct clk_hw *hw, 659 + unsigned long prate) 660 + { 661 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 662 + struct rockchip_pll_rate_table cur; 663 + u64 rate64 = prate; 664 + 665 + rockchip_rk3399_pll_get_params(pll, &cur); 666 + 667 + rate64 *= cur.fbdiv; 668 + do_div(rate64, cur.refdiv); 669 + 670 + if (cur.dsmpd == 0) { 671 + /* fractional mode */ 672 + u64 frac_rate64 = prate * cur.frac; 673 + 674 + do_div(frac_rate64, cur.refdiv); 675 + rate64 += frac_rate64 >> 24; 676 + } 677 + 678 + do_div(rate64, cur.postdiv1); 679 + do_div(rate64, cur.postdiv2); 680 + 681 + return (unsigned long)rate64; 682 + } 683 + 684 + static int rockchip_rk3399_pll_set_params(struct rockchip_clk_pll *pll, 685 + const struct rockchip_pll_rate_table *rate) 686 + { 687 + const struct clk_ops *pll_mux_ops = pll->pll_mux_ops; 688 + struct clk_mux *pll_mux = &pll->pll_mux; 689 + struct rockchip_pll_rate_table cur; 690 + u32 pllcon; 691 + int rate_change_remuxed = 0; 692 + int cur_parent; 693 + int ret; 694 + 695 + pr_debug("%s: rate settings for %lu fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 696 + __func__, rate->rate, rate->fbdiv, rate->postdiv1, rate->refdiv, 697 + rate->postdiv2, rate->dsmpd, rate->frac); 698 + 699 + rockchip_rk3399_pll_get_params(pll, &cur); 700 + cur.rate = 0; 701 + 702 + cur_parent = pll_mux_ops->get_parent(&pll_mux->hw); 703 + if (cur_parent == PLL_MODE_NORM) { 704 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_SLOW); 705 + rate_change_remuxed = 1; 706 + } 707 + 708 + /* update pll values */ 709 + writel_relaxed(HIWORD_UPDATE(rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, 710 + RK3399_PLLCON0_FBDIV_SHIFT), 711 + pll->reg_base + RK3399_PLLCON(0)); 712 + 713 + writel_relaxed(HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, 714 + RK3399_PLLCON1_REFDIV_SHIFT) | 715 + HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, 716 + RK3399_PLLCON1_POSTDIV1_SHIFT) | 717 + HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, 718 + RK3399_PLLCON1_POSTDIV2_SHIFT), 719 + pll->reg_base + RK3399_PLLCON(1)); 720 + 721 + /* xPLL CON2 is not HIWORD_MASK */ 722 + pllcon = readl_relaxed(pll->reg_base + RK3399_PLLCON(2)); 723 + pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT); 724 + pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT; 725 + writel_relaxed(pllcon, pll->reg_base + RK3399_PLLCON(2)); 726 + 727 + writel_relaxed(HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, 728 + RK3399_PLLCON3_DSMPD_SHIFT), 729 + pll->reg_base + RK3399_PLLCON(3)); 730 + 731 + /* wait for the pll to lock */ 732 + ret = rockchip_rk3399_pll_wait_lock(pll); 733 + if (ret) { 734 + pr_warn("%s: pll update unsuccessful, trying to restore old params\n", 735 + __func__); 736 + rockchip_rk3399_pll_set_params(pll, &cur); 737 + } 738 + 739 + if (rate_change_remuxed) 740 + pll_mux_ops->set_parent(&pll_mux->hw, PLL_MODE_NORM); 741 + 742 + return ret; 743 + } 744 + 745 + static int rockchip_rk3399_pll_set_rate(struct clk_hw *hw, unsigned long drate, 746 + unsigned long prate) 747 + { 748 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 749 + const struct rockchip_pll_rate_table *rate; 750 + 751 + pr_debug("%s: changing %s to %lu with a parent rate of %lu\n", 752 + __func__, __clk_get_name(hw->clk), drate, prate); 753 + 754 + /* Get required rate settings from table */ 755 + rate = rockchip_get_pll_settings(pll, drate); 756 + if (!rate) { 757 + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, 758 + drate, __clk_get_name(hw->clk)); 759 + return -EINVAL; 760 + } 761 + 762 + return rockchip_rk3399_pll_set_params(pll, rate); 763 + } 764 + 765 + static int rockchip_rk3399_pll_enable(struct clk_hw *hw) 766 + { 767 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 768 + 769 + writel(HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0), 770 + pll->reg_base + RK3399_PLLCON(3)); 771 + 772 + return 0; 773 + } 774 + 775 + static void rockchip_rk3399_pll_disable(struct clk_hw *hw) 776 + { 777 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 778 + 779 + writel(HIWORD_UPDATE(RK3399_PLLCON3_PWRDOWN, 780 + RK3399_PLLCON3_PWRDOWN, 0), 781 + pll->reg_base + RK3399_PLLCON(3)); 782 + } 783 + 784 + static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw) 785 + { 786 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 787 + u32 pllcon = readl(pll->reg_base + RK3399_PLLCON(3)); 788 + 789 + return !(pllcon & RK3399_PLLCON3_PWRDOWN); 790 + } 791 + 792 + static void rockchip_rk3399_pll_init(struct clk_hw *hw) 793 + { 794 + struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw); 795 + const struct rockchip_pll_rate_table *rate; 796 + struct rockchip_pll_rate_table cur; 797 + unsigned long drate; 798 + 799 + if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE)) 800 + return; 801 + 802 + drate = clk_hw_get_rate(hw); 803 + rate = rockchip_get_pll_settings(pll, drate); 804 + 805 + /* when no rate setting for the current rate, rely on clk_set_rate */ 806 + if (!rate) 807 + return; 808 + 809 + rockchip_rk3399_pll_get_params(pll, &cur); 810 + 811 + pr_debug("%s: pll %s@%lu: Hz\n", __func__, __clk_get_name(hw->clk), 812 + drate); 813 + pr_debug("old - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 814 + cur.fbdiv, cur.postdiv1, cur.refdiv, cur.postdiv2, 815 + cur.dsmpd, cur.frac); 816 + pr_debug("new - fbdiv: %d, postdiv1: %d, refdiv: %d, postdiv2: %d, dsmpd: %d, frac: %d\n", 817 + rate->fbdiv, rate->postdiv1, rate->refdiv, rate->postdiv2, 818 + rate->dsmpd, rate->frac); 819 + 820 + if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || 821 + rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || 822 + rate->dsmpd != cur.dsmpd || rate->frac != cur.frac) { 823 + struct clk *parent = clk_get_parent(hw->clk); 824 + 825 + if (!parent) { 826 + pr_warn("%s: parent of %s not available\n", 827 + __func__, __clk_get_name(hw->clk)); 828 + return; 829 + } 830 + 831 + pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n", 832 + __func__, __clk_get_name(hw->clk)); 833 + rockchip_rk3399_pll_set_params(pll, rate); 834 + } 835 + } 836 + 837 + static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = { 838 + .recalc_rate = rockchip_rk3399_pll_recalc_rate, 839 + .enable = rockchip_rk3399_pll_enable, 840 + .disable = rockchip_rk3399_pll_disable, 841 + .is_enabled = rockchip_rk3399_pll_is_enabled, 842 + }; 843 + 844 + static const struct clk_ops rockchip_rk3399_pll_clk_ops = { 845 + .recalc_rate = rockchip_rk3399_pll_recalc_rate, 846 + .round_rate = rockchip_pll_round_rate, 847 + .set_rate = rockchip_rk3399_pll_set_rate, 848 + .enable = rockchip_rk3399_pll_enable, 849 + .disable = rockchip_rk3399_pll_disable, 850 + .is_enabled = rockchip_rk3399_pll_is_enabled, 851 + .init = rockchip_rk3399_pll_init, 852 + }; 853 + 570 854 /* 571 855 * Common registering of pll clocks 572 856 */ 573 857 574 - struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 858 + struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 859 + enum rockchip_pll_type pll_type, 575 860 const char *name, const char *const *parent_names, 576 - u8 num_parents, void __iomem *base, int con_offset, 577 - int grf_lock_offset, int lock_shift, int mode_offset, 578 - int mode_shift, struct rockchip_pll_rate_table *rate_table, 579 - u8 clk_pll_flags, spinlock_t *lock) 861 + u8 num_parents, int con_offset, int grf_lock_offset, 862 + int lock_shift, int mode_offset, int mode_shift, 863 + struct rockchip_pll_rate_table *rate_table, 864 + u8 clk_pll_flags) 580 865 { 581 866 const char *pll_parents[3]; 582 867 struct clk_init_data init; ··· 861 624 /* create the mux on top of the real pll */ 862 625 pll->pll_mux_ops = &clk_mux_ops; 863 626 pll_mux = &pll->pll_mux; 864 - pll_mux->reg = base + mode_offset; 627 + pll_mux->reg = ctx->reg_base + mode_offset; 865 628 pll_mux->shift = mode_shift; 866 629 pll_mux->mask = PLL_MODE_MASK; 867 630 pll_mux->flags = 0; 868 - pll_mux->lock = lock; 631 + pll_mux->lock = &ctx->lock; 869 632 pll_mux->hw.init = &init; 870 633 871 - if (pll_type == pll_rk3036 || pll_type == pll_rk3066) 634 + if (pll_type == pll_rk3036 || 635 + pll_type == pll_rk3066 || 636 + pll_type == pll_rk3399) 872 637 pll_mux->flags |= CLK_MUX_HIWORD_MASK; 873 638 874 639 /* the actual muxing is xin24m, pll-output, xin32k */ ··· 916 677 917 678 switch (pll_type) { 918 679 case pll_rk3036: 919 - if (!pll->rate_table) 680 + if (!pll->rate_table || IS_ERR(ctx->grf)) 920 681 init.ops = &rockchip_rk3036_pll_clk_norate_ops; 921 682 else 922 683 init.ops = &rockchip_rk3036_pll_clk_ops; 923 684 break; 924 685 case pll_rk3066: 925 - if (!pll->rate_table) 686 + if (!pll->rate_table || IS_ERR(ctx->grf)) 926 687 init.ops = &rockchip_rk3066_pll_clk_norate_ops; 927 688 else 928 689 init.ops = &rockchip_rk3066_pll_clk_ops; 690 + break; 691 + case pll_rk3399: 692 + if (!pll->rate_table) 693 + init.ops = &rockchip_rk3399_pll_clk_norate_ops; 694 + else 695 + init.ops = &rockchip_rk3399_pll_clk_ops; 929 696 break; 930 697 default: 931 698 pr_warn("%s: Unknown pll type for pll clk %s\n", ··· 940 695 941 696 pll->hw.init = &init; 942 697 pll->type = pll_type; 943 - pll->reg_base = base + con_offset; 698 + pll->reg_base = ctx->reg_base + con_offset; 944 699 pll->lock_offset = grf_lock_offset; 945 700 pll->lock_shift = lock_shift; 946 701 pll->flags = clk_pll_flags; 947 - pll->lock = lock; 702 + pll->lock = &ctx->lock; 703 + pll->ctx = ctx; 948 704 949 705 pll_clk = clk_register(NULL, &pll->hw); 950 706 if (IS_ERR(pll_clk)) {
+16 -5
drivers/clk/rockchip/clk-rk3036.c
··· 113 113 .core_reg = RK2928_CLKSEL_CON(0), 114 114 .div_core_shift = 0, 115 115 .div_core_mask = 0x1f, 116 + .mux_core_alt = 1, 117 + .mux_core_main = 0, 116 118 .mux_core_shift = 7, 119 + .mux_core_mask = 0x1, 117 120 }; 118 121 119 122 PNAME(mux_pll_p) = { "xin24m", "xin24m" }; ··· 440 437 441 438 static void __init rk3036_clk_init(struct device_node *np) 442 439 { 440 + struct rockchip_clk_provider *ctx; 443 441 void __iomem *reg_base; 444 442 struct clk *clk; 445 443 ··· 450 446 return; 451 447 } 452 448 453 - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 449 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 450 + if (IS_ERR(ctx)) { 451 + pr_err("%s: rockchip clk init failed\n", __func__); 452 + iounmap(reg_base); 453 + return; 454 + } 454 455 455 456 clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1); 456 457 if (IS_ERR(clk)) 457 458 pr_warn("%s: could not register clock usb480m: %ld\n", 458 459 __func__, PTR_ERR(clk)); 459 460 460 - rockchip_clk_register_plls(rk3036_pll_clks, 461 + rockchip_clk_register_plls(ctx, rk3036_pll_clks, 461 462 ARRAY_SIZE(rk3036_pll_clks), 462 463 RK3036_GRF_SOC_STATUS0); 463 - rockchip_clk_register_branches(rk3036_clk_branches, 464 + rockchip_clk_register_branches(ctx, rk3036_clk_branches, 464 465 ARRAY_SIZE(rk3036_clk_branches)); 465 466 rockchip_clk_protect_critical(rk3036_critical_clocks, 466 467 ARRAY_SIZE(rk3036_critical_clocks)); 467 468 468 - rockchip_clk_register_armclk(ARMCLK, "armclk", 469 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 469 470 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 470 471 &rk3036_cpuclk_data, rk3036_cpuclk_rates, 471 472 ARRAY_SIZE(rk3036_cpuclk_rates)); ··· 478 469 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 479 470 ROCKCHIP_SOFTRST_HIWORD_MASK); 480 471 481 - rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 472 + rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); 473 + 474 + rockchip_clk_of_add_provider(np, ctx); 482 475 } 483 476 CLK_OF_DECLARE(rk3036_cru, "rockchip,rk3036-cru", rk3036_clk_init);
+38 -13
drivers/clk/rockchip/clk-rk3188.c
··· 155 155 .core_reg = RK2928_CLKSEL_CON(0), 156 156 .div_core_shift = 0, 157 157 .div_core_mask = 0x1f, 158 + .mux_core_alt = 1, 159 + .mux_core_main = 0, 158 160 .mux_core_shift = 8, 161 + .mux_core_mask = 0x1, 159 162 }; 160 163 161 164 #define RK3188_DIV_ACLK_CORE_MASK 0x7 ··· 194 191 .core_reg = RK2928_CLKSEL_CON(0), 195 192 .div_core_shift = 9, 196 193 .div_core_mask = 0x1f, 194 + .mux_core_alt = 1, 195 + .mux_core_main = 0, 197 196 .mux_core_shift = 8, 197 + .mux_core_mask = 0x1, 198 198 }; 199 199 200 200 PNAME(mux_pll_p) = { "xin24m", "xin32k" }; ··· 759 753 "hclk_cpubus" 760 754 }; 761 755 762 - static void __init rk3188_common_clk_init(struct device_node *np) 756 + static struct rockchip_clk_provider *__init rk3188_common_clk_init(struct device_node *np) 763 757 { 758 + struct rockchip_clk_provider *ctx; 764 759 void __iomem *reg_base; 765 760 766 761 reg_base = of_iomap(np, 0); 767 762 if (!reg_base) { 768 763 pr_err("%s: could not map cru region\n", __func__); 769 - return; 764 + return ERR_PTR(-ENOMEM); 770 765 } 771 766 772 - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 767 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 768 + if (IS_ERR(ctx)) { 769 + pr_err("%s: rockchip clk init failed\n", __func__); 770 + iounmap(reg_base); 771 + return ERR_PTR(-ENOMEM); 772 + } 773 773 774 - rockchip_clk_register_branches(common_clk_branches, 774 + rockchip_clk_register_branches(ctx, common_clk_branches, 775 775 ARRAY_SIZE(common_clk_branches)); 776 776 777 777 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 778 778 ROCKCHIP_SOFTRST_HIWORD_MASK); 779 779 780 - rockchip_register_restart_notifier(RK2928_GLB_SRST_FST, NULL); 780 + rockchip_register_restart_notifier(ctx, RK2928_GLB_SRST_FST, NULL); 781 + 782 + return ctx; 781 783 } 782 784 783 785 static void __init rk3066a_clk_init(struct device_node *np) 784 786 { 785 - rk3188_common_clk_init(np); 786 - rockchip_clk_register_plls(rk3066_pll_clks, 787 + struct rockchip_clk_provider *ctx; 788 + 789 + ctx = rk3188_common_clk_init(np); 790 + if (IS_ERR(ctx)) 791 + return; 792 + 793 + rockchip_clk_register_plls(ctx, rk3066_pll_clks, 787 794 ARRAY_SIZE(rk3066_pll_clks), 788 795 RK3066_GRF_SOC_STATUS); 789 - rockchip_clk_register_branches(rk3066a_clk_branches, 796 + rockchip_clk_register_branches(ctx, rk3066a_clk_branches, 790 797 ARRAY_SIZE(rk3066a_clk_branches)); 791 - rockchip_clk_register_armclk(ARMCLK, "armclk", 798 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 792 799 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 793 800 &rk3066_cpuclk_data, rk3066_cpuclk_rates, 794 801 ARRAY_SIZE(rk3066_cpuclk_rates)); 795 802 rockchip_clk_protect_critical(rk3188_critical_clocks, 796 803 ARRAY_SIZE(rk3188_critical_clocks)); 804 + rockchip_clk_of_add_provider(np, ctx); 797 805 } 798 806 CLK_OF_DECLARE(rk3066a_cru, "rockchip,rk3066a-cru", rk3066a_clk_init); 799 807 800 808 static void __init rk3188a_clk_init(struct device_node *np) 801 809 { 810 + struct rockchip_clk_provider *ctx; 802 811 struct clk *clk1, *clk2; 803 812 unsigned long rate; 804 813 int ret; 805 814 806 - rk3188_common_clk_init(np); 807 - rockchip_clk_register_plls(rk3188_pll_clks, 815 + ctx = rk3188_common_clk_init(np); 816 + if (IS_ERR(ctx)) 817 + return; 818 + 819 + rockchip_clk_register_plls(ctx, rk3188_pll_clks, 808 820 ARRAY_SIZE(rk3188_pll_clks), 809 821 RK3188_GRF_SOC_STATUS); 810 - rockchip_clk_register_branches(rk3188_clk_branches, 822 + rockchip_clk_register_branches(ctx, rk3188_clk_branches, 811 823 ARRAY_SIZE(rk3188_clk_branches)); 812 - rockchip_clk_register_armclk(ARMCLK, "armclk", 824 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 813 825 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 814 826 &rk3188_cpuclk_data, rk3188_cpuclk_rates, 815 827 ARRAY_SIZE(rk3188_cpuclk_rates)); ··· 851 827 852 828 rockchip_clk_protect_critical(rk3188_critical_clocks, 853 829 ARRAY_SIZE(rk3188_critical_clocks)); 830 + rockchip_clk_of_add_provider(np, ctx); 854 831 } 855 832 CLK_OF_DECLARE(rk3188a_cru, "rockchip,rk3188a-cru", rk3188a_clk_init); 856 833
+16 -5
drivers/clk/rockchip/clk-rk3228.c
··· 111 111 .core_reg = RK2928_CLKSEL_CON(0), 112 112 .div_core_shift = 0, 113 113 .div_core_mask = 0x1f, 114 + .mux_core_alt = 1, 115 + .mux_core_main = 0, 114 116 .mux_core_shift = 6, 117 + .mux_core_mask = 0x1, 115 118 }; 116 119 117 120 PNAME(mux_pll_p) = { "clk_24m", "xin24m" }; ··· 628 625 629 626 static void __init rk3228_clk_init(struct device_node *np) 630 627 { 628 + struct rockchip_clk_provider *ctx; 631 629 void __iomem *reg_base; 632 630 633 631 reg_base = of_iomap(np, 0); ··· 637 633 return; 638 634 } 639 635 640 - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 636 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 637 + if (IS_ERR(ctx)) { 638 + pr_err("%s: rockchip clk init failed\n", __func__); 639 + iounmap(reg_base); 640 + return; 641 + } 641 642 642 - rockchip_clk_register_plls(rk3228_pll_clks, 643 + rockchip_clk_register_plls(ctx, rk3228_pll_clks, 643 644 ARRAY_SIZE(rk3228_pll_clks), 644 645 RK3228_GRF_SOC_STATUS0); 645 - rockchip_clk_register_branches(rk3228_clk_branches, 646 + rockchip_clk_register_branches(ctx, rk3228_clk_branches, 646 647 ARRAY_SIZE(rk3228_clk_branches)); 647 648 rockchip_clk_protect_critical(rk3228_critical_clocks, 648 649 ARRAY_SIZE(rk3228_critical_clocks)); 649 650 650 - rockchip_clk_register_armclk(ARMCLK, "armclk", 651 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 651 652 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 652 653 &rk3228_cpuclk_data, rk3228_cpuclk_rates, 653 654 ARRAY_SIZE(rk3228_cpuclk_rates)); ··· 660 651 rockchip_register_softrst(np, 9, reg_base + RK2928_SOFTRST_CON(0), 661 652 ROCKCHIP_SOFTRST_HIWORD_MASK); 662 653 663 - rockchip_register_restart_notifier(RK3228_GLB_SRST_FST, NULL); 654 + rockchip_register_restart_notifier(ctx, RK3228_GLB_SRST_FST, NULL); 655 + 656 + rockchip_clk_of_add_provider(np, ctx); 664 657 } 665 658 CLK_OF_DECLARE(rk3228_cru, "rockchip,rk3228-cru", rk3228_clk_init);
+17 -6
drivers/clk/rockchip/clk-rk3288.c
··· 165 165 .core_reg = RK3288_CLKSEL_CON(0), 166 166 .div_core_shift = 8, 167 167 .div_core_mask = 0x1f, 168 + .mux_core_alt = 1, 169 + .mux_core_main = 0, 168 170 .mux_core_shift = 15, 171 + .mux_core_mask = 0x1, 169 172 }; 170 173 171 174 PNAME(mux_pll_p) = { "xin24m", "xin32k" }; ··· 881 878 882 879 static void __init rk3288_clk_init(struct device_node *np) 883 880 { 881 + struct rockchip_clk_provider *ctx; 884 882 struct clk *clk; 885 883 886 884 rk3288_cru_base = of_iomap(np, 0); ··· 890 886 return; 891 887 } 892 888 893 - rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); 889 + ctx = rockchip_clk_init(np, rk3288_cru_base, CLK_NR_CLKS); 890 + if (IS_ERR(ctx)) { 891 + pr_err("%s: rockchip clk init failed\n", __func__); 892 + iounmap(rk3288_cru_base); 893 + return; 894 + } 894 895 895 896 /* Watchdog pclk is controlled by RK3288_SGRF_SOC_CON0[1]. */ 896 897 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); ··· 903 894 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 904 895 __func__, PTR_ERR(clk)); 905 896 else 906 - rockchip_clk_add_lookup(clk, PCLK_WDT); 897 + rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); 907 898 908 - rockchip_clk_register_plls(rk3288_pll_clks, 899 + rockchip_clk_register_plls(ctx, rk3288_pll_clks, 909 900 ARRAY_SIZE(rk3288_pll_clks), 910 901 RK3288_GRF_SOC_STATUS1); 911 - rockchip_clk_register_branches(rk3288_clk_branches, 902 + rockchip_clk_register_branches(ctx, rk3288_clk_branches, 912 903 ARRAY_SIZE(rk3288_clk_branches)); 913 904 rockchip_clk_protect_critical(rk3288_critical_clocks, 914 905 ARRAY_SIZE(rk3288_critical_clocks)); 915 906 916 - rockchip_clk_register_armclk(ARMCLK, "armclk", 907 + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", 917 908 mux_armclk_p, ARRAY_SIZE(mux_armclk_p), 918 909 &rk3288_cpuclk_data, rk3288_cpuclk_rates, 919 910 ARRAY_SIZE(rk3288_cpuclk_rates)); ··· 922 913 rk3288_cru_base + RK3288_SOFTRST_CON(0), 923 914 ROCKCHIP_SOFTRST_HIWORD_MASK); 924 915 925 - rockchip_register_restart_notifier(RK3288_GLB_SRST_FST, 916 + rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST, 926 917 rk3288_clk_shutdown); 927 918 register_syscore_ops(&rk3288_clk_syscore_ops); 919 + 920 + rockchip_clk_of_add_provider(np, ctx); 928 921 } 929 922 CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init);
+21 -7
drivers/clk/rockchip/clk-rk3368.c
··· 165 165 .core_reg = RK3368_CLKSEL_CON(0), 166 166 .div_core_shift = 0, 167 167 .div_core_mask = 0x1f, 168 + .mux_core_alt = 1, 169 + .mux_core_main = 0, 168 170 .mux_core_shift = 7, 171 + .mux_core_mask = 0x1, 169 172 }; 170 173 171 174 static const struct rockchip_cpuclk_reg_data rk3368_cpuclkl_data = { 172 175 .core_reg = RK3368_CLKSEL_CON(2), 173 176 .div_core_shift = 0, 177 + .mux_core_alt = 1, 178 + .mux_core_main = 0, 174 179 .div_core_mask = 0x1f, 175 180 .mux_core_shift = 7, 181 + .mux_core_mask = 0x1, 176 182 }; 177 183 178 184 #define RK3368_DIV_ACLKM_MASK 0x1f ··· 862 856 863 857 static void __init rk3368_clk_init(struct device_node *np) 864 858 { 859 + struct rockchip_clk_provider *ctx; 865 860 void __iomem *reg_base; 866 861 struct clk *clk; 867 862 ··· 872 865 return; 873 866 } 874 867 875 - rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 868 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 869 + if (IS_ERR(ctx)) { 870 + pr_err("%s: rockchip clk init failed\n", __func__); 871 + iounmap(reg_base); 872 + return; 873 + } 876 874 877 875 /* Watchdog pclk is controlled by sgrf_soc_con3[7]. */ 878 876 clk = clk_register_fixed_factor(NULL, "pclk_wdt", "pclk_pd_alive", 0, 1, 1); ··· 885 873 pr_warn("%s: could not register clock pclk_wdt: %ld\n", 886 874 __func__, PTR_ERR(clk)); 887 875 else 888 - rockchip_clk_add_lookup(clk, PCLK_WDT); 876 + rockchip_clk_add_lookup(ctx, clk, PCLK_WDT); 889 877 890 - rockchip_clk_register_plls(rk3368_pll_clks, 878 + rockchip_clk_register_plls(ctx, rk3368_pll_clks, 891 879 ARRAY_SIZE(rk3368_pll_clks), 892 880 RK3368_GRF_SOC_STATUS0); 893 - rockchip_clk_register_branches(rk3368_clk_branches, 881 + rockchip_clk_register_branches(ctx, rk3368_clk_branches, 894 882 ARRAY_SIZE(rk3368_clk_branches)); 895 883 rockchip_clk_protect_critical(rk3368_critical_clocks, 896 884 ARRAY_SIZE(rk3368_critical_clocks)); 897 885 898 - rockchip_clk_register_armclk(ARMCLKB, "armclkb", 886 + rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb", 899 887 mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), 900 888 &rk3368_cpuclkb_data, rk3368_cpuclkb_rates, 901 889 ARRAY_SIZE(rk3368_cpuclkb_rates)); 902 890 903 - rockchip_clk_register_armclk(ARMCLKL, "armclkl", 891 + rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl", 904 892 mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), 905 893 &rk3368_cpuclkl_data, rk3368_cpuclkl_rates, 906 894 ARRAY_SIZE(rk3368_cpuclkl_rates)); ··· 908 896 rockchip_register_softrst(np, 15, reg_base + RK3368_SOFTRST_CON(0), 909 897 ROCKCHIP_SOFTRST_HIWORD_MASK); 910 898 911 - rockchip_register_restart_notifier(RK3368_GLB_SRST_FST, NULL); 899 + rockchip_register_restart_notifier(ctx, RK3368_GLB_SRST_FST, NULL); 900 + 901 + rockchip_clk_of_add_provider(np, ctx); 912 902 } 913 903 CLK_OF_DECLARE(rk3368_cru, "rockchip,rk3368-cru", rk3368_clk_init);
+1573
drivers/clk/rockchip/clk-rk3399.c
··· 1 + /* 2 + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. 3 + * Author: Xing Zheng <zhengxing@rock-chips.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + * 10 + * This program is distributed in the hope that it will be useful, 11 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 + * GNU General Public License for more details. 14 + */ 15 + 16 + #include <linux/clk-provider.h> 17 + #include <linux/of.h> 18 + #include <linux/of_address.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/regmap.h> 21 + #include <dt-bindings/clock/rk3399-cru.h> 22 + #include "clk.h" 23 + 24 + enum rk3399_plls { 25 + lpll, bpll, dpll, cpll, gpll, npll, vpll, 26 + }; 27 + 28 + enum rk3399_pmu_plls { 29 + ppll, 30 + }; 31 + 32 + static struct rockchip_pll_rate_table rk3399_pll_rates[] = { 33 + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ 34 + RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0), 35 + RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0), 36 + RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0), 37 + RK3036_PLL_RATE(2136000000, 1, 89, 1, 1, 1, 0), 38 + RK3036_PLL_RATE(2112000000, 1, 88, 1, 1, 1, 0), 39 + RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0), 40 + RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0), 41 + RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0), 42 + RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0), 43 + RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0), 44 + RK3036_PLL_RATE(1968000000, 1, 82, 1, 1, 1, 0), 45 + RK3036_PLL_RATE(1944000000, 1, 81, 1, 1, 1, 0), 46 + RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0), 47 + RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), 48 + RK3036_PLL_RATE(1872000000, 1, 78, 1, 1, 1, 0), 49 + RK3036_PLL_RATE(1848000000, 1, 77, 1, 1, 1, 0), 50 + RK3036_PLL_RATE(1824000000, 1, 76, 1, 1, 1, 0), 51 + RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), 52 + RK3036_PLL_RATE(1776000000, 1, 74, 1, 1, 1, 0), 53 + RK3036_PLL_RATE(1752000000, 1, 73, 1, 1, 1, 0), 54 + RK3036_PLL_RATE(1728000000, 1, 72, 1, 1, 1, 0), 55 + RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), 56 + RK3036_PLL_RATE(1680000000, 1, 70, 1, 1, 1, 0), 57 + RK3036_PLL_RATE(1656000000, 1, 69, 1, 1, 1, 0), 58 + RK3036_PLL_RATE(1632000000, 1, 68, 1, 1, 1, 0), 59 + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), 60 + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), 61 + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), 62 + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), 63 + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), 64 + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), 65 + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), 66 + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), 67 + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), 68 + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), 69 + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), 70 + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), 71 + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), 72 + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), 73 + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), 74 + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), 75 + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), 76 + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), 77 + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), 78 + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), 79 + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), 80 + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), 81 + RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0), 82 + RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0), 83 + RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0), 84 + RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0), 85 + RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0), 86 + RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0), 87 + RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0), 88 + RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0), 89 + RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0), 90 + RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0), 91 + RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0), 92 + RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0), 93 + RK3036_PLL_RATE( 676000000, 3, 169, 2, 1, 1, 0), 94 + RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0), 95 + RK3036_PLL_RATE( 594000000, 1, 99, 4, 1, 1, 0), 96 + RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0), 97 + RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0), 98 + RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0), 99 + RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0), 100 + RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0), 101 + RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0), 102 + RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0), 103 + RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0), 104 + RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0), 105 + RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0), 106 + RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0), 107 + { /* sentinel */ }, 108 + }; 109 + 110 + /* CRU parents */ 111 + PNAME(mux_pll_p) = { "xin24m", "xin32k" }; 112 + 113 + PNAME(mux_armclkl_p) = { "clk_core_l_lpll_src", 114 + "clk_core_l_bpll_src", 115 + "clk_core_l_dpll_src", 116 + "clk_core_l_gpll_src" }; 117 + PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src", 118 + "clk_core_b_bpll_src", 119 + "clk_core_b_dpll_src", 120 + "clk_core_b_gpll_src" }; 121 + PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", 122 + "gpll_aclk_cci_src", 123 + "npll_aclk_cci_src", 124 + "vpll_aclk_cci_src" }; 125 + PNAME(mux_cci_trace_p) = { "cpll_cci_trace", 126 + "gpll_cci_trace" }; 127 + PNAME(mux_cs_p) = { "cpll_cs", "gpll_cs", 128 + "npll_cs"}; 129 + PNAME(mux_aclk_perihp_p) = { "cpll_aclk_perihp_src", 130 + "gpll_aclk_perihp_src" }; 131 + 132 + PNAME(mux_pll_src_cpll_gpll_p) = { "cpll", "gpll" }; 133 + PNAME(mux_pll_src_cpll_gpll_npll_p) = { "cpll", "gpll", "npll" }; 134 + PNAME(mux_pll_src_cpll_gpll_ppll_p) = { "cpll", "gpll", "ppll" }; 135 + PNAME(mux_pll_src_cpll_gpll_upll_p) = { "cpll", "gpll", "upll" }; 136 + PNAME(mux_pll_src_npll_cpll_gpll_p) = { "npll", "cpll", "gpll" }; 137 + PNAME(mux_pll_src_cpll_gpll_npll_ppll_p) = { "cpll", "gpll", "npll", 138 + "ppll" }; 139 + PNAME(mux_pll_src_cpll_gpll_npll_24m_p) = { "cpll", "gpll", "npll", 140 + "xin24m" }; 141 + PNAME(mux_pll_src_cpll_gpll_npll_usbphy480m_p) = { "cpll", "gpll", "npll", 142 + "clk_usbphy_480m" }; 143 + PNAME(mux_pll_src_ppll_cpll_gpll_npll_p) = { "ppll", "cpll", "gpll", 144 + "npll", "upll" }; 145 + PNAME(mux_pll_src_cpll_gpll_npll_upll_24m_p) = { "cpll", "gpll", "npll", 146 + "upll", "xin24m" }; 147 + PNAME(mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p) = { "cpll", "gpll", "npll", 148 + "ppll", "upll", "xin24m" }; 149 + 150 + PNAME(mux_pll_src_vpll_cpll_gpll_p) = { "vpll", "cpll", "gpll" }; 151 + PNAME(mux_pll_src_vpll_cpll_gpll_npll_p) = { "vpll", "cpll", "gpll", 152 + "npll" }; 153 + PNAME(mux_pll_src_vpll_cpll_gpll_24m_p) = { "vpll", "cpll", "gpll", 154 + "xin24m" }; 155 + 156 + PNAME(mux_dclk_vop0_p) = { "dclk_vop0_div", 157 + "dclk_vop0_frac" }; 158 + PNAME(mux_dclk_vop1_p) = { "dclk_vop1_div", 159 + "dclk_vop1_frac" }; 160 + 161 + PNAME(mux_clk_cif_p) = { "clk_cifout_src", "xin24m" }; 162 + 163 + PNAME(mux_pll_src_24m_usbphy480m_p) = { "xin24m", "clk_usbphy_480m" }; 164 + PNAME(mux_pll_src_24m_pciephy_p) = { "xin24m", "clk_pciephy_ref100m" }; 165 + PNAME(mux_pll_src_24m_32k_cpll_gpll_p) = { "xin24m", "xin32k", 166 + "cpll", "gpll" }; 167 + PNAME(mux_pciecore_cru_phy_p) = { "clk_pcie_core_cru", 168 + "clk_pcie_core_phy" }; 169 + 170 + PNAME(mux_aclk_emmc_p) = { "cpll_aclk_emmc_src", 171 + "gpll_aclk_emmc_src" }; 172 + 173 + PNAME(mux_aclk_perilp0_p) = { "cpll_aclk_perilp0_src", 174 + "gpll_aclk_perilp0_src" }; 175 + 176 + PNAME(mux_fclk_cm0s_p) = { "cpll_fclk_cm0s_src", 177 + "gpll_fclk_cm0s_src" }; 178 + 179 + PNAME(mux_hclk_perilp1_p) = { "cpll_hclk_perilp1_src", 180 + "gpll_hclk_perilp1_src" }; 181 + 182 + PNAME(mux_clk_testout1_p) = { "clk_testout1_pll_src", "xin24m" }; 183 + PNAME(mux_clk_testout2_p) = { "clk_testout2_pll_src", "xin24m" }; 184 + 185 + PNAME(mux_usbphy_480m_p) = { "clk_usbphy0_480m_src", 186 + "clk_usbphy1_480m_src" }; 187 + PNAME(mux_aclk_gmac_p) = { "cpll_aclk_gmac_src", 188 + "gpll_aclk_gmac_src" }; 189 + PNAME(mux_rmii_p) = { "clk_gmac", "clkin_gmac" }; 190 + PNAME(mux_spdif_p) = { "clk_spdif_div", "clk_spdif_frac", 191 + "clkin_i2s", "xin12m" }; 192 + PNAME(mux_i2s0_p) = { "clk_i2s0_div", "clk_i2s0_frac", 193 + "clkin_i2s", "xin12m" }; 194 + PNAME(mux_i2s1_p) = { "clk_i2s1_div", "clk_i2s1_frac", 195 + "clkin_i2s", "xin12m" }; 196 + PNAME(mux_i2s2_p) = { "clk_i2s2_div", "clk_i2s2_frac", 197 + "clkin_i2s", "xin12m" }; 198 + PNAME(mux_i2sch_p) = { "clk_i2s0", "clk_i2s1", 199 + "clk_i2s2" }; 200 + PNAME(mux_i2sout_p) = { "clk_i2sout_src", "xin12m" }; 201 + 202 + PNAME(mux_uart0_p) = { "clk_uart0_div", "clk_uart0_frac", "xin24m" }; 203 + PNAME(mux_uart1_p) = { "clk_uart1_div", "clk_uart1_frac", "xin24m" }; 204 + PNAME(mux_uart2_p) = { "clk_uart2_div", "clk_uart2_frac", "xin24m" }; 205 + PNAME(mux_uart3_p) = { "clk_uart3_div", "clk_uart3_frac", "xin24m" }; 206 + 207 + /* PMU CRU parents */ 208 + PNAME(mux_ppll_24m_p) = { "ppll", "xin24m" }; 209 + PNAME(mux_24m_ppll_p) = { "xin24m", "ppll" }; 210 + PNAME(mux_fclk_cm0s_pmu_ppll_p) = { "fclk_cm0s_pmu_ppll_src", "xin24m" }; 211 + PNAME(mux_wifi_pmu_p) = { "clk_wifi_div", "clk_wifi_frac" }; 212 + PNAME(mux_uart4_pmu_p) = { "clk_uart4_div", "clk_uart4_frac", 213 + "xin24m" }; 214 + PNAME(mux_clk_testout2_2io_p) = { "clk_testout2", "clk_32k_suspend_pmu" }; 215 + 216 + static struct rockchip_pll_clock rk3399_pll_clks[] __initdata = { 217 + [lpll] = PLL(pll_rk3399, PLL_APLLL, "lpll", mux_pll_p, 0, RK3399_PLL_CON(0), 218 + RK3399_PLL_CON(3), 8, 31, 0, rk3399_pll_rates), 219 + [bpll] = PLL(pll_rk3399, PLL_APLLB, "bpll", mux_pll_p, 0, RK3399_PLL_CON(8), 220 + RK3399_PLL_CON(11), 8, 31, 0, rk3399_pll_rates), 221 + [dpll] = PLL(pll_rk3399, PLL_DPLL, "dpll", mux_pll_p, 0, RK3399_PLL_CON(16), 222 + RK3399_PLL_CON(19), 8, 31, 0, NULL), 223 + [cpll] = PLL(pll_rk3399, PLL_CPLL, "cpll", mux_pll_p, 0, RK3399_PLL_CON(24), 224 + RK3399_PLL_CON(27), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), 225 + [gpll] = PLL(pll_rk3399, PLL_GPLL, "gpll", mux_pll_p, 0, RK3399_PLL_CON(32), 226 + RK3399_PLL_CON(35), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), 227 + [npll] = PLL(pll_rk3399, PLL_NPLL, "npll", mux_pll_p, 0, RK3399_PLL_CON(40), 228 + RK3399_PLL_CON(43), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), 229 + [vpll] = PLL(pll_rk3399, PLL_VPLL, "vpll", mux_pll_p, 0, RK3399_PLL_CON(48), 230 + RK3399_PLL_CON(51), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), 231 + }; 232 + 233 + static struct rockchip_pll_clock rk3399_pmu_pll_clks[] __initdata = { 234 + [ppll] = PLL(pll_rk3399, PLL_PPLL, "ppll", mux_pll_p, 0, RK3399_PMU_PLL_CON(0), 235 + RK3399_PMU_PLL_CON(3), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk3399_pll_rates), 236 + }; 237 + 238 + #define MFLAGS CLK_MUX_HIWORD_MASK 239 + #define DFLAGS CLK_DIVIDER_HIWORD_MASK 240 + #define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) 241 + #define IFLAGS ROCKCHIP_INVERTER_HIWORD_MASK 242 + 243 + static struct rockchip_clk_branch rk3399_spdif_fracmux __initdata = 244 + MUX(0, "clk_spdif_mux", mux_spdif_p, CLK_SET_RATE_PARENT, 245 + RK3399_CLKSEL_CON(32), 13, 2, MFLAGS); 246 + 247 + static struct rockchip_clk_branch rk3399_i2s0_fracmux __initdata = 248 + MUX(0, "clk_i2s0_mux", mux_i2s0_p, CLK_SET_RATE_PARENT, 249 + RK3399_CLKSEL_CON(28), 8, 2, MFLAGS); 250 + 251 + static struct rockchip_clk_branch rk3399_i2s1_fracmux __initdata = 252 + MUX(0, "clk_i2s1_mux", mux_i2s1_p, CLK_SET_RATE_PARENT, 253 + RK3399_CLKSEL_CON(29), 8, 2, MFLAGS); 254 + 255 + static struct rockchip_clk_branch rk3399_i2s2_fracmux __initdata = 256 + MUX(0, "clk_i2s2_mux", mux_i2s2_p, CLK_SET_RATE_PARENT, 257 + RK3399_CLKSEL_CON(30), 8, 2, MFLAGS); 258 + 259 + static struct rockchip_clk_branch rk3399_uart0_fracmux __initdata = 260 + MUX(SCLK_UART0, "clk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT, 261 + RK3399_CLKSEL_CON(33), 8, 2, MFLAGS); 262 + 263 + static struct rockchip_clk_branch rk3399_uart1_fracmux __initdata = 264 + MUX(SCLK_UART1, "clk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT, 265 + RK3399_CLKSEL_CON(34), 8, 2, MFLAGS); 266 + 267 + static struct rockchip_clk_branch rk3399_uart2_fracmux __initdata = 268 + MUX(SCLK_UART2, "clk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT, 269 + RK3399_CLKSEL_CON(35), 8, 2, MFLAGS); 270 + 271 + static struct rockchip_clk_branch rk3399_uart3_fracmux __initdata = 272 + MUX(SCLK_UART3, "clk_uart3", mux_uart3_p, CLK_SET_RATE_PARENT, 273 + RK3399_CLKSEL_CON(36), 8, 2, MFLAGS); 274 + 275 + static struct rockchip_clk_branch rk3399_uart4_pmu_fracmux __initdata = 276 + MUX(SCLK_UART4_PMU, "clk_uart4_pmu", mux_uart4_pmu_p, CLK_SET_RATE_PARENT, 277 + RK3399_PMU_CLKSEL_CON(5), 8, 2, MFLAGS); 278 + 279 + static struct rockchip_clk_branch rk3399_dclk_vop0_fracmux __initdata = 280 + MUX(DCLK_VOP0, "dclk_vop0", mux_dclk_vop0_p, CLK_SET_RATE_PARENT, 281 + RK3399_CLKSEL_CON(49), 11, 1, MFLAGS); 282 + 283 + static struct rockchip_clk_branch rk3399_dclk_vop1_fracmux __initdata = 284 + MUX(DCLK_VOP1, "dclk_vop1", mux_dclk_vop1_p, CLK_SET_RATE_PARENT, 285 + RK3399_CLKSEL_CON(50), 11, 1, MFLAGS); 286 + 287 + static struct rockchip_clk_branch rk3399_pmuclk_wifi_fracmux __initdata = 288 + MUX(SCLK_WIFI_PMU, "clk_wifi_pmu", mux_wifi_pmu_p, CLK_SET_RATE_PARENT, 289 + RK3399_PMU_CLKSEL_CON(1), 14, 1, MFLAGS); 290 + 291 + static const struct rockchip_cpuclk_reg_data rk3399_cpuclkl_data = { 292 + .core_reg = RK3399_CLKSEL_CON(0), 293 + .div_core_shift = 0, 294 + .div_core_mask = 0x1f, 295 + .mux_core_alt = 3, 296 + .mux_core_main = 0, 297 + .mux_core_shift = 6, 298 + .mux_core_mask = 0x3, 299 + }; 300 + 301 + static const struct rockchip_cpuclk_reg_data rk3399_cpuclkb_data = { 302 + .core_reg = RK3399_CLKSEL_CON(2), 303 + .div_core_shift = 0, 304 + .div_core_mask = 0x1f, 305 + .mux_core_alt = 3, 306 + .mux_core_main = 1, 307 + .mux_core_shift = 6, 308 + .mux_core_mask = 0x3, 309 + }; 310 + 311 + #define RK3399_DIV_ACLKM_MASK 0x1f 312 + #define RK3399_DIV_ACLKM_SHIFT 8 313 + #define RK3399_DIV_ATCLK_MASK 0x1f 314 + #define RK3399_DIV_ATCLK_SHIFT 0 315 + #define RK3399_DIV_PCLK_DBG_MASK 0x1f 316 + #define RK3399_DIV_PCLK_DBG_SHIFT 8 317 + 318 + #define RK3399_CLKSEL0(_offs, _aclkm) \ 319 + { \ 320 + .reg = RK3399_CLKSEL_CON(0 + _offs), \ 321 + .val = HIWORD_UPDATE(_aclkm, RK3399_DIV_ACLKM_MASK, \ 322 + RK3399_DIV_ACLKM_SHIFT), \ 323 + } 324 + #define RK3399_CLKSEL1(_offs, _atclk, _pdbg) \ 325 + { \ 326 + .reg = RK3399_CLKSEL_CON(1 + _offs), \ 327 + .val = HIWORD_UPDATE(_atclk, RK3399_DIV_ATCLK_MASK, \ 328 + RK3399_DIV_ATCLK_SHIFT) | \ 329 + HIWORD_UPDATE(_pdbg, RK3399_DIV_PCLK_DBG_MASK, \ 330 + RK3399_DIV_PCLK_DBG_SHIFT), \ 331 + } 332 + 333 + /* cluster_l: aclkm in clksel0, rest in clksel1 */ 334 + #define RK3399_CPUCLKL_RATE(_prate, _aclkm, _atclk, _pdbg) \ 335 + { \ 336 + .prate = _prate##U, \ 337 + .divs = { \ 338 + RK3399_CLKSEL0(0, _aclkm), \ 339 + RK3399_CLKSEL1(0, _atclk, _pdbg), \ 340 + }, \ 341 + } 342 + 343 + /* cluster_b: aclkm in clksel2, rest in clksel3 */ 344 + #define RK3399_CPUCLKB_RATE(_prate, _aclkm, _atclk, _pdbg) \ 345 + { \ 346 + .prate = _prate##U, \ 347 + .divs = { \ 348 + RK3399_CLKSEL0(2, _aclkm), \ 349 + RK3399_CLKSEL1(2, _atclk, _pdbg), \ 350 + }, \ 351 + } 352 + 353 + static struct rockchip_cpuclk_rate_table rk3399_cpuclkl_rates[] __initdata = { 354 + RK3399_CPUCLKL_RATE(1800000000, 1, 8, 8), 355 + RK3399_CPUCLKL_RATE(1704000000, 1, 8, 8), 356 + RK3399_CPUCLKL_RATE(1608000000, 1, 7, 7), 357 + RK3399_CPUCLKL_RATE(1512000000, 1, 7, 7), 358 + RK3399_CPUCLKL_RATE(1488000000, 1, 6, 6), 359 + RK3399_CPUCLKL_RATE(1416000000, 1, 6, 6), 360 + RK3399_CPUCLKL_RATE(1200000000, 1, 5, 5), 361 + RK3399_CPUCLKL_RATE(1008000000, 1, 5, 5), 362 + RK3399_CPUCLKL_RATE( 816000000, 1, 4, 4), 363 + RK3399_CPUCLKL_RATE( 696000000, 1, 3, 3), 364 + RK3399_CPUCLKL_RATE( 600000000, 1, 3, 3), 365 + RK3399_CPUCLKL_RATE( 408000000, 1, 2, 2), 366 + RK3399_CPUCLKL_RATE( 312000000, 1, 1, 1), 367 + RK3399_CPUCLKL_RATE( 216000000, 1, 1, 1), 368 + RK3399_CPUCLKL_RATE( 96000000, 1, 1, 1), 369 + }; 370 + 371 + static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = { 372 + RK3399_CPUCLKB_RATE(2208000000, 1, 11, 11), 373 + RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11), 374 + RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10), 375 + RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10), 376 + RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9), 377 + RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9), 378 + RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8), 379 + RK3399_CPUCLKB_RATE(1704000000, 1, 8, 8), 380 + RK3399_CPUCLKB_RATE(1608000000, 1, 7, 7), 381 + RK3399_CPUCLKB_RATE(1512000000, 1, 7, 7), 382 + RK3399_CPUCLKB_RATE(1488000000, 1, 6, 6), 383 + RK3399_CPUCLKB_RATE(1416000000, 1, 6, 6), 384 + RK3399_CPUCLKB_RATE(1200000000, 1, 5, 5), 385 + RK3399_CPUCLKB_RATE(1008000000, 1, 5, 5), 386 + RK3399_CPUCLKB_RATE( 816000000, 1, 4, 4), 387 + RK3399_CPUCLKB_RATE( 696000000, 1, 3, 3), 388 + RK3399_CPUCLKB_RATE( 600000000, 1, 3, 3), 389 + RK3399_CPUCLKB_RATE( 408000000, 1, 2, 2), 390 + RK3399_CPUCLKB_RATE( 312000000, 1, 1, 1), 391 + RK3399_CPUCLKB_RATE( 216000000, 1, 1, 1), 392 + RK3399_CPUCLKB_RATE( 96000000, 1, 1, 1), 393 + }; 394 + 395 + static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { 396 + /* 397 + * CRU Clock-Architecture 398 + */ 399 + 400 + /* usbphy */ 401 + GATE(SCLK_USB2PHY0_REF, "clk_usb2phy0_ref", "xin24m", CLK_IGNORE_UNUSED, 402 + RK3399_CLKGATE_CON(6), 5, GFLAGS), 403 + GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", CLK_IGNORE_UNUSED, 404 + RK3399_CLKGATE_CON(6), 6, GFLAGS), 405 + 406 + GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", CLK_IGNORE_UNUSED, 407 + RK3399_CLKGATE_CON(13), 12, GFLAGS), 408 + GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", CLK_IGNORE_UNUSED, 409 + RK3399_CLKGATE_CON(13), 12, GFLAGS), 410 + MUX(0, "clk_usbphy_480m", mux_usbphy_480m_p, CLK_IGNORE_UNUSED, 411 + RK3399_CLKSEL_CON(14), 6, 1, MFLAGS), 412 + 413 + MUX(0, "upll", mux_pll_src_24m_usbphy480m_p, 0, 414 + RK3399_CLKSEL_CON(14), 15, 1, MFLAGS), 415 + 416 + COMPOSITE_NODIV(SCLK_HSICPHY, "clk_hsicphy", mux_pll_src_cpll_gpll_npll_usbphy480m_p, 0, 417 + RK3399_CLKSEL_CON(19), 0, 2, MFLAGS, 418 + RK3399_CLKGATE_CON(6), 4, GFLAGS), 419 + 420 + COMPOSITE(ACLK_USB3, "aclk_usb3", mux_pll_src_cpll_gpll_npll_p, 0, 421 + RK3399_CLKSEL_CON(39), 6, 2, MFLAGS, 0, 5, DFLAGS, 422 + RK3399_CLKGATE_CON(12), 0, GFLAGS), 423 + GATE(ACLK_USB3_NOC, "aclk_usb3_noc", "aclk_usb3", CLK_IGNORE_UNUSED, 424 + RK3399_CLKGATE_CON(30), 0, GFLAGS), 425 + GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb3", 0, 426 + RK3399_CLKGATE_CON(30), 1, GFLAGS), 427 + GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb3", 0, 428 + RK3399_CLKGATE_CON(30), 2, GFLAGS), 429 + GATE(ACLK_USB3_RKSOC_AXI_PERF, "aclk_usb3_rksoc_axi_perf", "aclk_usb3", 0, 430 + RK3399_CLKGATE_CON(30), 3, GFLAGS), 431 + GATE(ACLK_USB3_GRF, "aclk_usb3_grf", "aclk_usb3", 0, 432 + RK3399_CLKGATE_CON(30), 4, GFLAGS), 433 + 434 + GATE(SCLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0, 435 + RK3399_CLKGATE_CON(12), 1, GFLAGS), 436 + GATE(SCLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0, 437 + RK3399_CLKGATE_CON(12), 2, GFLAGS), 438 + 439 + COMPOSITE(SCLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", mux_pll_p, 0, 440 + RK3399_CLKSEL_CON(40), 15, 1, MFLAGS, 0, 10, DFLAGS, 441 + RK3399_CLKGATE_CON(12), 3, GFLAGS), 442 + 443 + COMPOSITE(SCLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", mux_pll_p, 0, 444 + RK3399_CLKSEL_CON(41), 15, 1, MFLAGS, 0, 10, DFLAGS, 445 + RK3399_CLKGATE_CON(12), 4, GFLAGS), 446 + 447 + COMPOSITE(SCLK_UPHY0_TCPDPHY_REF, "clk_uphy0_tcpdphy_ref", mux_pll_p, 0, 448 + RK3399_CLKSEL_CON(64), 15, 1, MFLAGS, 8, 5, DFLAGS, 449 + RK3399_CLKGATE_CON(13), 4, GFLAGS), 450 + 451 + COMPOSITE(SCLK_UPHY0_TCPDCORE, "clk_uphy0_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0, 452 + RK3399_CLKSEL_CON(64), 6, 2, MFLAGS, 0, 5, DFLAGS, 453 + RK3399_CLKGATE_CON(13), 5, GFLAGS), 454 + 455 + COMPOSITE(SCLK_UPHY1_TCPDPHY_REF, "clk_uphy1_tcpdphy_ref", mux_pll_p, 0, 456 + RK3399_CLKSEL_CON(65), 15, 1, MFLAGS, 8, 5, DFLAGS, 457 + RK3399_CLKGATE_CON(13), 6, GFLAGS), 458 + 459 + COMPOSITE(SCLK_UPHY1_TCPDCORE, "clk_uphy1_tcpdcore", mux_pll_src_24m_32k_cpll_gpll_p, 0, 460 + RK3399_CLKSEL_CON(65), 6, 2, MFLAGS, 0, 5, DFLAGS, 461 + RK3399_CLKGATE_CON(13), 7, GFLAGS), 462 + 463 + /* little core */ 464 + GATE(0, "clk_core_l_lpll_src", "lpll", CLK_IGNORE_UNUSED, 465 + RK3399_CLKGATE_CON(0), 0, GFLAGS), 466 + GATE(0, "clk_core_l_bpll_src", "bpll", CLK_IGNORE_UNUSED, 467 + RK3399_CLKGATE_CON(0), 1, GFLAGS), 468 + GATE(0, "clk_core_l_dpll_src", "dpll", CLK_IGNORE_UNUSED, 469 + RK3399_CLKGATE_CON(0), 2, GFLAGS), 470 + GATE(0, "clk_core_l_gpll_src", "gpll", CLK_IGNORE_UNUSED, 471 + RK3399_CLKGATE_CON(0), 3, GFLAGS), 472 + 473 + COMPOSITE_NOMUX(0, "aclkm_core_l", "armclkl", CLK_IGNORE_UNUSED, 474 + RK3399_CLKSEL_CON(0), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 475 + RK3399_CLKGATE_CON(0), 4, GFLAGS), 476 + COMPOSITE_NOMUX(0, "atclk_core_l", "armclkl", CLK_IGNORE_UNUSED, 477 + RK3399_CLKSEL_CON(1), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 478 + RK3399_CLKGATE_CON(0), 5, GFLAGS), 479 + COMPOSITE_NOMUX(0, "pclk_dbg_core_l", "armclkl", CLK_IGNORE_UNUSED, 480 + RK3399_CLKSEL_CON(1), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 481 + RK3399_CLKGATE_CON(0), 6, GFLAGS), 482 + 483 + GATE(ACLK_CORE_ADB400_CORE_L_2_CCI500, "aclk_core_adb400_core_l_2_cci500", "aclkm_core_l", CLK_IGNORE_UNUSED, 484 + RK3399_CLKGATE_CON(14), 12, GFLAGS), 485 + GATE(ACLK_PERF_CORE_L, "aclk_perf_core_l", "aclkm_core_l", CLK_IGNORE_UNUSED, 486 + RK3399_CLKGATE_CON(14), 13, GFLAGS), 487 + 488 + GATE(0, "clk_dbg_pd_core_l", "armclkl", CLK_IGNORE_UNUSED, 489 + RK3399_CLKGATE_CON(14), 9, GFLAGS), 490 + GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_core_adb400_gic_2_core_l", "armclkl", CLK_IGNORE_UNUSED, 491 + RK3399_CLKGATE_CON(14), 10, GFLAGS), 492 + GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_core_adb400_core_l_2_gic", "armclkl", CLK_IGNORE_UNUSED, 493 + RK3399_CLKGATE_CON(14), 11, GFLAGS), 494 + GATE(SCLK_PVTM_CORE_L, "clk_pvtm_core_l", "xin24m", CLK_IGNORE_UNUSED, 495 + RK3399_CLKGATE_CON(0), 7, GFLAGS), 496 + 497 + /* big core */ 498 + GATE(0, "clk_core_b_lpll_src", "lpll", CLK_IGNORE_UNUSED, 499 + RK3399_CLKGATE_CON(1), 0, GFLAGS), 500 + GATE(0, "clk_core_b_bpll_src", "bpll", CLK_IGNORE_UNUSED, 501 + RK3399_CLKGATE_CON(1), 1, GFLAGS), 502 + GATE(0, "clk_core_b_dpll_src", "dpll", CLK_IGNORE_UNUSED, 503 + RK3399_CLKGATE_CON(1), 2, GFLAGS), 504 + GATE(0, "clk_core_b_gpll_src", "gpll", CLK_IGNORE_UNUSED, 505 + RK3399_CLKGATE_CON(1), 3, GFLAGS), 506 + 507 + COMPOSITE_NOMUX(0, "aclkm_core_b", "armclkb", CLK_IGNORE_UNUSED, 508 + RK3399_CLKSEL_CON(2), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 509 + RK3399_CLKGATE_CON(1), 4, GFLAGS), 510 + COMPOSITE_NOMUX(0, "atclk_core_b", "armclkb", CLK_IGNORE_UNUSED, 511 + RK3399_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 512 + RK3399_CLKGATE_CON(1), 5, GFLAGS), 513 + COMPOSITE_NOMUX(0, "pclk_dbg_core_b", "armclkb", CLK_IGNORE_UNUSED, 514 + RK3399_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, 515 + RK3399_CLKGATE_CON(1), 6, GFLAGS), 516 + 517 + GATE(ACLK_CORE_ADB400_CORE_B_2_CCI500, "aclk_core_adb400_core_b_2_cci500", "aclkm_core_b", CLK_IGNORE_UNUSED, 518 + RK3399_CLKGATE_CON(14), 5, GFLAGS), 519 + GATE(ACLK_PERF_CORE_B, "aclk_perf_core_b", "aclkm_core_b", CLK_IGNORE_UNUSED, 520 + RK3399_CLKGATE_CON(14), 6, GFLAGS), 521 + 522 + GATE(0, "clk_dbg_pd_core_b", "armclkb", CLK_IGNORE_UNUSED, 523 + RK3399_CLKGATE_CON(14), 1, GFLAGS), 524 + GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_core_adb400_gic_2_core_b", "armclkb", CLK_IGNORE_UNUSED, 525 + RK3399_CLKGATE_CON(14), 3, GFLAGS), 526 + GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_core_adb400_core_b_2_gic", "armclkb", CLK_IGNORE_UNUSED, 527 + RK3399_CLKGATE_CON(14), 4, GFLAGS), 528 + 529 + DIV(0, "pclken_dbg_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, 530 + RK3399_CLKSEL_CON(3), 13, 2, DFLAGS | CLK_DIVIDER_READ_ONLY), 531 + 532 + GATE(0, "pclk_dbg_cxcs_pd_core_b", "pclk_dbg_core_b", CLK_IGNORE_UNUSED, 533 + RK3399_CLKGATE_CON(14), 2, GFLAGS), 534 + 535 + GATE(SCLK_PVTM_CORE_B, "clk_pvtm_core_b", "xin24m", CLK_IGNORE_UNUSED, 536 + RK3399_CLKGATE_CON(1), 7, GFLAGS), 537 + 538 + /* gmac */ 539 + GATE(0, "cpll_aclk_gmac_src", "cpll", CLK_IGNORE_UNUSED, 540 + RK3399_CLKGATE_CON(6), 9, GFLAGS), 541 + GATE(0, "gpll_aclk_gmac_src", "gpll", CLK_IGNORE_UNUSED, 542 + RK3399_CLKGATE_CON(6), 8, GFLAGS), 543 + COMPOSITE(0, "aclk_gmac_pre", mux_aclk_gmac_p, 0, 544 + RK3399_CLKSEL_CON(20), 7, 1, MFLAGS, 0, 5, DFLAGS, 545 + RK3399_CLKGATE_CON(6), 10, GFLAGS), 546 + 547 + GATE(ACLK_GMAC, "aclk_gmac", "aclk_gmac_pre", 0, 548 + RK3399_CLKGATE_CON(32), 0, GFLAGS), 549 + GATE(ACLK_GMAC_NOC, "aclk_gmac_noc", "aclk_gmac_pre", CLK_IGNORE_UNUSED, 550 + RK3399_CLKGATE_CON(32), 1, GFLAGS), 551 + GATE(ACLK_PERF_GMAC, "aclk_perf_gmac", "aclk_gmac_pre", 0, 552 + RK3399_CLKGATE_CON(32), 4, GFLAGS), 553 + 554 + COMPOSITE_NOMUX(0, "pclk_gmac_pre", "aclk_gmac_pre", 0, 555 + RK3399_CLKSEL_CON(19), 8, 3, DFLAGS, 556 + RK3399_CLKGATE_CON(6), 11, GFLAGS), 557 + GATE(PCLK_GMAC, "pclk_gmac", "pclk_gmac_pre", 0, 558 + RK3399_CLKGATE_CON(32), 2, GFLAGS), 559 + GATE(PCLK_GMAC_NOC, "pclk_gmac_noc", "pclk_gmac_pre", CLK_IGNORE_UNUSED, 560 + RK3399_CLKGATE_CON(32), 3, GFLAGS), 561 + 562 + COMPOSITE(SCLK_MAC, "clk_gmac", mux_pll_src_cpll_gpll_npll_p, 0, 563 + RK3399_CLKSEL_CON(20), 14, 2, MFLAGS, 8, 5, DFLAGS, 564 + RK3399_CLKGATE_CON(5), 5, GFLAGS), 565 + 566 + MUX(SCLK_RMII_SRC, "clk_rmii_src", mux_rmii_p, CLK_SET_RATE_PARENT, 567 + RK3399_CLKSEL_CON(19), 4, 1, MFLAGS), 568 + GATE(SCLK_MACREF_OUT, "clk_mac_refout", "clk_rmii_src", 0, 569 + RK3399_CLKGATE_CON(5), 6, GFLAGS), 570 + GATE(SCLK_MACREF, "clk_mac_ref", "clk_rmii_src", 0, 571 + RK3399_CLKGATE_CON(5), 7, GFLAGS), 572 + GATE(SCLK_MAC_RX, "clk_rmii_rx", "clk_rmii_src", 0, 573 + RK3399_CLKGATE_CON(5), 8, GFLAGS), 574 + GATE(SCLK_MAC_TX, "clk_rmii_tx", "clk_rmii_src", 0, 575 + RK3399_CLKGATE_CON(5), 9, GFLAGS), 576 + 577 + /* spdif */ 578 + COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0, 579 + RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, 580 + RK3399_CLKGATE_CON(8), 13, GFLAGS), 581 + COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, 582 + RK3399_CLKSEL_CON(99), 0, 583 + RK3399_CLKGATE_CON(8), 14, GFLAGS, 584 + &rk3399_spdif_fracmux), 585 + GATE(SCLK_SPDIF_8CH, "clk_spdif", "clk_spdif_mux", CLK_SET_RATE_PARENT, 586 + RK3399_CLKGATE_CON(8), 15, GFLAGS), 587 + 588 + COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, 0, 589 + RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS, 590 + RK3399_CLKGATE_CON(10), 6, GFLAGS), 591 + /* i2s */ 592 + COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, 593 + RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, 594 + RK3399_CLKGATE_CON(8), 3, GFLAGS), 595 + COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, 596 + RK3399_CLKSEL_CON(96), 0, 597 + RK3399_CLKGATE_CON(8), 4, GFLAGS, 598 + &rk3399_i2s0_fracmux), 599 + GATE(SCLK_I2S0_8CH, "clk_i2s0", "clk_i2s0_mux", CLK_SET_RATE_PARENT, 600 + RK3399_CLKGATE_CON(8), 5, GFLAGS), 601 + 602 + COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0, 603 + RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, 604 + RK3399_CLKGATE_CON(8), 6, GFLAGS), 605 + COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, 606 + RK3399_CLKSEL_CON(97), 0, 607 + RK3399_CLKGATE_CON(8), 7, GFLAGS, 608 + &rk3399_i2s1_fracmux), 609 + GATE(SCLK_I2S1_8CH, "clk_i2s1", "clk_i2s1_mux", CLK_SET_RATE_PARENT, 610 + RK3399_CLKGATE_CON(8), 8, GFLAGS), 611 + 612 + COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0, 613 + RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, 614 + RK3399_CLKGATE_CON(8), 9, GFLAGS), 615 + COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, 616 + RK3399_CLKSEL_CON(98), 0, 617 + RK3399_CLKGATE_CON(8), 10, GFLAGS, 618 + &rk3399_i2s2_fracmux), 619 + GATE(SCLK_I2S2_8CH, "clk_i2s2", "clk_i2s2_mux", CLK_SET_RATE_PARENT, 620 + RK3399_CLKGATE_CON(8), 11, GFLAGS), 621 + 622 + MUX(0, "clk_i2sout_src", mux_i2sch_p, CLK_SET_RATE_PARENT, 623 + RK3399_CLKSEL_CON(31), 0, 2, MFLAGS), 624 + COMPOSITE_NODIV(SCLK_I2S_8CH_OUT, "clk_i2sout", mux_i2sout_p, CLK_SET_RATE_PARENT, 625 + RK3399_CLKSEL_CON(30), 8, 2, MFLAGS, 626 + RK3399_CLKGATE_CON(8), 12, GFLAGS), 627 + 628 + /* uart */ 629 + MUX(0, "clk_uart0_src", mux_pll_src_cpll_gpll_upll_p, 0, 630 + RK3399_CLKSEL_CON(33), 12, 2, MFLAGS), 631 + COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, 632 + RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, 633 + RK3399_CLKGATE_CON(9), 0, GFLAGS), 634 + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, 635 + RK3399_CLKSEL_CON(100), 0, 636 + RK3399_CLKGATE_CON(9), 1, GFLAGS, 637 + &rk3399_uart0_fracmux), 638 + 639 + MUX(0, "clk_uart_src", mux_pll_src_cpll_gpll_p, 0, 640 + RK3399_CLKSEL_CON(33), 15, 1, MFLAGS), 641 + COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, 642 + RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, 643 + RK3399_CLKGATE_CON(9), 2, GFLAGS), 644 + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, 645 + RK3399_CLKSEL_CON(101), 0, 646 + RK3399_CLKGATE_CON(9), 3, GFLAGS, 647 + &rk3399_uart1_fracmux), 648 + 649 + COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, 650 + RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, 651 + RK3399_CLKGATE_CON(9), 4, GFLAGS), 652 + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, 653 + RK3399_CLKSEL_CON(102), 0, 654 + RK3399_CLKGATE_CON(9), 5, GFLAGS, 655 + &rk3399_uart2_fracmux), 656 + 657 + COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, 658 + RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, 659 + RK3399_CLKGATE_CON(9), 6, GFLAGS), 660 + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, 661 + RK3399_CLKSEL_CON(103), 0, 662 + RK3399_CLKGATE_CON(9), 7, GFLAGS, 663 + &rk3399_uart3_fracmux), 664 + 665 + COMPOSITE(0, "pclk_ddr", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, 666 + RK3399_CLKSEL_CON(6), 15, 1, MFLAGS, 8, 5, DFLAGS, 667 + RK3399_CLKGATE_CON(3), 4, GFLAGS), 668 + 669 + GATE(PCLK_CENTER_MAIN_NOC, "pclk_center_main_noc", "pclk_ddr", CLK_IGNORE_UNUSED, 670 + RK3399_CLKGATE_CON(18), 10, GFLAGS), 671 + GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_ddr", CLK_IGNORE_UNUSED, 672 + RK3399_CLKGATE_CON(18), 12, GFLAGS), 673 + GATE(PCLK_CIC, "pclk_cic", "pclk_ddr", CLK_IGNORE_UNUSED, 674 + RK3399_CLKGATE_CON(18), 15, GFLAGS), 675 + GATE(PCLK_DDR_SGRF, "pclk_ddr_sgrf", "pclk_ddr", CLK_IGNORE_UNUSED, 676 + RK3399_CLKGATE_CON(19), 2, GFLAGS), 677 + 678 + GATE(SCLK_PVTM_DDR, "clk_pvtm_ddr", "xin24m", CLK_IGNORE_UNUSED, 679 + RK3399_CLKGATE_CON(4), 11, GFLAGS), 680 + GATE(SCLK_DFIMON0_TIMER, "clk_dfimon0_timer", "xin24m", CLK_IGNORE_UNUSED, 681 + RK3399_CLKGATE_CON(3), 5, GFLAGS), 682 + GATE(SCLK_DFIMON1_TIMER, "clk_dfimon1_timer", "xin24m", CLK_IGNORE_UNUSED, 683 + RK3399_CLKGATE_CON(3), 6, GFLAGS), 684 + 685 + /* cci */ 686 + GATE(0, "cpll_aclk_cci_src", "cpll", CLK_IGNORE_UNUSED, 687 + RK3399_CLKGATE_CON(2), 0, GFLAGS), 688 + GATE(0, "gpll_aclk_cci_src", "gpll", CLK_IGNORE_UNUSED, 689 + RK3399_CLKGATE_CON(2), 1, GFLAGS), 690 + GATE(0, "npll_aclk_cci_src", "npll", CLK_IGNORE_UNUSED, 691 + RK3399_CLKGATE_CON(2), 2, GFLAGS), 692 + GATE(0, "vpll_aclk_cci_src", "vpll", CLK_IGNORE_UNUSED, 693 + RK3399_CLKGATE_CON(2), 3, GFLAGS), 694 + 695 + COMPOSITE(0, "aclk_cci_pre", mux_aclk_cci_p, CLK_IGNORE_UNUSED, 696 + RK3399_CLKSEL_CON(5), 6, 2, MFLAGS, 0, 5, DFLAGS, 697 + RK3399_CLKGATE_CON(2), 4, GFLAGS), 698 + 699 + GATE(ACLK_ADB400M_PD_CORE_L, "aclk_adb400m_pd_core_l", "aclk_cci_pre", CLK_IGNORE_UNUSED, 700 + RK3399_CLKGATE_CON(15), 0, GFLAGS), 701 + GATE(ACLK_ADB400M_PD_CORE_B, "aclk_adb400m_pd_core_b", "aclk_cci_pre", CLK_IGNORE_UNUSED, 702 + RK3399_CLKGATE_CON(15), 1, GFLAGS), 703 + GATE(ACLK_CCI, "aclk_cci", "aclk_cci_pre", CLK_IGNORE_UNUSED, 704 + RK3399_CLKGATE_CON(15), 2, GFLAGS), 705 + GATE(ACLK_CCI_NOC0, "aclk_cci_noc0", "aclk_cci_pre", CLK_IGNORE_UNUSED, 706 + RK3399_CLKGATE_CON(15), 3, GFLAGS), 707 + GATE(ACLK_CCI_NOC1, "aclk_cci_noc1", "aclk_cci_pre", CLK_IGNORE_UNUSED, 708 + RK3399_CLKGATE_CON(15), 4, GFLAGS), 709 + GATE(ACLK_CCI_GRF, "aclk_cci_grf", "aclk_cci_pre", CLK_IGNORE_UNUSED, 710 + RK3399_CLKGATE_CON(15), 7, GFLAGS), 711 + 712 + GATE(0, "cpll_cci_trace", "cpll", CLK_IGNORE_UNUSED, 713 + RK3399_CLKGATE_CON(2), 5, GFLAGS), 714 + GATE(0, "gpll_cci_trace", "gpll", CLK_IGNORE_UNUSED, 715 + RK3399_CLKGATE_CON(2), 6, GFLAGS), 716 + COMPOSITE(SCLK_CCI_TRACE, "clk_cci_trace", mux_cci_trace_p, CLK_IGNORE_UNUSED, 717 + RK3399_CLKSEL_CON(5), 15, 2, MFLAGS, 8, 5, DFLAGS, 718 + RK3399_CLKGATE_CON(2), 7, GFLAGS), 719 + 720 + GATE(0, "cpll_cs", "cpll", CLK_IGNORE_UNUSED, 721 + RK3399_CLKGATE_CON(2), 8, GFLAGS), 722 + GATE(0, "gpll_cs", "gpll", CLK_IGNORE_UNUSED, 723 + RK3399_CLKGATE_CON(2), 9, GFLAGS), 724 + GATE(0, "npll_cs", "npll", CLK_IGNORE_UNUSED, 725 + RK3399_CLKGATE_CON(2), 10, GFLAGS), 726 + COMPOSITE_NOGATE(0, "clk_cs", mux_cs_p, CLK_IGNORE_UNUSED, 727 + RK3399_CLKSEL_CON(4), 6, 2, MFLAGS, 0, 5, DFLAGS), 728 + GATE(0, "clk_dbg_cxcs", "clk_cs", CLK_IGNORE_UNUSED, 729 + RK3399_CLKGATE_CON(15), 5, GFLAGS), 730 + GATE(0, "clk_dbg_noc", "clk_cs", CLK_IGNORE_UNUSED, 731 + RK3399_CLKGATE_CON(15), 6, GFLAGS), 732 + 733 + /* vcodec */ 734 + COMPOSITE(0, "aclk_vcodec_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, 735 + RK3399_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS, 736 + RK3399_CLKGATE_CON(4), 0, GFLAGS), 737 + COMPOSITE_NOMUX(0, "hclk_vcodec_pre", "aclk_vcodec_pre", 0, 738 + RK3399_CLKSEL_CON(7), 8, 5, DFLAGS, 739 + RK3399_CLKGATE_CON(4), 1, GFLAGS), 740 + GATE(HCLK_VCODEC, "hclk_vcodec", "hclk_vcodec_pre", 0, 741 + RK3399_CLKGATE_CON(17), 2, GFLAGS), 742 + GATE(0, "hclk_vcodec_noc", "hclk_vcodec_pre", CLK_IGNORE_UNUSED, 743 + RK3399_CLKGATE_CON(17), 3, GFLAGS), 744 + 745 + GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0, 746 + RK3399_CLKGATE_CON(17), 0, GFLAGS), 747 + GATE(0, "aclk_vcodec_noc", "aclk_vcodec_pre", CLK_IGNORE_UNUSED, 748 + RK3399_CLKGATE_CON(17), 1, GFLAGS), 749 + 750 + /* vdu */ 751 + COMPOSITE(SCLK_VDU_CORE, "clk_vdu_core", mux_pll_src_cpll_gpll_npll_p, 0, 752 + RK3399_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS, 753 + RK3399_CLKGATE_CON(4), 4, GFLAGS), 754 + COMPOSITE(SCLK_VDU_CA, "clk_vdu_ca", mux_pll_src_cpll_gpll_npll_p, 0, 755 + RK3399_CLKSEL_CON(9), 14, 2, MFLAGS, 8, 5, DFLAGS, 756 + RK3399_CLKGATE_CON(4), 5, GFLAGS), 757 + 758 + COMPOSITE(0, "aclk_vdu_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, 759 + RK3399_CLKSEL_CON(8), 6, 2, MFLAGS, 0, 5, DFLAGS, 760 + RK3399_CLKGATE_CON(4), 2, GFLAGS), 761 + COMPOSITE_NOMUX(0, "hclk_vdu_pre", "aclk_vdu_pre", 0, 762 + RK3399_CLKSEL_CON(8), 8, 5, DFLAGS, 763 + RK3399_CLKGATE_CON(4), 3, GFLAGS), 764 + GATE(HCLK_VDU, "hclk_vdu", "hclk_vdu_pre", 0, 765 + RK3399_CLKGATE_CON(17), 10, GFLAGS), 766 + GATE(HCLK_VDU_NOC, "hclk_vdu_noc", "hclk_vdu_pre", CLK_IGNORE_UNUSED, 767 + RK3399_CLKGATE_CON(17), 11, GFLAGS), 768 + 769 + GATE(ACLK_VDU, "aclk_vdu", "aclk_vdu_pre", 0, 770 + RK3399_CLKGATE_CON(17), 8, GFLAGS), 771 + GATE(ACLK_VDU_NOC, "aclk_vdu_noc", "aclk_vdu_pre", CLK_IGNORE_UNUSED, 772 + RK3399_CLKGATE_CON(17), 9, GFLAGS), 773 + 774 + /* iep */ 775 + COMPOSITE(0, "aclk_iep_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, 776 + RK3399_CLKSEL_CON(10), 6, 2, MFLAGS, 0, 5, DFLAGS, 777 + RK3399_CLKGATE_CON(4), 6, GFLAGS), 778 + COMPOSITE_NOMUX(0, "hclk_iep_pre", "aclk_iep_pre", 0, 779 + RK3399_CLKSEL_CON(10), 8, 5, DFLAGS, 780 + RK3399_CLKGATE_CON(4), 7, GFLAGS), 781 + GATE(HCLK_IEP, "hclk_iep", "hclk_iep_pre", 0, 782 + RK3399_CLKGATE_CON(16), 2, GFLAGS), 783 + GATE(HCLK_IEP_NOC, "hclk_iep_noc", "hclk_iep_pre", CLK_IGNORE_UNUSED, 784 + RK3399_CLKGATE_CON(16), 3, GFLAGS), 785 + 786 + GATE(ACLK_IEP, "aclk_iep", "aclk_iep_pre", 0, 787 + RK3399_CLKGATE_CON(16), 0, GFLAGS), 788 + GATE(ACLK_IEP_NOC, "aclk_iep_noc", "aclk_iep_pre", CLK_IGNORE_UNUSED, 789 + RK3399_CLKGATE_CON(16), 1, GFLAGS), 790 + 791 + /* rga */ 792 + COMPOSITE(SCLK_RGA_CORE, "clk_rga_core", mux_pll_src_cpll_gpll_npll_ppll_p, 0, 793 + RK3399_CLKSEL_CON(12), 6, 2, MFLAGS, 0, 5, DFLAGS, 794 + RK3399_CLKGATE_CON(4), 10, GFLAGS), 795 + 796 + COMPOSITE(0, "aclk_rga_pre", mux_pll_src_cpll_gpll_npll_ppll_p, 0, 797 + RK3399_CLKSEL_CON(11), 6, 2, MFLAGS, 0, 5, DFLAGS, 798 + RK3399_CLKGATE_CON(4), 8, GFLAGS), 799 + COMPOSITE_NOMUX(0, "hclk_rga_pre", "aclk_rga_pre", 0, 800 + RK3399_CLKSEL_CON(11), 8, 5, DFLAGS, 801 + RK3399_CLKGATE_CON(4), 9, GFLAGS), 802 + GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0, 803 + RK3399_CLKGATE_CON(16), 10, GFLAGS), 804 + GATE(HCLK_RGA_NOC, "hclk_rga_noc", "hclk_rga_pre", CLK_IGNORE_UNUSED, 805 + RK3399_CLKGATE_CON(16), 11, GFLAGS), 806 + 807 + GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, 808 + RK3399_CLKGATE_CON(16), 8, GFLAGS), 809 + GATE(ACLK_RGA_NOC, "aclk_rga_noc", "aclk_rga_pre", CLK_IGNORE_UNUSED, 810 + RK3399_CLKGATE_CON(16), 9, GFLAGS), 811 + 812 + /* center */ 813 + COMPOSITE(0, "aclk_center", mux_pll_src_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, 814 + RK3399_CLKSEL_CON(12), 14, 2, MFLAGS, 8, 5, DFLAGS, 815 + RK3399_CLKGATE_CON(3), 7, GFLAGS), 816 + GATE(ACLK_CENTER_MAIN_NOC, "aclk_center_main_noc", "aclk_center", CLK_IGNORE_UNUSED, 817 + RK3399_CLKGATE_CON(19), 0, GFLAGS), 818 + GATE(ACLK_CENTER_PERI_NOC, "aclk_center_peri_noc", "aclk_center", CLK_IGNORE_UNUSED, 819 + RK3399_CLKGATE_CON(19), 1, GFLAGS), 820 + 821 + /* gpu */ 822 + COMPOSITE(0, "aclk_gpu_pre", mux_pll_src_ppll_cpll_gpll_npll_p, CLK_IGNORE_UNUSED, 823 + RK3399_CLKSEL_CON(13), 5, 3, MFLAGS, 0, 5, DFLAGS, 824 + RK3399_CLKGATE_CON(13), 0, GFLAGS), 825 + GATE(ACLK_GPU, "aclk_gpu", "aclk_gpu_pre", 0, 826 + RK3399_CLKGATE_CON(30), 8, GFLAGS), 827 + GATE(ACLK_PERF_GPU, "aclk_perf_gpu", "aclk_gpu_pre", 0, 828 + RK3399_CLKGATE_CON(30), 10, GFLAGS), 829 + GATE(ACLK_GPU_GRF, "aclk_gpu_grf", "aclk_gpu_pre", 0, 830 + RK3399_CLKGATE_CON(30), 11, GFLAGS), 831 + GATE(SCLK_PVTM_GPU, "aclk_pvtm_gpu", "xin24m", 0, 832 + RK3399_CLKGATE_CON(13), 1, GFLAGS), 833 + 834 + /* perihp */ 835 + GATE(0, "cpll_aclk_perihp_src", "gpll", CLK_IGNORE_UNUSED, 836 + RK3399_CLKGATE_CON(5), 0, GFLAGS), 837 + GATE(0, "gpll_aclk_perihp_src", "cpll", CLK_IGNORE_UNUSED, 838 + RK3399_CLKGATE_CON(5), 1, GFLAGS), 839 + COMPOSITE(ACLK_PERIHP, "aclk_perihp", mux_aclk_perihp_p, CLK_IGNORE_UNUSED, 840 + RK3399_CLKSEL_CON(14), 7, 1, MFLAGS, 0, 5, DFLAGS, 841 + RK3399_CLKGATE_CON(5), 2, GFLAGS), 842 + COMPOSITE_NOMUX(HCLK_PERIHP, "hclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED, 843 + RK3399_CLKSEL_CON(14), 8, 2, DFLAGS, 844 + RK3399_CLKGATE_CON(5), 3, GFLAGS), 845 + COMPOSITE_NOMUX(PCLK_PERIHP, "pclk_perihp", "aclk_perihp", CLK_IGNORE_UNUSED, 846 + RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, 847 + RK3399_CLKGATE_CON(5), 4, GFLAGS), 848 + 849 + GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, 850 + RK3399_CLKGATE_CON(20), 2, GFLAGS), 851 + GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, 852 + RK3399_CLKGATE_CON(20), 10, GFLAGS), 853 + GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED, 854 + RK3399_CLKGATE_CON(20), 12, GFLAGS), 855 + 856 + GATE(HCLK_HOST0, "hclk_host0", "hclk_perihp", 0, 857 + RK3399_CLKGATE_CON(20), 5, GFLAGS), 858 + GATE(HCLK_HOST0_ARB, "hclk_host0_arb", "hclk_perihp", 0, 859 + RK3399_CLKGATE_CON(20), 6, GFLAGS), 860 + GATE(HCLK_HOST1, "hclk_host1", "hclk_perihp", 0, 861 + RK3399_CLKGATE_CON(20), 7, GFLAGS), 862 + GATE(HCLK_HOST1_ARB, "hclk_host1_arb", "hclk_perihp", 0, 863 + RK3399_CLKGATE_CON(20), 8, GFLAGS), 864 + GATE(HCLK_HSIC, "hclk_hsic", "hclk_perihp", 0, 865 + RK3399_CLKGATE_CON(20), 9, GFLAGS), 866 + GATE(0, "hclk_perihp_noc", "hclk_perihp", CLK_IGNORE_UNUSED, 867 + RK3399_CLKGATE_CON(20), 13, GFLAGS), 868 + GATE(0, "hclk_ahb1tom", "hclk_perihp", CLK_IGNORE_UNUSED, 869 + RK3399_CLKGATE_CON(20), 15, GFLAGS), 870 + 871 + GATE(PCLK_PERIHP_GRF, "pclk_perihp_grf", "pclk_perihp", CLK_IGNORE_UNUSED, 872 + RK3399_CLKGATE_CON(20), 4, GFLAGS), 873 + GATE(PCLK_PCIE, "pclk_pcie", "pclk_perihp", 0, 874 + RK3399_CLKGATE_CON(20), 11, GFLAGS), 875 + GATE(0, "pclk_perihp_noc", "pclk_perihp", CLK_IGNORE_UNUSED, 876 + RK3399_CLKGATE_CON(20), 14, GFLAGS), 877 + GATE(PCLK_HSICPHY, "pclk_hsicphy", "pclk_perihp", 0, 878 + RK3399_CLKGATE_CON(31), 8, GFLAGS), 879 + 880 + /* sdio & sdmmc */ 881 + COMPOSITE(0, "hclk_sd", mux_pll_src_cpll_gpll_p, 0, 882 + RK3399_CLKSEL_CON(13), 15, 1, MFLAGS, 8, 5, DFLAGS, 883 + RK3399_CLKGATE_CON(12), 13, GFLAGS), 884 + GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_sd", 0, 885 + RK3399_CLKGATE_CON(33), 8, GFLAGS), 886 + GATE(0, "hclk_sdmmc_noc", "hclk_sd", CLK_IGNORE_UNUSED, 887 + RK3399_CLKGATE_CON(33), 9, GFLAGS), 888 + 889 + COMPOSITE(SCLK_SDIO, "clk_sdio", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0, 890 + RK3399_CLKSEL_CON(15), 8, 3, MFLAGS, 0, 7, DFLAGS, 891 + RK3399_CLKGATE_CON(6), 0, GFLAGS), 892 + 893 + COMPOSITE(SCLK_SDMMC, "clk_sdmmc", mux_pll_src_cpll_gpll_npll_ppll_upll_24m_p, 0, 894 + RK3399_CLKSEL_CON(16), 8, 3, MFLAGS, 0, 7, DFLAGS, 895 + RK3399_CLKGATE_CON(6), 1, GFLAGS), 896 + 897 + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", RK3399_SDMMC_CON0, 1), 898 + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", RK3399_SDMMC_CON1, 1), 899 + 900 + MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3399_SDIO_CON0, 1), 901 + MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3399_SDIO_CON1, 1), 902 + 903 + /* pcie */ 904 + COMPOSITE(SCLK_PCIE_PM, "clk_pcie_pm", mux_pll_src_cpll_gpll_npll_24m_p, 0, 905 + RK3399_CLKSEL_CON(17), 8, 3, MFLAGS, 0, 7, DFLAGS, 906 + RK3399_CLKGATE_CON(6), 2, GFLAGS), 907 + 908 + COMPOSITE_NOMUX(SCLK_PCIEPHY_REF100M, "clk_pciephy_ref100m", "npll", 0, 909 + RK3399_CLKSEL_CON(18), 11, 5, DFLAGS, 910 + RK3399_CLKGATE_CON(12), 6, GFLAGS), 911 + MUX(SCLK_PCIEPHY_REF, "clk_pciephy_ref", mux_pll_src_24m_pciephy_p, CLK_SET_RATE_PARENT, 912 + RK3399_CLKSEL_CON(18), 10, 1, MFLAGS), 913 + 914 + COMPOSITE(0, "clk_pcie_core_cru", mux_pll_src_cpll_gpll_npll_p, 0, 915 + RK3399_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 7, DFLAGS, 916 + RK3399_CLKGATE_CON(6), 3, GFLAGS), 917 + MUX(SCLK_PCIE_CORE, "clk_pcie_core", mux_pciecore_cru_phy_p, CLK_SET_RATE_PARENT, 918 + RK3399_CLKSEL_CON(18), 7, 1, MFLAGS), 919 + 920 + /* emmc */ 921 + COMPOSITE(SCLK_EMMC, "clk_emmc", mux_pll_src_cpll_gpll_npll_upll_24m_p, 0, 922 + RK3399_CLKSEL_CON(22), 8, 3, MFLAGS, 0, 7, DFLAGS, 923 + RK3399_CLKGATE_CON(6), 14, GFLAGS), 924 + 925 + GATE(0, "cpll_aclk_emmc_src", "cpll", CLK_IGNORE_UNUSED, 926 + RK3399_CLKGATE_CON(6), 12, GFLAGS), 927 + GATE(0, "gpll_aclk_emmc_src", "gpll", CLK_IGNORE_UNUSED, 928 + RK3399_CLKGATE_CON(6), 13, GFLAGS), 929 + COMPOSITE_NOGATE(ACLK_EMMC, "aclk_emmc", mux_aclk_emmc_p, CLK_IGNORE_UNUSED, 930 + RK3399_CLKSEL_CON(21), 7, 1, MFLAGS, 0, 5, DFLAGS), 931 + GATE(ACLK_EMMC_CORE, "aclk_emmccore", "aclk_emmc", CLK_IGNORE_UNUSED, 932 + RK3399_CLKGATE_CON(32), 8, GFLAGS), 933 + GATE(ACLK_EMMC_NOC, "aclk_emmc_noc", "aclk_emmc", CLK_IGNORE_UNUSED, 934 + RK3399_CLKGATE_CON(32), 9, GFLAGS), 935 + GATE(ACLK_EMMC_GRF, "aclk_emmcgrf", "aclk_emmc", CLK_IGNORE_UNUSED, 936 + RK3399_CLKGATE_CON(32), 10, GFLAGS), 937 + 938 + /* perilp0 */ 939 + GATE(0, "cpll_aclk_perilp0_src", "cpll", CLK_IGNORE_UNUSED, 940 + RK3399_CLKGATE_CON(7), 1, GFLAGS), 941 + GATE(0, "gpll_aclk_perilp0_src", "gpll", CLK_IGNORE_UNUSED, 942 + RK3399_CLKGATE_CON(7), 0, GFLAGS), 943 + COMPOSITE(ACLK_PERILP0, "aclk_perilp0", mux_aclk_perilp0_p, CLK_IGNORE_UNUSED, 944 + RK3399_CLKSEL_CON(23), 7, 1, MFLAGS, 0, 5, DFLAGS, 945 + RK3399_CLKGATE_CON(7), 2, GFLAGS), 946 + COMPOSITE_NOMUX(HCLK_PERILP0, "hclk_perilp0", "aclk_perilp0", CLK_IGNORE_UNUSED, 947 + RK3399_CLKSEL_CON(23), 8, 2, DFLAGS, 948 + RK3399_CLKGATE_CON(7), 3, GFLAGS), 949 + COMPOSITE_NOMUX(PCLK_PERILP0, "pclk_perilp0", "aclk_perilp0", 0, 950 + RK3399_CLKSEL_CON(23), 12, 3, DFLAGS, 951 + RK3399_CLKGATE_CON(7), 4, GFLAGS), 952 + 953 + /* aclk_perilp0 gates */ 954 + GATE(ACLK_INTMEM, "aclk_intmem", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 0, GFLAGS), 955 + GATE(ACLK_TZMA, "aclk_tzma", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 1, GFLAGS), 956 + GATE(SCLK_INTMEM0, "clk_intmem0", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 2, GFLAGS), 957 + GATE(SCLK_INTMEM1, "clk_intmem1", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 3, GFLAGS), 958 + GATE(SCLK_INTMEM2, "clk_intmem2", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 4, GFLAGS), 959 + GATE(SCLK_INTMEM3, "clk_intmem3", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 5, GFLAGS), 960 + GATE(SCLK_INTMEM4, "clk_intmem4", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 6, GFLAGS), 961 + GATE(SCLK_INTMEM5, "clk_intmem5", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 7, GFLAGS), 962 + GATE(ACLK_DCF, "aclk_dcf", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 8, GFLAGS), 963 + GATE(ACLK_DMAC0_PERILP, "aclk_dmac0_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 5, GFLAGS), 964 + GATE(ACLK_DMAC1_PERILP, "aclk_dmac1_perilp", "aclk_perilp0", 0, RK3399_CLKGATE_CON(25), 6, GFLAGS), 965 + GATE(ACLK_PERILP0_NOC, "aclk_perilp0_noc", "aclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 7, GFLAGS), 966 + 967 + /* hclk_perilp0 gates */ 968 + GATE(HCLK_ROM, "hclk_rom", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(24), 4, GFLAGS), 969 + GATE(HCLK_M_CRYPTO0, "hclk_m_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 5, GFLAGS), 970 + GATE(HCLK_S_CRYPTO0, "hclk_s_crypto0", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 6, GFLAGS), 971 + GATE(HCLK_M_CRYPTO1, "hclk_m_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 14, GFLAGS), 972 + GATE(HCLK_S_CRYPTO1, "hclk_s_crypto1", "hclk_perilp0", 0, RK3399_CLKGATE_CON(24), 15, GFLAGS), 973 + GATE(HCLK_PERILP0_NOC, "hclk_perilp0_noc", "hclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 8, GFLAGS), 974 + 975 + /* pclk_perilp0 gates */ 976 + GATE(PCLK_DCF, "pclk_dcf", "pclk_perilp0", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(23), 9, GFLAGS), 977 + 978 + /* crypto */ 979 + COMPOSITE(SCLK_CRYPTO0, "clk_crypto0", mux_pll_src_cpll_gpll_ppll_p, 0, 980 + RK3399_CLKSEL_CON(24), 6, 2, MFLAGS, 0, 5, DFLAGS, 981 + RK3399_CLKGATE_CON(7), 7, GFLAGS), 982 + 983 + COMPOSITE(SCLK_CRYPTO1, "clk_crypto1", mux_pll_src_cpll_gpll_ppll_p, 0, 984 + RK3399_CLKSEL_CON(26), 6, 2, MFLAGS, 0, 5, DFLAGS, 985 + RK3399_CLKGATE_CON(7), 8, GFLAGS), 986 + 987 + /* cm0s_perilp */ 988 + GATE(0, "cpll_fclk_cm0s_src", "cpll", 0, 989 + RK3399_CLKGATE_CON(7), 6, GFLAGS), 990 + GATE(0, "gpll_fclk_cm0s_src", "gpll", 0, 991 + RK3399_CLKGATE_CON(7), 5, GFLAGS), 992 + COMPOSITE(FCLK_CM0S, "fclk_cm0s", mux_fclk_cm0s_p, 0, 993 + RK3399_CLKSEL_CON(24), 15, 1, MFLAGS, 8, 5, DFLAGS, 994 + RK3399_CLKGATE_CON(7), 9, GFLAGS), 995 + 996 + /* fclk_cm0s gates */ 997 + GATE(SCLK_M0_PERILP, "sclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 8, GFLAGS), 998 + GATE(HCLK_M0_PERILP, "hclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 9, GFLAGS), 999 + GATE(DCLK_M0_PERILP, "dclk_m0_perilp", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 10, GFLAGS), 1000 + GATE(SCLK_M0_PERILP_DEC, "clk_m0_perilp_dec", "fclk_cm0s", 0, RK3399_CLKGATE_CON(24), 11, GFLAGS), 1001 + GATE(HCLK_M0_PERILP_NOC, "hclk_m0_perilp_noc", "fclk_cm0s", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 11, GFLAGS), 1002 + 1003 + /* perilp1 */ 1004 + GATE(0, "cpll_hclk_perilp1_src", "cpll", CLK_IGNORE_UNUSED, 1005 + RK3399_CLKGATE_CON(8), 1, GFLAGS), 1006 + GATE(0, "gpll_hclk_perilp1_src", "gpll", CLK_IGNORE_UNUSED, 1007 + RK3399_CLKGATE_CON(8), 0, GFLAGS), 1008 + COMPOSITE_NOGATE(HCLK_PERILP1, "hclk_perilp1", mux_hclk_perilp1_p, CLK_IGNORE_UNUSED, 1009 + RK3399_CLKSEL_CON(25), 7, 1, MFLAGS, 0, 5, DFLAGS), 1010 + COMPOSITE_NOMUX(PCLK_PERILP1, "pclk_perilp1", "hclk_perilp1", CLK_IGNORE_UNUSED, 1011 + RK3399_CLKSEL_CON(25), 8, 3, DFLAGS, 1012 + RK3399_CLKGATE_CON(8), 2, GFLAGS), 1013 + 1014 + /* hclk_perilp1 gates */ 1015 + GATE(0, "hclk_perilp1_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 9, GFLAGS), 1016 + GATE(0, "hclk_sdio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(25), 12, GFLAGS), 1017 + GATE(HCLK_I2S0_8CH, "hclk_i2s0", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 0, GFLAGS), 1018 + GATE(HCLK_I2S1_8CH, "hclk_i2s1", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 1, GFLAGS), 1019 + GATE(HCLK_I2S2_8CH, "hclk_i2s2", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 2, GFLAGS), 1020 + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 3, GFLAGS), 1021 + GATE(HCLK_SDIO, "hclk_sdio", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 4, GFLAGS), 1022 + GATE(PCLK_SPI5, "pclk_spi5", "hclk_perilp1", 0, RK3399_CLKGATE_CON(34), 5, GFLAGS), 1023 + GATE(0, "hclk_sdioaudio_noc", "hclk_perilp1", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(34), 6, GFLAGS), 1024 + 1025 + /* pclk_perilp1 gates */ 1026 + GATE(PCLK_UART0, "pclk_uart0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 0, GFLAGS), 1027 + GATE(PCLK_UART1, "pclk_uart1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 1, GFLAGS), 1028 + GATE(PCLK_UART2, "pclk_uart2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 2, GFLAGS), 1029 + GATE(PCLK_UART3, "pclk_uart3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 3, GFLAGS), 1030 + GATE(PCLK_I2C7, "pclk_rki2c7", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 5, GFLAGS), 1031 + GATE(PCLK_I2C1, "pclk_rki2c1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 6, GFLAGS), 1032 + GATE(PCLK_I2C5, "pclk_rki2c5", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 7, GFLAGS), 1033 + GATE(PCLK_I2C6, "pclk_rki2c6", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 8, GFLAGS), 1034 + GATE(PCLK_I2C2, "pclk_rki2c2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 9, GFLAGS), 1035 + GATE(PCLK_I2C3, "pclk_rki2c3", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 10, GFLAGS), 1036 + GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 11, GFLAGS), 1037 + GATE(PCLK_SARADC, "pclk_saradc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 12, GFLAGS), 1038 + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 13, GFLAGS), 1039 + GATE(PCLK_EFUSE1024NS, "pclk_efuse1024ns", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 14, GFLAGS), 1040 + GATE(PCLK_EFUSE1024S, "pclk_efuse1024s", "pclk_perilp1", 0, RK3399_CLKGATE_CON(22), 15, GFLAGS), 1041 + GATE(PCLK_SPI0, "pclk_spi0", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 10, GFLAGS), 1042 + GATE(PCLK_SPI1, "pclk_spi1", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 11, GFLAGS), 1043 + GATE(PCLK_SPI2, "pclk_spi2", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 12, GFLAGS), 1044 + GATE(PCLK_SPI4, "pclk_spi4", "pclk_perilp1", 0, RK3399_CLKGATE_CON(23), 13, GFLAGS), 1045 + GATE(PCLK_PERIHP_GRF, "pclk_perilp_sgrf", "pclk_perilp1", 0, RK3399_CLKGATE_CON(24), 13, GFLAGS), 1046 + GATE(0, "pclk_perilp1_noc", "pclk_perilp1", 0, RK3399_CLKGATE_CON(25), 10, GFLAGS), 1047 + 1048 + /* saradc */ 1049 + COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0, 1050 + RK3399_CLKSEL_CON(26), 8, 8, DFLAGS, 1051 + RK3399_CLKGATE_CON(9), 11, GFLAGS), 1052 + 1053 + /* tsadc */ 1054 + COMPOSITE(SCLK_TSADC, "clk_tsadc", mux_pll_p, 0, 1055 + RK3399_CLKSEL_CON(27), 15, 1, MFLAGS, 0, 10, DFLAGS, 1056 + RK3399_CLKGATE_CON(9), 10, GFLAGS), 1057 + 1058 + /* cif_testout */ 1059 + MUX(0, "clk_testout1_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, 1060 + RK3399_CLKSEL_CON(38), 6, 2, MFLAGS), 1061 + COMPOSITE(0, "clk_testout1", mux_clk_testout1_p, 0, 1062 + RK3399_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, 1063 + RK3399_CLKGATE_CON(13), 14, GFLAGS), 1064 + 1065 + MUX(0, "clk_testout2_pll_src", mux_pll_src_cpll_gpll_npll_p, 0, 1066 + RK3399_CLKSEL_CON(38), 14, 2, MFLAGS), 1067 + COMPOSITE(0, "clk_testout2", mux_clk_testout2_p, 0, 1068 + RK3399_CLKSEL_CON(38), 13, 1, MFLAGS, 8, 5, DFLAGS, 1069 + RK3399_CLKGATE_CON(13), 15, GFLAGS), 1070 + 1071 + /* vio */ 1072 + COMPOSITE(ACLK_VIO, "aclk_vio", mux_pll_src_cpll_gpll_ppll_p, CLK_IGNORE_UNUSED, 1073 + RK3399_CLKSEL_CON(42), 6, 2, MFLAGS, 0, 5, DFLAGS, 1074 + RK3399_CLKGATE_CON(11), 10, GFLAGS), 1075 + COMPOSITE_NOMUX(PCLK_VIO, "pclk_vio", "aclk_vio", 0, 1076 + RK3399_CLKSEL_CON(43), 0, 5, DFLAGS, 1077 + RK3399_CLKGATE_CON(11), 1, GFLAGS), 1078 + 1079 + GATE(ACLK_VIO_NOC, "aclk_vio_noc", "aclk_vio", CLK_IGNORE_UNUSED, 1080 + RK3399_CLKGATE_CON(29), 0, GFLAGS), 1081 + 1082 + GATE(PCLK_MIPI_DSI0, "pclk_mipi_dsi0", "pclk_vio", 0, 1083 + RK3399_CLKGATE_CON(29), 1, GFLAGS), 1084 + GATE(PCLK_MIPI_DSI1, "pclk_mipi_dsi1", "pclk_vio", 0, 1085 + RK3399_CLKGATE_CON(29), 2, GFLAGS), 1086 + GATE(PCLK_VIO_GRF, "pclk_vio_grf", "pclk_vio", CLK_IGNORE_UNUSED, 1087 + RK3399_CLKGATE_CON(29), 12, GFLAGS), 1088 + 1089 + /* hdcp */ 1090 + COMPOSITE(ACLK_HDCP, "aclk_hdcp", mux_pll_src_cpll_gpll_ppll_p, 0, 1091 + RK3399_CLKSEL_CON(42), 14, 2, MFLAGS, 8, 5, DFLAGS, 1092 + RK3399_CLKGATE_CON(11), 12, GFLAGS), 1093 + COMPOSITE_NOMUX(HCLK_HDCP, "hclk_hdcp", "aclk_hdcp", 0, 1094 + RK3399_CLKSEL_CON(43), 5, 5, DFLAGS, 1095 + RK3399_CLKGATE_CON(11), 3, GFLAGS), 1096 + COMPOSITE_NOMUX(PCLK_HDCP, "pclk_hdcp", "aclk_hdcp", 0, 1097 + RK3399_CLKSEL_CON(43), 10, 5, DFLAGS, 1098 + RK3399_CLKGATE_CON(11), 10, GFLAGS), 1099 + 1100 + GATE(ACLK_HDCP_NOC, "aclk_hdcp_noc", "aclk_hdcp", CLK_IGNORE_UNUSED, 1101 + RK3399_CLKGATE_CON(29), 4, GFLAGS), 1102 + GATE(ACLK_HDCP22, "aclk_hdcp22", "aclk_hdcp", 0, 1103 + RK3399_CLKGATE_CON(29), 10, GFLAGS), 1104 + 1105 + GATE(HCLK_HDCP_NOC, "hclk_hdcp_noc", "hclk_hdcp", CLK_IGNORE_UNUSED, 1106 + RK3399_CLKGATE_CON(29), 5, GFLAGS), 1107 + GATE(HCLK_HDCP22, "hclk_hdcp22", "hclk_hdcp", 0, 1108 + RK3399_CLKGATE_CON(29), 9, GFLAGS), 1109 + 1110 + GATE(PCLK_HDCP_NOC, "pclk_hdcp_noc", "pclk_hdcp", CLK_IGNORE_UNUSED, 1111 + RK3399_CLKGATE_CON(29), 3, GFLAGS), 1112 + GATE(PCLK_HDMI_CTRL, "pclk_hdmi_ctrl", "pclk_hdcp", 0, 1113 + RK3399_CLKGATE_CON(29), 6, GFLAGS), 1114 + GATE(PCLK_DP_CTRL, "pclk_dp_ctrl", "pclk_hdcp", 0, 1115 + RK3399_CLKGATE_CON(29), 7, GFLAGS), 1116 + GATE(PCLK_HDCP22, "pclk_hdcp22", "pclk_hdcp", 0, 1117 + RK3399_CLKGATE_CON(29), 8, GFLAGS), 1118 + GATE(PCLK_GASKET, "pclk_gasket", "pclk_hdcp", 0, 1119 + RK3399_CLKGATE_CON(29), 11, GFLAGS), 1120 + 1121 + /* edp */ 1122 + COMPOSITE(SCLK_DP_CORE, "clk_dp_core", mux_pll_src_npll_cpll_gpll_p, 0, 1123 + RK3399_CLKSEL_CON(46), 6, 2, MFLAGS, 0, 5, DFLAGS, 1124 + RK3399_CLKGATE_CON(11), 8, GFLAGS), 1125 + 1126 + COMPOSITE(PCLK_EDP, "pclk_edp", mux_pll_src_cpll_gpll_p, 0, 1127 + RK3399_CLKSEL_CON(44), 15, 1, MFLAGS, 8, 5, DFLAGS, 1128 + RK3399_CLKGATE_CON(11), 11, GFLAGS), 1129 + GATE(PCLK_EDP_NOC, "pclk_edp_noc", "pclk_edp", CLK_IGNORE_UNUSED, 1130 + RK3399_CLKGATE_CON(32), 12, GFLAGS), 1131 + GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_edp", 0, 1132 + RK3399_CLKGATE_CON(32), 13, GFLAGS), 1133 + 1134 + /* hdmi */ 1135 + GATE(SCLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0, 1136 + RK3399_CLKGATE_CON(11), 6, GFLAGS), 1137 + 1138 + COMPOSITE(SCLK_HDMI_CEC, "clk_hdmi_cec", mux_pll_p, 0, 1139 + RK3399_CLKSEL_CON(45), 15, 1, MFLAGS, 0, 10, DFLAGS, 1140 + RK3399_CLKGATE_CON(11), 7, GFLAGS), 1141 + 1142 + /* vop0 */ 1143 + COMPOSITE(ACLK_VOP0_PRE, "aclk_vop0_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0, 1144 + RK3399_CLKSEL_CON(47), 6, 2, MFLAGS, 0, 5, DFLAGS, 1145 + RK3399_CLKGATE_CON(10), 8, GFLAGS), 1146 + COMPOSITE_NOMUX(0, "hclk_vop0_pre", "aclk_vop0_pre", 0, 1147 + RK3399_CLKSEL_CON(47), 8, 5, DFLAGS, 1148 + RK3399_CLKGATE_CON(10), 9, GFLAGS), 1149 + 1150 + GATE(ACLK_VOP0, "aclk_vop0", "aclk_vop0_pre", 0, 1151 + RK3399_CLKGATE_CON(28), 3, GFLAGS), 1152 + GATE(ACLK_VOP0_NOC, "aclk_vop0_noc", "aclk_vop0_pre", CLK_IGNORE_UNUSED, 1153 + RK3399_CLKGATE_CON(28), 1, GFLAGS), 1154 + 1155 + GATE(HCLK_VOP0, "hclk_vop0", "hclk_vop0_pre", 0, 1156 + RK3399_CLKGATE_CON(28), 2, GFLAGS), 1157 + GATE(HCLK_VOP0_NOC, "hclk_vop0_noc", "hclk_vop0_pre", CLK_IGNORE_UNUSED, 1158 + RK3399_CLKGATE_CON(28), 0, GFLAGS), 1159 + 1160 + COMPOSITE(DCLK_VOP0_DIV, "dclk_vop0_div", mux_pll_src_vpll_cpll_gpll_p, 0, 1161 + RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, 1162 + RK3399_CLKGATE_CON(10), 12, GFLAGS), 1163 + 1164 + COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, 1165 + RK3399_CLKSEL_CON(106), 0, 1166 + &rk3399_dclk_vop0_fracmux), 1167 + 1168 + COMPOSITE(SCLK_VOP0_PWM, "clk_vop0_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, 0, 1169 + RK3399_CLKSEL_CON(51), 6, 2, MFLAGS, 0, 5, DFLAGS, 1170 + RK3399_CLKGATE_CON(10), 14, GFLAGS), 1171 + 1172 + /* vop1 */ 1173 + COMPOSITE(ACLK_VOP1_PRE, "aclk_vop1_pre", mux_pll_src_vpll_cpll_gpll_npll_p, 0, 1174 + RK3399_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS, 1175 + RK3399_CLKGATE_CON(10), 10, GFLAGS), 1176 + COMPOSITE_NOMUX(0, "hclk_vop1_pre", "aclk_vop1_pre", 0, 1177 + RK3399_CLKSEL_CON(48), 8, 5, DFLAGS, 1178 + RK3399_CLKGATE_CON(10), 11, GFLAGS), 1179 + 1180 + GATE(ACLK_VOP1, "aclk_vop1", "aclk_vop1_pre", 0, 1181 + RK3399_CLKGATE_CON(28), 7, GFLAGS), 1182 + GATE(ACLK_VOP1_NOC, "aclk_vop1_noc", "aclk_vop1_pre", CLK_IGNORE_UNUSED, 1183 + RK3399_CLKGATE_CON(28), 5, GFLAGS), 1184 + 1185 + GATE(HCLK_VOP1, "hclk_vop1", "hclk_vop1_pre", 0, 1186 + RK3399_CLKGATE_CON(28), 6, GFLAGS), 1187 + GATE(HCLK_VOP1_NOC, "hclk_vop1_noc", "hclk_vop1_pre", CLK_IGNORE_UNUSED, 1188 + RK3399_CLKGATE_CON(28), 4, GFLAGS), 1189 + 1190 + COMPOSITE(DCLK_VOP1_DIV, "dclk_vop1_div", mux_pll_src_vpll_cpll_gpll_p, 0, 1191 + RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS, 1192 + RK3399_CLKGATE_CON(10), 13, GFLAGS), 1193 + 1194 + COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, 1195 + RK3399_CLKSEL_CON(107), 0, 1196 + &rk3399_dclk_vop1_fracmux), 1197 + 1198 + COMPOSITE(SCLK_VOP1_PWM, "clk_vop1_pwm", mux_pll_src_vpll_cpll_gpll_24m_p, CLK_IGNORE_UNUSED, 1199 + RK3399_CLKSEL_CON(52), 6, 2, MFLAGS, 0, 5, DFLAGS, 1200 + RK3399_CLKGATE_CON(10), 15, GFLAGS), 1201 + 1202 + /* isp */ 1203 + COMPOSITE(ACLK_ISP0, "aclk_isp0", mux_pll_src_cpll_gpll_ppll_p, 0, 1204 + RK3399_CLKSEL_CON(53), 6, 2, MFLAGS, 0, 5, DFLAGS, 1205 + RK3399_CLKGATE_CON(12), 8, GFLAGS), 1206 + COMPOSITE_NOMUX(HCLK_ISP0, "hclk_isp0", "aclk_isp0", 0, 1207 + RK3399_CLKSEL_CON(53), 8, 5, DFLAGS, 1208 + RK3399_CLKGATE_CON(12), 9, GFLAGS), 1209 + 1210 + GATE(ACLK_ISP0_NOC, "aclk_isp0_noc", "aclk_isp0", CLK_IGNORE_UNUSED, 1211 + RK3399_CLKGATE_CON(27), 1, GFLAGS), 1212 + GATE(ACLK_ISP0_WRAPPER, "aclk_isp0_wrapper", "aclk_isp0", 0, 1213 + RK3399_CLKGATE_CON(27), 5, GFLAGS), 1214 + GATE(HCLK_ISP1_WRAPPER, "hclk_isp1_wrapper", "aclk_isp0", 0, 1215 + RK3399_CLKGATE_CON(27), 7, GFLAGS), 1216 + 1217 + GATE(HCLK_ISP0_NOC, "hclk_isp0_noc", "hclk_isp0", CLK_IGNORE_UNUSED, 1218 + RK3399_CLKGATE_CON(27), 0, GFLAGS), 1219 + GATE(HCLK_ISP0_WRAPPER, "hclk_isp0_wrapper", "hclk_isp0", 0, 1220 + RK3399_CLKGATE_CON(27), 4, GFLAGS), 1221 + 1222 + COMPOSITE(SCLK_ISP0, "clk_isp0", mux_pll_src_cpll_gpll_npll_p, 0, 1223 + RK3399_CLKSEL_CON(55), 6, 2, MFLAGS, 0, 5, DFLAGS, 1224 + RK3399_CLKGATE_CON(11), 4, GFLAGS), 1225 + 1226 + COMPOSITE(ACLK_ISP1, "aclk_isp1", mux_pll_src_cpll_gpll_ppll_p, 0, 1227 + RK3399_CLKSEL_CON(54), 6, 2, MFLAGS, 0, 5, DFLAGS, 1228 + RK3399_CLKGATE_CON(12), 10, GFLAGS), 1229 + COMPOSITE_NOMUX(HCLK_ISP1, "hclk_isp1", "aclk_isp1", 0, 1230 + RK3399_CLKSEL_CON(54), 8, 5, DFLAGS, 1231 + RK3399_CLKGATE_CON(12), 11, GFLAGS), 1232 + 1233 + GATE(ACLK_ISP1_NOC, "aclk_isp1_noc", "aclk_isp1", CLK_IGNORE_UNUSED, 1234 + RK3399_CLKGATE_CON(27), 3, GFLAGS), 1235 + 1236 + GATE(HCLK_ISP1_NOC, "hclk_isp1_noc", "hclk_isp1", CLK_IGNORE_UNUSED, 1237 + RK3399_CLKGATE_CON(27), 2, GFLAGS), 1238 + GATE(ACLK_ISP1_WRAPPER, "aclk_isp1_wrapper", "hclk_isp1", 0, 1239 + RK3399_CLKGATE_CON(27), 8, GFLAGS), 1240 + 1241 + COMPOSITE(SCLK_ISP1, "clk_isp1", mux_pll_src_cpll_gpll_npll_p, 0, 1242 + RK3399_CLKSEL_CON(55), 14, 2, MFLAGS, 8, 5, DFLAGS, 1243 + RK3399_CLKGATE_CON(11), 5, GFLAGS), 1244 + 1245 + /* 1246 + * We use pclkin_cifinv by default GRF_SOC_CON20[9] (GSC20_9) setting in system, 1247 + * so we ignore the mux and make clocks nodes as following, 1248 + * 1249 + * pclkin_cifinv --|-------\ 1250 + * |GSC20_9|-- pclkin_cifmux -- |G27_6| -- pclkin_isp1_wrapper 1251 + * pclkin_cif --|-------/ 1252 + */ 1253 + GATE(PCLK_ISP1_WRAPPER, "pclkin_isp1_wrapper", "pclkin_cif", 0, 1254 + RK3399_CLKGATE_CON(27), 6, GFLAGS), 1255 + 1256 + /* cif */ 1257 + COMPOSITE_NODIV(0, "clk_cifout_src", mux_pll_src_cpll_gpll_npll_p, 0, 1258 + RK3399_CLKSEL_CON(56), 6, 2, MFLAGS, 1259 + RK3399_CLKGATE_CON(10), 7, GFLAGS), 1260 + 1261 + COMPOSITE_NOGATE(SCLK_CIF_OUT, "clk_cifout", mux_clk_cif_p, 0, 1262 + RK3399_CLKSEL_CON(56), 5, 1, MFLAGS, 0, 5, DFLAGS), 1263 + 1264 + /* gic */ 1265 + COMPOSITE(ACLK_GIC_PRE, "aclk_gic_pre", mux_pll_src_cpll_gpll_p, CLK_IGNORE_UNUSED, 1266 + RK3399_CLKSEL_CON(56), 15, 1, MFLAGS, 8, 5, DFLAGS, 1267 + RK3399_CLKGATE_CON(12), 12, GFLAGS), 1268 + 1269 + GATE(ACLK_GIC, "aclk_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 0, GFLAGS), 1270 + GATE(ACLK_GIC_NOC, "aclk_gic_noc", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 1, GFLAGS), 1271 + GATE(ACLK_GIC_ADB400_CORE_L_2_GIC, "aclk_gic_adb400_core_l_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 2, GFLAGS), 1272 + GATE(ACLK_GIC_ADB400_CORE_B_2_GIC, "aclk_gic_adb400_core_b_2_gic", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 3, GFLAGS), 1273 + GATE(ACLK_GIC_ADB400_GIC_2_CORE_L, "aclk_gic_adb400_gic_2_core_l", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 4, GFLAGS), 1274 + GATE(ACLK_GIC_ADB400_GIC_2_CORE_B, "aclk_gic_adb400_gic_2_core_b", "aclk_gic_pre", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(33), 5, GFLAGS), 1275 + 1276 + /* alive */ 1277 + /* pclk_alive_gpll_src is controlled by PMUGRF_SOC_CON0[6] */ 1278 + DIV(PCLK_ALIVE, "pclk_alive", "gpll", 0, 1279 + RK3399_CLKSEL_CON(57), 0, 5, DFLAGS), 1280 + 1281 + GATE(PCLK_USBPHY_MUX_G, "pclk_usbphy_mux_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 4, GFLAGS), 1282 + GATE(PCLK_UPHY0_TCPHY_G, "pclk_uphy0_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 5, GFLAGS), 1283 + GATE(PCLK_UPHY0_TCPD_G, "pclk_uphy0_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 6, GFLAGS), 1284 + GATE(PCLK_UPHY1_TCPHY_G, "pclk_uphy1_tcphy_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 8, GFLAGS), 1285 + GATE(PCLK_UPHY1_TCPD_G, "pclk_uphy1_tcpd_g", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 9, GFLAGS), 1286 + 1287 + GATE(PCLK_GRF, "pclk_grf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 1, GFLAGS), 1288 + GATE(PCLK_INTR_ARB, "pclk_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 2, GFLAGS), 1289 + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 3, GFLAGS), 1290 + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 4, GFLAGS), 1291 + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 5, GFLAGS), 1292 + GATE(PCLK_TIMER0, "pclk_timer0", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 6, GFLAGS), 1293 + GATE(PCLK_TIMER1, "pclk_timer1", "pclk_alive", 0, RK3399_CLKGATE_CON(31), 7, GFLAGS), 1294 + GATE(PCLK_PMU_INTR_ARB, "pclk_pmu_intr_arb", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 9, GFLAGS), 1295 + GATE(PCLK_SGRF, "pclk_sgrf", "pclk_alive", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(31), 10, GFLAGS), 1296 + 1297 + GATE(SCLK_MIPIDPHY_REF, "clk_mipidphy_ref", "xin24m", 0, RK3399_CLKGATE_CON(11), 14, GFLAGS), 1298 + GATE(SCLK_DPHY_PLL, "clk_dphy_pll", "clk_mipidphy_ref", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 0, GFLAGS), 1299 + 1300 + GATE(SCLK_MIPIDPHY_CFG, "clk_mipidphy_cfg", "xin24m", 0, RK3399_CLKGATE_CON(11), 15, GFLAGS), 1301 + GATE(SCLK_DPHY_TX0_CFG, "clk_dphy_tx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 1, GFLAGS), 1302 + GATE(SCLK_DPHY_TX1RX1_CFG, "clk_dphy_tx1rx1_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 2, GFLAGS), 1303 + GATE(SCLK_DPHY_RX0_CFG, "clk_dphy_rx0_cfg", "clk_mipidphy_cfg", CLK_IGNORE_UNUSED, RK3399_CLKGATE_CON(21), 3, GFLAGS), 1304 + 1305 + /* testout */ 1306 + MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, 1307 + RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), 1308 + COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, 1309 + RK3399_CLKSEL_CON(105), 0, 1310 + RK3399_CLKGATE_CON(13), 9, GFLAGS), 1311 + 1312 + DIV(0, "clk_test_24m", "xin24m", 0, 1313 + RK3399_CLKSEL_CON(57), 6, 10, DFLAGS), 1314 + 1315 + /* spi */ 1316 + COMPOSITE(SCLK_SPI0, "clk_spi0", mux_pll_src_cpll_gpll_p, 0, 1317 + RK3399_CLKSEL_CON(59), 7, 1, MFLAGS, 0, 7, DFLAGS, 1318 + RK3399_CLKGATE_CON(9), 12, GFLAGS), 1319 + 1320 + COMPOSITE(SCLK_SPI1, "clk_spi1", mux_pll_src_cpll_gpll_p, 0, 1321 + RK3399_CLKSEL_CON(59), 15, 1, MFLAGS, 8, 7, DFLAGS, 1322 + RK3399_CLKGATE_CON(9), 13, GFLAGS), 1323 + 1324 + COMPOSITE(SCLK_SPI2, "clk_spi2", mux_pll_src_cpll_gpll_p, 0, 1325 + RK3399_CLKSEL_CON(60), 7, 1, MFLAGS, 0, 7, DFLAGS, 1326 + RK3399_CLKGATE_CON(9), 14, GFLAGS), 1327 + 1328 + COMPOSITE(SCLK_SPI4, "clk_spi4", mux_pll_src_cpll_gpll_p, 0, 1329 + RK3399_CLKSEL_CON(60), 15, 1, MFLAGS, 8, 7, DFLAGS, 1330 + RK3399_CLKGATE_CON(9), 15, GFLAGS), 1331 + 1332 + COMPOSITE(SCLK_SPI5, "clk_spi5", mux_pll_src_cpll_gpll_p, 0, 1333 + RK3399_CLKSEL_CON(58), 15, 1, MFLAGS, 8, 7, DFLAGS, 1334 + RK3399_CLKGATE_CON(13), 13, GFLAGS), 1335 + 1336 + /* i2c */ 1337 + COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_pll_src_cpll_gpll_p, 0, 1338 + RK3399_CLKSEL_CON(61), 7, 1, MFLAGS, 0, 7, DFLAGS, 1339 + RK3399_CLKGATE_CON(10), 0, GFLAGS), 1340 + 1341 + COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_pll_src_cpll_gpll_p, 0, 1342 + RK3399_CLKSEL_CON(62), 7, 1, MFLAGS, 0, 7, DFLAGS, 1343 + RK3399_CLKGATE_CON(10), 2, GFLAGS), 1344 + 1345 + COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_pll_src_cpll_gpll_p, 0, 1346 + RK3399_CLKSEL_CON(63), 7, 1, MFLAGS, 0, 7, DFLAGS, 1347 + RK3399_CLKGATE_CON(10), 4, GFLAGS), 1348 + 1349 + COMPOSITE(SCLK_I2C5, "clk_i2c5", mux_pll_src_cpll_gpll_p, 0, 1350 + RK3399_CLKSEL_CON(61), 15, 1, MFLAGS, 8, 7, DFLAGS, 1351 + RK3399_CLKGATE_CON(10), 1, GFLAGS), 1352 + 1353 + COMPOSITE(SCLK_I2C6, "clk_i2c6", mux_pll_src_cpll_gpll_p, 0, 1354 + RK3399_CLKSEL_CON(62), 15, 1, MFLAGS, 8, 7, DFLAGS, 1355 + RK3399_CLKGATE_CON(10), 3, GFLAGS), 1356 + 1357 + COMPOSITE(SCLK_I2C7, "clk_i2c7", mux_pll_src_cpll_gpll_p, 0, 1358 + RK3399_CLKSEL_CON(63), 15, 1, MFLAGS, 8, 7, DFLAGS, 1359 + RK3399_CLKGATE_CON(10), 5, GFLAGS), 1360 + 1361 + /* timer */ 1362 + GATE(SCLK_TIMER00, "clk_timer00", "xin24m", 0, RK3399_CLKGATE_CON(26), 0, GFLAGS), 1363 + GATE(SCLK_TIMER01, "clk_timer01", "xin24m", 0, RK3399_CLKGATE_CON(26), 1, GFLAGS), 1364 + GATE(SCLK_TIMER02, "clk_timer02", "xin24m", 0, RK3399_CLKGATE_CON(26), 2, GFLAGS), 1365 + GATE(SCLK_TIMER03, "clk_timer03", "xin24m", 0, RK3399_CLKGATE_CON(26), 3, GFLAGS), 1366 + GATE(SCLK_TIMER04, "clk_timer04", "xin24m", 0, RK3399_CLKGATE_CON(26), 4, GFLAGS), 1367 + GATE(SCLK_TIMER05, "clk_timer05", "xin24m", 0, RK3399_CLKGATE_CON(26), 5, GFLAGS), 1368 + GATE(SCLK_TIMER06, "clk_timer06", "xin24m", 0, RK3399_CLKGATE_CON(26), 6, GFLAGS), 1369 + GATE(SCLK_TIMER07, "clk_timer07", "xin24m", 0, RK3399_CLKGATE_CON(26), 7, GFLAGS), 1370 + GATE(SCLK_TIMER08, "clk_timer08", "xin24m", 0, RK3399_CLKGATE_CON(26), 8, GFLAGS), 1371 + GATE(SCLK_TIMER09, "clk_timer09", "xin24m", 0, RK3399_CLKGATE_CON(26), 9, GFLAGS), 1372 + GATE(SCLK_TIMER10, "clk_timer10", "xin24m", 0, RK3399_CLKGATE_CON(26), 10, GFLAGS), 1373 + GATE(SCLK_TIMER11, "clk_timer11", "xin24m", 0, RK3399_CLKGATE_CON(26), 11, GFLAGS), 1374 + 1375 + /* clk_test */ 1376 + /* clk_test_pre is controlled by CRU_MISC_CON[3] */ 1377 + COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED, 1378 + RK3368_CLKSEL_CON(58), 0, 5, DFLAGS, 1379 + RK3368_CLKGATE_CON(13), 11, GFLAGS), 1380 + }; 1381 + 1382 + static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { 1383 + /* 1384 + * PMU CRU Clock-Architecture 1385 + */ 1386 + 1387 + GATE(0, "fclk_cm0s_pmu_ppll_src", "ppll", 0, 1388 + RK3399_PMU_CLKGATE_CON(0), 1, GFLAGS), 1389 + 1390 + COMPOSITE_NOGATE(FCLK_CM0S_SRC_PMU, "fclk_cm0s_src_pmu", mux_fclk_cm0s_pmu_ppll_p, 0, 1391 + RK3399_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 8, 5, DFLAGS), 1392 + 1393 + COMPOSITE(SCLK_SPI3_PMU, "clk_spi3_pmu", mux_24m_ppll_p, 0, 1394 + RK3399_PMU_CLKSEL_CON(1), 7, 1, MFLAGS, 0, 7, DFLAGS, 1395 + RK3399_PMU_CLKGATE_CON(0), 2, GFLAGS), 1396 + 1397 + COMPOSITE(0, "clk_wifi_div", mux_ppll_24m_p, CLK_IGNORE_UNUSED, 1398 + RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, 1399 + RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), 1400 + 1401 + COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, 1402 + RK3399_PMU_CLKSEL_CON(7), 0, 1403 + &rk3399_pmuclk_wifi_fracmux), 1404 + 1405 + MUX(0, "clk_timer_src_pmu", mux_pll_p, CLK_IGNORE_UNUSED, 1406 + RK3399_PMU_CLKSEL_CON(1), 15, 1, MFLAGS), 1407 + 1408 + COMPOSITE_NOMUX(SCLK_I2C0_PMU, "clk_i2c0_pmu", "ppll", 0, 1409 + RK3399_PMU_CLKSEL_CON(2), 0, 7, DFLAGS, 1410 + RK3399_PMU_CLKGATE_CON(0), 9, GFLAGS), 1411 + 1412 + COMPOSITE_NOMUX(SCLK_I2C4_PMU, "clk_i2c4_pmu", "ppll", 0, 1413 + RK3399_PMU_CLKSEL_CON(3), 0, 7, DFLAGS, 1414 + RK3399_PMU_CLKGATE_CON(0), 10, GFLAGS), 1415 + 1416 + COMPOSITE_NOMUX(SCLK_I2C8_PMU, "clk_i2c8_pmu", "ppll", 0, 1417 + RK3399_PMU_CLKSEL_CON(2), 8, 7, DFLAGS, 1418 + RK3399_PMU_CLKGATE_CON(0), 11, GFLAGS), 1419 + 1420 + DIV(0, "clk_32k_suspend_pmu", "xin24m", CLK_IGNORE_UNUSED, 1421 + RK3399_PMU_CLKSEL_CON(4), 0, 10, DFLAGS), 1422 + MUX(0, "clk_testout_2io", mux_clk_testout2_2io_p, CLK_IGNORE_UNUSED, 1423 + RK3399_PMU_CLKSEL_CON(4), 15, 1, MFLAGS), 1424 + 1425 + COMPOSITE(0, "clk_uart4_div", mux_24m_ppll_p, 0, 1426 + RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS, 1427 + RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), 1428 + 1429 + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, 1430 + RK3399_PMU_CLKSEL_CON(6), 0, 1431 + RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, 1432 + &rk3399_uart4_pmu_fracmux), 1433 + 1434 + DIV(PCLK_SRC_PMU, "pclk_pmu_src", "ppll", CLK_IGNORE_UNUSED, 1435 + RK3399_PMU_CLKSEL_CON(0), 0, 5, DFLAGS), 1436 + 1437 + /* pmu clock gates */ 1438 + GATE(SCLK_TIMER12_PMU, "clk_timer0_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 3, GFLAGS), 1439 + GATE(SCLK_TIMER13_PMU, "clk_timer1_pmu", "clk_timer_src_pmu", 0, RK3399_PMU_CLKGATE_CON(0), 4, GFLAGS), 1440 + 1441 + GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(0), 7, GFLAGS), 1442 + 1443 + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 0, GFLAGS), 1444 + GATE(PCLK_PMUGRF_PMU, "pclk_pmugrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 1, GFLAGS), 1445 + GATE(PCLK_INTMEM1_PMU, "pclk_intmem1_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 2, GFLAGS), 1446 + GATE(PCLK_GPIO0_PMU, "pclk_gpio0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 3, GFLAGS), 1447 + GATE(PCLK_GPIO1_PMU, "pclk_gpio1_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 4, GFLAGS), 1448 + GATE(PCLK_SGRF_PMU, "pclk_sgrf_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 5, GFLAGS), 1449 + GATE(PCLK_NOC_PMU, "pclk_noc_pmu", "pclk_pmu_src", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(1), 6, GFLAGS), 1450 + GATE(PCLK_I2C0_PMU, "pclk_i2c0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 7, GFLAGS), 1451 + GATE(PCLK_I2C4_PMU, "pclk_i2c4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 8, GFLAGS), 1452 + GATE(PCLK_I2C8_PMU, "pclk_i2c8_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 9, GFLAGS), 1453 + GATE(PCLK_RKPWM_PMU, "pclk_rkpwm_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 10, GFLAGS), 1454 + GATE(PCLK_SPI3_PMU, "pclk_spi3_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 11, GFLAGS), 1455 + GATE(PCLK_TIMER_PMU, "pclk_timer_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 12, GFLAGS), 1456 + GATE(PCLK_MAILBOX_PMU, "pclk_mailbox_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 13, GFLAGS), 1457 + GATE(PCLK_UART4_PMU, "pclk_uart4_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 14, GFLAGS), 1458 + GATE(PCLK_WDT_M0_PMU, "pclk_wdt_m0_pmu", "pclk_pmu_src", 0, RK3399_PMU_CLKGATE_CON(1), 15, GFLAGS), 1459 + 1460 + GATE(FCLK_CM0S_PMU, "fclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 0, GFLAGS), 1461 + GATE(SCLK_CM0S_PMU, "sclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 1, GFLAGS), 1462 + GATE(HCLK_CM0S_PMU, "hclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 2, GFLAGS), 1463 + GATE(DCLK_CM0S_PMU, "dclk_cm0s_pmu", "fclk_cm0s_src_pmu", 0, RK3399_PMU_CLKGATE_CON(2), 3, GFLAGS), 1464 + GATE(HCLK_NOC_PMU, "hclk_noc_pmu", "fclk_cm0s_src_pmu", CLK_IGNORE_UNUSED, RK3399_PMU_CLKGATE_CON(2), 5, GFLAGS), 1465 + }; 1466 + 1467 + static const char *const rk3399_cru_critical_clocks[] __initconst = { 1468 + "aclk_cci_pre", 1469 + "pclk_perilp0", 1470 + "pclk_perilp0", 1471 + "hclk_perilp0", 1472 + "hclk_perilp0_noc", 1473 + "pclk_perilp1", 1474 + "pclk_perilp1_noc", 1475 + "pclk_perihp", 1476 + "pclk_perihp_noc", 1477 + "hclk_perihp", 1478 + "aclk_perihp", 1479 + "aclk_perihp_noc", 1480 + "aclk_perilp0", 1481 + "aclk_perilp0_noc", 1482 + "hclk_perilp1", 1483 + "hclk_perilp1_noc", 1484 + "aclk_dmac0_perilp", 1485 + "gpll_hclk_perilp1_src", 1486 + "gpll_aclk_perilp0_src", 1487 + "gpll_aclk_perihp_src", 1488 + }; 1489 + 1490 + static const char *const rk3399_pmucru_critical_clocks[] __initconst = { 1491 + "ppll", 1492 + "pclk_pmu_src", 1493 + "fclk_cm0s_src_pmu", 1494 + "clk_timer_src_pmu", 1495 + }; 1496 + 1497 + static void __init rk3399_clk_init(struct device_node *np) 1498 + { 1499 + struct rockchip_clk_provider *ctx; 1500 + void __iomem *reg_base; 1501 + 1502 + reg_base = of_iomap(np, 0); 1503 + if (!reg_base) { 1504 + pr_err("%s: could not map cru region\n", __func__); 1505 + return; 1506 + } 1507 + 1508 + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); 1509 + if (IS_ERR(ctx)) { 1510 + pr_err("%s: rockchip clk init failed\n", __func__); 1511 + return; 1512 + } 1513 + 1514 + rockchip_clk_register_plls(ctx, rk3399_pll_clks, 1515 + ARRAY_SIZE(rk3399_pll_clks), -1); 1516 + 1517 + rockchip_clk_register_branches(ctx, rk3399_clk_branches, 1518 + ARRAY_SIZE(rk3399_clk_branches)); 1519 + 1520 + rockchip_clk_protect_critical(rk3399_cru_critical_clocks, 1521 + ARRAY_SIZE(rk3399_cru_critical_clocks)); 1522 + 1523 + rockchip_clk_register_armclk(ctx, ARMCLKL, "armclkl", 1524 + mux_armclkl_p, ARRAY_SIZE(mux_armclkl_p), 1525 + &rk3399_cpuclkl_data, rk3399_cpuclkl_rates, 1526 + ARRAY_SIZE(rk3399_cpuclkl_rates)); 1527 + 1528 + rockchip_clk_register_armclk(ctx, ARMCLKB, "armclkb", 1529 + mux_armclkb_p, ARRAY_SIZE(mux_armclkb_p), 1530 + &rk3399_cpuclkb_data, rk3399_cpuclkb_rates, 1531 + ARRAY_SIZE(rk3399_cpuclkb_rates)); 1532 + 1533 + rockchip_register_softrst(np, 21, reg_base + RK3399_SOFTRST_CON(0), 1534 + ROCKCHIP_SOFTRST_HIWORD_MASK); 1535 + 1536 + rockchip_register_restart_notifier(ctx, RK3399_GLB_SRST_FST, NULL); 1537 + 1538 + rockchip_clk_of_add_provider(np, ctx); 1539 + } 1540 + CLK_OF_DECLARE(rk3399_cru, "rockchip,rk3399-cru", rk3399_clk_init); 1541 + 1542 + static void __init rk3399_pmu_clk_init(struct device_node *np) 1543 + { 1544 + struct rockchip_clk_provider *ctx; 1545 + void __iomem *reg_base; 1546 + 1547 + reg_base = of_iomap(np, 0); 1548 + if (!reg_base) { 1549 + pr_err("%s: could not map cru pmu region\n", __func__); 1550 + return; 1551 + } 1552 + 1553 + ctx = rockchip_clk_init(np, reg_base, CLKPMU_NR_CLKS); 1554 + if (IS_ERR(ctx)) { 1555 + pr_err("%s: rockchip pmu clk init failed\n", __func__); 1556 + return; 1557 + } 1558 + 1559 + rockchip_clk_register_plls(ctx, rk3399_pmu_pll_clks, 1560 + ARRAY_SIZE(rk3399_pmu_pll_clks), -1); 1561 + 1562 + rockchip_clk_register_branches(ctx, rk3399_clk_pmu_branches, 1563 + ARRAY_SIZE(rk3399_clk_pmu_branches)); 1564 + 1565 + rockchip_clk_protect_critical(rk3399_pmucru_critical_clocks, 1566 + ARRAY_SIZE(rk3399_pmucru_critical_clocks)); 1567 + 1568 + rockchip_register_softrst(np, 2, reg_base + RK3399_PMU_SOFTRST_CON(0), 1569 + ROCKCHIP_SOFTRST_HIWORD_MASK); 1570 + 1571 + rockchip_clk_of_add_provider(np, ctx); 1572 + } 1573 + CLK_OF_DECLARE(rk3399_cru_pmu, "rockchip,rk3399-pmucru", rk3399_pmu_clk_init);
+92 -59
drivers/clk/rockchip/clk.c
··· 2 2 * Copyright (c) 2014 MundoReader S.L. 3 3 * Author: Heiko Stuebner <heiko@sntech.de> 4 4 * 5 + * Copyright (c) 2016 Rockchip Electronics Co. Ltd. 6 + * Author: Xing Zheng <zhengxing@rock-chips.com> 7 + * 5 8 * based on 6 9 * 7 10 * samsung/clk.c ··· 42 39 * sometimes without one of those components. 43 40 */ 44 41 static struct clk *rockchip_clk_register_branch(const char *name, 45 - const char *const *parent_names, u8 num_parents, void __iomem *base, 42 + const char *const *parent_names, u8 num_parents, 43 + void __iomem *base, 46 44 int muxdiv_offset, u8 mux_shift, u8 mux_width, u8 mux_flags, 47 45 u8 div_shift, u8 div_width, u8 div_flags, 48 46 struct clk_div_table *div_table, int gate_offset, ··· 140 136 pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n", 141 137 __func__, event, ndata->old_rate, ndata->new_rate); 142 138 if (event == PRE_RATE_CHANGE) { 143 - frac->rate_change_idx = frac->mux_ops->get_parent(&frac_mux->hw); 139 + frac->rate_change_idx = 140 + frac->mux_ops->get_parent(&frac_mux->hw); 144 141 if (frac->rate_change_idx != frac->mux_frac_idx) { 145 - frac->mux_ops->set_parent(&frac_mux->hw, frac->mux_frac_idx); 142 + frac->mux_ops->set_parent(&frac_mux->hw, 143 + frac->mux_frac_idx); 146 144 frac->rate_change_remuxed = 1; 147 145 } 148 146 } else if (event == POST_RATE_CHANGE) { ··· 155 149 * reaches the mux itself. 156 150 */ 157 151 if (frac->rate_change_remuxed) { 158 - frac->mux_ops->set_parent(&frac_mux->hw, frac->rate_change_idx); 152 + frac->mux_ops->set_parent(&frac_mux->hw, 153 + frac->rate_change_idx); 159 154 frac->rate_change_remuxed = 0; 160 155 } 161 156 } ··· 164 157 return notifier_from_errno(ret); 165 158 } 166 159 167 - static struct clk *rockchip_clk_register_frac_branch(const char *name, 160 + static struct clk *rockchip_clk_register_frac_branch( 161 + struct rockchip_clk_provider *ctx, const char *name, 168 162 const char *const *parent_names, u8 num_parents, 169 163 void __iomem *base, int muxdiv_offset, u8 div_flags, 170 164 int gate_offset, u8 gate_shift, u8 gate_flags, ··· 258 250 if (IS_ERR(mux_clk)) 259 251 return clk; 260 252 261 - rockchip_clk_add_lookup(mux_clk, child->id); 253 + rockchip_clk_add_lookup(ctx, mux_clk, child->id); 262 254 263 255 /* notifier on the fraction divider to catch rate changes */ 264 256 if (frac->mux_frac_idx >= 0) { ··· 322 314 return clk; 323 315 } 324 316 325 - static DEFINE_SPINLOCK(clk_lock); 326 - static struct clk **clk_table; 327 - static void __iomem *reg_base; 328 - static struct clk_onecell_data clk_data; 329 - static struct device_node *cru_node; 330 - static struct regmap *grf; 331 - 332 - void __init rockchip_clk_init(struct device_node *np, void __iomem *base, 333 - unsigned long nr_clks) 317 + struct rockchip_clk_provider * __init rockchip_clk_init(struct device_node *np, 318 + void __iomem *base, unsigned long nr_clks) 334 319 { 335 - reg_base = base; 336 - cru_node = np; 337 - grf = ERR_PTR(-EPROBE_DEFER); 320 + struct rockchip_clk_provider *ctx; 321 + struct clk **clk_table; 322 + int i; 323 + 324 + ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); 325 + if (!ctx) 326 + return ERR_PTR(-ENOMEM); 338 327 339 328 clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); 340 329 if (!clk_table) 341 - pr_err("%s: could not allocate clock lookup table\n", __func__); 330 + goto err_free; 342 331 343 - clk_data.clks = clk_table; 344 - clk_data.clk_num = nr_clks; 345 - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); 332 + for (i = 0; i < nr_clks; ++i) 333 + clk_table[i] = ERR_PTR(-ENOENT); 334 + 335 + ctx->reg_base = base; 336 + ctx->clk_data.clks = clk_table; 337 + ctx->clk_data.clk_num = nr_clks; 338 + ctx->cru_node = np; 339 + ctx->grf = ERR_PTR(-EPROBE_DEFER); 340 + spin_lock_init(&ctx->lock); 341 + 342 + ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node, 343 + "rockchip,grf"); 344 + 345 + return ctx; 346 + 347 + err_free: 348 + kfree(ctx); 349 + return ERR_PTR(-ENOMEM); 346 350 } 347 351 348 - struct regmap *rockchip_clk_get_grf(void) 352 + void __init rockchip_clk_of_add_provider(struct device_node *np, 353 + struct rockchip_clk_provider *ctx) 349 354 { 350 - if (IS_ERR(grf)) 351 - grf = syscon_regmap_lookup_by_phandle(cru_node, "rockchip,grf"); 352 - return grf; 355 + if (of_clk_add_provider(np, of_clk_src_onecell_get, 356 + &ctx->clk_data)) 357 + pr_err("%s: could not register clk provider\n", __func__); 353 358 } 354 359 355 - void rockchip_clk_add_lookup(struct clk *clk, unsigned int id) 360 + void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 361 + struct clk *clk, unsigned int id) 356 362 { 357 - if (clk_table && id) 358 - clk_table[id] = clk; 363 + if (ctx->clk_data.clks && id) 364 + ctx->clk_data.clks[id] = clk; 359 365 } 360 366 361 - void __init rockchip_clk_register_plls(struct rockchip_pll_clock *list, 367 + void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 368 + struct rockchip_pll_clock *list, 362 369 unsigned int nr_pll, int grf_lock_offset) 363 370 { 364 371 struct clk *clk; 365 372 int idx; 366 373 367 374 for (idx = 0; idx < nr_pll; idx++, list++) { 368 - clk = rockchip_clk_register_pll(list->type, list->name, 375 + clk = rockchip_clk_register_pll(ctx, list->type, list->name, 369 376 list->parent_names, list->num_parents, 370 - reg_base, list->con_offset, grf_lock_offset, 377 + list->con_offset, grf_lock_offset, 371 378 list->lock_shift, list->mode_offset, 372 379 list->mode_shift, list->rate_table, 373 - list->pll_flags, &clk_lock); 380 + list->pll_flags); 374 381 if (IS_ERR(clk)) { 375 382 pr_err("%s: failed to register clock %s\n", __func__, 376 383 list->name); 377 384 continue; 378 385 } 379 386 380 - rockchip_clk_add_lookup(clk, list->id); 387 + rockchip_clk_add_lookup(ctx, clk, list->id); 381 388 } 382 389 } 383 390 384 391 void __init rockchip_clk_register_branches( 392 + struct rockchip_clk_provider *ctx, 385 393 struct rockchip_clk_branch *list, 386 394 unsigned int nr_clk) 387 395 { ··· 413 389 case branch_mux: 414 390 clk = clk_register_mux(NULL, list->name, 415 391 list->parent_names, list->num_parents, 416 - flags, reg_base + list->muxdiv_offset, 392 + flags, ctx->reg_base + list->muxdiv_offset, 417 393 list->mux_shift, list->mux_width, 418 - list->mux_flags, &clk_lock); 394 + list->mux_flags, &ctx->lock); 419 395 break; 420 396 case branch_divider: 421 397 if (list->div_table) 422 398 clk = clk_register_divider_table(NULL, 423 399 list->name, list->parent_names[0], 424 - flags, reg_base + list->muxdiv_offset, 400 + flags, 401 + ctx->reg_base + list->muxdiv_offset, 425 402 list->div_shift, list->div_width, 426 403 list->div_flags, list->div_table, 427 - &clk_lock); 404 + &ctx->lock); 428 405 else 429 406 clk = clk_register_divider(NULL, list->name, 430 407 list->parent_names[0], flags, 431 - reg_base + list->muxdiv_offset, 408 + ctx->reg_base + list->muxdiv_offset, 432 409 list->div_shift, list->div_width, 433 - list->div_flags, &clk_lock); 410 + list->div_flags, &ctx->lock); 434 411 break; 435 412 case branch_fraction_divider: 436 - clk = rockchip_clk_register_frac_branch(list->name, 413 + clk = rockchip_clk_register_frac_branch(ctx, list->name, 437 414 list->parent_names, list->num_parents, 438 - reg_base, list->muxdiv_offset, list->div_flags, 415 + ctx->reg_base, list->muxdiv_offset, 416 + list->div_flags, 439 417 list->gate_offset, list->gate_shift, 440 418 list->gate_flags, flags, list->child, 441 - &clk_lock); 419 + &ctx->lock); 442 420 break; 443 421 case branch_gate: 444 422 flags |= CLK_SET_RATE_PARENT; 445 423 446 424 clk = clk_register_gate(NULL, list->name, 447 425 list->parent_names[0], flags, 448 - reg_base + list->gate_offset, 449 - list->gate_shift, list->gate_flags, &clk_lock); 426 + ctx->reg_base + list->gate_offset, 427 + list->gate_shift, list->gate_flags, &ctx->lock); 450 428 break; 451 429 case branch_composite: 452 430 clk = rockchip_clk_register_branch(list->name, 453 431 list->parent_names, list->num_parents, 454 - reg_base, list->muxdiv_offset, list->mux_shift, 432 + ctx->reg_base, list->muxdiv_offset, 433 + list->mux_shift, 455 434 list->mux_width, list->mux_flags, 456 435 list->div_shift, list->div_width, 457 436 list->div_flags, list->div_table, 458 437 list->gate_offset, list->gate_shift, 459 - list->gate_flags, flags, &clk_lock); 438 + list->gate_flags, flags, &ctx->lock); 460 439 break; 461 440 case branch_mmc: 462 441 clk = rockchip_clk_register_mmc( 463 442 list->name, 464 443 list->parent_names, list->num_parents, 465 - reg_base + list->muxdiv_offset, 444 + ctx->reg_base + list->muxdiv_offset, 466 445 list->div_shift 467 446 ); 468 447 break; ··· 473 446 clk = rockchip_clk_register_inverter( 474 447 list->name, list->parent_names, 475 448 list->num_parents, 476 - reg_base + list->muxdiv_offset, 477 - list->div_shift, list->div_flags, &clk_lock); 449 + ctx->reg_base + list->muxdiv_offset, 450 + list->div_shift, list->div_flags, &ctx->lock); 478 451 break; 479 452 case branch_factor: 480 453 clk = rockchip_clk_register_factor_branch( 481 454 list->name, list->parent_names, 482 - list->num_parents, reg_base, 455 + list->num_parents, ctx->reg_base, 483 456 list->div_shift, list->div_width, 484 457 list->gate_offset, list->gate_shift, 485 - list->gate_flags, flags, &clk_lock); 458 + list->gate_flags, flags, &ctx->lock); 486 459 break; 487 460 } 488 461 ··· 499 472 continue; 500 473 } 501 474 502 - rockchip_clk_add_lookup(clk, list->id); 475 + rockchip_clk_add_lookup(ctx, clk, list->id); 503 476 } 504 477 } 505 478 506 - void __init rockchip_clk_register_armclk(unsigned int lookup_id, 479 + void __init rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 480 + unsigned int lookup_id, 507 481 const char *name, const char *const *parent_names, 508 482 u8 num_parents, 509 483 const struct rockchip_cpuclk_reg_data *reg_data, ··· 514 486 struct clk *clk; 515 487 516 488 clk = rockchip_clk_register_cpuclk(name, parent_names, num_parents, 517 - reg_data, rates, nrates, reg_base, 518 - &clk_lock); 489 + reg_data, rates, nrates, 490 + ctx->reg_base, &ctx->lock); 519 491 if (IS_ERR(clk)) { 520 492 pr_err("%s: failed to register clock %s: %ld\n", 521 493 __func__, name, PTR_ERR(clk)); 522 494 return; 523 495 } 524 496 525 - rockchip_clk_add_lookup(clk, lookup_id); 497 + rockchip_clk_add_lookup(ctx, clk, lookup_id); 526 498 } 527 499 528 500 void __init rockchip_clk_protect_critical(const char *const clocks[], ··· 539 511 } 540 512 } 541 513 514 + static void __iomem *rst_base; 542 515 static unsigned int reg_restart; 543 516 static void (*cb_restart)(void); 544 517 static int rockchip_restart_notify(struct notifier_block *this, ··· 548 519 if (cb_restart) 549 520 cb_restart(); 550 521 551 - writel(0xfdb9, reg_base + reg_restart); 522 + writel(0xfdb9, rst_base + reg_restart); 552 523 return NOTIFY_DONE; 553 524 } 554 525 ··· 557 528 .priority = 128, 558 529 }; 559 530 560 - void __init rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)) 531 + void __init 532 + rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 533 + unsigned int reg, 534 + void (*cb)(void)) 561 535 { 562 536 int ret; 563 537 538 + rst_base = ctx->reg_base; 564 539 reg_restart = reg; 565 540 cb_restart = cb; 566 541 ret = register_restart_handler(&rockchip_restart_handler);
+85 -19
drivers/clk/rockchip/clk.h
··· 27 27 #define CLK_ROCKCHIP_CLK_H 28 28 29 29 #include <linux/io.h> 30 + #include <linux/clk-provider.h> 30 31 31 32 struct clk; 32 33 33 34 #define HIWORD_UPDATE(val, mask, shift) \ 34 35 ((val) << (shift) | (mask) << ((shift) + 16)) 35 36 36 - /* register positions shared by RK2928, RK3036, RK3066, RK3188 and RK3228 */ 37 37 #define RK2928_PLL_CON(x) ((x) * 0x4) 38 38 #define RK2928_MODE_CON 0x40 39 39 #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) ··· 92 92 #define RK3368_EMMC_CON0 0x418 93 93 #define RK3368_EMMC_CON1 0x41c 94 94 95 + #define RK3399_PLL_CON(x) RK2928_PLL_CON(x) 96 + #define RK3399_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 97 + #define RK3399_CLKGATE_CON(x) ((x) * 0x4 + 0x300) 98 + #define RK3399_SOFTRST_CON(x) ((x) * 0x4 + 0x400) 99 + #define RK3399_GLB_SRST_FST 0x500 100 + #define RK3399_GLB_SRST_SND 0x504 101 + #define RK3399_GLB_CNT_TH 0x508 102 + #define RK3399_MISC_CON 0x50c 103 + #define RK3399_RST_CON 0x510 104 + #define RK3399_RST_ST 0x514 105 + #define RK3399_SDMMC_CON0 0x580 106 + #define RK3399_SDMMC_CON1 0x584 107 + #define RK3399_SDIO_CON0 0x588 108 + #define RK3399_SDIO_CON1 0x58c 109 + 110 + #define RK3399_PMU_PLL_CON(x) RK2928_PLL_CON(x) 111 + #define RK3399_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x80) 112 + #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) 113 + #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) 114 + 95 115 enum rockchip_pll_type { 96 116 pll_rk3036, 97 117 pll_rk3066, 118 + pll_rk3399, 98 119 }; 99 120 100 121 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ ··· 148 127 .nb = _nb, \ 149 128 } 150 129 130 + /** 131 + * struct rockchip_clk_provider - information about clock provider 132 + * @reg_base: virtual address for the register base. 133 + * @clk_data: holds clock related data like clk* and number of clocks. 134 + * @cru_node: device-node of the clock-provider 135 + * @grf: regmap of the general-register-files syscon 136 + * @lock: maintains exclusion between callbacks for a given clock-provider. 137 + */ 138 + struct rockchip_clk_provider { 139 + void __iomem *reg_base; 140 + struct clk_onecell_data clk_data; 141 + struct device_node *cru_node; 142 + struct regmap *grf; 143 + spinlock_t lock; 144 + }; 145 + 151 146 struct rockchip_pll_rate_table { 152 147 unsigned long rate; 153 148 unsigned int nr; 154 149 unsigned int nf; 155 150 unsigned int no; 156 151 unsigned int nb; 157 - /* for RK3036 */ 152 + /* for RK3036/RK3399 */ 158 153 unsigned int fbdiv; 159 154 unsigned int postdiv1; 160 155 unsigned int refdiv; ··· 180 143 }; 181 144 182 145 /** 183 - * struct rockchip_pll_clock: information about pll clock 146 + * struct rockchip_pll_clock - information about pll clock 184 147 * @id: platform specific id of the clock. 185 148 * @name: name of this pll clock. 186 - * @parent_name: name of the parent clock. 149 + * @parent_names: name of the parent clock. 150 + * @num_parents: number of parents 187 151 * @flags: optional flags for basic clock. 188 152 * @con_offset: offset of the register for configuring the PLL. 189 153 * @mode_offset: offset of the register for configuring the PLL-mode. ··· 232 194 .rate_table = _rtable, \ 233 195 } 234 196 235 - struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type, 197 + struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 198 + enum rockchip_pll_type pll_type, 236 199 const char *name, const char *const *parent_names, 237 - u8 num_parents, void __iomem *base, int con_offset, 238 - int grf_lock_offset, int lock_shift, int reg_mode, 239 - int mode_shift, struct rockchip_pll_rate_table *rate_table, 240 - u8 clk_pll_flags, spinlock_t *lock); 200 + u8 num_parents, int con_offset, int grf_lock_offset, 201 + int lock_shift, int mode_offset, int mode_shift, 202 + struct rockchip_pll_rate_table *rate_table, 203 + u8 clk_pll_flags); 241 204 242 205 struct rockchip_cpuclk_clksel { 243 206 int reg; ··· 252 213 }; 253 214 254 215 /** 255 - * struct rockchip_cpuclk_reg_data: describes register offsets and masks of the cpuclock 216 + * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock 256 217 * @core_reg: register offset of the core settings register 257 218 * @div_core_shift: core divider offset used to divide the pll value 258 219 * @div_core_mask: core divider mask 220 + * @mux_core_alt: mux value to select alternate parent 221 + * @mux_core_main: mux value to select main parent of core 259 222 * @mux_core_shift: offset of the core multiplexer 223 + * @mux_core_mask: core multiplexer mask 260 224 */ 261 225 struct rockchip_cpuclk_reg_data { 262 226 int core_reg; 263 227 u8 div_core_shift; 264 228 u32 div_core_mask; 265 - int mux_core_reg; 229 + u8 mux_core_alt; 230 + u8 mux_core_main; 266 231 u8 mux_core_shift; 232 + u32 mux_core_mask; 267 233 }; 268 234 269 235 struct clk *rockchip_clk_register_cpuclk(const char *name, ··· 472 428 .child = ch, \ 473 429 } 474 430 431 + #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ 432 + { \ 433 + .id = _id, \ 434 + .branch_type = branch_fraction_divider, \ 435 + .name = cname, \ 436 + .parent_names = (const char *[]){ pname }, \ 437 + .num_parents = 1, \ 438 + .flags = f, \ 439 + .muxdiv_offset = mo, \ 440 + .div_shift = 16, \ 441 + .div_width = 16, \ 442 + .div_flags = df, \ 443 + .gate_offset = -1, \ 444 + .child = ch, \ 445 + } 446 + 475 447 #define MUX(_id, cname, pnames, f, o, s, w, mf) \ 476 448 { \ 477 449 .id = _id, \ ··· 596 536 .gate_flags = gf, \ 597 537 } 598 538 599 - void rockchip_clk_init(struct device_node *np, void __iomem *base, 600 - unsigned long nr_clks); 601 - struct regmap *rockchip_clk_get_grf(void); 602 - void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); 603 - void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, 539 + struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 540 + void __iomem *base, unsigned long nr_clks); 541 + void rockchip_clk_of_add_provider(struct device_node *np, 542 + struct rockchip_clk_provider *ctx); 543 + void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 544 + struct clk *clk, unsigned int id); 545 + void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, 546 + struct rockchip_clk_branch *list, 604 547 unsigned int nr_clk); 605 - void rockchip_clk_register_plls(struct rockchip_pll_clock *pll_list, 548 + void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 549 + struct rockchip_pll_clock *pll_list, 606 550 unsigned int nr_pll, int grf_lock_offset); 607 - void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name, 551 + void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 552 + unsigned int lookup_id, const char *name, 608 553 const char *const *parent_names, u8 num_parents, 609 554 const struct rockchip_cpuclk_reg_data *reg_data, 610 555 const struct rockchip_cpuclk_rate_table *rates, 611 556 int nrates); 612 557 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 613 - void rockchip_register_restart_notifier(unsigned int reg, void (*cb)(void)); 558 + void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 559 + unsigned int reg, void (*cb)(void)); 614 560 615 561 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 616 562
+46 -29
drivers/clk/samsung/clk-exynos5420.c
··· 554 554 }; 555 555 556 556 static struct samsung_div_clock exynos5800_div_clks[] __initdata = { 557 - DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3), 558 - 557 + DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore", 558 + "mout_aclk400_wcore", DIV_TOP0, 16, 3), 559 559 DIV(0, "dout_aclk550_cam", "mout_aclk550_cam", 560 560 DIV_TOP8, 16, 3), 561 561 DIV(0, "dout_aclkfl1_550_cam", "mout_aclkfl1_550_cam", ··· 607 607 }; 608 608 609 609 static struct samsung_div_clock exynos5420_div_clks[] __initdata = { 610 - DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", 611 - DIV_TOP0, 16, 3), 610 + DIV(CLK_DOUT_ACLK400_WCORE, "dout_aclk400_wcore", 611 + "mout_aclk400_wcore_bpll", DIV_TOP0, 16, 3), 612 612 }; 613 613 614 614 static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = { ··· 785 785 DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3), 786 786 DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), 787 787 788 - DIV(0, "dout_aclk400_isp", "mout_aclk400_isp", DIV_TOP0, 0, 3), 789 - DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), 790 - DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), 791 - DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), 792 - DIV(0, "dout_aclk100_noc", "mout_aclk100_noc", DIV_TOP0, 20, 3), 793 - DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), 794 - DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), 788 + DIV(CLK_DOUT_ACLK400_ISP, "dout_aclk400_isp", "mout_aclk400_isp", 789 + DIV_TOP0, 0, 3), 790 + DIV(CLK_DOUT_ACLK400_MSCL, "dout_aclk400_mscl", "mout_aclk400_mscl", 791 + DIV_TOP0, 4, 3), 792 + DIV(CLK_DOUT_ACLK200, "dout_aclk200", "mout_aclk200", 793 + DIV_TOP0, 8, 3), 794 + DIV(CLK_DOUT_ACLK200_FSYS2, "dout_aclk200_fsys2", "mout_aclk200_fsys2", 795 + DIV_TOP0, 12, 3), 796 + DIV(CLK_DOUT_ACLK100_NOC, "dout_aclk100_noc", "mout_aclk100_noc", 797 + DIV_TOP0, 20, 3), 798 + DIV(CLK_DOUT_PCLK200_FSYS, "dout_pclk200_fsys", "mout_pclk200_fsys", 799 + DIV_TOP0, 24, 3), 800 + DIV(CLK_DOUT_ACLK200_FSYS, "dout_aclk200_fsys", "mout_aclk200_fsys", 801 + DIV_TOP0, 28, 3), 802 + DIV(CLK_DOUT_ACLK333_432_GSCL, "dout_aclk333_432_gscl", 803 + "mout_aclk333_432_gscl", DIV_TOP1, 0, 3), 804 + DIV(CLK_DOUT_ACLK333_432_ISP, "dout_aclk333_432_isp", 805 + "mout_aclk333_432_isp", DIV_TOP1, 4, 3), 806 + DIV(CLK_DOUT_ACLK66, "dout_aclk66", "mout_aclk66", 807 + DIV_TOP1, 8, 6), 808 + DIV(CLK_DOUT_ACLK333_432_ISP0, "dout_aclk333_432_isp0", 809 + "mout_aclk333_432_isp0", DIV_TOP1, 16, 3), 810 + DIV(CLK_DOUT_ACLK266, "dout_aclk266", "mout_aclk266", 811 + DIV_TOP1, 20, 3), 812 + DIV(CLK_DOUT_ACLK166, "dout_aclk166", "mout_aclk166", 813 + DIV_TOP1, 24, 3), 814 + DIV(CLK_DOUT_ACLK333, "dout_aclk333", "mout_aclk333", 815 + DIV_TOP1, 28, 3), 795 816 796 - DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", 797 - DIV_TOP1, 0, 3), 798 - DIV(0, "dout_aclk333_432_isp", "mout_aclk333_432_isp", 799 - DIV_TOP1, 4, 3), 800 - DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), 801 - DIV(0, "dout_aclk333_432_isp0", "mout_aclk333_432_isp0", 802 - DIV_TOP1, 16, 3), 803 - DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), 804 - DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), 805 - DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), 806 - 807 - DIV(0, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3), 808 - DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), 809 - DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), 810 - DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), 811 - DIV(0, "dout_aclk300_disp1", "mout_aclk300_disp1", DIV_TOP2, 24, 3), 812 - DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), 817 + DIV(CLK_DOUT_ACLK333_G2D, "dout_aclk333_g2d", "mout_aclk333_g2d", 818 + DIV_TOP2, 8, 3), 819 + DIV(CLK_DOUT_ACLK266_G2D, "dout_aclk266_g2d", "mout_aclk266_g2d", 820 + DIV_TOP2, 12, 3), 821 + DIV(CLK_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 822 + 16, 3), 823 + DIV(CLK_DOUT_ACLK300_JPEG, "dout_aclk300_jpeg", "mout_aclk300_jpeg", 824 + DIV_TOP2, 20, 3), 825 + DIV(CLK_DOUT_ACLK300_DISP1, "dout_aclk300_disp1", 826 + "mout_aclk300_disp1", DIV_TOP2, 24, 3), 827 + DIV(CLK_DOUT_ACLK300_GSCL, "dout_aclk300_gscl", "mout_aclk300_gscl", 828 + DIV_TOP2, 28, 3), 813 829 814 830 /* DISP1 Block */ 815 831 DIV(0, "dout_fimd1", "mout_fimd1_final", DIV_DISP10, 0, 4), ··· 833 817 DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), 834 818 DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), 835 819 DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2), 836 - DIV(0, "dout_aclk400_disp1", "mout_aclk400_disp1", DIV_TOP2, 4, 3), 820 + DIV(CLK_DOUT_ACLK400_DISP1, "dout_aclk400_disp1", 821 + "mout_aclk400_disp1", DIV_TOP2, 4, 3), 837 822 838 823 /* Audio Block */ 839 824 DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4),
+3 -4
drivers/clk/sirf/clk-atlas6.c
··· 130 130 panic("unable to map clkc registers\n"); 131 131 132 132 /* These are always available (RTC and 26MHz OSC)*/ 133 - atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 134 - CLK_IS_ROOT, 32768); 135 - atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 136 - CLK_IS_ROOT, 26000000); 133 + atlas6_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768); 134 + atlas6_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0, 135 + 26000000); 137 136 138 137 for (i = pll1; i < maxclk; i++) { 139 138 atlas6_clks[i] = clk_register(NULL, atlas6_clk_hw_array[i]);
+3 -4
drivers/clk/sirf/clk-prima2.c
··· 129 129 panic("unable to map clkc registers\n"); 130 130 131 131 /* These are always available (RTC and 26MHz OSC)*/ 132 - prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 133 - CLK_IS_ROOT, 32768); 134 - prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 135 - CLK_IS_ROOT, 26000000); 132 + prima2_clks[rtc] = clk_register_fixed_rate(NULL, "rtc", NULL, 0, 32768); 133 + prima2_clks[osc] = clk_register_fixed_rate(NULL, "osc", NULL, 0, 134 + 26000000); 136 135 137 136 for (i = pll1; i < maxclk; i++) { 138 137 prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
+3
drivers/clk/sunxi/Makefile
··· 11 11 obj-y += clk-a20-gmac.o 12 12 obj-y += clk-mod0.o 13 13 obj-y += clk-simple-gates.o 14 + obj-y += clk-sun4i-display.o 15 + obj-y += clk-sun4i-pll3.o 16 + obj-y += clk-sun4i-tcon-ch1.o 14 17 obj-y += clk-sun8i-bus-gates.o 15 18 obj-y += clk-sun8i-mbus.o 16 19 obj-y += clk-sun9i-core.o
+1 -2
drivers/clk/sunxi/clk-a10-hosc.c
··· 54 54 NULL, 0, 55 55 NULL, NULL, 56 56 &fixed->hw, &clk_fixed_rate_ops, 57 - &gate->hw, &clk_gate_ops, 58 - CLK_IS_ROOT); 57 + &gate->hw, &clk_gate_ops, 0); 59 58 60 59 if (IS_ERR(clk)) 61 60 goto err_free_gate;
+1 -1
drivers/clk/sunxi/clk-a10-mod1.c
··· 62 62 clk = clk_register_composite(NULL, clk_name, parents, i, 63 63 &mux->hw, &clk_mux_ops, 64 64 NULL, NULL, 65 - &gate->hw, &clk_gate_ops, 0); 65 + &gate->hw, &clk_gate_ops, CLK_SET_RATE_PARENT); 66 66 if (IS_ERR(clk)) 67 67 goto err_free_gate; 68 68
+261
drivers/clk/sunxi/clk-sun4i-display.c
··· 1 + /* 2 + * Copyright 2015 Maxime Ripard 3 + * 4 + * Maxime Ripard <maxime.ripard@free-electrons.com> 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 + #include <linux/clk-provider.h> 18 + #include <linux/kernel.h> 19 + #include <linux/of_address.h> 20 + #include <linux/reset-controller.h> 21 + #include <linux/slab.h> 22 + #include <linux/spinlock.h> 23 + 24 + struct sun4i_a10_display_clk_data { 25 + bool has_div; 26 + u8 num_rst; 27 + u8 parents; 28 + 29 + u8 offset_en; 30 + u8 offset_div; 31 + u8 offset_mux; 32 + u8 offset_rst; 33 + 34 + u8 width_div; 35 + u8 width_mux; 36 + }; 37 + 38 + struct reset_data { 39 + void __iomem *reg; 40 + spinlock_t *lock; 41 + struct reset_controller_dev rcdev; 42 + u8 offset; 43 + }; 44 + 45 + static DEFINE_SPINLOCK(sun4i_a10_display_lock); 46 + 47 + static inline struct reset_data *rcdev_to_reset_data(struct reset_controller_dev *rcdev) 48 + { 49 + return container_of(rcdev, struct reset_data, rcdev); 50 + }; 51 + 52 + static int sun4i_a10_display_assert(struct reset_controller_dev *rcdev, 53 + unsigned long id) 54 + { 55 + struct reset_data *data = rcdev_to_reset_data(rcdev); 56 + unsigned long flags; 57 + u32 reg; 58 + 59 + spin_lock_irqsave(data->lock, flags); 60 + 61 + reg = readl(data->reg); 62 + writel(reg & ~BIT(data->offset + id), data->reg); 63 + 64 + spin_unlock_irqrestore(data->lock, flags); 65 + 66 + return 0; 67 + } 68 + 69 + static int sun4i_a10_display_deassert(struct reset_controller_dev *rcdev, 70 + unsigned long id) 71 + { 72 + struct reset_data *data = rcdev_to_reset_data(rcdev); 73 + unsigned long flags; 74 + u32 reg; 75 + 76 + spin_lock_irqsave(data->lock, flags); 77 + 78 + reg = readl(data->reg); 79 + writel(reg | BIT(data->offset + id), data->reg); 80 + 81 + spin_unlock_irqrestore(data->lock, flags); 82 + 83 + return 0; 84 + } 85 + 86 + static int sun4i_a10_display_status(struct reset_controller_dev *rcdev, 87 + unsigned long id) 88 + { 89 + struct reset_data *data = rcdev_to_reset_data(rcdev); 90 + 91 + return !(readl(data->reg) & BIT(data->offset + id)); 92 + } 93 + 94 + static const struct reset_control_ops sun4i_a10_display_reset_ops = { 95 + .assert = sun4i_a10_display_assert, 96 + .deassert = sun4i_a10_display_deassert, 97 + .status = sun4i_a10_display_status, 98 + }; 99 + 100 + static int sun4i_a10_display_reset_xlate(struct reset_controller_dev *rcdev, 101 + const struct of_phandle_args *spec) 102 + { 103 + /* We only have a single reset signal */ 104 + return 0; 105 + } 106 + 107 + static void __init sun4i_a10_display_init(struct device_node *node, 108 + const struct sun4i_a10_display_clk_data *data) 109 + { 110 + const char *parents[4]; 111 + const char *clk_name = node->name; 112 + struct reset_data *reset_data; 113 + struct clk_divider *div = NULL; 114 + struct clk_gate *gate; 115 + struct resource res; 116 + struct clk_mux *mux; 117 + void __iomem *reg; 118 + struct clk *clk; 119 + int ret; 120 + 121 + of_property_read_string(node, "clock-output-names", &clk_name); 122 + 123 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 124 + if (IS_ERR(reg)) { 125 + pr_err("%s: Could not map the clock registers\n", clk_name); 126 + return; 127 + } 128 + 129 + ret = of_clk_parent_fill(node, parents, data->parents); 130 + if (ret != data->parents) { 131 + pr_err("%s: Could not retrieve the parents\n", clk_name); 132 + goto unmap; 133 + } 134 + 135 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 136 + if (!mux) 137 + goto unmap; 138 + 139 + mux->reg = reg; 140 + mux->shift = data->offset_mux; 141 + mux->mask = (1 << data->width_mux) - 1; 142 + mux->lock = &sun4i_a10_display_lock; 143 + 144 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 145 + if (!gate) 146 + goto free_mux; 147 + 148 + gate->reg = reg; 149 + gate->bit_idx = data->offset_en; 150 + gate->lock = &sun4i_a10_display_lock; 151 + 152 + if (data->has_div) { 153 + div = kzalloc(sizeof(*div), GFP_KERNEL); 154 + if (!div) 155 + goto free_gate; 156 + 157 + div->reg = reg; 158 + div->shift = data->offset_div; 159 + div->width = data->width_div; 160 + div->lock = &sun4i_a10_display_lock; 161 + } 162 + 163 + clk = clk_register_composite(NULL, clk_name, 164 + parents, data->parents, 165 + &mux->hw, &clk_mux_ops, 166 + data->has_div ? &div->hw : NULL, 167 + data->has_div ? &clk_divider_ops : NULL, 168 + &gate->hw, &clk_gate_ops, 169 + 0); 170 + if (IS_ERR(clk)) { 171 + pr_err("%s: Couldn't register the clock\n", clk_name); 172 + goto free_div; 173 + } 174 + 175 + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); 176 + if (ret) { 177 + pr_err("%s: Couldn't register DT provider\n", clk_name); 178 + goto free_clk; 179 + } 180 + 181 + if (!data->num_rst) 182 + return; 183 + 184 + reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); 185 + if (!reset_data) 186 + goto free_of_clk; 187 + 188 + reset_data->reg = reg; 189 + reset_data->offset = data->offset_rst; 190 + reset_data->lock = &sun4i_a10_display_lock; 191 + reset_data->rcdev.nr_resets = data->num_rst; 192 + reset_data->rcdev.ops = &sun4i_a10_display_reset_ops; 193 + reset_data->rcdev.of_node = node; 194 + 195 + if (data->num_rst == 1) { 196 + reset_data->rcdev.of_reset_n_cells = 0; 197 + reset_data->rcdev.of_xlate = &sun4i_a10_display_reset_xlate; 198 + } else { 199 + reset_data->rcdev.of_reset_n_cells = 1; 200 + } 201 + 202 + if (reset_controller_register(&reset_data->rcdev)) { 203 + pr_err("%s: Couldn't register the reset controller\n", 204 + clk_name); 205 + goto free_reset; 206 + } 207 + 208 + return; 209 + 210 + free_reset: 211 + kfree(reset_data); 212 + free_of_clk: 213 + of_clk_del_provider(node); 214 + free_clk: 215 + clk_unregister_composite(clk); 216 + free_div: 217 + kfree(div); 218 + free_gate: 219 + kfree(gate); 220 + free_mux: 221 + kfree(mux); 222 + unmap: 223 + iounmap(reg); 224 + of_address_to_resource(node, 0, &res); 225 + release_mem_region(res.start, resource_size(&res)); 226 + } 227 + 228 + static const struct sun4i_a10_display_clk_data sun4i_a10_tcon_ch0_data __initconst = { 229 + .num_rst = 2, 230 + .parents = 4, 231 + .offset_en = 31, 232 + .offset_rst = 29, 233 + .offset_mux = 24, 234 + .width_mux = 2, 235 + }; 236 + 237 + static void __init sun4i_a10_tcon_ch0_setup(struct device_node *node) 238 + { 239 + sun4i_a10_display_init(node, &sun4i_a10_tcon_ch0_data); 240 + } 241 + CLK_OF_DECLARE(sun4i_a10_tcon_ch0, "allwinner,sun4i-a10-tcon-ch0-clk", 242 + sun4i_a10_tcon_ch0_setup); 243 + 244 + static const struct sun4i_a10_display_clk_data sun4i_a10_display_data __initconst = { 245 + .has_div = true, 246 + .num_rst = 1, 247 + .parents = 3, 248 + .offset_en = 31, 249 + .offset_rst = 30, 250 + .offset_mux = 24, 251 + .offset_div = 0, 252 + .width_mux = 2, 253 + .width_div = 4, 254 + }; 255 + 256 + static void __init sun4i_a10_display_setup(struct device_node *node) 257 + { 258 + sun4i_a10_display_init(node, &sun4i_a10_display_data); 259 + } 260 + CLK_OF_DECLARE(sun4i_a10_display, "allwinner,sun4i-a10-display-clk", 261 + sun4i_a10_display_setup);
+98
drivers/clk/sunxi/clk-sun4i-pll3.c
··· 1 + /* 2 + * Copyright 2015 Maxime Ripard 3 + * 4 + * Maxime Ripard <maxime.ripard@free-electrons.com> 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 + #include <linux/clk-provider.h> 18 + #include <linux/of.h> 19 + #include <linux/of_address.h> 20 + #include <linux/slab.h> 21 + #include <linux/spinlock.h> 22 + 23 + #define SUN4I_A10_PLL3_GATE_BIT 31 24 + #define SUN4I_A10_PLL3_DIV_WIDTH 7 25 + #define SUN4I_A10_PLL3_DIV_SHIFT 0 26 + 27 + static DEFINE_SPINLOCK(sun4i_a10_pll3_lock); 28 + 29 + static void __init sun4i_a10_pll3_setup(struct device_node *node) 30 + { 31 + const char *clk_name = node->name, *parent; 32 + struct clk_multiplier *mult; 33 + struct clk_gate *gate; 34 + struct resource res; 35 + void __iomem *reg; 36 + struct clk *clk; 37 + int ret; 38 + 39 + of_property_read_string(node, "clock-output-names", &clk_name); 40 + parent = of_clk_get_parent_name(node, 0); 41 + 42 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 43 + if (IS_ERR(reg)) { 44 + pr_err("%s: Could not map the clock registers\n", clk_name); 45 + return; 46 + } 47 + 48 + gate = kzalloc(sizeof(*gate), GFP_KERNEL); 49 + if (!gate) 50 + goto err_unmap; 51 + 52 + gate->reg = reg; 53 + gate->bit_idx = SUN4I_A10_PLL3_GATE_BIT; 54 + gate->lock = &sun4i_a10_pll3_lock; 55 + 56 + mult = kzalloc(sizeof(*mult), GFP_KERNEL); 57 + if (!mult) 58 + goto err_free_gate; 59 + 60 + mult->reg = reg; 61 + mult->shift = SUN4I_A10_PLL3_DIV_SHIFT; 62 + mult->width = SUN4I_A10_PLL3_DIV_WIDTH; 63 + mult->lock = &sun4i_a10_pll3_lock; 64 + 65 + clk = clk_register_composite(NULL, clk_name, 66 + &parent, 1, 67 + NULL, NULL, 68 + &mult->hw, &clk_multiplier_ops, 69 + &gate->hw, &clk_gate_ops, 70 + 0); 71 + if (IS_ERR(clk)) { 72 + pr_err("%s: Couldn't register the clock\n", clk_name); 73 + goto err_free_mult; 74 + } 75 + 76 + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); 77 + if (ret) { 78 + pr_err("%s: Couldn't register DT provider\n", 79 + clk_name); 80 + goto err_clk_unregister; 81 + } 82 + 83 + return; 84 + 85 + err_clk_unregister: 86 + clk_unregister_composite(clk); 87 + err_free_mult: 88 + kfree(mult); 89 + err_free_gate: 90 + kfree(gate); 91 + err_unmap: 92 + iounmap(reg); 93 + of_address_to_resource(node, 0, &res); 94 + release_mem_region(res.start, resource_size(&res)); 95 + } 96 + 97 + CLK_OF_DECLARE(sun4i_a10_pll3, "allwinner,sun4i-a10-pll3-clk", 98 + sun4i_a10_pll3_setup);
+300
drivers/clk/sunxi/clk-sun4i-tcon-ch1.c
··· 1 + /* 2 + * Copyright 2015 Maxime Ripard 3 + * 4 + * Maxime Ripard <maxime.ripard@free-electrons.com> 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 + #include <linux/clk-provider.h> 18 + #include <linux/of.h> 19 + #include <linux/of_address.h> 20 + #include <linux/slab.h> 21 + #include <linux/spinlock.h> 22 + 23 + #define TCON_CH1_SCLK2_PARENTS 4 24 + 25 + #define TCON_CH1_SCLK2_GATE_BIT BIT(31) 26 + #define TCON_CH1_SCLK2_MUX_MASK 3 27 + #define TCON_CH1_SCLK2_MUX_SHIFT 24 28 + #define TCON_CH1_SCLK2_DIV_MASK 0xf 29 + #define TCON_CH1_SCLK2_DIV_SHIFT 0 30 + 31 + #define TCON_CH1_SCLK1_GATE_BIT BIT(15) 32 + #define TCON_CH1_SCLK1_HALF_BIT BIT(11) 33 + 34 + struct tcon_ch1_clk { 35 + struct clk_hw hw; 36 + spinlock_t lock; 37 + void __iomem *reg; 38 + }; 39 + 40 + #define hw_to_tclk(hw) container_of(hw, struct tcon_ch1_clk, hw) 41 + 42 + static void tcon_ch1_disable(struct clk_hw *hw) 43 + { 44 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 45 + unsigned long flags; 46 + u32 reg; 47 + 48 + spin_lock_irqsave(&tclk->lock, flags); 49 + reg = readl(tclk->reg); 50 + reg &= ~(TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT); 51 + writel(reg, tclk->reg); 52 + spin_unlock_irqrestore(&tclk->lock, flags); 53 + } 54 + 55 + static int tcon_ch1_enable(struct clk_hw *hw) 56 + { 57 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 58 + unsigned long flags; 59 + u32 reg; 60 + 61 + spin_lock_irqsave(&tclk->lock, flags); 62 + reg = readl(tclk->reg); 63 + reg |= TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT; 64 + writel(reg, tclk->reg); 65 + spin_unlock_irqrestore(&tclk->lock, flags); 66 + 67 + return 0; 68 + } 69 + 70 + static int tcon_ch1_is_enabled(struct clk_hw *hw) 71 + { 72 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 73 + u32 reg; 74 + 75 + reg = readl(tclk->reg); 76 + return reg & (TCON_CH1_SCLK2_GATE_BIT | TCON_CH1_SCLK1_GATE_BIT); 77 + } 78 + 79 + static u8 tcon_ch1_get_parent(struct clk_hw *hw) 80 + { 81 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 82 + int num_parents = clk_hw_get_num_parents(hw); 83 + u32 reg; 84 + 85 + reg = readl(tclk->reg) >> TCON_CH1_SCLK2_MUX_SHIFT; 86 + reg &= reg >> TCON_CH1_SCLK2_MUX_MASK; 87 + 88 + if (reg >= num_parents) 89 + return -EINVAL; 90 + 91 + return reg; 92 + } 93 + 94 + static int tcon_ch1_set_parent(struct clk_hw *hw, u8 index) 95 + { 96 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 97 + unsigned long flags; 98 + u32 reg; 99 + 100 + spin_lock_irqsave(&tclk->lock, flags); 101 + reg = readl(tclk->reg); 102 + reg &= ~(TCON_CH1_SCLK2_MUX_MASK << TCON_CH1_SCLK2_MUX_SHIFT); 103 + reg |= index << TCON_CH1_SCLK2_MUX_SHIFT; 104 + writel(reg, tclk->reg); 105 + spin_unlock_irqrestore(&tclk->lock, flags); 106 + 107 + return 0; 108 + }; 109 + 110 + static unsigned long tcon_ch1_calc_divider(unsigned long rate, 111 + unsigned long parent_rate, 112 + u8 *div, 113 + bool *half) 114 + { 115 + unsigned long best_rate = 0; 116 + u8 best_m = 0, m; 117 + bool is_double; 118 + 119 + for (m = 1; m < 16; m++) { 120 + u8 d; 121 + 122 + for (d = 1; d < 3; d++) { 123 + unsigned long tmp_rate; 124 + 125 + tmp_rate = parent_rate / m / d; 126 + 127 + if (tmp_rate > rate) 128 + continue; 129 + 130 + if (!best_rate || 131 + (rate - tmp_rate) < (rate - best_rate)) { 132 + best_rate = tmp_rate; 133 + best_m = m; 134 + is_double = d; 135 + } 136 + } 137 + } 138 + 139 + if (div && half) { 140 + *div = best_m; 141 + *half = is_double; 142 + } 143 + 144 + return best_rate; 145 + } 146 + 147 + static int tcon_ch1_determine_rate(struct clk_hw *hw, 148 + struct clk_rate_request *req) 149 + { 150 + long best_rate = -EINVAL; 151 + int i; 152 + 153 + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 154 + unsigned long parent_rate; 155 + unsigned long tmp_rate; 156 + struct clk_hw *parent; 157 + 158 + parent = clk_hw_get_parent_by_index(hw, i); 159 + if (!parent) 160 + continue; 161 + 162 + parent_rate = clk_hw_get_rate(parent); 163 + 164 + tmp_rate = tcon_ch1_calc_divider(req->rate, parent_rate, 165 + NULL, NULL); 166 + 167 + if (best_rate < 0 || 168 + (req->rate - tmp_rate) < (req->rate - best_rate)) { 169 + best_rate = tmp_rate; 170 + req->best_parent_rate = parent_rate; 171 + req->best_parent_hw = parent; 172 + } 173 + } 174 + 175 + if (best_rate < 0) 176 + return best_rate; 177 + 178 + req->rate = best_rate; 179 + return 0; 180 + } 181 + 182 + static unsigned long tcon_ch1_recalc_rate(struct clk_hw *hw, 183 + unsigned long parent_rate) 184 + { 185 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 186 + u32 reg; 187 + 188 + reg = readl(tclk->reg); 189 + 190 + parent_rate /= (reg & TCON_CH1_SCLK2_DIV_MASK) + 1; 191 + 192 + if (reg & TCON_CH1_SCLK1_HALF_BIT) 193 + parent_rate /= 2; 194 + 195 + return parent_rate; 196 + } 197 + 198 + static int tcon_ch1_set_rate(struct clk_hw *hw, unsigned long rate, 199 + unsigned long parent_rate) 200 + { 201 + struct tcon_ch1_clk *tclk = hw_to_tclk(hw); 202 + unsigned long flags; 203 + bool half; 204 + u8 div_m; 205 + u32 reg; 206 + 207 + tcon_ch1_calc_divider(rate, parent_rate, &div_m, &half); 208 + 209 + spin_lock_irqsave(&tclk->lock, flags); 210 + reg = readl(tclk->reg); 211 + reg &= ~(TCON_CH1_SCLK2_DIV_MASK | TCON_CH1_SCLK1_HALF_BIT); 212 + reg |= (div_m - 1) & TCON_CH1_SCLK2_DIV_MASK; 213 + 214 + if (half) 215 + reg |= TCON_CH1_SCLK1_HALF_BIT; 216 + 217 + writel(reg, tclk->reg); 218 + spin_unlock_irqrestore(&tclk->lock, flags); 219 + 220 + return 0; 221 + } 222 + 223 + static const struct clk_ops tcon_ch1_ops = { 224 + .disable = tcon_ch1_disable, 225 + .enable = tcon_ch1_enable, 226 + .is_enabled = tcon_ch1_is_enabled, 227 + 228 + .get_parent = tcon_ch1_get_parent, 229 + .set_parent = tcon_ch1_set_parent, 230 + 231 + .determine_rate = tcon_ch1_determine_rate, 232 + .recalc_rate = tcon_ch1_recalc_rate, 233 + .set_rate = tcon_ch1_set_rate, 234 + }; 235 + 236 + static void __init tcon_ch1_setup(struct device_node *node) 237 + { 238 + const char *parents[TCON_CH1_SCLK2_PARENTS]; 239 + const char *clk_name = node->name; 240 + struct clk_init_data init; 241 + struct tcon_ch1_clk *tclk; 242 + struct resource res; 243 + struct clk *clk; 244 + void __iomem *reg; 245 + int ret; 246 + 247 + of_property_read_string(node, "clock-output-names", &clk_name); 248 + 249 + reg = of_io_request_and_map(node, 0, of_node_full_name(node)); 250 + if (IS_ERR(reg)) { 251 + pr_err("%s: Could not map the clock registers\n", clk_name); 252 + return; 253 + } 254 + 255 + ret = of_clk_parent_fill(node, parents, TCON_CH1_SCLK2_PARENTS); 256 + if (ret != TCON_CH1_SCLK2_PARENTS) { 257 + pr_err("%s Could not retrieve the parents\n", clk_name); 258 + goto err_unmap; 259 + } 260 + 261 + tclk = kzalloc(sizeof(*tclk), GFP_KERNEL); 262 + if (!tclk) 263 + goto err_unmap; 264 + 265 + init.name = clk_name; 266 + init.ops = &tcon_ch1_ops; 267 + init.parent_names = parents; 268 + init.num_parents = TCON_CH1_SCLK2_PARENTS; 269 + init.flags = CLK_SET_RATE_PARENT; 270 + 271 + tclk->reg = reg; 272 + tclk->hw.init = &init; 273 + spin_lock_init(&tclk->lock); 274 + 275 + clk = clk_register(NULL, &tclk->hw); 276 + if (IS_ERR(clk)) { 277 + pr_err("%s: Couldn't register the clock\n", clk_name); 278 + goto err_free_data; 279 + } 280 + 281 + ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); 282 + if (ret) { 283 + pr_err("%s: Couldn't register our clock provider\n", clk_name); 284 + goto err_unregister_clk; 285 + } 286 + 287 + return; 288 + 289 + err_unregister_clk: 290 + clk_unregister(clk); 291 + err_free_data: 292 + kfree(tclk); 293 + err_unmap: 294 + iounmap(reg); 295 + of_address_to_resource(node, 0, &res); 296 + release_mem_region(res.start, resource_size(&res)); 297 + } 298 + 299 + CLK_OF_DECLARE(tcon_ch1, "allwinner,sun4i-a10-tcon-ch1-clk", 300 + tcon_ch1_setup);
+1 -1
drivers/clk/sunxi/clk-sun9i-mmc.c
··· 106 106 107 107 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 108 108 /* one clock/reset pair per word */ 109 - count = DIV_ROUND_UP((r->end - r->start + 1), SUN9I_MMC_WIDTH); 109 + count = DIV_ROUND_UP((resource_size(r)), SUN9I_MMC_WIDTH); 110 110 data->membase = devm_ioremap_resource(&pdev->dev, r); 111 111 if (IS_ERR(data->membase)) 112 112 return PTR_ERR(data->membase);
+68 -11
drivers/clk/sunxi/clk-sunxi.c
··· 523 523 .enable = 31, 524 524 .table = &sun4i_pll5_config, 525 525 .getter = sun4i_get_pll5_factors, 526 - .name = "pll5", 527 - }; 528 - 529 - static const struct factors_data sun4i_pll6_data __initconst = { 530 - .enable = 31, 531 - .table = &sun4i_pll5_config, 532 - .getter = sun4i_get_pll5_factors, 533 - .name = "pll6", 534 526 }; 535 527 536 528 static const struct factors_data sun6i_a31_pll6_data __initconst = { 537 529 .enable = 31, 538 530 .table = &sun6i_a31_pll6_config, 539 531 .getter = sun6i_a31_get_pll6_factors, 540 - .name = "pll6x2", 541 532 }; 542 533 543 534 static const struct factors_data sun5i_a13_ahb_data __initconst = { ··· 924 933 }; 925 934 926 935 static const struct divs_data pll6_divs_data __initconst = { 927 - .factors = &sun4i_pll6_data, 936 + .factors = &sun4i_pll5_data, 928 937 .ndivs = 4, 929 938 .div = { 930 939 { .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */ ··· 966 975 struct clk_gate *gate = NULL; 967 976 struct clk_fixed_factor *fix_factor; 968 977 struct clk_divider *divider; 978 + struct factors_data factors = *data->factors; 979 + char *derived_name = NULL; 969 980 void __iomem *reg; 970 981 int ndivs = SUNXI_DIVS_MAX_QTY, i = 0; 971 982 int flags, clkflags; ··· 976 983 if (data->ndivs) 977 984 ndivs = data->ndivs; 978 985 986 + /* Try to find a name for base factor clock */ 987 + for (i = 0; i < ndivs; i++) { 988 + if (data->div[i].self) { 989 + of_property_read_string_index(node, "clock-output-names", 990 + i, &factors.name); 991 + break; 992 + } 993 + } 994 + /* If we don't have a .self clk use the first output-name up to '_' */ 995 + if (factors.name == NULL) { 996 + char *endp; 997 + 998 + of_property_read_string_index(node, "clock-output-names", 999 + 0, &clk_name); 1000 + endp = strchr(clk_name, '_'); 1001 + if (endp) { 1002 + derived_name = kstrndup(clk_name, endp - clk_name, 1003 + GFP_KERNEL); 1004 + factors.name = derived_name; 1005 + } else { 1006 + factors.name = clk_name; 1007 + } 1008 + } 1009 + 979 1010 /* Set up factor clock that we will be dividing */ 980 - pclk = sunxi_factors_clk_setup(node, data->factors); 1011 + pclk = sunxi_factors_clk_setup(node, &factors); 981 1012 if (!pclk) 982 1013 return NULL; 1014 + 983 1015 parent = __clk_get_name(pclk); 1016 + kfree(derived_name); 984 1017 985 1018 reg = of_iomap(node, 0); 986 1019 if (!reg) { ··· 1146 1127 } 1147 1128 CLK_OF_DECLARE(sun6i_pll6, "allwinner,sun6i-a31-pll6-clk", 1148 1129 sun6i_pll6_clk_setup); 1130 + 1131 + /* 1132 + * sun6i display 1133 + * 1134 + * rate = parent_rate / (m + 1); 1135 + */ 1136 + static void sun6i_display_factors(struct factors_request *req) 1137 + { 1138 + u8 m; 1139 + 1140 + if (req->rate > req->parent_rate) 1141 + req->rate = req->parent_rate; 1142 + 1143 + m = DIV_ROUND_UP(req->parent_rate, req->rate); 1144 + 1145 + req->rate = req->parent_rate / m; 1146 + req->m = m - 1; 1147 + } 1148 + 1149 + static const struct clk_factors_config sun6i_display_config = { 1150 + .mshift = 0, 1151 + .mwidth = 4, 1152 + }; 1153 + 1154 + static const struct factors_data sun6i_display_data __initconst = { 1155 + .enable = 31, 1156 + .mux = 24, 1157 + .muxmask = BIT(2) | BIT(1) | BIT(0), 1158 + .table = &sun6i_display_config, 1159 + .getter = sun6i_display_factors, 1160 + }; 1161 + 1162 + static void __init sun6i_display_setup(struct device_node *node) 1163 + { 1164 + sunxi_factors_clk_setup(node, &sun6i_display_data); 1165 + } 1166 + CLK_OF_DECLARE(sun6i_display, "allwinner,sun6i-a31-display-clk", 1167 + sun6i_display_setup);
+1
drivers/clk/tegra/Makefile
··· 3 3 obj-y += clk-dfll.o 4 4 obj-y += clk-divider.o 5 5 obj-y += clk-periph.o 6 + obj-y += clk-periph-fixed.o 6 7 obj-y += clk-periph-gate.o 7 8 obj-y += clk-pll.o 8 9 obj-y += clk-pll-out.o
+6 -5
drivers/clk/tegra/clk-dfll.c
··· 55 55 #include <linux/seq_file.h> 56 56 57 57 #include "clk-dfll.h" 58 + #include "cvb.h" 58 59 59 60 /* 60 61 * DFLL control registers - access via dfll_{readl,writel} ··· 443 442 { 444 443 td->tune_range = DFLL_TUNE_LOW; 445 444 446 - dfll_writel(td, td->soc->tune0_low, DFLL_TUNE0); 447 - dfll_writel(td, td->soc->tune1, DFLL_TUNE1); 445 + dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune0_low, DFLL_TUNE0); 446 + dfll_writel(td, td->soc->cvb->cpu_dfll_data.tune1, DFLL_TUNE1); 448 447 dfll_wmb(td); 449 448 450 449 if (td->soc->set_clock_trimmers_low) ··· 1450 1449 } 1451 1450 v_max = dev_pm_opp_get_voltage(opp); 1452 1451 1453 - v = td->soc->min_millivolts * 1000; 1452 + v = td->soc->cvb->min_millivolts * 1000; 1454 1453 lut = find_vdd_map_entry_exact(td, v); 1455 1454 if (lut < 0) 1456 1455 goto out; ··· 1462 1461 break; 1463 1462 v_opp = dev_pm_opp_get_voltage(opp); 1464 1463 1465 - if (v_opp <= td->soc->min_millivolts * 1000) 1464 + if (v_opp <= td->soc->cvb->min_millivolts * 1000) 1466 1465 td->dvco_rate_min = dev_pm_opp_get_freq(opp); 1467 1466 1468 1467 for (;;) { ··· 1491 1490 1492 1491 if (!td->dvco_rate_min) 1493 1492 dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n", 1494 - td->soc->min_millivolts); 1493 + td->soc->cvb->min_millivolts); 1495 1494 else 1496 1495 ret = 0; 1497 1496
+9 -13
drivers/clk/tegra/clk-dfll.h
··· 24 24 25 25 /** 26 26 * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver 27 - * @opp_dev: struct device * that holds the OPP table for the DFLL 28 - * @min_millivolts: minimum voltage (in mV) that the DFLL can operate 29 - * @tune0_low: DFLL tuning register 0 (low voltage range) 30 - * @tune0_high: DFLL tuning register 0 (high voltage range) 31 - * @tune1: DFLL tuning register 1 32 - * @assert_dvco_reset: fn ptr to place the DVCO in reset 33 - * @deassert_dvco_reset: fn ptr to release the DVCO reset 34 - * @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage 35 - * @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage 27 + * @dev: struct device * that holds the OPP table for the DFLL 28 + * @max_freq: maximum frequency supported on this SoC 29 + * @cvb: CPU frequency table for this SoC 30 + * @init_clock_trimmers: callback to initialize clock trimmers 31 + * @set_clock_trimmers_high: callback to tune clock trimmers for high voltage 32 + * @set_clock_trimmers_low: callback to tune clock trimmers for low voltage 36 33 */ 37 34 struct tegra_dfll_soc_data { 38 35 struct device *dev; 39 - unsigned int min_millivolts; 40 - u32 tune0_low; 41 - u32 tune0_high; 42 - u32 tune1; 36 + unsigned long max_freq; 37 + const struct cvb_table *cvb; 38 + 43 39 void (*init_clock_trimmers)(void); 44 40 void (*set_clock_trimmers_high)(void); 45 41 void (*set_clock_trimmers_low)(void);
+2
drivers/clk/tegra/clk-id.h
··· 71 71 tegra_clk_disp2_8, 72 72 tegra_clk_dp2, 73 73 tegra_clk_dpaux, 74 + tegra_clk_dpaux1, 74 75 tegra_clk_dsialp, 75 76 tegra_clk_dsia_mux, 76 77 tegra_clk_dsiblp, ··· 307 306 tegra_clk_xusb_ss_div2, 308 307 tegra_clk_xusb_ssp_src, 309 308 tegra_clk_sclk_mux, 309 + tegra_clk_sor_safe, 310 310 tegra_clk_max, 311 311 }; 312 312
+120
drivers/clk/tegra/clk-periph-fixed.c
··· 1 + /* 2 + * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License 14 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 + */ 16 + 17 + #include <linux/clk-provider.h> 18 + 19 + #include "clk.h" 20 + 21 + static inline struct tegra_clk_periph_fixed * 22 + to_tegra_clk_periph_fixed(struct clk_hw *hw) 23 + { 24 + return container_of(hw, struct tegra_clk_periph_fixed, hw); 25 + } 26 + 27 + static int tegra_clk_periph_fixed_is_enabled(struct clk_hw *hw) 28 + { 29 + struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); 30 + u32 mask = 1 << (fixed->num % 32), value; 31 + 32 + value = readl(fixed->base + fixed->regs->enb_reg); 33 + if (value & mask) { 34 + value = readl(fixed->base + fixed->regs->rst_reg); 35 + if ((value & mask) == 0) 36 + return 1; 37 + } 38 + 39 + return 0; 40 + } 41 + 42 + static int tegra_clk_periph_fixed_enable(struct clk_hw *hw) 43 + { 44 + struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); 45 + u32 mask = 1 << (fixed->num % 32); 46 + 47 + writel(mask, fixed->base + fixed->regs->enb_set_reg); 48 + 49 + return 0; 50 + } 51 + 52 + static void tegra_clk_periph_fixed_disable(struct clk_hw *hw) 53 + { 54 + struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); 55 + u32 mask = 1 << (fixed->num % 32); 56 + 57 + writel(mask, fixed->base + fixed->regs->enb_clr_reg); 58 + } 59 + 60 + static unsigned long 61 + tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw, 62 + unsigned long parent_rate) 63 + { 64 + struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw); 65 + unsigned long long rate; 66 + 67 + rate = (unsigned long long)parent_rate * fixed->mul; 68 + do_div(rate, fixed->div); 69 + 70 + return (unsigned long)rate; 71 + } 72 + 73 + static const struct clk_ops tegra_clk_periph_fixed_ops = { 74 + .is_enabled = tegra_clk_periph_fixed_is_enabled, 75 + .enable = tegra_clk_periph_fixed_enable, 76 + .disable = tegra_clk_periph_fixed_disable, 77 + .recalc_rate = tegra_clk_periph_fixed_recalc_rate, 78 + }; 79 + 80 + struct clk *tegra_clk_register_periph_fixed(const char *name, 81 + const char *parent, 82 + unsigned long flags, 83 + void __iomem *base, 84 + unsigned int mul, 85 + unsigned int div, 86 + unsigned int num) 87 + { 88 + const struct tegra_clk_periph_regs *regs; 89 + struct tegra_clk_periph_fixed *fixed; 90 + struct clk_init_data init; 91 + struct clk *clk; 92 + 93 + regs = get_reg_bank(num); 94 + if (!regs) 95 + return ERR_PTR(-EINVAL); 96 + 97 + fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); 98 + if (!fixed) 99 + return ERR_PTR(-ENOMEM); 100 + 101 + init.name = name; 102 + init.flags = flags; 103 + init.parent_names = parent ? &parent : NULL; 104 + init.num_parents = parent ? 1 : 0; 105 + init.ops = &tegra_clk_periph_fixed_ops; 106 + 107 + fixed->base = base; 108 + fixed->regs = regs; 109 + fixed->mul = mul; 110 + fixed->div = div; 111 + fixed->num = num; 112 + 113 + fixed->hw.init = &init; 114 + 115 + clk = clk_register(NULL, &fixed->hw); 116 + if (IS_ERR(clk)) 117 + kfree(fixed); 118 + 119 + return clk; 120 + }
+1 -1
drivers/clk/tegra/clk-periph-gate.c
··· 134 134 struct tegra_clk_periph_gate *gate; 135 135 struct clk *clk; 136 136 struct clk_init_data init; 137 - struct tegra_clk_periph_regs *pregs; 137 + const struct tegra_clk_periph_regs *pregs; 138 138 139 139 pregs = get_reg_bank(clk_num); 140 140 if (!pregs)
+1 -1
drivers/clk/tegra/clk-periph.c
··· 145 145 { 146 146 struct clk *clk; 147 147 struct clk_init_data init; 148 - struct tegra_clk_periph_regs *bank; 148 + const struct tegra_clk_periph_regs *bank; 149 149 bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); 150 150 151 151 if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) {
+46
drivers/clk/tegra/clk-pll.c
··· 2013 2013 #endif 2014 2014 2015 2015 #if defined(CONFIG_ARCH_TEGRA_210_SOC) 2016 + struct clk *tegra_clk_register_pllre_tegra210(const char *name, 2017 + const char *parent_name, void __iomem *clk_base, 2018 + void __iomem *pmc, unsigned long flags, 2019 + struct tegra_clk_pll_params *pll_params, 2020 + spinlock_t *lock, unsigned long parent_rate) 2021 + { 2022 + u32 val; 2023 + struct tegra_clk_pll *pll; 2024 + struct clk *clk; 2025 + 2026 + pll_params->vco_min = _clip_vco_min(pll_params->vco_min, parent_rate); 2027 + 2028 + if (pll_params->adjust_vco) 2029 + pll_params->vco_min = pll_params->adjust_vco(pll_params, 2030 + parent_rate); 2031 + 2032 + pll = _tegra_init_pll(clk_base, pmc, pll_params, lock); 2033 + if (IS_ERR(pll)) 2034 + return ERR_CAST(pll); 2035 + 2036 + /* program minimum rate by default */ 2037 + 2038 + val = pll_readl_base(pll); 2039 + if (val & PLL_BASE_ENABLE) 2040 + WARN_ON(readl_relaxed(clk_base + pll_params->iddq_reg) & 2041 + BIT(pll_params->iddq_bit_idx)); 2042 + else { 2043 + val = 0x4 << divm_shift(pll); 2044 + val |= 0x41 << divn_shift(pll); 2045 + pll_writel_base(val, pll); 2046 + } 2047 + 2048 + /* disable lock override */ 2049 + 2050 + val = pll_readl_misc(pll); 2051 + val &= ~BIT(29); 2052 + pll_writel_misc(val, pll); 2053 + 2054 + clk = _tegra_clk_register_pll(pll, name, parent_name, flags, 2055 + &tegra_clk_pllre_ops); 2056 + if (IS_ERR(clk)) 2057 + kfree(pll); 2058 + 2059 + return clk; 2060 + } 2061 + 2016 2062 static int clk_plle_tegra210_enable(struct clk_hw *hw) 2017 2063 { 2018 2064 struct tegra_clk_pll *pll = to_clk_pll(hw);
-1
drivers/clk/tegra/clk-tegra-fixed.c
··· 107 107 *dt_clk = clk; 108 108 } 109 109 } 110 -
+2 -3
drivers/clk/tegra/clk-tegra-periph.c
··· 803 803 GATE("hda2hdmi", "clk_m", 128, TEGRA_PERIPH_ON_APB, tegra_clk_hda2hdmi, 0), 804 804 GATE("bsea", "clk_m", 62, 0, tegra_clk_bsea, 0), 805 805 GATE("bsev", "clk_m", 63, 0, tegra_clk_bsev, 0), 806 - GATE("mipi-cal", "clk_m", 56, 0, tegra_clk_mipi_cal, 0), 806 + GATE("mipi-cal", "clk72mhz", 56, 0, tegra_clk_mipi_cal, 0), 807 807 GATE("usbd", "clk_m", 22, 0, tegra_clk_usbd, 0), 808 808 GATE("usb2", "clk_m", 58, 0, tegra_clk_usb2, 0), 809 809 GATE("usb3", "clk_m", 59, 0, tegra_clk_usb3, 0), ··· 821 821 GATE("ispb", "clk_m", 3, 0, tegra_clk_ispb, 0), 822 822 GATE("vim2_clk", "clk_m", 11, 0, tegra_clk_vim2_clk, 0), 823 823 GATE("pcie", "clk_m", 70, 0, tegra_clk_pcie, 0), 824 - GATE("dpaux", "clk_m", 181, 0, tegra_clk_dpaux, 0), 825 824 GATE("gpu", "pll_ref", 184, 0, tegra_clk_gpu, 0), 826 825 GATE("pllg_ref", "pll_ref", 189, 0, tegra_clk_pll_g_ref, 0), 827 826 GATE("hsic_trk", "usb2_hsic_trk", 209, TEGRA_PERIPH_NO_RESET, tegra_clk_hsic_trk, 0), ··· 876 877 struct clk **dt_clk; 877 878 878 879 for (i = 0; i < ARRAY_SIZE(periph_clks); i++) { 879 - struct tegra_clk_periph_regs *bank; 880 + const struct tegra_clk_periph_regs *bank; 880 881 struct tegra_periph_init_data *data; 881 882 882 883 data = periph_clks + i;
+5 -1
drivers/clk/tegra/clk-tegra114.c
··· 743 743 [tegra_clk_csi] = { .dt_id = TEGRA114_CLK_CSI, .present = true }, 744 744 [tegra_clk_i2c2] = { .dt_id = TEGRA114_CLK_I2C2, .present = true }, 745 745 [tegra_clk_uartc] = { .dt_id = TEGRA114_CLK_UARTC, .present = true }, 746 - [tegra_clk_mipi_cal] = { .dt_id = TEGRA114_CLK_MIPI_CAL, .present = true }, 747 746 [tegra_clk_emc] = { .dt_id = TEGRA114_CLK_EMC, .present = true }, 748 747 [tegra_clk_usb2] = { .dt_id = TEGRA114_CLK_USB2, .present = true }, 749 748 [tegra_clk_usb3] = { .dt_id = TEGRA114_CLK_USB3, .present = true }, ··· 1235 1236 clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, 1236 1237 &emc_lock); 1237 1238 clks[TEGRA114_CLK_MC] = clk; 1239 + 1240 + clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base, 1241 + CLK_SET_RATE_PARENT, 56, 1242 + periph_clk_enb_refcnt); 1243 + clks[TEGRA114_CLK_MIPI_CAL] = clk; 1238 1244 1239 1245 for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { 1240 1246 data = &tegra_periph_clk_list[i];
+60 -43
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
··· 47 47 }, 48 48 .speedo_scale = 100, 49 49 .voltage_scale = 1000, 50 - .cvb_table = { 51 - {204000000UL, {1112619, -29295, 402} }, 52 - {306000000UL, {1150460, -30585, 402} }, 53 - {408000000UL, {1190122, -31865, 402} }, 54 - {510000000UL, {1231606, -33155, 402} }, 55 - {612000000UL, {1274912, -34435, 402} }, 56 - {714000000UL, {1320040, -35725, 402} }, 57 - {816000000UL, {1366990, -37005, 402} }, 58 - {918000000UL, {1415762, -38295, 402} }, 59 - {1020000000UL, {1466355, -39575, 402} }, 60 - {1122000000UL, {1518771, -40865, 402} }, 61 - {1224000000UL, {1573009, -42145, 402} }, 62 - {1326000000UL, {1629068, -43435, 402} }, 63 - {1428000000UL, {1686950, -44715, 402} }, 64 - {1530000000UL, {1746653, -46005, 402} }, 65 - {1632000000UL, {1808179, -47285, 402} }, 66 - {1734000000UL, {1871526, -48575, 402} }, 67 - {1836000000UL, {1936696, -49855, 402} }, 68 - {1938000000UL, {2003687, -51145, 402} }, 69 - {2014500000UL, {2054787, -52095, 402} }, 70 - {2116500000UL, {2124957, -53385, 402} }, 71 - {2218500000UL, {2196950, -54665, 402} }, 72 - {2320500000UL, {2270765, -55955, 402} }, 73 - {2422500000UL, {2346401, -57235, 402} }, 74 - {2524500000UL, {2437299, -58535, 402} }, 75 - {0, { 0, 0, 0} }, 50 + .entries = { 51 + { 204000000UL, { 1112619, -29295, 402 } }, 52 + { 306000000UL, { 1150460, -30585, 402 } }, 53 + { 408000000UL, { 1190122, -31865, 402 } }, 54 + { 510000000UL, { 1231606, -33155, 402 } }, 55 + { 612000000UL, { 1274912, -34435, 402 } }, 56 + { 714000000UL, { 1320040, -35725, 402 } }, 57 + { 816000000UL, { 1366990, -37005, 402 } }, 58 + { 918000000UL, { 1415762, -38295, 402 } }, 59 + { 1020000000UL, { 1466355, -39575, 402 } }, 60 + { 1122000000UL, { 1518771, -40865, 402 } }, 61 + { 1224000000UL, { 1573009, -42145, 402 } }, 62 + { 1326000000UL, { 1629068, -43435, 402 } }, 63 + { 1428000000UL, { 1686950, -44715, 402 } }, 64 + { 1530000000UL, { 1746653, -46005, 402 } }, 65 + { 1632000000UL, { 1808179, -47285, 402 } }, 66 + { 1734000000UL, { 1871526, -48575, 402 } }, 67 + { 1836000000UL, { 1936696, -49855, 402 } }, 68 + { 1938000000UL, { 2003687, -51145, 402 } }, 69 + { 2014500000UL, { 2054787, -52095, 402 } }, 70 + { 2116500000UL, { 2124957, -53385, 402 } }, 71 + { 2218500000UL, { 2196950, -54665, 402 } }, 72 + { 2320500000UL, { 2270765, -55955, 402 } }, 73 + { 2422500000UL, { 2346401, -57235, 402 } }, 74 + { 2524500000UL, { 2437299, -58535, 402 } }, 75 + { 0UL, { 0, 0, 0 } }, 76 76 }, 77 77 .cpu_dfll_data = { 78 78 .tune0_low = 0x005020ff, ··· 84 84 85 85 static int tegra124_dfll_fcpu_probe(struct platform_device *pdev) 86 86 { 87 - int process_id, speedo_id, speedo_value; 87 + int process_id, speedo_id, speedo_value, err; 88 88 struct tegra_dfll_soc_data *soc; 89 - const struct cvb_table *cvb; 90 89 91 90 process_id = tegra_sku_info.cpu_process_id; 92 91 speedo_id = tegra_sku_info.cpu_speedo_id; ··· 107 108 return -ENODEV; 108 109 } 109 110 110 - cvb = tegra_cvb_build_opp_table(tegra124_cpu_cvb_tables, 111 - ARRAY_SIZE(tegra124_cpu_cvb_tables), 112 - process_id, speedo_id, speedo_value, 113 - cpu_max_freq_table[speedo_id], 114 - soc->dev); 115 - if (IS_ERR(cvb)) { 116 - dev_err(&pdev->dev, "couldn't build OPP table: %ld\n", 117 - PTR_ERR(cvb)); 118 - return PTR_ERR(cvb); 111 + soc->max_freq = cpu_max_freq_table[speedo_id]; 112 + 113 + soc->cvb = tegra_cvb_add_opp_table(soc->dev, tegra124_cpu_cvb_tables, 114 + ARRAY_SIZE(tegra124_cpu_cvb_tables), 115 + process_id, speedo_id, speedo_value, 116 + soc->max_freq); 117 + if (IS_ERR(soc->cvb)) { 118 + dev_err(&pdev->dev, "couldn't add OPP table: %ld\n", 119 + PTR_ERR(soc->cvb)); 120 + return PTR_ERR(soc->cvb); 119 121 } 120 122 121 - soc->min_millivolts = cvb->min_millivolts; 122 - soc->tune0_low = cvb->cpu_dfll_data.tune0_low; 123 - soc->tune0_high = cvb->cpu_dfll_data.tune0_high; 124 - soc->tune1 = cvb->cpu_dfll_data.tune1; 123 + err = tegra_dfll_register(pdev, soc); 124 + if (err < 0) { 125 + tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); 126 + return err; 127 + } 125 128 126 - return tegra_dfll_register(pdev, soc); 129 + platform_set_drvdata(pdev, soc); 130 + 131 + return 0; 132 + } 133 + 134 + static int tegra124_dfll_fcpu_remove(struct platform_device *pdev) 135 + { 136 + struct tegra_dfll_soc_data *soc = platform_get_drvdata(pdev); 137 + int err; 138 + 139 + err = tegra_dfll_unregister(pdev); 140 + if (err < 0) 141 + dev_err(&pdev->dev, "failed to unregister DFLL: %d\n", err); 142 + 143 + tegra_cvb_remove_opp_table(soc->dev, soc->cvb, soc->max_freq); 144 + 145 + return 0; 127 146 } 128 147 129 148 static const struct of_device_id tegra124_dfll_fcpu_of_match[] = { ··· 157 140 158 141 static struct platform_driver tegra124_dfll_fcpu_driver = { 159 142 .probe = tegra124_dfll_fcpu_probe, 160 - .remove = tegra_dfll_unregister, 143 + .remove = tegra124_dfll_fcpu_remove, 161 144 .driver = { 162 145 .name = "tegra124-dfll", 163 146 .of_match_table = tegra124_dfll_fcpu_of_match,
+4
drivers/clk/tegra/clk-tegra124.c
··· 1155 1155 1, 2); 1156 1156 clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk; 1157 1157 1158 + clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base, 1159 + 1, 17, 181); 1160 + clks[TEGRA124_CLK_DPAUX] = clk; 1161 + 1158 1162 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, 1159 1163 clk_base + PLLD_MISC, 30, 0, &pll_d_lock); 1160 1164 clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk;
+27 -2
drivers/clk/tegra/clk-tegra210.c
··· 92 92 #define PLLE_AUX 0x48c 93 93 #define PLLRE_BASE 0x4c4 94 94 #define PLLRE_MISC0 0x4c8 95 + #define PLLRE_OUT1 0x4cc 95 96 #define PLLDP_BASE 0x590 96 97 #define PLLDP_MISC 0x594 97 98 ··· 2151 2150 [tegra_clk_clk72Mhz_8] = { .dt_id = TEGRA210_CLK_CLK72MHZ, .present = true }, 2152 2151 [tegra_clk_vic03_8] = { .dt_id = TEGRA210_CLK_VIC03, .present = true }, 2153 2152 [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, 2153 + [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true }, 2154 2154 [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, 2155 2155 [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, 2156 2156 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, ··· 2463 2461 1, 2); 2464 2462 clks[TEGRA210_CLK_XUSB_SS_DIV2] = clk; 2465 2463 2464 + clk = tegra_clk_register_periph_fixed("dpaux", "pll_p", 0, clk_base, 2465 + 1, 17, 181); 2466 + clks[TEGRA210_CLK_DPAUX] = clk; 2467 + 2468 + clk = tegra_clk_register_periph_fixed("dpaux1", "pll_p", 0, clk_base, 2469 + 1, 17, 207); 2470 + clks[TEGRA210_CLK_DPAUX1] = clk; 2471 + 2472 + clk = tegra_clk_register_periph_fixed("sor_safe", "pll_p", 0, clk_base, 2473 + 1, 17, 222); 2474 + clks[TEGRA210_CLK_SOR_SAFE] = clk; 2475 + 2466 2476 /* pll_d_dsi_out */ 2467 2477 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, 2468 2478 clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); ··· 2654 2640 clks[TEGRA210_CLK_PLL_D_OUT0] = clk; 2655 2641 2656 2642 /* PLLRE */ 2657 - clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc, 2658 - 0, &pll_re_vco_params, &pll_re_lock, pll_ref_freq); 2643 + clk = tegra_clk_register_pllre_tegra210("pll_re_vco", "pll_ref", 2644 + clk_base, pmc, 0, 2645 + &pll_re_vco_params, 2646 + &pll_re_lock, pll_ref_freq); 2659 2647 clk_register_clkdev(clk, "pll_re_vco", NULL); 2660 2648 clks[TEGRA210_CLK_PLL_RE_VCO] = clk; 2661 2649 ··· 2666 2650 pll_vco_post_div_table, &pll_re_lock); 2667 2651 clk_register_clkdev(clk, "pll_re_out", NULL); 2668 2652 clks[TEGRA210_CLK_PLL_RE_OUT] = clk; 2653 + 2654 + clk = tegra_clk_register_divider("pll_re_out1_div", "pll_re_vco", 2655 + clk_base + PLLRE_OUT1, 0, 2656 + TEGRA_DIVIDER_ROUND_UP, 2657 + 8, 8, 1, NULL); 2658 + clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div", 2659 + clk_base + PLLRE_OUT1, 1, 0, 2660 + CLK_SET_RATE_PARENT, 0, NULL); 2661 + clks[TEGRA210_CLK_PLL_RE_OUT1] = clk; 2669 2662 2670 2663 /* PLLE */ 2671 2664 clk = tegra_clk_register_plle_tegra210("pll_e", "pll_ref",
+7 -5
drivers/clk/tegra/clk-tegra30.c
··· 339 339 }; 340 340 341 341 static struct tegra_clk_pll_freq_table pll_u_freq_table[] = { 342 - { 12000000, 480000000, 960, 12, 1, 12 }, 343 - { 13000000, 480000000, 960, 13, 1, 12 }, 344 - { 16800000, 480000000, 400, 7, 1, 5 }, 345 - { 19200000, 480000000, 200, 4, 1, 3 }, 346 - { 26000000, 480000000, 960, 26, 1, 12 }, 342 + { 12000000, 480000000, 960, 12, 2, 12 }, 343 + { 13000000, 480000000, 960, 13, 2, 12 }, 344 + { 16800000, 480000000, 400, 7, 2, 5 }, 345 + { 19200000, 480000000, 200, 4, 2, 3 }, 346 + { 26000000, 480000000, 960, 26, 2, 12 }, 347 347 { 0, 0, 0, 0, 0, 0 }, 348 348 }; 349 349 ··· 1372 1372 { TEGRA30_CLK_SBC4, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1373 1373 { TEGRA30_CLK_SBC5, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1374 1374 { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 }, 1375 + { TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 }, 1375 1376 { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 }, 1376 1377 { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 }, 1377 1378 { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 }, ··· 1380 1379 { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1381 1380 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1382 1381 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, 1382 + { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, 1383 1383 /* must be the last entry */ 1384 1384 { TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 }, 1385 1385 };
+2 -2
drivers/clk/tegra/clk.c
··· 84 84 static int (*special_reset_deassert)(unsigned long); 85 85 static unsigned int num_special_reset; 86 86 87 - static struct tegra_clk_periph_regs periph_regs[] = { 87 + static const struct tegra_clk_periph_regs periph_regs[] = { 88 88 [0] = { 89 89 .enb_reg = CLK_OUT_ENB_L, 90 90 .enb_set_reg = CLK_OUT_ENB_SET_L, ··· 182 182 return -EINVAL; 183 183 } 184 184 185 - struct tegra_clk_periph_regs *get_reg_bank(int clkid) 185 + const struct tegra_clk_periph_regs *get_reg_bank(int clkid) 186 186 { 187 187 int reg_bank = clkid / 32; 188 188
+25 -2
drivers/clk/tegra/clk.h
··· 386 386 struct tegra_clk_pll_params *pll_params, 387 387 spinlock_t *lock, unsigned long parent_rate); 388 388 389 + struct clk *tegra_clk_register_pllre_tegra210(const char *name, 390 + const char *parent_name, void __iomem *clk_base, 391 + void __iomem *pmc, unsigned long flags, 392 + struct tegra_clk_pll_params *pll_params, 393 + spinlock_t *lock, unsigned long parent_rate); 394 + 389 395 struct clk *tegra_clk_register_plle_tegra114(const char *name, 390 396 const char *parent_name, 391 397 void __iomem *clk_base, unsigned long flags, ··· 502 496 u8 flags; 503 497 int clk_num; 504 498 int *enable_refcnt; 505 - struct tegra_clk_periph_regs *regs; 499 + const struct tegra_clk_periph_regs *regs; 506 500 }; 507 501 508 502 #define to_clk_periph_gate(_hw) \ ··· 521 515 struct clk *tegra_clk_register_periph_gate(const char *name, 522 516 const char *parent_name, u8 gate_flags, void __iomem *clk_base, 523 517 unsigned long flags, int clk_num, int *enable_refcnt); 518 + 519 + struct tegra_clk_periph_fixed { 520 + struct clk_hw hw; 521 + void __iomem *base; 522 + const struct tegra_clk_periph_regs *regs; 523 + unsigned int mul; 524 + unsigned int div; 525 + unsigned int num; 526 + }; 527 + 528 + struct clk *tegra_clk_register_periph_fixed(const char *name, 529 + const char *parent, 530 + unsigned long flags, 531 + void __iomem *base, 532 + unsigned int mul, 533 + unsigned int div, 534 + unsigned int num); 524 535 525 536 /** 526 537 * struct clk-periph - peripheral clock ··· 739 716 void tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list, 740 717 struct clk *clks[], int clk_max); 741 718 742 - struct tegra_clk_periph_regs *get_reg_bank(int clkid); 719 + const struct tegra_clk_periph_regs *get_reg_bank(int clkid); 743 720 struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks); 744 721 745 722 struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
+43 -28
drivers/clk/tegra/cvb.c
··· 61 61 return mv; 62 62 } 63 63 64 - static int build_opp_table(const struct cvb_table *d, 65 - int speedo_value, 66 - unsigned long max_freq, 67 - struct device *opp_dev) 64 + static int build_opp_table(struct device *dev, const struct cvb_table *table, 65 + int speedo_value, unsigned long max_freq) 68 66 { 67 + const struct rail_alignment *align = &table->alignment; 69 68 int i, ret, dfll_mv, min_mv, max_mv; 70 - const struct cvb_table_freq_entry *table = NULL; 71 - const struct rail_alignment *align = &d->alignment; 72 69 73 - min_mv = round_voltage(d->min_millivolts, align, UP); 74 - max_mv = round_voltage(d->max_millivolts, align, DOWN); 70 + min_mv = round_voltage(table->min_millivolts, align, UP); 71 + max_mv = round_voltage(table->max_millivolts, align, DOWN); 75 72 76 73 for (i = 0; i < MAX_DVFS_FREQS; i++) { 77 - table = &d->cvb_table[i]; 78 - if (!table->freq || (table->freq > max_freq)) 74 + const struct cvb_table_freq_entry *entry = &table->entries[i]; 75 + 76 + if (!entry->freq || (entry->freq > max_freq)) 79 77 break; 80 78 81 - dfll_mv = get_cvb_voltage( 82 - speedo_value, d->speedo_scale, &table->coefficients); 83 - dfll_mv = round_cvb_voltage(dfll_mv, d->voltage_scale, align); 79 + dfll_mv = get_cvb_voltage(speedo_value, table->speedo_scale, 80 + &entry->coefficients); 81 + dfll_mv = round_cvb_voltage(dfll_mv, table->voltage_scale, 82 + align); 84 83 dfll_mv = clamp(dfll_mv, min_mv, max_mv); 85 84 86 - ret = dev_pm_opp_add(opp_dev, table->freq, dfll_mv * 1000); 85 + ret = dev_pm_opp_add(dev, entry->freq, dfll_mv * 1000); 87 86 if (ret) 88 87 return ret; 89 88 } ··· 91 92 } 92 93 93 94 /** 94 - * tegra_cvb_build_opp_table - build OPP table from Tegra CVB tables 95 + * tegra_cvb_add_opp_table - build OPP table from Tegra CVB tables 95 96 * @cvb_tables: array of CVB tables 96 97 * @sz: size of the previously mentioned array 97 98 * @process_id: process id of the HW module ··· 107 108 * given @opp_dev. Returns a pointer to the struct cvb_table that matched 108 109 * or an ERR_PTR on failure. 109 110 */ 110 - const struct cvb_table *tegra_cvb_build_opp_table( 111 - const struct cvb_table *cvb_tables, 112 - size_t sz, int process_id, 113 - int speedo_id, int speedo_value, 114 - unsigned long max_rate, 115 - struct device *opp_dev) 111 + const struct cvb_table * 112 + tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *tables, 113 + size_t count, int process_id, int speedo_id, 114 + int speedo_value, unsigned long max_freq) 116 115 { 117 - int i, ret; 116 + size_t i; 117 + int ret; 118 118 119 - for (i = 0; i < sz; i++) { 120 - const struct cvb_table *d = &cvb_tables[i]; 119 + for (i = 0; i < count; i++) { 120 + const struct cvb_table *table = &tables[i]; 121 121 122 - if (d->speedo_id != -1 && d->speedo_id != speedo_id) 122 + if (table->speedo_id != -1 && table->speedo_id != speedo_id) 123 123 continue; 124 - if (d->process_id != -1 && d->process_id != process_id) 124 + 125 + if (table->process_id != -1 && table->process_id != process_id) 125 126 continue; 126 127 127 - ret = build_opp_table(d, speedo_value, max_rate, opp_dev); 128 - return ret ? ERR_PTR(ret) : d; 128 + ret = build_opp_table(dev, table, speedo_value, max_freq); 129 + return ret ? ERR_PTR(ret) : table; 129 130 } 130 131 131 132 return ERR_PTR(-EINVAL); 133 + } 134 + 135 + void tegra_cvb_remove_opp_table(struct device *dev, 136 + const struct cvb_table *table, 137 + unsigned long max_freq) 138 + { 139 + unsigned int i; 140 + 141 + for (i = 0; i < MAX_DVFS_FREQS; i++) { 142 + const struct cvb_table_freq_entry *entry = &table->entries[i]; 143 + 144 + if (!entry->freq || (entry->freq > max_freq)) 145 + break; 146 + 147 + dev_pm_opp_remove(dev, entry->freq); 148 + } 132 149 }
+8 -7
drivers/clk/tegra/cvb.h
··· 53 53 54 54 int speedo_scale; 55 55 int voltage_scale; 56 - struct cvb_table_freq_entry cvb_table[MAX_DVFS_FREQS]; 56 + struct cvb_table_freq_entry entries[MAX_DVFS_FREQS]; 57 57 struct cvb_cpu_dfll_data cpu_dfll_data; 58 58 }; 59 59 60 - const struct cvb_table *tegra_cvb_build_opp_table( 61 - const struct cvb_table *cvb_tables, 62 - size_t sz, int process_id, 63 - int speedo_id, int speedo_value, 64 - unsigned long max_rate, 65 - struct device *opp_dev); 60 + const struct cvb_table * 61 + tegra_cvb_add_opp_table(struct device *dev, const struct cvb_table *cvb_tables, 62 + size_t count, int process_id, int speedo_id, 63 + int speedo_value, unsigned long max_freq); 64 + void tegra_cvb_remove_opp_table(struct device *dev, 65 + const struct cvb_table *table, 66 + unsigned long max_freq); 66 67 67 68 #endif
+1
drivers/clk/ti/clk-54xx.c
··· 210 210 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"), 211 211 DT_CLK("omap_wdt", "ick", "dummy_ck"), 212 212 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), 213 + DT_CLK(NULL, "sys_clkin_ck", "sys_clkin"), 213 214 DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"), 214 215 DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"), 215 216 DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"),
+1
drivers/clk/ti/clk-7xx.c
··· 289 289 DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"), 290 290 DT_CLK("omap_wdt", "ick", "dummy_ck"), 291 291 DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"), 292 + DT_CLK(NULL, "sys_clkin_ck", "timer_sys_clk_div"), 292 293 DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"), 293 294 DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"), 294 295 DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"),
+2
drivers/clk/ti/clk-dra7-atl.c
··· 265 265 266 266 /* Get configuration for the ATL instances */ 267 267 snprintf(prop, sizeof(prop), "atl%u", i); 268 + of_node_get(node); 268 269 cfg_node = of_find_node_by_name(node, prop); 269 270 if (cfg_node) { 270 271 ret = of_property_read_u32(cfg_node, "bws", ··· 279 278 atl_write(cinfo, DRA7_ATL_AWSMUX_REG(i), 280 279 cdesc->aws); 281 280 } 281 + of_node_put(cfg_node); 282 282 } 283 283 284 284 cdesc->probed = true;
+1 -1
drivers/clk/ti/clkt_dflt.c
··· 222 222 } 223 223 } 224 224 225 - if (unlikely(IS_ERR(clk->enable_reg))) { 225 + if (IS_ERR(clk->enable_reg)) { 226 226 pr_err("%s: %s missing enable_reg\n", __func__, 227 227 clk_hw_get_name(hw)); 228 228 ret = -EINVAL;
+3
drivers/clk/ti/clkt_dpll.c
··· 301 301 302 302 dd = clk->dpll_data; 303 303 304 + if (dd->max_rate && target_rate > dd->max_rate) 305 + target_rate = dd->max_rate; 306 + 304 307 ref_rate = clk_hw_get_rate(dd->clk_ref); 305 308 clk_name = clk_hw_get_name(hw); 306 309 pr_debug("clock: %s: starting DPLL round_rate, target rate %lu\n",
+5
drivers/clk/ti/dpll.c
··· 655 655 .max_multiplier = 2047, 656 656 .max_divider = 128, 657 657 .min_divider = 1, 658 + .max_rate = 1000000000, 658 659 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 659 660 }; 660 661 ··· 675 674 .max_divider = 256, 676 675 .min_divider = 2, 677 676 .flags = DPLL_J_TYPE, 677 + .max_rate = 2000000000, 678 678 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 679 679 }; 680 680 ··· 694 692 .max_multiplier = 2047, 695 693 .max_divider = 128, 696 694 .min_divider = 1, 695 + .max_rate = 2000000000, 697 696 .flags = DPLL_J_TYPE, 698 697 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 699 698 }; ··· 715 712 .max_multiplier = 2047, 716 713 .max_divider = 128, 717 714 .min_divider = 1, 715 + .max_rate = 1000000000, 718 716 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 719 717 }; 720 718 ··· 733 729 .max_multiplier = 2047, 734 730 .max_divider = 128, 735 731 .min_divider = 1, 732 + .max_rate = 1000000000, 736 733 .modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED), 737 734 }; 738 735
+1 -2
drivers/clk/zte/clk-zx296702.c
··· 234 234 WARN_ON(!topcrm_base); 235 235 236 236 clk[ZX296702_OSC] = 237 - clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, 238 - 30000000); 237 + clk_register_fixed_rate(NULL, "osc", NULL, 0, 30000000); 239 238 clk[ZX296702_PLL_A9] = 240 239 clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base 241 240 + 0x01c, pll_a9_config,
+38
include/dt-bindings/clock/axis,artpec6-clkctrl.h
··· 1 + /* 2 + * ARTPEC-6 clock controller indexes 3 + * 4 + * Copyright 2016 Axis Comunications AB. 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 version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #ifndef DT_BINDINGS_CLK_ARTPEC6_CLKCTRL_H 12 + #define DT_BINDINGS_CLK_ARTPEC6_CLKCTRL_H 13 + 14 + #define ARTPEC6_CLK_CPU 0 15 + #define ARTPEC6_CLK_CPU_PERIPH 1 16 + #define ARTPEC6_CLK_NAND_CLKA 2 17 + #define ARTPEC6_CLK_NAND_CLKB 3 18 + #define ARTPEC6_CLK_ETH_ACLK 4 19 + #define ARTPEC6_CLK_DMA_ACLK 5 20 + #define ARTPEC6_CLK_PTP_REF 6 21 + #define ARTPEC6_CLK_SD_PCLK 7 22 + #define ARTPEC6_CLK_SD_IMCLK 8 23 + #define ARTPEC6_CLK_I2S_HST 9 24 + #define ARTPEC6_CLK_I2S0_CLK 10 25 + #define ARTPEC6_CLK_I2S1_CLK 11 26 + #define ARTPEC6_CLK_UART_PCLK 12 27 + #define ARTPEC6_CLK_UART_REFCLK 13 28 + #define ARTPEC6_CLK_I2C 14 29 + #define ARTPEC6_CLK_SPI_PCLK 15 30 + #define ARTPEC6_CLK_SPI_SSPCLK 16 31 + #define ARTPEC6_CLK_SYS_TIMER 17 32 + #define ARTPEC6_CLK_FRACDIV_IN 18 33 + #define ARTPEC6_CLK_DBG_PCLK 19 34 + 35 + /* This must be the highest clock index plus one. */ 36 + #define ARTPEC6_CLK_NUMCLOCKS 20 37 + 38 + #endif
+19 -1
include/dt-bindings/clock/bcm2835.h
··· 44 44 #define BCM2835_CLOCK_EMMC 28 45 45 #define BCM2835_CLOCK_PERI_IMAGE 29 46 46 #define BCM2835_CLOCK_PWM 30 47 + #define BCM2835_CLOCK_PCM 31 47 48 48 - #define BCM2835_CLOCK_COUNT 31 49 + #define BCM2835_PLLA_DSI0 32 50 + #define BCM2835_PLLA_CCP2 33 51 + #define BCM2835_PLLD_DSI0 34 52 + #define BCM2835_PLLD_DSI1 35 53 + 54 + #define BCM2835_CLOCK_AVEO 36 55 + #define BCM2835_CLOCK_DFT 37 56 + #define BCM2835_CLOCK_GP0 38 57 + #define BCM2835_CLOCK_GP1 39 58 + #define BCM2835_CLOCK_GP2 40 59 + #define BCM2835_CLOCK_SLIM 41 60 + #define BCM2835_CLOCK_SMI 42 61 + #define BCM2835_CLOCK_TEC 43 62 + #define BCM2835_CLOCK_DPI 44 63 + #define BCM2835_CLOCK_CAM0 45 64 + #define BCM2835_CLOCK_CAM1 46 65 + #define BCM2835_CLOCK_DSI0E 47 66 + #define BCM2835_CLOCK_DSI1E 48
+23 -1
include/dt-bindings/clock/exynos5420.h
··· 217 217 218 218 /* divider clocks */ 219 219 #define CLK_DOUT_PIXEL 768 220 + #define CLK_DOUT_ACLK400_WCORE 769 221 + #define CLK_DOUT_ACLK400_ISP 770 222 + #define CLK_DOUT_ACLK400_MSCL 771 223 + #define CLK_DOUT_ACLK200 772 224 + #define CLK_DOUT_ACLK200_FSYS2 773 225 + #define CLK_DOUT_ACLK100_NOC 774 226 + #define CLK_DOUT_PCLK200_FSYS 775 227 + #define CLK_DOUT_ACLK200_FSYS 776 228 + #define CLK_DOUT_ACLK333_432_GSCL 777 229 + #define CLK_DOUT_ACLK333_432_ISP 778 230 + #define CLK_DOUT_ACLK66 779 231 + #define CLK_DOUT_ACLK333_432_ISP0 780 232 + #define CLK_DOUT_ACLK266 781 233 + #define CLK_DOUT_ACLK166 782 234 + #define CLK_DOUT_ACLK333 783 235 + #define CLK_DOUT_ACLK333_G2D 784 236 + #define CLK_DOUT_ACLK266_G2D 785 237 + #define CLK_DOUT_ACLK_G3D 786 238 + #define CLK_DOUT_ACLK300_JPEG 787 239 + #define CLK_DOUT_ACLK300_DISP1 788 240 + #define CLK_DOUT_ACLK300_GSCL 789 241 + #define CLK_DOUT_ACLK400_DISP1 790 220 242 221 243 /* must be greater than maximal clock id */ 222 - #define CLK_NR_CLKS 769 244 + #define CLK_NR_CLKS 791 223 245 224 246 #endif /* _DT_BINDINGS_CLOCK_EXYNOS_5420_H */
+40
include/dt-bindings/clock/hi3519-clock.h
··· 1 + /* 2 + * Copyright (c) 2015 HiSilicon Technologies Co., Ltd. 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 + * You should have received a copy of the GNU General Public License 15 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __DTS_HI3519_CLOCK_H 19 + #define __DTS_HI3519_CLOCK_H 20 + 21 + #define HI3519_FMC_CLK 1 22 + #define HI3519_SPI0_CLK 2 23 + #define HI3519_SPI1_CLK 3 24 + #define HI3519_SPI2_CLK 4 25 + #define HI3519_UART0_CLK 5 26 + #define HI3519_UART1_CLK 6 27 + #define HI3519_UART2_CLK 7 28 + #define HI3519_UART3_CLK 8 29 + #define HI3519_UART4_CLK 9 30 + #define HI3519_PWM_CLK 10 31 + #define HI3519_DMA_CLK 11 32 + #define HI3519_IR_CLK 12 33 + #define HI3519_ETH_PHY_CLK 13 34 + #define HI3519_ETH_MAC_CLK 14 35 + #define HI3519_ETH_MACIF_CLK 15 36 + #define HI3519_USB2_BUS_CLK 16 37 + #define HI3519_USB2_PORT_CLK 17 38 + #define HI3519_USB3_CLK 18 39 + 40 + #endif /* __DTS_HI3519_CLOCK_H */
+2 -1
include/dt-bindings/clock/imx7d-clock.h
··· 448 448 #define IMX7D_PLL_DRAM_TEST_DIV 435 449 449 #define IMX7D_ADC_ROOT_CLK 436 450 450 #define IMX7D_CLK_ARM 437 451 - #define IMX7D_CLK_END 438 451 + #define IMX7D_CKIL 438 452 + #define IMX7D_CLK_END 439 452 453 #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
+1 -1
include/dt-bindings/clock/tegra210-car.h
··· 346 346 #define TEGRA210_CLK_PLL_P_OUT_HSIO 316 347 347 #define TEGRA210_CLK_PLL_P_OUT_XUSB 317 348 348 #define TEGRA210_CLK_XUSB_SSP_SRC 318 349 - /* 319 */ 349 + #define TEGRA210_CLK_PLL_RE_OUT1 319 350 350 /* 320 */ 351 351 /* 321 */ 352 352 /* 322 */
+6 -2
include/dt-bindings/clock/vf610-clock.h
··· 194 194 #define VF610_PLL7_BYPASS 181 195 195 #define VF610_CLK_SNVS 182 196 196 #define VF610_CLK_DAP 183 197 - #define VF610_CLK_OCOTP 184 198 - #define VF610_CLK_END 185 197 + #define VF610_CLK_OCOTP 184 198 + #define VF610_CLK_DDRMC 185 199 + #define VF610_CLK_WKPU 186 200 + #define VF610_CLK_TCON0 187 201 + #define VF610_CLK_TCON1 188 202 + #define VF610_CLK_END 189 199 203 200 204 #endif /* __DT_BINDINGS_CLOCK_VF610_H */
+102 -1
include/linux/clk-provider.h
··· 32 32 #define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ 33 33 #define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ 34 34 #define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */ 35 + #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ 35 36 36 37 struct clk; 37 38 struct clk_hw; ··· 283 282 struct clk *clk_register_fixed_rate(struct device *dev, const char *name, 284 283 const char *parent_name, unsigned long flags, 285 284 unsigned long fixed_rate); 285 + struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name, 286 + const char *parent_name, unsigned long flags, 287 + unsigned long fixed_rate); 286 288 struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev, 287 289 const char *name, const char *parent_name, unsigned long flags, 288 290 unsigned long fixed_rate, unsigned long fixed_accuracy); 289 291 void clk_unregister_fixed_rate(struct clk *clk); 292 + struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev, 293 + const char *name, const char *parent_name, unsigned long flags, 294 + unsigned long fixed_rate, unsigned long fixed_accuracy); 295 + 290 296 void of_fixed_clk_setup(struct device_node *np); 291 297 292 298 /** ··· 334 326 const char *parent_name, unsigned long flags, 335 327 void __iomem *reg, u8 bit_idx, 336 328 u8 clk_gate_flags, spinlock_t *lock); 329 + struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name, 330 + const char *parent_name, unsigned long flags, 331 + void __iomem *reg, u8 bit_idx, 332 + u8 clk_gate_flags, spinlock_t *lock); 337 333 void clk_unregister_gate(struct clk *clk); 334 + void clk_hw_unregister_gate(struct clk_hw *hw); 338 335 339 336 struct clk_div_table { 340 337 unsigned int val; ··· 420 407 const char *parent_name, unsigned long flags, 421 408 void __iomem *reg, u8 shift, u8 width, 422 409 u8 clk_divider_flags, spinlock_t *lock); 410 + struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name, 411 + const char *parent_name, unsigned long flags, 412 + void __iomem *reg, u8 shift, u8 width, 413 + u8 clk_divider_flags, spinlock_t *lock); 423 414 struct clk *clk_register_divider_table(struct device *dev, const char *name, 424 415 const char *parent_name, unsigned long flags, 425 416 void __iomem *reg, u8 shift, u8 width, 426 417 u8 clk_divider_flags, const struct clk_div_table *table, 427 418 spinlock_t *lock); 419 + struct clk_hw *clk_hw_register_divider_table(struct device *dev, 420 + const char *name, const char *parent_name, unsigned long flags, 421 + void __iomem *reg, u8 shift, u8 width, 422 + u8 clk_divider_flags, const struct clk_div_table *table, 423 + spinlock_t *lock); 428 424 void clk_unregister_divider(struct clk *clk); 425 + void clk_hw_unregister_divider(struct clk_hw *hw); 429 426 430 427 /** 431 428 * struct clk_mux - multiplexer clock ··· 486 463 unsigned long flags, 487 464 void __iomem *reg, u8 shift, u8 width, 488 465 u8 clk_mux_flags, spinlock_t *lock); 466 + struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name, 467 + const char * const *parent_names, u8 num_parents, 468 + unsigned long flags, 469 + void __iomem *reg, u8 shift, u8 width, 470 + u8 clk_mux_flags, spinlock_t *lock); 489 471 490 472 struct clk *clk_register_mux_table(struct device *dev, const char *name, 491 473 const char * const *parent_names, u8 num_parents, 492 474 unsigned long flags, 493 475 void __iomem *reg, u8 shift, u32 mask, 494 476 u8 clk_mux_flags, u32 *table, spinlock_t *lock); 477 + struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name, 478 + const char * const *parent_names, u8 num_parents, 479 + unsigned long flags, 480 + void __iomem *reg, u8 shift, u32 mask, 481 + u8 clk_mux_flags, u32 *table, spinlock_t *lock); 495 482 496 483 void clk_unregister_mux(struct clk *clk); 484 + void clk_hw_unregister_mux(struct clk_hw *hw); 497 485 498 486 void of_fixed_factor_clk_setup(struct device_node *node); 499 487 ··· 533 499 const char *parent_name, unsigned long flags, 534 500 unsigned int mult, unsigned int div); 535 501 void clk_unregister_fixed_factor(struct clk *clk); 502 + struct clk_hw *clk_hw_register_fixed_factor(struct device *dev, 503 + const char *name, const char *parent_name, unsigned long flags, 504 + unsigned int mult, unsigned int div); 505 + void clk_hw_unregister_fixed_factor(struct clk_hw *hw); 536 506 537 507 /** 538 508 * struct clk_fractional_divider - adjustable fractional divider clock ··· 571 533 const char *name, const char *parent_name, unsigned long flags, 572 534 void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 573 535 u8 clk_divider_flags, spinlock_t *lock); 536 + struct clk_hw *clk_hw_register_fractional_divider(struct device *dev, 537 + const char *name, const char *parent_name, unsigned long flags, 538 + void __iomem *reg, u8 mshift, u8 mwidth, u8 nshift, u8 nwidth, 539 + u8 clk_divider_flags, spinlock_t *lock); 540 + void clk_hw_unregister_fractional_divider(struct clk_hw *hw); 574 541 575 542 /** 576 543 * struct clk_multiplier - adjustable multiplier clock ··· 646 603 struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 647 604 struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 648 605 unsigned long flags); 606 + void clk_unregister_composite(struct clk *clk); 607 + struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name, 608 + const char * const *parent_names, int num_parents, 609 + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, 610 + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, 611 + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, 612 + unsigned long flags); 613 + void clk_hw_unregister_composite(struct clk_hw *hw); 649 614 650 615 /*** 651 616 * struct clk_gpio_gate - gpio gated clock ··· 676 625 struct clk *clk_register_gpio_gate(struct device *dev, const char *name, 677 626 const char *parent_name, unsigned gpio, bool active_low, 678 627 unsigned long flags); 628 + struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name, 629 + const char *parent_name, unsigned gpio, bool active_low, 630 + unsigned long flags); 631 + void clk_hw_unregister_gpio_gate(struct clk_hw *hw); 679 632 680 633 /** 681 634 * struct clk_gpio_mux - gpio controlled clock multiplexer ··· 695 640 struct clk *clk_register_gpio_mux(struct device *dev, const char *name, 696 641 const char * const *parent_names, u8 num_parents, unsigned gpio, 697 642 bool active_low, unsigned long flags); 643 + struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name, 644 + const char * const *parent_names, u8 num_parents, unsigned gpio, 645 + bool active_low, unsigned long flags); 646 + void clk_hw_unregister_gpio_mux(struct clk_hw *hw); 698 647 699 648 /** 700 649 * clk_register - allocate a new clock, register it and return an opaque cookie ··· 714 655 struct clk *clk_register(struct device *dev, struct clk_hw *hw); 715 656 struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw); 716 657 658 + int __must_check clk_hw_register(struct device *dev, struct clk_hw *hw); 659 + int __must_check devm_clk_hw_register(struct device *dev, struct clk_hw *hw); 660 + 717 661 void clk_unregister(struct clk *clk); 718 662 void devm_clk_unregister(struct device *dev, struct clk *clk); 663 + 664 + void clk_hw_unregister(struct clk_hw *hw); 665 + void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw); 719 666 720 667 /* helper functions */ 721 668 const char *__clk_get_name(const struct clk *clk); ··· 768 703 unsigned int clk_num; 769 704 }; 770 705 706 + struct clk_hw_onecell_data { 707 + size_t num; 708 + struct clk_hw *hws[]; 709 + }; 710 + 771 711 extern struct of_device_id __clk_of_table; 772 712 773 713 #define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) ··· 782 712 struct clk *(*clk_src_get)(struct of_phandle_args *args, 783 713 void *data), 784 714 void *data); 715 + int of_clk_add_hw_provider(struct device_node *np, 716 + struct clk_hw *(*get)(struct of_phandle_args *clkspec, 717 + void *data), 718 + void *data); 785 719 void of_clk_del_provider(struct device_node *np); 786 720 struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, 787 721 void *data); 722 + struct clk_hw *of_clk_hw_simple_get(struct of_phandle_args *clkspec, 723 + void *data); 788 724 struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data); 725 + struct clk_hw *of_clk_hw_onecell_get(struct of_phandle_args *clkspec, 726 + void *data); 789 727 unsigned int of_clk_get_parent_count(struct device_node *np); 790 728 int of_clk_parent_fill(struct device_node *np, const char **parents, 791 729 unsigned int size); 792 730 const char *of_clk_get_parent_name(struct device_node *np, int index); 793 - 731 + int of_clk_detect_critical(struct device_node *np, int index, 732 + unsigned long *flags); 794 733 void of_clk_init(const struct of_device_id *matches); 795 734 796 735 #else /* !CONFIG_OF */ ··· 811 732 { 812 733 return 0; 813 734 } 735 + static inline int of_clk_add_hw_provider(struct device_node *np, 736 + struct clk_hw *(*get)(struct of_phandle_args *clkspec, 737 + void *data), 738 + void *data) 739 + { 740 + return 0; 741 + } 814 742 static inline void of_clk_del_provider(struct device_node *np) {} 815 743 static inline struct clk *of_clk_src_simple_get( 816 744 struct of_phandle_args *clkspec, void *data) 817 745 { 818 746 return ERR_PTR(-ENOENT); 819 747 } 748 + static inline struct clk_hw * 749 + of_clk_hw_simple_get(struct of_phandle_args *clkspec, void *data) 750 + { 751 + return ERR_PTR(-ENOENT); 752 + } 820 753 static inline struct clk *of_clk_src_onecell_get( 821 754 struct of_phandle_args *clkspec, void *data) 755 + { 756 + return ERR_PTR(-ENOENT); 757 + } 758 + static inline struct clk_hw * 759 + of_clk_hw_onecell_get(struct of_phandle_args *clkspec, void *data) 822 760 { 823 761 return ERR_PTR(-ENOENT); 824 762 } ··· 852 756 int index) 853 757 { 854 758 return NULL; 759 + } 760 + static inline int of_clk_detect_critical(struct device_node *np, int index, 761 + unsigned long *flags) 762 + { 763 + return 0; 855 764 } 856 765 static inline void of_clk_init(const struct of_device_id *matches) {} 857 766 #endif /* CONFIG_OF */
+2
include/linux/clk/ti.h
··· 37 37 * @last_rounded_n: cache of the last N result of omap2_dpll_round_rate() 38 38 * @min_divider: minimum valid non-bypass divider value (actual) 39 39 * @max_divider: maximum valid non-bypass divider value (actual) 40 + * @max_rate: maximum clock rate for the DPLL 40 41 * @modes: possible values of @enable_mask 41 42 * @autoidle_reg: register containing the DPLL autoidle mode bitfield 42 43 * @idlest_reg: register containing the DPLL idle status bitfield ··· 82 81 u8 last_rounded_n; 83 82 u8 min_divider; 84 83 u16 max_divider; 84 + unsigned long max_rate; 85 85 u8 modes; 86 86 void __iomem *autoidle_reg; 87 87 void __iomem *idlest_reg;
+6 -1
include/linux/clkdev.h
··· 15 15 #include <asm/clkdev.h> 16 16 17 17 struct clk; 18 + struct clk_hw; 18 19 struct device; 19 20 20 21 struct clk_lookup { ··· 35 34 36 35 struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, 37 36 const char *dev_fmt, ...) __printf(3, 4); 37 + struct clk_lookup *clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, 38 + const char *dev_fmt, ...) __printf(3, 4); 38 39 39 40 void clkdev_add(struct clk_lookup *cl); 40 41 void clkdev_drop(struct clk_lookup *cl); 41 42 42 43 struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id, 43 44 const char *dev_fmt, ...) __printf(3, 4); 45 + struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id, 46 + const char *dev_fmt, ...) __printf(3, 4); 44 47 45 48 void clkdev_add_table(struct clk_lookup *, size_t); 46 49 int clk_add_alias(const char *, const char *, const char *, struct device *); 47 50 48 51 int clk_register_clkdev(struct clk *, const char *, const char *); 49 - int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); 52 + int clk_hw_register_clkdev(struct clk_hw *, const char *, const char *); 50 53 51 54 #ifdef CONFIG_COMMON_CLK 52 55 int __clk_get(struct clk *clk);